mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-08-03 02:11:07 +05:30
Two related bugs surfaced during end-to-end verification:
1. The 'isAlreadyV5' short-circuit in both the main-side and renderer-side
v4-to-v5 transforms returned the persisted object as-is when a
migration.version=5 marker was present. A previously-shipped v4 build
had written theme: 'ayu-light' (and similar) under the v5 marker;
the transform trusted the marker and passed the invalid theme through,
which then failed the renderer's zod schema on every launch and
reset user settings to defaults.
Fix: in both transforms, when isAlreadyV5 matches, normalize theme
against the v5 enum (light/dark/system) and validate the full result
with the v5 schema before returning. Out-of-range values are replaced
with the v5 default ('system').
2. The renderer's settings-store onRehydrateStorage callback called
useSettingsStore.setState() to reset the store on validation failure.
At that moment the store is still being constructed, and setState
could hit a TDZ ReferenceError (the one we already wrapped in a
try/catch in v5.0.0, which only hid the symptom).
Fix: return the normalized state object from onRehydrateStorage
instead. Zustand's persist middleware applies the returned value
*after* construction completes, so there is no TDZ.
Tests: 334 vitest + 208 jest = 542 passing.
E2E: 12/12 verify-features.mjs steps green; no console errors.
Amit Haridas
43 lines
1.6 KiB
TypeScript
43 lines
1.6 KiB
TypeScript
import { describe, expect, test } from 'vitest';
|
|
import { migrateV4ToV5, v4SettingsSchema } from '@/lib/migrations/v4-to-v5';
|
|
|
|
describe('migrateV4ToV5', () => {
|
|
test('maps theme auto to system', () => {
|
|
const out = migrateV4ToV5({ theme: 'auto', editorFontSize: 14 });
|
|
expect(out.theme).toBe('system');
|
|
expect(out.editorFontSize).toBe(14);
|
|
});
|
|
|
|
test('drops unknown keys, applies defaults', () => {
|
|
const out = migrateV4ToV5({ theme: 'light', weirdKey: 1 });
|
|
expect(out.theme).toBe('light');
|
|
expect(out.weirdKey).toBeUndefined();
|
|
expect(out.tabSize).toBe(4); // default
|
|
});
|
|
|
|
test('throws on invalid v4 input', () => {
|
|
expect(() => migrateV4ToV5({ theme: 42 })).toThrow();
|
|
});
|
|
|
|
test('is idempotent — running twice yields the same v5 output', () => {
|
|
const v4 = { theme: 'dark', editorFontSize: 16, recentFiles: ['/a.md'] };
|
|
const a = migrateV4ToV5(v4);
|
|
const b = migrateV4ToV5(v4);
|
|
expect(a).toEqual(b);
|
|
});
|
|
|
|
test('normalizes legacy theme names like "ayu-light" to a v5 value', () => {
|
|
// A previously-shipped v4 build wrote theme: 'ayu-light' (and similar).
|
|
// When an already-v5-marker file has such a value, isAlreadyV5 used to
|
|
// short-circuit and return the file as-is — which then failed the v5
|
|
// schema and reset user settings on every launch. The transform must
|
|
// normalize unknown theme values to the schema's default.
|
|
const out = migrateV4ToV5({ 'migration.version': 5, theme: 'ayu-light' });
|
|
expect(['light', 'dark', 'system']).toContain(out.theme);
|
|
});
|
|
|
|
test('exposes the v4 schema for use by main', () => {
|
|
expect(v4SettingsSchema).toBeDefined();
|
|
});
|
|
});
|