Files
SkinbaseNova/resources/js/lib/useLazyProfileFavourites.test.jsx
T

75 lines
2.9 KiB
React

import React from 'react'
import { render, waitFor } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import useLazyProfileFavourites from './useLazyProfileFavourites'
function Harness({ username = 'alice', initial = null, enabled = false }) {
const state = useLazyProfileFavourites({
username,
initialFavourites: initial,
enabled,
})
return <output data-testid="state">{JSON.stringify(state)}</output>
}
describe('useLazyProfileFavourites', () => {
beforeEach(() => {
vi.restoreAllMocks()
})
it('does not request before activation and requests page one once on activation', async () => {
const fetchMock = vi.spyOn(globalThis, 'fetch').mockResolvedValue({
ok: true,
json: async () => ({ data: [{ id: 1 }], next_cursor: 'c1' }),
})
const view = render(<Harness />)
expect(fetchMock).not.toHaveBeenCalled()
view.rerender(<Harness enabled />)
await waitFor(() => expect(fetchMock).toHaveBeenCalledTimes(1))
expect(fetchMock).toHaveBeenCalledWith('/api/profile/alice/favourites', expect.objectContaining({
credentials: 'same-origin',
}))
})
it('uses SSR data without a page-one request and survives rerenders', async () => {
const fetchMock = vi.spyOn(globalThis, 'fetch')
const view = render(<Harness enabled initial={{ data: [{ id: 9 }], next_cursor: 'c2' }} />)
view.rerender(<Harness enabled initial={{ data: [{ id: 9 }], next_cursor: 'c2' }} />)
await waitFor(() => expect(JSON.parse(view.getByTestId('state').textContent).items).toEqual([{ id: 9 }]))
expect(fetchMock).not.toHaveBeenCalled()
})
it('does not refetch after switching away and back', async () => {
const fetchMock = vi.spyOn(globalThis, 'fetch').mockResolvedValue({
ok: true,
json: async () => ({ data: [{ id: 3 }], next_cursor: null }),
})
const view = render(<Harness enabled />)
await waitFor(() => expect(fetchMock).toHaveBeenCalledTimes(1))
view.rerender(<Harness enabled={false} />)
view.rerender(<Harness enabled />)
await waitFor(() => expect(JSON.parse(view.getByTestId('state').textContent).items).toEqual([{ id: 3 }]))
expect(fetchMock).toHaveBeenCalledTimes(1)
})
it('resets profile state and ignores a stale response', async () => {
let resolveRequest
const fetchMock = vi.spyOn(globalThis, 'fetch').mockImplementation(() => new Promise((resolve) => {
resolveRequest = resolve
}))
const view = render(<Harness username="alice" enabled />)
await waitFor(() => expect(fetchMock).toHaveBeenCalledTimes(1))
view.rerender(<Harness username="bob" enabled />)
expect(JSON.parse(view.getByTestId('state').textContent).items).toEqual([])
resolveRequest({ ok: true, json: async () => ({ data: [{ id: 1 }], next_cursor: null }) })
await waitFor(() => expect(JSON.parse(view.getByTestId('state').textContent).items).toEqual([]))
})
})