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