| import { afterEach, beforeEach, describe, expect, it } from "vitest"; |
| import { |
| __resetCustomerMemoryForTests, |
| getCustomerMemoryScope, |
| getPotsEstimatorCarryover, |
| getRapidRouterDraftCarryover, |
| getSmartProfile, |
| listResumeWorkCards, |
| mergeSmartProfile, |
| setCustomerMemoryScope, |
| setPotsEstimatorCarryover, |
| setRapidRouterDraftCarryover, |
| upsertResumeWorkCard, |
| } from "./customerMemory"; |
|
|
| const LEGACY_CUSTOMER_MEMORY_KEY = "masters_toolkit_customer_memory_v1"; |
| const store = new Map<string, string>(); |
|
|
| beforeEach(() => { |
| store.clear(); |
| __resetCustomerMemoryForTests(); |
| setCustomerMemoryScope("anonymous"); |
| Object.defineProperty(window, "localStorage", { |
| configurable: true, |
| value: { |
| getItem: (key: string) => (store.has(key) ? String(store.get(key)) : null), |
| setItem: (key: string, value: string) => { |
| store.set(key, String(value)); |
| }, |
| removeItem: (key: string) => { |
| store.delete(key); |
| }, |
| clear: () => { |
| store.clear(); |
| }, |
| }, |
| }); |
| }); |
|
|
| afterEach(() => { |
| __resetCustomerMemoryForTests(); |
| setCustomerMemoryScope("anonymous"); |
| store.clear(); |
| }); |
|
|
| describe("customerMemory", () => { |
| it("isolates stored customer data by scoped user identity", () => { |
| store.set( |
| LEGACY_CUSTOMER_MEMORY_KEY, |
| JSON.stringify({ |
| profile: { companyName: "Legacy Shared Customer" }, |
| }) |
| ); |
|
|
| setCustomerMemoryScope(" James@Verizon.com "); |
| expect(getCustomerMemoryScope()).toBe("james@verizon.com"); |
| expect(getSmartProfile()).toBeNull(); |
| mergeSmartProfile({ companyName: "John Q", email: "johnq@example.com" }); |
| setRapidRouterDraftCarryover({ customerName: "John Q", qty: 2 }, "James draft"); |
| upsertResumeWorkCard({ |
| id: "rapid_router:last_order_draft", |
| title: "Repeat last Rapid Router order draft", |
| source: "rapid_router", |
| actionCommand: "navigate:rapid_router_draft", |
| }); |
|
|
| setCustomerMemoryScope("timmy@verizon.com"); |
| expect(getSmartProfile()).toBeNull(); |
| expect(getRapidRouterDraftCarryover()).toBeNull(); |
| expect(listResumeWorkCards()).toEqual([]); |
|
|
| mergeSmartProfile({ companyName: "Different Customer" }); |
| expect(getSmartProfile()?.companyName).toBe("Different Customer"); |
|
|
| setCustomerMemoryScope("james@verizon.com"); |
| expect(getSmartProfile()?.companyName).toBe("John Q"); |
| expect(getRapidRouterDraftCarryover()?.summary).toBe("James draft"); |
| expect(listResumeWorkCards()[0]?.id).toBe("rapid_router:last_order_draft"); |
| const persisted = JSON.parse(store.get("masters_toolkit_customer_memory_v2:james@verizon.com") || "{}"); |
| expect(persisted.profile?.companyName).toBe("John Q"); |
| expect(persisted.carryover?.rapidRouterDraft?.summary).toBe("James draft"); |
| expect(Array.isArray(persisted.cards)).toBe(true); |
| }); |
|
|
| it("merges and returns smart profile fields", () => { |
| setCustomerMemoryScope("owner@example.com"); |
| mergeSmartProfile({ companyName: "Acme", city: "Miami", state: "fl", zip: "33127-1000" }); |
| mergeSmartProfile({ contactName: "Pat", email: "pat@example.com" }); |
| const profile = getSmartProfile(); |
| expect(profile?.companyName).toBe("Acme"); |
| expect(profile?.city).toBe("Miami"); |
| expect(profile?.state).toBe("FL"); |
| expect(profile?.zip).toBe("33127"); |
| expect(profile?.contactName).toBe("Pat"); |
| expect(profile?.email).toBe("pat@example.com"); |
| }); |
|
|
| it("stores and sorts resume cards by recency", () => { |
| setCustomerMemoryScope("owner@example.com"); |
| upsertResumeWorkCard({ |
| id: "older", |
| title: "Older card", |
| source: "knowledgebase", |
| actionCommand: "router_helper:open", |
| updatedAt: "2026-03-01T00:00:00.000Z", |
| }); |
| upsertResumeWorkCard({ |
| id: "newer", |
| title: "Newer card", |
| source: "rapid_router", |
| actionCommand: "navigate:rapid_router_draft", |
| updatedAt: "2026-03-02T00:00:00.000Z", |
| }); |
| const cards = listResumeWorkCards(); |
| expect(cards[0]?.id).toBe("newer"); |
| expect(cards[1]?.id).toBe("older"); |
| }); |
|
|
| it("persists customer carryover and profile data across a reload", () => { |
| setCustomerMemoryScope("owner@example.com"); |
| mergeSmartProfile({ companyName: "Acme", city: "Miami" }); |
| setPotsEstimatorCarryover({ companyName: "Acme", totalLines: 12 }, "Acme carryover"); |
| setRapidRouterDraftCarryover({ customerName: "Acme", qty: 3 }, "Acme order"); |
|
|
| __resetCustomerMemoryForTests(); |
|
|
| expect(getSmartProfile()?.companyName).toBe("Acme"); |
| expect(getSmartProfile()?.city).toBe("Miami"); |
| expect(getPotsEstimatorCarryover()?.summary).toBe("Acme carryover"); |
| expect(getRapidRouterDraftCarryover()?.summary).toBe("Acme order"); |
| expect((getPotsEstimatorCarryover()?.payload || {}).companyName).toBe("Acme"); |
| expect((getRapidRouterDraftCarryover()?.payload || {}).qty).toBe(3); |
| expect(store.get("masters_toolkit_customer_memory_v2:owner@example.com")).toContain("Acme"); |
| }); |
| }); |
|
|