forked from Nutlope/turboseek
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathjest.setup.ts
150 lines (133 loc) · 3.75 KB
/
jest.setup.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import '@testing-library/jest-dom';
import { TextDecoder, TextEncoder } from 'util';
import { Connection } from '@solana/web3.js';
// Polyfills for Next.js and Web APIs
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;
// Mock Response, Request, and Headers for fetch API
export class MockResponse {
private body: string;
public status: number;
public statusText: string;
public headers: Headers;
public ok: boolean;
constructor(body: string | object, init?: { status?: number; statusText?: string; headers?: Record<string, string> }) {
this.body = typeof body === 'string' ? body : JSON.stringify(body);
this.status = init?.status ?? 200;
this.statusText = init?.statusText ?? '';
this.headers = new Headers(init?.headers);
this.ok = this.status >= 200 && this.status < 300;
}
json() {
return Promise.resolve(JSON.parse(this.body));
}
text() {
return Promise.resolve(this.body);
}
}
global.Response = MockResponse as any;
global.Headers = class Headers {
private headers: Record<string, string>;
constructor(init?: Record<string, string>) {
this.headers = init || {};
}
get(name: string): string | null {
return this.headers[name.toLowerCase()] || null;
}
set(name: string, value: string): void {
this.headers[name.toLowerCase()] = value;
}
} as any;
// Mock Next.js router
jest.mock('next/navigation', () => ({
useRouter: () => ({
push: jest.fn(),
replace: jest.fn(),
prefetch: jest.fn(),
back: jest.fn(),
}),
useSearchParams: () => new URLSearchParams(),
usePathname: () => '',
}));
// Mock Solana Connection
jest.mock('@solana/web3.js', () => ({
Connection: jest.fn().mockImplementation(() => ({
getBlockHeight: jest.fn().mockResolvedValue(100),
getProgramAccounts: jest.fn().mockResolvedValue([]),
})),
PublicKey: jest.fn().mockImplementation((key) => ({
toString: () => key,
toBase58: () => key,
})),
}));
// Mock rate limiter
jest.mock('@/lib/rate-limit', () => ({
rateLimit: () => ({
check: jest.fn().mockResolvedValue(true),
}),
}));
// Test utilities
export const TEST_ENDPOINTS = {
local: 'http://localhost:8899',
devnet: 'https://api.devnet.solana.com',
mockRPC: 'mock://solana',
};
export const fixtures = {
nftCollections: [
{
address: 'DGNAqCCHypUq5kQhRhxXpUj9H1yBj7iGZUmDgqJBVhMV',
name: 'Degen Apes',
symbol: 'DAPE',
mintDate: '2025-01-27',
image: 'https://example.com/dape.png',
},
{
address: 'SMNKqxEVjmqmEuEYHzKVTKLPGWpwHkxRTxkGJhBhxVi',
name: 'Solana Monke',
symbol: 'SMONK',
mintDate: '2025-01-26',
image: 'https://example.com/smonk.png',
},
],
tokenDetails: {
decimals: 9,
supply: '1000000000',
volume: '50000',
},
};
// Mock fetch globally
global.fetch = jest.fn() as jest.MockedFunction<typeof fetch>;
export const mockNetworkConditions = {
offline: () => {
(global.fetch as jest.Mock).mockRejectedValue(new Error('Network error'));
},
slow: () => {
(global.fetch as jest.Mock).mockImplementation(
() => new Promise((resolve) => setTimeout(() => {
resolve(new MockResponse({}, {
status: 200,
headers: { 'Content-Type': 'application/json' },
}));
}, 2000))
);
},
normal: () => {
(global.fetch as jest.Mock).mockResolvedValue(
new MockResponse({}, {
status: 200,
headers: { 'Content-Type': 'application/json' },
})
);
},
};
// Custom matchers
expect.extend({
toMatchPerformanceMetrics(received, expected, tolerance = 0.05) {
const pass = Math.abs(received - expected) <= expected * tolerance;
return {
pass,
message: () =>
`expected ${received} to be within ${tolerance * 100}% of ${expected}`,
};
},
});