You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_jina_auth.py 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. from unittest.mock import MagicMock, patch
  2. import httpx
  3. import pytest
  4. from services.auth.jina.jina import JinaAuth
  5. class TestJinaAuth:
  6. def test_should_initialize_with_valid_bearer_credentials(self):
  7. """Test successful initialization with valid bearer credentials"""
  8. credentials = {"auth_type": "bearer", "config": {"api_key": "test_api_key_123"}}
  9. auth = JinaAuth(credentials)
  10. assert auth.api_key == "test_api_key_123"
  11. assert auth.credentials == credentials
  12. def test_should_raise_error_for_invalid_auth_type(self):
  13. """Test that non-bearer auth type raises ValueError"""
  14. credentials = {"auth_type": "basic", "config": {"api_key": "test_api_key_123"}}
  15. with pytest.raises(ValueError) as exc_info:
  16. JinaAuth(credentials)
  17. assert str(exc_info.value) == "Invalid auth type, Jina Reader auth type must be Bearer"
  18. def test_should_raise_error_for_missing_api_key(self):
  19. """Test that missing API key raises ValueError"""
  20. credentials = {"auth_type": "bearer", "config": {}}
  21. with pytest.raises(ValueError) as exc_info:
  22. JinaAuth(credentials)
  23. assert str(exc_info.value) == "No API key provided"
  24. def test_should_raise_error_for_missing_config(self):
  25. """Test that missing config section raises ValueError"""
  26. credentials = {"auth_type": "bearer"}
  27. with pytest.raises(ValueError) as exc_info:
  28. JinaAuth(credentials)
  29. assert str(exc_info.value) == "No API key provided"
  30. @patch("services.auth.jina.jina.httpx.post")
  31. def test_should_validate_valid_credentials_successfully(self, mock_post):
  32. """Test successful credential validation"""
  33. mock_response = MagicMock()
  34. mock_response.status_code = 200
  35. mock_post.return_value = mock_response
  36. credentials = {"auth_type": "bearer", "config": {"api_key": "test_api_key_123"}}
  37. auth = JinaAuth(credentials)
  38. result = auth.validate_credentials()
  39. assert result is True
  40. mock_post.assert_called_once_with(
  41. "https://r.jina.ai",
  42. headers={"Content-Type": "application/json", "Authorization": "Bearer test_api_key_123"},
  43. json={"url": "https://example.com"},
  44. )
  45. @patch("services.auth.jina.jina.httpx.post")
  46. def test_should_handle_http_402_error(self, mock_post):
  47. """Test handling of 402 Payment Required error"""
  48. mock_response = MagicMock()
  49. mock_response.status_code = 402
  50. mock_response.json.return_value = {"error": "Payment required"}
  51. mock_post.return_value = mock_response
  52. credentials = {"auth_type": "bearer", "config": {"api_key": "test_api_key_123"}}
  53. auth = JinaAuth(credentials)
  54. with pytest.raises(Exception) as exc_info:
  55. auth.validate_credentials()
  56. assert str(exc_info.value) == "Failed to authorize. Status code: 402. Error: Payment required"
  57. @patch("services.auth.jina.jina.httpx.post")
  58. def test_should_handle_http_409_error(self, mock_post):
  59. """Test handling of 409 Conflict error"""
  60. mock_response = MagicMock()
  61. mock_response.status_code = 409
  62. mock_response.json.return_value = {"error": "Conflict error"}
  63. mock_post.return_value = mock_response
  64. credentials = {"auth_type": "bearer", "config": {"api_key": "test_api_key_123"}}
  65. auth = JinaAuth(credentials)
  66. with pytest.raises(Exception) as exc_info:
  67. auth.validate_credentials()
  68. assert str(exc_info.value) == "Failed to authorize. Status code: 409. Error: Conflict error"
  69. @patch("services.auth.jina.jina.httpx.post")
  70. def test_should_handle_http_500_error(self, mock_post):
  71. """Test handling of 500 Internal Server Error"""
  72. mock_response = MagicMock()
  73. mock_response.status_code = 500
  74. mock_response.json.return_value = {"error": "Internal server error"}
  75. mock_post.return_value = mock_response
  76. credentials = {"auth_type": "bearer", "config": {"api_key": "test_api_key_123"}}
  77. auth = JinaAuth(credentials)
  78. with pytest.raises(Exception) as exc_info:
  79. auth.validate_credentials()
  80. assert str(exc_info.value) == "Failed to authorize. Status code: 500. Error: Internal server error"
  81. @patch("services.auth.jina.jina.httpx.post")
  82. def test_should_handle_unexpected_error_with_text_response(self, mock_post):
  83. """Test handling of unexpected errors with text response"""
  84. mock_response = MagicMock()
  85. mock_response.status_code = 403
  86. mock_response.text = '{"error": "Forbidden"}'
  87. mock_response.json.side_effect = Exception("Not JSON")
  88. mock_post.return_value = mock_response
  89. credentials = {"auth_type": "bearer", "config": {"api_key": "test_api_key_123"}}
  90. auth = JinaAuth(credentials)
  91. with pytest.raises(Exception) as exc_info:
  92. auth.validate_credentials()
  93. assert str(exc_info.value) == "Failed to authorize. Status code: 403. Error: Forbidden"
  94. @patch("services.auth.jina.jina.httpx.post")
  95. def test_should_handle_unexpected_error_without_text(self, mock_post):
  96. """Test handling of unexpected errors without text response"""
  97. mock_response = MagicMock()
  98. mock_response.status_code = 404
  99. mock_response.text = ""
  100. mock_response.json.side_effect = Exception("Not JSON")
  101. mock_post.return_value = mock_response
  102. credentials = {"auth_type": "bearer", "config": {"api_key": "test_api_key_123"}}
  103. auth = JinaAuth(credentials)
  104. with pytest.raises(Exception) as exc_info:
  105. auth.validate_credentials()
  106. assert str(exc_info.value) == "Unexpected error occurred while trying to authorize. Status code: 404"
  107. @patch("services.auth.jina.jina.httpx.post")
  108. def test_should_handle_network_errors(self, mock_post):
  109. """Test handling of network connection errors"""
  110. mock_post.side_effect = httpx.ConnectError("Network error")
  111. credentials = {"auth_type": "bearer", "config": {"api_key": "test_api_key_123"}}
  112. auth = JinaAuth(credentials)
  113. with pytest.raises(httpx.ConnectError):
  114. auth.validate_credentials()
  115. def test_should_not_expose_api_key_in_error_messages(self):
  116. """Test that API key is not exposed in error messages"""
  117. credentials = {"auth_type": "bearer", "config": {"api_key": "super_secret_key_12345"}}
  118. auth = JinaAuth(credentials)
  119. # Verify API key is stored but not in any error message
  120. assert auth.api_key == "super_secret_key_12345"
  121. # Test various error scenarios don't expose the key
  122. with pytest.raises(ValueError) as exc_info:
  123. JinaAuth({"auth_type": "basic", "config": {"api_key": "super_secret_key_12345"}})
  124. assert "super_secret_key_12345" not in str(exc_info.value)