统一阶段拼图配置和进度上报,增加同步写入协调与失败重试,优化收集确认及同步反馈,并展示菜单探索进度。补充相关回归测试与字体素材。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
69 lines
3.1 KiB
TypeScript
69 lines
3.1 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
const { setUserDefine } = vi.hoisted(() => ({
|
|
setUserDefine: vi.fn().mockResolvedValue({ success: true }),
|
|
}))
|
|
vi.mock('@/lib/utils/api-common', () => ({ setUserDefine }))
|
|
|
|
beforeEach(() => {
|
|
vi.resetModules()
|
|
setUserDefine.mockClear()
|
|
const storage = new Map<string, string>()
|
|
vi.stubGlobal('localStorage', {
|
|
getItem: (key: string) => storage.get(key) ?? null,
|
|
setItem: (key: string, value: string) => storage.set(key, value),
|
|
removeItem: (key: string) => storage.delete(key),
|
|
})
|
|
vi.stubGlobal('window', { localStorage })
|
|
})
|
|
|
|
afterEach(() => vi.unstubAllGlobals())
|
|
|
|
const image = 'data:image/jpeg;base64,YWJj'
|
|
|
|
describe('local-only artwork', () => {
|
|
it('keeps Zhang Leping artwork locally and excludes even short data URLs from sync', async () => {
|
|
const { useZhanglepingStore, saveZhanglepingStore, applyZhanglepingPersistedState } =
|
|
await import('./zhanglepingStore')
|
|
useZhanglepingStore.getState().setDrawArtwork(image, 'caption')
|
|
await saveZhanglepingStore()
|
|
const payload = JSON.parse(setUserDefine.mock.calls[0]![2])
|
|
expect(payload).not.toHaveProperty('drawArtworkDataUrl')
|
|
expect(payload.drawArtworkCaption).toBe('caption')
|
|
expect(payload.hasDrawArtwork).toBe(true)
|
|
applyZhanglepingPersistedState(payload)
|
|
expect(useZhanglepingStore.getState().drawArtworkDataUrl).toBe(image)
|
|
expect(JSON.parse(localStorage.getItem('zhangleping-storage')!).state.drawArtworkDataUrl).toBe(
|
|
image
|
|
)
|
|
})
|
|
|
|
it('keeps Nie Er previews locally while syncing other work fields', async () => {
|
|
const { useNieerStore, saveNieerStore, applyNieerPersistedState } = await import('./nieerStore')
|
|
useNieerStore.getState().setReflectionWork(6, { previewImageDataUrl: image, paradeId: '1' })
|
|
await saveNieerStore()
|
|
const payload = JSON.parse(setUserDefine.mock.calls[0]![2])
|
|
expect(payload.reflectionWorks[6]).not.toHaveProperty('previewImageDataUrl')
|
|
expect(payload.reflectionWorks[6].paradeId).toBe('1')
|
|
expect(useNieerStore.getState().reflectionWorks[6]?.previewImageDataUrl).toBe(image)
|
|
applyNieerPersistedState(payload)
|
|
expect(useNieerStore.getState().reflectionWorks[6]?.previewImageDataUrl).toBe(image)
|
|
expect(
|
|
JSON.parse(localStorage.getItem('nieer-storage')!).state.reflectionWorks[6]
|
|
.previewImageDataUrl
|
|
).toBe(image)
|
|
})
|
|
|
|
it('does not restore legacy remote images over local images', async () => {
|
|
const { useZhanglepingStore, applyZhanglepingPersistedState } =
|
|
await import('./zhanglepingStore')
|
|
const { useNieerStore, applyNieerPersistedState } = await import('./nieerStore')
|
|
useZhanglepingStore.getState().setDrawArtwork(image, 'caption')
|
|
useNieerStore.getState().setReflectionWork(6, { previewImageDataUrl: image })
|
|
applyZhanglepingPersistedState({ drawArtworkDataUrl: 'remote' })
|
|
applyNieerPersistedState({ reflectionWorks: { 6: { previewImageDataUrl: 'remote' } } })
|
|
expect(useZhanglepingStore.getState().drawArtworkDataUrl).toBe(image)
|
|
expect(useNieerStore.getState().reflectionWorks[6]?.previewImageDataUrl).toBe(image)
|
|
})
|
|
})
|