from unittest.mock import MagicMock, patch import pytest from backend.app.services.patreon_resolver import resolve_campaign_id @pytest.mark.asyncio async def test_resolves_on_happy_path(): fake_response = MagicMock() fake_response.status_code = 200 fake_response.json.return_value = {"data": [{"id": "12345678", "type": "campaign"}]} with patch("backend.app.services.patreon_resolver.requests.get", return_value=fake_response): result = await resolve_campaign_id("alice", cookies_path=None) assert result == "12345678" @pytest.mark.asyncio async def test_returns_none_on_401(): fake_response = MagicMock() fake_response.status_code = 401 fake_response.json.return_value = {} with patch("backend.app.services.patreon_resolver.requests.get", return_value=fake_response): result = await resolve_campaign_id("alice", cookies_path=None) assert result is None @pytest.mark.asyncio async def test_returns_none_on_network_error(): import requests with patch( "backend.app.services.patreon_resolver.requests.get", side_effect=requests.ConnectionError("nope"), ): result = await resolve_campaign_id("alice", cookies_path=None) assert result is None @pytest.mark.asyncio async def test_returns_none_on_empty_data(): fake_response = MagicMock() fake_response.status_code = 200 fake_response.json.return_value = {"data": []} with patch("backend.app.services.patreon_resolver.requests.get", return_value=fake_response): result = await resolve_campaign_id("alice", cookies_path=None) assert result is None @pytest.mark.asyncio async def test_returns_none_on_malformed_json(): fake_response = MagicMock() fake_response.status_code = 200 fake_response.json.side_effect = ValueError("not json") with patch("backend.app.services.patreon_resolver.requests.get", return_value=fake_response): result = await resolve_campaign_id("alice", cookies_path=None) assert result is None @pytest.mark.asyncio async def test_missing_cookies_file_does_not_raise(tmp_path): fake_response = MagicMock() fake_response.status_code = 200 fake_response.json.return_value = {"data": [{"id": "1", "type": "campaign"}]} with patch("backend.app.services.patreon_resolver.requests.get", return_value=fake_response): result = await resolve_campaign_id( "alice", cookies_path=str(tmp_path / "does-not-exist.txt") ) assert result == "1" @pytest.mark.asyncio async def test_loads_cookies_file_when_present(tmp_path): cookies = tmp_path / "cookies.txt" cookies.write_text( "# Netscape HTTP Cookie File\n" ".patreon.com\tTRUE\t/\tTRUE\t1700000000\tsession_id\tabc\n" ) fake_response = MagicMock() fake_response.status_code = 200 fake_response.json.return_value = {"data": [{"id": "9", "type": "campaign"}]} with patch( "backend.app.services.patreon_resolver.requests.get", return_value=fake_response, ) as mock_get: result = await resolve_campaign_id("alice", cookies_path=str(cookies)) assert result == "9" _, kwargs = mock_get.call_args assert kwargs.get("cookies") is not None