ce8ba538b7
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
87 lines
3.1 KiB
Python
87 lines
3.1 KiB
Python
"""Unit tests for the Patreon campaign-ID resolver."""
|
|
import aiohttp
|
|
import pytest
|
|
from aioresponses import aioresponses
|
|
|
|
from app.services.patreon_resolver import resolve_campaign_id
|
|
|
|
|
|
CAMPAIGNS_URL = "https://www.patreon.com/api/campaigns?filter%5Bvanity%5D=mstsu&fields%5Bcampaign%5D=name"
|
|
|
|
|
|
async def test_happy_path_returns_campaign_id():
|
|
with aioresponses() as mock:
|
|
mock.get(
|
|
CAMPAIGNS_URL,
|
|
payload={"data": [{"id": "12345", "type": "campaign", "attributes": {"name": "MSTSU"}}]},
|
|
)
|
|
result = await resolve_campaign_id("mstsu", cookies_path=None)
|
|
assert result == "12345"
|
|
|
|
|
|
async def test_empty_data_returns_none():
|
|
with aioresponses() as mock:
|
|
mock.get(CAMPAIGNS_URL, payload={"data": []})
|
|
result = await resolve_campaign_id("mstsu", cookies_path=None)
|
|
assert result is None
|
|
|
|
|
|
async def test_missing_data_key_returns_none():
|
|
with aioresponses() as mock:
|
|
mock.get(CAMPAIGNS_URL, payload={"errors": [{"code": 1}]})
|
|
result = await resolve_campaign_id("mstsu", cookies_path=None)
|
|
assert result is None
|
|
|
|
|
|
async def test_missing_id_field_returns_none():
|
|
with aioresponses() as mock:
|
|
mock.get(CAMPAIGNS_URL, payload={"data": [{"type": "campaign"}]})
|
|
result = await resolve_campaign_id("mstsu", cookies_path=None)
|
|
assert result is None
|
|
|
|
|
|
async def test_http_401_returns_none():
|
|
with aioresponses() as mock:
|
|
mock.get(CAMPAIGNS_URL, status=401, body="Unauthorized")
|
|
result = await resolve_campaign_id("mstsu", cookies_path=None)
|
|
assert result is None
|
|
|
|
|
|
async def test_network_error_returns_none():
|
|
with aioresponses() as mock:
|
|
mock.get(CAMPAIGNS_URL, exception=aiohttp.ClientConnectionError("boom"))
|
|
result = await resolve_campaign_id("mstsu", cookies_path=None)
|
|
assert result is None
|
|
|
|
|
|
async def test_timeout_returns_none():
|
|
import asyncio
|
|
with aioresponses() as mock:
|
|
mock.get(CAMPAIGNS_URL, exception=asyncio.TimeoutError())
|
|
result = await resolve_campaign_id("mstsu", cookies_path=None)
|
|
assert result is None
|
|
|
|
|
|
async def test_invalid_json_returns_none():
|
|
with aioresponses() as mock:
|
|
mock.get(CAMPAIGNS_URL, body="<html>not json</html>", content_type="text/html")
|
|
result = await resolve_campaign_id("mstsu", cookies_path=None)
|
|
assert result is None
|
|
|
|
|
|
async def test_missing_cookies_path_proceeds_without_jar(tmp_path):
|
|
"""When cookies_path is None, the request still goes out (cookies are optional)."""
|
|
with aioresponses() as mock:
|
|
mock.get(CAMPAIGNS_URL, payload={"data": [{"id": "99", "type": "campaign"}]})
|
|
result = await resolve_campaign_id("mstsu", cookies_path=None)
|
|
assert result == "99"
|
|
|
|
|
|
async def test_nonexistent_cookies_path_proceeds_without_jar(tmp_path):
|
|
"""When cookies_path points to a missing file, don't crash — just skip the jar."""
|
|
ghost = tmp_path / "does-not-exist.txt"
|
|
with aioresponses() as mock:
|
|
mock.get(CAMPAIGNS_URL, payload={"data": [{"id": "99"}]})
|
|
result = await resolve_campaign_id("mstsu", cookies_path=str(ghost))
|
|
assert result == "99"
|