import { test } from 'node:test'; import assert from 'node:assert/strict'; import { resolveBootstrap } from '../../YouleNexus/assets/framework/config/bootstrap.ts'; import { BUILD_IDENTITY } from '../../YouleNexus/assets/framework/config/sources/defaults.ts'; import type { ConfigFetcher, RemoteConfig } from '../../YouleNexus/assets/framework/config/remote-config.ts'; import { PROFILES } from '../../YouleNexus/assets/framework/config/profiles.ts'; function fetcherReturning(config: RemoteConfig): ConfigFetcher & { calls: string[] } { const calls: string[] = []; return { calls, fetch: async (url: string) => { calls.push(url); return config; } }; } const throwingFetcher: ConfigFetcher = { fetch: async () => { throw new Error('net down'); }, }; const REMOTE: RemoteConfig = { data: { player_server_tcp: '5.5.5.5:5000' } }; test('debug + profile=local:用 profile.server 直连,不抓远程', async () => { const fetcher = fetcherReturning(REMOTE); const r = await resolveBootstrap({ mode: 'debug', win: {}, search: '?profile=local', fetcher, isNative: false }); assert.deepEqual(r.servers, ['ws://127.0.0.1:3088']); assert.equal(r.rawConfig, null); assert.equal(fetcher.calls.length, 0); }); test('debug + prod + H5:抓远程配置产出 servers,identity 来自 defaults', async () => { const fetcher = fetcherReturning(REMOTE); const r = await resolveBootstrap({ mode: 'debug', win: {}, search: '', fetcher, isNative: false }); assert.deepEqual(r.servers, ['ws://5.5.5.5:5000']); assert.equal(r.identity.agentid, BUILD_IDENTITY.agentid); assert.equal(r.identity.gameid, BUILD_IDENTITY.gameid); assert.equal(fetcher.calls.length, 1); }); test('debug + H5 显式 URL query 覆盖身份(最高优先级)', async () => { const fetcher = fetcherReturning(REMOTE); const r = await resolveBootstrap({ mode: 'debug', win: {}, search: '?agentid=999&channelid=C9', fetcher, isNative: false }); assert.equal(r.identity.agentid, '999'); assert.equal(r.identity.channelid, 'C9'); }); test('debug + 原生模式:identity 来自 window.settings', async () => { const fetcher = fetcherReturning(REMOTE); const win = { settings: { getothername: () => 'NA', getchannelName: () => 'NC', getmarketname: () => 3 } }; const r = await resolveBootstrap({ mode: 'debug', win, search: '', fetcher, isNative: true }); assert.equal(r.identity.agentid, 'NA'); assert.equal(r.identity.channelid, 'NC'); assert.equal(r.identity.marketid, 3); }); test('远程抓取失败 → 抛 ConfigFetchError(不兜底)', async () => { await assert.rejects( resolveBootstrap({ mode: 'debug', win: {}, search: '', fetcher: throwingFetcher, isNative: false }), /远程配置抓取失败/, ); }); test('远程配置未给出可用服务器地址 → 抛错(不兜底)', async () => { const emptyFetcher: ConfigFetcher = { fetch: async () => ({ data: {} }) }; await assert.rejects( resolveBootstrap({ mode: 'debug', win: {}, search: '', fetcher: emptyFetcher, isNative: false }), /未给出可用服务器/, ); }); test('debug 结果含 mode/isDebugger', async () => { const fetcher = fetcherReturning(REMOTE); const r = await resolveBootstrap({ mode: 'debug', win: {}, search: '', fetcher, isNative: false }); assert.equal(r.mode, 'debug'); assert.equal(r.isDebugger, true); }); test('release:忽略所有 URL 覆盖,强制 prod,identity 不被 URL 改', async () => { const fetcher = fetcherReturning(REMOTE); const r = await resolveBootstrap({ mode: 'release', win: {}, search: '?profile=local&agentid=999', fetcher, isNative: false }); assert.equal(r.profile.name, 'prod'); assert.deepEqual(r.servers, ['ws://5.5.5.5:5000']); // 走远程,不是 local 直连 assert.equal(r.identity.agentid, BUILD_IDENTITY.agentid); // 999 无效 assert.equal(r.isDebugger, false); assert.equal(r.mode, 'release'); assert.equal(fetcher.calls.length, 1); }); test('release:原生身份仍生效(URL 的 999 无效)', async () => { const fetcher = fetcherReturning(REMOTE); const win = { settings: { getothername: () => 'NA', getchannelName: () => 'NC', getmarketname: () => 3 } }; const r = await resolveBootstrap({ mode: 'release', win, search: '?agentid=999', fetcher, isNative: true }); assert.equal(r.identity.agentid, 'NA'); assert.equal(r.identity.channelid, 'NC'); }); test('debug + serverOverride:走远程全链路但连接地址覆盖为本地', async () => { const fetcher = fetcherReturning(REMOTE); // REMOTE.player_server_tcp = 5.5.5.5:5000 const r = await resolveBootstrap({ mode: 'debug', win: {}, search: '?profile=staging', fetcher, isNative: false }); assert.deepEqual(r.servers, [PROFILES.staging.serverOverride]); // 覆盖为 profile.serverOverride assert.ok(r.rawConfig); // 远程配置仍抓取(全链路) assert.equal(fetcher.calls.length, 1); }); test('release:serverOverride 不生效(强制 prod,用远程解析地址)', async () => { const fetcher = fetcherReturning(REMOTE); const r = await resolveBootstrap({ mode: 'release', win: {}, search: '?profile=staging', fetcher, isNative: true }); assert.deepEqual(r.servers, ['ws://5.5.5.5:5000']); // prod 无 override,用远程解析 }); test('debug:account 来自当前 profile', async () => { const fetcher = fetcherReturning(REMOTE); const r = await resolveBootstrap({ mode: 'debug', win: {}, search: '?profile=staging', fetcher, isNative: false }); assert.deepEqual(r.account, PROFILES.staging.account); }); test('release:account 恒为 undefined(不从调试配置泄漏账号)', async () => { const fetcher = fetcherReturning(REMOTE); const r = await resolveBootstrap({ mode: 'release', win: {}, search: '?profile=staging', fetcher, isNative: true }); assert.equal(r.account, undefined); });