reading-list / tests /test_query.py
pardeep-singh's picture
Deploy reading-list from main 730966e
06b349d verified
Raw History Blame Contribute Delete
4.24 kB
import pytest
from app.models import Book, Status
def seed(client, *books): # books: (title, author, status) tuples
store = client.app.state.store
for title, author, status in books:
book = Book(id=store._next_id, title=title, author=author, status=status)
store._books[book.id] = book
store._next_id += 1
def test_list_empty_returns_empty_array(client):
r = client.get("/api/books")
assert r.status_code == 200
assert r.json() == []
def test_list_all_in_id_order(client):
seed(
client,
("Dune", "Frank Herbert", Status.READING),
("Emma", None, Status.TO_READ),
("Ulysses", "James Joyce", Status.DONE),
)
r = client.get("/api/books")
assert r.status_code == 200
assert r.json() == [
{"id": 1, "title": "Dune", "author": "Frank Herbert", "status": "reading"},
{"id": 2, "title": "Emma", "author": None, "status": "to-read"},
{"id": 3, "title": "Ulysses", "author": "James Joyce", "status": "done"},
]
@pytest.mark.parametrize(
("status", "expected_ids"),
[("to-read", [2, 4]), ("reading", [1]), ("done", [3])],
)
def test_list_filtered_by_status(client, status, expected_ids):
seed(
client,
("Dune", "Frank Herbert", Status.READING),
("Emma", None, Status.TO_READ),
("Ulysses", "James Joyce", Status.DONE),
("Beloved", "Toni Morrison", Status.TO_READ),
)
r = client.get("/api/books", params={"status": status})
assert r.status_code == 200
body = r.json()
assert [b["id"] for b in body] == expected_ids
assert all(b["status"] == status for b in body)
def test_list_invalid_status_gives_422(client):
r = client.get("/api/books", params={"status": "bogus"})
assert r.status_code == 422
detail = r.json()["detail"]
assert isinstance(detail, list)
assert detail[0]["loc"] == ["query", "status"]
def test_patch_updates_status_and_persists(client):
seed(
client,
("Dune", "Frank Herbert", Status.READING),
("Emma", None, Status.TO_READ),
)
r = client.patch("/api/books/1", json={"status": "done"})
assert r.status_code == 200
assert r.json() == {
"id": 1,
"title": "Dune",
"author": "Frank Herbert",
"status": "done",
}
listed = client.get("/api/books").json()
assert [b["status"] for b in listed] == ["done", "to-read"]
def test_patch_missing_id_gives_404(client):
seed(client, ("Dune", "Frank Herbert", Status.READING))
r = client.patch("/api/books/99", json={"status": "done"})
assert r.status_code == 404
assert r.json() == {"detail": "Book not found"}
@pytest.mark.parametrize(
"kwargs",
[
{"json": {"status": "bogus"}},
{"json": {}},
{},
],
ids=["bad-status", "missing-status", "missing-body"],
)
def test_patch_invalid_body_gives_422(client, kwargs):
seed(client, ("Dune", "Frank Herbert", Status.READING))
r = client.patch("/api/books/1", **kwargs)
assert r.status_code == 422
assert isinstance(r.json()["detail"], list)
assert client.get("/api/books").json()[0]["status"] == "reading"
def test_patch_non_integer_id_gives_422(client):
r = client.patch("/api/books/abc", json={"status": "done"})
assert r.status_code == 422
assert r.json()["detail"][0]["loc"] == ["path", "book_id"]
def test_stats_empty_store_all_zero(client):
r = client.get("/api/stats")
assert r.status_code == 200
assert r.json() == {
"total": 0,
"by_status": {"to-read": 0, "reading": 0, "done": 0},
}
def test_stats_counts_seeded_books_and_tracks_patch(client):
seed(
client,
("Dune", "Frank Herbert", Status.READING),
("Emma", None, Status.TO_READ),
("Ulysses", "James Joyce", Status.DONE),
("Beloved", "Toni Morrison", Status.DONE),
)
assert client.get("/api/stats").json() == {
"total": 4,
"by_status": {"to-read": 1, "reading": 1, "done": 2},
}
client.patch("/api/books/1", json={"status": "done"})
assert client.get("/api/stats").json() == {
"total": 4,
"by_status": {"to-read": 1, "reading": 0, "done": 3},
}