1import importlib 2from pathlib import Path 3 4import pytest 5from fastapi.testclient import TestClient 6 7openapi_schema = { 8 "openapi": "3.0.2", 9 "info": {"title": "FastAPI", "version": "0.1.0"}, 10 "paths": { 11 "/users/": { 12 "get": { 13 "responses": { 14 "200": { 15 "description": "Successful Response", 16 "content": { 17 "application/json": { 18 "schema": { 19 "title": "Response Read Users Users Get", 20 "type": "array", 21 "items": {"$ref": "#/components/schemas/User"}, 22 } 23 } 24 }, 25 }, 26 "422": { 27 "description": "Validation Error", 28 "content": { 29 "application/json": { 30 "schema": { 31 "$ref": "#/components/schemas/HTTPValidationError" 32 } 33 } 34 }, 35 }, 36 }, 37 "summary": "Read Users", 38 "operationId": "read_users_users__get", 39 "parameters": [ 40 { 41 "required": False, 42 "schema": {"title": "Skip", "type": "integer", "default": 0}, 43 "name": "skip", 44 "in": "query", 45 }, 46 { 47 "required": False, 48 "schema": {"title": "Limit", "type": "integer", "default": 100}, 49 "name": "limit", 50 "in": "query", 51 }, 52 ], 53 }, 54 "post": { 55 "responses": { 56 "200": { 57 "description": "Successful Response", 58 "content": { 59 "application/json": { 60 "schema": {"$ref": "#/components/schemas/User"} 61 } 62 }, 63 }, 64 "422": { 65 "description": "Validation Error", 66 "content": { 67 "application/json": { 68 "schema": { 69 "$ref": "#/components/schemas/HTTPValidationError" 70 } 71 } 72 }, 73 }, 74 }, 75 "summary": "Create User", 76 "operationId": "create_user_users__post", 77 "requestBody": { 78 "content": { 79 "application/json": { 80 "schema": {"$ref": "#/components/schemas/UserCreate"} 81 } 82 }, 83 "required": True, 84 }, 85 }, 86 }, 87 "/users/{user_id}": { 88 "get": { 89 "responses": { 90 "200": { 91 "description": "Successful Response", 92 "content": { 93 "application/json": { 94 "schema": {"$ref": "#/components/schemas/User"} 95 } 96 }, 97 }, 98 "422": { 99 "description": "Validation Error", 100 "content": { 101 "application/json": { 102 "schema": { 103 "$ref": "#/components/schemas/HTTPValidationError" 104 } 105 } 106 }, 107 }, 108 }, 109 "summary": "Read User", 110 "operationId": "read_user_users__user_id__get", 111 "parameters": [ 112 { 113 "required": True, 114 "schema": {"title": "User Id", "type": "integer"}, 115 "name": "user_id", 116 "in": "path", 117 } 118 ], 119 } 120 }, 121 "/users/{user_id}/items/": { 122 "post": { 123 "responses": { 124 "200": { 125 "description": "Successful Response", 126 "content": { 127 "application/json": { 128 "schema": {"$ref": "#/components/schemas/Item"} 129 } 130 }, 131 }, 132 "422": { 133 "description": "Validation Error", 134 "content": { 135 "application/json": { 136 "schema": { 137 "$ref": "#/components/schemas/HTTPValidationError" 138 } 139 } 140 }, 141 }, 142 }, 143 "summary": "Create Item For User", 144 "operationId": "create_item_for_user_users__user_id__items__post", 145 "parameters": [ 146 { 147 "required": True, 148 "schema": {"title": "User Id", "type": "integer"}, 149 "name": "user_id", 150 "in": "path", 151 } 152 ], 153 "requestBody": { 154 "content": { 155 "application/json": { 156 "schema": {"$ref": "#/components/schemas/ItemCreate"} 157 } 158 }, 159 "required": True, 160 }, 161 } 162 }, 163 "/items/": { 164 "get": { 165 "responses": { 166 "200": { 167 "description": "Successful Response", 168 "content": { 169 "application/json": { 170 "schema": { 171 "title": "Response Read Items Items Get", 172 "type": "array", 173 "items": {"$ref": "#/components/schemas/Item"}, 174 } 175 } 176 }, 177 }, 178 "422": { 179 "description": "Validation Error", 180 "content": { 181 "application/json": { 182 "schema": { 183 "$ref": "#/components/schemas/HTTPValidationError" 184 } 185 } 186 }, 187 }, 188 }, 189 "summary": "Read Items", 190 "operationId": "read_items_items__get", 191 "parameters": [ 192 { 193 "required": False, 194 "schema": {"title": "Skip", "type": "integer", "default": 0}, 195 "name": "skip", 196 "in": "query", 197 }, 198 { 199 "required": False, 200 "schema": {"title": "Limit", "type": "integer", "default": 100}, 201 "name": "limit", 202 "in": "query", 203 }, 204 ], 205 } 206 }, 207 }, 208 "components": { 209 "schemas": { 210 "ItemCreate": { 211 "title": "ItemCreate", 212 "required": ["title"], 213 "type": "object", 214 "properties": { 215 "title": {"title": "Title", "type": "string"}, 216 "description": {"title": "Description", "type": "string"}, 217 }, 218 }, 219 "Item": { 220 "title": "Item", 221 "required": ["title", "id", "owner_id"], 222 "type": "object", 223 "properties": { 224 "title": {"title": "Title", "type": "string"}, 225 "description": {"title": "Description", "type": "string"}, 226 "id": {"title": "Id", "type": "integer"}, 227 "owner_id": {"title": "Owner Id", "type": "integer"}, 228 }, 229 }, 230 "User": { 231 "title": "User", 232 "required": ["email", "id", "is_active"], 233 "type": "object", 234 "properties": { 235 "email": {"title": "Email", "type": "string"}, 236 "id": {"title": "Id", "type": "integer"}, 237 "is_active": {"title": "Is Active", "type": "boolean"}, 238 "items": { 239 "title": "Items", 240 "type": "array", 241 "items": {"$ref": "#/components/schemas/Item"}, 242 "default": [], 243 }, 244 }, 245 }, 246 "UserCreate": { 247 "title": "UserCreate", 248 "required": ["email", "password"], 249 "type": "object", 250 "properties": { 251 "email": {"title": "Email", "type": "string"}, 252 "password": {"title": "Password", "type": "string"}, 253 }, 254 }, 255 "ValidationError": { 256 "title": "ValidationError", 257 "required": ["loc", "msg", "type"], 258 "type": "object", 259 "properties": { 260 "loc": { 261 "title": "Location", 262 "type": "array", 263 "items": {"type": "string"}, 264 }, 265 "msg": {"title": "Message", "type": "string"}, 266 "type": {"title": "Error Type", "type": "string"}, 267 }, 268 }, 269 "HTTPValidationError": { 270 "title": "HTTPValidationError", 271 "type": "object", 272 "properties": { 273 "detail": { 274 "title": "Detail", 275 "type": "array", 276 "items": {"$ref": "#/components/schemas/ValidationError"}, 277 } 278 }, 279 }, 280 } 281 }, 282} 283 284 285@pytest.fixture(scope="module") 286def client(): 287 test_db = Path("./sql_app.db") 288 if test_db.is_file(): # pragma: nocover 289 test_db.unlink() 290 # Import while creating the client to create the DB after starting the test session 291 from docs_src.sql_databases.sql_app import alt_main 292 293 # Ensure import side effects are re-executed 294 importlib.reload(alt_main) 295 296 with TestClient(alt_main.app) as c: 297 yield c 298 if test_db.is_file(): # pragma: nocover 299 test_db.unlink() 300 301 302def test_openapi_schema(client): 303 response = client.get("/openapi.json") 304 assert response.status_code == 200, response.text 305 assert response.json() == openapi_schema 306 307 308def test_create_user(client): 309 test_user = {"email": "johndoe@example.com", "password": "secret"} 310 response = client.post("/users/", json=test_user) 311 assert response.status_code == 200, response.text 312 data = response.json() 313 assert test_user["email"] == data["email"] 314 assert "id" in data 315 response = client.post("/users/", json=test_user) 316 assert response.status_code == 400, response.text 317 318 319def test_get_user(client): 320 response = client.get("/users/1") 321 assert response.status_code == 200, response.text 322 data = response.json() 323 assert "email" in data 324 assert "id" in data 325 326 327def test_inexistent_user(client): 328 response = client.get("/users/999") 329 assert response.status_code == 404, response.text 330 331 332def test_get_users(client): 333 response = client.get("/users/") 334 assert response.status_code == 200, response.text 335 data = response.json() 336 assert "email" in data[0] 337 assert "id" in data[0] 338 339 340def test_create_item(client): 341 item = {"title": "Foo", "description": "Something that fights"} 342 response = client.post("/users/1/items/", json=item) 343 assert response.status_code == 200, response.text 344 item_data = response.json() 345 assert item["title"] == item_data["title"] 346 assert item["description"] == item_data["description"] 347 assert "id" in item_data 348 assert "owner_id" in item_data 349 response = client.get("/users/1") 350 assert response.status_code == 200, response.text 351 user_data = response.json() 352 item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0] 353 assert item_to_check["title"] == item["title"] 354 assert item_to_check["description"] == item["description"] 355 response = client.get("/users/1") 356 assert response.status_code == 200, response.text 357 user_data = response.json() 358 item_to_check = [it for it in user_data["items"] if it["id"] == item_data["id"]][0] 359 assert item_to_check["title"] == item["title"] 360 assert item_to_check["description"] == item["description"] 361 362 363def test_read_items(client): 364 response = client.get("/items/") 365 assert response.status_code == 200, response.text 366 data = response.json() 367 assert data 368 first_item = data[0] 369 assert "title" in first_item 370 assert "description" in first_item 371