| 9 | |
| 10 | from quantmind.preprocess.fetch.http import ( |
| 11 | FetchAttemptsExhausted, |
| 12 | FetchPolicy, |
| 13 | HttpFetcher, |
| 14 | fetch_url, |
| 15 | ) |
| 16 | |
| 17 | |
| 18 | class FetchUrlTests(unittest.IsolatedAsyncioTestCase): |
| 19 | async def test_returns_body_and_metadata(self): |
| 20 | with respx.mock(assert_all_called=True) as router: |
| 21 | router.get("https://example.com/data").mock( |
| 22 | return_value=httpx.Response( |
| 23 | 200, |
| 24 | headers={ |
| 25 | "Content-Type": "text/plain; charset=utf-8", |
| 26 | "ETag": "abc123", |
| 27 | "X-Ignored": "ignored", |
| 28 | }, |
| 29 | content=b"hello world", |
| 30 | ) |
| 31 | ) |
| 32 | result = await fetch_url("https://example.com/data") |
| 33 | |
| 34 | self.assertEqual(result.bytes, b"hello world") |
| 35 | self.assertEqual(result.content_type, "text/plain") |
| 36 | self.assertEqual(result.source_url, "https://example.com/data") |
| 37 | self.assertEqual(result.status_code, 200) |
| 38 | self.assertEqual(result.resolved_url, "https://example.com/data") |
| 39 | self.assertIsNotNone(result.fetched_at) |
| 40 | self.assertEqual(result.headers.get("etag"), "abc123") |
| 41 | self.assertNotIn("x-ignored", result.headers) |
| 42 | |
| 43 | async def test_default_user_agent_sent(self): |
| 44 | with respx.mock(assert_all_called=True) as router: |
| 45 | route = router.get("https://example.com").mock( |
| 46 | return_value=httpx.Response(200, content=b"") |
| 47 | ) |
| 48 | await fetch_url("https://example.com") |
| 49 | |
| 50 | sent_request = route.calls.last.request |
| 51 | self.assertIn("QuantMind", sent_request.headers["User-Agent"]) |
| 52 | |
| 53 | async def test_max_bytes_overflow_raises(self): |
| 54 | with respx.mock(assert_all_called=True) as router: |
| 55 | router.get("https://example.com").mock( |
| 56 | return_value=httpx.Response(200, content=b"x" * 50) |
| 57 | ) |
| 58 | with self.assertRaises(ValueError): |
| 59 | await fetch_url("https://example.com", max_bytes=10) |
| 60 | |
| 61 | async def test_http_error_propagates(self): |
| 62 | with respx.mock(assert_all_called=True) as router: |
| 63 | router.get("https://example.com").mock( |
| 64 | return_value=httpx.Response(404) |
| 65 | ) |
| 66 | with self.assertRaises(httpx.HTTPStatusError): |
| 67 | await fetch_url("https://example.com") |
| 68 |
nothing calls this directly
no outgoing calls
no test coverage detected