from typing import Any, Literal from unittest.mock import patch import pytest from fastapi.testclient import TestClient from pydantic import BaseModel from monday_com_orca_backend.api.main import app from monday_com_orca_backend.enums import HttpMethod @pytest.fixture(scope="module") def test_client(): """Create a test client for the FastAPI app with patched JWT token, so that we can test the API endpoints without needing a real JWT token. """ with patch("monday_com_orca_backend.api.auth.main.verify_token", return_value=None): with TestClient(app) as client: yield client def is_non_empty_list(data) -> bool: """Assert that the data is a non-empty list.""" return isinstance(data, list) and len(data) > 0 def assert_collection_response( response: dict[str, Any] | BaseModel, expect_empty: bool = False, expect_more: bool | None = None, # None to ignore the expectation ) -> Literal[True]: """Perform assertions on collection responses.""" response_content = response if isinstance(response, dict) else response.dict() response_data = response_content["data"] assert is_non_empty_list(response_data) is not expect_empty, ( "Expected a non-empty list in the response, " "but got an empty list" if expect_empty else "Expected an empty list, but got a non-empty list" ) if expect_more is not None: assert "more" in response_content, "'more' field is missing in the response" assert response_content["more"] is expect_more, ( f"Expected 'more' to be {expect_more}, " f"but got {response_content['more']}" ) return True @pytest.fixture def get_collection_response_data(test_client): def _inner( endpoint: str, *, method: HttpMethod | str = HttpMethod.GET, json: dict[str, Any] | None = None, expect_empty: bool = False, expect_more: bool | None = None, # None to ignore the expectation ) -> list: """Convenience fixture to fetch data from the endpoint and validate the response. Works only for endpoints that return a collection response. Args: endpoint: The API endpoint to fetch data from. expect_empty: If True, expect the response data to be an empty list. expect_more: If not None, expect the 'more' field in the response to match this value. """ func = getattr(test_client, method.lower()) if method.upper() == HttpMethod.POST.value.upper(): resp = func(endpoint, json=json) else: resp = func(endpoint) assert resp.status_code == 200 resp_content = resp.json() assert assert_collection_response( resp_content, expect_empty=expect_empty, expect_more=expect_more ) resp_data = resp_content["data"] return resp_data return _inner