Replaces the reject-route test (behavior removed) with coverage of the
replacement flow, run against the shared dev DB per the doctrine:
fresh per-run regular user for deterministic claims, uuid-suffixed
identifiers so UNIQUE(device_identifier) stays clear across runs, and
device rows cascade away with the fresh user — testuser is untouched.
- TestPairingClaimHappyPath: lookup normalizes spaced digits, does not
bind; claim binds to the claimer only; the device's status poll then
delivers a token matching the stored row.
- TestPairingWrongCodeIsGenericAndNonDestructive: a miss answers the
generic invalid-code error and leaves the real code claimable.
- TestPairingClaimBindsClaimerOnly: the admin account has no device
row for another user's claim, and the used code answers 409.
- TestPairingReRegisterRetiresPriorCode: the old code and its
registration UUID both die; the fresh code claims.
- TestPairingCancelByRegistrationUUID: cancel is idempotent, kills only
its own registration (code and poll), and leaves a sibling
registration untouched.
- TestPairingAttemptRateLimit: 13th lookup/claim attempt in a minute is
refused with 429 (uses the fresh regular user — the limiter is
process-global, so sibling tests sharing a token would otherwise
pre-spend the budget).
- TestListPendingRegistrations now pins the invisibility invariant: a
live registration appears in no account's pending list, total 0.
- TestRejectDeviceRegistrationRemoved pins the reject route's removal
(404/405).