feat(scaffold): add model-backed CRUD service template
Provides a complete OpenAPI-first CRUD example with a Pydantic model layer, explicit runtime semantics, and integration tests to support developer onboarding and real-world service structure.
This commit is contained in:
98
openapi_first/templates/model_app/test_model_app.py
Normal file
98
openapi_first/templates/model_app/test_model_app.py
Normal file
@@ -0,0 +1,98 @@
|
||||
"""
|
||||
End-to-end tests for the OpenAPI-first model CRUD example app.
|
||||
|
||||
These tests validate that all CRUD operations behave correctly
|
||||
against the in-memory mock data store using Pydantic models.
|
||||
|
||||
The tests assume:
|
||||
- OpenAPI-first route binding
|
||||
- Pydantic model validation
|
||||
- In-memory storage (no persistence guarantees)
|
||||
- Deterministic behavior in a single process
|
||||
"""
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from main import app
|
||||
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
|
||||
def test_list_items_initial():
|
||||
"""Initial items should be present."""
|
||||
response = client.get("/items")
|
||||
assert response.status_code == 200
|
||||
|
||||
data = response.json()
|
||||
assert isinstance(data, list)
|
||||
assert len(data) >= 2
|
||||
|
||||
ids = {item["id"] for item in data}
|
||||
assert 1 in ids
|
||||
assert 2 in ids
|
||||
|
||||
|
||||
def test_get_item():
|
||||
"""Existing item should be retrievable by ID."""
|
||||
response = client.get("/items/1")
|
||||
assert response.status_code == 200
|
||||
|
||||
item = response.json()
|
||||
assert item["id"] == 1
|
||||
assert isinstance(item["name"], str)
|
||||
assert isinstance(item["price"], float)
|
||||
|
||||
|
||||
def test_create_item():
|
||||
"""Creating a new item should return the created entity."""
|
||||
payload = {
|
||||
"name": "Orange",
|
||||
"price": 0.8,
|
||||
}
|
||||
|
||||
response = client.post("/items", json=payload)
|
||||
assert response.status_code == 201
|
||||
|
||||
item = response.json()
|
||||
assert "id" in item
|
||||
assert item["name"] == payload["name"]
|
||||
assert item["price"] == payload["price"]
|
||||
|
||||
# Verify it appears in list
|
||||
list_response = client.get("/items")
|
||||
ids = {i["id"] for i in list_response.json()}
|
||||
assert item["id"] in ids
|
||||
|
||||
|
||||
def test_update_item():
|
||||
"""Updating an item should replace its values."""
|
||||
payload = {
|
||||
"name": "Green Apple",
|
||||
"price": 0.6,
|
||||
}
|
||||
|
||||
response = client.put("/items/1", json=payload)
|
||||
assert response.status_code == 200
|
||||
|
||||
item = response.json()
|
||||
assert item["id"] == 1
|
||||
assert item["name"] == payload["name"]
|
||||
assert item["price"] == payload["price"]
|
||||
|
||||
# Verify persisted update
|
||||
get_response = client.get("/items/1")
|
||||
updated = get_response.json()
|
||||
assert updated["name"] == payload["name"]
|
||||
assert updated["price"] == payload["price"]
|
||||
|
||||
|
||||
def test_delete_item():
|
||||
"""Deleting an item should remove it from the store."""
|
||||
response = client.delete("/items/2")
|
||||
assert response.status_code == 204
|
||||
|
||||
# Verify deletion
|
||||
list_response = client.get("/items")
|
||||
ids = {item["id"] for item in list_response.json()}
|
||||
assert 2 not in ids
|
||||
Reference in New Issue
Block a user