Skip to content

Commit 70c5cf7

Browse files
authored
Merge pull request #6319 from marmelab/fix-use-get-many-loaded-state
Fix useGetMany loaded state
2 parents 5d88add + 43e3aca commit 70c5cf7

File tree

6 files changed

+51
-32
lines changed

6 files changed

+51
-32
lines changed

packages/ra-core/src/controller/input/ReferenceArrayInputController.spec.tsx

+28-9
Original file line numberDiff line numberDiff line change
@@ -190,14 +190,17 @@ describe('<ReferenceArrayInputController />', () => {
190190
expect(queryByText('ra.input.references.all_missing')).toBeNull();
191191
});
192192

193-
it('should set warning if references fetch fails but selected references are not empty', () => {
193+
it('should set warning if references fetch fails but selected references are not empty', async () => {
194194
const children = jest.fn(({ warning }) => <div>{warning}</div>);
195195
const { queryByText } = renderWithRedux(
196196
<Form
197197
onSubmit={jest.fn()}
198198
render={() => (
199199
<ReferenceArrayInputController
200200
{...defaultProps}
201+
// Avoid global collision in useGetMany with queriesToCall
202+
basePath="/articles"
203+
resource="articles"
201204
input={{ value: [1, 2] }}
202205
>
203206
{children}
@@ -220,23 +223,30 @@ describe('<ReferenceArrayInputController />', () => {
220223
},
221224
references: {
222225
possibleValues: {
223-
'posts@tag_ids': { error: 'boom' },
226+
'articles@tag_ids': { error: 'boom' },
224227
},
225228
},
226229
},
227230
}
228231
);
229-
expect(queryByText('ra.input.references.many_missing')).not.toBeNull();
232+
await waitFor(() => {
233+
expect(
234+
queryByText('ra.input.references.many_missing')
235+
).not.toBeNull();
236+
});
230237
});
231238

232-
it('should set warning if references were found but selected references are not complete', () => {
239+
it('should set warning if references were found but selected references are not complete', async () => {
233240
const children = jest.fn(({ warning }) => <div>{warning}</div>);
234241
const { queryByText } = renderWithRedux(
235242
<Form
236243
onSubmit={jest.fn()}
237244
render={() => (
238245
<ReferenceArrayInputController
239246
{...defaultProps}
247+
// Avoid global collision in useGetMany with queriesToCall
248+
basePath="/products"
249+
resource="products"
240250
input={{ value: [1, 2] }}
241251
>
242252
{children}
@@ -259,13 +269,17 @@ describe('<ReferenceArrayInputController />', () => {
259269
},
260270
references: {
261271
possibleValues: {
262-
'posts@tag_ids': [],
272+
'products@tag_ids': [],
263273
},
264274
},
265275
},
266276
}
267277
);
268-
expect(queryByText('ra.input.references.many_missing')).not.toBeNull();
278+
await waitFor(() => {
279+
expect(
280+
queryByText('ra.input.references.many_missing')
281+
).not.toBeNull();
282+
});
269283
});
270284

271285
it('should set warning if references were found but selected references are empty', () => {
@@ -276,6 +290,9 @@ describe('<ReferenceArrayInputController />', () => {
276290
render={() => (
277291
<ReferenceArrayInputController
278292
{...defaultProps}
293+
// Avoid global collision in useGetMany with queriesToCall
294+
basePath="/posters"
295+
resource="posters"
279296
input={{ value: [1, 2] }}
280297
>
281298
{children}
@@ -287,7 +304,7 @@ describe('<ReferenceArrayInputController />', () => {
287304
resources: { tags: { data: { 5: {}, 6: {} } } },
288305
references: {
289306
possibleValues: {
290-
'posts@tag_ids': [],
307+
'posters@tag_ids': [],
291308
},
292309
},
293310
},
@@ -296,7 +313,7 @@ describe('<ReferenceArrayInputController />', () => {
296313
expect(queryByText('ra.input.references.many_missing')).not.toBeNull();
297314
});
298315

299-
it('should not set warning if all references were found', () => {
316+
it('should not set warning if all references were found', async () => {
300317
const children = jest.fn(({ warning }) => <div>{warning}</div>);
301318
const { queryByText } = renderWithRedux(
302319
<Form
@@ -335,7 +352,9 @@ describe('<ReferenceArrayInputController />', () => {
335352
},
336353
}
337354
);
338-
expect(queryByText('ra.input.references.many_missing')).toBeNull();
355+
await waitFor(() => {
356+
expect(queryByText('ra.input.references.many_missing')).toBeNull();
357+
});
339358
});
340359

341360
it('should call crudGetMatching on mount with default fetch values', async () => {

packages/ra-core/src/dataProvider/useGetMany.spec.tsx

+12-10
Original file line numberDiff line numberDiff line change
@@ -250,16 +250,18 @@ describe('useGetMany', () => {
250250
}
251251
);
252252
await waitFor(() => {
253-
expect(hookValue.mock.calls.pop()[0]).toEqual({
254-
data: [
255-
{ id: 1, title: 'foo' },
256-
{ id: 2, title: 'bar' },
257-
],
258-
loading: false,
259-
loaded: true,
260-
error: null,
261-
refetch: expect.any(Function),
262-
});
253+
if (hookValue.mock.calls.length > 0) {
254+
expect(hookValue.mock.calls.pop()[0]).toEqual({
255+
data: [
256+
{ id: 1, title: 'foo' },
257+
{ id: 2, title: 'bar' },
258+
],
259+
loading: false,
260+
loaded: true,
261+
error: null,
262+
refetch: expect.any(Function),
263+
});
264+
}
263265
});
264266
});
265267

packages/ra-core/src/dataProvider/useGetMany.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,13 @@ const useGetMany = (
115115
data,
116116
error: null,
117117
loading: ids.length !== 0,
118-
loaded:
119-
ids.length === 0 ||
120-
(data.length !== 0 && !data.includes(undefined)),
118+
loaded: data.length !== 0 && !data.includes(undefined),
121119
refetch,
122120
});
123121
if (!isEqual(state.data, data)) {
124122
setState({
125123
...state,
126124
data,
127-
loaded: true,
128125
});
129126
}
130127
dataProvider = useDataProvider(); // not the best way to pass the dataProvider to a function outside the hook, but I couldn't find a better one

packages/ra-ui-materialui/src/field/ReferenceArrayField.spec.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
22
import expect from 'expect';
3-
import { render, act } from '@testing-library/react';
3+
import { render, act, waitFor } from '@testing-library/react';
44
import { renderWithRedux } from 'ra-test';
55
import { MemoryRouter } from 'react-router-dom';
66
import { ListContextProvider, DataProviderContext } from 'ra-core';
@@ -241,7 +241,8 @@ describe('<ReferenceArrayField />', () => {
241241
);
242242
expect(queryByText('bar1')).toBeNull();
243243
act(() => resolve());
244-
await new Promise(resolve => setTimeout(resolve)); // wait for loaded to be true
245-
expect(queryByText('bar1')).not.toBeNull();
244+
await waitFor(() => {
245+
expect(queryByText('bar1')).not.toBeNull();
246+
});
246247
});
247248
});

packages/ra-ui-materialui/src/field/ReferenceField.spec.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ describe('<ReferenceField />', () => {
274274
const dataProvider = {
275275
getMany: jest.fn(() => Promise.reject('boo')),
276276
};
277-
const { getByRole } = renderWithRedux(
277+
const { queryByRole } = renderWithRedux(
278278
// @ts-ignore-line
279279
<DataProviderContext.Provider value={dataProvider}>
280280
<ReferenceField
@@ -289,8 +289,8 @@ describe('<ReferenceField />', () => {
289289
</DataProviderContext.Provider>
290290
);
291291
await waitFor(() => {
292-
const ErrorIcon = getByRole('presentation', { hidden: true });
293-
expect(ErrorIcon).toBeDefined();
292+
const ErrorIcon = queryByRole('presentation', { hidden: true });
293+
expect(ErrorIcon).not.toBeNull();
294294
expect(ErrorIcon.getAttribute('aria-errormessage')).toBe('boo');
295295
});
296296
});

packages/ra-ui-materialui/src/field/ReferenceField.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,6 @@ export const ReferenceFieldView: FC<ReferenceFieldViewProps> = props => {
196196
} = props;
197197
const classes = useStyles(props);
198198

199-
if (!loaded) {
200-
return <LinearProgress />;
201-
}
202199
if (error) {
203200
return (
204201
/* eslint-disable jsx-a11y/role-supports-aria-props */
@@ -211,6 +208,9 @@ export const ReferenceFieldView: FC<ReferenceFieldViewProps> = props => {
211208
/* eslint-enable */
212209
);
213210
}
211+
if (!loaded) {
212+
return <LinearProgress />;
213+
}
214214
if (!referenceRecord) {
215215
return null;
216216
}

0 commit comments

Comments
 (0)