import gzip from collections.abc import Iterator import pytest from botocore.exceptions import ClientError from moto import mock_aws from infrastructure.s3.gzip_csv_s3_client import GzipCsvS3Client from tests.infrastructure import make_boto_client BUCKET = "gzip-csv-bucket" @pytest.fixture def gzip_client() -> Iterator[GzipCsvS3Client]: with mock_aws(): boto_client = make_boto_client("s3") boto_client.create_bucket(Bucket=BUCKET) yield GzipCsvS3Client(boto_client, BUCKET) def test_read_csv_gz_decodes_gzipped_csv_into_dataframe( gzip_client: GzipCsvS3Client, ) -> None: # arrange csv = "ADDRESS,UPRN\n47 GORDON ROAD,100\n48 GORDON ROAD,200\n" gzip_client.put_object("historical_epc/AB338AL/data.csv.gz", gzip.compress(csv.encode())) # act df = gzip_client.read_csv_gz("historical_epc/AB338AL/data.csv.gz") # assert assert list(df.columns) == ["ADDRESS", "UPRN"] assert df.shape == (2, 2) assert df["ADDRESS"].tolist() == ["47 GORDON ROAD", "48 GORDON ROAD"] def test_read_csv_gz_raises_no_such_key_when_object_missing( gzip_client: GzipCsvS3Client, ) -> None: # act / assert — a missing object surfaces as a ClientError; translating that # into a domain miss is the Repo's job, not the client's. with pytest.raises(ClientError) as exc_info: gzip_client.read_csv_gz("historical_epc/ZZ999ZZ/data.csv.gz") assert exc_info.value.response["Error"]["Code"] == "NoSuchKey"