teqo-backup/tests/int/testDatabaseLease.int.spec.ts
Francisco Ignácio Fontoura Solla bcac665cb5 Ship /campanha nuclei MVP with RBAC, invites, and vote estimates.
Adds electoral nuclei, leaderships, updates, and WhatsApp invite flows behind campaign auth, plus the consolidated schema migration that Vercel applies on deploy.
2026-07-18 15:01:56 -03:00

399 lines
13 KiB
TypeScript

// @vitest-environment node
import { getPayload, type Payload } from 'payload'
import { beforeAll, describe, expect, it } from 'vitest'
import config from '@/payload.config'
import {
acquireSharedTestDatabaseLease,
acquireTestDatabaseLease,
CAMPAIGN_INVITE_CONSENT_LEASE_KEY,
ensureInviteConsent,
startTestDatabaseLeaseAcquisition,
waitForAdvisoryLockWaiter,
withInviteConsent,
withMissingInviteConsentFixture,
withMutableConsentFixture,
withSharedTestDatabaseLease,
} from '../helpers/testDatabaseLease'
let payload: Payload
const expectExactWaiter = (
waiting: Awaited<ReturnType<typeof waitForAdvisoryLockWaiter>>,
pid: number,
mode: 'ExclusiveLock' | 'ShareLock',
) => {
expect(waiting).toEqual({
activityDatabaseOID: waiting.databaseOID,
classID: waiting.expectedClassID,
databaseOID: expect.any(Number),
expectedClassID: expect.stringMatching(/^\d+$/),
expectedObjectID: expect.stringMatching(/^\d+$/),
granted: false,
mode,
objectID: waiting.expectedObjectID,
objectSubID: 1,
pid,
virtualTransaction: expect.stringMatching(/^\d+\/\d+$/),
})
expect(waiting.databaseOID).toBeGreaterThan(0)
}
describe('test database lease', () => {
beforeAll(async () => {
payload = await getPayload({ config: await config })
})
it('blocks an independent transaction session until the first lease releases', async () => {
const first = await acquireTestDatabaseLease(payload, CAMPAIGN_INVITE_CONSENT_LEASE_KEY)
let secondEntered = false
const pendingSecond = startTestDatabaseLeaseAcquisition(
payload,
CAMPAIGN_INVITE_CONSENT_LEASE_KEY,
)
const secondPID = await pendingSecond.backendPID
const secondAcquisition = pendingSecond.acquisition.then((lease) => {
secondEntered = true
return lease
})
const waiting = await waitForAdvisoryLockWaiter(payload, {
key: `test:${CAMPAIGN_INVITE_CONSENT_LEASE_KEY}`,
mode: 'ExclusiveLock',
waiterPID: secondPID,
})
expectExactWaiter(waiting, secondPID, 'ExclusiveLock')
expect(secondEntered).toBe(false)
await first.release()
const second = await secondAcquisition
expect(secondEntered).toBe(true)
await second.release()
})
it('allows shared readers to overlap and blocks an exclusive writer until both release', async () => {
const firstReader = await acquireSharedTestDatabaseLease(
payload,
CAMPAIGN_INVITE_CONSENT_LEASE_KEY,
)
const secondReader = await acquireSharedTestDatabaseLease(
payload,
CAMPAIGN_INVITE_CONSENT_LEASE_KEY,
)
let writerEntered = false
const pendingWriter = startTestDatabaseLeaseAcquisition(
payload,
CAMPAIGN_INVITE_CONSENT_LEASE_KEY,
)
const writerPID = await pendingWriter.backendPID
const writerAcquisition = pendingWriter.acquisition.then((lease) => {
writerEntered = true
return lease
})
const waiting = await waitForAdvisoryLockWaiter(payload, {
key: `test:${CAMPAIGN_INVITE_CONSENT_LEASE_KEY}`,
mode: 'ExclusiveLock',
waiterPID: writerPID,
})
expectExactWaiter(waiting, writerPID, 'ExclusiveLock')
expect(writerEntered).toBe(false)
await firstReader.release()
const stillWaiting = await waitForAdvisoryLockWaiter(payload, {
key: `test:${CAMPAIGN_INVITE_CONSENT_LEASE_KEY}`,
mode: 'ExclusiveLock',
waiterPID: writerPID,
})
expectExactWaiter(stillWaiting, writerPID, 'ExclusiveLock')
expect(stillWaiting.virtualTransaction).toBe(waiting.virtualTransaction)
expect(writerEntered).toBe(false)
await secondReader.release()
const writer = await writerAcquisition
expect(writerEntered).toBe(true)
await writer.release()
})
it('blocks shared readers while an exclusive writer is active', async () => {
const writer = await acquireTestDatabaseLease(payload, CAMPAIGN_INVITE_CONSENT_LEASE_KEY)
let readerEntered = false
const pendingReader = startTestDatabaseLeaseAcquisition(
payload,
CAMPAIGN_INVITE_CONSENT_LEASE_KEY,
'shared',
)
const readerPID = await pendingReader.backendPID
const readerAcquisition = pendingReader.acquisition.then((lease) => {
readerEntered = true
return lease
})
const waiting = await waitForAdvisoryLockWaiter(payload, {
key: `test:${CAMPAIGN_INVITE_CONSENT_LEASE_KEY}`,
mode: 'ShareLock',
waiterPID: readerPID,
})
expectExactWaiter(waiting, readerPID, 'ShareLock')
expect(readerEntered).toBe(false)
await writer.release()
const reader = await readerAcquisition
expect(readerEntered).toBe(true)
await reader.release()
})
it('creates a missing configured consent only once under concurrent ensures', async () => {
await withMissingInviteConsentFixture(payload, async () => {
const ensured = await Promise.all([
ensureInviteConsent(payload),
ensureInviteConsent(payload),
ensureInviteConsent(payload),
])
const configured = await withSharedTestDatabaseLease(
payload,
CAMPAIGN_INVITE_CONSENT_LEASE_KEY,
() =>
payload.find({
collection: 'consent',
where: { key: { equals: 'lideranca-autopreenchimento' } },
depth: 0,
limit: 10,
}),
)
expect(new Set(ensured.map((document) => document.id))).toHaveLength(1)
expect(configured.docs).toHaveLength(1)
})
})
it('releases a shared consent scope after its callback fails', async () => {
const callbackFailure = new Error('intentional shared callback failure')
await expect(
withInviteConsent(payload, async () => {
throw callbackFailure
}),
).rejects.toBe(callbackFailure)
const writer = await acquireTestDatabaseLease(payload, CAMPAIGN_INVITE_CONSENT_LEASE_KEY)
await writer.release()
})
it('restores the exact configured consent after deletion and recreation', async () => {
const before = await withInviteConsent(payload, async (consent) => consent)
await withMutableConsentFixture(payload, async (consent) => {
await payload.delete({ collection: 'consent', id: consent.id })
await payload.create({
collection: 'consent',
data: {
key: 'lideranca-autopreenchimento',
text: {
root: {
type: 'root',
children: [
{
type: 'paragraph',
children: [{ type: 'text', text: 'Temporary recreation', version: 1 }],
direction: null,
format: '',
indent: 0,
version: 1,
},
],
direction: null,
format: '',
indent: 0,
version: 1,
},
},
},
depth: 0,
})
})
const after = await withInviteConsent(payload, async (consent) => consent)
expect(after).toEqual(before)
})
it('restores the configured consent and releases after a callback assertion failure', async () => {
const before = await withSharedTestDatabaseLease(
payload,
CAMPAIGN_INVITE_CONSENT_LEASE_KEY,
() =>
payload.find({
collection: 'consent',
where: { key: { equals: 'lideranca-autopreenchimento' } },
depth: 0,
limit: 1,
}),
)
const callbackFailure = new Error('intentional callback assertion failure')
await expect(
withMutableConsentFixture(payload, async (consent) => {
await payload.update({
collection: 'consent',
id: consent.id,
data: {
key: 'temporarily-renamed-consent',
text: {
root: {
type: 'root',
children: [
{
type: 'paragraph',
children: [{ type: 'text', text: 'Temporary text', version: 1 }],
direction: null,
format: '',
indent: 0,
version: 1,
},
],
direction: null,
format: '',
indent: 0,
version: 1,
},
},
},
})
throw callbackFailure
}),
).rejects.toBe(callbackFailure)
const after = await withSharedTestDatabaseLease(
payload,
CAMPAIGN_INVITE_CONSENT_LEASE_KEY,
() =>
payload.find({
collection: 'consent',
where: { key: { equals: 'lideranca-autopreenchimento' } },
depth: 0,
limit: 1,
}),
)
if (before.docs[0]) {
expect(after.docs[0]).toMatchObject({
id: before.docs[0].id,
key: before.docs[0].key,
text: before.docs[0].text,
})
} else {
expect(after.docs).toHaveLength(0)
}
const subsequent = await acquireTestDatabaseLease(payload, CAMPAIGN_INVITE_CONSENT_LEASE_KEY)
await subsequent.release()
})
it('aggregates callback and restore lease acquisition failures in original order', async () => {
const callbackFailure = new Error('intentional callback failure')
const restoreAcquisitionFailure = new Error('intentional restore acquisition failure')
const failure = await withMissingInviteConsentFixture(
payload,
async () => {
throw callbackFailure
},
{
beforeRestoreLeaseAcquire: async () => {
throw restoreAcquisitionFailure
},
},
).catch((error: unknown) => error)
expect(failure).toBeInstanceOf(AggregateError)
expect((failure as AggregateError).errors).toEqual([
callbackFailure,
restoreAcquisitionFailure,
])
})
it('aggregates snapshot setup and setup lease release failures in original order', async () => {
const snapshotFailure = new Error('intentional snapshot setup failure')
const releaseFailure = new Error('intentional setup release failure')
const failure = await withMissingInviteConsentFixture(
payload,
async () => undefined,
{
beforeSnapshotSetup: async () => {
throw snapshotFailure
},
beforeSetupLeaseRelease: async () => {
throw releaseFailure
},
},
).catch((error: unknown) => error)
expect(failure).toBeInstanceOf(AggregateError)
expect((failure as AggregateError).errors).toEqual([snapshotFailure, releaseFailure])
const subsequent = await acquireTestDatabaseLease(payload, CAMPAIGN_INVITE_CONSENT_LEASE_KEY)
await subsequent.release()
})
it('rolls back a failed missing-consent setup and preserves rollback errors', async () => {
const before = await withInviteConsent(payload, async (consent) => consent)
const releaseFailure = new Error('intentional setup release failure after deletion')
const rollbackFailure = new Error('intentional setup rollback cleanup failure')
let callbackCalled = false
const failure = await withMissingInviteConsentFixture(
payload,
async () => {
callbackCalled = true
},
{
beforeSetupLeaseRelease: async () => {
throw releaseFailure
},
beforeSetupLeaseRollback: async () => {
throw rollbackFailure
},
},
).catch((error: unknown) => error)
expect(callbackCalled).toBe(false)
expect(failure).toBeInstanceOf(AggregateError)
expect((failure as AggregateError).errors).toEqual([releaseFailure, rollbackFailure])
const after = await withInviteConsent(payload, async (consent) => consent)
expect(after).toEqual(before)
const subsequent = await acquireTestDatabaseLease(payload, CAMPAIGN_INVITE_CONSENT_LEASE_KEY)
await subsequent.release()
})
it('keeps an absent consent absent when missing-consent setup release fails', async () => {
const consentKey = `absent-consent-${Date.now()}-${Math.random()}`
const leaseKey = `absent-consent-lease-${Date.now()}-${Math.random()}`
const releaseFailure = new Error('intentional absent setup release failure')
const failure = await withMissingInviteConsentFixture(
payload,
async () => {
throw new Error('callback must not run')
},
{
consentKey,
leaseKey,
beforeSetupLeaseRelease: async () => {
throw releaseFailure
},
},
).catch((error: unknown) => error)
expect(failure).toBe(releaseFailure)
const configured = await payload.find({
collection: 'consent',
where: { key: { equals: consentKey } },
depth: 0,
limit: 1,
})
expect(configured.docs).toHaveLength(0)
const subsequent = await acquireTestDatabaseLease(payload, leaseKey)
await subsequent.release()
})
})