Skip to content

Commit ef781da

Browse files
committed
skip validation errors notification handling
1 parent 86e5fe2 commit ef781da

3 files changed

Lines changed: 66 additions & 71 deletions

File tree

src/list/ListGuesser.spec.tsx

Lines changed: 0 additions & 61 deletions
This file was deleted.

src/useOnSubmit.test.tsx

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@ import * as React from 'react';
22
import { jest } from '@jest/globals';
33
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
44
import { render, waitFor } from '@testing-library/react';
5-
import type { CreateResult, RaRecord, UpdateResult } from 'react-admin';
6-
import { DataProviderContext, testDataProvider } from 'react-admin';
5+
import {
6+
type CreateResult,
7+
DataProviderContext,
8+
type RaRecord,
9+
type UpdateResult,
10+
testDataProvider,
11+
} from 'react-admin';
712
import { MemoryRouter, Route, Routes } from 'react-router-dom';
813

914
import useOnSubmit from './useOnSubmit.js';
@@ -23,6 +28,16 @@ const onSubmitProps = {
2328
};
2429

2530
jest.mock('./getIdentifierValue.js');
31+
const notify = jest.fn();
32+
const reactAdminActual = jest.requireActual('react-admin') as Record<
33+
string,
34+
unknown
35+
>;
36+
jest.mock('react-admin', () => ({
37+
__esModule: true,
38+
...reactAdminActual,
39+
useNotify: () => notify,
40+
}));
2641

2742
test.each([
2843
{
@@ -125,3 +140,44 @@ test.each([
125140
});
126141
});
127142
});
143+
144+
test('skip validation errors notification handling', async () => {
145+
notify.mockClear();
146+
const validationError = { name: 'Book name is required' };
147+
dataProvider.create = jest.fn(() => Promise.reject(new Error('Validation')));
148+
149+
let save;
150+
const Dummy = () => {
151+
const onSubmit = useOnSubmit({
152+
...onSubmitProps,
153+
schemaAnalyzer: {
154+
...onSubmitProps.schemaAnalyzer,
155+
getSubmissionErrors: () => validationError,
156+
},
157+
});
158+
save = onSubmit;
159+
return <span />;
160+
};
161+
162+
render(
163+
<DataProviderContext.Provider value={dataProvider}>
164+
<QueryClientProvider client={new QueryClient()}>
165+
<MemoryRouter initialEntries={['/books/create']}>
166+
<Routes>
167+
<Route path="/books/create" element={<Dummy />} />
168+
</Routes>
169+
</MemoryRouter>
170+
</QueryClientProvider>
171+
</DataProviderContext.Provider>,
172+
);
173+
174+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
175+
// @ts-ignore
176+
const errors = await save({ author: 'Author 1' });
177+
178+
await waitFor(() => {
179+
expect(dataProvider.create).toHaveBeenCalled();
180+
});
181+
expect(notify).not.toHaveBeenCalled();
182+
expect(errors).toEqual(validationError);
183+
});

src/useOnSubmit.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,14 @@ const useOnSubmit = ({
9292
const failure =
9393
mutationOptions?.onError ??
9494
((error: string | Error) => {
95-
let message = 'ra.notification.http_error';
96-
if (!submissionErrors) {
97-
message =
98-
typeof error === 'string' ? error : error.message || message;
95+
// Notification will be handled by the useNotifyIsFormInvalid hook.
96+
if (submissionErrors) {
97+
return;
9998
}
99+
const message =
100+
typeof error === 'string'
101+
? error
102+
: error.message || 'ra.notification.http_error';
100103
let errorMessage;
101104
if (typeof error === 'string') {
102105
errorMessage = error;
@@ -116,10 +119,7 @@ const useOnSubmit = ({
116119
},
117120
{},
118121
);
119-
if (submissionErrors) {
120-
return submissionErrors;
121-
}
122-
return {};
122+
return submissionErrors ?? {};
123123
}
124124
},
125125
[

0 commit comments

Comments
 (0)