refactor(cv): use app-owned confirmations
CI and Deploy / test (pull_request) Failing after 4m43s
CI and Deploy / deploy (pull_request) Has been skipped

This commit is contained in:
cesnimda
2026-08-15 13:16:00 +02:00
parent 15e5464da7
commit 0dfaac18a1
2 changed files with 59 additions and 21 deletions
@@ -1,6 +1,6 @@
import React from 'react';
import '@testing-library/jest-dom';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { fireEvent, render, screen, waitFor, within } from '@testing-library/react';
import { createMemoryRouter, RouterProvider } from 'react-router-dom';
import CvBuilderEditor from './views/CvBuilderEditor';
@@ -8,6 +8,8 @@ import { I18nProvider } from './i18n/I18nProvider';
import { ToastProvider } from './toast';
import { api } from './api';
import { emptyCvVariantSettings } from './cvBuilder';
import { ConfirmProvider } from './confirm';
import { PromptProvider } from './prompt';
// The Application Workspace CV section deep-links straight into the builder at
// /career/builder/:id. These tests cover that entry point: the variant loads, and a variant the
@@ -44,7 +46,11 @@ function renderAt(id: number) {
return render(
<I18nProvider>
<ToastProvider>
<RouterProvider router={router} />
<ConfirmProvider>
<PromptProvider>
<RouterProvider router={router} />
</PromptProvider>
</ConfirmProvider>
</ToastProvider>
</I18nProvider>,
);
@@ -124,20 +130,20 @@ test('failed autosave is visible and can be retried with the latest data', async
test('internal navigation warns and can be cancelled before discarding a pending edit', async () => {
routeGet(() => Promise.resolve({ data: variant } as any));
const confirm = jest.spyOn(window, 'confirm').mockReturnValue(false);
renderAt(3);
fireEvent.change(await screen.findByLabelText('Headline override'), { target: { value: 'Unsaved headline' } });
fireEvent.click(screen.getByRole('button', { name: 'Back to CVs' }));
expect(confirm).toHaveBeenCalledWith('This CV has unsaved changes. Leave and discard them?');
const dialog = await screen.findByRole('dialog', { name: 'Discard unsaved CV changes?' });
expect(within(dialog).getByText('This CV has unsaved changes. Leave and discard them?')).toBeInTheDocument();
fireEvent.click(within(dialog).getByRole('button', { name: 'Cancel' }));
await waitFor(() => expect(screen.queryByRole('dialog')).not.toBeInTheDocument());
expect(screen.getByDisplayValue('Backend CV')).toBeInTheDocument();
confirm.mockRestore();
});
test('custom entries can be added, edited, reordered and deleted with confirmation', async () => {
routeGet(() => Promise.resolve({ data: variant } as any));
mockedApi.put.mockResolvedValue({ data: variant } as any);
const confirm = jest.spyOn(window, 'confirm');
renderAt(3);
await screen.findByLabelText('Headline override');
@@ -152,11 +158,16 @@ test('custom entries can be added, edited, reordered and deleted with confirmati
expect(screen.getByLabelText('Entry 1')).toHaveValue('Second project');
expect(screen.getByLabelText('Entry 2')).toHaveValue('First project');
confirm.mockReturnValueOnce(false).mockReturnValueOnce(true);
fireEvent.click(screen.getByRole('button', { name: 'Delete custom entry 1' }));
let dialog = await screen.findByRole('dialog', { name: 'Delete custom entry' });
fireEvent.click(within(dialog).getByRole('button', { name: 'Cancel' }));
await waitFor(() => expect(screen.queryByRole('dialog')).not.toBeInTheDocument());
expect(screen.getAllByLabelText(/^Entry /)).toHaveLength(2);
fireEvent.click(screen.getByRole('button', { name: 'Delete custom entry 1' }));
expect(screen.getAllByLabelText(/^Entry /)).toHaveLength(1);
dialog = await screen.findByRole('dialog', { name: 'Delete custom entry' });
fireEvent.click(within(dialog).getByRole('button', { name: 'Delete entry' }));
await waitFor(() => expect(screen.getAllByLabelText(/^Entry /)).toHaveLength(1));
await waitFor(() => expect(screen.queryByRole('dialog')).not.toBeInTheDocument());
fireEvent.click(screen.getByRole('button', { name: 'Save now' }));
expect(await screen.findByText('Saved')).toBeInTheDocument();
@@ -166,12 +177,15 @@ test('custom entries can be added, edited, reordered and deleted with confirmati
}),
}));
confirm.mockReturnValueOnce(false).mockReturnValueOnce(true);
fireEvent.click(screen.getByRole('button', { name: 'Remove custom section' }));
dialog = await screen.findByRole('dialog', { name: 'Delete custom section' });
fireEvent.click(within(dialog).getByRole('button', { name: 'Cancel' }));
await waitFor(() => expect(screen.queryByRole('dialog')).not.toBeInTheDocument());
expect(screen.getByLabelText('Custom section title')).toBeInTheDocument();
fireEvent.click(screen.getByRole('button', { name: 'Remove custom section' }));
expect(screen.queryByLabelText('Custom section title')).not.toBeInTheDocument();
confirm.mockRestore();
dialog = await screen.findByRole('dialog', { name: 'Delete custom section' });
fireEvent.click(within(dialog).getByRole('button', { name: 'Delete section' }));
await waitFor(() => expect(screen.queryByLabelText('Custom section title')).not.toBeInTheDocument());
});
test('profile-backed sections expand, reorder, hide and persist variant-only overrides', async () => {