Files
healer-man/server/online-session.test.mjs
2026-09-08 10:40:26 -04:00

164 lines
4.8 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import { GameDatabaseError } from "./database.mjs";
import { createOnlineSessionManager } from "./online-session.mjs";
function groupSnapshot() {
return {
invitations: [],
group: {
id: "group-one",
leaderAccountId: "leader",
members: [
{
accountId: "leader",
username: "Leader",
character: { id: "lead", name: "Bulwark", classId: "warrior", raceId: "human", gender: "male", level: 20 },
role: "tank",
},
{
accountId: "healer",
username: "Healer",
character: { id: "heal", name: "Mendara", classId: "priest", raceId: "human", gender: "female", level: 20 },
role: "healer",
},
],
activity: {
id: "activity-one",
type: "dungeon",
contentId: "wailing-caverns",
fillWithAi: false,
partySize: 2,
startingLevel: null,
startedAt: Date.now(),
},
},
};
}
const presence = {
position: [1, 2, 3],
yaw: 0.5,
health: 900,
maxHealth: 1_000,
resource: 400,
maxResource: 500,
resourceName: "Mana",
};
test("synchronizes player presence, leader world state, and ordered combat events", () => {
const manager = createOnlineSessionManager();
const snapshot = groupSnapshot();
const leader = manager.sync({ id: "leader" }, snapshot, {
presence,
world: { mobs: { boss: { health: 500, maxHealth: 500 } }, encounter: { phase: "boss" } },
});
assert.equal(leader.authority, true);
assert.equal(leader.players[0].character.name, "Bulwark");
assert.equal(leader.world.mobs.boss.health, 500);
const healer = manager.sync({ id: "healer" }, snapshot, {
presence: { ...presence, position: [4, 5, 6] },
afterEventId: 0,
events: [{
clientEventId: "heal:1",
kind: "damage",
sourceActorId: "online-player:healer",
targetActorId: "boss",
school: "holy",
rawAmount: 75,
effectiveAmount: 60,
occurredAt: 123,
}],
});
assert.equal(healer.players.length, 2);
assert.equal(healer.events.length, 1);
assert.equal(healer.events[0].id, 1);
assert.equal(healer.events[0].sourceAccountId, "healer");
const deduplicated = manager.sync({ id: "healer" }, snapshot, {
presence,
afterEventId: 1,
events: [{
clientEventId: "heal:1",
kind: "damage",
sourceActorId: "online-player:healer",
targetActorId: "boss",
rawAmount: 75,
effectiveAmount: 60,
}],
});
assert.equal(deduplicated.events.length, 0);
assert.equal(deduplicated.latestEventId, 1);
});
test("rejects non-leader world updates and forged enemy events", () => {
const manager = createOnlineSessionManager();
const snapshot = groupSnapshot();
assert.throws(() => manager.sync({ id: "healer" }, snapshot, {
presence,
world: { mobs: {} },
}), (error) => error instanceof GameDatabaseError && error.code === "activity_authority_required");
const state = manager.sync({ id: "healer" }, snapshot, {
presence,
events: [{
clientEventId: "forged",
kind: "damage",
sourceActorId: "boss",
targetActorId: "online-player:leader",
rawAmount: 1_000_000,
}],
});
assert.equal(state.events.length, 0);
});
test("relays member interactions but bounds authoritative world snapshots", () => {
const manager = createOnlineSessionManager();
const snapshot = groupSnapshot();
const interaction = manager.sync({ id: "healer" }, snapshot, {
presence,
events: [{
clientEventId: "interact:door:1",
kind: "interact",
sourceActorId: "online-player:healer",
targetActorId: "temple-door",
}],
});
assert.equal(interaction.events[0]?.kind, "interact");
assert.equal(interaction.events[0]?.targetActorId, "temple-door");
assert.throws(() => manager.sync({ id: "leader" }, snapshot, {
presence,
world: { padding: "x".repeat(4 * 1024 * 1024) },
}), (error) => error instanceof GameDatabaseError && error.code === "world_state_too_large");
});
test("accepts party teleports only from the activity leader", () => {
const manager = createOnlineSessionManager();
const snapshot = groupSnapshot();
const forged = manager.sync({ id: "healer" }, snapshot, {
presence,
events: [{
clientEventId: "teleport:forged",
kind: "party-teleport",
sourceActorId: "online-player:healer",
targetActorId: "party",
position: [9, 8, 7],
}],
});
assert.equal(forged.events.length, 0);
const accepted = manager.sync({ id: "leader" }, snapshot, {
presence,
events: [{
clientEventId: "teleport:leader",
kind: "party-teleport",
sourceActorId: "online-player:leader",
targetActorId: "party",
position: [9, 8, 7],
}],
});
assert.deepEqual(accepted.events[0]?.position, [9, 8, 7]);
});