142 lines
4.7 KiB
TypeScript
Executable File
142 lines
4.7 KiB
TypeScript
Executable File
import { resolveFetch, resolveHeadersConstructor, fetchWithAuth } from '../../src/lib/fetch.ts'
|
|
|
|
// Mock fetch for testing
|
|
const mockFetch = jest.fn()
|
|
const mockHeaders = jest.fn()
|
|
|
|
describe('fetch module', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks()
|
|
// Reset global fetch
|
|
delete (global as any).fetch
|
|
delete (global as any).Headers
|
|
})
|
|
|
|
describe('resolveFetch', () => {
|
|
test('should use custom fetch when provided', () => {
|
|
const customFetch = jest.fn()
|
|
const result = resolveFetch(customFetch)
|
|
expect(typeof result).toBe('function')
|
|
// Test that it actually calls the custom fetch
|
|
result('test')
|
|
expect(customFetch).toHaveBeenCalledWith('test')
|
|
})
|
|
|
|
test('should use global fetch when available', () => {
|
|
const globalFetch = jest.fn()
|
|
;(global as any).fetch = globalFetch
|
|
|
|
const result = resolveFetch()
|
|
expect(typeof result).toBe('function')
|
|
// Test that it actually calls the global fetch
|
|
result('test')
|
|
expect(globalFetch).toHaveBeenCalledWith('test')
|
|
})
|
|
|
|
test('should fallback to node-fetch when global fetch is undefined', () => {
|
|
const result = resolveFetch()
|
|
expect(typeof result).toBe('function')
|
|
})
|
|
})
|
|
|
|
describe('resolveHeadersConstructor', () => {
|
|
test('should use global Headers when available', () => {
|
|
const GlobalHeaders = jest.fn()
|
|
;(global as any).Headers = GlobalHeaders
|
|
|
|
const result = resolveHeadersConstructor()
|
|
expect(result).toBe(GlobalHeaders)
|
|
})
|
|
|
|
test('should fallback to NodeFetchHeaders when global Headers is undefined', () => {
|
|
const result = resolveHeadersConstructor()
|
|
expect(typeof result).toBe('function')
|
|
})
|
|
})
|
|
|
|
describe('fetchWithAuth', () => {
|
|
test('should add apikey and authorization headers', async () => {
|
|
const mockResponse = { ok: true }
|
|
const mockFetchImpl = jest.fn().mockResolvedValue(mockResponse)
|
|
const mockHeadersImpl = jest.fn().mockReturnValue({
|
|
has: jest.fn().mockReturnValue(false),
|
|
set: jest.fn(),
|
|
})
|
|
|
|
;(global as any).fetch = mockFetchImpl
|
|
;(global as any).Headers = mockHeadersImpl
|
|
|
|
const supabaseKey = 'test-key'
|
|
const getAccessToken = jest.fn().mockResolvedValue('test-token')
|
|
|
|
const authFetch = fetchWithAuth(supabaseKey, getAccessToken)
|
|
await authFetch('https://example.com')
|
|
|
|
expect(mockHeadersImpl).toHaveBeenCalled()
|
|
expect(getAccessToken).toHaveBeenCalled()
|
|
})
|
|
|
|
test('should use supabaseKey as fallback when getAccessToken returns null', async () => {
|
|
const mockResponse = { ok: true }
|
|
const mockFetchImpl = jest.fn().mockResolvedValue(mockResponse)
|
|
const mockHeadersImpl = jest.fn().mockReturnValue({
|
|
has: jest.fn().mockReturnValue(false),
|
|
set: jest.fn(),
|
|
})
|
|
|
|
;(global as any).fetch = mockFetchImpl
|
|
;(global as any).Headers = mockHeadersImpl
|
|
|
|
const supabaseKey = 'test-key'
|
|
const getAccessToken = jest.fn().mockResolvedValue(null)
|
|
|
|
const authFetch = fetchWithAuth(supabaseKey, getAccessToken)
|
|
await authFetch('https://example.com')
|
|
|
|
expect(getAccessToken).toHaveBeenCalled()
|
|
})
|
|
|
|
test('should not override existing apikey header', async () => {
|
|
const mockResponse = { ok: true }
|
|
const mockFetchImpl = jest.fn().mockResolvedValue(mockResponse)
|
|
const mockSet = jest.fn()
|
|
const mockHeadersImpl = jest.fn().mockReturnValue({
|
|
has: jest.fn().mockImplementation((key) => key === 'apikey'),
|
|
set: mockSet,
|
|
})
|
|
|
|
;(global as any).fetch = mockFetchImpl
|
|
;(global as any).Headers = mockHeadersImpl
|
|
|
|
const supabaseKey = 'test-key'
|
|
const getAccessToken = jest.fn().mockResolvedValue('test-token')
|
|
|
|
const authFetch = fetchWithAuth(supabaseKey, getAccessToken)
|
|
await authFetch('https://example.com')
|
|
|
|
expect(mockSet).not.toHaveBeenCalledWith('apikey', supabaseKey)
|
|
})
|
|
|
|
test('should not override existing authorization header', async () => {
|
|
const mockResponse = { ok: true }
|
|
const mockFetchImpl = jest.fn().mockResolvedValue(mockResponse)
|
|
const mockSet = jest.fn()
|
|
const mockHeadersImpl = jest.fn().mockReturnValue({
|
|
has: jest.fn().mockImplementation((key) => key === 'Authorization'),
|
|
set: mockSet,
|
|
})
|
|
|
|
;(global as any).fetch = mockFetchImpl
|
|
;(global as any).Headers = mockHeadersImpl
|
|
|
|
const supabaseKey = 'test-key'
|
|
const getAccessToken = jest.fn().mockResolvedValue('test-token')
|
|
|
|
const authFetch = fetchWithAuth(supabaseKey, getAccessToken)
|
|
await authFetch('https://example.com')
|
|
|
|
expect(mockSet).not.toHaveBeenCalledWith('Authorization', expect.stringContaining('Bearer'))
|
|
})
|
|
})
|
|
})
|