tests/test_tutorial/test_sql_databases/test_tutorial002.py PYTHON 442 lines View on github.com → Search inside
1import importlib2import warnings3from typing import Any, cast45import pytest6from dirty_equals import IsInt7from fastapi.testclient import TestClient8from inline_snapshot import Is, snapshot9from sqlalchemy import StaticPool10from sqlmodel import SQLModel, create_engine11from sqlmodel.main import default_registry1213from tests.utils import needs_py310141516def clear_sqlmodel():17    # Clear the tables in the metadata for the default base model18    SQLModel.metadata.clear()19    # Clear the Models associated with the registry, to avoid warnings20    default_registry.dispose()212223@pytest.fixture(24    name="client",25    params=[26        pytest.param("tutorial002_py310", marks=needs_py310),27        pytest.param("tutorial002_an_py310", marks=needs_py310),28    ],29    scope="module",30)31def get_client(request: pytest.FixtureRequest):32    clear_sqlmodel()33    # TODO: remove when updating SQL tutorial to use new lifespan API34    with warnings.catch_warnings(record=True):35        warnings.simplefilter("always")36        mod = importlib.import_module(f"docs_src.sql_databases.{request.param}")37        clear_sqlmodel()38        importlib.reload(mod)39    mod_any = cast(Any, mod)40    mod_any.sqlite_url = "sqlite://"41    mod_any.engine = create_engine(42        mod_any.sqlite_url,43        connect_args={"check_same_thread": False},44        poolclass=StaticPool,45    )4647    with TestClient(mod_any.app) as c:48        yield c49    # Clean up connection explicitly to avoid resource warning50    mod_any.engine.dispose()515253def test_crud_app(client: TestClient):54    # TODO: this warns that SQLModel.from_orm is deprecated in Pydantic v1, refactor55    # this if using obj.model_validate becomes independent of Pydantic v256    with warnings.catch_warnings(record=True):57        warnings.simplefilter("always")58        # No heroes before creating59        response = client.get("heroes/")60        assert response.status_code == 200, response.text61        assert response.json() == []6263        # Create a hero64        response = client.post(65            "/heroes/",66            json={67                "id": 9000,68                "name": "Dead Pond",69                "age": 30,70                "secret_name": "Dive Wilson",71            },72        )73        assert response.status_code == 200, response.text74        assert response.json() == snapshot(75            {"age": 30, "id": IsInt(), "name": "Dead Pond"}76        )77        assert response.json()["id"] != 9000, (78            "The ID should be generated by the database"79        )8081        # Read a hero82        hero_id = response.json()["id"]83        response = client.get(f"/heroes/{hero_id}")84        assert response.status_code == 200, response.text85        assert response.json() == snapshot(86            {"name": "Dead Pond", "age": 30, "id": IsInt()}87        )8889        # Read all heroes90        # Create more heroes first91        response = client.post(92            "/heroes/",93            json={"name": "Spider-Boy", "age": 18, "secret_name": "Pedro Parqueador"},94        )95        assert response.status_code == 200, response.text96        response = client.post(97            "/heroes/", json={"name": "Rusty-Man", "secret_name": "Tommy Sharp"}98        )99        assert response.status_code == 200, response.text100101        response = client.get("/heroes/")102        assert response.status_code == 200, response.text103        assert response.json() == snapshot(104            [105                {"name": "Dead Pond", "age": 30, "id": IsInt()},106                {"name": "Spider-Boy", "age": 18, "id": IsInt()},107                {"name": "Rusty-Man", "age": None, "id": IsInt()},108            ]109        )110111        response = client.get("/heroes/?offset=1&limit=1")112        assert response.status_code == 200, response.text113        assert response.json() == snapshot(114            [{"name": "Spider-Boy", "age": 18, "id": IsInt()}]115        )116117        # Update a hero118        response = client.patch(119            f"/heroes/{hero_id}", json={"name": "Dog Pond", "age": None}120        )121        assert response.status_code == 200, response.text122        assert response.json() == snapshot(123            {"name": "Dog Pond", "age": None, "id": Is(hero_id)}124        )125126        # Get updated hero127        response = client.get(f"/heroes/{hero_id}")128        assert response.status_code == 200, response.text129        assert response.json() == snapshot(130            {"name": "Dog Pond", "age": None, "id": Is(hero_id)}131        )132133        # Delete a hero134        response = client.delete(f"/heroes/{hero_id}")135        assert response.status_code == 200, response.text136        assert response.json() == snapshot({"ok": True})137138        # The hero is no longer found139        response = client.get(f"/heroes/{hero_id}")140        assert response.status_code == 404, response.text141142        # Delete a hero that does not exist143        response = client.delete(f"/heroes/{hero_id}")144        assert response.status_code == 404, response.text145        assert response.json() == snapshot({"detail": "Hero not found"})146147        # Update a hero that does not exist148        response = client.patch(f"/heroes/{hero_id}", json={"name": "Dog Pond"})149        assert response.status_code == 404, response.text150        assert response.json() == snapshot({"detail": "Hero not found"})151152153def test_openapi_schema(client: TestClient):154    response = client.get("/openapi.json")155    assert response.status_code == 200, response.text156    assert response.json() == snapshot(157        {158            "openapi": "3.1.0",159            "info": {"title": "FastAPI", "version": "0.1.0"},160            "paths": {161                "/heroes/": {162                    "post": {163                        "summary": "Create Hero",164                        "operationId": "create_hero_heroes__post",165                        "requestBody": {166                            "required": True,167                            "content": {168                                "application/json": {169                                    "schema": {170                                        "$ref": "#/components/schemas/HeroCreate"171                                    }172                                }173                            },174                        },175                        "responses": {176                            "200": {177                                "description": "Successful Response",178                                "content": {179                                    "application/json": {180                                        "schema": {181                                            "$ref": "#/components/schemas/HeroPublic"182                                        }183                                    }184                                },185                            },186                            "422": {187                                "description": "Validation Error",188                                "content": {189                                    "application/json": {190                                        "schema": {191                                            "$ref": "#/components/schemas/HTTPValidationError"192                                        }193                                    }194                                },195                            },196                        },197                    },198                    "get": {199                        "summary": "Read Heroes",200                        "operationId": "read_heroes_heroes__get",201                        "parameters": [202                            {203                                "name": "offset",204                                "in": "query",205                                "required": False,206                                "schema": {207                                    "type": "integer",208                                    "default": 0,209                                    "title": "Offset",210                                },211                            },212                            {213                                "name": "limit",214                                "in": "query",215                                "required": False,216                                "schema": {217                                    "type": "integer",218                                    "maximum": 100,219                                    "default": 100,220                                    "title": "Limit",221                                },222                            },223                        ],224                        "responses": {225                            "200": {226                                "description": "Successful Response",227                                "content": {228                                    "application/json": {229                                        "schema": {230                                            "type": "array",231                                            "items": {232                                                "$ref": "#/components/schemas/HeroPublic"233                                            },234                                            "title": "Response Read Heroes Heroes  Get",235                                        }236                                    }237                                },238                            },239                            "422": {240                                "description": "Validation Error",241                                "content": {242                                    "application/json": {243                                        "schema": {244                                            "$ref": "#/components/schemas/HTTPValidationError"245                                        }246                                    }247                                },248                            },249                        },250                    },251                },252                "/heroes/{hero_id}": {253                    "get": {254                        "summary": "Read Hero",255                        "operationId": "read_hero_heroes__hero_id__get",256                        "parameters": [257                            {258                                "name": "hero_id",259                                "in": "path",260                                "required": True,261                                "schema": {"type": "integer", "title": "Hero Id"},262                            }263                        ],264                        "responses": {265                            "200": {266                                "description": "Successful Response",267                                "content": {268                                    "application/json": {269                                        "schema": {270                                            "$ref": "#/components/schemas/HeroPublic"271                                        }272                                    }273                                },274                            },275                            "422": {276                                "description": "Validation Error",277                                "content": {278                                    "application/json": {279                                        "schema": {280                                            "$ref": "#/components/schemas/HTTPValidationError"281                                        }282                                    }283                                },284                            },285                        },286                    },287                    "patch": {288                        "summary": "Update Hero",289                        "operationId": "update_hero_heroes__hero_id__patch",290                        "parameters": [291                            {292                                "name": "hero_id",293                                "in": "path",294                                "required": True,295                                "schema": {"type": "integer", "title": "Hero Id"},296                            }297                        ],298                        "requestBody": {299                            "required": True,300                            "content": {301                                "application/json": {302                                    "schema": {303                                        "$ref": "#/components/schemas/HeroUpdate"304                                    }305                                }306                            },307                        },308                        "responses": {309                            "200": {310                                "description": "Successful Response",311                                "content": {312                                    "application/json": {313                                        "schema": {314                                            "$ref": "#/components/schemas/HeroPublic"315                                        }316                                    }317                                },318                            },319                            "422": {320                                "description": "Validation Error",321                                "content": {322                                    "application/json": {323                                        "schema": {324                                            "$ref": "#/components/schemas/HTTPValidationError"325                                        }326                                    }327                                },328                            },329                        },330                    },331                    "delete": {332                        "summary": "Delete Hero",333                        "operationId": "delete_hero_heroes__hero_id__delete",334                        "parameters": [335                            {336                                "name": "hero_id",337                                "in": "path",338                                "required": True,339                                "schema": {"type": "integer", "title": "Hero Id"},340                            }341                        ],342                        "responses": {343                            "200": {344                                "description": "Successful Response",345                                "content": {"application/json": {"schema": {}}},346                            },347                            "422": {348                                "description": "Validation Error",349                                "content": {350                                    "application/json": {351                                        "schema": {352                                            "$ref": "#/components/schemas/HTTPValidationError"353                                        }354                                    }355                                },356                            },357                        },358                    },359                },360            },361            "components": {362                "schemas": {363                    "HTTPValidationError": {364                        "properties": {365                            "detail": {366                                "items": {367                                    "$ref": "#/components/schemas/ValidationError"368                                },369                                "type": "array",370                                "title": "Detail",371                            }372                        },373                        "type": "object",374                        "title": "HTTPValidationError",375                    },376                    "HeroCreate": {377                        "properties": {378                            "name": {"type": "string", "title": "Name"},379                            "age": {380                                "anyOf": [{"type": "integer"}, {"type": "null"}],381                                "title": "Age",382                            },383                            "secret_name": {"type": "string", "title": "Secret Name"},384                        },385                        "type": "object",386                        "required": ["name", "secret_name"],387                        "title": "HeroCreate",388                    },389                    "HeroPublic": {390                        "properties": {391                            "name": {"type": "string", "title": "Name"},392                            "age": {393                                "anyOf": [{"type": "integer"}, {"type": "null"}],394                                "title": "Age",395                            },396                            "id": {"type": "integer", "title": "Id"},397                        },398                        "type": "object",399                        "required": ["name", "id"],400                        "title": "HeroPublic",401                    },402                    "HeroUpdate": {403                        "properties": {404                            "name": {405                                "anyOf": [{"type": "string"}, {"type": "null"}],406                                "title": "Name",407                            },408                            "age": {409                                "anyOf": [{"type": "integer"}, {"type": "null"}],410                                "title": "Age",411                            },412                            "secret_name": {413                                "anyOf": [{"type": "string"}, {"type": "null"}],414                                "title": "Secret Name",415                            },416                        },417                        "type": "object",418                        "title": "HeroUpdate",419                    },420                    "ValidationError": {421                        "properties": {422                            "ctx": {"title": "Context", "type": "object"},423                            "input": {"title": "Input"},424                            "loc": {425                                "items": {426                                    "anyOf": [{"type": "string"}, {"type": "integer"}]427                                },428                                "type": "array",429                                "title": "Location",430                            },431                            "msg": {"type": "string", "title": "Message"},432                            "type": {"type": "string", "title": "Error Type"},433                        },434                        "type": "object",435                        "required": ["loc", "msg", "type"],436                        "title": "ValidationError",437                    },438                }439            },440        }441    )

Code quality findings 2

Ensure functions have docstrings for documentation
info maintainability missing-docstring
def clear_sqlmodel():
Ensure functions have docstrings for documentation
info maintainability missing-docstring
def get_client(request: pytest.FixtureRequest):

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.

Generated by searchcode.com · powered by code_get_file + code_get_findings