import { afterEach, describe, expect, it, vi } from "vitest"; import { createDefaultAppearance } from "../app/characterCatalog"; import { createCharacter, loadUiPreferences, saveUiPreferences } from "../app/accountRepository"; import { useShellStore } from "../app/shellStore"; import { defaultActionBarForCharacter } from "./abilityCatalog"; import { assignDesktopAbility, normalizeUiPreferences } from "./uiLayout"; import { activateCharacterUi, useUiLayoutStore } from "./uiLayoutStore"; afterEach(() => { vi.unstubAllGlobals(); useShellStore.setState({ session: null }); }); describe("character PC action bars", () => { it("persists custom assignments and empty slots across character switches and sign-in", () => { const values = new Map(); const storage = { getItem: (key: string) => values.get(key) ?? null, setItem: (key: string, value: string) => { values.set(key, value); }, removeItem: (key: string) => { values.delete(key); } }; vi.stubGlobal("window", { localStorage: storage }); const create = (name: string) => createCharacter({ ownerId: "offline-bars", name, classId: "priest", raceId: "human", gender: "female", appearance: createDefaultAppearance(), }, storage).character!; const first = create("Firstbars"); const second = create("Secondbars"); const ui = normalizeUiPreferences(null); ui.current.pc.wowBars = true; saveUiPreferences(first.ownerId, ui, storage); const session = { kind: "offline" as const, ownerId: first.ownerId, displayName: "Offline" }; useShellStore.setState({ session }); activateCharacterUi(first); expect(useUiLayoutStore.getState().preferences.current.pc.bars[0].slots[0].abilityId) .toBe(defaultActionBarForCharacter("priest", null, 1)[0]); const state = useUiLayoutStore.getState(); const pc = assignDesktopAbility(assignDesktopAbility(state.preferences.current.pc, 0, 0, null), 0, 2, "priest-flash-heal"); state.persist({ ...state.preferences, current: { ...state.preferences.current, pc } }); activateCharacterUi(second); expect(useUiLayoutStore.getState().preferences.current.pc.bars[0].slots[0].abilityId).not.toBeNull(); activateCharacterUi(first); expect(useUiLayoutStore.getState().preferences.current.pc.bars[0].slots[0].abilityId).toBeNull(); expect(useUiLayoutStore.getState().preferences.current.pc.bars[0].slots[2].abilityId).toBe("priest-flash-heal"); useShellStore.setState({ session: null }); useShellStore.setState({ session: { ...session } }); activateCharacterUi(first); expect(useUiLayoutStore.getState().preferences.current.pc.bars[0].slots[0].abilityId).toBeNull(); expect(useUiLayoutStore.getState().preferences.current.pc.bars[0].slots[2].abilityId).toBe("priest-flash-heal"); expect(loadUiPreferences("another-owner", storage).desktopAbilityLoadouts).toEqual({}); activateCharacterUi({ ...second, ownerId: "another-owner" }); expect(useUiLayoutStore.getState().desktopLoadoutKey).toContain(first.id); }); });