import assert from "node:assert/strict"; import test from "node:test"; import { chartLibraryFromCloudOthers, chartLibraryOnCloudFailure, chartLibrarySessionBranch, } from "../src/lib/chart-library-session.ts"; import { sessionSidebarSubtitle, sessionSidebarTitle } from "../src/lib/home-profile.ts"; import { emptyProfile, type ChartLibraryRecord, type ChatSession } from "../src/lib/home-types.ts"; type RecordShape = { id: string; role: "self" | "other" }; function upsertSelf(library: RecordShape[], profile: unknown): RecordShape[] { const others = library.filter((record) => record.role !== "self"); if (!profile) return others; return [{ id: "self", role: "self" }, ...others]; } test("clearing the account empties the chart library session", () => { assert.equal(chartLibrarySessionBranch(null, "acct-1"), "clear"); assert.equal(chartLibrarySessionBranch("", "acct-1"), "clear"); }); test("switching accounts hydrates local then cloud instead of writing the previous library", () => { assert.equal(chartLibrarySessionBranch("acct-2", "acct-1"), "hydrate-then-persist"); }); test("a later profile change on the same account still upserts self", () => { assert.equal(chartLibrarySessionBranch("acct-1", "acct-1"), "persist-self"); const current: RecordShape[] = [{ id: "other-1", role: "other" }]; assert.deepEqual(upsertSelf(current, { name: "self" }), [ { id: "self", role: "self" }, { id: "other-1", role: "other" }, ]); }); test("a successful cloud read keeps only non-self records before upserting self", () => { const cloud: RecordShape[] = [ { id: "stale-self", role: "self" }, { id: "other-1", role: "other" }, ]; assert.deepEqual(chartLibraryFromCloudOthers(cloud, { name: "self" }, upsertSelf), [ { id: "self", role: "self" }, { id: "other-1", role: "other" }, ]); }); test("a failed cloud read keeps only the profile-derived self chart", () => { // Former value: keepLocalChartLibraryOnCloudFailure(local) === local. // Local other-charts are no longer a fallback when the cloud read fails. const local: RecordShape[] = [{ id: "self", role: "self" }, { id: "other-1", role: "other" }]; assert.notDeepEqual(chartLibraryOnCloudFailure({ name: "self" }, upsertSelf), local); assert.deepEqual(chartLibraryOnCloudFailure({ name: "self" }, upsertSelf), [ { id: "self", role: "self" }, ]); }); test("sidebar titles drop the chart-name prefix and only subtitle others", () => { const selfRecord: ChartLibraryRecord = { id: "self", role: "self", relationship: "self", updatedAt: 1, profile: { ...emptyProfile, name: "本人" }, }; const library: ChartLibraryRecord[] = [selfRecord]; const base: ChatSession = { id: "11111111-1111-4111-8111-111111111111", title: "半年内换工作时机", theme: "career", modelId: "m", messages: [], updatedAt: 1, sessionType: "consultation", rectificationCaseId: null, chartProfileId: "self", chartProfileName: "本人", chartProfileRole: "self", pinned: false, archivedAt: null, messagesHydrated: true, }; assert.equal(sessionSidebarTitle(base, library), "半年内换工作时机"); assert.equal(sessionSidebarSubtitle(base, library), null); const other = { ...base, chartProfileId: "other-1", chartProfileName: "对方", chartProfileRole: "other" as const }; assert.equal(sessionSidebarSubtitle(other, library), "资料已删除 · 对方"); const liveOtherLibrary: ChartLibraryRecord[] = [{ ...selfRecord, id: "other-1", role: "other", relationship: "partner", profile: { ...emptyProfile, name: "对方" }, }]; assert.equal(sessionSidebarSubtitle(other, liveOtherLibrary), "对方"); });