test_admin_api.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. """
  2. End-to-end tests for the Admin API endpoints.
  3. """
  4. from contextlib import contextmanager
  5. from unittest.mock import Mock
  6. from fastapi import status
  7. from web.core.config import get_settings
  8. class TestAdminRefreshRemotesEndpoint:
  9. """Test suite for the /admin/refresh_remotes endpoint."""
  10. AUTH_HEADERS = {"Authorization": "Bearer test-remote-reload-token-12345"}
  11. TEST_TOKEN = "test-remote-reload-token-12345"
  12. @staticmethod
  13. @contextmanager
  14. def override_settings(client, mock_settings):
  15. """override get_settings with the provided mock."""
  16. client.app.dependency_overrides[get_settings] = lambda: mock_settings
  17. try:
  18. yield
  19. finally:
  20. client.app.dependency_overrides.pop(get_settings, None)
  21. def test_refresh_remotes_success(self, client, test_base_dir):
  22. """Test successful refresh of remotes with valid auth and verifies against remotes.json."""
  23. import os
  24. import json
  25. remotes_file = os.path.join(test_base_dir, "configs", "remotes.json")
  26. assert os.path.exists(remotes_file)
  27. with open(remotes_file, "r") as f:
  28. initial_remotes = json.load(f)
  29. mock_settings = Mock()
  30. mock_settings.remote_reload_token = self.TEST_TOKEN
  31. with self.override_settings(client, mock_settings):
  32. response = client.post(
  33. "/api/v1/admin/refresh_remotes",
  34. headers=self.AUTH_HEADERS
  35. )
  36. assert response.status_code == status.HTTP_200_OK
  37. assert "application/json" in response.headers["content-type"]
  38. data = response.json()
  39. assert len(data["remotes"]) == len(initial_remotes)
  40. expected_names = [r["name"] for r in initial_remotes]
  41. for name in expected_names:
  42. assert name in data["remotes"]
  43. def test_refresh_remotes_no_auth(self, client):
  44. """Test refresh without authentication - should fail."""
  45. mock_settings = Mock()
  46. mock_settings.remote_reload_token = self.TEST_TOKEN
  47. with self.override_settings(client, mock_settings):
  48. response = client.post("/api/v1/admin/refresh_remotes")
  49. assert response.status_code == status.HTTP_401_UNAUTHORIZED
  50. def test_refresh_remotes_invalid_token(self, client):
  51. """Test refresh with invalid token - should fail."""
  52. mock_settings = Mock()
  53. mock_settings.remote_reload_token = self.TEST_TOKEN
  54. with self.override_settings(client, mock_settings):
  55. response = client.post(
  56. "/api/v1/admin/refresh_remotes",
  57. headers={"Authorization": "Bearer invalid-token-xyz"}
  58. )
  59. assert response.status_code == status.HTTP_401_UNAUTHORIZED
  60. data = response.json()
  61. assert "detail" in data
  62. assert "Invalid authentication token" in data["detail"]
  63. def test_refresh_remotes_malformed_auth_header(self, client):
  64. """Test refresh with malformed authorization header."""
  65. mock_settings = Mock()
  66. mock_settings.remote_reload_token = self.TEST_TOKEN
  67. with self.override_settings(client, mock_settings):
  68. response = client.post(
  69. "/api/v1/admin/refresh_remotes",
  70. headers={"Authorization": "test-remote-reload-token-12345"}
  71. )
  72. assert response.status_code == status.HTTP_401_UNAUTHORIZED
  73. def test_refresh_remotes_empty_token(self, client):
  74. """Test refresh with empty token."""
  75. mock_settings = Mock()
  76. mock_settings.remote_reload_token = self.TEST_TOKEN
  77. with self.override_settings(client, mock_settings):
  78. response = client.post(
  79. "/api/v1/admin/refresh_remotes",
  80. headers={"Authorization": "Bearer "}
  81. )
  82. assert response.status_code == status.HTTP_401_UNAUTHORIZED
  83. def test_refresh_remotes_method_not_allowed(self, client):
  84. """Test that only POST method is allowed."""
  85. disallowed_methods = [
  86. ("GET", client.get),
  87. ("PUT", client.put),
  88. ("PATCH", client.patch),
  89. ("DELETE", client.delete),
  90. ]
  91. mock_settings = Mock()
  92. mock_settings.remote_reload_token = self.TEST_TOKEN
  93. with self.override_settings(client, mock_settings):
  94. for method_name, method_func in disallowed_methods:
  95. response = method_func(
  96. "/api/v1/admin/refresh_remotes",
  97. headers=self.AUTH_HEADERS
  98. )
  99. assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED, \
  100. f"{method_name} should return 405"