"""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