"use strict"; const test = require("node:test"); const assert = require("node:assert/strict"); function withTempEnv(patch, run) { const previous = {}; for (const key of Object.keys(patch)) { previous[key] = process.env[key]; if (patch[key] === undefined) { delete process.env[key]; } else { process.env[key] = patch[key]; } } try { delete require.cache[require.resolve("../src/config")]; run(); } finally { for (const key of Object.keys(patch)) { if (previous[key] === undefined) { delete process.env[key]; } else { process.env[key] = previous[key]; } } delete require.cache[require.resolve("../src/config")]; } } test("config uses defaults when env is missing", () => { withTempEnv({ PORT: "", LOG_LEVEL: "", APP_BASE_URL: "", BETTER_AUTH_SECRET: "", BETTER_AUTH_BASE_PATH: "", INTERNAL_API_TOKEN: "", QWEN_TTS_MODEL: "", MINIO_SIGNED_URL_TTL_SEC: "", MINIO_USE_SSL: "", WEBHOOK_RPM: "", }, () => { const { config } = require("../src/config"); assert.equal(config.port, 3000); assert.equal(config.logLevel, "info"); assert.equal(config.appBaseUrl, "http://localhost:3000"); assert.equal(config.betterAuthBasePath, "/api/auth"); assert.equal(config.internalApiToken, ""); assert.equal(config.qwenTtsModel, "qwen-tts-latest"); assert.equal(config.minioSignedUrlTtlSec, 3600); assert.equal(config.minioUseSSL, true); assert.equal(config.rateLimits.webhookPerMinute, 120); assert.equal(config.abuse.maxJobsPerUserPerDay, 0); assert.equal(config.abuse.cooldownSec, 0); assert.deepEqual(config.abuse.denyUserIds, []); }); }); test("config reads convex/qwen/minio overrides", () => { withTempEnv({ PORT: "8080", LOG_LEVEL: "debug", APP_BASE_URL: "https://xartaudio.app", BETTER_AUTH_SECRET: "prod-secret", BETTER_AUTH_BASE_PATH: "/api/auth", BETTER_AUTH_DEV_PASSWORD: "xartaudio-dev-password", INTERNAL_API_TOKEN: "internal-token", CONVEX_DEPLOYMENT_URL: "https://example.convex.cloud", CONVEX_AUTH_TOKEN: "convex-token", CONVEX_STATE_QUERY: "state:get", CONVEX_STATE_MUTATION: "state:put", QWEN_TTS_MODEL: "qwen3-tts", MINIO_ENDPOINT: "minio.internal", MINIO_PORT: "9000", MINIO_USE_SSL: "false", MINIO_BUCKET: "audio", MINIO_SIGNED_URL_TTL_SEC: "7200", WEBHOOK_RPM: "77", ABUSE_MAX_JOBS_PER_USER_PER_DAY: "5", ABUSE_COOLDOWN_SEC: "120", ABUSE_DENY_USER_IDS: "u1,u2", }, () => { const { config } = require("../src/config"); assert.equal(config.port, 8080); assert.equal(config.logLevel, "debug"); assert.equal(config.appBaseUrl, "https://xartaudio.app"); assert.equal(config.betterAuthSecret, "prod-secret"); assert.equal(config.internalApiToken, "internal-token"); assert.equal(config.convexDeploymentUrl, "https://example.convex.cloud"); assert.equal(config.convexAuthToken, "convex-token"); assert.equal(config.convexStateQuery, "state:get"); assert.equal(config.convexStateMutation, "state:put"); assert.equal(config.qwenTtsModel, "qwen3-tts"); assert.equal(config.minioEndPoint, "minio.internal"); assert.equal(config.minioPort, 9000); assert.equal(config.minioUseSSL, false); assert.equal(config.minioBucket, "audio"); assert.equal(config.minioSignedUrlTtlSec, 7200); assert.equal(config.rateLimits.webhookPerMinute, 77); assert.equal(config.abuse.maxJobsPerUserPerDay, 5); assert.equal(config.abuse.cooldownSec, 120); assert.deepEqual(config.abuse.denyUserIds, ["u1", "u2"]); }); });