from __future__ import annotations import asyncio from types import SimpleNamespace from uuid import uuid4 from app.models import Project from app.services.dataset_service import DatasetService class FakeUploadFile: filename = "real-orthophoto.tif" content_type = "image/tiff" async def read(self) -> bytes: return b"fake-raster" class FakeSession: def __init__(self, project_id): self.project_id = project_id self.added = [] def get(self, model, item_id): if model is Project and item_id == self.project_id: return SimpleNamespace(id=item_id) return None def add(self, item): self.added.append(item) def commit(self): return None def refresh(self, _item): return None def test_raster_upload_maps_metadata_bounds_resolution_and_bands(monkeypatch) -> None: project_id = uuid4() db = FakeSession(project_id) monkeypatch.setattr( "app.services.dataset_service.StorageService.persist_dataset_file", lambda **_: { "storage_path": "/tmp/real-orthophoto.tif", "original_filename": "real-orthophoto.tif", "stored_filename": "real-orthophoto.tif", "content_type": "image/tiff", "size_bytes": 11, "checksum_sha256": "checksum", }, ) monkeypatch.setattr( "app.services.dataset_service.extract_raster_metadata", lambda _path: { "driver": "GTiff", "crs": "EPSG:31370", "bounds": [193277.5, 205708.2, 193777.5, 206208.2], "resolution": [0.9765625, 0.9765625], "dtype": ["uint8", "uint8", "uint8"], }, ) response = asyncio.run( DatasetService.upload_dataset( db=db, project_id=project_id, file=FakeUploadFile(), dataset_type="raster", source="user_upload", ) ) assert response.status == "ready" assert response.crs == "EPSG:31370" assert response.bounds_json == { "minx": 193277.5, "miny": 205708.2, "maxx": 193777.5, "maxy": 206208.2, } assert db.added[0].bounds_json == response.bounds_json assert db.added[0].resolution_json == {"x": 0.9765625, "y": 0.9765625} assert db.added[0].bands_json == {"dtype": ["uint8", "uint8", "uint8"]}