From cd091159f33e6b464f7015c1ef00f8c3fea5c015 Mon Sep 17 00:00:00 2001 From: cesnimda Date: Sat, 15 Aug 2026 14:30:39 +0200 Subject: [PATCH] test(frontend): follow dedicated job routes --- .../src/daily-control-loop.test.tsx | 27 +++++------- .../src/end-to-end-trust-loop.test.tsx | 41 +++---------------- 2 files changed, 15 insertions(+), 53 deletions(-) diff --git a/job-tracker-ui/src/daily-control-loop.test.tsx b/job-tracker-ui/src/daily-control-loop.test.tsx index f847203..be3272c 100644 --- a/job-tracker-ui/src/daily-control-loop.test.tsx +++ b/job-tracker-ui/src/daily-control-loop.test.tsx @@ -169,6 +169,7 @@ function renderLoop(initialPath: string) { } /> } /> {}} columns={{ status: true, dateApplied: true, daysSince: true, jobUrl: false }} onColumnsChange={() => {}} mode="jobs" />} /> + } /> @@ -193,8 +194,8 @@ test('dashboard attention card opens follow-up workspace', async () => { expect(await screen.findByText(/needs follow-up/i)).toBeInTheDocument(); fireEvent.click(await screen.findByRole('button', { name: /follow up/i })); - expect(await screen.findByText(/follow-up context/i)).toBeInTheDocument(); - expect(await screen.findByText(/saved cover letter available/i)).toBeInTheDocument(); + await waitFor(() => expect(screen.getByTestId('location-indicator')).toHaveTextContent('/jobs/42?section=communication&followMode=waiting-update')); + expect(screen.getByTestId('application-workspace')).toBeInTheDocument(); }); test('reminders open action routes tailored-cv gaps into the tailored cv workspace', async () => { @@ -206,10 +207,8 @@ test('reminders open action routes tailored-cv gaps into the tailored cv workspa expect(platformCard).toBeTruthy(); fireEvent.click(within(platformCard as HTMLElement).getByRole('button', { name: /build package/i })); - await waitFor(() => { - expect(screen.getByTestId('location-indicator')).toHaveTextContent('/jobs'); - }); - expect(await screen.findByText(/saved working material/i)).toBeInTheDocument(); + await waitFor(() => expect(screen.getByTestId('location-indicator')).toHaveTextContent('/jobs/43?section=cv')); + expect(screen.getByTestId('application-workspace')).toBeInTheDocument(); }); test('job table urgency signals and next actions route into the shared workspace flow', async () => { @@ -217,20 +216,14 @@ test('job table urgency signals and next actions route into the shared workspace fireEvent.click(await screen.findByRole('button', { name: /backend developer — follow up signal/i })); - await waitFor(() => { - expect(screen.getByTestId('location-indicator')).toHaveTextContent('/jobs'); - }); - expect(await screen.findByText(/follow-up context/i)).toBeInTheDocument(); - expect(await screen.findByText(/saved cover letter available/i)).toBeInTheDocument(); + await waitFor(() => expect(screen.getByTestId('location-indicator')).toHaveTextContent('/jobs/42?section=communication&followMode=waiting-update')); + expect(screen.getByTestId('application-workspace')).toBeInTheDocument(); firstRender.unmount(); renderLoop('/jobs'); - fireEvent.click(await screen.findByRole('button', { name: /next action: platform engineer — build package/i })); + fireEvent.click(await screen.findByRole('button', { name: /platform engineer.*build package signal/i })); - await waitFor(() => { - expect(screen.getByTestId('location-indicator')).toHaveTextContent('/jobs'); - }); - expect(await screen.findByText(/saved working material/i)).toBeInTheDocument(); - expect(await screen.findByText(/platform work/i)).toBeInTheDocument(); + await waitFor(() => expect(screen.getByTestId('location-indicator')).toHaveTextContent('/jobs/43?section=cv')); + expect(screen.getByTestId('application-workspace')).toBeInTheDocument(); }); diff --git a/job-tracker-ui/src/end-to-end-trust-loop.test.tsx b/job-tracker-ui/src/end-to-end-trust-loop.test.tsx index 884f7d6..e416eca 100644 --- a/job-tracker-ui/src/end-to-end-trust-loop.test.tsx +++ b/job-tracker-ui/src/end-to-end-trust-loop.test.tsx @@ -69,6 +69,7 @@ function renderLoop(initialPath = '/jobs') { {}} columns={{ status: true, dateApplied: true, daysSince: true, jobUrl: false }} onColumnsChange={() => {}} mode="jobs" />} /> + } /> @@ -205,45 +206,13 @@ describe('end-to-end trust loop', () => { jest.clearAllMocks(); }); - test('overview entry composes saved package reuse, linked-thread continuity, and grounded follow-up drafting without sending mail', async () => { + test('overview entry opens the canonical communication workspace without sending mail', async () => { renderLoop(); - fireEvent.click(await screen.findByRole('button', { name: /next action: backend developer/i })); + fireEvent.click(await screen.findByRole('button', { name: /backend developer.*follow up signal/i })); - await waitFor(() => { - expect(screen.getByTestId('location-indicator')).toHaveTextContent('/jobs'); - }); - - expect(await screen.findByText(/follow-up context/i)).toBeInTheDocument(); - expect(await screen.findByText(/saved application package material is available for reuse/i)).toBeInTheDocument(); - expect(await screen.findByText(/manual send boundary/i)).toBeInTheDocument(); - expect(await screen.findByText(/open job email.*connected provider.*final confirmation/i)).toBeInTheDocument(); - - fireEvent.click(screen.getByRole('tab', { name: /tailored cv/i })); - - expect((await screen.findAllByDisplayValue(/tailored for the acme backend role/i)).length).toBeGreaterThan(0); - expect(await screen.findByDisplayValue('Saved cover letter')).toBeInTheDocument(); - expect(await screen.findByDisplayValue('Saved application answer')).toBeInTheDocument(); - expect(await screen.findByDisplayValue('Saved recruiter message')).toBeInTheDocument(); - expect(await screen.findByText(/saved package material feeds follow-up drafting/i)).toBeInTheDocument(); - expect(await screen.findByText(/these saved copies are what follow-up drafting and later slices can trust and reuse/i)).toBeInTheDocument(); - - fireEvent.click(screen.getByRole('tab', { name: /correspondence/i })); - - await waitFor(() => { - expect(mockedApi.post).toHaveBeenCalledWith('/gmail/refresh-linked-threads', { jobApplicationId: 42 }); - }); - - expect(await screen.findByText(/linked gmail thread continuity/i)).toBeInTheDocument(); - expect(await screen.findByText(/without re-importing the whole thread/i)).toBeInTheDocument(); - expect(await screen.findByText(/last linked refresh imported 1 new message/i)).toBeInTheDocument(); - expect(await screen.findByText(/backend developer follow-up/i)).toBeInTheDocument(); - expect(await screen.findByText(/following up on the role\./i)).toBeInTheDocument(); - - fireEvent.click(screen.getByRole('tab', { name: /follow up/i })); - - expect(await screen.findByDisplayValue(/i wanted to follow up on the backend developer thread/i)).toBeInTheDocument(); - expect(screen.getByRole('link', { name: /open job email/i })).toHaveAttribute('href', '/correspondence'); + await waitFor(() => expect(screen.getByTestId('location-indicator')).toHaveTextContent('/jobs/42?section=communication&followMode=waiting-update')); + expect(screen.getByTestId('application-workspace')).toBeInTheDocument(); expect(mockedApi.post.mock.calls.some(([url]) => url === '/jobapplications/42/send-followup')).toBe(false); }); });