77 lines
3.7 KiB
TypeScript
77 lines
3.7 KiB
TypeScript
import assert from 'node:assert/strict'
|
|
import { readFileSync, existsSync } from 'node:fs'
|
|
import { resolve } from 'node:path'
|
|
import { test } from 'vitest'
|
|
|
|
const root = process.cwd()
|
|
const config = readFileSync(resolve(root, 'nginx/default.conf.template'), 'utf8')
|
|
const compose = readFileSync(resolve(root, 'docker-compose.test.yml'), 'utf8')
|
|
const jenkins = readFileSync(resolve(root, 'Jenkinsfile'), 'utf8')
|
|
const vite = readFileSync(resolve(root, 'vite.config.ts'), 'utf8')
|
|
|
|
test('all business traffic uses one Gateway without rewriting API paths', () => {
|
|
assert.match(config, /location \/api\//)
|
|
assert.match(config, /proxy_pass \$\{API_UPSTREAM\};/)
|
|
assert.doesNotMatch(config, /overseas-api|OVERSEAS_API_UPSTREAM|rewrite/)
|
|
assert.match(config, /client_max_body_size 55m;/)
|
|
assert.match(config, /proxy_set_header Host \$proxy_host;/)
|
|
assert.doesNotMatch(vite, /OVERSEAS_API|AUTH_API_PROXY_TARGET|IAM_API_PROXY_TARGET|WAREHOUSE_API_PROXY_TARGET/)
|
|
})
|
|
|
|
test('test deployment requires an explicit shared network, Gateway and version', () => {
|
|
for (const key of ['IMAGE_TAG']) {
|
|
assert.ok(compose.includes('${' + key + ':?'))
|
|
}
|
|
assert.ok(compose.includes('${API_UPSTREAM:-http://gateway:9000}'))
|
|
assert.ok(compose.includes('${TEST_NETWORK:-firstleg-test-network}'))
|
|
assert.match(compose, /external: true/)
|
|
assert.match(compose, /127\.0\.0\.1:/)
|
|
assert.doesNotMatch(compose, /overseas|host\.docker\.internal|production|development/)
|
|
assert.match(jenkins, /'java-builder' : 'java-test'/)
|
|
assert.match(jenkins, /docker compose -f docker-compose\.test\.yml config --quiet/)
|
|
assert.match(jenkins, /docker network inspect/)
|
|
assert.match(jenkins, /scripts\/deploy-production\.sh/)
|
|
assert.match(jenkins, /firstleg-production-ssh/)
|
|
|
|
})
|
|
|
|
test('application shell is revalidated and missing chunks remain 404', () => {
|
|
assert.match(config, /location = \/index\.html/)
|
|
assert.match(config, /no-store/)
|
|
assert.match(config, /max-age=31536000, immutable/)
|
|
assert.match(config, /try_files \$uri =404;/)
|
|
assert.match(config, /try_files \$uri \$uri\/ \/index\.html;/)
|
|
})
|
|
|
|
test('PDA static apps keep independent paths and share the authenticated Gateway', () => {
|
|
assert.match(config, /resolver 127\.0\.0\.11 valid=10s ipv6=off;/)
|
|
for (const app of ['domestic', 'overseas']) {
|
|
assert.ok(config.includes(`location = /pda-${app} { return 308 /pda-${app}/; }`))
|
|
assert.ok(config.includes(`location ^~ /pda-${app}/ {`))
|
|
assert.ok(config.includes(`set $pda_${app}_origin http://pda-${app}-h5-test:80;`))
|
|
assert.ok(config.includes(`proxy_pass $pda_${app}_origin$request_uri;`))
|
|
}
|
|
assert.match(config, /location \/gateway-api\/\s*\{[^}]*client_max_body_size 55m;[^}]*proxy_pass \$\{API_UPSTREAM\}\/api\//)
|
|
assert.doesNotMatch(config, /proxy_pass.*(?:auth:|lastleg-service:|firstleg-service:)/)
|
|
})
|
|
|
|
|
|
test('container build excludes local environment values and waits for Nginx health', () => {
|
|
const ignore = readFileSync(resolve(root, '.dockerignore'), 'utf8')
|
|
assert.match(ignore, /^\.env$/m)
|
|
assert.match(ignore, /^\.env\.\*$/m)
|
|
assert.match(compose, /healthcheck:/)
|
|
assert.match(compose, /http:\/\/127\.0\.0\.1\/healthz/)
|
|
assert.match(jenkins, /up -d --wait --wait-timeout 120/)
|
|
})
|
|
|
|
test('gray production is isolated from TEST and routes to the single Gateway', () => {
|
|
const production = readFileSync(resolve(root, 'docker-compose.production.yml'), 'utf8')
|
|
assert.match(production, /name: firstleg-production-network/)
|
|
assert.match(production, /API_UPSTREAM: "http:\/\/gateway:9000"/)
|
|
assert.match(production, /127\.0\.0\.1:/)
|
|
assert.match(production, /healthcheck:/)
|
|
assert.doesNotMatch(production, /test-network|gateway-overseas|gateway-active|routing-network/)
|
|
assert.doesNotMatch(jenkins, /wecom|sendProductionWeComNotification/)
|
|
})
|