/** * test/config.test.ts * * Testes unitários para a validação da configuração carregada por * variáveis de ambiente (src/config/env.config.ts). */ import { describe, it } from "node:test"; import assert from "node:assert/strict"; import { loadSchedulingConfig } from "../src/config/env.config.js"; function env( overrides: Record = {}, ): NodeJS.ProcessEnv { return { SCHEDULING_PROVIDER: "zpro", ZPRO_BASE_URL: "https://zpro.example.com", ZPRO_API_TOKEN: "token-secreto", ZPRO_API_ID: "api-1", ZPRO_INSTANCE_ID: "", ...overrides, } as NodeJS.ProcessEnv; } describe("loadSchedulingConfig", () => { it("carrega uma configuração válida do Z-PRO", () => { const config = loadSchedulingConfig( env({ ZPRO_INSTANCE_ID: "instancia-1" }), ); assert.deepEqual(config, { provider: "zpro", baseUrl: "https://zpro.example.com", apiToken: "token-secreto", apiId: "api-1", instanceId: "instancia-1", }); }); it("define o provider como 'zpro' por padrão", () => { const withoutProvider = env(); delete withoutProvider.SCHEDULING_PROVIDER; const config = loadSchedulingConfig(withoutProvider); assert.equal(config.provider, "zpro"); }); it("trata ZPRO_INSTANCE_ID vazio como ausente", () => { const config = loadSchedulingConfig(env()); assert.equal(config.instanceId, undefined); }); it("falha quando ZPRO_BASE_URL está ausente", () => { const missingBaseUrl = env(); delete missingBaseUrl.ZPRO_BASE_URL; assert.throws( () => loadSchedulingConfig(missingBaseUrl), (error: unknown) => { assert.ok(error instanceof Error); assert.match(error.message, /ZPRO_BASE_URL/); return true; }, ); }); it("falha quando ZPRO_API_TOKEN está ausente", () => { const missingToken = env(); delete missingToken.ZPRO_API_TOKEN; assert.throws( () => loadSchedulingConfig(missingToken), (error: unknown) => { assert.ok(error instanceof Error); assert.match(error.message, /ZPRO_API_TOKEN/); return true; }, ); }); it("falha quando ZPRO_API_ID está ausente", () => { const missingApiId = env(); delete missingApiId.ZPRO_API_ID; assert.throws( () => loadSchedulingConfig(missingApiId), (error: unknown) => { assert.ok(error instanceof Error); assert.match(error.message, /ZPRO_API_ID/); return true; }, ); }); it("não expõe o token em mensagens de erro", () => { const missingBaseUrl = env(); delete missingBaseUrl.ZPRO_BASE_URL; assert.throws( () => loadSchedulingConfig(missingBaseUrl), (error: unknown) => { assert.ok(error instanceof Error); assert.ok(!error.message.includes("token-secreto")); return true; }, ); }); it("rejeita um provider desconhecido", () => { assert.throws( () => loadSchedulingConfig(env({ SCHEDULING_PROVIDER: "syslife" })), (error: unknown) => { assert.ok(error instanceof Error); assert.match(error.message, /SCHEDULING_PROVIDER/); return true; }, ); }); it("não exige variáveis ZPRO_* quando o provider é 'klingo'", () => { const config = loadSchedulingConfig({ SCHEDULING_PROVIDER: "klingo", KLINGO_BASE_URL: "https://klingo.example.com", KLINGO_APP_TOKEN: "app-token-secreto", } as NodeJS.ProcessEnv); assert.deepEqual(config, { provider: "klingo", baseUrl: "https://klingo.example.com", appToken: "app-token-secreto", }); }); it("falha quando KLINGO_BASE_URL está ausente com provider 'klingo'", () => { assert.throws( () => loadSchedulingConfig({ SCHEDULING_PROVIDER: "klingo", KLINGO_APP_TOKEN: "app-token-secreto", } as NodeJS.ProcessEnv), (error: unknown) => { assert.ok(error instanceof Error); assert.match(error.message, /KLINGO_BASE_URL/); return true; }, ); }); it("falha quando KLINGO_APP_TOKEN está ausente com provider 'klingo'", () => { assert.throws( () => loadSchedulingConfig({ SCHEDULING_PROVIDER: "klingo", KLINGO_BASE_URL: "https://klingo.example.com", } as NodeJS.ProcessEnv), (error: unknown) => { assert.ok(error instanceof Error); assert.match(error.message, /KLINGO_APP_TOKEN/); return true; }, ); }); it("não exige variáveis KLINGO_* quando o provider é 'zpro'", () => { const config = loadSchedulingConfig(env()); assert.equal(config.provider, "zpro"); }); });