TypeFetched/tests/mock-controller.test.ts

107 lines
3.2 KiB
TypeScript

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)
})
})