broekema41_obsidian-vcf-con.../tests/context.spec.ts

160 lines
5 KiB
TypeScript

import { effect } from "@preact/signals-core";
import { App } from "obsidian";
import { clearApp,getApp, setApp } from 'src/context/sharedAppContext'
import {
clearSettings,
getSettings, initSettings,
setSettings,
settings, updateSetting,
} from 'src/context/sharedSettingsContext';
vi.mock("src/insights/insightService", () => ({
insightService: {
settings: vi.fn(() => [
{ settingPropertyName: "someRandomProcessor", settingDefaultValue: true },
{ settingPropertyName: "anotherProcessor", settingDefaultValue: false },
]),
},
}));
import { DEFAULT_SETTINGS } from "src/settings/setting";
import type { ContactsPluginSettings } from 'src/settings/settings.d';
import { afterEach,describe, expect, it, vi } from 'vitest';
const mockSettings: ContactsPluginSettings = {
contactsFolder: 'Contacts',
defaultHashtag: '',
processors: {
someRandomProcessor: true,
},
syncEnabled: false,
groupInsights: true,
syncSelected: 'None',
CardDAV: {
addressBookUrl: '',
syncInterval: 900,
authKey: '',
authType: 'apikey'
},
createFieldsKeys:['N.FN']
};
const testDefaultSettings = {
...DEFAULT_SETTINGS,
...{processors: {
"anotherProcessor": false,
"someRandomProcessor": true,
}}
};
export const loadData = vi.fn(async () => mockSettings);
// Async mock that records calls and resolves
export const saveData = vi.fn(async (data: ContactsPluginSettings) => {
// You can inspect `data` in your tests
return Promise.resolve();
});
describe('sharedAppContext', () => {
afterEach(() => clearApp());
it('stores and retrieves the app instance', () => {
const mockApp = { vault: { name: 'test' }, workspace: { activeLeaf: true } } as unknown as App;
setApp(mockApp);
const retrieved = getApp();
expect(retrieved).toBe(mockApp);
});
it('throws if app is not set', () => {
expect(() => getApp()).toThrow('App context has not been set.');
});
});
describe('sharedSettingsContext', () => {
afterEach(() => {
clearSettings();
vi.clearAllMocks();
});
it('should be initialized and have default settings', async () => {
await initSettings(async () => {}, saveData)
const retrieved = getSettings();
expect(retrieved).to.deep.equal(testDefaultSettings);
expect(saveData).toHaveBeenCalledTimes(1);
expect(saveData).toHaveBeenCalledWith(expect.objectContaining(testDefaultSettings));
});
it('setSettings should overwrite the complete settings object', async () => {
await initSettings(loadData, saveData)
await setSettings(mockSettings);
const firstSaveArgs = saveData.mock.calls[0];
const firstSaveData = firstSaveArgs[0];
expect(firstSaveData.processors.someRandomProcessor).toBe(true);
expect(firstSaveData.processors.anotherProcessor).toBe(false);
const retrieved = getSettings();
expect(saveData).toHaveBeenCalledTimes(2);
expect(retrieved).to.deep.equal(mockSettings);
});
it('throws if getSettings called while not initialized', () => {
expect(() => getSettings()).toThrow('Plugin context has not been set.');
});
it('throws if updateSetting called while not initialized', async () => {
await expect(async () => await updateSetting('contactsFolder', 'empty')).rejects.toThrow('Plugin context has not been set.');
});
it('throws if updateSetting called with a field that does not exist in the settings object', async () => {
await initSettings(loadData, saveData)
await expect(async () => await updateSetting('contactsFolder.not.exist', 'empty')).rejects.toThrow('Invalid settings path: contactsFolder.not.exist');
});
it('calls listeners when settings are updated', async () => {
const listener = vi.fn();
const unsubscribe = effect(() => {
if (settings.value !== undefined) {
listener(settings.value);
}
});
await initSettings(loadData, saveData)
await setSettings(mockSettings);
expect(listener).toHaveBeenCalledTimes(2);
expect(listener).toHaveBeenCalledWith(mockSettings);
unsubscribe();
});
it('removes listener when unsubscribe is called', async () => {
await initSettings(async () => {}, saveData);
const listener = vi.fn();
const unsubscribe = effect(() => {
if (settings.value !== undefined) {
listener(settings.value);
}
});
unsubscribe();
await setSettings(mockSettings);
expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith(testDefaultSettings);
const retrieved = getSettings();
expect(retrieved).to.deep.equal(mockSettings);
});
it('clears listeners and settings', async () => {
await initSettings(async () => {}, saveData);
const listener = vi.fn();
const unsubscribe = effect(() => {
listener(settings.value);
});
await setSettings(mockSettings);
expect(listener).toHaveBeenCalledTimes(2);
expect(listener).toHaveBeenCalledWith(mockSettings);
clearSettings();
expect(() => getSettings()).toThrow();
expect(listener).toHaveBeenCalledTimes(3);
expect(listener).toHaveBeenCalledWith(undefined);
unsubscribe();
});
});