Files
relicario/extension/src/popup/components/__tests__/field-history.test.ts
adlee-was-taken ce59223fc0 feat(ext): shared state host — decouple components from popup.ts
Introduce shared/state.ts as a service-locator so popup components
(item-detail, item-form, trash, devices, settings, etc.) work in both
the popup and vault tab bundles. Both entry points register themselves
as the host; components import from shared/state instead of popup.ts.
Vault.ts now delegates to the real popup components, removing ~300 lines
of placeholder renderers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-27 16:38:06 -04:00

73 lines
1.9 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest';
import { renderFieldHistory, teardown } from '../field-history';
// Mock popup module
vi.mock('../../../shared/state', () => ({
getState: vi.fn(() => ({
historyItemId: 'item123',
selectedItem: { id: 'item123', title: 'Test Item', modified: 1000 },
})),
setState: vi.fn(),
sendMessage: vi.fn(),
navigate: vi.fn(),
escapeHtml: (s: string) => s,
popOutToTab: vi.fn(),
isInTab: vi.fn(() => false),
openVaultTab: vi.fn(),
}));
import { sendMessage, navigate } from '../../../shared/state';
describe('field-history view', () => {
let app: HTMLElement;
beforeEach(() => {
app = document.createElement('div');
teardown();
vi.clearAllMocks();
});
it('renders empty state when no history', async () => {
(sendMessage as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
ok: true,
data: { history: [] },
});
await renderFieldHistory(app);
expect(app.innerHTML).toContain('No history available');
});
it('renders history entries masked by default', async () => {
(sendMessage as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
ok: true,
data: {
history: [{
field_id: 'f1',
field_name: 'password',
current_value: 'secret123',
entries: [{ value: 'oldpass', changed_at: 500 }],
}],
},
});
await renderFieldHistory(app);
expect(app.innerHTML).toContain('••••••••••••');
expect(app.innerHTML).not.toContain('secret123');
expect(app.innerHTML).toContain('current');
});
it('back button navigates to detail', async () => {
(sendMessage as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
ok: true,
data: { history: [] },
});
await renderFieldHistory(app);
app.querySelector<HTMLButtonElement>('#back-btn')?.click();
expect(navigate).toHaveBeenCalledWith('detail');
});
});