|
| 1 | +import asyncio |
| 2 | +import unittest |
| 3 | + |
| 4 | +from core.storage import S3FileStorage |
| 5 | + |
| 6 | + |
| 7 | +class FakeS3Client: |
| 8 | + def __init__(self, list_response): |
| 9 | + self.list_response = list_response |
| 10 | + self.head_calls = 0 |
| 11 | + |
| 12 | + async def __aenter__(self): |
| 13 | + return self |
| 14 | + |
| 15 | + async def __aexit__(self, exc_type, exc, traceback): |
| 16 | + return False |
| 17 | + |
| 18 | + async def head_object(self, **kwargs): |
| 19 | + self.head_calls += 1 |
| 20 | + raise RuntimeError("head not supported") |
| 21 | + |
| 22 | + async def list_objects_v2(self, **kwargs): |
| 23 | + return self.list_response |
| 24 | + |
| 25 | + |
| 26 | +class S3FileExistsTests(unittest.TestCase): |
| 27 | + def test_file_exists_falls_back_to_list_objects(self): |
| 28 | + client = FakeS3Client({"Contents": [{"Key": "share/data/file.txt"}]}) |
| 29 | + storage = S3FileStorage.__new__(S3FileStorage) |
| 30 | + storage.bucket_name = "bucket" |
| 31 | + storage._client = lambda: client |
| 32 | + |
| 33 | + exists = asyncio.run(storage.file_exists("share/data/file.txt")) |
| 34 | + |
| 35 | + self.assertTrue(exists) |
| 36 | + self.assertEqual(client.head_calls, 3) |
| 37 | + |
| 38 | + def test_file_exists_returns_false_when_missing(self): |
| 39 | + client = FakeS3Client({"Contents": [{"Key": "share/data/other.txt"}]}) |
| 40 | + storage = S3FileStorage.__new__(S3FileStorage) |
| 41 | + storage.bucket_name = "bucket" |
| 42 | + storage._client = lambda: client |
| 43 | + |
| 44 | + exists = asyncio.run(storage.file_exists("share/data/file.txt")) |
| 45 | + |
| 46 | + self.assertFalse(exists) |
0 commit comments