Coverage for tests / test_additional_responses_union_duplicate_anyof.py: 100%
19 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-12 18:15 +0000
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-12 18:15 +0000
1"""
2Regression test: Ensure app-level responses with Union models and content/examples
3don't accumulate duplicate $ref entries in anyOf arrays.
4See https://github.com/fastapi/fastapi/pull/14463
5"""
7from typing import Union 1abcd
9from fastapi import FastAPI 1abcd
10from fastapi.testclient import TestClient 1abcd
11from inline_snapshot import snapshot 1abcd
12from pydantic import BaseModel 1abcd
15class ModelA(BaseModel): 1abcd
16 a: str 1abcd
19class ModelB(BaseModel): 1abcd
20 b: str 1abcd
23app = FastAPI( 1abcd
24 responses={
25 500: {
26 "model": Union[ModelA, ModelB],
27 "content": {"application/json": {"examples": {"Case A": {"value": "a"}}}},
28 }
29 }
30)
33@app.get("/route1") 1abcd
34async def route1(): 1abcd
35 pass # pragma: no cover
38@app.get("/route2") 1abcd
39async def route2(): 1abcd
40 pass # pragma: no cover
43client = TestClient(app) 1abcd
46def test_openapi_schema(): 1abcd
47 response = client.get("/openapi.json") 1efg
48 assert response.status_code == 200, response.text 1efg
49 assert response.json() == snapshot( 1efg
50 {
51 "openapi": "3.1.0",
52 "info": {"title": "FastAPI", "version": "0.1.0"},
53 "paths": {
54 "/route1": {
55 "get": {
56 "summary": "Route1",
57 "operationId": "route1_route1_get",
58 "responses": {
59 "200": {
60 "description": "Successful Response",
61 "content": {"application/json": {"schema": {}}},
62 },
63 "500": {
64 "description": "Internal Server Error",
65 "content": {
66 "application/json": {
67 "schema": {
68 "anyOf": [
69 {"$ref": "#/components/schemas/ModelA"},
70 {"$ref": "#/components/schemas/ModelB"},
71 ],
72 "title": "Response 500 Route1 Route1 Get",
73 },
74 "examples": {"Case A": {"value": "a"}},
75 }
76 },
77 },
78 },
79 }
80 },
81 "/route2": {
82 "get": {
83 "summary": "Route2",
84 "operationId": "route2_route2_get",
85 "responses": {
86 "200": {
87 "description": "Successful Response",
88 "content": {"application/json": {"schema": {}}},
89 },
90 "500": {
91 "description": "Internal Server Error",
92 "content": {
93 "application/json": {
94 "schema": {
95 "anyOf": [
96 {"$ref": "#/components/schemas/ModelA"},
97 {"$ref": "#/components/schemas/ModelB"},
98 ],
99 "title": "Response 500 Route2 Route2 Get",
100 },
101 "examples": {"Case A": {"value": "a"}},
102 }
103 },
104 },
105 },
106 }
107 },
108 },
109 "components": {
110 "schemas": {
111 "ModelA": {
112 "properties": {"a": {"type": "string", "title": "A"}},
113 "type": "object",
114 "required": ["a"],
115 "title": "ModelA",
116 },
117 "ModelB": {
118 "properties": {"b": {"type": "string", "title": "B"}},
119 "type": "object",
120 "required": ["b"],
121 "title": "ModelB",
122 },
123 }
124 },
125 }
126 )