Files
jobtrackingapp/job-tracker-ui/src/cv-import-mapping.test.tsx
T

64 lines
4.9 KiB
TypeScript

import React, { useState } from 'react';
import '@testing-library/jest-dom';
import { fireEvent, render, screen, within } from '@testing-library/react';
import { I18nProvider } from './i18n/I18nProvider';
import CvImportMappingEditor, { type MappingDraft } from './views/career/CvImportMappingEditor';
let latest: MappingDraft[] = [];
function Harness() {
const [drafts, setDrafts] = useState<MappingDraft[]>([]);
return <I18nProvider><CvImportMappingEditor drafts={drafts} onChange={value => { latest = value; setDrafts(value); }} disabled={false}
categories={[{ category: 'jobs', fields: [{ name: 'title', multiple: false }, { name: 'company', multiple: false }, { name: 'bullets', multiple: true }] }]}
targets={[{ category: 'jobs', index: 0, label: 'Saved job', values: { title: 'Old title', company: 'Old company' } }]}
blocks={[{ id: 'b1', text: 'Engineer', kind: 'paragraph', page: 1 }, { id: 'b2', text: 'Example AS', kind: 'paragraph', page: 1 }]}
label={value => ({ jobs: 'Experience', title: 'Title', company: 'Company', bullets: 'Details' } as Record<string, string>)[value] ?? value} /></I18nProvider>;
}
beforeEach(() => { localStorage.clear(); latest = []; });
test('selecting source text fills an empty mapped value without approving or replacing a correction', () => {
render(<Harness />);
fireEvent.click(screen.getByRole('button', { name: 'Create missing record' }));
const record = screen.getByRole('group', { name: 'Mapped record 1' });
fireEvent.change(within(record).getByRole('combobox', { name: 'Source evidence 1' }), { target: { value: 'b1' } });
expect(within(record).getByRole('textbox', { name: 'Value 1' })).toHaveValue('Engineer');
expect(latest[0].confirmed).toBe(false);
fireEvent.change(within(record).getByRole('textbox', { name: 'Value 1' }), { target: { value: 'My correction' } });
fireEvent.change(within(record).getByRole('combobox', { name: 'Source evidence 1' }), { target: { value: 'b2' } });
expect(within(record).getByRole('textbox', { name: 'Value 1' })).toHaveValue('My correction');
});
test('missing records require explicit source assignments and approval without a default existing target', () => {
render(<Harness />);
fireEvent.click(screen.getByRole('button', { name: 'Create missing record' }));
const record = screen.getByRole('group', { name: 'Mapped record 1' });
expect(within(record).getByRole('combobox', { name: 'Destination' })).toHaveValue('');
fireEvent.change(within(record).getByRole('textbox', { name: 'Value 1' }), { target: { value: 'Engineer' } });
fireEvent.change(within(record).getByRole('textbox', { name: 'Value 2' }), { target: { value: 'Example AS' } });
fireEvent.click(within(record).getByRole('button', { name: 'Approve mapped record' }));
expect(latest[0].confirmed).toBe(false);
expect(within(record).getByRole('alert')).toBeInTheDocument();
fireEvent.change(within(record).getByRole('combobox', { name: 'Source evidence 1' }), { target: { value: 'b1' } });
fireEvent.change(within(record).getByRole('combobox', { name: 'Source evidence 2' }), { target: { value: 'b2' } });
fireEvent.click(within(record).getByRole('button', { name: 'Approve mapped record' }));
expect(latest[0]).toMatchObject({ category: 'jobs', targetIndex: null, confirmed: true, fields: [{ name: 'title', value: 'Engineer', sourceBlockId: 'b1', corrected: false }, { name: 'company', value: 'Example AS', sourceBlockId: 'b2', corrected: false }] });
fireEvent.change(within(record).getByRole('combobox', { name: 'Destination' }), { target: { value: '0' } });
expect(latest[0]).toMatchObject({ targetIndex: 0, confirmed: false });
expect(within(record).getByText('Current: Old title')).toBeInTheDocument();
expect(within(record).getByText('Current: Old company')).toBeInTheDocument();
});
test('unsupported wording requires an explicit correction and edits reset record approval', () => {
render(<Harness />);
fireEvent.click(screen.getByRole('button', { name: 'Create missing record' }));
const record = screen.getByRole('group', { name: 'Mapped record 1' });
fireEvent.click(within(record).getByRole('button', { name: 'Remove field 2' }));
fireEvent.change(within(record).getByRole('textbox', { name: 'Value 1' }), { target: { value: 'Senior Engineer' } });
fireEvent.change(within(record).getByRole('combobox', { name: 'Source evidence 1' }), { target: { value: 'b1' } });
fireEvent.click(within(record).getByRole('button', { name: 'Approve mapped record' }));
expect(latest[0].confirmed).toBe(false);
fireEvent.click(within(record).getByRole('checkbox', { name: 'This value is my correction' }));
fireEvent.click(within(record).getByRole('button', { name: 'Approve mapped record' }));
expect(latest[0].confirmed).toBe(true);
fireEvent.change(within(record).getByRole('textbox', { name: 'Value 1' }), { target: { value: 'Engineer' } });
expect(latest[0].confirmed).toBe(false);
fireEvent.click(within(record).getByRole('button', { name: 'Remove mapped record' }));
expect(latest).toEqual([]);
});