-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Expand file tree
/
Copy pathuseMutationWithMutationMode.spec.tsx
More file actions
157 lines (148 loc) · 5.03 KB
/
useMutationWithMutationMode.spec.tsx
File metadata and controls
157 lines (148 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import * as React from 'react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import expect from 'expect';
import {
useMutationWithMutationMode,
UseMutationWithMutationModeOptions,
} from './useMutationWithMutationMode';
import { CoreAdminContext } from '../core/CoreAdminContext';
import { useDataProvider } from './useDataProvider';
import { DataProvider } from '../types';
import { testDataProvider } from './testDataProvider';
describe('useMutationWithMutationMode', () => {
type MyDataProvider = DataProvider & {
updateUserProfile: ({ data }: { data: any }) => Promise<{ data: any }>;
};
const useUpdateUserProfile = (
args?: { data?: any },
options?: Pick<
UseMutationWithMutationModeOptions<
Error,
{ data: any },
{ data?: any }
>,
'mutationMode'
>
) => {
const dataProvider = useDataProvider<MyDataProvider>();
return useMutationWithMutationMode<
Error,
{ data: any },
{ data?: any }
>(args, {
mutationFn: ({ data }) => {
if (!data) {
throw new Error('data is required');
}
return dataProvider
.updateUserProfile({ data })
.then(({ data }) => data);
},
updateCache: ({ data }) => {
return data;
},
getSnapshot: () => {
return [];
},
...options,
});
};
it('returns a callback that can be used with update arguments', async () => {
const dataProvider = testDataProvider({
updateUserProfile: jest.fn(({ data }) =>
Promise.resolve({ data: { id: 1, ...data } } as any)
),
}) as MyDataProvider;
let localUpdate;
const Dummy = () => {
const [update] = useUpdateUserProfile();
localUpdate = update;
return <span />;
};
render(
<CoreAdminContext dataProvider={dataProvider}>
<Dummy />
</CoreAdminContext>
);
localUpdate({
data: { bar: 'baz' },
});
await waitFor(() => {
expect(dataProvider.updateUserProfile).toHaveBeenCalledWith({
data: { bar: 'baz' },
});
});
});
it('returns a callback that can be used with no arguments', async () => {
const dataProvider = testDataProvider({
updateUserProfile: jest.fn(({ data }) =>
Promise.resolve({ data: { id: 1, ...data } } as any)
),
}) as MyDataProvider;
let localUpdate;
const Dummy = () => {
const [update] = useUpdateUserProfile({
data: { bar: 'baz' },
});
localUpdate = update;
return <span />;
};
render(
<CoreAdminContext dataProvider={dataProvider}>
<Dummy />
</CoreAdminContext>
);
localUpdate();
await waitFor(() => {
expect(dataProvider.updateUserProfile).toHaveBeenCalledWith({
data: { bar: 'baz' },
});
});
});
it('uses the latest params at execution time in optimistic mode', async () => {
const dataProvider = testDataProvider({
updateUserProfile: jest.fn(({ data }) =>
Promise.resolve({ data: { id: 1, ...data } } as any)
),
}) as MyDataProvider;
const Dummy = () => {
const [data, setData] = React.useState({ value: 'value1' });
const [update] = useUpdateUserProfile(
{
data,
},
{ mutationMode: 'optimistic' }
);
return (
<>
<p>{data.value}</p>
<button onClick={() => setData({ value: 'value2' })}>
Update data
</button>
<button onClick={() => update()}>Update</button>
</>
);
};
render(
<CoreAdminContext dataProvider={dataProvider}>
<Dummy />
</CoreAdminContext>
);
fireEvent.click(screen.getByText('Update'));
// In case of undoable, clicking the _Update data_ button would trigger the mutation
fireEvent.click(screen.getByText('Update data'));
await screen.findByText('value2');
fireEvent.click(screen.getByText('Update'));
await waitFor(() => {
expect(dataProvider.updateUserProfile).toHaveBeenCalledWith({
data: { value: 'value1' },
});
});
// Ensure the next call uses the latest data
await waitFor(() => {
expect(dataProvider.updateUserProfile).toHaveBeenCalledWith({
data: { value: 'value2' },
});
});
});
});