import { describe, it, expect, beforeEach, afterAll } from '@jest/globals'; import { assertAiServiceConfig } from './check-ai-service-config'; /** * Pre-flight validation contract for `AI_SERVICE_*` env vars. * Mirrors the test posture of `check-log-user-id-salt.spec.ts` — * each rejection path produces an actionable error message. */ const ORIGINAL_ENV = { ...process.env }; function setEnv(values: Record): void { for (const [key, value] of Object.entries(values)) { if (value === undefined) { delete process.env[key]; } else { process.env[key] = value; } } } beforeEach(() => { delete process.env['AI_SERVICE_GRPC_ENDPOINT']; delete process.env['AI_SERVICE_CLIENT_ID']; delete process.env['AI_SERVICE_GRPC_TLS']; }); afterAll(() => { process.env = { ...ORIGINAL_ENV }; }); describe('assertAiServiceConfig', () => { it('returns the parsed config when every required var is present', () => { setEnv({ AI_SERVICE_GRPC_ENDPOINT: 'apf-ai-service:8080', AI_SERVICE_CLIENT_ID: 'apf-portal-dev', AI_SERVICE_GRPC_TLS: 'false', }); expect(assertAiServiceConfig()).toEqual({ endpoint: 'apf-ai-service:8080', clientId: 'apf-portal-dev', useTls: false, }); }); it('defaults useTls to true when AI_SERVICE_GRPC_TLS is unset', () => { setEnv({ AI_SERVICE_GRPC_ENDPOINT: 'apf-ai.internal:443', AI_SERVICE_CLIENT_ID: 'apf-portal-prod', }); expect(assertAiServiceConfig().useTls).toBe(true); }); it('throws when AI_SERVICE_GRPC_ENDPOINT is missing', () => { setEnv({ AI_SERVICE_CLIENT_ID: 'apf-portal-dev' }); expect(() => assertAiServiceConfig()).toThrow(/AI_SERVICE_GRPC_ENDPOINT is not set/); }); it('throws when AI_SERVICE_GRPC_ENDPOINT does not match host:port', () => { setEnv({ AI_SERVICE_GRPC_ENDPOINT: 'no-port-here', AI_SERVICE_CLIENT_ID: 'apf-portal-dev', }); expect(() => assertAiServiceConfig()).toThrow(/must match "host:port"/); }); it('throws when AI_SERVICE_CLIENT_ID is missing', () => { setEnv({ AI_SERVICE_GRPC_ENDPOINT: 'apf-ai-service:8080' }); expect(() => assertAiServiceConfig()).toThrow(/AI_SERVICE_CLIENT_ID is not set/); }); it('throws when AI_SERVICE_CLIENT_ID has invalid characters', () => { setEnv({ AI_SERVICE_GRPC_ENDPOINT: 'apf-ai-service:8080', AI_SERVICE_CLIENT_ID: 'Apf Portal Dev', }); expect(() => assertAiServiceConfig()).toThrow(/lowercase kebab-case slug/); }); it('throws when AI_SERVICE_GRPC_TLS is neither "true" nor "false"', () => { setEnv({ AI_SERVICE_GRPC_ENDPOINT: 'apf-ai-service:8080', AI_SERVICE_CLIENT_ID: 'apf-portal-dev', AI_SERVICE_GRPC_TLS: 'yes', }); expect(() => assertAiServiceConfig()).toThrow(/must be "true" or "false"/); }); });