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()