import { describe, expect, it } from "vitest"; import { sampleContentPack } from "@/data/sampleContentPack"; import { createStartingAdventurer } from "./character"; import { createRunState, returnToTown } from "./runState"; import { grantDebugTreasure, queueTreasureForSale, sellPendingTreasure, stashCarriedTreasure, withdrawStashedTreasure, } from "./townInventory"; function createAdventurer() { return createStartingAdventurer(sampleContentPack, { name: "Aster", weaponId: "weapon.short-sword", armourId: "armour.leather-vest", scrollId: "scroll.lesser-heal", }); } function createTownRun() { const run = createRunState({ content: sampleContentPack, campaignId: "campaign.1", adventurer: createAdventurer(), }); return returnToTown(run, "2026-03-18T21:00:00.000Z").run; } describe("town inventory loop", () => { it("stores carried treasure in the town stash", () => { const inTown = createTownRun(); inTown.adventurerSnapshot.inventory.carried.push({ definitionId: "item.silver-chalice", quantity: 1, }); const result = stashCarriedTreasure({ content: sampleContentPack, run: inTown, definitionId: "item.silver-chalice", at: "2026-03-18T21:05:00.000Z", }); expect(result.run.adventurerSnapshot.inventory.carried).not.toEqual( expect.arrayContaining([expect.objectContaining({ definitionId: "item.silver-chalice" })]), ); expect(result.run.townState.stash).toEqual( expect.arrayContaining([ expect.objectContaining({ definitionId: "item.silver-chalice", quantity: 1, }), ]), ); }); it("withdraws stashed treasure back to the pack", () => { const inTown = createTownRun(); inTown.townState.stash.push({ definitionId: "item.garnet-ring", quantity: 1, }); const result = withdrawStashedTreasure({ content: sampleContentPack, run: inTown, definitionId: "item.garnet-ring", at: "2026-03-18T21:06:00.000Z", }); expect(result.run.townState.stash).toHaveLength(0); expect(result.run.adventurerSnapshot.inventory.carried).toEqual( expect.arrayContaining([ expect.objectContaining({ definitionId: "item.garnet-ring", quantity: 1, }), ]), ); }); it("queues treasure for sale and converts it into gold", () => { const inTown = createTownRun(); const withTreasure = grantDebugTreasure({ content: sampleContentPack, run: inTown, definitionId: "item.garnet-ring", quantity: 2, at: "2026-03-18T21:07:00.000Z", }).run; const queued = queueTreasureForSale({ content: sampleContentPack, run: withTreasure, definitionId: "item.garnet-ring", quantity: 2, source: "carried", at: "2026-03-18T21:08:00.000Z", }).run; const sold = sellPendingTreasure({ content: sampleContentPack, run: queued, at: "2026-03-18T21:09:00.000Z", }).run; expect(queued.townState.pendingSales).toEqual( expect.arrayContaining([ expect.objectContaining({ definitionId: "item.garnet-ring", quantity: 2, }), ]), ); expect(sold.townState.pendingSales).toHaveLength(0); expect(sold.adventurerSnapshot.inventory.currency.gold).toBe( withTreasure.adventurerSnapshot.inventory.currency.gold + 24, ); expect(sold.log.at(-1)?.text).toContain("24 gold"); }); });