A real refactor on TicketFlow with a complete net. No solutions.md before submitting.
Exercise 1 — The net audit
- Before touching anything: what does your suite cover for
reservar()? List by level (unit/integration/contract/E2E) which test exists TODAY and which gap you see (the locked transaction? the outbox after commit? the 409's problem+json?). - Write the 2 missing characterization tests so you can refactor with a net (if you think none is missing: write one that fails if anyone moves the outbox before the commit).
Exercise 2 — The guided extraction
- Run the reservation service's refactor in 4 commits (validar_asientos / cobrar / ReservacionService / deprecating the old function). Suite green after each commit — paste the 4 hashes and the
git log --onelineoutput. - In each step note: how many tests were touched? The goal is that the characterization tests are NOT touched in any of them.
- Step 4 (deprecation): the old function delegates to the service with a
DeprecationWarning. Who still calls it, and over how long does it die?
Exercise 3 — The bug in passing (the forbidden experiment)
- DIDACTIC PURPOSE: do it ONCE to watch it break. On the refactor branch, fix in passing the total rounding bug (08) and add a new field to the response. Run the suite: how many red tests? Which contract ones?
- Now do it right:
git revertthe mixed commit, the bug in a separate commit with the regression test first, the new field with its test and version note (14). The whole suite green in both commits separately.
Exercise 4 — Feigning the contract
- List YOUR frontend's 5 untouchables (status, problem types, JSON fields, IDs, parsed messages). Write the "contract guard" test: a battery that fails if any of them changes (you can reuse
assert_problemfrom 26). - Break ONE on purpose (rename
seat_refs→seatsin the response): which test catches it, and after how many seconds did you know?
Exercise 5 — The job extraction (29's prep)
- Extract
expirar_reservas(clock) -> list[str](expired refs) into the service, leaving the management command as a pure trigger. Test with FakeClock: 3 reservations, one expired, two valid → returns 1 ref and marks themEXPIREDwith the rightexpires_at. - Write the trigger's test: the command calls the service once and returns the count. The logic is NOT in the command — verify with a mock that if the service raises, the command propagates.
Submit
Paste the refactor's hashes, the bug-in-passing experiment (red), the contract guard and the job extraction. Next: Lesson 29 — Queues and background jobs (module 6).