Brings the test count from 29 → 93 across 8 files. Each new file
exercises one feature area through the HTTP layer using a shared
helper that spins up a fresh Hono app on a fresh temp DB.
New test files:
- tests/helpers.ts: setupTestApp(), signupAndGetCookie(),
req()/reqJson() convenience, the ttest()
helper that wraps test() with a 30s
timeout (Argon2id signups blow the 5s
default).
- tests/activities.test.ts (17 tests): create + read per visibility,
owner_id stripping on semi, visibility
transitions (column wipes, tag-row
clearing), validation rejects, delete +
update authz (owner / moderator),
display-name fallback chain.
- tests/engagement.test.ts (10 tests): heart toggle + idempotency
+ private-refusal + auth gate; same for
bookmarks; tag normalisation + autocomplete
prefix-match + tag-store-never-sees-private
+ tag-update-deccrements-old.
- tests/admin.test.ts (9 tests): first-user-auto-admin, admin gate
(401/403/200), promote/demote, last-admin
guard, admin-implies-moderator (via
feedback-list endpoint), user-list shape,
admin-can-delete-semi crossover.
- tests/social.test.ts (11 tests): feedback submit/list/done/delete +
admin-only gates; invite create/claim/cancel,
single-use behaviour, audit-trail preservation
on claimed invites, cross-user delete blocked;
settings GET (public), closed-registry gate
with invite bypass.
- tests/profile.test.ts (17 tests): display_name + username updates,
username validation (incl. silent
lowercasing), username uniqueness via 409,
public-list opt-in / opt-out, full login
flow (challenge → login → me), wrong-verifier
vs unknown-email both 401, logout
invalidates session, password change happy
path (re-login with new + old fails),
duplicate email 409, invalid email 400.
**Real bug uncovered**: the invite signup flow hit a `FOREIGN KEY
constraint failed` because `claimInvite()` does `UPDATE invites SET
claimed_by_user_id = <new user id>` *before* the user INSERT runs.
With foreign_keys=ON (which we run with), the FK on
`invites.claimed_by_user_id → users.id` blows up immediately. No live
session had exercised invite signup end-to-end, so the bug was
invisible.
Fix in server/auth.ts: `PRAGMA defer_foreign_keys = ON` inside the
signup transaction, so FK checks happen at COMMIT after the user
INSERT has run. The PRAGMA is per-transaction and resets automatically.
93/93 tests pass; typecheck clean; build succeeds.