48 lines
2.4 KiB
TypeScript
48 lines
2.4 KiB
TypeScript
import { describe, expect, test } from 'bun:test';
|
|
import {
|
|
BASELINE_RELEASE_CAPABILITIES,
|
|
capabilityEnabled,
|
|
parseCapabilityAllowlist,
|
|
releaseIdIsImmutable,
|
|
} from '../src/lib/server/release-gate';
|
|
import { releaseSafetyErrors } from '../scripts/release-check';
|
|
|
|
describe('deployment rollout gate', () => {
|
|
test('keeps the existing private baseline and defaults new capabilities off', () => {
|
|
const baseline = parseCapabilityAllowlist(undefined);
|
|
expect(baseline).toEqual(BASELINE_RELEASE_CAPABILITIES);
|
|
expect(capabilityEnabled('asset_search', baseline)).toBe(true);
|
|
expect(capabilityEnabled('wallet_balance', baseline)).toBe(false);
|
|
expect(capabilityEnabled('subscriptions', baseline)).toBe(true);
|
|
});
|
|
|
|
test('supports explicit narrowing and rejects unknown or empty names', () => {
|
|
expect(parseCapabilityAllowlist('asset_search, asset_search,session_token')).toEqual(['asset_search', 'session_token']);
|
|
expect(parseCapabilityAllowlist('subscriptions')).toEqual(['subscriptions']);
|
|
expect(parseCapabilityAllowlist('')).toEqual([]);
|
|
expect(() => parseCapabilityAllowlist('asset_search,typo')).toThrow('Unknown deployment capability');
|
|
expect(() => parseCapabilityAllowlist('asset_search,')).toThrow('Unknown deployment capability');
|
|
});
|
|
|
|
test('requires a non-placeholder production release identifier', () => {
|
|
expect(releaseIdIsImmutable('local', 'production')).toBe(false);
|
|
expect(releaseIdIsImmutable('abc1234', 'production')).toBe(true);
|
|
expect(releaseIdIsImmutable('latest', 'production')).toBe(false);
|
|
expect(releaseIdIsImmutable('local', 'development')).toBe(true);
|
|
});
|
|
|
|
test('release check catches unsafe production inputs without printing values', () => {
|
|
const errors = releaseSafetyErrors({
|
|
mode: 'demo', releaseId: 'local', releaseEnvironment: 'production', dashboardImage: 'convex-dashboard:latest',
|
|
capabilityAllowlist: 'wallet_balance,unknown', trackedFiles: ['.env.example', 'secrets/app.pem'],
|
|
});
|
|
expect(errors).toEqual(expect.arrayContaining([
|
|
'APP_RELEASE_ID must be a non-placeholder immutable identifier for this release environment',
|
|
'CONVEX_DASHBOARD_IMAGE must be digest-pinned for staging/production',
|
|
'APP_MODE=demo is not permitted for a staging/production release',
|
|
'Unknown deployment capability: unknown',
|
|
'secret-like file is tracked: secrets/app.pem',
|
|
]));
|
|
});
|
|
});
|