import assert from 'node:assert/strict'; import test from 'node:test'; import { EnvironmentConfigurationError, loadConfig } from '../src/config/env.js'; const validEnvironment: NodeJS.ProcessEnv = { NODE_ENV: 'test', HOST: '127.0.0.1', PORT: '4400', DATABASE_URL: 'postgres://user:password@127.0.0.1:5432/saas_voc', MIGRATION_DATABASE_URL: 'postgres://owner:password@127.0.0.1:5432/saas_voc', PARSE_APP_ID: 'test-app-id', PARSE_MASTER_KEY: 'a'.repeat(32), PARSE_MAINTENANCE_KEY: 'b'.repeat(32), PARSE_SERVER_URL: 'http://127.0.0.1:4400/parse', API_AUTH_MODE: 'disabled', FMODE_BASE_URL: 'http://127.0.0.1:3000/api/voc-e-commerce', FMODE_API_KEY: 'test-key', CORS_ORIGINS: 'http://127.0.0.1:4300', }; test('loadConfig rejects missing secrets before startup', () => { const environment = { ...validEnvironment }; delete environment.DATABASE_URL; delete environment.PARSE_MASTER_KEY; delete environment.PARSE_MAINTENANCE_KEY; delete environment.FMODE_API_KEY; assert.throws( () => loadConfig(environment), (error: unknown) => { assert.ok(error instanceof EnvironmentConfigurationError); assert.match(error.message, /DATABASE_URL/); assert.match(error.message, /PARSE_MASTER_KEY/); assert.match(error.message, /PARSE_MAINTENANCE_KEY/); assert.match(error.message, /FMODE_API_KEY/); return true; }, ); }); test('loadConfig normalizes URLs and CORS origins', () => { const config = loadConfig({ ...validEnvironment, FMODE_BASE_URL: 'http://127.0.0.1:3000/api/voc-e-commerce/', CORS_ORIGINS: 'http://127.0.0.1:4300, http://localhost:4200', }); assert.equal(config.fmode.baseUrl, 'http://127.0.0.1:3000/api/voc-e-commerce'); assert.equal(config.ai.baseUrl, 'https://api.fmode.cn'); assert.equal(config.ai.defaultModel, 'deepseek-v4-pro'); assert.equal(config.ai.token, ''); assert.equal(config.database.migrationUrl, validEnvironment.MIGRATION_DATABASE_URL); assert.equal(config.worker.enabled, true); assert.equal(config.worker.staleAfterMs, 900_000); assert.equal(config.worker.reviewMaxPages, 1); assert.equal(config.auth.mode, 'disabled'); assert.equal(config.auth.defaultWorkspaceId, 'demashi'); assert.equal(config.listingAi.jdVocEnabled, false); assert.equal(config.listingAi.jdVocAiEnabled, false); assert.equal(config.listingAi.jdVocImageShadowEnabled, false); assert.equal(config.listingAi.jdVocDisplayDefault, false); assert.equal(config.listingAi.jdVocAiModel, 'gpt-4o-mini'); assert.deepEqual(config.corsOrigins, ['http://127.0.0.1:4300', 'http://localhost:4200']); }); test('loadConfig enables each approved JD-VOC rollout switch independently', () => { const config = loadConfig({ ...validEnvironment, JD_VOC_ENABLED:'true', JD_VOC_AI_ENABLED:'true', JD_VOC_IMAGE_SHADOW_ENABLED:'true', JD_VOC_DISPLAY_DEFAULT:'true' }); assert.equal(config.listingAi.jdVocEnabled, true); assert.equal(config.listingAi.jdVocAiEnabled, true); assert.equal(config.listingAi.jdVocImageShadowEnabled, true); assert.equal(config.listingAi.jdVocDisplayDefault, true); }); test('loadConfig treats blank optional environment values as unset', () => { const config = loadConfig({ ...validEnvironment, MIGRATION_DATABASE_URL: '', SAAS_BOOTSTRAP_ADMIN_USER_ID: '', }); assert.equal(config.database.migrationUrl, validEnvironment.DATABASE_URL); assert.equal(config.auth.bootstrapAdminUserId, ''); }); test('loadConfig supports Parse REST storage without a direct database connection', () => { const environment: NodeJS.ProcessEnv = { ...validEnvironment, STORAGE_DRIVER: 'parse_rest' }; delete environment.DATABASE_URL; delete environment.MIGRATION_DATABASE_URL; delete environment.PARSE_MAINTENANCE_KEY; environment.PARSE_APP_ID = 'dev'; environment.PARSE_MASTER_KEY = 'short-test-key'; environment.PARSE_SERVER_URL = 'http://dev.example.test/parse'; const config = loadConfig(environment); assert.equal(config.storageDriver, 'parse_rest'); assert.equal(config.database.url, ''); assert.equal(config.parse.serverUrl, 'http://dev.example.test/parse'); }); test('loadConfig rejects disabled authentication in production', () => { assert.throws( () => loadConfig({ ...validEnvironment, NODE_ENV: 'production', API_AUTH_MODE: 'disabled' }), (error: unknown) => error instanceof EnvironmentConfigurationError && error.message.includes('disabled authentication is not allowed in production'), ); });