"""Smoke tests for openapi_first.binder.""" import types import pytest from fastapi import FastAPI from openapi_first.binder import bind_routes from openapi_first.errors import MissingOperationHandler def _routes_module(): module = types.ModuleType("smoke_routes") def get_health(): return {"status": "ok"} module.get_health = get_health return module def test_bind_routes_registers_matching_routes(minimal_spec): from fastapi.routing import APIRoute app = FastAPI() bind_routes(app, minimal_spec, _routes_module()) bound = [r for r in app.router.routes if isinstance(r, APIRoute)] assert len(bound) == 1 assert bound[0].name == "get_health" assert bound[0].path == "/health" assert "GET" in bound[0].methods def test_bind_routes_missing_handler(minimal_spec): app = FastAPI() module = types.ModuleType("empty_routes") with pytest.raises(MissingOperationHandler): bind_routes(app, minimal_spec, module) def test_bind_routes_missing_operation_id(spec_file): spec = { "openapi": "3.0.3", "info": {"title": "No OpId", "version": "1.0.0"}, "paths": {"/health": {"get": {"responses": {"200": {"description": "OK"}}}}}, } app = FastAPI() with pytest.raises(MissingOperationHandler): bind_routes(app, spec, _routes_module()) def test_bind_routes_ignores_spec_only_paths(): from fastapi.routing import APIRoute spec = { "openapi": "3.0.3", "info": {"title": "Path Item", "version": "1.0.0"}, "paths": { "/health": { "parameters": [{"name": "x-trace", "in": "header"}], "get": { "operationId": "get_health", "responses": {"200": {"description": "OK"}}, }, } }, } app = FastAPI() bind_routes(app, spec, _routes_module()) bound = [r for r in app.router.routes if isinstance(r, APIRoute)] assert len(bound) == 1 assert bound[0].name == "get_health"