diff --git a/scripts/check_dev_routes.py b/scripts/check_dev_routes.py index 3ed4ca68..99190355 100644 --- a/scripts/check_dev_routes.py +++ b/scripts/check_dev_routes.py @@ -54,8 +54,16 @@ def check_routes(base_url, context=None, *, solution_templates_status=401): ("/api/token/", "POST", 400), ): status, content_type, body = request(base_url, path, method, context) - assert status == expected and content_type == "application/json", (method, path, status, content_type) - json.loads(body) + assert content_type == "application/json", (method, path, status, content_type) + payload = json.loads(body) + # Repeated DEV deploys share the password reset API's anonymous rate limit. + throttled = ( + path == "/auth/reset_password/" + and status == 429 + and isinstance(payload, dict) + and bool(payload.get("detail")) + ) + assert status == expected or throttled, (method, path, status, content_type) sys.stdout.write(f"API {method} OK: {path} ({status})\n") diff --git a/scripts/tests/test_dev_nginx_routes.py b/scripts/tests/test_dev_nginx_routes.py index e744733c..08c72375 100644 --- a/scripts/tests/test_dev_nginx_routes.py +++ b/scripts/tests/test_dev_nginx_routes.py @@ -12,11 +12,31 @@ from threading import Thread import time import unittest +from unittest.mock import patch sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from check_dev_routes import check_routes, request # noqa: E402 +class DevRoutingSmokeTests(unittest.TestCase): + def test_only_password_reset_can_report_a_rate_limit(self): + def response(_base, path, method="GET", context=None): + if path == "/": + return 200, "text/html", b"" + if "routing_check" in path: + return 200, "text/html", b"" if method == "HEAD" else b"" + if path == throttled_path: + return 429, "application/json", b'{"detail":"Request was throttled."}' + return (400 if method == "POST" else 401), "application/json", b"{}" + + with patch("check_dev_routes.request", side_effect=response): + throttled_path = "/auth/reset_password/" + check_routes("https://dev.procollab.ru") + throttled_path = "/api/token/" + with self.assertRaises(AssertionError): + check_routes("https://dev.procollab.ru") + + class Backend(BaseHTTPRequestHandler): def respond(self, status): body = json.dumps({"backend_method": self.command, "backend_path": self.path}).encode()