aps-agent/scripts/serve-client.test.mjs

44 lines
1.9 KiB
JavaScript
Raw Permalink Normal View History

/**
* 客户端托管冒烟测试(任务 A1.5)。
*
* 验证「构建后由平台服务单端口托管」这条路:GET / 返回客户端页面,静态资源可取,
* 同时 /v1 接口不受影响。
*/
import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import { test } from 'node:test';
import { fileURLToPath } from 'node:url';
const ROOT = fileURLToPath(new URL('..', import.meta.url));
const isWindows = process.platform === 'win32';
test('平台服务托管客户端产物,且 API 不受影响', async () => {
execFileSync('pnpm', ['--filter', '@aps/client-app', 'run', 'build'], { cwd: ROOT, stdio: 'pipe', shell: isWindows });
const { startServer } = await import('../server/dist/index.js');
const server = await startServer({ host: '127.0.0.1', port: 0, version: 'test', databasePath: ':memory:', engine: 'fake' });
try {
const page = await fetch(`${server.url}/`);
assert.equal(page.status, 200, 'GET / 应返回客户端页面');
const html = await page.text();
assert.match(html, /<div id="root">/, '返回的应是客户端 index.html');
const assetPath = html.match(/src="([^"]+\.js)"/)?.[1];
assert.ok(assetPath, 'index.html 里应有脚本引用');
const asset = await fetch(`${server.url}${assetPath}`);
assert.equal(asset.status, 200, '静态资源应可取');
const assetBody = await asset.text();
assert.ok(assetBody.length > 1000, '脚本内容应非空');
const health = await (await fetch(`${server.url}/v1/health`)).json();
assert.equal(health.status, 'ok', 'API 不应被静态托管影响');
const spaFallback = await fetch(`${server.url}/some/deep/link`);
assert.equal(spaFallback.status, 200, '非 API 路径应回退到 index.html');
const apiMissing = await fetch(`${server.url}/v1/nope`);
assert.equal(apiMissing.status, 404, 'API 路径仍走协议错误处理');
} finally {
await server.close();
}
});