import React from 'react'
import { act, render, screen, waitFor } from '@testing-library/react'
import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'
import useLazyProfileFeaturedArtworks from './useLazyProfileFeaturedArtworks'
function Harness({ username = 'alice', initial = null, enabled = false }) {
const state = useLazyProfileFeaturedArtworks({
username,
initialFeaturedArtworks: initial,
enabled,
})
return (
{state.items.length}
{String(state.loading)}
{String(state.error)}
{state.items.map((item) => {item.title})}
)
}
describe('useLazyProfileFeaturedArtworks', () => {
beforeEach(() => {
vi.stubGlobal('fetch', vi.fn(async () => ({
ok: true,
json: async () => ({ data: [{ id: 1, title: 'Featured one' }] }),
})))
})
afterEach(() => vi.unstubAllGlobals())
it('does not request while the posts tab is active', () => {
render()
expect(fetch).not.toHaveBeenCalled()
})
it('loads once on first artworks activation and reuses the result', async () => {
const view = render()
await waitFor(() => expect(screen.getByText('Featured one')).toBeTruthy())
expect(fetch).toHaveBeenCalledTimes(1)
view.rerender()
view.rerender()
expect(fetch).toHaveBeenCalledTimes(1)
})
it('does not request when SSR already supplied featured artworks', () => {
render()
expect(screen.getByText('SSR feature')).toBeTruthy()
expect(fetch).not.toHaveBeenCalled()
})
it('allows a safe retry after failure', async () => {
fetch.mockRejectedValueOnce(new Error('network'))
render()
await waitFor(() => expect(screen.getByTestId('error').textContent).toBe('true'))
await act(async () => screen.getByRole('button', { name: 'retry' }).click())
await waitFor(() => expect(screen.getByText('Featured one')).toBeTruthy())
expect(fetch).toHaveBeenCalledTimes(2)
})
it('ignores a stale response after profile navigation', async () => {
let resolveAlice
fetch.mockImplementationOnce(() => new Promise((resolve) => { resolveAlice = resolve }))
const view = render()
view.rerender()
await act(async () => resolveAlice({ ok: true, json: async () => ({ data: [{ id: 1, title: 'Alice feature' }] }) }))
expect(screen.queryByText('Alice feature')).toBeNull()
expect(screen.getByTestId('count').textContent).toBe('0')
})
})