import logging from typing import Any from unittest import mock import pytest from starlette.applications import Starlette from starlette.middleware import Middleware from starlette.requests import Request from starlette.responses import PlainTextResponse from starlette.routing import Route from starlette.testclient import TestClient from audience_common.logger.asgi.middleware import RequestLoggerMiddleware @pytest.fixture def logger_mock() -> mock.MagicMock: return mock.MagicMock(spec=logging.Logger) @pytest.fixture def app(logger_mock: mock.MagicMock) -> Starlette: def endpoint_ok(request: Request) -> PlainTextResponse: return PlainTextResponse("ok") def endpoint_error(request: Request) -> Any: raise ValueError app = Starlette( middleware=[ Middleware( RequestLoggerMiddleware, exclude_paths=["/ignore"], logger=logger_mock, ), ], routes=[ Route("/ok", endpoint_ok), Route("/error", endpoint_error), Route("/ignore", endpoint_ok), ], ) return app @pytest.fixture def client(app: Starlette) -> TestClient: return TestClient(app, raise_server_exceptions=False) def test_log_response_ok(client: TestClient, logger_mock: mock.MagicMock) -> None: client.get("/ok") logger_mock.log.assert_called_once_with(logging.INFO, "200 - GET /ok", extra={}) def test_log_response_error(client: TestClient, logger_mock: mock.MagicMock) -> None: client.get("/error") logger_mock.log.assert_called_once_with(logging.ERROR, "500 - GET /error", extra={}) def test_log_response_ignore(client: TestClient, logger_mock: mock.MagicMock) -> None: client.get("/ignore") logger_mock.log.assert_not_called()