Each requirement of qa-practice-api, the designed test cases that check it, and their results in CI run #110 (schedule, 2026-10-19, commit d8355c4). Requirements and cases come from the test plan, risks from the test strategy. Back to the reports. Generated 2026-10-19.
A requirement passes only when every one of its cases passed. One failed case makes it failing; a case with no result makes it incomplete.
| Requirement | What it says | Risks | Cases | Status |
|---|---|---|---|---|
| REQ-01 | A product's price is a JSON number ≥ 0, on create and on update | R-05 | TC-EP-01 passedTC-EP-02 passedTC-EP-03 passedTC-EP-04 passedTC-EP-05 passedTC-EP-06 passedTC-BVA-01 passedTC-BVA-02 passedTC-BVA-03 passed | Passing |
| REQ-02 | A product's stock is a whole JSON number ≥ 0; left out on create, it is 0 | R-05 | TC-EP-07 passedTC-EP-08 passedTC-EP-09 passedTC-EP-10 passedTC-BVA-04 passedTC-BVA-05 passedTC-BVA-06 passed | Passing |
| REQ-03 | Each order line has a product_id and a whole-number quantity ≥ 1; items is a non-empty array | R-04, R-11 | TC-EP-11 passedTC-EP-12 passedTC-EP-13 passedTC-EP-14 passedTC-EP-15 passedTC-EP-16 passedTC-BVA-07 passedTC-BVA-08 passedTC-DT-10 passed | Passing |
| REQ-04 | An order is accepted only if every product exists and has stock for its quantity summed across lines. If accepted, stock goes down by that amount; if not, no stock changes | R-04 | TC-BVA-09 passedTC-BVA-10 passedTC-BVA-11 passedTC-BVA-12 passedTC-DT-11 passedTC-DT-12 passedTC-DT-14 passed | Passing |
| REQ-05 | An order's total is the sum of price × quantity, rounded to cents | R-12 | TC-DT-13 passed | Passing |
| REQ-06 | Order status follows the order lifecycle (pending → processing or cancelled, processing → shipped or cancelled, shipped → delivered). Any other move returns 409 and leaves the status as it was | R-01 | TC-ST-01 passedTC-ST-02 passedTC-ST-03 passedTC-ST-04 passedTC-ST-05 passedTC-ST-06 passedTC-ST-07 passedTC-ST-08 passedTC-ST-09 passedTC-ST-10 passedTC-ST-11 passedTC-ST-12 passedTC-ST-13 passedTC-ST-14 passedTC-ST-15 passedTC-ST-16 passedTC-ST-17 passedTC-ST-18 passedTC-ST-19 passedTC-ST-20 passedTC-ST-21 passedTC-ST-22 passedTC-ST-23 passedTC-ST-24 passedTC-ST-25 passed | Passing |
| REQ-07 | Cancelling an order returns its stock to the products that still exist | R-01 | TC-ST-26 passedTC-ST-27 passedTC-ST-28 passedTC-ST-29 passed | Passing |
| REQ-08 | Lists use page ≥ 1 and limit 1–50; values outside are clamped to the nearest edge, a missing or non-numeric value means page 1 or limit 10, and a page past the end is empty | R-17 | TC-BVA-13 passedTC-BVA-14 passedTC-BVA-15 passedTC-BVA-16 passedTC-BVA-17 passedTC-BVA-18 passedTC-BVA-19 passedTC-BVA-20 passedTC-BVA-21 passedTC-BVA-22 passed | Passing |
| REQ-09 | PUT /users/:id changes only the caller's own account (admins: any). Another account gets 403 before its existence is checked; name and email must be non-empty strings; an email used by another account gets 409; a deleted or unknown account gets 404 to an admin | R-02 | TC-DT-01 passedTC-DT-02 passedTC-DT-03 passedTC-DT-04 passedTC-DT-05 passedTC-DT-06 passedTC-DT-07 passedTC-DT-08 passedTC-DT-15 passedTC-DT-16 passedTC-DT-17 passed | Passing |
| REQ-10 | Every error response is JSON { error }, including for a malformed request body | R-11 | TC-EP-17 passed | Passing |
| REQ-11 | Sign-up and sign-in fields must be non-empty strings; anything else gets 400, not 500 | R-11 | TC-EP-18 passedTC-EP-19 passedTC-EP-20 passed | Passing |
| REQ-12 | Placing an order needs a signed-in user | R-06 | TC-DT-09 passed | Passing |
| REQ-13 | Only an admin creates, changes or deletes products; a customer gets 403 and nothing changes | R-03 | TC-AC-01 passedTC-AC-02 passedTC-AC-03 passedTC-AC-04 passed | Passing |
| REQ-14 | A customer reads, lists and cancels only their own orders; another customer's order answers 404, as if it didn't exist. An admin reads and lists every order | R-08 | TC-AC-05 passedTC-AC-06 passedTC-AC-07 passedTC-AC-08 passed | Passing |
| REQ-15 | Only an admin moves an order to processing, shipped or delivered; a customer asking for any of these gets 403. A customer may cancel their own order (the lifecycle rules of REQ-06 still apply) | R-07 | TC-AC-09 passedTC-AC-10 passedTC-AC-11 passedTC-AC-12 passed | Passing |
| REQ-16 | Only an admin lists accounts or reads or deletes another user's account; a customer gets 403 for any account but their own | R-19 | TC-AC-13 passedTC-AC-14 passedTC-AC-15 passedTC-AC-16 passed | Passing |
| REQ-17 | A token works only while its account exists and only if this server signed it; the role comes from the account, never from the request | R-06, R-20, R-21 | TC-AC-17 passedTC-AC-18 passedTC-AC-19 passedTC-AC-20 passedTC-AC-21 passedTC-AC-22 passed | Passing |
| REQ-18 | Sign-in allows 5 attempts per email and client in 15 minutes without a success. Further attempts get 429 with Retry-After, even with the right password, until the window ends; a success clears the count; other emails are unaffected; concurrent attempts are counted as they start | R-09 | TC-BVA-23 passedTC-BVA-24 passedTC-BVA-25 passedTC-DT-18 passedTC-DT-19 passedTC-DT-20 passedTC-DT-21 passedTC-DT-22 passedTC-DT-23 passed | Passing |
Failure details are in the qa-practice-api report. 172 other tests in the suite are route-level checks written before the plan and aren't tied to a requirement.
| Case | Technique | Requirement | Input | Expected | Result |
|---|---|---|---|---|---|
| TC-EP-01 | Equivalence partitioning | REQ-01 | price 12.5 | 201, price 12.5 | passed |
| TC-EP-02 | Equivalence partitioning | REQ-01 | price "12.5" | 400 | passed |
| TC-EP-03 | Equivalence partitioning | REQ-01 | price "" | 400 | passed |
| TC-EP-04 | Equivalence partitioning | REQ-01 | price true | 400 | passed |
| TC-EP-05 | Equivalence partitioning | REQ-01 | price "abc" | 400 | passed |
| TC-EP-06 | Equivalence partitioning | REQ-01 | price [5] | 400 | passed |
| TC-EP-07 | Equivalence partitioning | REQ-02 | no stock | 201, stock 0 | passed |
| TC-EP-08 | Equivalence partitioning | REQ-02 | stock "" | 400 | passed |
| TC-EP-09 | Equivalence partitioning | REQ-02 | stock "5" | 400 | passed |
| TC-EP-10 | Equivalence partitioning | REQ-02 | stock 2.5 | 400 | passed |
| TC-EP-11 | Equivalence partitioning | REQ-03 | quantity 2 (stock 10) | 201, stock 8 | passed |
| TC-EP-12 | Equivalence partitioning | REQ-03 | quantity "2" | 400, stock unchanged | passed |
| TC-EP-13 | Equivalence partitioning | REQ-03 | quantity 1.5 | 400, stock unchanged | passed |
| TC-EP-14 | Equivalence partitioning | REQ-03 | line with no quantity | 400, stock unchanged | passed |
| TC-EP-15 | Equivalence partitioning | REQ-03 | items: [null] | 400 JSON, stock unchanged | passed |
| TC-EP-16 | Equivalence partitioning | REQ-03 | items: "two widgets" | 400 | passed |
| TC-EP-17 | Equivalence partitioning | REQ-10 | body {"name": "Widget", | 400, JSON { error } | passed |
| TC-EP-18 | Equivalence partitioning | REQ-11 | sign-up with password 12345 (a number) | 400 | passed |
| TC-EP-19 | Equivalence partitioning | REQ-11 | sign-up with email { "$ne": "" } | 400 | passed |
| TC-EP-20 | Equivalence partitioning | REQ-11 | sign-in with password 12345 (a number) | 400 | passed |
| TC-BVA-01 | Boundary value analysis | REQ-01 | price −0.01 | 400 | passed |
| TC-BVA-02 | Boundary value analysis | REQ-01 | price 0 | 201 | passed |
| TC-BVA-03 | Boundary value analysis | REQ-01 | price 0.01 | 201 | passed |
| TC-BVA-04 | Boundary value analysis | REQ-02 | stock −1 | 400 | passed |
| TC-BVA-05 | Boundary value analysis | REQ-02 | stock 0 | 201 | passed |
| TC-BVA-06 | Boundary value analysis | REQ-02 | stock 1 | 201 | passed |
| TC-BVA-07 | Boundary value analysis | REQ-03 | quantity 0, stock 5 | 400, stock 5 | passed |
| TC-BVA-08 | Boundary value analysis | REQ-03 | quantity 1, stock 5 | 201, stock 4 | passed |
| TC-BVA-09 | Boundary value analysis | REQ-04 | quantity 5, stock 5 | 201, stock 0 | passed |
| TC-BVA-10 | Boundary value analysis | REQ-04 | quantity 6, stock 5 | 400, stock 5 | passed |
| TC-BVA-11 | Boundary value analysis | REQ-04 | two lines, 2 + 3, stock 5 | 201, stock 0 | passed |
| TC-BVA-12 | Boundary value analysis | REQ-04 | two lines, 3 + 3, stock 5 | 400, stock 5 | passed |
| TC-BVA-13 | Boundary value analysis | REQ-08 | limit=-1 | limit 1 | passed |
| TC-BVA-14 | Boundary value analysis | REQ-08 | limit=0 | limit 1 | passed |
| TC-BVA-15 | Boundary value analysis | REQ-08 | limit=1 | limit 1 | passed |
| TC-BVA-16 | Boundary value analysis | REQ-08 | limit=50 | limit 50 | passed |
| TC-BVA-17 | Boundary value analysis | REQ-08 | limit=51 | limit 50 | passed |
| TC-BVA-18 | Boundary value analysis | REQ-08 | no limit | limit 10 | passed |
| TC-BVA-19 | Boundary value analysis | REQ-08 | limit=abc | limit 10 | passed |
| TC-BVA-20 | Boundary value analysis | REQ-08 | page=0, 3 items, limit 2 | page 1, 2 items | passed |
| TC-BVA-21 | Boundary value analysis | REQ-08 | page=2 (last) | 1 item, pages 2 | passed |
| TC-BVA-22 | Boundary value analysis | REQ-08 | page=3 (past the end) | 0 items, pages 2 | passed |
| TC-BVA-23 | Boundary value analysis | REQ-18 | 5th wrong password | 401 | passed |
| TC-BVA-24 | Boundary value analysis | REQ-18 | 6th wrong password | 429 | passed |
| TC-BVA-25 | Boundary value analysis | REQ-18 | 20 wrong passwords sent at once | exactly 5 × 401, 15 × 429 | passed |
| TC-DT-01 | Decision tables | REQ-09 | update another user's name | 403 | passed |
| TC-DT-02 | Decision tables | REQ-09 | update own name and email to an unused email | 200 | passed |
| TC-DT-03 | Decision tables | REQ-09 | update own email to the same email | 200 | passed |
| TC-DT-04 | Decision tables | REQ-09 | update own email to another user's | 409, account unchanged | passed |
| TC-DT-05 | Decision tables | REQ-09 | update own name to " " | 400 | passed |
| TC-DT-06 | Decision tables | REQ-09 | update own email to 42 | 400 | passed |
| TC-DT-07 | Decision tables | REQ-09 | update user 999999 | 403 | passed |
| TC-DT-08 | Decision tables | REQ-09 | admin updates an account after it was deleted | 404 | passed |
| TC-DT-09 | Decision tables | REQ-12 | order with no token | 401 | passed |
| TC-DT-10 | Decision tables | REQ-03 | order with quantity 0 | 400 | passed |
| TC-DT-11 | Decision tables | REQ-04 | order product 999999 | 404 | passed |
| TC-DT-12 | Decision tables | REQ-04 | order 2 of a product with stock 1 | 400 | passed |
| TC-DT-13 | Decision tables | REQ-05 | order 3 at price 0.1 | 201, total 0.3 | passed |
| TC-DT-14 | Decision tables | REQ-04 | lines for a real product and product 999999 | 404, real product's stock unchanged | passed |
| TC-DT-15 | Decision tables | REQ-09 | admin updates another user's name | 200 | passed |
| TC-DT-16 | Decision tables | REQ-09 | admin updates user 999999 | 404 | passed |
| TC-DT-17 | Decision tables | REQ-09 | admin gives a user another account's email | 409 | passed |
| TC-DT-18 | Decision tables | REQ-18 | 4 wrong passwords, the right one, 4 wrong, the right one | 200 both times | passed |
| TC-DT-19 | Decision tables | REQ-18 | 1 wrong password | 401 | passed |
| TC-DT-20 | Decision tables | REQ-18 | 5 wrong passwords, then the right one | 429, Retry-After 1–900 s | passed |
| TC-DT-21 | Decision tables | REQ-18 | 5 wrong passwords, then a 6th | 429 | passed |
| TC-DT-22 | Decision tables | REQ-18 | 5 wrong for one email, then the right password for another | 200 | passed |
| TC-DT-23 | Decision tables | REQ-18 | 5 attempts for an email with no account, then a 6th | 429 | passed |
| TC-ST-01 | State transitions | REQ-06 | pending → pending | 409 | passed |
| TC-ST-02 | State transitions | REQ-06 | pending → processing | 200 | passed |
| TC-ST-03 | State transitions | REQ-06 | pending → shipped | 409 | passed |
| TC-ST-04 | State transitions | REQ-06 | pending → delivered | 409 | passed |
| TC-ST-05 | State transitions | REQ-06 | pending → cancelled | 200 | passed |
| TC-ST-06 | State transitions | REQ-06 | processing → pending | 409 | passed |
| TC-ST-07 | State transitions | REQ-06 | processing → processing | 409 | passed |
| TC-ST-08 | State transitions | REQ-06 | processing → shipped | 200 | passed |
| TC-ST-09 | State transitions | REQ-06 | processing → delivered | 409 | passed |
| TC-ST-10 | State transitions | REQ-06 | processing → cancelled | 200 | passed |
| TC-ST-11 | State transitions | REQ-06 | shipped → pending | 409 | passed |
| TC-ST-12 | State transitions | REQ-06 | shipped → processing | 409 | passed |
| TC-ST-13 | State transitions | REQ-06 | shipped → shipped | 409 | passed |
| TC-ST-14 | State transitions | REQ-06 | shipped → delivered | 200 | passed |
| TC-ST-15 | State transitions | REQ-06 | shipped → cancelled | 409 | passed |
| TC-ST-16 | State transitions | REQ-06 | delivered → pending | 409 | passed |
| TC-ST-17 | State transitions | REQ-06 | delivered → processing | 409 | passed |
| TC-ST-18 | State transitions | REQ-06 | delivered → shipped | 409 | passed |
| TC-ST-19 | State transitions | REQ-06 | delivered → delivered | 409 | passed |
| TC-ST-20 | State transitions | REQ-06 | delivered → cancelled | 409 | passed |
| TC-ST-21 | State transitions | REQ-06 | cancelled → pending | 409 | passed |
| TC-ST-22 | State transitions | REQ-06 | cancelled → processing | 409 | passed |
| TC-ST-23 | State transitions | REQ-06 | cancelled → shipped | 409 | passed |
| TC-ST-24 | State transitions | REQ-06 | cancelled → delivered | 409 | passed |
| TC-ST-25 | State transitions | REQ-06 | cancelled → cancelled | 409 | passed |
| TC-ST-26 | State transitions | REQ-07 | cancel a pending order of 4 (stock 10 → 6) | 200, stock 10 | passed |
| TC-ST-27 | State transitions | REQ-07 | cancel a processing order of 4 | 200, stock 10 | passed |
| TC-ST-28 | State transitions | REQ-07 | cancel a shipped order of 4 | 409, stock stays 6 | passed |
| TC-ST-29 | State transitions | REQ-07 | cancel after the product was deleted | 200 | passed |
| TC-AC-01 | Access control | REQ-13 | customer creates a product | 403 | passed |
| TC-AC-02 | Access control | REQ-13 | customer sets a product's price to 0.01 | 403, price unchanged | passed |
| TC-AC-03 | Access control | REQ-13 | customer deletes a product | 403, product still there | passed |
| TC-AC-04 | Access control | REQ-13 | admin creates, updates and deletes a product | 201, 200, 204 | passed |
| TC-AC-05 | Access control | REQ-14 | customer reads another customer's order | 404 | passed |
| TC-AC-06 | Access control | REQ-14 | customer lists orders while another customer has one | only their own | passed |
| TC-AC-07 | Access control | REQ-14 | customer cancels another customer's order | 404, still pending | passed |
| TC-AC-08 | Access control | REQ-14 | admin reads and lists a customer's order | 200, in the list | passed |
| TC-AC-09 | Access control | REQ-15 | customer moves their own pending order to processing | 403, still pending | passed |
| TC-AC-10 | Access control | REQ-15 | customer marks their own shipped order delivered | 403, still shipped | passed |
| TC-AC-11 | Access control | REQ-15 | customer cancels their own pending order | 200, stock returned | passed |
| TC-AC-12 | Access control | REQ-15 | admin moves a customer's order to processing | 200 | passed |
| TC-AC-13 | Access control | REQ-16 | customer lists all users | 403, no emails in the body | passed |
| TC-AC-14 | Access control | REQ-16 | customer reads another user's account | 403, no email in the body | passed |
| TC-AC-15 | Access control | REQ-16 | customer reads their own account | 200 | passed |
| TC-AC-16 | Access control | REQ-16 | admin deletes a customer's account | 204, then 404 | passed |
| TC-AC-17 | Access control | REQ-17 | deleted account's token on GET /auth/me | 401 | passed |
| TC-AC-18 | Access control | REQ-17 | deleted account's token places an order | 401, stock unchanged | passed |
| TC-AC-19 | Access control | REQ-17 | admin token signed with the secret that used to be built in | 401 | passed |
| TC-AC-20 | Access control | REQ-17 | unsigned token (alg: none) claiming admin | 401 | passed |
| TC-AC-21 | Access control | REQ-17 | sign-up with role: "admin" in the body | 201, role user, admin routes 403 | passed |
| TC-AC-22 | Access control | REQ-17 | PUT own account with role: "admin" | 200, role still user | passed |