from typing import Any import pytest from fastapi import FastAPI, Query from starlette import status from starlette.middleware import Middleware from starlette.testclient import TestClient from fansifter_common.api.middleware.query_string import QueryStringFlatteningMiddleware @pytest.fixture(scope="session") def app() -> FastAPI: app = FastAPI( middleware=[ Middleware(QueryStringFlatteningMiddleware, skip_keys=["orderBy"]), ] ) @app.get("/test") def endpoint_test(ids: list[int] | None = Query(None)) -> Any: return {"ids": ids} @app.get("/test-skipped") def endpoint_test_skipped( order_by: str | None = Query(None, alias="orderBy"), ) -> Any: return {"order_by": order_by} return app @pytest.fixture(scope="session") def client(app: FastAPI) -> TestClient: return TestClient(app) @pytest.mark.parametrize( "params, expected", [ (None, None), ({}, None), ({"ids": None}, None), ({"ids": ""}, None), ({"ids": " "}, None), ({"ids": "1,2,3"}, [1, 2, 3]), ({"ids": ["1", "2"]}, [1, 2]), ], ) def test_query_string_flattening( params: Any, expected: list[int] | None, client: TestClient ) -> None: response = client.get("/test", params=params) assert response.status_code == status.HTTP_200_OK assert response.json() == {"ids": expected} @pytest.mark.parametrize( "params, expected", [ (None, None), ({}, None), ({"orderBy": None}, ""), ({"orderBy": ""}, ""), ({"orderBy": " "}, ""), ({"orderBy": "name,age"}, "name,age"), ], ) def test_query_string_flattening_skipped( params: Any, expected: list[int] | None, client: TestClient ) -> None: response = client.get("/test-skipped", params=params) assert response.status_code == status.HTTP_200_OK assert response.json() == {"order_by": expected}