diff --git a/src/content/market/favorites-import.ts b/src/content/market/favorites-import.ts new file mode 100644 index 0000000..18cbe55 --- /dev/null +++ b/src/content/market/favorites-import.ts @@ -0,0 +1,17 @@ +import type { FavoriteCreator } from "./favorites-store"; +import type { MarketRecord } from "./types"; + +export function toFavoriteMarketRecords(creators: FavoriteCreator[]): MarketRecord[] { + const byAuthorId = new Map(); + creators.forEach((creator) => { + if (creator.authorId && !byAuthorId.has(creator.authorId)) { + byAuthorId.set(creator.authorId, creator); + } + }); + return Array.from(byAuthorId.values()).map((creator) => ({ + authorId: creator.authorId, + authorName: creator.authorName, + ...(creator.coreUserId ? { coreUserId: creator.coreUserId } : {}), + status: "idle" as const + })); +} diff --git a/tests/favorites-import.test.ts b/tests/favorites-import.test.ts new file mode 100644 index 0000000..2db2790 --- /dev/null +++ b/tests/favorites-import.test.ts @@ -0,0 +1,76 @@ +import { describe, expect, test } from "vitest"; + +import { toFavoriteMarketRecords } from "../src/content/market/favorites-import"; + +describe("favorites-import", () => { + test("returns no records for an empty favorites list", () => { + expect(toFavoriteMarketRecords([])).toEqual([]); + }); + + test("preserves a creator core user id for later batch payload mapping", () => { + expect( + toFavoriteMarketRecords([ + { + authorId: "author-1", + authorName: "达人A", + coreUserId: "core-1", + savedAt: "2026-07-17T00:00:00.000Z" + } + ]) + ).toEqual([ + { + authorId: "author-1", + authorName: "达人A", + coreUserId: "core-1", + status: "idle" + } + ]); + }); + + test("keeps the first creator for each author id in first-occurrence order", () => { + expect( + toFavoriteMarketRecords([ + { + authorId: "author-2", + authorName: "达人B", + savedAt: "2026-07-17T00:00:00.000Z" + }, + { + authorId: "author-1", + authorName: "达人A", + savedAt: "2026-07-17T00:00:01.000Z" + }, + { + authorId: "author-2", + authorName: "达人B更新", + coreUserId: "core-2", + savedAt: "2026-07-17T00:00:02.000Z" + } + ]) + ).toEqual([ + { authorId: "author-2", authorName: "达人B", status: "idle" }, + { authorId: "author-1", authorName: "达人A", status: "idle" } + ]); + }); + + test("returns only the minimal idle market record fields", () => { + const [record] = toFavoriteMarketRecords([ + { + authorId: "author-1", + authorName: "达人A", + savedAt: "2026-07-17T00:00:00.000Z" + } + ]); + + expect(record).toEqual({ + authorId: "author-1", + authorName: "达人A", + status: "idle" + }); + expect(Object.keys(record ?? {})).toEqual([ + "authorId", + "authorName", + "status" + ]); + }); +});