Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@
"require": "./lib/commonjs/index.js",
"types": "./lib/typescript/index.d.ts"
},
"./internal": {
Comment thread
sameerank marked this conversation as resolved.
Resolved
"import": "./lib/module/internal.js",
"require": "./lib/commonjs/internal.js",
"types": "./lib/typescript/internal.d.ts"
Comment thread
cdn34dd marked this conversation as resolved.
Resolved
},
"./metro": {
"import": "./lib/module/metro.js",
"require": "./lib/commonjs/metro.js",
Expand Down
42 changes: 23 additions & 19 deletions packages/core/src/__tests__/DdSdkReactNative.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { AttributesSingleton } from '../sdk/AttributesSingleton/AttributesSingle
import { DdSdkWrapper } from '../sdk/DdSdkInternal';
import { GlobalState } from '../sdk/GlobalState/GlobalState';
import { UserInfoSingleton } from '../sdk/UserInfoSingleton/UserInfoSingleton';
import NativeDdSdkSpec from '../specs/NativeDdSdk';
import { getNativeDdSdk } from '../specs/NativeDdSdk';
import type { LogEvent } from '../types';
import { ErrorSource } from '../types';
import { version as sdkVersion } from '../version';
Expand Down Expand Up @@ -1318,8 +1318,8 @@ describe('DdSdkReactNative', () => {
await DdSdkReactNative.addAttribute(key, value);

// THEN
expect(NativeDdSdkSpec.addAttribute).toHaveBeenCalledTimes(1);
expect(NativeDdSdkSpec.addAttribute).toHaveBeenCalledWith(key, {
expect(getNativeDdSdk()?.addAttribute).toHaveBeenCalledTimes(1);
expect(getNativeDdSdk()?.addAttribute).toHaveBeenCalledWith(key, {
value
});
expect(AttributesSingleton.getInstance().getAttribute(key)).toEqual(
Expand All @@ -1339,8 +1339,8 @@ describe('DdSdkReactNative', () => {
await DdSdkReactNative.removeAttribute(key);

// THEN
expect(NativeDdSdkSpec.removeAttribute).toHaveBeenCalledTimes(1);
expect(NativeDdSdkSpec.removeAttribute).toHaveBeenCalledWith(key);
expect(getNativeDdSdk()?.removeAttribute).toHaveBeenCalledTimes(1);
expect(getNativeDdSdk()?.removeAttribute).toHaveBeenCalledWith(key);
expect(AttributesSingleton.getInstance().getAttribute(key)).toEqual(
undefined
);
Expand All @@ -1357,8 +1357,8 @@ describe('DdSdkReactNative', () => {
await DdSdkReactNative.addAttributes(attributes);

// THEN
expect(NativeDdSdkSpec.addAttributes).toHaveBeenCalledTimes(1);
expect(NativeDdSdkSpec.addAttributes).toHaveBeenCalledWith(
expect(getNativeDdSdk()?.addAttributes).toHaveBeenCalledTimes(1);
expect(getNativeDdSdk()?.addAttributes).toHaveBeenCalledWith(
attributes
);
expect(AttributesSingleton.getInstance().getAttributes()).toEqual({
Expand All @@ -1377,8 +1377,8 @@ describe('DdSdkReactNative', () => {
await DdSdkReactNative.removeAttributes(['foo', 'baz']);

// THEN
expect(NativeDdSdkSpec.removeAttributes).toHaveBeenCalledTimes(1);
expect(NativeDdSdkSpec.removeAttributes).toHaveBeenCalledWith([
expect(getNativeDdSdk()?.removeAttributes).toHaveBeenCalledTimes(1);
expect(getNativeDdSdk()?.removeAttributes).toHaveBeenCalledWith([
'foo',
'baz'
]);
Expand All @@ -1404,8 +1404,10 @@ describe('DdSdkReactNative', () => {
await DdSdkReactNative.setUserInfo(userInfo);

// THEN
expect(NativeDdSdkSpec.setUserInfo).toHaveBeenCalledTimes(1);
expect(NativeDdSdkSpec.setUserInfo).toHaveBeenCalledWith(userInfo);
expect(getNativeDdSdk()?.setUserInfo).toHaveBeenCalledTimes(1);
expect(getNativeDdSdk()?.setUserInfo).toHaveBeenCalledWith(
userInfo
);
expect(UserInfoSingleton.getInstance().getUserInfo()).toEqual(
userInfo
);
Expand All @@ -1425,8 +1427,8 @@ describe('DdSdkReactNative', () => {
await DdSdkReactNative.addUserExtraInfo(extraInfo);

// THEN
expect(NativeDdSdkSpec.addUserExtraInfo).toHaveBeenCalledTimes(1);
expect(NativeDdSdkSpec.addUserExtraInfo).toHaveBeenCalledWith(
expect(getNativeDdSdk()?.addUserExtraInfo).toHaveBeenCalledTimes(1);
expect(getNativeDdSdk()?.addUserExtraInfo).toHaveBeenCalledWith(
extraInfo
);
expect(UserInfoSingleton.getInstance().getUserInfo()).toEqual({
Expand All @@ -1446,7 +1448,7 @@ describe('DdSdkReactNative', () => {
await DdSdkReactNative.addUserExtraInfo(extraInfo);

// THEN
expect(NativeDdSdkSpec.addUserExtraInfo).toHaveBeenCalledWith(
expect(getNativeDdSdk()?.addUserExtraInfo).toHaveBeenCalledWith(
extraInfo
);
expect(UserInfoSingleton.getInstance().getUserInfo()).toEqual({
Expand Down Expand Up @@ -1475,8 +1477,8 @@ describe('DdSdkReactNative', () => {
await DdSdkReactNative.clearUserInfo();

// THEN
expect(NativeDdSdkSpec.clearUserInfo).toHaveBeenCalledTimes(1);
expect(NativeDdSdkSpec.setUserInfo).toHaveBeenCalled();
expect(getNativeDdSdk()?.clearUserInfo).toHaveBeenCalledTimes(1);
expect(getNativeDdSdk()?.setUserInfo).toHaveBeenCalled();
expect(
UserInfoSingleton.getInstance().getUserInfo()
).toBeUndefined();
Expand All @@ -1493,8 +1495,10 @@ describe('DdSdkReactNative', () => {
DdSdkReactNative.setTrackingConsent(consent);

// THEN
expect(NativeDdSdkSpec.setTrackingConsent).toHaveBeenCalledTimes(1);
expect(NativeDdSdkSpec.setTrackingConsent).toHaveBeenCalledWith(
expect(getNativeDdSdk()?.setTrackingConsent).toHaveBeenCalledTimes(
1
);
expect(getNativeDdSdk()?.setTrackingConsent).toHaveBeenCalledWith(
consent
);
});
Expand All @@ -1506,7 +1510,7 @@ describe('DdSdkReactNative', () => {
DdSdkReactNative.clearAllData();

// THEN
expect(NativeDdSdkSpec.clearAllData).toHaveBeenCalledTimes(1);
expect(getNativeDdSdk()?.clearAllData).toHaveBeenCalledTimes(1);
});
});

Expand Down
26 changes: 26 additions & 0 deletions packages/core/src/__tests__/internalEntry.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
describe('./internal entry', () => {
it('exports the internals react-native-vega needs', () => {
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
const internal = require('../internal');
const expected = [
'addDefaultValuesToAutoInstrumentationConfiguration',
'buildConfigurationFromPartialConfiguration',
'DdSdkNativeConfiguration',
'RUM_DEFAULTS',
'adaptLongTaskThreshold',
'version',
'AccountInfoSingleton',
'AttributesSingleton',
'UserInfoSingleton',
'GlobalState',
'BufferSingleton',
'DatadogProviderState',
'DdRumResourceTracking'
];
for (const name of expected) {
expect(internal[name]).toBeDefined();
}
});

// Import safety of this entry point is covered in wrapperImportSafety.test.ts.
});
4 changes: 1 addition & 3 deletions packages/core/src/__tests__/mock.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ import { DdLogs, DdRum, DdTrace, DdSdkReactNative } from '../index';
*/

const privateProperties = {
DdTrace: ['nativeTrace'],
DdTrace: [],
DdLogs: [
'nativeLogs',
'logEventMapper',
'printLogDroppedSdkNotInitialized',
'printLogDroppedByMapper',
Expand All @@ -33,7 +32,6 @@ const privateProperties = {
'logWithError'
],
DdRum: [
'nativeRum',
'errorEventMapper',
'resourceEventMapper',
'actionEventMapper',
Expand Down
102 changes: 102 additions & 0 deletions packages/core/src/__tests__/nativeSpecGetters.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2016-Present Datadog, Inc.
*/

describe('native spec getters', () => {
afterEach(() => {
jest.restoreAllMocks();
});

it.each([
['../specs/NativeDdSdk', 'getNativeDdSdk', 'DdSdk'],
['../specs/NativeDdRum', 'getNativeDdRum', 'DdRum'],
['../specs/NativeDdLogs', 'getNativeDdLogs', 'DdLogs'],
['../specs/NativeDdTrace', 'getNativeDdTrace', 'DdTrace'],
['../specs/NativeDdFlags', 'getNativeDdFlags', 'DdFlags']
])(
'%s retries a missing module and caches it once found',
(modulePath, getterName, registryName) => {
jest.isolateModules(() => {
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
const { TurboModuleRegistry } = require('react-native');
const nativeModule = { name: registryName };
const getSpy = jest
.spyOn(TurboModuleRegistry, 'get')
.mockReturnValueOnce(null)
.mockReturnValue(nativeModule);
// eslint-disable-next-line global-require, import/no-dynamic-require, @typescript-eslint/no-var-requires
const getter = require(modulePath)[getterName];

expect(getter()).toBeNull();
expect(getter()).toBe(nativeModule);
expect(getter()).toBe(nativeModule);
expect(getSpy).toHaveBeenCalledTimes(2);
expect(getSpy).toHaveBeenCalledWith(registryName);
});
}
);

it('FlagsClient retries a missing module and uses it for fetching and tracking', async () => {
await jest.isolateModulesAsync(async () => {
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
const { TurboModuleRegistry } = require('react-native');
const nativeModule = {
setEvaluationContext: jest.fn().mockResolvedValue({
feature: { key: 'feature', value: true, reason: 'STATIC' }
}),
trackEvaluation: jest.fn().mockResolvedValue(undefined)
};
const getSpy = jest
.spyOn(TurboModuleRegistry, 'get')
.mockReturnValueOnce(null)
.mockReturnValue(nativeModule);
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
const { FlagsClient } = require('../flags/FlagsClient');
const client = new FlagsClient('late-native');
const context = { targetingKey: 'user', attributes: {} };

expect(getSpy).not.toHaveBeenCalled();
await expect(
client.setEvaluationContext(context)
).rejects.toThrow();
await expect(
client.setEvaluationContext(context)
).resolves.toBeUndefined();
expect(nativeModule.setEvaluationContext).toHaveBeenCalledWith(
'late-native',
'user',
{}
);
expect(client.getBooleanValue('feature', false)).toBe(true);
expect(nativeModule.trackEvaluation).toHaveBeenCalledWith(
'late-native',
'feature',
expect.objectContaining({ value: true }),
'user',
{}
);
expect(getSpy).toHaveBeenCalledTimes(2);
expect(getSpy).toHaveBeenCalledWith('DdFlags');
});
});

it('DdSdkWrapper picks up a module that was missing on first use', () => {
jest.isolateModules(() => {
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
const { TurboModuleRegistry } = require('react-native');
const nativeModule = { clearAllData: jest.fn() };
jest.spyOn(TurboModuleRegistry, 'get')
.mockReturnValueOnce(null)
.mockReturnValue(nativeModule);
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
const { DdSdkWrapper } = require('../sdk/DdSdkInternal');
const sdk = new DdSdkWrapper();

expect(() => sdk.clearAllData()).toThrow();
sdk.clearAllData();
expect(nativeModule.clearAllData).toHaveBeenCalledTimes(1);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import React from 'react';
import type { DdNativeRumType } from '../../../nativeModulesTypes';
import { DdRumUserInteractionTracking } from '../../../rum/instrumentation/interactionTracking/DdRumUserInteractionTracking';
import { BufferSingleton } from '../../../sdk/DatadogProvider/Buffer/BufferSingleton';
import NativeDdSdkSpec from '../../../specs/NativeDdSdk';
import { getNativeDdSdk } from '../../../specs/NativeDdSdk';

const styles = StyleSheet.create({
button: {
Expand Down Expand Up @@ -467,7 +467,7 @@ describe('startTracking', () => {
jest.setMock('react/jsx-runtime', {});
DdRumUserInteractionTracking.startTracking({});
expect(DdRumUserInteractionTracking['isTracking']).toBe(true);
expect(NativeDdSdkSpec.telemetryDebug).toBeCalledWith(
expect(getNativeDdSdk()?.telemetryDebug).toBeCalledWith(
'React jsx runtime does not export new jsx transform'
);
});
Expand All @@ -477,7 +477,7 @@ describe('startTracking', () => {

DdRumUserInteractionTracking.startTracking({});
expect(DdRumUserInteractionTracking['isTracking']).toBe(true);
expect(NativeDdSdkSpec.telemetryDebug).toBeCalledWith(
expect(getNativeDdSdk()?.telemetryDebug).toBeCalledWith(
'React version does not support new jsx transform'
);
});
Expand Down
Loading
Loading