from copy import deepcopy from pathlib import Path from typing import Any, Dict import sys import pytest from bson import ObjectId from fastapi.testclient import TestClient PROJECT_ROOT = Path(__file__).resolve().parents[1] if str(PROJECT_ROOT) not in sys.path: sys.path.append(str(PROJECT_ROOT)) from app.main import app class FakeInsertOneResult: def __init__(self, inserted_id): self.inserted_id = inserted_id class FakeCollection: def __init__(self): self._documents = [] async def find_one(self, query: Dict[str, Any]): for document in self._documents: if all(document.get(key) == value for key, value in query.items()): return deepcopy(document) return None async def insert_one(self, document: Dict[str, Any]): stored_document = deepcopy(document) stored_document.setdefault("_id", ObjectId()) self._documents.append(stored_document) return FakeInsertOneResult(stored_document["_id"]) async def create_index(self, *args, **kwargs): # pragma: no cover - behaviour not essential for tests return None @pytest.fixture def fake_collections(monkeypatch, tmp_path_factory): users_collection = FakeCollection() incidents_collection = FakeCollection() def get_collection(name: str): if name == "users": return users_collection if name == "incidents": return incidents_collection raise KeyError(name) async def get_users_collection(): return users_collection monkeypatch.setattr("app.database.get_collection", get_collection) monkeypatch.setattr("app.main.get_collection", get_collection) monkeypatch.setattr("app.services.users.get_collection", get_collection) monkeypatch.setattr("app.services.users.get_users_collection", get_users_collection) monkeypatch.setattr("app.services.incidents.get_collection", get_collection) upload_dir = tmp_path_factory.mktemp("uploads") monkeypatch.setattr("app.services.incidents.UPLOAD_DIR", upload_dir, raising=False) return { "users": users_collection, "incidents": incidents_collection, } @pytest.fixture def client(fake_collections): with TestClient(app) as client: yield client