import test from 'node:test' import { runInNewContext } from 'node:vm' import assert from 'node:assert/strict' import { mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join, resolve } from 'node:path' import { fileURLToPath, pathToFileURL } from 'node:url' import { loadEnv } from 'vite' const read = path => readFile(new URL(path, import.meta.url), 'utf8') test('PDA H5 has no container publishing entry', async () => { const files = await readdir(new URL('../deploy/', import.meta.url)) assert.deepEqual(files.filter(name => /docker|compose/i.test(name)), []) await assert.rejects(read('../.dockerignore'), { code: 'ENOENT' }) }) test('host nginx serves uploaded files and proxies only the API prefix', async () => { const nginx = await read('../deploy/nginx.conf.template') assert.ok(nginx.includes('root ${PDA_SITE_ROOT};')) const page = nginx.match(/location \/ \{([^{}]*)\}/)?.[1] assert.ok(page) assert.match(page, /try_files \$uri \$uri\/ =404;/) assert.match(page, /Cache-Control "no-store" always/) assert.doesNotMatch(page, /proxy_pass|try_files[^;]*index\.html/) assert.match(nginx, /location \^~ \/gateway-api\//) assert.ok(nginx.includes('proxy_pass ${PDA_GATEWAY_ORIGIN}/api/;')) assert.equal((nginx.match(/proxy_pass/g) || []).length, 1) assert.match(nginx, /proxy_set_header Authorization \$http_authorization;/) assert.match(nginx, /client_max_body_size 55m;/) assert.doesNotMatch(nginx, /29005|29006|\/srv\/pda-h5|gateway:9000/) }) test('only H5 production overrides the toolchain asset base', async () => { const source = (await read('../vite.config.js')) .replace(/^import .*$/gm, '') .replaceAll('import.meta.url', 'configUrl') .replace('export default ', '') for (const platform of ['h5', 'app', 'app-plus', 'app-harmony', undefined]) { for (const mode of ['production', 'development']) { const factory = runInNewContext(source, { URL, fileURLToPath, configUrl: new URL('../vite.config.js', import.meta.url).href, defineConfig: value => value, loadEnv: () => ({}), uni: () => ({}), process: { env: { UNI_PLATFORM: platform }, cwd: () => '/project' } }) assert.equal(factory({ mode }).base, platform === 'h5' && mode === 'production' ? '/' : undefined, `${platform}:${mode}`) } } }) test('H5 proxy uses the shared gateway prefix and preserves API suffixes', async () => { const source = (await read('../vite.config.js')).replace(/^import .*$/gm, '') .replaceAll('import.meta.url', 'configUrl').replace('export default ', '') const factory = runInNewContext(source, { URL, fileURLToPath, configUrl: new URL('../vite.config.js', import.meta.url).href, defineConfig: value => value, loadEnv: () => ({ API_PROXY_TARGET: 'https://gateway.example.com' }), uni: () => ({}), process: { env: { UNI_PLATFORM: 'h5' }, cwd: () => '/project' } }) const proxy = factory({ mode: 'development' }).server.proxy assert.deepEqual(Object.keys(proxy), ['/gateway-api']) assert.equal(proxy['/gateway-api'].target, 'https://gateway.example.com') for (const suffix of ['/auth/login', '/pda/v1/last-leg/photos/1/download?preview=1']) { assert.equal(proxy['/gateway-api'].rewrite(`/gateway-api${suffix}`), `/api${suffix}`) } }) test('App update configuration loads from the project when HBuilderX starts elsewhere', async t => { const fixturePrefix = join(tmpdir(), 'overseas-pda-env-') const fixtureDir = await mkdtemp(fixturePrefix) assert.ok(resolve(fixtureDir).startsWith(resolve(fixturePrefix))) t.after(() => rm(fixtureDir, { recursive: true, force: true })) const endpoint = 'https://updates.example.test/pda/overseas/latest' await writeFile(join(fixtureDir, '.env.local'), `VITE_PDA_UPDATE_URL=${endpoint}\n`) const source = (await read('../vite.config.js')).replace(/^import .*$/gm, '') .replaceAll('import.meta.url', 'configUrl').replace('export default ', '') const factory = runInNewContext(source, { URL, fileURLToPath, configUrl: pathToFileURL(join(fixtureDir, 'vite.config.js')).href, defineConfig: value => value, loadEnv, uni: () => ({}), process: { env: { UNI_PLATFORM: 'app' }, cwd: () => join(fixtureDir, 'HBuilderX') } }) for (const mode of ['development', 'production']) { const config = factory({ mode }) assert.equal(JSON.parse(config.define['import.meta.env.VITE_PDA_UPDATE_URL']), endpoint) assert.equal(resolve(config.envDir), resolve(fixtureDir)) } })