Spaces:
Running
Running
File size: 3,987 Bytes
d411bd0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | """Crown Commend: who may post, and how requests are counted.
Runs on a small app holding only the Commend router, with YouTube stubbed.
"""
from __future__ import annotations
import importlib
from collections import defaultdict
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from app.routes.commend.router import router
commend_module = importlib.import_module("app.routes.commend.router")
URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
POST_BODY = {"videoUrl": URL, "commentText": "Nice one."}
@pytest.fixture
def client(monkeypatch):
monkeypatch.setattr(commend_module, "_rate_limit_store", defaultdict(list))
monkeypatch.setattr(commend_module, "get_video_details", lambda url: (None, "stubbed"))
app = FastAPI()
app.include_router(router)
return TestClient(app)
def configure(monkeypatch, *, key=None, require_auth=True, posting=True):
monkeypatch.setattr(commend_module, "_COMMEND_API_KEY", key)
monkeypatch.setattr(commend_module, "_COMMEND_REQUIRE_AUTH", require_auth)
monkeypatch.setattr(commend_module, "_COMMEND_POSTING_ENABLED", posting)
def test_posting_needs_a_key_even_when_auth_is_switched_off(client, monkeypatch) -> None:
configure(monkeypatch, key=None, require_auth=False, posting=True)
response = client.post("/api/commend/post", json=POST_BODY)
assert response.status_code == 401
assert response.json()["detail"]["code"] == "unauthorized"
def test_posting_rejects_a_wrong_key(client, monkeypatch) -> None:
configure(monkeypatch, key="secret-key", require_auth=False)
response = client.post("/api/commend/post", json=POST_BODY, headers={"X-API-Key": "nope"})
assert response.status_code == 401
def test_posting_with_the_key_reaches_the_posting_switch(client, monkeypatch) -> None:
configure(monkeypatch, key="secret-key", posting=False)
response = client.post("/api/commend/post", json=POST_BODY, headers={"X-API-Key": "secret-key"})
assert response.status_code == 403
assert response.json()["detail"]["code"] == "posting_disabled"
def test_posting_error_does_not_echo_the_provider_message(client, monkeypatch) -> None:
configure(monkeypatch, key="secret-key", posting=True)
monkeypatch.setattr(commend_module, "is_video_commented", lambda video_id: False)
monkeypatch.setattr(commend_module, "post_youtube_comment", lambda video_id, text: (None, "token=abc123 expired"))
response = client.post("/api/commend/post", json=POST_BODY, headers={"X-API-Key": "secret-key"})
assert response.status_code == 500
assert "abc123" not in response.text
def test_generate_stays_closed_when_auth_is_required_but_no_key_is_set(client, monkeypatch) -> None:
configure(monkeypatch, key=None, require_auth=True)
body = {"videoUrl": URL, "language": "English", "commentStyle": "supportive"}
assert client.post("/api/commend/generate", json=body).status_code == 503
def test_video_details_is_rate_limited(client, monkeypatch) -> None:
monkeypatch.setattr(commend_module, "_RATE_LIMIT_MAX", 2)
body = {"videoUrl": URL, "language": "English", "commentStyle": "supportive"}
codes = [client.post("/api/commend/video-details", json=body).status_code for _ in range(3)]
assert codes[:2] == [400, 400]
assert codes[2] == 429
def test_visitors_behind_the_proxy_are_counted_separately(client, monkeypatch) -> None:
monkeypatch.setattr(commend_module, "_RATE_LIMIT_MAX", 1)
body = {"videoUrl": URL, "language": "English", "commentStyle": "supportive"}
first = client.post("/api/commend/video-details", json=body, headers={"X-Forwarded-For": "203.0.113.1"})
second = client.post("/api/commend/video-details", json=body, headers={"X-Forwarded-For": "203.0.113.2"})
again = client.post("/api/commend/video-details", json=body, headers={"X-Forwarded-For": "203.0.113.1"})
assert first.status_code == 400
assert second.status_code == 400
assert again.status_code == 429
|