Files
mercadodevida/project/src/app/tests/config-flags.test.ts
rikrdo 4851692031 feat(F-004): typed fail-fast config and feature flag module
- loadConfig: pure over env object, accumulates all problems, names var names only
- DATABASE_URL now required at startup; PORT/HOST/LOG_LEVEL/NODE_ENV/REDIS_URL defaulted
- flags module behind FeatureFlagProvider; unknown flags OFF; runtime setEnabled (no redeploy)
- buildApp decorates app.flags; server.ts fail-fast before app boot
- tests caught and fixed flag-store case-normalization bug before gates
- zero new dependencies; all gates approved; verify.sh green
2026-08-14 22:29:18 +02:00

48 lines
1.9 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { buildApp } from '../build-app.js';
import { createFlagStore } from '../../modules/flags/index.js';
import { createLogger } from '../../infrastructure/logging/logger.js';
import type { DestinationStream } from 'pino';
function silentLogger() {
const destination: DestinationStream = { write: () => undefined };
return createLogger({ level: 'info', destination });
}
describe('feature flags wiring (composition)', () => {
it('default flags are all OFF when no store is injected', async () => {
const app = await buildApp({ logger: silentLogger() });
app.get('/__test/guarded', async (request) => {
return { enabled: request.server.flags.isEnabled('risky_path') };
});
const response = await app.inject({ method: 'GET', url: '/__test/guarded' });
expect(response.json()).toEqual({ enabled: false });
await app.close();
});
it('guarded path is skipped when the flag is off and runs once enabled at runtime', async () => {
const store = createFlagStore({ risky_path: false });
const app = await buildApp({ logger: silentLogger(), flags: store });
app.get('/__test/guarded', async (request) => {
if (!request.server.flags.isEnabled('risky_path')) {
return { path: 'skipped' };
}
return { path: 'executed' };
});
const off = await app.inject({ method: 'GET', url: '/__test/guarded' });
expect(off.json()).toEqual({ path: 'skipped' });
// Activation without redeploy: same running app instance.
store.setEnabled('risky_path', true);
const on = await app.inject({ method: 'GET', url: '/__test/guarded' });
expect(on.json()).toEqual({ path: 'executed' });
store.setEnabled('risky_path', false);
const offAgain = await app.inject({ method: 'GET', url: '/__test/guarded' });
expect(offAgain.json()).toEqual({ path: 'skipped' });
await app.close();
});
});