Coverage for tests / test_tutorial / test_path_operation_configurations / test_tutorial003_tutorial004.py: 100%
24 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
1import importlib 1abdc
2from textwrap import dedent 1abdc
4import pytest 1abdc
5from dirty_equals import IsList 1abdc
6from fastapi.testclient import TestClient 1abdc
7from inline_snapshot import Is, snapshot 1abdc
9from ...utils import needs_py310 1abdc
11DESCRIPTIONS = { 1abdc
12 "tutorial003": "Create an item with all the information, name, description, price, tax and a set of unique tags",
13 "tutorial004": dedent("""
14 Create an item with all the information:
16 - **name**: each item must have a name
17 - **description**: a long description
18 - **price**: required
19 - **tax**: if the item doesn't have tax, you can omit this
20 - **tags**: a set of unique tag strings for this item
21 """).strip(),
22}
25@pytest.fixture( 1abdc
26 name="mod_name",
27 params=[
28 pytest.param("tutorial003_py310", marks=needs_py310),
29 pytest.param("tutorial004_py310", marks=needs_py310),
30 ],
31)
32def get_mod_name(request: pytest.FixtureRequest) -> str: 1abdc
33 return request.param 1abc
36@pytest.fixture(name="client") 1abdc
37def get_client(mod_name: str) -> TestClient: 1abdc
38 mod = importlib.import_module(f"docs_src.path_operation_configuration.{mod_name}") 1abc
39 return TestClient(mod.app) 1abc
42def test_post_items(client: TestClient): 1abdc
43 response = client.post( 1hij
44 "/items/",
45 json={
46 "name": "Foo",
47 "description": "Item description",
48 "price": 42.0,
49 "tax": 3.2,
50 "tags": ["bar", "baz"],
51 },
52 )
53 assert response.status_code == 200, response.text 1hij
54 assert response.json() == { 1hij
55 "name": "Foo",
56 "description": "Item description",
57 "price": 42.0,
58 "tax": 3.2,
59 "tags": IsList("bar", "baz", check_order=False),
60 }
63def test_openapi_schema(client: TestClient, mod_name: str): 1abdc
64 mod_name = mod_name[:11] 1efg
66 response = client.get("/openapi.json") 1efg
67 assert response.status_code == 200, response.text 1efg
68 assert response.json() == snapshot( 1efg
69 {
70 "openapi": "3.1.0",
71 "info": {"title": "FastAPI", "version": "0.1.0"},
72 "paths": {
73 "/items/": {
74 "post": {
75 "summary": "Create an item",
76 "description": Is(DESCRIPTIONS[mod_name]),
77 "operationId": "create_item_items__post",
78 "requestBody": {
79 "content": {
80 "application/json": {
81 "schema": {"$ref": "#/components/schemas/Item"}
82 }
83 },
84 "required": True,
85 },
86 "responses": {
87 "200": {
88 "description": "Successful Response",
89 "content": {
90 "application/json": {
91 "schema": {"$ref": "#/components/schemas/Item"}
92 }
93 },
94 },
95 "422": {
96 "description": "Validation Error",
97 "content": {
98 "application/json": {
99 "schema": {
100 "$ref": "#/components/schemas/HTTPValidationError"
101 }
102 }
103 },
104 },
105 },
106 },
107 },
108 },
109 "components": {
110 "schemas": {
111 "HTTPValidationError": {
112 "properties": {
113 "detail": {
114 "items": {
115 "$ref": "#/components/schemas/ValidationError",
116 },
117 "title": "Detail",
118 "type": "array",
119 },
120 },
121 "title": "HTTPValidationError",
122 "type": "object",
123 },
124 "Item": {
125 "properties": {
126 "description": {
127 "anyOf": [
128 {
129 "type": "string",
130 },
131 {
132 "type": "null",
133 },
134 ],
135 "title": "Description",
136 },
137 "name": {
138 "title": "Name",
139 "type": "string",
140 },
141 "price": {
142 "title": "Price",
143 "type": "number",
144 },
145 "tags": {
146 "default": [],
147 "items": {
148 "type": "string",
149 },
150 "title": "Tags",
151 "type": "array",
152 "uniqueItems": True,
153 },
154 "tax": {
155 "anyOf": [
156 {
157 "type": "number",
158 },
159 {
160 "type": "null",
161 },
162 ],
163 "title": "Tax",
164 },
165 },
166 "required": [
167 "name",
168 "price",
169 ],
170 "title": "Item",
171 "type": "object",
172 },
173 "ValidationError": {
174 "properties": {
175 "ctx": {"title": "Context", "type": "object"},
176 "input": {"title": "Input"},
177 "loc": {
178 "items": {
179 "anyOf": [
180 {
181 "type": "string",
182 },
183 {
184 "type": "integer",
185 },
186 ],
187 },
188 "title": "Location",
189 "type": "array",
190 },
191 "msg": {
192 "title": "Message",
193 "type": "string",
194 },
195 "type": {
196 "title": "Error Type",
197 "type": "string",
198 },
199 },
200 "required": [
201 "loc",
202 "msg",
203 "type",
204 ],
205 "title": "ValidationError",
206 "type": "object",
207 },
208 },
209 },
210 }
211 )