Update Healer Man server

This commit is contained in:
phenom committed 2026-09-27 14:31:15 -04:00
1 parent ab1434a3b8
commit e284f4fc76
60 files changed
+2704 -118

No files matched your search

+51
View File
@@ -1,6 +1,8 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { useDungeonRaceStore, type RaceServerState } from "./dungeonRaceStore";
import type { CharacterProfile, PlayerSession } from "./types";
import { appendCombatEvent } from "../game/combatEvents";
import { startRaceCombatLog } from "../game/dungeonRaceCombatLog";
const request = vi.hoisted(() => vi.fn());
vi.mock("./onlineAccountClient", () => ({ requestOnlineJson: request }));
@@ -80,4 +82,53 @@ describe("dungeon race exit", () => {
matchId: null, startAt: null, result: null });
expect(request).not.toHaveBeenCalled();
});
it("sends the full recorded stream with a completed online clear", async () => {
request.mockResolvedValue(queued);
await useDungeonRaceStore.getState().startOnline(session, character, "healer", "authored");
const startedAt = Date.now() - 1_000;
useDungeonRaceStore.setState({ mode: "online", status: "active", inGame: true,
matchId: "race-combat-clear", seed: "race-combat-clear",
dungeonId: "bite-sized-stormwind-stockade", startAt: startedAt, serverOffset: 0 });
startRaceCombatLog("race-combat-clear", "bite-sized-stormwind-stockade");
appendCombatEvent([], { occurredAt: startedAt + 100, kind: "damage",
sourceActorId: "player", targetActorId: "mob-1", rawAmount: 20,
effectiveAmount: 20, overheal: 0, absorbed: 0, critical: false }, 1);
await useDungeonRaceStore.getState().reportClear(["boss-1"]);
const finish = request.mock.calls.find(([path]) => path === "/api/dungeon-races/race-combat-clear/finish");
expect(finish).toBeDefined();
const body = JSON.parse(finish![1].body);
expect(body.combatLog).toMatchObject({ completed: true, runId: "race-combat-clear",
events: [{ kind: "damage", effective: 20 }] });
});
it("uploads a partial log before leaving a started online race", async () => {
request.mockResolvedValue(queued);
await useDungeonRaceStore.getState().startOnline(session, character, "healer", "authored");
useDungeonRaceStore.setState({ mode: "online", status: "active", inGame: true,
matchId: "race-combat-leave", seed: "race-combat-leave",
dungeonId: "bite-sized-stormwind-stockade", startAt: Date.now() - 1_000, serverOffset: 0 });
startRaceCombatLog("race-combat-leave", "bite-sized-stormwind-stockade");
await useDungeonRaceStore.getState().leave();
const partial = request.mock.calls.find(([path]) => path === "/api/dungeon-races/race-combat-leave/combat-log");
expect(partial).toBeDefined();
expect(JSON.parse(partial![1].body).combatLog.completed).toBe(false);
expect(request.mock.calls.map(([path, init]) => `${init.method}:${path}`)).toEqual([
"POST:/api/dungeon-races/queue",
"POST:/api/dungeon-races/race-combat-leave/combat-log",
"DELETE:/api/dungeon-races/queue",
]);
});
it("rejects an unknown server mechanic pair before entering or readying", async () => {
request.mockImplementation((path: string) => Promise.resolve(path === "/api/dungeon-races/queue"
? { status: "preparing", serverTime: Date.now(), matchId: "future-race",
seed: "future-race", dungeonId: "bite-sized-stormwind-stockade",
affixIds: ["unknown-kill", "falling-stars"] } : queued));
await useDungeonRaceStore.getState().startOnline(session, character, "healer", "authored");
await vi.waitFor(() => expect(useDungeonRaceStore.getState().error).toContain("does not support"));
expect(useDungeonRaceStore.getState()).toMatchObject({ mode: null, status: "idle", inGame: false, ready: false });
expect(request.mock.calls.map(([path]) => path)).toContain("/api/dungeon-races/queue");
expect(request.mock.calls.some(([, init]) => init.method === "DELETE")).toBe(true);
});
});