Keep the profile payload smaller on first paint and fetch collections through a dedicated API when the collections tab is needed.
71 lines
2.8 KiB
React
71 lines
2.8 KiB
React
import React from 'react'
|
|
import { render, waitFor } from '@testing-library/react'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import useLazyProfileCollections from './useLazyProfileCollections'
|
|
|
|
function Harness({ username = 'alice', initial = null, enabled = false }) {
|
|
const state = useLazyProfileCollections({
|
|
username,
|
|
initialCollections: initial,
|
|
enabled,
|
|
})
|
|
|
|
return <output data-testid="state">{JSON.stringify(state)}</output>
|
|
}
|
|
|
|
describe('useLazyProfileCollections', () => {
|
|
beforeEach(() => vi.restoreAllMocks())
|
|
|
|
it('does not request while the profile remains on Posts', () => {
|
|
const fetchMock = vi.spyOn(globalThis, 'fetch')
|
|
render(<Harness />)
|
|
expect(fetchMock).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('requests once on first Collections activation and reuses the result', async () => {
|
|
const fetchMock = vi.spyOn(globalThis, 'fetch').mockResolvedValue({
|
|
ok: true,
|
|
json: async () => ({ data: [{ id: 1, title: 'One' }] }),
|
|
})
|
|
const view = render(<Harness />)
|
|
|
|
view.rerender(<Harness enabled />)
|
|
await waitFor(() => expect(fetchMock).toHaveBeenCalledTimes(1))
|
|
await waitFor(() => expect(JSON.parse(view.getByTestId('state').textContent).items).toHaveLength(1))
|
|
|
|
view.rerender(<Harness enabled={false} />)
|
|
view.rerender(<Harness enabled />)
|
|
expect(fetchMock).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('treats an empty response as loaded and does not refetch', async () => {
|
|
const fetchMock = vi.spyOn(globalThis, 'fetch').mockResolvedValue({ ok: true, json: async () => ({ data: [] }) })
|
|
const view = render(<Harness enabled />)
|
|
|
|
await waitFor(() => expect(JSON.parse(view.getByTestId('state').textContent).loaded).toBe(true))
|
|
view.rerender(<Harness enabled={false} />)
|
|
view.rerender(<Harness enabled />)
|
|
expect(fetchMock).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('uses direct Collections SSR data without a lazy request', () => {
|
|
const fetchMock = vi.spyOn(globalThis, 'fetch')
|
|
const initial = [{ id: 9, title: 'SSR collection' }]
|
|
const view = render(<Harness initial={initial} enabled />)
|
|
|
|
expect(fetchMock).not.toHaveBeenCalled()
|
|
expect(JSON.parse(view.getByTestId('state').textContent).items).toEqual(initial)
|
|
})
|
|
|
|
it('ignores a stale response after profile navigation', async () => {
|
|
let resolveAlice
|
|
const fetchMock = vi.spyOn(globalThis, 'fetch').mockImplementation(() => new Promise((resolve) => { resolveAlice = resolve }))
|
|
const view = render(<Harness username="alice" enabled />)
|
|
await waitFor(() => expect(fetchMock).toHaveBeenCalledTimes(1))
|
|
|
|
view.rerender(<Harness username="bob" enabled />)
|
|
resolveAlice({ ok: true, json: async () => ({ data: [{ id: 'alice' }] }) })
|
|
await waitFor(() => expect(JSON.parse(view.getByTestId('state').textContent).items).toEqual([]))
|
|
})
|
|
})
|