93 lines
2.3 KiB
TypeScript
93 lines
2.3 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import {
|
|
registerHost,
|
|
__resetHostForTests,
|
|
getState,
|
|
setState,
|
|
navigate,
|
|
sendMessage,
|
|
} from '../state';
|
|
import type { StateHost } from '../state';
|
|
import type { PopupState } from '../popup-state';
|
|
|
|
function makeHost(initial?: Partial<PopupState>): StateHost {
|
|
let state: PopupState = {
|
|
view: 'list',
|
|
entries: [],
|
|
selectedId: null,
|
|
selectedItem: null,
|
|
selectedIndex: 0,
|
|
searchQuery: '',
|
|
activeGroup: null,
|
|
error: null,
|
|
loading: false,
|
|
capturedTabId: null,
|
|
capturedUrl: '',
|
|
newType: null,
|
|
vaultSettings: null,
|
|
generatorDefaults: null,
|
|
historyItemId: null,
|
|
...initial,
|
|
};
|
|
|
|
return {
|
|
getState: () => state,
|
|
setState: (partial) => { state = { ...state, ...partial }; },
|
|
navigate: vi.fn(),
|
|
sendMessage: vi.fn().mockResolvedValue({ ok: true }),
|
|
escapeHtml: (s) => s,
|
|
popOutToTab: vi.fn(),
|
|
isInTab: () => false,
|
|
openVaultTab: vi.fn(),
|
|
};
|
|
}
|
|
|
|
describe('shared/state', () => {
|
|
beforeEach(() => {
|
|
__resetHostForTests();
|
|
});
|
|
|
|
it('register-then-getState round-trips', () => {
|
|
const host = makeHost({ view: 'detail' });
|
|
registerHost(host);
|
|
expect(getState().view).toBe('detail');
|
|
});
|
|
|
|
it('double-register throws', () => {
|
|
registerHost(makeHost());
|
|
expect(() => registerHost(makeHost())).toThrow(/already registered/);
|
|
});
|
|
|
|
it('__resetHostForTests clears the singleton', () => {
|
|
registerHost(makeHost());
|
|
__resetHostForTests();
|
|
expect(() => getState()).toThrow(/No state host/);
|
|
});
|
|
|
|
it('getState without host throws', () => {
|
|
expect(() => getState()).toThrow(/No state host/);
|
|
});
|
|
|
|
it('setState merges partial state', () => {
|
|
const host = makeHost();
|
|
registerHost(host);
|
|
setState({ loading: true });
|
|
expect(getState().loading).toBe(true);
|
|
});
|
|
|
|
it('navigate delegates to host', () => {
|
|
const host = makeHost();
|
|
registerHost(host);
|
|
navigate('settings');
|
|
expect(host.navigate).toHaveBeenCalledWith('settings', undefined);
|
|
});
|
|
|
|
it('sendMessage delegates to host', async () => {
|
|
const host = makeHost();
|
|
registerHost(host);
|
|
const resp = await sendMessage({ type: 'is_unlocked' });
|
|
expect(host.sendMessage).toHaveBeenCalledWith({ type: 'is_unlocked' });
|
|
expect(resp).toEqual({ ok: true });
|
|
});
|
|
});
|