fix: 完善学习进度同步与拼图收集流程
统一阶段拼图配置和进度上报,增加同步写入协调与失败重试,优化收集确认及同步反馈,并展示菜单探索进度。补充相关回归测试与字体素材。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
6491b0c918
commit
9ab67b1bd3
63 files changed
+2141
-360
No files matched your search
@@ -0,0 +1,68 @@
|
||||
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)
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user