Files
relicario/extension/src/popup/components/__tests__/field-history.test.ts

81 lines
2.4 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 with section-header and glyph buttons', 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);
// Masked by default
expect(app.innerHTML).toContain('••••••••••••');
expect(app.innerHTML).not.toContain('secret123');
// Section-header per field with uppercase name + entry count
expect(app.innerHTML).toContain('section-header');
expect(app.innerHTML).toContain('PASSWORD · 2 entries');
// Current entry annotation
expect(app.innerHTML).toContain('current · ');
// Explicit glyph buttons (reveal + copy) on each entry
expect(app.querySelectorAll('[data-entry-reveal]').length).toBe(2);
expect(app.querySelectorAll('[data-entry-copy]').length).toBe(2);
});
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');
});
});