import { nanoid } from 'nanoid' import * as TestApp from '../../../test/App.js' import * as Runtime from '../../../test/runtime.js' import * as Db from '../Db.js' import * as ApiKeyRevocations from './apiKeyRevocations.js' describe('prune', () => { test('qualifies tables in a schema-scoped database', async () => { const schema = `t_${nanoid()}` const migrator = Db.postgres({ connectionString: Runtime.postgresUrl, schema }) await migrator.migrate() await migrator.close() // A fresh pool keeps the default search path, matching preview Workers. const db = Db.postgres({ connectionString: Runtime.postgresUrl, schema }) const expired = '2026-01-01T00:00:00.000Z' await db.kysely .insertInto('api_key_revocations') .values({ expiresAt: expired, id: 'key_scoped', orgId: null, revokedAt: expired }) .execute() expect(await ApiKeyRevocations.prune(db, new Date('2026-01-02T00:00:00.000Z'))).toBe(1) await db.close() }) test('concurrent pruners delete admissions for their exact fence batches', async () => { const db = TestApp.database() const count = ApiKeyRevocations.pruneLimit + 1 const expiresAt = '2026-01-01T00:00:00.000Z' const ids = Array.from({ length: count }, (_, index) => `key_prune_${index}`) await db.kysely .insertInto('api_key_revocations') .values( ids.map((id) => ({ expiresAt, id, orgId: null, revokedAt: expiresAt, })), ) .execute() await db.kysely .insertInto('api_key_admissions') .values( ids.map((id) => ({ expiresAt: null, id, orgId: 'org_prune', projectId: null, })), ) .execute() const deleted = await Promise.all([ ApiKeyRevocations.prune(db, new Date('2026-01-02T00:00:00.000Z')), ApiKeyRevocations.prune(db, new Date('2026-01-02T00:00:00.000Z')), ]) expect(deleted.reduce((total, value) => total + value, 0)).toBe(count) const [admissions, revocations] = await Promise.all([ db.kysely .selectFrom('api_key_admissions') .select((eb) => eb.fn.countAll().as('count')) .executeTakeFirstOrThrow(), db.kysely .selectFrom('api_key_revocations') .select((eb) => eb.fn.countAll().as('count')) .executeTakeFirstOrThrow(), ]) expect(Number(admissions.count)).toBe(0) expect(Number(revocations.count)).toBe(0) }) })