diff --git a/cocoscreator_projects/framework-tests/integration/login-flow.test.ts b/cocoscreator_projects/framework-tests/integration/login-flow.test.ts new file mode 100644 index 0000000..00bfe63 --- /dev/null +++ b/cocoscreator_projects/framework-tests/integration/login-flow.test.ts @@ -0,0 +1,57 @@ +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { NetClient } from '../../YouleNexus/assets/framework/net/net-client.ts'; +import { FakeTransport } from '../helpers/fake-transport.ts'; +import { parseLoginResponse } from '../../YouleNexus/assets/framework/protocol/login.ts'; +import type { Clock } from '../../YouleNexus/assets/framework/net/heartbeat.ts'; + +const realishClock: Clock = { setTimeout: (fn, ms) => setTimeout(fn, ms), clearTimeout: (h: any) => clearTimeout(h) }; +const IDENTITY = { agentid: 1, gameid: 2, openid: 'o', nickname: 'n', avatar: 'a', sex: 0, province: '', city: '', unionid: 'u', version: '1', channelid: 0, marketid: 0 }; + +test('login 全流程:握手→登录→业务包,且 parseLoginResponse 识别房间恢复', async () => { + const t = new FakeTransport(); + const client = new NetClient({ servers: 'ws://srv', transportFactory: () => t, clock: realishClock }); + client.setIdentity(IDENTITY); + + let loginData: any = null; + const business: any[] = []; + client.on('login', (d: any) => { loginData = d; }); + client.on('message', (m: any) => business.push(m)); + + client.start(); + await t.flush(); + + // 服务器先发握手包(应被忽略) + t.serverPush(JSON.stringify({ data: '@toconconHELLO' })); + await t.flush(); + + // 客户端应已发出 player_login + assert.equal(JSON.parse(t.sent[0]).rpc, 'player_login'); + + // 服务器回 login 响应(带房间恢复 + 对局) + t.serverPush(JSON.stringify({ data: JSON.stringify({ + route: 'agent', rpc: 'player_login', + data: { state: 0, playerid: 42, bean: 500, roomcode: 'ROOM1', isbattle: 1, deskinfo: { round: 3 } }, + }) })); + await t.flush(); + + assert.ok(loginData); + const parsed = parseLoginResponse(loginData); + assert.equal(parsed.ok, true); + assert.equal(parsed.playerid, 42); + assert.equal(parsed.inRoom, true); + assert.equal(parsed.hasBattle, true); + assert.deepEqual(parsed.deskinfo, { round: 3 }); + + // 心跳包(忽略,不进 business) + t.serverPush(JSON.stringify({ data: JSON.stringify({ com: '@serverheartbeat' }) })); + // 正常业务推送(门控已清,放行) + t.serverPush(JSON.stringify({ data: JSON.stringify({ route: 'room', rpc: 'other_join_room', data: { seat: 2 } }) })); + await t.flush(); + + assert.equal(business.length, 1); + assert.equal(business[0].rpc, 'other_join_room'); + assert.equal(business[0].data.seat, 2); + + client.stop(); +});