import { describe, it, expect, beforeAll } from 'vitest' import * as db from '../src/database.js' const pubkey = 'dup-test-' + Date.now() const email = 'dup-test-' + Date.now() + '@example.com' let token: string describe('Duplicate subscription prevention — idempotent re-register after confirm', () => { beforeAll(async () => { await db.migrate() }) it('registers a subscription (fresh)', async () => { const sub = await db.insertSubscription(pubkey, email, 'daily') expect(sub).toBeTruthy() expect(sub!.confirmed_at).toBeFalsy() expect(sub!.unsubscribed_at).toBeFalsy() token = sub!.key }) it('confirms the subscription', async () => { const result = await db.confirmSubscription(token) expect(result).toBeTruthy() expect(result!.alreadyConfirmed).toBe(false) expect(result!.sub.confirmed_at).toBeTruthy() }) it('re-registers with the same email and frequency (idempotent PUT)', async () => { // This simulates a second PUT from the client with identical params. // The bug would create a second active row + send a new confirmation email. const sub = await db.insertSubscription(pubkey, email, 'daily') expect(sub).toBeTruthy() // Must return the existing confirmed row, NOT a fresh unconfirmed row expect(sub!.confirmed_at).toBeTruthy() expect(sub!.unsubscribed_at).toBeFalsy() // The key must remain unchanged — a new row would have a different key expect(sub!.key).toBe(token) }) it('has exactly one active row for this pubkey', async () => { // getSubscriptionByPubkey filters by unsubscribed_at IS NULL and // returns at most one row (enforced by the partial unique index). // If a second active row exists, the index is absent or bypassed. const active = await db.getSubscriptionByPubkey(pubkey) expect(active).toBeTruthy() expect(active!.confirmed_at).toBeTruthy() expect(active!.key).toBe(token) }) })