Skip to content

Commit 3b88f33

Browse files
committed
add tests for some mutations
1 parent 4b78582 commit 3b88f33

File tree

4 files changed

+47
-4
lines changed

4 files changed

+47
-4
lines changed

examples/vite/src/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ function AppCore() {
124124
</a>
125125

126126
<button
127-
onClick={() => deletePostMutation.client.mutate({ params: { id: post.id } })}
128-
// disabled={deletePostMutation.client.isMutating() > 0}
127+
onClick={() => deletePostMutation.client.mutate({ params: { id: post.id } }).catch(() => {})}
128+
disabled={deletePostMutation.client.isMutating({ params: { id: post.id } }) > 0}
129129
>
130130
Delete
131131
</button>

examples/vite/tests/Render.test.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,42 @@ test('Loads next page when clicked', async () => {
3333
await loadBtn.click();
3434
await expect.element(getByText('Load next page')).not.toBeInTheDocument();
3535
});
36+
37+
test('Deletes posts immediately on clicking delete button', async () => {
38+
const { getByText } = render(<App />);
39+
40+
const el = getByText('1 - 10 Tips for Better Time Management');
41+
42+
await expect.element(el).toBeInTheDocument();
43+
await getByText('Delete').nth(1).click();
44+
45+
await expect.element(el).not.toBeInTheDocument();
46+
});
47+
48+
test('Deletes deletes but reverts the deletion after server fails', async () => {
49+
const { getByText } = render(<App />);
50+
51+
const el = getByText('0 - Exploring the Future of AI');
52+
53+
await expect.element(el).toBeInTheDocument();
54+
await getByText('Delete').nth(0).click();
55+
56+
await expect.element(el).not.toBeInTheDocument();
57+
58+
await expect.element(el, { timeout: 4000 }).toBeInTheDocument();
59+
await expect.element(getByText('Error deleting post')).toBeInTheDocument();
60+
});
61+
62+
test('Posts deleted in other tabs are synced', async () => {
63+
const { getByText } = render(<App />);
64+
65+
const el = getByText('1 - 10 Tips for Better Time Management');
66+
67+
await expect.element(el).toBeInTheDocument();
68+
69+
// Simulate delete in another tab and send sync message
70+
await fetch(`${baseUrl}/posts/1`, { method: 'DELETE' });
71+
new BroadcastChannel('react-query-builder-tags').postMessage({ type: 'invalidate', data: [{ type: 'posts' }] });
72+
73+
await expect.element(el).not.toBeInTheDocument();
74+
});

packages/react-query-builder/src/builder/QueryBuilder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export class QueryBuilder<
9393
): QueryBuilder<TVars, TData, TError, TKey, TTags, TFlags | 'withClient'> {
9494
let syncChannel: BroadcastChannel | undefined = undefined;
9595

96-
if (syncTagsWithOtherTabs) {
96+
if (syncTagsWithOtherTabs && typeof BroadcastChannel !== 'undefined') {
9797
syncChannel = new BroadcastChannel('react-query-builder-tags');
9898
syncChannel.addEventListener('message', (event) => {
9999
const { type, data } = event.data;

packages/react-query-builder/src/builder/QueryBuilderFrozen.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,14 +277,18 @@ export class QueryBuilderFrozen<
277277
vars,
278278
filters,
279279
) => {
280+
const baseKey = this.preprocessVars(this.mergeVars([this.config.vars, vars]));
281+
280282
return {
281283
mutationKey: this.getMutationKey(),
282284
...filters,
283285
predicate: (m) => {
284286
if (filters?.predicate && !filters.predicate(m)) return false;
285287
if (vars == null) return true;
286288
if (!m.state.variables) return false;
287-
return areKeysEqual([m.state.variables], [vars], this.config.queryKeySanitizer);
289+
290+
const curKey = this.preprocessVars(this.mergeVars([this.config.vars, m.state.variables]));
291+
return areKeysEqual([curKey], [baseKey], this.config.queryKeySanitizer);
288292
},
289293
};
290294
};

0 commit comments

Comments
 (0)