import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; import { BABY_OBJECT_MATCH_EDUTAINMENT_TAG, hasBabyObjectMatchRequiredTag, } from '../../../packages/shared/src/contracts/edutainmentBabyObject'; import { createBabyObjectMatchDraft, deleteLocalBabyObjectMatchDraft, listLocalBabyObjectMatchDrafts, publishBabyObjectMatchWork, } from './babyObjectMatchClient'; describe('babyObjectMatchClient', () => { beforeEach(() => { const store = new Map(); vi.stubGlobal('window', { localStorage: { getItem: (key: string) => store.get(key) ?? null, setItem: (key: string, value: string) => { store.set(key, value); }, }, }); }); afterEach(() => { vi.unstubAllGlobals(); }); test('creates local demo draft with exact edutainment tag', async () => { vi.stubGlobal('crypto', { randomUUID: () => '11111111-2222-3333-4444-555555555555', }); const response = await createBabyObjectMatchDraft({ itemAName: ' 苹果 ', itemBName: '香蕉', }); expect(response.draft.templateName).toBe('宝贝识物'); expect(response.draft.itemNames).toEqual(['苹果', '香蕉']); expect(response.draft.itemAssets).toHaveLength(2); expect(response.draft.itemAssets[0]?.generationProvider).toBe( 'placeholder', ); expect(response.draft.themeTags).toContain( BABY_OBJECT_MATCH_EDUTAINMENT_TAG, ); expect(hasBabyObjectMatchRequiredTag(response.draft.themeTags)).toBe(true); }); test('rejects draft creation when any item name is empty', async () => { await expect( createBabyObjectMatchDraft({ itemAName: '苹果', itemBName: ' ', }), ).rejects.toThrow('请填写两个物品名称。'); }); test('publish normalizes exact edutainment tag into payload', async () => { const response = await createBabyObjectMatchDraft({ itemAName: '杯子', itemBName: '勺子', }); const published = await publishBabyObjectMatchWork({ draft: { ...response.draft, themeTags: ['儿童教育', '寓教于乐 '], }, }); expect(published.publicWorkCode).toMatch(/^BO-/u); expect(published.draft.publicationStatus).toBe('published'); expect(published.draft.themeTags[0]).toBe( BABY_OBJECT_MATCH_EDUTAINMENT_TAG, ); expect(hasBabyObjectMatchRequiredTag(published.draft.themeTags)).toBe(true); }); test('deletes local baby object match draft by profile id', async () => { const response = await createBabyObjectMatchDraft({ itemAName: '苹果', itemBName: '香蕉', }); expect(listLocalBabyObjectMatchDrafts()).toHaveLength(1); const nextItems = deleteLocalBabyObjectMatchDraft(response.draft.profileId); expect(nextItems).toHaveLength(0); expect(listLocalBabyObjectMatchDrafts()).toHaveLength(0); }); });