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 {JSON.stringify(state)} } describe('useLazyProfileCollections', () => { beforeEach(() => vi.restoreAllMocks()) it('does not request while the profile remains on Posts', () => { const fetchMock = vi.spyOn(globalThis, 'fetch') render() 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() view.rerender() await waitFor(() => expect(fetchMock).toHaveBeenCalledTimes(1)) await waitFor(() => expect(JSON.parse(view.getByTestId('state').textContent).items).toHaveLength(1)) view.rerender() view.rerender() 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() await waitFor(() => expect(JSON.parse(view.getByTestId('state').textContent).loaded).toBe(true)) view.rerender() view.rerender() 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() 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() await waitFor(() => expect(fetchMock).toHaveBeenCalledTimes(1)) view.rerender() resolveAlice({ ok: true, json: async () => ({ data: [{ id: 'alice' }] }) }) await waitFor(() => expect(JSON.parse(view.getByTestId('state').textContent).items).toEqual([])) }) })