Coverage for tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial001_py39.py: 100%
48 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-09 00:02 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-09 00:02 +0000
1from dirty_equals import IsDict 1jefghi
2from fastapi.testclient import TestClient 1jefghi
3from sqlalchemy import inspect 1jefghi
4from sqlalchemy.engine.reflection import Inspector 1jefghi
5from sqlmodel import create_engine 1jefghi
6from sqlmodel.pool import StaticPool 1jefghi
8from ....conftest import needs_py39 1jefghi
11@needs_py39 1jefghi
12def test_tutorial(clear_sqlmodel): 1efghi
13 from docs_src.tutorial.fastapi.multiple_models import tutorial001_py39 as mod 1abcd
15 mod.sqlite_url = "sqlite://" 1abcd
16 mod.engine = create_engine( 1abcd
17 mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool
18 )
20 with TestClient(mod.app) as client: 1abcd
21 hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} 1abcd
22 hero2_data = { 1abcd
23 "name": "Spider-Boy",
24 "secret_name": "Pedro Parqueador",
25 "id": 9000,
26 }
27 response = client.post("/heroes/", json=hero1_data) 1abcd
28 data = response.json() 1abcd
30 assert response.status_code == 200, response.text 1abcd
31 assert data["name"] == hero1_data["name"] 1abcd
32 assert data["secret_name"] == hero1_data["secret_name"] 1abcd
33 assert data["id"] is not None 1abcd
34 assert data["age"] is None 1abcd
36 response = client.post("/heroes/", json=hero2_data) 1abcd
37 data = response.json() 1abcd
39 assert response.status_code == 200, response.text 1abcd
40 assert data["name"] == hero2_data["name"] 1abcd
41 assert data["secret_name"] == hero2_data["secret_name"] 1abcd
42 assert data["id"] != hero2_data["id"], ( 1abcd
43 "Now it's not possible to predefine the ID from the request, "
44 "it's now set by the database"
45 )
46 assert data["age"] is None 1abcd
48 response = client.get("/heroes/") 1abcd
49 data = response.json() 1abcd
51 assert response.status_code == 200, response.text 1abcd
52 assert len(data) == 2 1abcd
53 assert data[0]["name"] == hero1_data["name"] 1abcd
54 assert data[0]["secret_name"] == hero1_data["secret_name"] 1abcd
55 assert data[1]["name"] == hero2_data["name"] 1abcd
56 assert data[1]["secret_name"] == hero2_data["secret_name"] 1abcd
57 assert data[1]["id"] != hero2_data["id"] 1abcd
59 response = client.get("/openapi.json") 1abcd
61 assert response.status_code == 200, response.text 1abcd
63 assert response.json() == { 1abcd
64 "openapi": "3.1.0",
65 "info": {"title": "FastAPI", "version": "0.1.0"},
66 "paths": {
67 "/heroes/": {
68 "get": {
69 "summary": "Read Heroes",
70 "operationId": "read_heroes_heroes__get",
71 "responses": {
72 "200": {
73 "description": "Successful Response",
74 "content": {
75 "application/json": {
76 "schema": {
77 "title": "Response Read Heroes Heroes Get",
78 "type": "array",
79 "items": {
80 "$ref": "#/components/schemas/HeroPublic"
81 },
82 }
83 }
84 },
85 }
86 },
87 },
88 "post": {
89 "summary": "Create Hero",
90 "operationId": "create_hero_heroes__post",
91 "requestBody": {
92 "content": {
93 "application/json": {
94 "schema": {
95 "$ref": "#/components/schemas/HeroCreate"
96 }
97 }
98 },
99 "required": True,
100 },
101 "responses": {
102 "200": {
103 "description": "Successful Response",
104 "content": {
105 "application/json": {
106 "schema": {
107 "$ref": "#/components/schemas/HeroPublic"
108 }
109 }
110 },
111 },
112 "422": {
113 "description": "Validation Error",
114 "content": {
115 "application/json": {
116 "schema": {
117 "$ref": "#/components/schemas/HTTPValidationError"
118 }
119 }
120 },
121 },
122 },
123 },
124 }
125 },
126 "components": {
127 "schemas": {
128 "HTTPValidationError": {
129 "title": "HTTPValidationError",
130 "type": "object",
131 "properties": {
132 "detail": {
133 "title": "Detail",
134 "type": "array",
135 "items": {
136 "$ref": "#/components/schemas/ValidationError"
137 },
138 }
139 },
140 },
141 "HeroCreate": {
142 "title": "HeroCreate",
143 "required": ["name", "secret_name"],
144 "type": "object",
145 "properties": {
146 "name": {"title": "Name", "type": "string"},
147 "secret_name": {"title": "Secret Name", "type": "string"},
148 "age": IsDict(
149 {
150 "title": "Age",
151 "anyOf": [{"type": "integer"}, {"type": "null"}],
152 }
153 )
154 | IsDict(
155 # TODO: remove when deprecating Pydantic v1
156 {"title": "Age", "type": "integer"}
157 ),
158 },
159 },
160 "HeroPublic": {
161 "title": "HeroPublic",
162 "required": ["id", "name", "secret_name"],
163 "type": "object",
164 "properties": {
165 "id": {"title": "Id", "type": "integer"},
166 "name": {"title": "Name", "type": "string"},
167 "secret_name": {"title": "Secret Name", "type": "string"},
168 "age": IsDict(
169 {
170 "title": "Age",
171 "anyOf": [{"type": "integer"}, {"type": "null"}],
172 }
173 )
174 | IsDict(
175 # TODO: remove when deprecating Pydantic v1
176 {"title": "Age", "type": "integer"}
177 ),
178 },
179 },
180 "ValidationError": {
181 "title": "ValidationError",
182 "required": ["loc", "msg", "type"],
183 "type": "object",
184 "properties": {
185 "loc": {
186 "title": "Location",
187 "type": "array",
188 "items": {
189 "anyOf": [{"type": "string"}, {"type": "integer"}]
190 },
191 },
192 "msg": {"title": "Message", "type": "string"},
193 "type": {"title": "Error Type", "type": "string"},
194 },
195 },
196 }
197 },
198 }
200 # Test inherited indexes
201 insp: Inspector = inspect(mod.engine) 1abcd
202 indexes = insp.get_indexes(str(mod.Hero.__tablename__)) 1abcd
203 expected_indexes = [ 1abcd
204 {
205 "name": "ix_hero_name",
206 "dialect_options": {},
207 "column_names": ["name"],
208 "unique": 0,
209 },
210 {
211 "name": "ix_hero_age",
212 "dialect_options": {},
213 "column_names": ["age"],
214 "unique": 0,
215 },
216 ]
217 for index in expected_indexes: 1abcd
218 assert index in indexes, "This expected index should be in the indexes in DB" 1abcd
219 # Now that this index was checked, remove it from the list of indexes
220 indexes.pop(indexes.index(index)) 1abcd
221 assert len(indexes) == 0, "The database should only have the expected indexes" 1abcd