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