2.3 KiB
2.3 KiB
Testing Extensions
Vitest, same patterns as core. Tests colocated in __tests__/ next to extension files.
Setup
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { eventBus } from '@/lib/events/bus'
vi.mock('@/lib/supabase/server', () => ({ createClient: vi.fn() }))
vi.mock('@/lib/init', () => ({ ensureInitialized: vi.fn() }))
beforeEach(() => { vi.clearAllMocks(); eventBus.clear() })
Mock Context
const mockCtx: ExtensionContext = {
userId: 'user-123', extensionId: 'my-extension',
supabase: createMockSupabase() as any,
emit: vi.fn(),
settings: { get: vi.fn().mockResolvedValue({ featureEnabled: true }), set: vi.fn() },
storage: { download: vi.fn(), upload: vi.fn(), getPublicUrl: vi.fn() },
log: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
services: { ingestTransactions: vi.fn() },
}
Testing Event Handlers
it('should process events', async () => {
const handler = myExt.eventHandlers!.find(h => h.eventType === 'transaction.synced')!.handler
await handler({ transactions: [makeTransaction()], userId: 'user-123' }, mockCtx)
expect(mockCtx.supabase.from).toHaveBeenCalled()
})
it('should skip when disabled', async () => {
mockCtx.settings.get = vi.fn().mockResolvedValue({ featureEnabled: false })
const handler = myExt.eventHandlers!.find(h => h.eventType === 'transaction.synced')!.handler
await handler({ transactions: [], userId: 'user-123' }, mockCtx)
expect(mockCtx.supabase.from).not.toHaveBeenCalled()
})
Testing API Routes
const handler = myExtApiRoutes.find(r => r.method === 'GET' && r.path === '/')!.handler
const request = createMockRequest('GET', '/api/extensions/ext/my-extension/')
const response = await handler(request, mockCtx)
expect(response.status).toBe(200)
Test Helpers (tests/helpers.ts)
createMockSupabase(), createQueuedMockSupabase(), createMockRequest(method, url, body?), parseJsonResponse(response), makeTransaction(), makeJournalEntry(), makeInvoice(), makeCustomer(), makeSupplier(), makeReceipt(), makeDocumentAttachment(), makeCompanySettings()
Running
npm test # All tests
npx vitest run extensions/general/my-extension # Specific extension