fix(app): harden account and workflow state

This commit is contained in:
cesnimda
2026-08-24 20:21:09 +02:00
parent e7cacad7d6
commit dca5daa1a2
32 changed files with 811 additions and 86 deletions
@@ -70,10 +70,18 @@ function buildJob(overrides: Partial<JobApplication>): JobApplication {
}
function setupApiMocks({ reminders, jobs }: { reminders?: JobApplication[]; jobs?: JobApplication[] }) {
mockedApi.get.mockImplementation((url: string) => {
mockedApi.get.mockImplementation((url: string, config?: any) => {
if (url === '/companies') return Promise.resolve({ data: [{ id: 1, name: 'Acme' }, { id: 2, name: 'Beta' }] } as any);
if (url === '/jobapplications/reminders') return Promise.resolve({ data: reminders ?? [] } as any);
if (url === '/jobapplications') return Promise.resolve({ data: { items: jobs ?? [], total: jobs?.length ?? 0, page: 1, pageSize: 15 } } as any);
if (url === '/jobapplications') {
const readiness = config?.params?.readiness;
const filtered = (jobs ?? []).filter((job) => readiness === 'interview'
? job.workflowSignal?.needsInterviewPrep
: readiness === 'needs-work'
? job.workflowSignal?.hasPackageGap || job.workflowSignal?.needsInterviewPrep
: true);
return Promise.resolve({ data: { items: filtered, total: filtered.length, page: 1, pageSize: 15 } } as any);
}
if (url === '/jobapplications/stats') return Promise.resolve({ data: { total: reminders?.length ?? 0, active: reminders?.length ?? 0, deleted: 0, byStatus: {}, appliedLast30Days: reminders?.length ?? 0, averageDaysSinceApplied: 7 } } as any);
if (url === '/jobapplications/analytics-overview') return Promise.resolve({ data: { funnel: [], responseRateBySource: [], topCompanies: [], totalResponses: 1, totalActive: reminders?.length ?? 0 } } as any);
if (url === '/jobapplications/analytics' || url === '/jobapplications/tags') return Promise.resolve({ data: [] } as any);
@@ -270,5 +278,8 @@ test('job table readiness filter follows workflow signals instead of raw notes o
fireEvent.click(await screen.findByRole('option', { name: /needs work/i }));
expect(await screen.findByText(/application engineer/i)).toBeInTheDocument();
expect(screen.queryByText(/operations analyst/i)).not.toBeInTheDocument();
await waitFor(() => expect(screen.queryByText(/operations analyst/i)).not.toBeInTheDocument());
expect(mockedApi.get).toHaveBeenCalledWith('/jobapplications', expect.objectContaining({
params: expect.objectContaining({ readiness: 'needs-work' }),
}));
});