Coverage for tests/test_tutorial/test_body_fields/test_tutorial001.py: 100%
26 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-01-13 13:38 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-01-13 13:38 +0000
1import importlib 1abcde
3import pytest 1abcde
4from dirty_equals import IsDict 1abcde
5from fastapi.testclient import TestClient 1abcde
7from ...utils import needs_py39, needs_py310 1abcde
10@pytest.fixture( 1abcde
11 name="client",
12 params=[
13 "tutorial001",
14 pytest.param("tutorial001_py310", marks=needs_py310),
15 "tutorial001_an",
16 pytest.param("tutorial001_an_py39", marks=needs_py39),
17 pytest.param("tutorial001_an_py310", marks=needs_py310),
18 ],
19)
20def get_client(request: pytest.FixtureRequest): 1abcde
21 mod = importlib.import_module(f"docs_src.body_fields.{request.param}") 1abcde
23 client = TestClient(mod.app) 1abcde
24 return client 1abcde
27def test_items_5(client: TestClient): 1abcde
28 response = client.put("/items/5", json={"item": {"name": "Foo", "price": 3.0}}) 1fghij
29 assert response.status_code == 200 1fghij
30 assert response.json() == { 1fghij
31 "item_id": 5,
32 "item": {"name": "Foo", "price": 3.0, "description": None, "tax": None},
33 }
36def test_items_6(client: TestClient): 1abcde
37 response = client.put( 1klmno
38 "/items/6",
39 json={
40 "item": {
41 "name": "Bar",
42 "price": 0.2,
43 "description": "Some bar",
44 "tax": "5.4",
45 }
46 },
47 )
48 assert response.status_code == 200 1klmno
49 assert response.json() == { 1klmno
50 "item_id": 6,
51 "item": {
52 "name": "Bar",
53 "price": 0.2,
54 "description": "Some bar",
55 "tax": 5.4,
56 },
57 }
60def test_invalid_price(client: TestClient): 1abcde
61 response = client.put("/items/5", json={"item": {"name": "Foo", "price": -3.0}}) 1pqrst
62 assert response.status_code == 422 1pqrst
63 assert response.json() == IsDict( 1pqrst
64 {
65 "detail": [
66 {
67 "type": "greater_than",
68 "loc": ["body", "item", "price"],
69 "msg": "Input should be greater than 0",
70 "input": -3.0,
71 "ctx": {"gt": 0.0},
72 }
73 ]
74 }
75 ) | IsDict(
76 # TODO: remove when deprecating Pydantic v1
77 {
78 "detail": [
79 {
80 "ctx": {"limit_value": 0},
81 "loc": ["body", "item", "price"],
82 "msg": "ensure this value is greater than 0",
83 "type": "value_error.number.not_gt",
84 }
85 ]
86 }
87 )
90def test_openapi_schema(client: TestClient): 1abcde
91 response = client.get("/openapi.json") 1uvwxy
92 assert response.status_code == 200, response.text 1uvwxy
93 assert response.json() == { 1uvwxy
94 "openapi": "3.1.0",
95 "info": {"title": "FastAPI", "version": "0.1.0"},
96 "paths": {
97 "/items/{item_id}": {
98 "put": {
99 "responses": {
100 "200": {
101 "description": "Successful Response",
102 "content": {"application/json": {"schema": {}}},
103 },
104 "422": {
105 "description": "Validation Error",
106 "content": {
107 "application/json": {
108 "schema": {
109 "$ref": "#/components/schemas/HTTPValidationError"
110 }
111 }
112 },
113 },
114 },
115 "summary": "Update Item",
116 "operationId": "update_item_items__item_id__put",
117 "parameters": [
118 {
119 "required": True,
120 "schema": {"title": "Item Id", "type": "integer"},
121 "name": "item_id",
122 "in": "path",
123 }
124 ],
125 "requestBody": {
126 "content": {
127 "application/json": {
128 "schema": {
129 "$ref": "#/components/schemas/Body_update_item_items__item_id__put"
130 }
131 }
132 },
133 "required": True,
134 },
135 }
136 }
137 },
138 "components": {
139 "schemas": {
140 "Item": {
141 "title": "Item",
142 "required": ["name", "price"],
143 "type": "object",
144 "properties": {
145 "name": {"title": "Name", "type": "string"},
146 "description": IsDict(
147 {
148 "title": "The description of the item",
149 "anyOf": [
150 {"maxLength": 300, "type": "string"},
151 {"type": "null"},
152 ],
153 }
154 )
155 | IsDict(
156 # TODO: remove when deprecating Pydantic v1
157 {
158 "title": "The description of the item",
159 "maxLength": 300,
160 "type": "string",
161 }
162 ),
163 "price": {
164 "title": "Price",
165 "exclusiveMinimum": 0.0,
166 "type": "number",
167 "description": "The price must be greater than zero",
168 },
169 "tax": IsDict(
170 {
171 "title": "Tax",
172 "anyOf": [{"type": "number"}, {"type": "null"}],
173 }
174 )
175 | IsDict(
176 # TODO: remove when deprecating Pydantic v1
177 {"title": "Tax", "type": "number"}
178 ),
179 },
180 },
181 "Body_update_item_items__item_id__put": {
182 "title": "Body_update_item_items__item_id__put",
183 "required": ["item"],
184 "type": "object",
185 "properties": {"item": {"$ref": "#/components/schemas/Item"}},
186 },
187 "ValidationError": {
188 "title": "ValidationError",
189 "required": ["loc", "msg", "type"],
190 "type": "object",
191 "properties": {
192 "loc": {
193 "title": "Location",
194 "type": "array",
195 "items": {
196 "anyOf": [{"type": "string"}, {"type": "integer"}]
197 },
198 },
199 "msg": {"title": "Message", "type": "string"},
200 "type": {"title": "Error Type", "type": "string"},
201 },
202 },
203 "HTTPValidationError": {
204 "title": "HTTPValidationError",
205 "type": "object",
206 "properties": {
207 "detail": {
208 "title": "Detail",
209 "type": "array",
210 "items": {"$ref": "#/components/schemas/ValidationError"},
211 }
212 },
213 },
214 }
215 },
216 }