mirror of
https://github.com/mwisnowski/mtg_python_deckbuilder.git
synced 2025-12-17 08:00:13 +01:00
65 lines
2.1 KiB
Python
65 lines
2.1 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import os
|
||
|
|
import time
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
from fastapi.testclient import TestClient
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.fixture()
|
||
|
|
def throttle_client(monkeypatch):
|
||
|
|
monkeypatch.setenv("RANDOM_MODES", "1")
|
||
|
|
monkeypatch.setenv("RANDOM_UI", "1")
|
||
|
|
monkeypatch.setenv("CSV_FILES_DIR", os.path.join("csv_files", "testdata"))
|
||
|
|
|
||
|
|
import code.web.app as app_module
|
||
|
|
|
||
|
|
# Ensure feature flags and globals reflect the test configuration
|
||
|
|
app_module.RANDOM_MODES = True
|
||
|
|
app_module.RANDOM_UI = True
|
||
|
|
app_module.RATE_LIMIT_ENABLED = False
|
||
|
|
|
||
|
|
# Keep existing values so we can restore after the test
|
||
|
|
prev_ms = app_module.RANDOM_REROLL_THROTTLE_MS
|
||
|
|
prev_seconds = app_module._REROLL_THROTTLE_SECONDS
|
||
|
|
|
||
|
|
app_module.RANDOM_REROLL_THROTTLE_MS = 50
|
||
|
|
app_module._REROLL_THROTTLE_SECONDS = 0.05
|
||
|
|
|
||
|
|
app_module._RL_COUNTS.clear()
|
||
|
|
|
||
|
|
with TestClient(app_module.app) as client:
|
||
|
|
yield client, app_module
|
||
|
|
|
||
|
|
# Restore globals for other tests
|
||
|
|
app_module.RANDOM_REROLL_THROTTLE_MS = prev_ms
|
||
|
|
app_module._REROLL_THROTTLE_SECONDS = prev_seconds
|
||
|
|
app_module._RL_COUNTS.clear()
|
||
|
|
|
||
|
|
|
||
|
|
def test_random_reroll_session_throttle(throttle_client):
|
||
|
|
client, app_module = throttle_client
|
||
|
|
|
||
|
|
# First reroll succeeds and seeds the session timestamp
|
||
|
|
first = client.post("/api/random_reroll", json={"seed": 5000})
|
||
|
|
assert first.status_code == 200, first.text
|
||
|
|
assert "sid" in client.cookies
|
||
|
|
|
||
|
|
# Immediate follow-up should hit the throttle guard
|
||
|
|
second = client.post("/api/random_reroll", json={"seed": 5001})
|
||
|
|
assert second.status_code == 429
|
||
|
|
retry_after = second.headers.get("Retry-After")
|
||
|
|
assert retry_after is not None
|
||
|
|
assert int(retry_after) >= 1
|
||
|
|
|
||
|
|
# After waiting slightly longer than the throttle window, requests succeed again
|
||
|
|
time.sleep(0.06)
|
||
|
|
third = client.post("/api/random_reroll", json={"seed": 5002})
|
||
|
|
assert third.status_code == 200, third.text
|
||
|
|
assert int(third.json().get("seed")) >= 5002
|
||
|
|
|
||
|
|
# Telemetry shouldn't record fallback for the throttle rejection
|
||
|
|
metrics_snapshot = app_module._RANDOM_METRICS.get("reroll")
|
||
|
|
assert metrics_snapshot is not None
|
||
|
|
assert metrics_snapshot.get("error", 0) == 0
|