import { afterEach, describe, expect, it, vi } from 'vitest' import { RevolutionaryTypedFetch } from '../src/core/typed-fetch.js' describe('mock controller integration', () => { afterEach(() => { vi.restoreAllMocks() }) it('intercepts matching requests and skips fetch', async () => { const fetchSpy = vi.fn(() => Promise.reject(new Error('network should not be called'))) vi.stubGlobal('fetch', fetchSpy) const client = new RevolutionaryTypedFetch({ request: { baseURL: 'https://api.test' } }) client.mock({ method: 'GET', url: '/users/:id', response: { data: { id: '123', name: 'Mock User' }, status: 200 } }) const result = await client.get('/users/123') expect(result.data).toEqual({ id: '123', name: 'Mock User' }) expect(result.response.status).toBe(200) expect(fetchSpy).not.toHaveBeenCalled() }) it('passes params, query, headers, and body to handlers', async () => { const fetchSpy = vi.fn(() => Promise.reject(new Error('network should not be called'))) vi.stubGlobal('fetch', fetchSpy) const client = new RevolutionaryTypedFetch({ request: { baseURL: 'https://api.test' } }) client.mock({ method: 'PATCH', url: '/users/:id', handler: ({ params, query, headers, body }) => { expect(params.id).toBe('42') expect(query.filter).toBe('active') expect(headers['x-test']).toBe('1') expect((body as any).title).toBe('Director') return { data: { id: params.id, filter: query.filter, seenHeader: headers['x-test'] } } } }) const { data } = await client.patch( '/users/42?filter=active', { title: 'Director' }, { headers: { 'X-Test': '1' } } ) expect(data).toEqual({ id: '42', filter: 'active', seenHeader: '1' }) expect(fetchSpy).not.toHaveBeenCalled() }) it('mockOnce only intercepts the first call', async () => { const fetchSpy = vi.fn(async () => new Response(JSON.stringify({ ok: true }), { headers: { 'Content-Type': 'application/json' } }) ) vi.stubGlobal('fetch', fetchSpy) const client = new RevolutionaryTypedFetch({ request: { baseURL: 'https://api.test' } }) client.mockOnce({ method: 'GET', url: '/ping', response: { data: { mocked: true } } }) const first = await client.get('/ping') expect(first.data).toEqual({ mocked: true }) const second = await client.get('/ping') expect(fetchSpy).toHaveBeenCalledTimes(1) expect(second.data).toEqual({ ok: true }) }) it('clearMocks removes registered routes', async () => { const fetchSpy = vi.fn(async () => new Response(JSON.stringify({ ok: true }), { headers: { 'Content-Type': 'application/json' } }) ) vi.stubGlobal('fetch', fetchSpy) const client = new RevolutionaryTypedFetch({ request: { baseURL: 'https://api.test' } }) client.mock({ method: 'GET', url: '/users', response: { data: [{ id: 1 }] } }) client.clearMocks() const result = await client.get('/users') expect(result.data).toEqual({ ok: true }) expect(fetchSpy).toHaveBeenCalledTimes(1) }) })