Conversation
There was a problem hiding this comment.
Review Summary
This PR adds comprehensive test coverage for auth flows and 401 responses across all endpoints. The tests correctly verify both happy paths and error conditions.
Critical
None — no security issues or data isolation bugs.
Minor
- TIL formatting issue — one entry was accidentally split across two lines with another entry inserted in the middle. Clean read-through fix.
- Nice catch on the boundary test —
test_expiring_boundaryverifies the<=operator is correct, which prevents off-by-one bugs in expiry queries.
What I verified
✅ All auth tests match the actual fastapi-users behavior (login uses data= form encoding with username field)
✅ 401 tests correctly target unauthenticated access
✅ Household isolation tests still comprehensive
✅ No missing household_id filters in any query
✅ Boundary test aligns with the Batch.expiry_date <= cutoff logic in batches.py:271
Cost: $0.67
| - **Guard `TEST_DATABASE_URL != DATABASE_URL` at import time.** | ||
| - **`filterwarnings` in `pyproject.toml` scopes warning suppression to a specific package** — `"ignore::DeprecationWarning:fastapi_users_db_sqlalchemy"` suppresses only that library's warnings without risking hiding your own. Useful when a dependency emits unavoidable noise on every test run. A per-test TRUNCATE against production is catastrophic. Read both URLs via the settings class and raise `RuntimeError` at module import — fails before any connection is made. | ||
|
|
||
| --- |
There was a problem hiding this comment.
Typo in the TIL entry: The sentence "filterwarnings..." was inserted in the middle of the existing "Guard TEST_DATABASE_URL != DATABASE_URL..." entry, breaking it across lines 100 and 103. The guard entry should be on one line, and the filterwarnings entry should be separate.
Why this matters: This makes the TIL file harder to read — the guard note is split in half with an unrelated note in between.
| resp = await client.get("/expiring?days=7", headers=auth) | ||
| expiry_dates = [b["expiry_date"] for b in resp.json()] | ||
| assert cutoff in expiry_dates | ||
| assert just_outside not in expiry_dates |
There was a problem hiding this comment.
Good boundary test! This confirms that the <= operator on line 271 of batches.py is correct — batches expiring on the cutoff day should be included. A common off-by-one bug in expiry logic.
This is the kind of test that catches subtle regressions when someone "simplifies" the query later.
Review SummaryCriticalNone — no security issues or data isolation bugs. Minor
Cost: $0.67 |
Closes the remaining test gaps from the integration suite: auth flow, unauthenticated access, and two coverage holes identified on review.
Decisions worth noting
client, noauthfixture — testing the auth flow with a pre-authenticated state would defeat the purpose.GET /items/{id}isolation added explicitly — the existing isolation tests covered list, update, and delete for items but missed the single-item GET. The other resources don't have a GET-by-ID endpoint so this is items-specific./expiringboundary test checks both sides of the cutoff — the filter isexpiry_date <= today + days; a batch expiring exactly on the cutoff day must be included, one day after must not. Off-by-one bugs live at boundaries.filterwarningsscoped tightly tofastapi_users_db_sqlalchemy— the library emits a SQLModel deprecation warning on every query. Suppressing broadly would hide genuine warnings; the tight scope limits it to that package only.on_after_registeris not tested — verifying that the orphaned user is deleted when household creation fails would require mocking SQLAlchemy internals. The blanket no-mocks rule exists because isolation bugs are the risk here, not exception handling; this edge case doesn't meet the bar.What's next
Frontend — auth UI against the existing endpoints.