144 lines
4.9 KiB
JavaScript
144 lines
4.9 KiB
JavaScript
"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({
|
|
NODE_ENV: "",
|
|
PORT: "",
|
|
LOG_LEVEL: "",
|
|
APP_BASE_URL: "",
|
|
BETTER_AUTH_SECRET: "",
|
|
BETTER_AUTH_BASE_PATH: "",
|
|
INTERNAL_API_TOKEN: "",
|
|
CONVEX_URL: "",
|
|
QWEN_TTS_MODEL: "",
|
|
MINIO_SIGNED_URL_TTL_SEC: "",
|
|
MINIO_USE_SSL: "",
|
|
WEBHOOK_RPM: "",
|
|
ALLOW_IN_MEMORY_STATE_FALLBACK: "",
|
|
}, () => {
|
|
const { config } = require("../src/config");
|
|
assert.equal(config.nodeEnv, "development");
|
|
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.xOAuthClientId, "");
|
|
assert.equal(config.xOAuthClientSecret, "");
|
|
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.allowInMemoryStateFallback, true);
|
|
assert.equal(config.enableDevRoutes, true);
|
|
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({
|
|
NODE_ENV: "production",
|
|
PORT: "8080",
|
|
LOG_LEVEL: "debug",
|
|
APP_BASE_URL: "https://xartaudio.app",
|
|
BETTER_AUTH_SECRET: "prod-secret",
|
|
BETTER_AUTH_BASE_PATH: "/api/auth",
|
|
X_OAUTH_CLIENT_ID: "x-client-id",
|
|
X_OAUTH_CLIENT_SECRET: "x-client-secret",
|
|
INTERNAL_API_TOKEN: "internal-token",
|
|
CONVEX_DEPLOYMENT_URL: "https://example.convex.cloud",
|
|
CONVEX_URL: "https://should-not-win.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",
|
|
ALLOW_IN_MEMORY_STATE_FALLBACK: "",
|
|
}, () => {
|
|
const { config } = require("../src/config");
|
|
assert.equal(config.nodeEnv, "production");
|
|
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.xOAuthClientId, "x-client-id");
|
|
assert.equal(config.xOAuthClientSecret, "x-client-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"]);
|
|
assert.equal(config.allowInMemoryStateFallback, false);
|
|
assert.equal(config.enableDevRoutes, false);
|
|
});
|
|
});
|
|
|
|
test("allow in-memory fallback can be explicitly enabled in production", () => {
|
|
withTempEnv({
|
|
NODE_ENV: "production",
|
|
ALLOW_IN_MEMORY_STATE_FALLBACK: "true",
|
|
}, () => {
|
|
const { config } = require("../src/config");
|
|
assert.equal(config.allowInMemoryStateFallback, true);
|
|
});
|
|
});
|
|
|
|
test("config falls back to CONVEX_URL when deployment url variable is absent", () => {
|
|
withTempEnv({
|
|
CONVEX_DEPLOYMENT_URL: "",
|
|
CONVEX_URL: "https://from-convex-url.convex.cloud",
|
|
}, () => {
|
|
const { config } = require("../src/config");
|
|
assert.equal(config.convexDeploymentUrl, "https://from-convex-url.convex.cloud");
|
|
});
|
|
});
|