test(geschichte): add 403, catch-path, and CSRF header coverage for StoryDocumentPanel (#795)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -210,6 +210,62 @@ describe('StoryDocumentPanel — add', () => {
|
||||
m.geschichte_documents_added_announce({ title: 'Brief von Eugenie' })
|
||||
);
|
||||
});
|
||||
|
||||
it('routes a 403 response through getErrorMessage on POST', async () => {
|
||||
stubFetch([makeSearchResultItem('d1', 'Brief von Eugenie')], {
|
||||
ok: false,
|
||||
status: 403,
|
||||
body: { code: 'FORBIDDEN' }
|
||||
});
|
||||
render(StoryDocumentPanel, defaultProps());
|
||||
|
||||
await addViaPicker(/Brief von Eugenie/i);
|
||||
|
||||
await expect.element(page.getByRole('alert')).toBeInTheDocument();
|
||||
const alertText = page.getByRole('alert').element().textContent ?? '';
|
||||
expect(alertText).not.toBe('');
|
||||
expect(alertText).not.toContain('FORBIDDEN');
|
||||
});
|
||||
|
||||
it('shows the generic reload message when POST throws a network error', async () => {
|
||||
stubFetch([makeSearchResultItem('d1', 'Brief von Eugenie')]);
|
||||
vi.stubGlobal(
|
||||
'fetch',
|
||||
vi.fn((input: RequestInfo | URL, init?: RequestInit) => {
|
||||
if ((init?.method ?? 'GET').toUpperCase() === 'GET') {
|
||||
return Promise.resolve({
|
||||
ok: true,
|
||||
json: () =>
|
||||
Promise.resolve({ items: [makeSearchResultItem('d1', 'Brief von Eugenie')] })
|
||||
});
|
||||
}
|
||||
return Promise.reject(new Error('Network error'));
|
||||
})
|
||||
);
|
||||
render(StoryDocumentPanel, defaultProps());
|
||||
|
||||
await addViaPicker(/Brief von Eugenie/i);
|
||||
|
||||
await expect
|
||||
.element(page.getByRole('alert'))
|
||||
.toHaveTextContent(m.journey_mutation_error_reload());
|
||||
});
|
||||
|
||||
it('attaches X-XSRF-TOKEN header from cookie on POST', async () => {
|
||||
document.cookie = 'XSRF-TOKEN=test-csrf-token';
|
||||
const fetchMock = stubFetch([makeSearchResultItem('d1', 'Brief von Eugenie')], {
|
||||
ok: true,
|
||||
body: makeItem('i1', 10, docSummary('d1', 'Brief von Eugenie'))
|
||||
});
|
||||
render(StoryDocumentPanel, defaultProps());
|
||||
|
||||
await addViaPicker(/Brief von Eugenie/i);
|
||||
|
||||
const post = fetchMock.mock.calls.find(([, init]) => init?.method === 'POST');
|
||||
const headers = post?.[1]?.headers as Headers;
|
||||
expect(headers.get('X-XSRF-TOKEN')).toBe('test-csrf-token');
|
||||
document.cookie = 'XSRF-TOKEN=; Max-Age=0';
|
||||
});
|
||||
});
|
||||
|
||||
describe('StoryDocumentPanel — remove', () => {
|
||||
@@ -348,4 +404,45 @@ describe('StoryDocumentPanel — remove', () => {
|
||||
m.geschichte_documents_remove_label({ title: 'Brief von Eugenie' })
|
||||
);
|
||||
});
|
||||
|
||||
it('shows the generic reload message when DELETE throws a network error', async () => {
|
||||
vi.stubGlobal(
|
||||
'fetch',
|
||||
vi.fn(() => Promise.reject(new Error('Network error')))
|
||||
);
|
||||
render(
|
||||
StoryDocumentPanel,
|
||||
defaultProps({ items: [makeItem('i1', 10, docSummary('d1', 'Brief von Eugenie'))] })
|
||||
);
|
||||
|
||||
await userEvent.click(
|
||||
page.getByRole('button', {
|
||||
name: m.geschichte_documents_remove_label({ title: 'Brief von Eugenie' })
|
||||
})
|
||||
);
|
||||
|
||||
await expect
|
||||
.element(page.getByRole('alert'))
|
||||
.toHaveTextContent(m.journey_mutation_error_reload());
|
||||
});
|
||||
|
||||
it('attaches X-XSRF-TOKEN header from cookie on DELETE', async () => {
|
||||
document.cookie = 'XSRF-TOKEN=test-csrf-token';
|
||||
const fetchMock = stubFetch([], { ok: true, body: {} });
|
||||
render(
|
||||
StoryDocumentPanel,
|
||||
defaultProps({ items: [makeItem('i1', 10, docSummary('d1', 'Brief von Eugenie'))] })
|
||||
);
|
||||
|
||||
await userEvent.click(
|
||||
page.getByRole('button', {
|
||||
name: m.geschichte_documents_remove_label({ title: 'Brief von Eugenie' })
|
||||
})
|
||||
);
|
||||
|
||||
const del = fetchMock.mock.calls.find(([, init]) => init?.method === 'DELETE');
|
||||
const headers = del?.[1]?.headers as Headers;
|
||||
expect(headers.get('X-XSRF-TOKEN')).toBe('test-csrf-token');
|
||||
document.cookie = 'XSRF-TOKEN=; Max-Age=0';
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user