Skip to content

Commit 249e3f3

Browse files
committed
Update unit tests
1 parent d509538 commit 249e3f3

File tree

1 file changed

+110
-40
lines changed

1 file changed

+110
-40
lines changed

__tests__/AppsFlyerRPC.test.js

Lines changed: 110 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,56 @@ jest.mock('../src/NativeAppsFlyerRPC', () => ({
1717
},
1818
}));
1919

20-
// Mock NativeEventEmitter
21-
jest.mock('react-native', () => ({
22-
Platform: {
23-
OS: 'ios',
24-
},
25-
NativeEventEmitter: jest.fn().mockImplementation(() => ({
26-
addListener: jest.fn((eventName, callback) => ({
27-
remove: jest.fn(),
20+
// Mock react-native with TurboModuleRegistry and NativeModules
21+
jest.mock('react-native', () => {
22+
const mockModule = {
23+
executeJson: jest.fn(),
24+
addListener: jest.fn(),
25+
removeListeners: jest.fn(),
26+
};
27+
28+
return {
29+
Platform: {
30+
OS: 'ios',
31+
},
32+
NativeEventEmitter: jest.fn().mockImplementation(() => ({
33+
addListener: jest.fn((eventName, callback) => ({
34+
remove: jest.fn(),
35+
})),
2836
})),
29-
})),
30-
}));
37+
TurboModuleRegistry: {
38+
get: jest.fn((name) => {
39+
if (name === 'RNAppsFlyerRPC') {
40+
return mockModule;
41+
}
42+
return null;
43+
}),
44+
},
45+
NativeModules: {
46+
RNAppsFlyerRPC: mockModule,
47+
},
48+
};
49+
});
3150

3251
import NativeAppsFlyerRPC from '../src/NativeAppsFlyerRPC';
52+
import { NativeModules, TurboModuleRegistry } from 'react-native';
3353

3454
describe('AppsFlyerRPC', () => {
55+
// Get the mock native module for setting up expectations
56+
const getMockNativeModule = () => {
57+
return TurboModuleRegistry.get('RNAppsFlyerRPC') || NativeModules.RNAppsFlyerRPC;
58+
};
59+
3560
beforeEach(() => {
3661
jest.clearAllMocks();
62+
// Reset the mock module's executeJson to return a default success response
63+
const mockModule = getMockNativeModule();
64+
if (mockModule) {
65+
mockModule.executeJson.mockResolvedValue(JSON.stringify({
66+
id: 'test-123',
67+
result: { success: true },
68+
}));
69+
}
3770
});
3871

3972
describe('Singleton Pattern', () => {
@@ -50,22 +83,24 @@ describe('AppsFlyerRPC', () => {
5083

5184
describe('RPC Request/Response Handling', () => {
5285
it('should execute RPC request successfully', async () => {
86+
const mockModule = getMockNativeModule();
5387
const mockResponse = JSON.stringify({
5488
id: 'test-123',
5589
result: { success: true, message: 'OK' },
5690
});
57-
NativeAppsFlyerRPC.executeJson.mockResolvedValue(mockResponse);
91+
mockModule.executeJson.mockResolvedValue(mockResponse);
5892

5993
const result = await AppsFlyerRPC.instance.initialize({
6094
devKey: 'test-key',
6195
appId: 'id123',
6296
});
6397

64-
expect(NativeAppsFlyerRPC.executeJson).toHaveBeenCalled();
98+
expect(mockModule.executeJson).toHaveBeenCalled();
6599
expect(result).toBeUndefined(); // initialize returns void
66100
});
67101

68102
it('should handle RPC error response', async () => {
103+
const mockModule = getMockNativeModule();
69104
const mockErrorResponse = JSON.stringify({
70105
id: 'test-123',
71106
error: {
@@ -74,7 +109,7 @@ describe('AppsFlyerRPC', () => {
74109
details: null,
75110
},
76111
});
77-
NativeAppsFlyerRPC.executeJson.mockResolvedValue(mockErrorResponse);
112+
mockModule.executeJson.mockResolvedValue(mockErrorResponse);
78113

79114
await expect(
80115
AppsFlyerRPC.instance.initialize({
@@ -85,15 +120,17 @@ describe('AppsFlyerRPC', () => {
85120
});
86121

87122
it('should throw error for null response', async () => {
88-
NativeAppsFlyerRPC.executeJson.mockResolvedValue(null);
123+
const mockModule = getMockNativeModule();
124+
mockModule.executeJson.mockResolvedValue(null);
89125

90126
await expect(
91127
AppsFlyerRPC.instance.setDebug(true)
92-
).rejects.toThrow('Null response from native');
128+
).rejects.toThrow('Empty response from native');
93129
});
94130

95131
it('should throw error for invalid JSON response', async () => {
96-
NativeAppsFlyerRPC.executeJson.mockResolvedValue('invalid json');
132+
const mockModule = getMockNativeModule();
133+
mockModule.executeJson.mockResolvedValue('invalid json');
97134

98135
await expect(
99136
AppsFlyerRPC.instance.setDebug(true)
@@ -121,30 +158,32 @@ describe('AppsFlyerRPC', () => {
121158

122159
describe('API Methods', () => {
123160
beforeEach(() => {
161+
const mockModule = getMockNativeModule();
124162
const mockSuccessResponse = JSON.stringify({
125163
id: 'test-123',
126164
result: { success: true },
127165
});
128-
NativeAppsFlyerRPC.executeJson.mockResolvedValue(mockSuccessResponse);
166+
mockModule.executeJson.mockResolvedValue(mockSuccessResponse);
129167
});
130168

131169
describe('initialize', () => {
132170
it('should call setPluginInfo and init', async () => {
171+
const mockModule = getMockNativeModule();
133172
await AppsFlyerRPC.instance.initialize({
134173
devKey: 'test-key',
135174
appId: 'id123',
136175
});
137176

138-
expect(NativeAppsFlyerRPC.executeJson).toHaveBeenCalledTimes(2);
177+
expect(mockModule.executeJson).toHaveBeenCalledTimes(2);
139178

140179
// First call: setPluginInfo
141-
const firstCall = NativeAppsFlyerRPC.executeJson.mock.calls[0][0];
180+
const firstCall = mockModule.executeJson.mock.calls[0][0];
142181
const firstRequest = JSON.parse(firstCall);
143182
expect(firstRequest.method).toBe('setPluginInfo');
144183
expect(firstRequest.params.plugin).toBe('react_native');
145184

146185
// Second call: init
147-
const secondCall = NativeAppsFlyerRPC.executeJson.mock.calls[1][0];
186+
const secondCall = mockModule.executeJson.mock.calls[1][0];
148187
const secondRequest = JSON.parse(secondCall);
149188
expect(secondRequest.method).toBe('init');
150189
expect(secondRequest.params.devKey).toBe('test-key');
@@ -154,9 +193,10 @@ describe('AppsFlyerRPC', () => {
154193

155194
describe('setDebug', () => {
156195
it('should call isDebug RPC method', async () => {
196+
const mockModule = getMockNativeModule();
157197
await AppsFlyerRPC.instance.setDebug(true);
158198

159-
const call = NativeAppsFlyerRPC.executeJson.mock.calls[0][0];
199+
const call = mockModule.executeJson.mock.calls[0][0];
160200
const request = JSON.parse(call);
161201
expect(request.method).toBe('isDebug');
162202
expect(request.params.isDebug).toBe(true);
@@ -165,52 +205,57 @@ describe('AppsFlyerRPC', () => {
165205

166206
describe('waitForATT', () => {
167207
it('should call waitForATT with default timeout', async () => {
208+
const mockModule = getMockNativeModule();
168209
await AppsFlyerRPC.instance.waitForATT();
169210

170-
const call = NativeAppsFlyerRPC.executeJson.mock.calls[0][0];
211+
const call = mockModule.executeJson.mock.calls[0][0];
171212
const request = JSON.parse(call);
172213
expect(request.method).toBe('waitForATT');
173214
expect(request.params.timeout).toBe(60);
174215
});
175216

176217
it('should call waitForATT with custom timeout', async () => {
218+
const mockModule = getMockNativeModule();
177219
await AppsFlyerRPC.instance.waitForATT({ timeout: 30 });
178220

179-
const call = NativeAppsFlyerRPC.executeJson.mock.calls[0][0];
221+
const call = mockModule.executeJson.mock.calls[0][0];
180222
const request = JSON.parse(call);
181223
expect(request.params.timeout).toBe(30);
182224
});
183225
});
184226

185227
describe('start', () => {
186228
it('should call start without awaitResponse', async () => {
229+
const mockModule = getMockNativeModule();
187230
await AppsFlyerRPC.instance.start();
188231

189-
const call = NativeAppsFlyerRPC.executeJson.mock.calls[0][0];
232+
const call = mockModule.executeJson.mock.calls[0][0];
190233
const request = JSON.parse(call);
191234
expect(request.method).toBe('start');
192235
expect(request.params.awaitResponse).toBeUndefined();
193236
});
194237

195238
it('should call start with awaitResponse', async () => {
239+
const mockModule = getMockNativeModule();
196240
const mockResponse = JSON.stringify({
197241
id: 'test-123',
198242
result: { data: { attribution: 'data' } },
199243
});
200-
NativeAppsFlyerRPC.executeJson.mockResolvedValue(mockResponse);
244+
mockModule.executeJson.mockResolvedValue(mockResponse);
201245

202246
const result = await AppsFlyerRPC.instance.start({ awaitResponse: true });
203247

204-
const call = NativeAppsFlyerRPC.executeJson.mock.calls[0][0];
248+
const call = mockModule.executeJson.mock.calls[0][0];
205249
const request = JSON.parse(call);
206250
expect(request.params.awaitResponse).toBe(true);
207251
expect(result).toEqual({ attribution: 'data' });
208252
});
209253

210254
it('startWithCallback should call start with awaitResponse', async () => {
255+
const mockModule = getMockNativeModule();
211256
await AppsFlyerRPC.instance.startWithCallback();
212257

213-
const call = NativeAppsFlyerRPC.executeJson.mock.calls[0][0];
258+
const call = mockModule.executeJson.mock.calls[0][0];
214259
const request = JSON.parse(call);
215260
expect(request.method).toBe('start');
216261
expect(request.params.awaitResponse).toBe(true);
@@ -219,31 +264,34 @@ describe('AppsFlyerRPC', () => {
219264

220265
describe('logEvent', () => {
221266
it('should log event without values', async () => {
267+
const mockModule = getMockNativeModule();
222268
await AppsFlyerRPC.instance.logEvent('test_event');
223269

224-
const call = NativeAppsFlyerRPC.executeJson.mock.calls[0][0];
270+
const call = mockModule.executeJson.mock.calls[0][0];
225271
const request = JSON.parse(call);
226272
expect(request.method).toBe('logEvent');
227273
expect(request.params.eventName).toBe('test_event');
228274
expect(request.params.eventValues).toBeUndefined();
229275
});
230276

231277
it('should log event with values', async () => {
278+
const mockModule = getMockNativeModule();
232279
await AppsFlyerRPC.instance.logEvent('test_event', {
233280
eventValues: { key: 'value' },
234281
});
235282

236-
const call = NativeAppsFlyerRPC.executeJson.mock.calls[0][0];
283+
const call = mockModule.executeJson.mock.calls[0][0];
237284
const request = JSON.parse(call);
238285
expect(request.params.eventValues).toEqual({ key: 'value' });
239286
});
240287

241288
it('should log event with awaitResponse', async () => {
289+
const mockModule = getMockNativeModule();
242290
const mockResponse = JSON.stringify({
243291
id: 'test-123',
244292
result: { data: { statusCode: 200 } },
245293
});
246-
NativeAppsFlyerRPC.executeJson.mockResolvedValue(mockResponse);
294+
mockModule.executeJson.mockResolvedValue(mockResponse);
247295

248296
const result = await AppsFlyerRPC.instance.logEvent('test_event', {
249297
eventValues: { key: 'value' },
@@ -256,21 +304,23 @@ describe('AppsFlyerRPC', () => {
256304
});
257305

258306
it('logEventWithCallback should call logEvent with awaitResponse', async () => {
307+
const mockModule = getMockNativeModule();
259308
await AppsFlyerRPC.instance.logEventWithCallback('test_event', {
260309
eventValues: { key: 'value' },
261310
});
262311

263-
const call = NativeAppsFlyerRPC.executeJson.mock.calls[0][0];
312+
const call = mockModule.executeJson.mock.calls[0][0];
264313
const request = JSON.parse(call);
265314
expect(request.params.awaitResponse).toBe(true);
266315
});
267316
});
268317

269318
describe('registerConversionListener', () => {
270319
it('should call registerConversionListener', async () => {
320+
const mockModule = getMockNativeModule();
271321
await AppsFlyerRPC.instance.registerConversionListener();
272322

273-
const call = NativeAppsFlyerRPC.executeJson.mock.calls[0][0];
323+
const call = mockModule.executeJson.mock.calls[0][0];
274324
const request = JSON.parse(call);
275325
expect(request.method).toBe('registerConversionListener');
276326
expect(request.params).toEqual({});
@@ -279,9 +329,10 @@ describe('AppsFlyerRPC', () => {
279329

280330
describe('registerDeepLinkListener', () => {
281331
it('should call registerDeeplinkListener', async () => {
332+
const mockModule = getMockNativeModule();
282333
await AppsFlyerRPC.instance.registerDeepLinkListener();
283334

284-
const call = NativeAppsFlyerRPC.executeJson.mock.calls[0][0];
335+
const call = mockModule.executeJson.mock.calls[0][0];
285336
const request = JSON.parse(call);
286337
expect(request.method).toBe('registerDeeplinkListener');
287338
expect(request.params).toEqual({});
@@ -319,15 +370,34 @@ describe('AppsFlyerRPC', () => {
319370
});
320371

321372
describe('Platform Support', () => {
322-
it('should throw error on Android', async () => {
373+
it('should work on both iOS and Android', async () => {
374+
// Test iOS
375+
Platform.OS = 'ios';
376+
const mockModule = getMockNativeModule();
377+
const mockResponse = JSON.stringify({
378+
id: 'test-123',
379+
result: { success: true },
380+
});
381+
mockModule.executeJson.mockResolvedValue(mockResponse);
382+
383+
await AppsFlyerRPC.instance.initialize({
384+
devKey: 'test-key',
385+
appId: 'id123',
386+
});
387+
388+
expect(mockModule.executeJson).toHaveBeenCalled();
389+
390+
// Test Android
323391
Platform.OS = 'android';
392+
jest.clearAllMocks();
393+
mockModule.executeJson.mockResolvedValue(mockResponse);
324394

325-
await expect(
326-
AppsFlyerRPC.instance.initialize({
327-
devKey: 'test-key',
328-
appId: 'com.test.app',
329-
})
330-
).rejects.toThrow('RPC is currently only supported on iOS');
395+
await AppsFlyerRPC.instance.initialize({
396+
devKey: 'test-key',
397+
appId: 'com.test.app',
398+
});
399+
400+
expect(mockModule.executeJson).toHaveBeenCalled();
331401

332402
Platform.OS = 'ios'; // Reset
333403
});

0 commit comments

Comments
 (0)