Skip to content

Commit 3cb92cc

Browse files
chore: add network obfuscation and filtering unit tests
1 parent a9d0cec commit 3cb92cc

File tree

8 files changed

+142
-7
lines changed

8 files changed

+142
-7
lines changed

android/native.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
project.ext.instabug = [
2-
version: '13.4.1.6273165-SNAPSHOT'
2+
version: '14.0.0.6273213-SNAPSHOT'
33
]
44

55
dependencies {

examples/default/android/build.gradle

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ buildscript {
44
ext {
55
buildToolsVersion = "33.0.0"
66
minSdkVersion = 21
7-
compileSdkVersion = 33
8-
targetSdkVersion = 33
7+
compileSdkVersion = 34
8+
targetSdkVersion = 34
99
kotlinVersion = "1.7.10"
1010

1111
// We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
@@ -26,7 +26,8 @@ buildscript {
2626
classpath("com.android.tools.build:gradle")
2727
classpath("com.facebook.react:react-native-gradle-plugin")
2828
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
29-
classpath 'com.instabug.library:instabug-plugin:13.4.1.6273165-SNAPSHOT'
29+
classpath 'com.instabug.library:instabug-plugin:14.0.0.6273213-SNAPSHOT'
30+
3031
}
3132
}
3233

examples/default/ios/Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,6 @@ SPEC CHECKSUMS:
758758
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
759759
Yoga: 8796b55dba14d7004f980b54bcc9833ee45b28ce
760760

761-
PODFILE CHECKSUM: c4e288aeafe746a77427798d0e33069c948e4b76
761+
PODFILE CHECKSUM: 2859b36546d44408bcfd30e23db5e6bb05548a0c
762762

763763
COCOAPODS: 1.15.2

src/modules/NetworkLogger.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,19 @@ export const apolloLinkRequestHandler: RequestHandler = (operation, forward) =>
146146
return forward(operation);
147147
};
148148

149+
/**
150+
* @internal
151+
* Exported for internal/testing purposes only.
152+
*/
153+
export function registerNetworkLogsListener(
154+
type: NetworkListenerType,
155+
handler?: (networkSnapshot: NetworkData) => void,
156+
) {
157+
if (process.env.NODE_ENV === 'test') {
158+
_registerNetworkLogsListener(type, handler);
159+
}
160+
}
161+
149162
const _registerNetworkLogsListener = (
150163
type: NetworkListenerType,
151164
handler?: (networkSnapshot: NetworkData) => void,

test/mocks/mockNetworkLogger.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ const mockNetworkLogger: NetworkLoggerNativeModule = {
55
removeListeners: jest.fn(),
66
hasAPMNetworkPlugin: jest.fn(),
77
isNativeInterceptionEnabled: jest.fn(),
8+
forceStartNetworkLoggingIOS: jest.fn(),
9+
forceStopNetworkLoggingIOS: jest.fn(),
10+
registerNetworkLogsListener: jest.fn(),
11+
updateNetworkLogSnapshot: jest.fn(),
12+
setNetworkLoggingRequestFilterPredicateIOS: jest.fn(),
813
};
914

1015
export default mockNetworkLogger;

test/modules/Instabug.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -926,7 +926,7 @@ describe('Instabug iOS initialization tests', () => {
926926
await Instabug.init(config);
927927

928928
expect(NativeNetworkLogger.isNativeInterceptionEnabled).toHaveBeenCalled();
929-
expect(NetworkLogger.setEnabled).not.toHaveBeenCalled();
929+
expect(NetworkLogger.setEnabled).toHaveBeenCalledWith(false);
930930
expect(NativeInstabug.init).toHaveBeenCalledWith(
931931
config.token,
932932
config.invocationEvents,

test/modules/NetworkLogger.spec.ts

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,21 @@ import Interceptor from '../../src/utils/XhrNetworkInterceptor';
88
import { isContentTypeNotAllowed, reportNetworkLog } from '../../src/utils/InstabugUtils';
99
import InstabugConstants from '../../src/utils/InstabugConstants';
1010
import * as Instabug from '../../src/modules/Instabug';
11-
import { NativeNetworkLogger } from '../../src/native/NativeNetworkLogger';
11+
import {
12+
NativeNetworkLogger,
13+
NativeNetworkLoggerEvent,
14+
NetworkListenerType,
15+
NetworkLoggerEmitter,
16+
} from '../../src/native/NativeNetworkLogger';
1217
import { InvocationEvent, LogLevel, NetworkInterceptionMode } from '../../src';
1318
import { Platform } from 'react-native';
1419

1520
const clone = <T>(obj: T): T => {
1621
return JSON.parse(JSON.stringify(obj));
1722
};
1823

24+
jest.mock('../../src/native/NativeNetworkLogger');
25+
1926
describe('NetworkLogger Module', () => {
2027
const network: NetworkLogger.NetworkData = {
2128
id: '',
@@ -312,3 +319,111 @@ describe('NetworkLogger Module', () => {
312319
expect(NativeNetworkLogger.hasAPMNetworkPlugin).toHaveBeenCalled();
313320
});
314321
});
322+
323+
describe('_registerNetworkLogsListener', () => {
324+
let handlerMock: jest.Mock;
325+
let type: NetworkListenerType;
326+
327+
beforeEach(() => {
328+
jest.resetModules(); // Clear cached modules and reload
329+
jest.resetAllMocks(); // Reset mock implementation and calls
330+
jest.clearAllMocks(); // Clear only calls, keeping implementation intact
331+
});
332+
333+
afterEach(() => {
334+
handlerMock = jest.fn();
335+
type = NetworkListenerType.both;
336+
// Make sure to clean up listeners to avoid side effects
337+
NetworkLoggerEmitter.removeAllListeners(NativeNetworkLoggerEvent.NETWORK_LOGGER_HANDLER);
338+
});
339+
340+
it('should ignore repetitive calls with the same type', () => {
341+
// Simulate existing listener
342+
jest.spyOn(NetworkLoggerEmitter, 'listenerCount').mockReturnValue(1);
343+
NetworkLogger.registerNetworkLogsListener(type, handlerMock);
344+
345+
// Call again with the same type to ensure it does nothing
346+
NetworkLogger.registerNetworkLogsListener(type, handlerMock);
347+
348+
expect(NetworkLoggerEmitter.removeAllListeners).toHaveBeenCalledTimes(1);
349+
expect(NetworkLoggerEmitter.addListener).toHaveBeenCalledTimes(1);
350+
expect(NativeNetworkLogger.registerNetworkLogsListener).toHaveBeenCalledTimes(1);
351+
});
352+
353+
it('should remove old listeners if they exist', () => {
354+
// Simulate that there are existing listeners
355+
jest.spyOn(NetworkLoggerEmitter, 'listenerCount').mockReturnValue(2);
356+
357+
NetworkLogger.registerNetworkLogsListener(type, handlerMock);
358+
359+
expect(NetworkLoggerEmitter.removeAllListeners).toHaveBeenCalledWith(
360+
NativeNetworkLoggerEvent.NETWORK_LOGGER_HANDLER,
361+
);
362+
});
363+
364+
it('should set the new listener if _networkListener is null', () => {
365+
// No existing listener
366+
jest.spyOn(NetworkLoggerEmitter, 'listenerCount').mockReturnValue(0);
367+
368+
NetworkLogger.registerNetworkLogsListener(type, handlerMock);
369+
370+
expect(NetworkLoggerEmitter.addListener).toHaveBeenCalled();
371+
expect(NativeNetworkLogger.registerNetworkLogsListener).toHaveBeenCalledWith(type);
372+
});
373+
374+
it('should attach a new listener to the existing one if _networkListener is set', () => {
375+
type = NetworkListenerType.filtering;
376+
const newType = NetworkListenerType.both;
377+
378+
// First call to set the listener
379+
NetworkLogger.registerNetworkLogsListener(type, handlerMock);
380+
381+
// Second call with a different type to trigger setting to `both`
382+
NetworkLogger.registerNetworkLogsListener(newType, handlerMock);
383+
384+
expect(NetworkLoggerEmitter.addListener).toHaveBeenCalledTimes(2);
385+
expect(NativeNetworkLogger.registerNetworkLogsListener).toHaveBeenCalledWith(
386+
NetworkListenerType.both,
387+
);
388+
});
389+
390+
it('should map networkSnapshot data correctly and call handler', () => {
391+
const mockNetworkSnapshot = {
392+
id: '123',
393+
url: 'http://example.com',
394+
requestHeader: {},
395+
requestBody: 'test request body',
396+
responseHeader: {},
397+
response: 'test response',
398+
responseCode: 200,
399+
};
400+
401+
(NetworkLoggerEmitter.addListener as jest.Mock).mockImplementation((_, callback) => {
402+
callback(mockNetworkSnapshot);
403+
});
404+
405+
NetworkLogger.registerNetworkLogsListener(type, handlerMock);
406+
407+
const expectedNetworkData: NetworkLogger.NetworkData = {
408+
id: '123',
409+
url: 'http://example.com',
410+
requestBody: 'test request body',
411+
requestHeaders: {},
412+
method: '',
413+
responseBody: 'test response',
414+
responseCode: 200,
415+
responseHeaders: {},
416+
contentType: '',
417+
duration: 0,
418+
requestBodySize: 0,
419+
responseBodySize: 0,
420+
errorDomain: '',
421+
errorCode: 0,
422+
startTime: 0,
423+
serverErrorMessage: '',
424+
requestContentType: '',
425+
};
426+
427+
expect(handlerMock).toHaveBeenCalledWith(expectedNetworkData);
428+
});
429+
});

test/utils/InstabugUtils.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ describe('Instabug Utils', () => {
243243

244244
describe('reportNetworkLog', () => {
245245
const network: NetworkData = {
246+
id: 'id',
246247
url: 'https://api.instabug.com',
247248
method: 'GET',
248249
requestBody: 'requestBody',

0 commit comments

Comments
 (0)