Files
relicario/extension/src/popup/components/__tests__/trash.test.ts

72 lines
2.0 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest';
import { renderTrash } from '../trash';
// Mock popup module
vi.mock('../../../shared/state', () => ({
getState: vi.fn(() => ({
vaultSettings: { trash_retention: { kind: 'days', value: 30 } },
})),
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('trash view', () => {
let app: HTMLElement;
beforeEach(() => {
document.body.innerHTML = '<div id="app"></div>';
app = document.getElementById('app')!;
vi.clearAllMocks();
});
it('renders empty state when no trashed items', async () => {
(sendMessage as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
ok: true,
data: { items: [] },
});
await renderTrash(app);
expect(app.innerHTML).toContain('Trash is empty');
expect(app.querySelector('#empty-trash-btn')).toBeNull();
});
it('renders trashed items with restore buttons', async () => {
const now = Math.floor(Date.now() / 1000);
(sendMessage as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
ok: true,
data: {
items: [
['id1', { id: 'id1', type: 'login', title: 'Test Login', trashed_at: now - 3600, tags: [], favorite: false, modified: now, attachment_summaries: [] }],
],
},
});
await renderTrash(app);
expect(app.innerHTML).toContain('Test Login');
expect(app.querySelector('[data-restore]')).not.toBeNull();
expect(app.innerHTML).toContain('purges in');
expect(app.querySelector('#empty-trash-btn')).not.toBeNull();
});
it('back button navigates to list', async () => {
(sendMessage as ReturnType<typeof vi.fn>).mockResolvedValueOnce({
ok: true,
data: { items: [] },
});
await renderTrash(app);
app.querySelector<HTMLButtonElement>('#back-btn')?.click();
expect(navigate).toHaveBeenCalledWith('list');
});
});