import assert from "node:assert/strict"; import { spawnSync } from "node:child_process"; import { fileURLToPath } from "node:url"; import test from "node:test"; import { nativeConfigFailures } from "./validate-native-config.mjs"; const env = { VITE_API_ORIGIN: "https://im.bchongw.com", VITE_WS_ORIGIN: "wss://im.bchongw.com" }; const manifest = { appid: "__UNI__A031845", "app-plus": { modules: Object.fromEntries(["Camera", "Geolocation", "OAuth", "Payment", "Push", "Record"].map((name) => [name, {}])), distribute: { ios: { privacyDescription: { NSCameraUsageDescription: "用于拍摄头像" } } }, }, }; test("supports the assigned seven-character AppID and existing eight-character IDs", () => { for (const appid of ["__UNI__A031845", "__UNI__AB123456"]) { assert.deepEqual(nativeConfigFailures({ ...manifest, appid }, env), []); } }); test("still rejects empty or placeholder AppIDs and insecure or malformed origins", () => { for (const appid of ["", "__UNI__XXXXXXXX", "__UNI__XINGYUIM"]) { assert.ok(nativeConfigFailures({ ...manifest, appid }, env).some((error) => error.includes("AppID"))); } for (const VITE_API_ORIGIN of ["", "https://", "http://im.bchongw.com", "https://127.0.0.1:8888", "https://localhost", "https://[::1]", "https://im.bchongw.com/api/v1"]) { assert.ok(nativeConfigFailures(manifest, { ...env, VITE_API_ORIGIN }).some((error) => error.includes("HTTPS"))); } assert.ok(nativeConfigFailures(manifest, { ...env, VITE_WS_ORIGIN: "ws://im.bchongw.com" }).some((error) => error.includes("WSS"))); }); test("loads production env and manifest independently of the caller working directory", () => { const childEnv = { ...process.env }; delete childEnv.VITE_API_ORIGIN; delete childEnv.VITE_WS_ORIGIN; const result = spawnSync(process.execPath, [fileURLToPath(new URL("./validate-native-config.mjs", import.meta.url))], { cwd: fileURLToPath(new URL("../../", import.meta.url)), env: childEnv, encoding: "utf8", }); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /基础配置校验通过/); }); test("native login configuration never embeds the WeChat server secret", () => { const withOAuth = (oauth) => ({ ...manifest, 'app-plus': { ...manifest['app-plus'], distribute: { ...manifest['app-plus'].distribute, sdkConfigs: { oauth } }, } }); assert.ok(nativeConfigFailures(withOAuth({ weixin: { appid: 'wx1234', appsecret: 'server-secret' } }), env).some((error) => error.includes('AppSecret'))); assert.ok(nativeConfigFailures(withOAuth({ qq: { appid: '' } }), env).some((error) => error.includes('QQ'))); assert.deepEqual(nativeConfigFailures(withOAuth({ weixin: { appid: 'wx1234' }, qq: { appid: '123456' } }), env), []); assert.deepEqual(nativeConfigFailures(withOAuth({ google: {} }), env), []); }); test('real-device development validates the development environment, not production', () => { const childEnv = { ...process.env }; delete childEnv.VITE_API_ORIGIN; delete childEnv.VITE_WS_ORIGIN; const script = fileURLToPath(new URL('./validate-native-config.mjs', import.meta.url)); const result = spawnSync(process.execPath, [script, '--mode', 'development'], { cwd: fileURLToPath(new URL('../../', import.meta.url)), env: childEnv, encoding: 'utf8', }); assert.equal(result.status, 0, result.stderr); assert.match(result.stdout, /mode=development API=https:\/\/im\.bchongw\.com WS=wss:\/\/im\.bchongw\.com/); const overridden = spawnSync(process.execPath, [script, '--mode', 'development'], { env: { ...childEnv, VITE_API_ORIGIN: 'http://127.0.0.1:8888' }, encoding: 'utf8', }); assert.notEqual(overridden.status, 0, 'invalid shell override must not pass using production configuration'); });