test(config): cover production validation

This commit is contained in:
Saravana Achu Mac 2026-05-05 09:42:20 -07:00
parent 772b4bfc19
commit 8007fac947

View File

@ -0,0 +1,137 @@
import { describe, expect, it } from 'vitest';
import { DEFAULT_DEV_JWT_SECRET, envSchema, parseConfig } from './config.js';
const SAFE_PROD_ENV = {
NODE_ENV: 'production',
JWT_SECRET: 'prod-secret-at-least-32-characters',
DB_PROVIDER: 'cosmos',
COSMOS_ENDPOINT: 'https://cosmos.example.com',
COSMOS_KEY: 'cosmos-key',
COSMOS_DATABASE: 'bytelyst',
FIELD_ENCRYPT_ENABLED: 'true',
FIELD_ENCRYPT_KEY_PROVIDER: 'env',
FIELD_ENCRYPT_KEY: 'field-key-material',
} satisfies Record<string, string>;
function expectConfigIssue(env: Record<string, string | undefined>, path: string, message: string): void {
const result = envSchema.safeParse(env);
expect(result.success).toBe(false);
if (result.success) return;
expect(result.error.issues).toEqual(
expect.arrayContaining([
expect.objectContaining({
path: [path],
message,
}),
])
);
}
describe('backend config', () => {
it('keeps development ergonomics for local memory mode and empty JWT env values', () => {
const config = parseConfig({
NODE_ENV: 'development',
JWT_SECRET: '',
DB_PROVIDER: 'memory',
FIELD_ENCRYPT_KEY_PROVIDER: 'memory',
TELEMETRY_ENABLED: 'false',
FEATURE_FLAGS_ENABLED: '0',
});
expect(config.JWT_SECRET).toBe(DEFAULT_DEV_JWT_SECRET);
expect(config.DB_PROVIDER).toBe('memory');
expect(config.TELEMETRY_ENABLED).toBe(false);
expect(config.FEATURE_FLAGS_ENABLED).toBe(false);
});
it('accepts a safe production configuration', () => {
const config = parseConfig(SAFE_PROD_ENV);
expect(config.NODE_ENV).toBe('production');
expect(config.DB_PROVIDER).toBe('cosmos');
expect(config.FIELD_ENCRYPT_ENABLED).toBe(true);
});
it('rejects missing production JWT secret because it would fall back to the dev default', () => {
expectConfigIssue(
{ ...SAFE_PROD_ENV, JWT_SECRET: undefined },
'JWT_SECRET',
'Production JWT_SECRET must not use the development default'
);
});
it('rejects the development JWT secret in production', () => {
expectConfigIssue(
{ ...SAFE_PROD_ENV, JWT_SECRET: DEFAULT_DEV_JWT_SECRET },
'JWT_SECRET',
'Production JWT_SECRET must not use the development default'
);
});
it('rejects short production JWT secrets', () => {
expectConfigIssue(
{ ...SAFE_PROD_ENV, JWT_SECRET: 'short-prod-secret' },
'JWT_SECRET',
'Production JWT_SECRET must be at least 32 characters'
);
});
it('rejects memory DB in production', () => {
expectConfigIssue(
{ ...SAFE_PROD_ENV, DB_PROVIDER: 'memory' },
'DB_PROVIDER',
'Production DB_PROVIDER must be cosmos'
);
});
it('rejects missing production Cosmos credentials', () => {
expectConfigIssue(
{ ...SAFE_PROD_ENV, COSMOS_ENDPOINT: '', COSMOS_KEY: '', COSMOS_DATABASE: '' },
'COSMOS_ENDPOINT',
'COSMOS_ENDPOINT is required in production'
);
expectConfigIssue(
{ ...SAFE_PROD_ENV, COSMOS_ENDPOINT: '', COSMOS_KEY: '', COSMOS_DATABASE: '' },
'COSMOS_KEY',
'COSMOS_KEY is required in production'
);
expectConfigIssue(
{ ...SAFE_PROD_ENV, COSMOS_ENDPOINT: '', COSMOS_KEY: '', COSMOS_DATABASE: '' },
'COSMOS_DATABASE',
'COSMOS_DATABASE is required in production'
);
});
it('rejects disabled field encryption in production', () => {
expectConfigIssue(
{ ...SAFE_PROD_ENV, FIELD_ENCRYPT_ENABLED: 'false' },
'FIELD_ENCRYPT_ENABLED',
'Field encryption must be enabled in production'
);
});
it('rejects production memory encryption provider', () => {
expectConfigIssue(
{ ...SAFE_PROD_ENV, FIELD_ENCRYPT_KEY_PROVIDER: 'memory', FIELD_ENCRYPT_KEY: '' },
'FIELD_ENCRYPT_KEY_PROVIDER',
'Production FIELD_ENCRYPT_KEY_PROVIDER must be akv or env'
);
});
it('requires key material when FIELD_ENCRYPT_KEY_PROVIDER=env', () => {
expectConfigIssue(
{ ...SAFE_PROD_ENV, FIELD_ENCRYPT_KEY_PROVIDER: 'env', FIELD_ENCRYPT_KEY: '' },
'FIELD_ENCRYPT_KEY',
'FIELD_ENCRYPT_KEY is required when FIELD_ENCRYPT_KEY_PROVIDER=env'
);
});
it('requires a Key Vault URL when FIELD_ENCRYPT_KEY_PROVIDER=akv', () => {
expectConfigIssue(
{ ...SAFE_PROD_ENV, FIELD_ENCRYPT_KEY_PROVIDER: 'akv', FIELD_ENCRYPT_KEY: '', AZURE_KEYVAULT_URL: '' },
'AZURE_KEYVAULT_URL',
'AZURE_KEYVAULT_URL is required when FIELD_ENCRYPT_KEY_PROVIDER=akv'
);
});
});