deno.land / x / jotai@v1.8.4 / tests / urql / atomWithMutation.test.tsx
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129import { StrictMode, Suspense } from 'react'import { fireEvent, render, waitFor } from '@testing-library/react'import type { Client } from '@urql/core'import { delay, fromValue, pipe, take, toPromise } from 'wonka'import { atom, useAtom } from 'jotai'import { atomWithMutation } from 'jotai/urql'import { getTestProvider, itSkipIfVersionedWrite } from '../testUtils'
const withPromise = (source$: any) => { source$.toPromise = () => pipe(source$, take(1), toPromise) return source$}
const generateClient = (error?: () => boolean) => ({ mutation: () => { const source$ = withPromise( pipe( fromValue( error?.() ? { error: new Error('fetch error') } : { data: { count: 1 } } ), delay(100) ) ) return source$ }, } as unknown as Client)
const Provider = getTestProvider()
it('mutation basic test', async () => { const countAtom = atomWithMutation<{ count: number }, Record<string, never>>( () => 'mutation Test { count }', () => generateClient() ) const mutateAtom = atom(null, (_get, set) => set(countAtom, { variables: {} }) )
const Counter = () => { const [{ data }] = useAtom(countAtom) return ( <> <div>count: {data?.count}</div> </> ) }
const Controls = () => { const [, mutate] = useAtom(mutateAtom) return <button onClick={() => mutate()}>mutate</button> }
const { getByText, findByText } = render( <StrictMode> <Provider> <Suspense fallback="loading"> <Counter /> </Suspense> <Controls /> </Provider> </StrictMode> )
await findByText('loading')
await new Promise((r) => setTimeout(r, 100)) fireEvent.click(getByText('mutate')) await findByText('count: 1')})
describe('error handling', () => { itSkipIfVersionedWrite('mutation error test', async () => { const countAtom = atomWithMutation< { count: number }, Record<string, never> >( () => 'mutation Test { count }', () => generateClient(() => true) ) const mutateAtom = atom(null, (_get, set) => set(countAtom, { variables: {} }) )
const Counter = () => { const [{ data }] = useAtom(countAtom) return ( <> <div>count: {data?.count}</div> </> ) }
let errored = false const Controls = () => { const [, mutate] = useAtom(mutateAtom) const handleClick = async () => { try { await mutate() } catch { errored = true } } return <button onClick={handleClick}>mutate</button> }
const { getByText, findByText } = render( <StrictMode> <Provider> <Suspense fallback="loading"> <Counter /> </Suspense> <Controls /> </Provider> </StrictMode> )
await findByText('loading')
await new Promise((r) => setTimeout(r, 100)) fireEvent.click(getByText('mutate')) await waitFor(() => { expect(errored).toBe(true) }) })})
Version Info