|
3 | 3 | // expect(element).toHaveTextContent(/react/i) |
4 | 4 | // learn more: https://github.com/testing-library/jest-dom |
5 | 5 | import '@testing-library/jest-dom'; |
6 | | - |
7 | | -// Polyfill for TextEncoder/TextDecoder in Jest |
8 | | -global.TextEncoder = require('util').TextEncoder; |
9 | | -global.TextDecoder = require('util').TextDecoder; |
10 | | - |
11 | | -// Mock crypto for tests |
12 | | -Object.defineProperty(global, 'crypto', { |
13 | | - value: { |
14 | | - getRandomValues: jest.fn((arr) => { |
15 | | - for (let i = 0; i < arr.length; i++) { |
16 | | - arr[i] = Math.floor(Math.random() * 256); |
17 | | - } |
18 | | - return arr; |
19 | | - }), |
20 | | - subtle: { |
21 | | - digest: jest.fn(), |
22 | | - encrypt: jest.fn(), |
23 | | - decrypt: jest.fn(), |
24 | | - }, |
25 | | - }, |
26 | | -}); |
27 | | - |
28 | | -// Mock clipboard API |
29 | | -Object.defineProperty(navigator, 'clipboard', { |
30 | | - value: { |
31 | | - writeText: jest.fn(() => Promise.resolve()), |
32 | | - readText: jest.fn(() => Promise.resolve('')), |
33 | | - }, |
34 | | -}); |
35 | | - |
36 | | -// Mock ResizeObserver |
37 | | -global.ResizeObserver = jest.fn().mockImplementation(() => ({ |
38 | | - observe: jest.fn(), |
39 | | - unobserve: jest.fn(), |
40 | | - disconnect: jest.fn(), |
41 | | -})); |
42 | | - |
43 | | -// Mock matchMedia |
44 | | -Object.defineProperty(window, 'matchMedia', { |
45 | | - writable: true, |
46 | | - value: jest.fn().mockImplementation(query => ({ |
47 | | - matches: false, |
48 | | - media: query, |
49 | | - onchange: null, |
50 | | - addListener: jest.fn(), // deprecated |
51 | | - removeListener: jest.fn(), // deprecated |
52 | | - addEventListener: jest.fn(), |
53 | | - removeEventListener: jest.fn(), |
54 | | - dispatchEvent: jest.fn(), |
55 | | - })), |
56 | | -}); |
57 | | - |
58 | | -// Mock URL.createObjectURL |
59 | | -global.URL.createObjectURL = jest.fn(() => 'blob:mock-url'); |
60 | | -global.URL.revokeObjectURL = jest.fn(); |
61 | | - |
62 | | -// Mock crypto libraries to avoid flakiness |
63 | | -jest.mock('tweetnacl', () => { |
64 | | - const mockSecretbox = jest.fn((plaintext, nonce, key) => new Uint8Array(plaintext.length + 16)); |
65 | | - mockSecretbox.open = jest.fn((ciphertext, nonce, key) => new Uint8Array(ciphertext.length - 16)); |
66 | | - mockSecretbox.nonceLength = 24; |
67 | | - |
68 | | - return { |
69 | | - secretbox: mockSecretbox, |
70 | | - randomBytes: jest.fn((length) => { |
71 | | - const array = new Uint8Array(length); |
72 | | - for (let i = 0; i < length; i++) { |
73 | | - array[i] = Math.floor(Math.random() * 256); |
74 | | - } |
75 | | - return array; |
76 | | - }), |
77 | | - }; |
78 | | -}); |
79 | | - |
80 | | -jest.mock('argon2-browser', () => ({ |
81 | | - hash: jest.fn(() => Promise.resolve({ |
82 | | - hash: new Uint8Array(32), |
83 | | - encoded: 'mock-encoded-hash' |
84 | | - })), |
85 | | - ArgonType: { |
86 | | - Argon2id: 2, |
87 | | - }, |
88 | | -})); |
89 | | - |
90 | | -jest.mock('scrypt-js', () => jest.fn((password, salt, N, r, p, keylen, callback) => { |
91 | | - callback(null, new Uint8Array(keylen)); |
92 | | -})); |
93 | | -jest.mock('@solana/web3.js', () => { |
94 | | - const mockPublicKey = { |
95 | | - toBase58: jest.fn(() => 'mock-public-key'), |
96 | | - toString: jest.fn(() => 'mock-public-key'), |
97 | | - equals: jest.fn(() => false), |
98 | | - toJSON: jest.fn(() => 'mock-public-key'), |
99 | | - toBytes: jest.fn(() => new Uint8Array(32)), |
100 | | - toBuffer: jest.fn(() => Buffer.alloc(32)), |
101 | | - isOnCurve: jest.fn(() => true), |
102 | | - }; |
103 | | - |
104 | | - return { |
105 | | - PublicKey: jest.fn().mockImplementation(() => mockPublicKey), |
106 | | - Connection: jest.fn().mockImplementation(() => ({ |
107 | | - getAccountInfo: jest.fn(() => Promise.resolve(null)), |
108 | | - getBalance: jest.fn(() => Promise.resolve(0)), |
109 | | - getBlockHeight: jest.fn(() => Promise.resolve(100000)), |
110 | | - getSlot: jest.fn(() => Promise.resolve(100000)), |
111 | | - getEpochInfo: jest.fn(() => Promise.resolve({ |
112 | | - epoch: 500, |
113 | | - slotIndex: 1000, |
114 | | - slotsInEpoch: 432000, |
115 | | - })), |
116 | | - getRecentPerformanceSamples: jest.fn(() => Promise.resolve([])), |
117 | | - })), |
118 | | - Transaction: jest.fn().mockImplementation(() => ({ |
119 | | - add: jest.fn(), |
120 | | - sign: jest.fn(), |
121 | | - serialize: jest.fn(() => Buffer.alloc(10)), |
122 | | - })), |
123 | | - SystemProgram: { |
124 | | - transfer: jest.fn(() => ({})), |
125 | | - }, |
126 | | - LAMPORTS_PER_SOL: 1000000000, |
127 | | - }; |
128 | | -}); |
129 | | - |
130 | | -// Mock SVM-Pay to avoid network calls in tests |
131 | | -jest.mock('svm-pay', () => ({ |
132 | | - SVMPay: jest.fn().mockImplementation(() => ({ |
133 | | - generatePaymentURL: jest.fn(() => 'mock-payment-url'), |
134 | | - validatePaymentURL: jest.fn(() => Promise.resolve(true)), |
135 | | - processPayment: jest.fn(() => Promise.resolve({ signature: 'mock-signature' })), |
136 | | - getSupportedNetworks: jest.fn(() => ['solana', 'sonic', 'eclipse']), |
137 | | - })), |
138 | | -})); |
139 | | - |
140 | | -// Mock QR Code generation to avoid rendering issues |
141 | | -jest.mock('qrcode.react', () => ({ |
142 | | - QRCodeSVG: jest.fn(({ value }) => { |
143 | | - return `<svg data-testid="qr-code" data-value="${value}">Mock QR Code</svg>`; |
144 | | - }), |
145 | | -})); |
146 | | - |
147 | | -// Mock browser storage APIs |
148 | | -const mockStorage = { |
149 | | - getItem: jest.fn((key) => null), |
150 | | - setItem: jest.fn(), |
151 | | - removeItem: jest.fn(), |
152 | | - clear: jest.fn(), |
153 | | - length: 0, |
154 | | - key: jest.fn(), |
155 | | -}; |
156 | | - |
157 | | -Object.defineProperty(window, 'localStorage', { |
158 | | - value: mockStorage, |
159 | | -}); |
160 | | - |
161 | | -Object.defineProperty(window, 'sessionStorage', { |
162 | | - value: mockStorage, |
163 | | -}); |
164 | | - |
165 | | -// Mock fetch for network requests |
166 | | -global.fetch = jest.fn(() => |
167 | | - Promise.resolve({ |
168 | | - ok: true, |
169 | | - status: 200, |
170 | | - json: () => Promise.resolve({}), |
171 | | - text: () => Promise.resolve(''), |
172 | | - }) |
173 | | -); |
174 | | - |
175 | | -// Mock Intersection Observer for animation triggers |
176 | | -global.IntersectionObserver = jest.fn().mockImplementation(() => ({ |
177 | | - observe: jest.fn(), |
178 | | - unobserve: jest.fn(), |
179 | | - disconnect: jest.fn(), |
180 | | -})); |
181 | | - |
182 | | -// Mock window.opener for popup detection |
183 | | -Object.defineProperty(window, 'opener', { |
184 | | - value: null, |
185 | | - writable: true, |
186 | | -}); |
187 | | - |
188 | | -// Mock BeforeInstallPrompt event for PWA testing |
189 | | -global.BeforeInstallPromptEvent = class { |
190 | | - constructor() { |
191 | | - this.platforms = ['web']; |
192 | | - this.userChoice = Promise.resolve({ outcome: 'dismissed', platform: 'web' }); |
193 | | - } |
194 | | - |
195 | | - prompt() { |
196 | | - return Promise.resolve(); |
197 | | - } |
198 | | - |
199 | | - preventDefault() {} |
200 | | -}; |
0 commit comments