Skip to content

Commit 89cd8ce

Browse files
chore: move compliance checker tests back to mono
1 parent 4970615 commit 89cd8ce

File tree

1 file changed

+177
-0
lines changed

1 file changed

+177
-0
lines changed
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import axios from 'axios';
2+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3+
4+
import {
5+
TEST_ACCOUNT_1_NATIVE_SEGWIT_ADDRESS,
6+
TEST_ACCOUNT_2_TAPROOT_ADDRESS,
7+
} from '@leather.io/bitcoin';
8+
9+
import { checkEntityAddressIsCompliant, isAddressCompliant } from './compliance-checker';
10+
11+
// Mock axios
12+
vi.mock('axios');
13+
14+
// Setup mock implementations before each test
15+
beforeEach(() => {
16+
vi.mocked(axios.post).mockClear().mockResolvedValue({ data: {} });
17+
vi.mocked(axios.get).mockClear().mockResolvedValue({ data: {} });
18+
});
19+
20+
describe('compliance-checker', () => {
21+
beforeEach(() => {
22+
vi.clearAllMocks();
23+
});
24+
25+
afterEach(() => {
26+
vi.resetAllMocks();
27+
});
28+
29+
it('should correctly identify a sanctioned address', async () => {
30+
// Mock the API responses with proper structure
31+
vi.mocked(axios.post).mockResolvedValueOnce({ data: { success: true } });
32+
vi.mocked(axios.get).mockResolvedValueOnce({
33+
data: {
34+
risk: 'Severe',
35+
},
36+
});
37+
38+
const address = TEST_ACCOUNT_2_TAPROOT_ADDRESS;
39+
const result = await checkEntityAddressIsCompliant({ address });
40+
41+
// Verify API calls
42+
expect(axios.post).toHaveBeenCalledTimes(1);
43+
expect(axios.get).toHaveBeenCalledTimes(1);
44+
45+
// Verify result
46+
expect(result).toEqual({
47+
risk: 'Severe',
48+
isOnSanctionsList: true,
49+
});
50+
});
51+
52+
it('should correctly identify a non-sanctioned address', async () => {
53+
// Mock the API responses
54+
vi.mocked(axios.post).mockResolvedValueOnce({ data: { success: true } });
55+
vi.mocked(axios.get).mockResolvedValueOnce({
56+
data: {
57+
risk: 'Low',
58+
},
59+
});
60+
61+
const address = TEST_ACCOUNT_1_NATIVE_SEGWIT_ADDRESS;
62+
const result = await checkEntityAddressIsCompliant({ address });
63+
64+
// Verify API calls
65+
expect(axios.post).toHaveBeenCalledTimes(1);
66+
expect(axios.get).toHaveBeenCalledTimes(1);
67+
68+
// Verify result
69+
expect(result).toEqual({
70+
risk: 'Low',
71+
isOnSanctionsList: false,
72+
});
73+
});
74+
75+
it('should handle API errors gracefully', async () => {
76+
// Mock API error
77+
vi.mocked(axios.post).mockRejectedValueOnce(new Error('API Error'));
78+
79+
const address = '1ErrorAddressSample';
80+
81+
await expect(checkEntityAddressIsCompliant({ address })).rejects.toThrow('API Error');
82+
83+
expect(axios.post).toHaveBeenCalledTimes(1);
84+
expect(axios.get).not.toHaveBeenCalled();
85+
});
86+
87+
it('should make the correct API calls with the provided address', async () => {
88+
// Mock the API responses
89+
vi.mocked(axios.post).mockResolvedValueOnce({ data: { success: true } });
90+
vi.mocked(axios.get).mockResolvedValueOnce({
91+
data: {
92+
risk: 'Medium',
93+
},
94+
});
95+
96+
const address = TEST_ACCOUNT_1_NATIVE_SEGWIT_ADDRESS;
97+
await checkEntityAddressIsCompliant({ address });
98+
99+
// Verify API calls with correct parameters
100+
expect(axios.post).toHaveBeenCalledWith(
101+
'https://api.chainalysis.com/api/risk/v2/entities',
102+
{ address },
103+
expect.any(Object)
104+
);
105+
106+
expect(axios.get).toHaveBeenCalledWith(
107+
`https://api.chainalysis.com/api/risk/v2/entities/${address}`,
108+
expect.any(Object)
109+
);
110+
});
111+
});
112+
113+
describe('isAddressCompliant', () => {
114+
it('should return true for a compliant address', async () => {
115+
const result = await isAddressCompliant({
116+
address: TEST_ACCOUNT_1_NATIVE_SEGWIT_ADDRESS,
117+
chain: 'mainnet',
118+
});
119+
expect(result).toBe(true);
120+
});
121+
122+
it('should return false for an address on the sanctions list', async () => {
123+
// Mock the API responses
124+
vi.mocked(axios.post).mockResolvedValueOnce({ data: { success: true } });
125+
vi.mocked(axios.get).mockResolvedValueOnce({
126+
data: {
127+
risk: 'Severe',
128+
},
129+
});
130+
131+
const address = '1SanctionedAddressSample';
132+
const result = await isAddressCompliant({
133+
address,
134+
chain: 'mainnet',
135+
});
136+
137+
expect(result).toBe(false);
138+
expect(axios.post).toHaveBeenCalledWith(
139+
'https://api.chainalysis.com/api/risk/v2/entities',
140+
{ address },
141+
expect.any(Object)
142+
);
143+
expect(axios.get).toHaveBeenCalledWith(
144+
`https://api.chainalysis.com/api/risk/v2/entities/${address}`,
145+
expect.any(Object)
146+
);
147+
});
148+
149+
it('should return true for a non-mainnet chain', async () => {
150+
const result = await isAddressCompliant({
151+
address: '1AnyAddressSample',
152+
chain: 'testnet',
153+
});
154+
expect(result).toBe(true);
155+
expect(axios.post).not.toHaveBeenCalled();
156+
expect(axios.get).not.toHaveBeenCalled();
157+
});
158+
159+
it('should return false if the compliance check fails', async () => {
160+
// Mock the API responses
161+
vi.mocked(axios.post).mockRejectedValueOnce(new Error('API Error'));
162+
163+
const address = '1ErrorAddressSample';
164+
const result = await isAddressCompliant({
165+
address,
166+
chain: 'mainnet',
167+
});
168+
169+
expect(result).toBe(false);
170+
expect(axios.post).toHaveBeenCalledWith(
171+
'https://api.chainalysis.com/api/risk/v2/entities',
172+
{ address },
173+
expect.any(Object)
174+
);
175+
expect(axios.get).not.toHaveBeenCalled();
176+
});
177+
});

0 commit comments

Comments
 (0)