import { vi, expect, describe, test, beforeEach, afterEach } from 'vitest'; import { UserOperation } from '@prex0/prex-structs'; import { PrexApiService } from './api'; describe('PrexApiService', () => { const paymasterAndData = '0x001122334455'; beforeEach(async () => { vi.spyOn(global, 'fetch').mockImplementation( async (input: string | URL | Request) => { const url = input.toString(); if (url.includes('200')) { if (url.includes('get-paymaster-sig')) { return new Response(JSON.stringify({ paymasterAndData }), { status: 200, }); } else { return new Response('"ok"', { status: 200 }); } } else if (url.includes('400')) { return new Response(JSON.stringify({ message: 'error' }), { status: 400, }); } else { return new Response(JSON.stringify({ message: 'error' }), { status: 500, }); } } ); }); afterEach(() => { vi.restoreAllMocks(); }); const ruleId = '1'; const apiService200 = new PrexApiService(1, ruleId, 'http://test.com/200', { maxRetries: 1, }); const apiService400 = new PrexApiService(1, ruleId, 'http://test.com/400', { maxRetries: 1, }); const apiService500 = new PrexApiService(1, ruleId, 'http://test.com/500', { maxRetries: 0, }); describe('register', () => { test('succeed', async () => { const result = await apiService200.register('1', {} as any); expect(result).toBe('ok'); }); test('bad request', async () => { expect(async () => { await apiService400.register('1', {} as any); }).rejects.toThrowError('{"message":"error"}'); }); test('server error', async () => { expect(async () => { await apiService500.register('1', {} as any); }).rejects.toThrowError('{"message":"error"}'); }); }); describe('transfer', () => { test('succeed', async () => { const result = await apiService200.transfer('type', 'sig'); expect(result).toBe('ok'); }); test('bad request', async () => { expect(async () => { await apiService400.transfer('type', 'sig'); }).rejects.toThrowError('{"message":"error"}'); }); test('server error', async () => { expect(async () => { await apiService500.transfer('type', 'sig'); }).rejects.toThrowError('{"message":"error"}'); }); }); const userOperation = new UserOperation( { sender: '0x1234567890abcdef1234567890abcdef12345678', nonce: 1n, initCode: '0x', callData: '0x', callGasLimit: 1n, verificationGasLimit: 1n, preVerificationGas: 1n, maxFeePerGas: 1n, maxPriorityFeePerGas: 1n, paymasterAndData: '0x1234567890abcdef1234567890abcdef12345678', }, 1n ); describe('signPaymasterAndData', () => { test('succeed', async () => { const result = await apiService200.signPaymasterAndData(userOperation); expect(result).toBe(paymasterAndData); }); test('bad request', async () => { expect(async () => { await apiService400.signPaymasterAndData(userOperation); }).rejects.toThrowError('{"message":"error"}'); }); test('server error', async () => { expect(async () => { await apiService500.signPaymasterAndData(userOperation); }).rejects.toThrowError('{"message":"error"}'); }); }); describe('execute', () => { test('succeed', async () => { const result = await apiService200.execute( userOperation, '0x001122334455' ); expect(result).toBe('ok'); }); test('bad request', async () => { expect(async () => { await apiService400.execute(userOperation, '0x001122334455'); }).rejects.toThrowError('{"message":"error"}'); }); test('server error', async () => { expect(async () => { await apiService500.execute(userOperation, '0x001122334455'); }).rejects.toThrowError('{"message":"error"}'); }); }); });