fix(settings): ignore outdated settings and font responses
This commit is contained in:
1 parent
1882312435
commit
830fabaa2d
2 files changed
+49
-1
No files matched your search
@@ -8,7 +8,7 @@ import ShortcutSettings from './ShortcutSettings.vue'
|
||||
import { DEFAULTS, loadSettings, settings, settingsSave, SettingsAppearanceError, updateSettings } from './settings'
|
||||
import { searchSettings } from './settingsCatalog'
|
||||
import { ws } from './workspace'
|
||||
import { applyFontCatalog } from './fonts'
|
||||
import { applyFontCatalog, customFonts } from './fonts'
|
||||
|
||||
let app: App | undefined
|
||||
let host: HTMLElement | undefined
|
||||
@@ -194,6 +194,50 @@ describe('设置查找与重置', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('设置同步顺序', () => {
|
||||
it.each(['settings', 'fonts'] as const)('旧%s响应晚到时,不恢复已删除字体或覆盖新设置与缓存', async (delayed) => {
|
||||
const font = { id: 'custom-' + 'c'.repeat(64), name: '已删除字体', format: 'woff2' as const }
|
||||
const oldSettings = { uiFont: font.id, textFont: font.id, codeFont: font.id, fontSize: 18 }
|
||||
let release!: () => void
|
||||
const pending = new Promise<void>(resolve => { release = resolve })
|
||||
vi.mocked(api.settings).mockImplementationOnce(async () => {
|
||||
if (delayed === 'settings') await pending
|
||||
return oldSettings
|
||||
})
|
||||
vi.mocked(api.fonts).mockImplementationOnce(async () => {
|
||||
if (delayed === 'fonts') await pending
|
||||
return [font]
|
||||
})
|
||||
const oldLoad = loadSettings()
|
||||
vi.mocked(api.settings).mockResolvedValue({ uiFont: 'maple', textFont: 'maple', codeFont: 'maple', fontSize: 24 })
|
||||
await loadSettings()
|
||||
const cache = localStorage.getItem('rawmark.settings')
|
||||
release()
|
||||
await oldLoad
|
||||
expect(settings).toMatchObject({ uiFont: 'maple', textFont: 'maple', codeFont: 'maple', fontSize: 24 })
|
||||
expect(customFonts.value).toEqual([])
|
||||
expect(document.querySelector('#rm-custom-fonts')!.textContent).not.toContain(font.id)
|
||||
expect(document.documentElement.style.getPropertyValue('--rm-font-text')).not.toContain(font.id)
|
||||
expect(document.documentElement.style.getPropertyValue('--rm-font-size')).toBe('24px')
|
||||
expect(localStorage.getItem('rawmark.settings')).toBe(cache)
|
||||
})
|
||||
|
||||
it('最新同步失败仍报告原错误,迟到旧响应不会覆盖当前状态,后续可重新同步', async () => {
|
||||
let release!: (value: Record<string, unknown>) => void
|
||||
vi.mocked(api.settings).mockImplementationOnce(() => new Promise(resolve => { release = resolve }))
|
||||
const oldLoad = loadSettings()
|
||||
const cause = new ApiError(503, '字体列表暂时不可用')
|
||||
vi.mocked(api.fonts).mockRejectedValueOnce(cause)
|
||||
await expect(loadSettings()).rejects.toBe(cause)
|
||||
release({ fontSize: 18 })
|
||||
await oldLoad
|
||||
expect(settings.fontSize).toBe(DEFAULTS.fontSize)
|
||||
vi.mocked(api.settings).mockResolvedValue({ fontSize: 24 })
|
||||
await loadSettings()
|
||||
expect(settings.fontSize).toBe(24)
|
||||
})
|
||||
})
|
||||
|
||||
describe('保存反馈', () => {
|
||||
it('所有排队请求完成之前保留保存中,不提前发送后续请求', async () => {
|
||||
let finish!: (value: Record<string, unknown>) => void
|
||||
|
||||
@@ -94,8 +94,12 @@ applied({ ...settings })
|
||||
// 缓存只提前应用明暗模式;主题和片段等服务器确认后再应用。
|
||||
applyAppearance({ ...settings, theme: 'default', cssSnippets: [] }, '')
|
||||
|
||||
let settingsRequest = 0
|
||||
export async function loadSettings() {
|
||||
const request = ++settingsRequest
|
||||
const [raw, fonts] = await Promise.all([api.settings(), api.fonts()])
|
||||
// 目录与设置作为一批应用,迟到旧响应不能恢复已删除字体或覆盖新设置。
|
||||
if (request !== settingsRequest) return
|
||||
applyFontCatalog(parseFontCatalog(fonts))
|
||||
applied(sanitize(raw))
|
||||
await applySettingsAppearance()
|
||||
|
||||
Reference in new issue
Block a user