/** * Compliance Service Tests */ import { describe, it, expect, vi, beforeEach } from 'vitest'; import { ComplianceService, getComplianceService } from './compliance'; import fetch from 'node-fetch'; vi.mock('node-fetch'); describe('ComplianceService', () => { let service: ComplianceService; const subjectDid = 'did:web:example.com:subject-1'; const subjectData = { name: 'Test User', email: 'test@example.com', phone: '+1234567890', address: '123 Test St', dateOfBirth: '1990-01-01', nationality: 'US', }; beforeEach(() => { service = new ComplianceService(); vi.clearAllMocks(); }); describe('performComplianceChecks', () => { it('should perform all compliance checks', async () => { // Mock KYC check (fetch as any).mockResolvedValueOnce({ ok: true, json: async () => ({ verified: true }), }); // Mock AML check (fetch as any).mockResolvedValueOnce({ ok: true, json: async () => ({ cleared: true }), }); // Mock Sanctions check (fetch as any).mockResolvedValueOnce({ ok: true, json: async () => ({ match: false }), }); const result = await service.performComplianceChecks(subjectDid, subjectData); expect(result.passed).toBe(true); expect(result.checks).toHaveLength(4); // KYC, AML, Sanctions, Identity expect(result.riskScore).toBeLessThan(70); }); it('should fail on sanctions match', async () => { // Mock KYC check (fetch as any).mockResolvedValueOnce({ ok: true, json: async () => ({ verified: true }), }); // Mock AML check (fetch as any).mockResolvedValueOnce({ ok: true, json: async () => ({ cleared: true }), }); // Mock Sanctions check - MATCH (fetch as any).mockResolvedValueOnce({ ok: true, json: async () => ({ match: true, matches: [{ name: 'Test User' }] }), }); const result = await service.performComplianceChecks(subjectDid, subjectData); expect(result.passed).toBe(false); expect(result.riskScore).toBeGreaterThanOrEqual(70); expect(result.checks.some((c) => c.name === 'Sanctions Check' && !c.passed)).toBe( true ); }); it('should fail on high risk score', async () => { // Mock all checks to fail (fetch as any) .mockResolvedValueOnce({ ok: true, json: async () => ({ verified: false }), }) .mockResolvedValueOnce({ ok: true, json: async () => ({ cleared: false, riskLevel: 'high' }), }) .mockResolvedValueOnce({ ok: true, json: async () => ({ match: false }), }); const result = await service.performComplianceChecks(subjectDid, subjectData); expect(result.passed).toBe(false); expect(result.riskScore).toBeGreaterThanOrEqual(70); }); it('should use fallback when providers not configured', async () => { const serviceWithoutProviders = new ComplianceService({ enableKYC: true, enableAML: false, enableSanctions: false, enableIdentityVerification: true, kycProvider: undefined, // No provider configured }); const result = await serviceWithoutProviders.performComplianceChecks( subjectDid, subjectData ); // Should use fallback validation for KYC and identity verification expect(result.checks.length).toBeGreaterThanOrEqual(2); // KYC should pass with fallback (has required fields) expect(result.checks.find((c) => c.name === 'KYC Check')?.passed).toBe(true); }); }); describe('getComplianceService', () => { it('should return singleton instance', () => { const service1 = getComplianceService(); const service2 = getComplianceService(); expect(service1).toBe(service2); }); }); });