fix(platform): preserve recoverable outcomes and terminal sessions

This commit is contained in:
2026-09-05 10:50:55 +08:00
parent 1e3a21b476
commit 8eae3258ca
16 changed files with 500 additions and 48 deletions
@@ -25,6 +25,7 @@ function makeSession() {
const store = new PlatformStore();
const log: string[] = [];
const restored: unknown[] = [];
const denials: unknown[] = [];
const events: Array<{ event: PlatformToGameEvent; snapshot: PlatformGameSnapshot }> = [];
let host: GameHost;
const entry: GameEntry = {
@@ -55,6 +56,7 @@ function makeSession() {
const session = new RuntimeSession({
store,
gameSession,
onServerDenial: outcome => { denials.push(outcome); },
createGameHostLease: () => ({
host: {
seat: { toView: (seat) => seat, toServer: (seat) => seat },
@@ -66,9 +68,30 @@ function makeSession() {
invalidate() {},
}),
});
return { store, gameSession, session, log, restored, events };
return { store, gameSession, session, log, restored, events, denials };
}
test('server denials preserve an active room and module without committing a success action', () => {
const setup = makeSession();
setup.session.handleLogin(fixture('player-login-room.json'));
const before = setup.store.getState();
setup.log.length = 0;
const joinDenial = { state: 99, roomcode: '999999', showerror: 1, error: 'Room does not exist' };
const loginDenial = { state: 1, error: 'Login denied' };
setup.session.handleSelfJoin(joinDenial);
setup.session.markLoginPending();
setup.session.handleLogin(loginDenial);
assert.equal(setup.store.getState(), before);
assert.equal(setup.session.loginPending, false);
assert.equal(setup.session.state, 'operational');
assert.equal(setup.gameSession.state, 'active');
assert.deepEqual(setup.log, []);
assert.deepEqual(setup.denials, [
{ rpc: 'self_join_room', state: 99, data: joinDenial },
{ rpc: 'player_login', state: 1, data: loginDenial },
]);
});
test('RuntimeSession commits a room login before opening, publishing, and restoring deskinfo', () => {
const setup = makeSession();
const data = fixture('player-login-room.json');
@@ -220,6 +243,7 @@ function makeLeaseSession() {
const sessionOptions = {
store,
gameSession,
onServerDenial() { assert.fail('Unexpected server denial'); },
createGameHostLease() {
if (failures.has('lease-factory')) throw errors['lease-factory'];
const record: LeaseRecord = { host: host(), invalidations: 0 };