Files
order_site/apps/backend/src/config/env-overrides.test.ts
T
2026-05-28 13:05:44 +08:00

151 lines
4.8 KiB
TypeScript

import test from 'node:test'
import assert from 'node:assert/strict'
import path from 'node:path'
import { applyEnvOverrides, ENV_OVERRIDES } from './env-overrides.js'
import type { RuntimeConfig } from '../types/runtime-config.js'
test('applyEnvOverrides maps typed environment values without mutating base config', () => {
const baseConfig = createRuntimeConfig()
const config = applyEnvOverrides(baseConfig, {
PORT: '4000',
DATA_ROOT: './tmp/backend-data',
DATABASE_SSL: 'yes',
LOG_RETENTION_DAYS: '45',
ADMIN_DEFAULT_USERS_JSON: '[{"username":"admin","password":"secret","role":"admin"}]',
KAQUAN91_USER_ID: 'kaquan-user',
KAQUAN91_SECRET: 'kaquan-secret',
CLOUDTENTACLES_DEVICE_TYPE: '3',
})
assert.equal(config.server.port, 4000)
assert.equal(config.data.root, path.resolve('./tmp/backend-data'))
assert.equal(config.database.ssl, true)
assert.equal(config.logging.retentionDays, 45)
assert.deepEqual(config.admin.defaultUsers, [
{ username: 'admin', password: 'secret', role: 'admin' },
])
assert.equal(config.platforms.ninetyone.userId, 'kaquan-user')
assert.equal(config.platforms.ninetyone.secret, 'kaquan-secret')
assert.equal(config.platforms.cloudtentacles.deviceType, 3)
assert.equal(baseConfig.server.port, 3000)
assert.deepEqual(baseConfig.admin.defaultUsers, [])
})
test('applyEnvOverrides derives claim base url from app base url when explicit claim url is absent', () => {
const config = applyEnvOverrides(createRuntimeConfig(), {
APP_BASE_URL: 'https://example.test///',
})
assert.equal(config.orders.claimBaseUrl, 'https://example.test/#/claim')
})
test('applyEnvOverrides prefers explicit claim base url over app base url', () => {
const config = applyEnvOverrides(createRuntimeConfig(), {
APP_BASE_URL: 'https://example.test',
CLAIM_BASE_URL: 'https://claim.example.test/custom',
})
assert.equal(config.orders.claimBaseUrl, 'https://claim.example.test/custom')
})
test('applyEnvOverrides ignores empty or invalid values', () => {
const config = applyEnvOverrides(createRuntimeConfig(), {
PORT: 'not-a-number',
DATABASE_SSL: 'maybe',
ADMIN_DEFAULT_USERS_JSON: '{"username":"admin"}',
LOG_LEVEL: ' ',
LOG_RETENTION_DAYS: 'not-a-number',
})
assert.equal(config.server.port, 3000)
assert.equal(config.database.ssl, false)
assert.deepEqual(config.admin.defaultUsers, [])
assert.equal(config.logging.level, 'info')
assert.equal(config.logging.retentionDays, 30)
})
test('ENV_OVERRIDES keeps environment variable names unique', () => {
const names = ENV_OVERRIDES.map((override) => override.env)
assert.equal(new Set(names).size, names.length)
})
function createRuntimeConfig(): RuntimeConfig {
return {
server: {
port: 3000,
},
data: {
root: '/tmp/order-site',
},
logging: {
level: 'info',
retentionDays: 30,
},
database: {
url: 'postgres://postgres:postgres@127.0.0.1:5432/order_site',
ssl: false,
maxConnections: 10,
},
orders: {
claimBaseUrl: 'http://127.0.0.1:5173/#/claim',
tokenTtlHours: 24,
},
admin: {
sessionSecret: '',
sessionTtlHours: 12,
defaultUsers: [],
},
platforms: {
ninetyone: {
userId: '',
secret: '',
version: '1.0',
shopId: '91kaquan',
shopName: '91卡券',
timestampToleranceSeconds: 600,
cardsEncoding: 'aes-256-ecb-base64',
},
cloudtentacles: {
baseUrl: 'https://123.207.217.176',
timeoutMs: 5000,
sendSmsPath: '/public/verif_code',
loginPath: '/public/login',
userInfoPath: '/user/info',
assetPath: '/user/get_asset',
permissionPath: '/user/get_permission',
categoriesPath: '/categories/get',
skuListPath: '/sku/list',
skuBuyPath: '/sku/buy',
skuUsePath: '/sku/use',
knapsackPath: '/user/get_knapsack',
vnListPath: '/vn/list',
vnAppointPath: '/vn/appoint',
vnGenerateLoginCodePath: '/vn/generate_login_code',
vnVerifCodePath: '/public/vn_verif_code',
vnVerifyLoginCodePath: '/vn/verify_login_code',
vnBindUrlPath: '/vn/bind_url',
vnBindInfoPath: '/vn/bind_info',
vnBackPath: '/vn/back',
bindUrlTtlSeconds: 600,
bindUrlProbeIntervalSeconds: 30,
bindUrlProbeTimeoutMs: 5000,
bindUrlProbeUserAgent: '',
bindUrlProbeEndpoint: 'https://comm.ams.game.qq.com/ide/',
bindUrlProbeChartId: '323794',
bindUrlProbeSubChartId: '323794',
bindUrlProbeIdeToken: 'z90Syo',
bindUrlProbeActivityUrl: '',
bindUrlProbeReferer: 'https://gp.qq.com/',
bindUrlProbeExtraCookie: '',
publicKeyPem: '',
clientSource: 'ct-client',
deviceId: '08bc9d8c-fd15-48ea-bc00-8d754076cafc',
deviceType: 1,
},
},
}
}