import assert from 'node:assert/strict'; import test from 'node:test'; import { randomBytes, randomUUID } from 'node:crypto'; import { MongoClient } from 'mongodb'; import { createGameSessionStore } from '../src/server/game-session-store.js'; import { createRoomStore } from '../src/server/rooms.js'; import { normalizeAppearance } from '../src/shared/cosmetics.js'; test('bot and friend registrations snapshot all selected parts and keep them across session restoration', { skip: !process.env.TEST_MONGODB_URI }, async () => { const client = await new MongoClient(process.env.TEST_MONGODB_URI!, { serverSelectionTimeoutMS: 5000 }).connect(); const db = client.db(`dragon_ball_test_parts_${randomUUID().replaceAll('-', '')}`); try { const sessions = await createGameSessionStore(db), rooms = await createRoomStore(db); const host = await sessions.create(randomBytes(32).toString('base64url'), 'equipment-host'); const guest = await sessions.create(randomBytes(32).toString('base64url'), 'equipment-guest'); const hostLook = normalizeAppearance({ characterId: 0, skinTone: 'light', colorId: 'blue', hairStyle: 'white', equipment: ['shoes', 'headband', 'glasses'] }); const guestLook = normalizeAppearance({ characterId: 1, skinTone: 'tan', colorId: 'white', hairStyle: 'black', equipment: ['wristbands', 'sunglasses'] }); await db.collection('player_profiles').insertMany([{ _id: 'equipment-host', appearance: hostLook }, { _id: 'equipment-guest', appearance: guestLook }]); const bot = await sessions.register(host, { requestId: randomUUID(), matchId: randomUUID(), expectedPreviousSeq: 0, mode: 'bot' }); assert.deepEqual(bot.appearances?.[0], hostLook); assert.deepEqual((await sessions.get(host)).activeMatch?.appearances?.[0], hostLook); await sessions.record(host, { ...bot, outcome: 'aborted', reason: 'connection_failed' }); const room = await rooms.create(host.gameSessionId, randomUUID()); const joined = await rooms.join(guest.gameSessionId, room.code); assert.deepEqual(joined.appearances, [hostLook, guestLook]); // Editing the lobby profile in a second tab must not change this already-paired match. await db.collection('player_profiles').updateOne({ _id: 'equipment-host' }, { $set: { appearance: normalizeAppearance(undefined) } }); const register = (session: typeof host, previous: number) => sessions.register(session, { requestId: randomUUID(), matchId: joined.currentMatchId, expectedPreviousSeq: previous, mode: 'friend', roomId: joined.id, }); const [a, b] = await Promise.all([register(host, 1), register(guest, 0)]); assert.deepEqual(a.appearances, [hostLook, guestLook]); assert.deepEqual(b.appearances, a.appearances); assert.deepEqual((await sessions.get(guest)).activeMatch?.appearances, a.appearances); } finally { try { await db.dropDatabase(); } finally { await client.close(); } } });