Files
srbhr--resume-matcher/apps/frontend/tests/diff-preview-modal.test.tsx
T
wehub-resource-sync 5bdf4cc89a
Publish Docker Image / publish (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:39:36 +08:00

112 lines
3.3 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest';
import { fireEvent, render, screen } from '@testing-library/react';
import { DiffPreviewModal } from '@/components/tailor/diff-preview-modal';
import type {
ResumeDiffSummary,
ResumeFieldDiff,
} from '@/components/common/resume_previewer_context';
vi.mock('@/lib/i18n', () => ({
useTranslations: () => ({
t: (key: string) => key,
}),
}));
const diffSummary: ResumeDiffSummary = {
total_changes: 2,
skills_added: 1,
skills_removed: 0,
descriptions_modified: 1,
certifications_added: 0,
high_risk_changes: 1,
};
const detailedChanges: ResumeFieldDiff[] = [
{
field_path: 'summary',
field_type: 'summary',
change_type: 'modified',
original_value: 'old summary',
new_value: 'new summary',
confidence: 'medium',
},
{
field_path: 'additional.technicalSkills',
field_type: 'skill',
change_type: 'added',
new_value: 'Go',
confidence: 'high',
},
];
describe('DiffPreviewModal', () => {
it('renders fallback dialog when diff data is missing', () => {
const onClose = vi.fn();
const onConfirm = vi.fn();
render(<DiffPreviewModal isOpen onClose={onClose} onReject={vi.fn()} onConfirm={onConfirm} />);
expect(screen.getByText('tailor.missingDiffDialog.title')).toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: 'tailor.missingDiffDialog.confirmLabel' }));
expect(onConfirm).toHaveBeenCalledTimes(1);
});
it('shows warning banner and renders high-risk icon only for added high changes', () => {
render(
<DiffPreviewModal
isOpen
onClose={vi.fn()}
onReject={vi.fn()}
onConfirm={vi.fn()}
diffSummary={diffSummary}
detailedChanges={detailedChanges}
/>
);
expect(screen.getByText('tailor.diffModal.warningTitle', { exact: false })).toBeInTheDocument();
// Dialog uses createPortal to document.body, so the test's `container`
// wrapper does not contain the rendered dialog content. Query
// document.body directly to find the icons rendered inside the portal.
const alertIcons = document.body.querySelectorAll('.lucide-triangle-alert');
expect(alertIcons.length).toBe(2);
});
it('toggles section visibility on header click', () => {
render(
<DiffPreviewModal
isOpen
onClose={vi.fn()}
onReject={vi.fn()}
onConfirm={vi.fn()}
diffSummary={diffSummary}
detailedChanges={detailedChanges}
/>
);
expect(screen.getByText('new summary')).toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: /tailor\.diffModal\.summaryChanges/i }));
expect(screen.queryByText('new summary')).not.toBeInTheDocument();
});
it('fires confirm and reject handlers', () => {
const onConfirm = vi.fn();
const onReject = vi.fn();
render(
<DiffPreviewModal
isOpen
onClose={vi.fn()}
onReject={onReject}
onConfirm={onConfirm}
diffSummary={diffSummary}
detailedChanges={detailedChanges}
/>
);
fireEvent.click(screen.getByRole('button', { name: 'tailor.diffModal.confirmButton' }));
fireEvent.click(screen.getByRole('button', { name: 'tailor.diffModal.rejectButton' }));
expect(onConfirm).toHaveBeenCalledTimes(1);
expect(onReject).toHaveBeenCalledTimes(1);
});
});