docs: update README, Obsidian docs, and gap backlog after test optimization

- Update test count: 286/288 passing (was 222/224)
- Document TestMain per-package architecture
- Document TruncateTables optimization (~60% faster)
- Add local-dev-2.sh tee streaming for real-time test output
- Fix flaky admin reserve walk-in tests (time.Now → noon tomorrow)
- Add gap backlog item #51 for completed test optimization work
This commit is contained in:
2026-05-10 19:48:36 +01:00
parent e73c96b653
commit aa4a569a43
5 changed files with 48 additions and 49 deletions
+19 -30
View File
@@ -1,4 +1,4 @@
**Last Updated:** May 2026
**Last Updated:** May 2026 — Test infrastructure overhaul, 286/288 tests passing
> **Status:** Work in Progress
---
@@ -125,7 +125,10 @@
- [ ] **Guest user endpoint** - ✅ DONE: `POST /api/users/guest` creates disposable accounts, partial unique email index
#### Unit Tests & CI/CD
- [ ] Unit tests
- [x] 286/288 tests passing across all handler packages
- [x] TestMain per package — schema migration runs once per package (not per test)
- [x] TruncateTables() between tests — TRUNCATE CASCADE, ~60% faster than DROP+CREATE
- [x] Test output streamed in real-time via `tee` in local-dev-2.sh
- [ ] CI/CD pipeline
---
@@ -258,44 +261,30 @@ go test -v -run "TestBooking" ./...
### Test Database
- DSN: `postgres://myuser:mypassword@localhost:5432/crussell_test?sslmode=disable`
- Override: `export TEST_DB_DSN="..."`
- Uses `testdb.Migrate()` to run init-script.sql
- Tables truncated between tests via `testdb.TruncateTables()`
- Override: `export POSTGRES_USER=myuser POSTGRES_PASSWORD=mypassword POSTGRES_HOST=localhost POSTGRES_DB=crussell_test GO_TESTING=1`
- Each package has a `TestMain` that runs `testdb.Migrate()` once at package level
- Tables truncated between tests via `testdb.TruncateTables()` (TRUNCATE CASCADE)
- Tests run sequentially (`-p 1`) — all packages share same test database
### Conventions
- All test files use `//go:build test` build tag
- Test tokens use fixed secret: `test-secret-key-for-testing-only`
- Fixtures auto-generate unique emails to avoid conflicts
- `-count=N` is safe — each count re-runs TestMain + all tests (good for flaky test detection)
### Recent Testing Updates (May 2026)
**Major additions since March 2026:**
**Major Test Infrastructure Overhaul:**
- **TestMain per package** — Schema migration (DROP+CREATE) now runs once per package instead of once per test. 10 package-level TestMain functions across 10 test packages.
- **Truncate-only between tests** — Per-test setup changed from full schema rebuild to `TRUNCATE TABLE ... CASCADE` only. ~60% reduction in test DB setup time.
- **3 missing tables added to TruncateTables** — `booking_edit_requests`, `exceptional_group_applications`, `business_settings` were previously relying on implicit CASCADE cleanup.
- **discount_test.go moved to package bookings** — Was external test package (`bookings_test`), now shares TestMain with other booking tests.
- **Dead code removed** — `truncateDiscountTables()` helper (never called) deleted.
- **Flaky test fixes** — `TestAdminReserveSlot_WalkIn_Success` and `TestAdminReserveSlot_ReplacesExisting` used `time.Now()` which could fall after working hours. Fixed to use noon tomorrow.
- **local-dev-2.sh** — Test output now streamed in real-time via `tee` instead of captured silently.
**Guest Booking System:**
- `POST /api/users/guest` — disposable account creation with email collision handling
- Partial unique email index: `WHERE account_role != 'guest'`
- `POST /api/bookings` now accepts `user_id` for guest bookings (OptionalAuth middleware)
- Guest bookings bypass deposit and patch-test checks
- `AnonymizeStaleGuestAccounts()` — scrubs PII 6 months after booking start_time
**Slot Reservation System:**
- `POST /api/bookings/reserve` (public, OptionalAuth) — 4 TTL types: user=1h, anon=10min, walkin=5min, callin=1h
- Anonymous cap: 50 reservations per 10-minute rolling window
- `GetTimeBlockersInRange` excludes `RESERVATION:*` entries (self-block fix)
- Frontend: BookingFlow reserves on Step 2→3 transition, re-validates on "Next" click
- Admin modals wired to reserve endpoints (walk-in: 5min TTL, call-in: 60min TTL)
**Router Fix:**
- Chi routing conflict: `r.Route("/bookings", RequireAuth)` bled into `POST /bookings` (OptionalAuth)
- Flattened to explicit paths (`/bookings`, `/bookings/{id}`) with per-route middleware
**Seed Script Fixes:**
- `open_day()` now skips Saturday (6) not Monday (1), matching `working_hours` schema
- Guest booking dates moved to +16/+20/+22 days to avoid collisions with upcoming loop
- Seed now uses reserve-then-book flow matching frontend
**Test Coverage:** 222/224 passing
**Test Coverage: 286/288 passing** (was 222/224)
---
@@ -1,4 +1,4 @@
**Last Updated:** May 2026
**Last Updated:** May 2026 — Test infrastructure overhaul complete (#51)
**Status:** Living backlog — add to this as gaps are discovered
---
@@ -71,6 +71,7 @@ No external dependencies. No paid services. No API keys needed.
| 47 | **Recurring bookings** | L (3-5d) | Full-stack | Customers can't book the same slot weekly/monthly. Would need a `recurring_bookings` table + background job to materialize instances. |
| ~~48~~ | ~~**Waitlist functionality**~~ 🗑️ | — | — | Removed — not desired for this business. |
| ~~49~~ | ~~**Image optimization for portfolio**~~ ✅ | XS (30min) | Frontend | **Complete May 2026.** AVIF full-size (0.72 quality, 1500px max), WebP thumbnails (250x250), lazy loading all implemented. No srcset/picture needed — business decision. |
| ~~51~~ | ~~**Test DB optimization**~~ ✅ | M (1d) | Backend | **Complete May 2026.** TestMain per package (schema migration runs once per package, not per test). Per-test setup changed to TRUNCATE-only (~60% faster). 3 missing tables added to TruncateTables. discount_test.go moved to package bookings. Dead code removed. Flaky time-of-day tests fixed. Test output streamed in real-time via tee in local-dev-2.sh. **286/288 tests passing** (was 222/224). |
---