const assert = require('node:assert/strict')
const { execFileSync } = require('node:child_process')
const fs = require('node:fs')
const os = require('node:os')
const path = require('node:path')
const vm = require('node:vm')
const test = require('node:test')
const frontend = path.resolve(__dirname, '../frontend')
const docker = (...args) => execFileSync('docker', [
...(process.env.NGINX_TEST_DOCKER_CONTEXT ? ['--context', process.env.NGINX_TEST_DOCKER_CONTEXT] : []), ...args,
], { encoding: 'utf8', timeout: 30000, stdio: ['ignore', 'pipe', 'pipe'] }).trim()
test('startup embeds current validated config in both entry points on every run', { timeout: 90000 }, async () => {
const temp = fs.mkdtempSync(path.join(os.tmpdir(), 'weknora-runtime-config-'))
const name = `weknora-runtime-config-${process.pid}-${Date.now()}`
const image = process.env.NGINX_TEST_IMAGE || fs.readFileSync(path.join(frontend, 'Dockerfile'), 'utf8').match(/^FROM (\S+)/m)[1]
let created = false
try {
// The stand-in nginx exits, so the real startup script can be run repeatedly.
fs.writeFileSync(path.join(temp, 'nginx'), '#!/bin/sh\nexit 0\n', { mode: 0o755 })
docker('create', '--rm', '--pull', 'never', '--network', 'none', '--name', name,
'--entrypoint', 'sh', image, '-c', 'while :; do sleep 30; done')
created = true
docker('start', name)
docker('exec', name, 'mkdir', '-p', '/usr/share/nginx/runtime-templates', '/etc/nginx/templates', '/fixture-bin')
for (const page of ['index.html', 'embed.html']) docker('cp', path.join(frontend, page), `${name}:/usr/share/nginx/runtime-templates/${page}`)
docker('cp', path.join(frontend, 'nginx.conf'), `${name}:/etc/nginx/templates/default.conf.template`)
docker('cp', path.join(frontend, 'docker-entrypoint.sh'), `${name}:/fixture-entrypoint.sh`)
docker('cp', path.join(temp, 'nginx'), `${name}:/fixture-bin/nginx`)
const run = env => docker('exec', '-e', 'PATH=/fixture-bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
...Object.entries(env).flatMap(([key, value]) => ['-e', `${key}=${value}`]), name, 'sh', '/fixture-entrypoint.sh')
const readConfig = (source) => {
const matches = [...source.matchAll(/', MAX_FILE_SIZE_MB: 'invalid', MAX_SKILL_BUNDLE_SIZE_MB: '1;alert(1)' },
{ DEFAULT_LOCALE: '', MAX_FILE_SIZE_MB: 50, MAX_SKILL_BUNDLE_SIZE_MB: 256 }],
]) {
run(env)
for (const page of ['index.html', 'embed.html']) {
const body = docker('exec', name, 'cat', `/usr/share/nginx/html/${page}`)
assert.deepEqual(readConfig(body), expected)
assert.ok(body.includes('type="module"'))
}
const compatibility = { window: {} }
vm.runInNewContext(docker('exec', name, 'cat', '/usr/share/nginx/html/config.js'), compatibility, { timeout: 500 })
assert.deepEqual(JSON.parse(JSON.stringify(compatibility.window.__RUNTIME_CONFIG__)), expected)
}
} finally {
try { if (created) docker('rm', '--force', name) } finally { fs.rmSync(temp, { recursive: true, force: true }) }
}
})