feat(email): add safe message detail
CI and Deploy / test (pull_request) Failing after 1m29s
CI and Deploy / deploy (pull_request) Has been skipped

This commit is contained in:
cesnimda
2026-08-09 21:44:24 +02:00
parent 6f0e9bb516
commit a20775c24a
6 changed files with 262 additions and 23 deletions
@@ -53,12 +53,18 @@ describe('CorrespondenceInboxPage', () => {
date: new Date().toISOString(),
contentPreview: 'We would like to schedule an interview.',
externalThreadId: 'thread-1',
externalMessageId: 'message-1',
provider: 'gmail',
externalFrom: 'Maria Recruiter <maria@acme.test>',
externalTo: 'user@example.test',
labelCount: 2,
attachmentCount: 1,
},
] } as any);
if (url === '/email/message') return Promise.resolve({ data: {
id: 'message-1', threadId: 'thread-1', subject: 'Interview invite', from: 'Maria Recruiter <maria@acme.test>', to: 'user@example.test',
date: new Date().toISOString(), snippet: 'Interview', bodyText: 'Please choose an interview time.', labels: ['INBOX'], attachments: [{ fileName: 'agenda.pdf' }],
} } as any);
if (url === '/gmail/review-candidates') return Promise.resolve({ data: {
queries: [], candidateThreadCount: 0, autoLinkThreadCount: 0, reviewThreadCount: 0, unmatchedThreadCount: 0, threads: [],
} } as any);
@@ -97,6 +103,38 @@ describe('CorrespondenceInboxPage', () => {
});
});
test('opens provider-backed plain-text message detail in the hub', async () => {
renderPage();
fireEvent.click(await screen.findByRole('button', { name: /view message/i }));
expect(await screen.findByText(/please choose an interview time/i)).toBeInTheDocument();
expect(screen.getByText('INBOX')).toBeInTheDocument();
expect(screen.getByText('agenda.pdf')).toBeInTheDocument();
expect(mockedApi.get).toHaveBeenCalledWith('/email/message', {
params: { provider: 'gmail', messageId: 'message-1' },
});
});
test('falls back to the saved copy when provider detail is unavailable', async () => {
const original = mockedApi.get.getMockImplementation();
mockedApi.get.mockImplementation((url: string, config?: any) => {
if (url === '/email/message') return Promise.reject(new Error('reauthorization required'));
if (url === '/correspondence/message/1') return Promise.resolve({ data: {
id: 'message-1', threadId: 'thread-1', subject: 'Interview invite', from: 'Maria Recruiter', to: 'user@example.test',
date: new Date().toISOString(), snippet: 'Saved', bodyText: 'Saved interview message.', labels: [], attachments: [],
} } as any);
return original!(url, config);
});
renderPage();
fireEvent.click(await screen.findByRole('button', { name: /view message/i }));
expect(await screen.findByText(/showing the saved jobtracker copy/i)).toBeInTheDocument();
expect(await screen.findByText(/saved interview message/i)).toBeInTheDocument();
expect(mockedApi.get).toHaveBeenCalledWith('/correspondence/message/1');
});
test('uses one hub for linked messages and recruitment suggestions', async () => {
renderPage();