parent
4a74a5284b
commit
0ff8984a94
2 changed files with 46 additions and 10 deletions
|
|
@ -181,13 +181,13 @@ export const updateSubscription = instrument(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const getMostRecentTombstonedSubscription = async (pubkey: string) =>
|
const getMostRecentTombstonedSubscription = async (pubkey: string, email: string) =>
|
||||||
parseSubscription(
|
parseSubscription(
|
||||||
await get(
|
await get(
|
||||||
`SELECT * FROM subscriptions
|
`SELECT * FROM subscriptions
|
||||||
WHERE pubkey = ? AND unsubscribed_at IS NOT NULL
|
WHERE pubkey = ? AND email = ? AND unsubscribed_at IS NOT NULL
|
||||||
ORDER BY created_at DESC, id DESC LIMIT 1`,
|
ORDER BY rowid DESC LIMIT 1`,
|
||||||
[pubkey]
|
[pubkey, email]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -209,13 +209,13 @@ export const insertSubscription = instrument(
|
||||||
return assertResult(await updateSubscription(existing, email, frequency, hour, minute, dayOfWeek, timezone))
|
return assertResult(await updateSubscription(existing, email, frequency, hour, minute, dayOfWeek, timezone))
|
||||||
}
|
}
|
||||||
|
|
||||||
// No active row. If this account previously subscribed to the same email
|
// No active row. If this account previously subscribed to this email and
|
||||||
// and was unsubscribed, reactivate that row instead of inserting a fresh
|
// was unsubscribed, reactivate the most recent such row instead of inserting
|
||||||
// one. Otherwise every turn-on → turn-off → turn-on cycle would create a
|
// a fresh one. Otherwise every turn-on → turn-off → turn-on cycle would
|
||||||
// new row, abandoning the confirmed state (and the already-known key).
|
// create a new row, abandoning the confirmed state (and the already-known key).
|
||||||
const tombstoned = await getMostRecentTombstonedSubscription(pubkey)
|
const tombstoned = await getMostRecentTombstonedSubscription(pubkey, email)
|
||||||
|
|
||||||
if (tombstoned?.email === email) {
|
if (tombstoned) {
|
||||||
try {
|
try {
|
||||||
return assertResult(await reactivateSubscription(tombstoned, frequency))
|
return assertResult(await reactivateSubscription(tombstoned, frequency))
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
|
|
||||||
|
|
@ -150,3 +150,39 @@ describe('Re-subscribe with a changed frequency reactivates and updates cadence'
|
||||||
expect(rows).toHaveLength(1)
|
expect(rows).toHaveLength(1)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('Re-subscribe with mixed emails for one pubkey picks the right row', () => {
|
||||||
|
const pubkey = unique('resub-mixed')
|
||||||
|
const emailA = `${unique('resub-mixed-a')}@example.com`
|
||||||
|
const emailB = `${unique('resub-mixed-b')}@example.com`
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await db.migrate()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('creates and tombstones two different emails, then re-subscribes email B', async () => {
|
||||||
|
// Email A cycle
|
||||||
|
const subA = await db.insertSubscription(pubkey, emailA, 'daily')
|
||||||
|
await db.unsubscribeSubscription(subA.key)
|
||||||
|
|
||||||
|
// Email B cycle
|
||||||
|
const subB = await db.insertSubscription(pubkey, emailB, 'daily')
|
||||||
|
const bId = subB!.id
|
||||||
|
await db.unsubscribeSubscription(subB.key)
|
||||||
|
|
||||||
|
// Re-subscribe with email B — must reactivate B's own row, not A's,
|
||||||
|
// and must not resurrect the wrong email.
|
||||||
|
const resigned = await db.insertSubscription(pubkey, emailB, 'daily')
|
||||||
|
const active = await db.getSubscriptionByPubkey(pubkey)
|
||||||
|
|
||||||
|
expect(active!.id).toBe(bId)
|
||||||
|
expect(active!.id).not.toBe(subA!.id)
|
||||||
|
expect(active!.email).toBe(emailB)
|
||||||
|
expect(active!.unsubscribed_at).toBeFalsy()
|
||||||
|
|
||||||
|
const rows = await db.getAllSubscriptionsByPubkey(pubkey)
|
||||||
|
expect(rows).toHaveLength(2)
|
||||||
|
expect(rows.filter(r => r.email === emailA)).toHaveLength(1)
|
||||||
|
expect(rows.filter(r => r.email === emailB)).toHaveLength(1)
|
||||||
|
})
|
||||||
|
})
|
||||||
Loading…
Reference in a new issue