Expect a 400, not a 404, for a record that is gone

Running the password tier against a disposable 5.13.50 instance for the
first time failed its last check. The purge itself was fine — the row really
was gone — but the assertion looked for a 404 and the server answers 400.

`Handler.php` maps Laravel's `ModelNotFoundException` to a 400 carrying
`No query results for model [App\Models\X].` and reserves 404 for a route
that does not exist, so a not-found check written against 404 never fires.
The assertion now matches the status together with the message, so a 400
raised for some other reason still fails, and `Error::Api` says so for
callers, who would otherwise write the same dead branch.

Also adds jq to the devshell, which the MSRV recheck in CLAUDE.md pipes
through but which was only ever resolving from the host.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 21:57:12 -04:00
co-authored by Claude Opus 5
parent 0485272080
commit e7c9663621
5 changed files with 35 additions and 11 deletions
+6 -6
View File
@@ -274,12 +274,12 @@ session through without the header). Most are **irreversible**, and all are
| `POST /users/{id}/purge` | `purge_user` | `()` (the server answers 204) |
| `GET /users/create` | `new_user_template` | a blank `User`, nothing stored |
A merge keeps the first id and folds the second into it. These are verified
against the upstream controllers and mock servers only: running them needs the
account password, so the smoke test's optional password tier (merge two
throwaway clients, purge the survivor) has not yet been run against a real
instance. A password containing a control character cannot be a header value
and goes out as `X-API-PASSWORD-BASE64` instead.
A merge keeps the first id and folds the second into it. The smoke test's
optional password tier (merge two throwaway clients, purge the survivor) was
run against a disposable 5.13.50 instance on 2026-10-24 and passes; it also
established that a purged record reads back as a **400**, not a 404. A
password containing a control character cannot be a header value and goes out
as `X-API-PASSWORD-BASE64` instead.
## Per-resource extras