mirror of
https://github.com/Horizontal42/summarum.git
synced 2026-11-10 15:42:01 +03:00
Covers isTauri, and loadSettings/saveSettings across both the Tauri invoke path and the localStorage fallback, including corrupt-data and thrown-error recovery.
96 lines
3.7 KiB
TypeScript
96 lines
3.7 KiB
TypeScript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
import { isTauri, loadSettings, saveSettings, defaultSettingsData } from './storage';
|
|
import { invoke } from '@tauri-apps/api/core';
|
|
|
|
vi.mock('@tauri-apps/api/core', () => ({
|
|
invoke: vi.fn(),
|
|
}));
|
|
|
|
describe('storage', () => {
|
|
beforeEach(() => {
|
|
vi.resetAllMocks();
|
|
vi.stubGlobal('window', {});
|
|
vi.stubGlobal('localStorage', {
|
|
getItem: vi.fn(),
|
|
setItem: vi.fn(),
|
|
});
|
|
vi.stubGlobal('console', { warn: vi.fn() });
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
describe('isTauri', () => {
|
|
it('returns false when not in Tauri', () => {
|
|
expect(isTauri()).toBe(false);
|
|
});
|
|
|
|
it('returns true when in Tauri', () => {
|
|
vi.stubGlobal('window', { __TAURI_INTERNALS__: {} });
|
|
expect(isTauri()).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('loadSettings', () => {
|
|
it('loads from localStorage when not in Tauri', async () => {
|
|
vi.mocked(localStorage.getItem).mockReturnValue(JSON.stringify({ precision: 5 }));
|
|
const settings = await loadSettings();
|
|
expect(localStorage.getItem).toHaveBeenCalledWith('summarum.settings');
|
|
expect(settings.precision).toBe(5);
|
|
expect(settings.theme).toBe(defaultSettingsData.theme);
|
|
});
|
|
|
|
it('loads via invoke when in Tauri', async () => {
|
|
vi.stubGlobal('window', { __TAURI_INTERNALS__: {} });
|
|
vi.mocked(invoke).mockResolvedValue(JSON.stringify({ precision: 8 }));
|
|
const settings = await loadSettings();
|
|
expect(invoke).toHaveBeenCalledWith('load_file', { name: 'settings.json' });
|
|
expect(settings.precision).toBe(8);
|
|
expect(settings.theme).toBe(defaultSettingsData.theme);
|
|
});
|
|
|
|
it('falls back to defaultSettingsData if localStorage throws', async () => {
|
|
vi.mocked(localStorage.getItem).mockImplementation(() => { throw new Error('localStorage error'); });
|
|
const settings = await loadSettings();
|
|
expect(console.warn).toHaveBeenCalledWith('loadSettings failed', expect.any(Error));
|
|
expect(settings).toEqual(defaultSettingsData);
|
|
});
|
|
|
|
it('falls back to defaultSettingsData if invoke throws', async () => {
|
|
vi.stubGlobal('window', { __TAURI_INTERNALS__: {} });
|
|
vi.mocked(invoke).mockRejectedValue(new Error('invoke error'));
|
|
const settings = await loadSettings();
|
|
expect(console.warn).toHaveBeenCalledWith('loadSettings failed', expect.any(Error));
|
|
expect(settings).toEqual(defaultSettingsData);
|
|
});
|
|
|
|
it('falls back to defaultSettingsData if localStorage returns null', async () => {
|
|
vi.mocked(localStorage.getItem).mockReturnValue(null);
|
|
const settings = await loadSettings();
|
|
expect(settings).toEqual(defaultSettingsData);
|
|
});
|
|
|
|
it('falls back to defaultSettingsData if JSON is invalid', async () => {
|
|
vi.mocked(localStorage.getItem).mockReturnValue("invalid json");
|
|
const settings = await loadSettings();
|
|
expect(console.warn).toHaveBeenCalledWith('loadSettings failed', expect.any(Error));
|
|
expect(settings).toEqual(defaultSettingsData);
|
|
});
|
|
});
|
|
|
|
describe('saveSettings', () => {
|
|
it('saves to localStorage when not in Tauri', async () => {
|
|
const settings = { ...defaultSettingsData, precision: 10 };
|
|
await saveSettings(settings);
|
|
expect(localStorage.setItem).toHaveBeenCalledWith('summarum.settings', JSON.stringify(settings, null, 2));
|
|
});
|
|
|
|
it('saves via invoke when in Tauri', async () => {
|
|
vi.stubGlobal('window', { __TAURI_INTERNALS__: {} });
|
|
const settings = { ...defaultSettingsData, precision: 12 };
|
|
await saveSettings(settings);
|
|
expect(invoke).toHaveBeenCalledWith('save_file', { name: 'settings.json', contents: JSON.stringify(settings, null, 2) });
|
|
});
|
|
});
|
|
});
|