Files
multi-simadmin/apps/api/src/production-readiness.release.test.ts
T

68 lines
2.2 KiB
TypeScript

import Database from 'better-sqlite3';
import { describe, expect, it } from 'vitest';
import { migrateDatabase } from './infrastructure/database/migrations.js';
import { createProductionReadiness } from './production-readiness.js';
function fixture() {
const db = new Database(':memory:');
migrateDatabase(db);
return db;
}
describe('production readiness release gates', () => {
it('fails closed on pending credentials, recovery markers, missing assets and configured gateway failure', async () => {
const db = fixture();
db.prepare(
"INSERT INTO app_settings(key,value_json,created_at,updated_at) VALUES('legacyImport.pendingCredentials','2','x','x')",
).run();
const readiness = createProductionReadiness({
db,
gatewayToken: 'x'.repeat(32),
keychainMetadataCheck: async () => true,
assetsCheck: async () => false,
recoveryMarkersCheck: async () => 1,
upstreamGatewayCheck: async () => false,
});
await expect(readiness()).resolves.toEqual({
ready: false,
checks: {
database: 'ready',
migrations: 'ready',
gatewayAuth: 'ready',
keychain: 'ready',
pendingCredentials: 'pending:2',
recoveryMarkers: 'present:1',
assets: 'unavailable',
upstreamGateway: 'unavailable',
},
});
db.close();
});
it('requires explicit release checks and reports ready only when every gate passes', async () => {
const db = fixture();
const missing = await createProductionReadiness({
db,
gatewayToken: 'x'.repeat(32),
keychainMetadataCheck: async () => true,
})();
expect(missing.ready).toBe(false);
expect(missing.checks).toMatchObject({
assets: 'unconfigured',
recoveryMarkers: 'unconfigured',
upstreamGateway: 'unconfigured',
pendingCredentials: 'ready',
});
const ready = await createProductionReadiness({
db,
gatewayToken: 'x'.repeat(32),
keychainMetadataCheck: async () => true,
assetsCheck: async () => true,
recoveryMarkersCheck: async () => 0,
upstreamGatewayCheck: async () => true,
})();
expect(ready.ready).toBe(true);
db.close();
});
});