fix(jobs): align table and board query contracts
This commit is contained in:
@@ -34,11 +34,11 @@ function job(id: number, jobTitle: string, status: string, overrides: Partial<Jo
|
||||
} as JobApplication;
|
||||
}
|
||||
|
||||
function renderBoard() {
|
||||
function renderBoard(entry = '/kanban?source=board') {
|
||||
return render(
|
||||
<ToastProvider>
|
||||
<I18nProvider>
|
||||
<MemoryRouter initialEntries={['/kanban?source=board']}>
|
||||
<MemoryRouter initialEntries={[entry]}>
|
||||
<Routes>
|
||||
<Route path="/kanban" element={<KanbanBoard />} />
|
||||
<Route path="/jobs/:id" element={<div role="main">Job workspace <RouteState /></div>} />
|
||||
@@ -201,8 +201,8 @@ test('full-board population keeps jobs beyond the table page and offers a separa
|
||||
renderBoard();
|
||||
expect(await screen.findByText('Role 26')).toBeVisible();
|
||||
expect(screen.getAllByRole('button', { name: /Press Space to pick up/ })).toHaveLength(27);
|
||||
expect(mockedApi.get).toHaveBeenCalledWith('/jobapplications/board');
|
||||
expect(screen.getByRole('link', { name: /Job Applications/ })).toHaveAttribute('href', '/jobs');
|
||||
expect(mockedApi.get).toHaveBeenCalledWith('/jobapplications/board', expect.objectContaining({ params: expect.objectContaining({ includeDeleted: false }) }));
|
||||
expect(screen.getByRole('link', { name: /Job Applications/ })).toHaveAttribute('href', '/jobs?source=board');
|
||||
});
|
||||
|
||||
test('keyboard Escape cancels movement without a write and successful movement restores card focus', async () => {
|
||||
@@ -238,3 +238,39 @@ test('keyboard activation of the exact-status menu does not open the job', async
|
||||
expect(await screen.findByRole('menu')).toBeVisible();
|
||||
expect(screen.queryByText('Job workspace')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('Board sends the shared logical URL query, excluding Table paging and client ownership fields', async () => {
|
||||
mockedApi.get.mockResolvedValue({ data: [] } as any);
|
||||
renderBoard('/kanban?q=Board&status=Custom%20review&companyId=7&location=Troms%C3%B8&needsFollowUp=1&readiness=interview&includeDeleted=1&sortBy=jobTitle&sortDir=asc&page=3&pageSize=999&userId=other');
|
||||
await screen.findByRole('group', { name: 'Not Applied column' });
|
||||
expect(mockedApi.get).toHaveBeenCalledWith('/jobapplications/board', { params: {
|
||||
q: 'Board', status: 'Custom review', companyId: 7, location: 'Tromsø', needsFollowUp: true,
|
||||
readiness: 'interview', includeDeleted: true, sortBy: 'jobTitle', sortDir: 'asc',
|
||||
} });
|
||||
expect(screen.getByRole('link', { name: /Job Applications/ })).toHaveAttribute('href', expect.stringContaining('q=Board&status=Custom%20review'));
|
||||
});
|
||||
|
||||
test('a successful filtered move reloads membership and focuses the board when the job leaves it', async () => {
|
||||
mockedApi.get.mockResolvedValueOnce({ data: [job(11, 'Filtered Role', 'Saved')] } as any)
|
||||
.mockResolvedValueOnce({ data: [] } as any);
|
||||
renderBoard('/kanban?status=Saved');
|
||||
fireEvent.keyDown(await screen.findByRole('button', { name: /^Filtered Role/ }), { key: ' ' });
|
||||
fireEvent.keyDown(screen.getByRole('group', { name: 'Active column' }), { key: 'Enter' });
|
||||
await waitFor(() => expect(mockedApi.get).toHaveBeenCalledTimes(2));
|
||||
await waitFor(() => expect(screen.queryByText('Filtered Role')).not.toBeInTheDocument());
|
||||
await waitFor(() => expect(screen.getByRole('group', { name: 'Not Applied column' })).toHaveFocus());
|
||||
expect(mockedApi.get).toHaveBeenLastCalledWith('/jobapplications/board', { params: expect.objectContaining({ status: 'Saved' }) });
|
||||
});
|
||||
|
||||
test('a committed move followed by a failed query hides stale membership until retry succeeds', async () => {
|
||||
mockedApi.get.mockResolvedValueOnce({ data: [job(11, 'Filtered Role', 'Saved')] } as any)
|
||||
.mockRejectedValueOnce(new Error('read failed')).mockResolvedValueOnce({ data: [] } as any);
|
||||
renderBoard('/kanban?status=Saved');
|
||||
fireEvent.click(await screen.findByRole('button', { name: 'Quick status: Filtered Role' }));
|
||||
fireEvent.click(await screen.findByRole('menuitem', { name: 'Set Applied' }));
|
||||
expect(await screen.findByText('Unable to load the kanban board')).toBeVisible();
|
||||
expect(screen.queryByText('Filtered Role')).not.toBeInTheDocument();
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Retry' }));
|
||||
expect(await screen.findByRole('group', { name: 'Not Applied column' })).toBeVisible();
|
||||
expect(mockedApi.patch).toHaveBeenCalledTimes(1); // retry only the read, never replay the write
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user