Skip to content

Commit 13afc15

Browse files
authored
Merge branch 'main' into fix/query-devtools-undefined-nonce
2 parents 793a5c7 + ec4a59a commit 13afc15

1 file changed

Lines changed: 126 additions & 1 deletion

File tree

packages/query-devtools/src/__tests__/Explorer.test.tsx

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
2-
import { fireEvent, render } from '@solidjs/testing-library'
2+
import { fireEvent, render, within } from '@solidjs/testing-library'
33
import { QueryClient, onlineManager } from '@tanstack/query-core'
44
import Explorer from '../Explorer'
55
import { QueryDevtoolsContext, ThemeContext } from '../contexts'
@@ -232,6 +232,63 @@ describe('Explorer', () => {
232232
)
233233
})
234234

235+
it('should reset the copy button to the idle state 1500ms after a successful copy', async () => {
236+
const writeText = vi.fn().mockResolvedValue(undefined)
237+
vi.stubGlobal('navigator', { clipboard: { writeText } })
238+
queryClient.setQueryData(['data'], { name: 'Anna' })
239+
240+
const rendered = renderExplorer({
241+
label: 'data',
242+
value: { name: 'Anna' },
243+
editable: true,
244+
activeQuery: queryClient
245+
.getQueryCache()
246+
.find({ queryKey: ['data'] }) as Query,
247+
})
248+
249+
fireEvent.click(rendered.getByLabelText('Copy object to clipboard'))
250+
await vi.advanceTimersByTimeAsync(0)
251+
252+
expect(
253+
rendered.getByLabelText('Object copied to clipboard'),
254+
).toBeInTheDocument()
255+
256+
await vi.advanceTimersByTimeAsync(1500)
257+
258+
expect(
259+
rendered.getByLabelText('Copy object to clipboard'),
260+
).toBeInTheDocument()
261+
})
262+
263+
it('should reset the copy button to the idle state 1500ms after a failed copy', async () => {
264+
const writeText = vi.fn().mockRejectedValue(new Error('denied'))
265+
vi.stubGlobal('navigator', { clipboard: { writeText } })
266+
vi.spyOn(console, 'error').mockImplementation(() => {})
267+
queryClient.setQueryData(['data'], { name: 'Anna' })
268+
269+
const rendered = renderExplorer({
270+
label: 'data',
271+
value: { name: 'Anna' },
272+
editable: true,
273+
activeQuery: queryClient
274+
.getQueryCache()
275+
.find({ queryKey: ['data'] }) as Query,
276+
})
277+
278+
fireEvent.click(rendered.getByLabelText('Copy object to clipboard'))
279+
await vi.advanceTimersByTimeAsync(0)
280+
281+
expect(
282+
rendered.getByLabelText('Error copying object to clipboard'),
283+
).toBeInTheDocument()
284+
285+
await vi.advanceTimersByTimeAsync(1500)
286+
287+
expect(
288+
rendered.getByLabelText('Copy object to clipboard'),
289+
).toBeInTheDocument()
290+
})
291+
235292
it('should clear array items via "setQueryData" when the clear-array button is clicked', () => {
236293
queryClient.setQueryData(['data'], ['a', 'b', 'c'])
237294

@@ -357,6 +414,49 @@ describe('Explorer', () => {
357414
expect(rendered.getByText('0:')).toBeInTheDocument()
358415
expect(rendered.getByText('"item-0"')).toBeInTheDocument()
359416
})
417+
418+
it('should independently toggle two pages when their headers are clicked', () => {
419+
const rendered = renderExplorer({
420+
label: 'big',
421+
value: Array.from({ length: 200 }, (_, i) => `item-${i}`),
422+
})
423+
424+
fireEvent.click(rendered.getByRole('button', { expanded: false }))
425+
fireEvent.click(rendered.getByText('[0...99]'))
426+
fireEvent.click(rendered.getByText('[100...199]'))
427+
428+
expect(rendered.getByText('"item-0"')).toBeInTheDocument()
429+
expect(rendered.getByText('"item-100"')).toBeInTheDocument()
430+
431+
fireEvent.click(rendered.getByText('[0...99]'))
432+
433+
expect(rendered.queryByText('"item-0"')).toBeNull()
434+
expect(rendered.getByText('"item-100"')).toBeInTheDocument()
435+
})
436+
437+
it('should render action buttons for items inside a paginated page', () => {
438+
const value: Array<Array<number>> = Array.from(
439+
{ length: 200 },
440+
(_, i) => [i],
441+
)
442+
queryClient.setQueryData(['data'], value)
443+
444+
const rendered = renderExplorer({
445+
label: 'Data',
446+
value,
447+
defaultExpanded: ['Data'],
448+
editable: true,
449+
activeQuery: queryClient
450+
.getQueryCache()
451+
.find({ queryKey: ['data'] }) as Query,
452+
})
453+
454+
fireEvent.click(rendered.getByText('[0...99]'))
455+
456+
expect(
457+
rendered.getAllByLabelText('Remove all items').length,
458+
).toBeGreaterThan(1)
459+
})
360460
})
361461

362462
describe('inline edit', () => {
@@ -436,5 +536,30 @@ describe('Explorer', () => {
436536

437537
expect(rendered.getByLabelText('Delete item')).toBeInTheDocument()
438538
})
539+
540+
it('should delete fields from the active query when their inline delete buttons are clicked', () => {
541+
const value = { name: 'Anna', age: 30 }
542+
queryClient.setQueryData(['data'], value)
543+
544+
const rendered = renderExplorer({
545+
label: 'Data',
546+
value,
547+
defaultExpanded: ['Data'],
548+
editable: true,
549+
activeQuery: queryClient
550+
.getQueryCache()
551+
.find({ queryKey: ['data'] }) as Query,
552+
})
553+
554+
const ageRow = rendered.getByText('age:').parentElement!
555+
fireEvent.click(within(ageRow).getByLabelText('Delete item'))
556+
557+
expect(queryClient.getQueryData(['data'])).toEqual({ name: 'Anna' })
558+
559+
const nameRow = rendered.getByText('name:').parentElement!
560+
fireEvent.click(within(nameRow).getByLabelText('Delete item'))
561+
562+
expect(queryClient.getQueryData(['data'])).toEqual({})
563+
})
439564
})
440565
})

0 commit comments

Comments
 (0)