From 2c6be4a0d34b9780ba92ed1c45863fe0f46992b7 Mon Sep 17 00:00:00 2001 From: Jonathan Munz Date: Thu, 1 Aug 2024 11:33:12 -0400 Subject: [PATCH 1/7] flush spans after adding attributes or events --- packages/core/ios/RNEmbrace/EmbraceManager.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/core/ios/RNEmbrace/EmbraceManager.swift b/packages/core/ios/RNEmbrace/EmbraceManager.swift index 1cdda64a..61301fc9 100644 --- a/packages/core/ios/RNEmbrace/EmbraceManager.swift +++ b/packages/core/ios/RNEmbrace/EmbraceManager.swift @@ -482,6 +482,8 @@ class EmbraceManager: NSObject { } else { span?.addEvent(name: name, attributes: attributeValuesFrom(dict: attributes), timestamp: dateFrom(ms: time)) } + + Embrace.client?.flush(span!) resolve(true) } @@ -502,6 +504,7 @@ class EmbraceManager: NSObject { } span?.setAttribute(key: key, value: value) + Embrace.client?.flush(span!) resolve(true) } From 009ee6ec43fa5507c7d074248a662046531dbb10 Mon Sep 17 00:00:00 2001 From: Jonathan Munz Date: Thu, 1 Aug 2024 14:57:13 -0400 Subject: [PATCH 2/7] Update iOS initialization to configure from code instead of plist (#62) --- examples/react-native-test-suite/.gitignore | 1 + .../basic-test-app/app/_layout.tsx | 9 +- .../basic-test-app/ios/Embrace-Info.plist | 20 -- .../embracewrapper/EmbraceManagerModule.java | 3 +- packages/core/ios/RNEmbrace/EmbraceManager.m | 2 +- .../core/ios/RNEmbrace/EmbraceManager.swift | 50 ++++- packages/core/src/__tests__/embrace.test.ts | 186 ------------------ .../core/src/__tests__/initialize.test.ts | 133 +++++++++++++ packages/core/src/index.ts | 62 +++--- packages/core/src/interfaces/Config.ts | 12 ++ .../project.pbxproj | 110 ++++++----- .../ios/RNEmbraceTests/RNEmbraceTests.swift | 30 ++- 12 files changed, 320 insertions(+), 298 deletions(-) delete mode 100644 integration-tests/basic-test-app/ios/Embrace-Info.plist create mode 100644 packages/core/src/__tests__/initialize.test.ts create mode 100644 packages/core/src/interfaces/Config.ts diff --git a/examples/react-native-test-suite/.gitignore b/examples/react-native-test-suite/.gitignore index 9d4ee599..9c2d5299 100644 --- a/examples/react-native-test-suite/.gitignore +++ b/examples/react-native-test-suite/.gitignore @@ -38,6 +38,7 @@ ios/Pods node_modules/ npm-debug.log yarn-error.log +.yarn/* # BUCK buck-out/ diff --git a/integration-tests/basic-test-app/app/_layout.tsx b/integration-tests/basic-test-app/app/_layout.tsx index f38a5e53..a2054d55 100644 --- a/integration-tests/basic-test-app/app/_layout.tsx +++ b/integration-tests/basic-test-app/app/_layout.tsx @@ -14,7 +14,14 @@ SplashScreen.preventAutoHideAsync(); export default function RootLayout() { useEffect(() => { const init = async () => { - const hasStarted = await initEmbrace(); + await initEmbrace({ + sdkConfig: { + ios: { + appId: "abcdf", + endpointBaseUrl: "http://localhost:8877", + }, + }, + }); }; init(); diff --git a/integration-tests/basic-test-app/ios/Embrace-Info.plist b/integration-tests/basic-test-app/ios/Embrace-Info.plist deleted file mode 100644 index aa819598..00000000 --- a/integration-tests/basic-test-app/ios/Embrace-Info.plist +++ /dev/null @@ -1,20 +0,0 @@ - - - - - API_KEY - abcdf - CRASH_REPORT_ENABLED - - CONFIG_BASE_URL - http://localhost:8877 - DATA_BASE_URL - http://localhost:8877 - DATA_DEV_BASE_URL - http://localhost:8877 - IMAGES_BASE_URL - http://localhost:8877 - TEST_BASE_URL - http://localhost:8877 - - \ No newline at end of file diff --git a/packages/core/android/src/main/java/io/embrace/embracewrapper/EmbraceManagerModule.java b/packages/core/android/src/main/java/io/embrace/embracewrapper/EmbraceManagerModule.java index 7d7605c7..7805422e 100644 --- a/packages/core/android/src/main/java/io/embrace/embracewrapper/EmbraceManagerModule.java +++ b/packages/core/android/src/main/java/io/embrace/embracewrapper/EmbraceManagerModule.java @@ -53,7 +53,8 @@ public void isStarted(Promise promise) { } @ReactMethod - public void startNativeEmbraceSDK(Promise promise) { + public void startNativeEmbraceSDK(ReadableMap config, Promise promise) { + // config for now is only used to setup the iOS SDK, the Android SDK reads its config from a file try{ Embrace.getInstance().start(this.context.getApplicationContext(), false, Embrace.AppFramework.REACT_NATIVE); promise.resolve(true); diff --git a/packages/core/ios/RNEmbrace/EmbraceManager.m b/packages/core/ios/RNEmbrace/EmbraceManager.m index 84bfc4eb..34c81884 100755 --- a/packages/core/ios/RNEmbrace/EmbraceManager.m +++ b/packages/core/ios/RNEmbrace/EmbraceManager.m @@ -9,7 +9,7 @@ @interface RCT_EXTERN_MODULE(EmbraceManager, NSObject) RCT_EXTERN_METHOD(isStarted:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) -RCT_EXTERN_METHOD(startNativeEmbraceSDK:(NSString *)appId +RCT_EXTERN_METHOD(startNativeEmbraceSDK:(NSDictionary)config resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) diff --git a/packages/core/ios/RNEmbrace/EmbraceManager.swift b/packages/core/ios/RNEmbrace/EmbraceManager.swift index 61301fc9..d1528ced 100644 --- a/packages/core/ios/RNEmbrace/EmbraceManager.swift +++ b/packages/core/ios/RNEmbrace/EmbraceManager.swift @@ -5,6 +5,7 @@ import EmbraceIO import EmbraceCrash import EmbraceCommonInternal // TODO should not be needed import EmbraceOTelInternal // TODO should not be needed +import EmbraceCaptureService #if canImport(CodePush) import CodePush @@ -22,6 +23,23 @@ private let EVENT_NAME_KEY = "name" private let EVENT_TIMESTAMP_KEY = "timeStampMs" private let EVENT_ATTRIBUTES_KEY = "attributes" +class SDKConfig: NSObject { + public let appId: String; + public let appGroupId: String?; + public let disableCrashReporter: Bool; + public let disableAutomaticViewCapture: Bool; + public let endpointBaseUrl: String?; + + public init(from: NSDictionary) { + self.appId = from["appId"] as? String ?? "" + self.appGroupId = from["appGroupId"] as? String + self.disableCrashReporter = from["disableCrashReporter"] as? Bool ?? false + self.disableAutomaticViewCapture = from["disableAutomaticViewCapture"] as? Bool ?? false + self.endpointBaseUrl = from["endpointBaseUrl"] as? String + } +} + + @objc(EmbraceManager) class EmbraceManager: NSObject { private var log = OSLog(subsystem: "Embrace", category: "ReactNativeEmbraceManager") @@ -47,17 +65,37 @@ class EmbraceManager: NSObject { } @objc(startNativeEmbraceSDK:resolver:rejecter:) - func startNativeEmbraceSDK(_ appId: String, resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + func startNativeEmbraceSDK(configDict: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { + let config = SDKConfig(from: configDict) DispatchQueue.main.async { do { - var embraceOptions: Embrace.Options { + var crashReporter: CrashReporter? + if config.disableCrashReporter { + crashReporter = nil + } else { + crashReporter = EmbraceCrashReporter() + } + + let servicesBuilder = CaptureServiceBuilder().addDefaults() + if config.disableAutomaticViewCapture { + servicesBuilder.remove(ofType: ViewCaptureService.self) + } + + var endpoints: Embrace.Endpoints? = nil + if config.endpointBaseUrl != nil { + endpoints = Embrace.Endpoints(baseURL: config.endpointBaseUrl!, + developmentBaseURL: config.endpointBaseUrl!, + configBaseURL: config.endpointBaseUrl!) + } + return .init( - appId: appId, - appGroupId: nil, + appId: config.appId, + appGroupId: config.appGroupId, platform: .reactNative, - captureServices: .automatic, - crashReporter: EmbraceCrashReporter() + endpoints: endpoints, + captureServices: servicesBuilder.build(), + crashReporter: crashReporter ) } diff --git a/packages/core/src/__tests__/embrace.test.ts b/packages/core/src/__tests__/embrace.test.ts index 5f659e24..020267af 100644 --- a/packages/core/src/__tests__/embrace.test.ts +++ b/packages/core/src/__tests__/embrace.test.ts @@ -1,10 +1,8 @@ -import {handleGlobalError} from "../utils/ErrorUtil"; //TODO Check why its failing if we import the constants from the index.ts // import {INFO, ERROR, WARNING} from "../index"; const WARNING = "warning"; const INFO = "info"; const ERROR = "error"; - const testView = "View"; const testPersona = "Persona"; const testUserId = "Lucia"; @@ -778,187 +776,3 @@ describe("Test testing purpose functions", () => { expect(generateStackTrace()).toContain("Error:"); }); }); - -describe("Test initialize", () => { - test("initialize", () => { - const mockSetReactNativeVersion = jest.fn(); - const mockSetJavaScriptPatchNumber = jest.fn(); - const mockSetReactNativeSDKVersion = jest.fn(); - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - setReactNativeVersion: mockSetReactNativeVersion, - setJavaScriptPatchNumber: mockSetJavaScriptPatchNumber, - setReactNativeSDKVersion: mockSetReactNativeSDKVersion, - isStarted: () => true, - }, - }, - })); - - const {initialize} = require("../index"); - - const result = initialize({patch: testValue}); - - expect(result).resolves.toBe(true); - - result.then(() => { - expect(mockSetReactNativeVersion).toHaveBeenCalled(); - expect(mockSetJavaScriptPatchNumber).toHaveBeenCalled(); - expect(mockSetReactNativeSDKVersion).toHaveBeenCalled(); - }); - }); - - test("initialize - native not initialized", async () => { - const mockRNSDKVersion = jest.fn(); - const mockRNVersion = jest.fn(); - const mockSetPatchVersion = jest.fn(); - const mockIsStarted = jest.fn(); - const mockStartRNSDK = jest.fn(); - - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - isStarted: () => { - mockIsStarted(); - return false; - }, - startNativeEmbraceSDK: () => { - mockStartRNSDK(); - return true; - }, - setReactNativeSDKVersion: mockRNSDKVersion, - setJavaScriptPatchNumber: mockSetPatchVersion, - setReactNativeVersion: mockRNVersion, - }, - }, - })); - - const {initialize} = require("../index"); - - const promiseToResolve = initialize({patch: testValue}); - jest.runAllTicks(); - jest.runAllTimers(); - const result = await promiseToResolve; - expect(result).toBe(true); - expect(mockIsStarted).toBeCalledTimes(1); - expect(mockStartRNSDK).toBeCalledTimes(1); - expect(mockRNSDKVersion).toBeCalledTimes(1); - expect(mockSetPatchVersion).toBeCalledTimes(1); - }); - - test("initialize - native initialized", () => { - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - isStarted: () => false, - startNativeEmbraceSDK: () => true, - }, - }, - })); - - const {initialize} = require("../index"); - - const result = initialize({patch: testValue}); - jest.runAllTicks(); - - expect(result).resolves.toBe(true); - }); - - test("applying previousHandler", () => { - const previousHandler = jest.fn(); - const mockSetReactNativeVersion = jest.fn(); - const mockSetJavaScriptPatchNumber = jest.fn(); - const mockSetReactNativeSDKVersion = jest.fn(); - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - setReactNativeVersion: mockSetReactNativeVersion, - setJavaScriptPatchNumber: mockSetJavaScriptPatchNumber, - setReactNativeSDKVersion: mockSetReactNativeSDKVersion, - isStarted: () => true, - }, - }, - })); - ErrorUtils.getGlobalHandler = previousHandler; - const {initialize} = require("../index"); - const result = initialize({patch: testValue}); - - const handleError = () => {}; - const generatedGlobalErrorFunc = handleGlobalError( - previousHandler, - handleError, - ); - generatedGlobalErrorFunc(Error("Test")); - - expect(result).resolves.toBe(true); - - result.then(() => { - expect(previousHandler).toHaveBeenCalled(); - expect(mockSetReactNativeVersion).toHaveBeenCalled(); - expect(mockSetJavaScriptPatchNumber).toHaveBeenCalled(); - expect(mockSetReactNativeSDKVersion).toHaveBeenCalled(); - }); - }); - - test("store embrace sdk version", () => { - const mocksetReactNativeSDKVersion = jest.fn(); - - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - setReactNativeVersion: jest.fn(), - setReactNativeSDKVersion: mocksetReactNativeSDKVersion, - isStarted: () => true, - }, - }, - })); - const {initialize} = require("../index"); - - const result = initialize(); - - expect(result).resolves.toBe(true); - - result.then(() => { - expect(mocksetReactNativeSDKVersion).toHaveBeenCalled(); - }); - }); - - test("applying Tracking", () => { - interface ITracking { - onUnhandled: (_: any, error: Error) => {}; - } - - jest.mock("promise/setimmediate/rejection-tracking", () => ({ - enable: (c: ITracking) => { - const {onUnhandled} = c; - onUnhandled("e", new Error()); - }, - })); - - const mockLogMessageWithSeverityAndProperties = jest.fn(); - const mockSetReactNativeVersion = jest.fn(); - const mockSetJavaScriptPatchNumber = jest.fn(); - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - setReactNativeVersion: mockSetReactNativeVersion, - setJavaScriptPatchNumber: mockSetJavaScriptPatchNumber, - logMessageWithSeverityAndProperties: - mockLogMessageWithSeverityAndProperties, - setReactNativeSDKVersion: jest.fn(), - isStarted: () => true, - }, - }, - })); - - const {initialize} = require("../index"); - - const result = initialize({patch: testValue}); - - expect(result).resolves.toBe(true); - - result.then(() => { - expect(mockLogMessageWithSeverityAndProperties).toHaveBeenCalled(); - }); - }); -}); diff --git a/packages/core/src/__tests__/initialize.test.ts b/packages/core/src/__tests__/initialize.test.ts new file mode 100644 index 00000000..25430ba6 --- /dev/null +++ b/packages/core/src/__tests__/initialize.test.ts @@ -0,0 +1,133 @@ +import {handleGlobalError} from "../utils/ErrorUtil"; +import {initialize} from "../index"; + +const testValue = "Value"; + +const mockSetReactNativeVersion = jest.fn(); +const mockSetJavaScriptPatchNumber = jest.fn(); +const mockIsStarted = jest.fn(); +const mockStart = jest.fn(); +const mockSetReactNativeSDKVersion = jest.fn(); +const mockLogMessageWithSeverityAndProperties = jest.fn(); + +const ReactNativeMock = jest.requireMock("react-native"); + +jest.mock("react-native", () => ({ + NativeModules: { + EmbraceManager: { + setReactNativeVersion: (version: string) => + mockSetReactNativeVersion(version), + setJavaScriptPatchNumber: (patch: string) => + mockSetJavaScriptPatchNumber(patch), + setReactNativeSDKVersion: (version: string) => + mockSetReactNativeSDKVersion(version), + logMessageWithSeverityAndProperties: ( + message: string, + severity: string, + properties: object, + stacktrace: string, + ) => + mockLogMessageWithSeverityAndProperties( + message, + severity, + properties, + stacktrace, + ), + isStarted: () => mockIsStarted(), + startNativeEmbraceSDK: (appId?: string) => mockStart(appId), + }, + }, + Platform: {OS: "android"}, +})); + +interface ITracking { + onUnhandled: (_: any, error: Error) => {}; +} + +jest.mock("promise/setimmediate/rejection-tracking", () => ({ + enable: (c: ITracking) => { + const {onUnhandled} = c; + onUnhandled("e", new Error()); + }, +})); + +describe("initialize", () => { + beforeEach(() => { + jest.resetAllMocks(); + + mockStart.mockReturnValue(true); + ReactNativeMock.Platform.OS = "android"; + }); + + test("sdk already started", async () => { + mockIsStarted.mockReturnValue(true); + const result = await initialize({patch: testValue}); + + expect(result).toBe(true); + expect(mockSetReactNativeVersion).toHaveBeenCalledWith("0.56.1"); + expect(mockSetJavaScriptPatchNumber).toHaveBeenCalledWith(testValue); + expect(mockSetReactNativeSDKVersion).toHaveBeenCalledWith("4.2.0"); + expect(mockStart).not.toHaveBeenCalled(); + expect(mockLogMessageWithSeverityAndProperties).toHaveBeenCalled(); + expect(mockLogMessageWithSeverityAndProperties.mock.calls[0][0]).toBe( + "Unhandled promise rejection: ", + ); + }); + + test("sdk not already started", async () => { + mockIsStarted.mockReturnValue(false); + const result = await initialize({patch: testValue}); + + expect(result).toBe(true); + expect(mockStart).toHaveBeenCalledWith({}); + expect(mockSetReactNativeVersion).toHaveBeenCalledWith("0.56.1"); + expect(mockSetJavaScriptPatchNumber).toHaveBeenCalledWith(testValue); + expect(mockSetReactNativeSDKVersion).toHaveBeenCalledWith("4.2.0"); + expect(mockLogMessageWithSeverityAndProperties).toHaveBeenCalled(); + expect(mockLogMessageWithSeverityAndProperties.mock.calls[0][0]).toBe( + "Unhandled promise rejection: ", + ); + }); + + test("sdk not already started on iOS, missing app id", async () => { + ReactNativeMock.Platform.OS = "ios"; + mockIsStarted.mockReturnValue(false); + const result = await initialize({patch: testValue}); + expect(result).toBe(false); + expect(mockStart).not.toHaveBeenCalled(); + expect(mockSetReactNativeVersion).not.toHaveBeenCalled(); + expect(mockSetJavaScriptPatchNumber).not.toHaveBeenCalled(); + expect(mockSetReactNativeSDKVersion).not.toHaveBeenCalled(); + expect(mockLogMessageWithSeverityAndProperties).not.toHaveBeenCalled(); + }); + + test("sdk not already started on iOS, app id supplied", async () => { + ReactNativeMock.Platform.OS = "ios"; + mockIsStarted.mockReturnValue(false); + const result = await initialize({ + patch: testValue, + sdkConfig: {ios: {appId: "abc12"}}, + }); + expect(result).toBe(true); + expect(mockStart).toHaveBeenCalledWith({appId: "abc12"}); + expect(mockLogMessageWithSeverityAndProperties).toHaveBeenCalled(); + expect(mockLogMessageWithSeverityAndProperties.mock.calls[0][0]).toBe( + "Unhandled promise rejection: ", + ); + }); + + test("applying previousHandler", async () => { + const previousHandler = jest.fn(); + ErrorUtils.getGlobalHandler = previousHandler; + const result = await initialize({patch: testValue}); + expect(result).toBe(true); + + const handleError = () => {}; + const generatedGlobalErrorFunc = handleGlobalError( + previousHandler, + handleError, + ); + generatedGlobalErrorFunc(Error("Test")); + expect(previousHandler).toHaveBeenCalled(); + }); +}); diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 93b3b6b8..8fca900e 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,5 +1,5 @@ "use strict"; -import {NativeModules} from "react-native"; +import {NativeModules, Platform} from "react-native"; import * as embracePackage from "../package.json"; @@ -11,6 +11,7 @@ import { NETWORK_INTERCEPTOR_TYPES, } from "./interfaces/NetworkMonitoring"; import {MethodType} from "./interfaces/HTTP"; +import {SDKConfig} from "./interfaces/Config"; interface Properties { [key: string]: any; @@ -21,9 +22,7 @@ const tracking = require("promise/setimmediate/rejection-tracking"); const stackLimit = 200; -// TODO REFACTOR WHEN iOS IMPLEMENT THE METHOD - -// const unhandledPromiseRejectionPrefix = "Unhandled promise rejection: "; +const unhandledPromiseRejectionPrefix = "Unhandled promise rejection: "; const handleError = async (error: Error, callback: () => void) => { if (!(error instanceof Error)) { @@ -47,18 +46,20 @@ const isObjectNonEmpty = (obj?: object): boolean => export const initialize = async ({ patch, -}: {patch?: string} = {}): Promise => { - if (!ErrorUtils) { - console.warn( - "[Embrace] ErrorUtils is not defined. Not setting exception handler.", - ); - return createFalsePromise(); - } + sdkConfig, +}: {patch?: string; sdkConfig?: SDKConfig} = {}): Promise => { const hasNativeSDKStarted = await NativeModules.EmbraceManager.isStarted(); if (!hasNativeSDKStarted) { - // TODO CHANGE TO CONFIG OR SOMETHING - const result = - await NativeModules.EmbraceManager.startNativeEmbraceSDK("Jso7A"); + if (Platform.OS === "ios" && !sdkConfig?.ios?.appId) { + console.warn( + "[Embrace] sdkConfig.ios.appId is required to initialize Embrace's native SDK, please check the Embrace integration docs at https://embrace.io/docs/react-native/integration/", + ); + return createFalsePromise(); + } + + const result = await NativeModules.EmbraceManager.startNativeEmbraceSDK( + (Platform.OS === "ios" && sdkConfig?.ios) || {}, + ); if (!result) { console.warn( "[Embrace] We could not initialize Embrace's native SDK, please check the Embrace integration docs at https://embrace.io/docs/react-native/integration/", @@ -93,25 +94,32 @@ export const initialize = async ({ if (!__DEV__) { NativeModules.EmbraceManager.checkAndSetCodePushBundleURL(); } + + if (!ErrorUtils) { + console.warn( + "[Embrace] ErrorUtils is not defined. Not setting exception handler.", + ); + return createFalsePromise(); + } const previousHandler = ErrorUtils.getGlobalHandler(); ErrorUtils.setGlobalHandler(handleGlobalError(previousHandler, handleError)); tracking.enable({ allRejections: true, onUnhandled: (_: any, error: Error) => { - // TODO REFACTOR WHEN iOS IMPLEMENT THE METHOD - // let message = `Unhandled promise rejection: ${error}`; - // let st = ""; - // if (error instanceof Error) { - // message = unhandledPromiseRejectionPrefix + error.message; - // st = error.stack || ""; - // } - // return NativeModules.EmbraceManager.logMessageWithSeverityAndProperties( - // message, - // ERROR, - // {}, - // st, - // ); + let message = `Unhandled promise rejection: ${error}`; + let st = ""; + if (error instanceof Error) { + message = unhandledPromiseRejectionPrefix + error.message; + st = error.stack || ""; + } + + return NativeModules.EmbraceManager.logMessageWithSeverityAndProperties( + message, + ERROR, + {}, + st, + ); }, onHandled: () => {}, }); diff --git a/packages/core/src/interfaces/Config.ts b/packages/core/src/interfaces/Config.ts new file mode 100644 index 00000000..ee3f11e7 --- /dev/null +++ b/packages/core/src/interfaces/Config.ts @@ -0,0 +1,12 @@ +/** + * Defines the SDK configuration that can be passed into `initialize` + */ +export interface SDKConfig { + ios?: { + appId: string; + appGroupId?: string; + disableCrashReporter?: boolean; + disableAutomaticViewCapture?: boolean; + endpointBaseUrl?: string; + }; +} diff --git a/packages/core/test-project/ios/RNEmbraceTestProject.xcodeproj/project.pbxproj b/packages/core/test-project/ios/RNEmbraceTestProject.xcodeproj/project.pbxproj index ba12a370..f7fbf3a2 100644 --- a/packages/core/test-project/ios/RNEmbraceTestProject.xcodeproj/project.pbxproj +++ b/packages/core/test-project/ios/RNEmbraceTestProject.xcodeproj/project.pbxproj @@ -12,8 +12,8 @@ 30DFDA6A2C486677009F2ECC /* RNEmbrace.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30DFDA622C486677009F2ECC /* RNEmbrace.framework */; }; 30DFDA6F2C486677009F2ECC /* RNEmbraceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30DFDA6E2C486677009F2ECC /* RNEmbraceTests.swift */; }; 30DFDA7A2C4866AA009F2ECC /* EmbraceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30DFDA782C4866AA009F2ECC /* EmbraceManager.swift */; }; - 555DF868EF33DAC77D2959C2 /* libPods-RNEmbrace-RNEmbraceTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 668E67766CAC003F565720A7 /* libPods-RNEmbrace-RNEmbraceTests.a */; }; - B3F79D90DE411B4F04EC80BC /* libPods-RNEmbrace.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F0DBAF16B065C452AB2257F2 /* libPods-RNEmbrace.a */; }; + 3F9446F81086437913617695 /* libPods-RNEmbrace-RNEmbraceTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 84B378AFFF06A00CDD90700A /* libPods-RNEmbrace-RNEmbraceTests.a */; }; + D18EC446A0FD477DD3C14E3F /* libPods-RNEmbrace.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2971EBAF870951D46C499FF6 /* libPods-RNEmbrace.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -27,18 +27,18 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 2971EBAF870951D46C499FF6 /* libPods-RNEmbrace.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNEmbrace.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 308F09282C4EED4200C1EB4C /* EmbraceManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EmbraceManager.m; sourceTree = ""; }; 308F092A2C4EF1FE00C1EB4C /* SpanRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpanRepository.swift; sourceTree = ""; }; 30DFDA622C486677009F2ECC /* RNEmbrace.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RNEmbrace.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 30DFDA692C486677009F2ECC /* RNEmbraceTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNEmbraceTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 30DFDA6E2C486677009F2ECC /* RNEmbraceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNEmbraceTests.swift; sourceTree = ""; }; 30DFDA782C4866AA009F2ECC /* EmbraceManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmbraceManager.swift; sourceTree = ""; }; - 4433B9A49C451F504AAA3A78 /* Pods-RNEmbrace.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace.debug.xcconfig"; path = "Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace.debug.xcconfig"; sourceTree = ""; }; - 4A7809C520BF6784588D03DE /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig"; path = "Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig"; sourceTree = ""; }; - 668E67766CAC003F565720A7 /* libPods-RNEmbrace-RNEmbraceTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNEmbrace-RNEmbraceTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 795A0EB9E44D82C1ED5E99CB /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace-RNEmbraceTests.release.xcconfig"; path = "Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests.release.xcconfig"; sourceTree = ""; }; - AD37347296FAF53C1E0148A3 /* Pods-RNEmbrace.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace.release.xcconfig"; path = "Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace.release.xcconfig"; sourceTree = ""; }; - F0DBAF16B065C452AB2257F2 /* libPods-RNEmbrace.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNEmbrace.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6207261ABCF304D9D0A11328 /* Pods-RNEmbrace.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace.debug.xcconfig"; path = "Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace.debug.xcconfig"; sourceTree = ""; }; + 84B378AFFF06A00CDD90700A /* libPods-RNEmbrace-RNEmbraceTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNEmbrace-RNEmbraceTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 91F66420189F99483A85657C /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig"; path = "Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig"; sourceTree = ""; }; + B22986E47D154AD67F3DD423 /* Pods-RNEmbrace.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace.release.xcconfig"; path = "Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace.release.xcconfig"; sourceTree = ""; }; + DCF1830916CC2D1329507B44 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace-RNEmbraceTests.release.xcconfig"; path = "Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -46,7 +46,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - B3F79D90DE411B4F04EC80BC /* libPods-RNEmbrace.a in Frameworks */, + D18EC446A0FD477DD3C14E3F /* libPods-RNEmbrace.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -55,7 +55,7 @@ buildActionMask = 2147483647; files = ( 30DFDA6A2C486677009F2ECC /* RNEmbrace.framework in Frameworks */, - 555DF868EF33DAC77D2959C2 /* libPods-RNEmbrace-RNEmbraceTests.a in Frameworks */, + 3F9446F81086437913617695 /* libPods-RNEmbrace-RNEmbraceTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -65,10 +65,10 @@ 0C8E90FDF3018EA1FCF9459E /* Pods */ = { isa = PBXGroup; children = ( - 4433B9A49C451F504AAA3A78 /* Pods-RNEmbrace.debug.xcconfig */, - AD37347296FAF53C1E0148A3 /* Pods-RNEmbrace.release.xcconfig */, - 4A7809C520BF6784588D03DE /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */, - 795A0EB9E44D82C1ED5E99CB /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */, + 6207261ABCF304D9D0A11328 /* Pods-RNEmbrace.debug.xcconfig */, + B22986E47D154AD67F3DD423 /* Pods-RNEmbrace.release.xcconfig */, + 91F66420189F99483A85657C /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */, + DCF1830916CC2D1329507B44 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -80,7 +80,7 @@ 30DFDA6D2C486677009F2ECC /* RNEmbraceTests */, 30DFDA102C485A70009F2ECC /* Products */, 0C8E90FDF3018EA1FCF9459E /* Pods */, - BE728DC4A0B6E91F18B544FA /* Frameworks */, + C9F3B360627742333C49BB21 /* Frameworks */, ); sourceTree = ""; }; @@ -112,11 +112,11 @@ path = RNEmbraceTests; sourceTree = ""; }; - BE728DC4A0B6E91F18B544FA /* Frameworks */ = { + C9F3B360627742333C49BB21 /* Frameworks */ = { isa = PBXGroup; children = ( - F0DBAF16B065C452AB2257F2 /* libPods-RNEmbrace.a */, - 668E67766CAC003F565720A7 /* libPods-RNEmbrace-RNEmbraceTests.a */, + 2971EBAF870951D46C499FF6 /* libPods-RNEmbrace.a */, + 84B378AFFF06A00CDD90700A /* libPods-RNEmbrace-RNEmbraceTests.a */, ); name = Frameworks; sourceTree = ""; @@ -138,12 +138,12 @@ isa = PBXNativeTarget; buildConfigurationList = 30DFDA712C486677009F2ECC /* Build configuration list for PBXNativeTarget "RNEmbrace" */; buildPhases = ( - 513494E4CC736D9A88CCFD20 /* [CP] Check Pods Manifest.lock */, + 7D91ADB8297CC292259545D5 /* [CP] Check Pods Manifest.lock */, 30DFDA5D2C486677009F2ECC /* Headers */, 30DFDA5E2C486677009F2ECC /* Sources */, 30DFDA5F2C486677009F2ECC /* Frameworks */, 30DFDA602C486677009F2ECC /* Resources */, - 0BDA84EC7E5DDDC6C57FB1C8 /* [CP] Copy Pods Resources */, + 1BE76E2FFC098832273CFF81 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -158,13 +158,13 @@ isa = PBXNativeTarget; buildConfigurationList = 30DFDA742C486677009F2ECC /* Build configuration list for PBXNativeTarget "RNEmbraceTests" */; buildPhases = ( + 89172ED4C9BA29D058B75BF7 /* [CP] Check Pods Manifest.lock */, 3023F50B2C52EA4300981C97 /* ShellScript */, - 608BEC36CA69A292132EC307 /* [CP] Check Pods Manifest.lock */, 30DFDA652C486677009F2ECC /* Sources */, 30DFDA662C486677009F2ECC /* Frameworks */, 30DFDA672C486677009F2ECC /* Resources */, - 25FEBBB881CE2AEA914B30D6 /* [CP] Embed Pods Frameworks */, - 903AB43326D0EFDBB7F3880F /* [CP] Copy Pods Resources */, + 95A88EC839F3EE2753782849 /* [CP] Embed Pods Frameworks */, + 9C5E00AB9FBD971682159A46 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -172,8 +172,6 @@ 30DFDA6C2C486677009F2ECC /* PBXTargetDependency */, ); name = RNEmbraceTests; - packageProductDependencies = ( - ); productName = RNEmbraceTests; productReference = 30DFDA692C486677009F2ECC /* RNEmbraceTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; @@ -206,8 +204,6 @@ Base, ); mainGroup = 30DFDA052C485A70009F2ECC; - packageReferences = ( - ); productRefGroup = 30DFDA102C485A70009F2ECC /* Products */; projectDirPath = ""; projectRoot = ""; @@ -236,7 +232,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 0BDA84EC7E5DDDC6C57FB1C8 /* [CP] Copy Pods Resources */ = { + 1BE76E2FFC098832273CFF81 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -253,23 +249,6 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 25FEBBB881CE2AEA914B30D6 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; 3023F50B2C52EA4300981C97 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -287,7 +266,7 @@ shellPath = /bin/sh; shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; }; - 513494E4CC736D9A88CCFD20 /* [CP] Check Pods Manifest.lock */ = { + 7D91ADB8297CC292259545D5 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -309,7 +288,7 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 608BEC36CA69A292132EC307 /* [CP] Check Pods Manifest.lock */ = { + 89172ED4C9BA29D058B75BF7 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -331,7 +310,24 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 903AB43326D0EFDBB7F3880F /* [CP] Copy Pods Resources */ = { + 95A88EC839F3EE2753782849 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9C5E00AB9FBD971682159A46 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -442,7 +438,10 @@ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = "$(inherited) "; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; @@ -508,7 +507,10 @@ LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; - OTHER_LDFLAGS = "$(inherited) "; + OTHER_LDFLAGS = ( + "$(inherited)", + " ", + ); REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; @@ -521,7 +523,7 @@ }; 30DFDA722C486677009F2ECC /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4433B9A49C451F504AAA3A78 /* Pods-RNEmbrace.debug.xcconfig */; + baseConfigurationReference = 6207261ABCF304D9D0A11328 /* Pods-RNEmbrace.debug.xcconfig */; buildSettings = { BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; @@ -559,7 +561,7 @@ }; 30DFDA732C486677009F2ECC /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = AD37347296FAF53C1E0148A3 /* Pods-RNEmbrace.release.xcconfig */; + baseConfigurationReference = B22986E47D154AD67F3DD423 /* Pods-RNEmbrace.release.xcconfig */; buildSettings = { BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; @@ -596,7 +598,7 @@ }; 30DFDA752C486677009F2ECC /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4A7809C520BF6784588D03DE /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */; + baseConfigurationReference = 91F66420189F99483A85657C /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; @@ -615,7 +617,7 @@ }; 30DFDA762C486677009F2ECC /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 795A0EB9E44D82C1ED5E99CB /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */; + baseConfigurationReference = DCF1830916CC2D1329507B44 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; diff --git a/packages/core/test-project/ios/RNEmbraceTests/RNEmbraceTests.swift b/packages/core/test-project/ios/RNEmbraceTests/RNEmbraceTests.swift index 79fbbe58..449c0b4c 100644 --- a/packages/core/test-project/ios/RNEmbraceTests/RNEmbraceTests.swift +++ b/packages/core/test-project/ios/RNEmbraceTests/RNEmbraceTests.swift @@ -54,8 +54,8 @@ class EmbraceManagerTests: XCTestCase { } func testStartNativeEmbraceSDK() async throws { - module.startNativeEmbraceSDK("myApp", resolve: promise.resolve, rejecter: promise.reject) - + module.startNativeEmbraceSDK(configDict: NSDictionary(dictionary: ["appId": "myApp"]), + resolve: promise.resolve, rejecter: promise.reject) try await Task.sleep(nanoseconds: UInt64(5.0 * Double(NSEC_PER_SEC))) XCTAssertEqual(promise.resolveCalls.count, 1) XCTAssertTrue((promise.resolveCalls[0] as? Bool)!) @@ -64,6 +64,32 @@ class EmbraceManagerTests: XCTestCase { XCTAssertEqual(promise.resolveCalls.count, 2) XCTAssertTrue((promise.resolveCalls[1] as? Bool)!) } + + func testParseSDKConfig() { + let config = SDKConfig(from: NSDictionary(dictionary: [ + "appId": "myApp", + "appGroupId": "myAppGroup", + "disableCrashReporter": true, + "disableAutomaticViewCapture": true, + "endpointBaseUrl": "http://example.com" + ])) + + XCTAssertEqual(config.appId, "myApp") + XCTAssertEqual(config.appGroupId, "myAppGroup") + XCTAssertTrue(config.disableCrashReporter) + XCTAssertTrue(config.disableAutomaticViewCapture) + XCTAssertEqual(config.endpointBaseUrl, "http://example.com") + } + + func testParseSDKConfigDefaults() { + let config = SDKConfig(from: NSDictionary(dictionary: ["appId": "myApp"])) + + XCTAssertEqual(config.appId, "myApp") + XCTAssertNil(config.appGroupId) + XCTAssertFalse(config.disableCrashReporter) + XCTAssertFalse(config.disableAutomaticViewCapture) + XCTAssertNil(config.endpointBaseUrl) + } } class EmbraceSpansTests: XCTestCase { From cb392ceccb955258d7f7567e5cac9c3133dbbb88 Mon Sep 17 00:00:00 2001 From: Jonathan Munz Date: Wed, 7 Aug 2024 12:12:03 -0400 Subject: [PATCH 3/7] EMBR-4619 fix swift tests (#65) --- packages/core/test-project/ios/Podfile | 4 +- packages/core/test-project/ios/Podfile.lock | 112 +++++++++--------- .../project.pbxproj | 76 ++++++------ .../ios/RNEmbraceTests/RNEmbraceTests.swift | 13 +- 4 files changed, 105 insertions(+), 100 deletions(-) diff --git a/packages/core/test-project/ios/Podfile b/packages/core/test-project/ios/Podfile index 343dc249..e63902dd 100644 --- a/packages/core/test-project/ios/Podfile +++ b/packages/core/test-project/ios/Podfile @@ -1,3 +1,5 @@ +source 'https://github.com/CocoaPods/Specs.git' + # Resolve react_native_pods.rb with node to allow for hoisting require Pod::Executable.execute_command('node', ['-p', 'require.resolve( @@ -23,7 +25,7 @@ target 'RNEmbrace' do :app_path => "#{Pod::Config.instance.installation_root}/.." ) - pod 'EmbraceIO-DEV' + pod 'EmbraceIO', '6.3.0-rc2' target 'RNEmbraceTests' do inherit! :complete diff --git a/packages/core/test-project/ios/Podfile.lock b/packages/core/test-project/ios/Podfile.lock index d0a97269..5fb7d8a4 100644 --- a/packages/core/test-project/ios/Podfile.lock +++ b/packages/core/test-project/ios/Podfile.lock @@ -1,55 +1,55 @@ PODS: - boost (1.83.0) - DoubleConversion (1.1.6) - - EmbraceIO-DEV (6.2.0): - - EmbraceIO-DEV/EmbraceIO (= 6.2.0) - - EmbraceIO-DEV/EmbraceCaptureService (6.2.0): - - EmbraceIO-DEV/EmbraceOTelInternal - - EmbraceIO-DEV/OpenTelemetrySdk - - EmbraceIO-DEV/EmbraceCommonInternal (6.2.0) - - EmbraceIO-DEV/EmbraceConfigInternal (6.2.0): - - EmbraceIO-DEV/EmbraceCommonInternal - - EmbraceIO-DEV/EmbraceCore (6.2.0): - - EmbraceIO-DEV/EmbraceCaptureService - - EmbraceIO-DEV/EmbraceCommonInternal - - EmbraceIO-DEV/EmbraceConfigInternal - - EmbraceIO-DEV/EmbraceObjCUtilsInternal - - EmbraceIO-DEV/EmbraceOTelInternal - - EmbraceIO-DEV/EmbraceStorageInternal - - EmbraceIO-DEV/EmbraceUploadInternal - - EmbraceIO-DEV/EmbraceCrash (6.2.0): - - EmbraceIO-DEV/EmbraceCommonInternal - - EmbraceIO-DEV/KSCrash - - EmbraceIO-DEV/EmbraceIO (6.2.0): - - EmbraceIO-DEV/EmbraceCaptureService - - EmbraceIO-DEV/EmbraceCommonInternal - - EmbraceIO-DEV/EmbraceCore - - EmbraceIO-DEV/EmbraceCrash - - EmbraceIO-DEV/EmbraceObjCUtilsInternal (6.2.0) - - EmbraceIO-DEV/EmbraceOTelInternal (6.2.0): - - EmbraceIO-DEV/EmbraceCommonInternal - - EmbraceIO-DEV/OpenTelemetrySdk - - EmbraceIO-DEV/EmbraceStorageInternal (6.2.0): - - EmbraceIO-DEV/EmbraceCommonInternal - - EmbraceIO-DEV/GRDB - - EmbraceIO-DEV/OpenTelemetryApi - - EmbraceIO-DEV/EmbraceUploadInternal (6.2.0): - - EmbraceIO-DEV/EmbraceCommonInternal - - EmbraceIO-DEV/EmbraceOTelInternal - - EmbraceIO-DEV/GRDB - - EmbraceIO-DEV/GRDB (6.2.0) - - EmbraceIO-DEV/KSCrash (6.2.0): - - EmbraceIO-DEV/KSCrashCore - - EmbraceIO-DEV/KSCrashRecording - - EmbraceIO-DEV/KSCrashRecordingCore - - EmbraceIO-DEV/KSCrashCore (6.2.0) - - EmbraceIO-DEV/KSCrashRecording (6.2.0): - - EmbraceIO-DEV/KSCrashRecordingCore - - EmbraceIO-DEV/KSCrashRecordingCore (6.2.0): - - EmbraceIO-DEV/KSCrashCore - - EmbraceIO-DEV/OpenTelemetryApi (6.2.0) - - EmbraceIO-DEV/OpenTelemetrySdk (6.2.0): - - EmbraceIO-DEV/OpenTelemetryApi + - EmbraceIO (6.3.0-rc2): + - EmbraceIO/EmbraceIO (= 6.3.0-rc2) + - EmbraceIO/EmbraceCaptureService (6.3.0-rc2): + - EmbraceIO/EmbraceOTelInternal + - EmbraceIO/OpenTelemetrySdk + - EmbraceIO/EmbraceCommonInternal (6.3.0-rc2) + - EmbraceIO/EmbraceConfigInternal (6.3.0-rc2): + - EmbraceIO/EmbraceCommonInternal + - EmbraceIO/EmbraceCore (6.3.0-rc2): + - EmbraceIO/EmbraceCaptureService + - EmbraceIO/EmbraceCommonInternal + - EmbraceIO/EmbraceConfigInternal + - EmbraceIO/EmbraceObjCUtilsInternal + - EmbraceIO/EmbraceOTelInternal + - EmbraceIO/EmbraceStorageInternal + - EmbraceIO/EmbraceUploadInternal + - EmbraceIO/EmbraceCrash (6.3.0-rc2): + - EmbraceIO/EmbraceCommonInternal + - EmbraceIO/KSCrash + - EmbraceIO/EmbraceIO (6.3.0-rc2): + - EmbraceIO/EmbraceCaptureService + - EmbraceIO/EmbraceCommonInternal + - EmbraceIO/EmbraceCore + - EmbraceIO/EmbraceCrash + - EmbraceIO/EmbraceObjCUtilsInternal (6.3.0-rc2) + - EmbraceIO/EmbraceOTelInternal (6.3.0-rc2): + - EmbraceIO/EmbraceCommonInternal + - EmbraceIO/OpenTelemetrySdk + - EmbraceIO/EmbraceStorageInternal (6.3.0-rc2): + - EmbraceIO/EmbraceCommonInternal + - EmbraceIO/GRDB + - EmbraceIO/OpenTelemetryApi + - EmbraceIO/EmbraceUploadInternal (6.3.0-rc2): + - EmbraceIO/EmbraceCommonInternal + - EmbraceIO/EmbraceOTelInternal + - EmbraceIO/GRDB + - EmbraceIO/GRDB (6.3.0-rc2) + - EmbraceIO/KSCrash (6.3.0-rc2): + - EmbraceIO/KSCrashCore + - EmbraceIO/KSCrashRecording + - EmbraceIO/KSCrashRecordingCore + - EmbraceIO/KSCrashCore (6.3.0-rc2) + - EmbraceIO/KSCrashRecording (6.3.0-rc2): + - EmbraceIO/KSCrashRecordingCore + - EmbraceIO/KSCrashRecordingCore (6.3.0-rc2): + - EmbraceIO/KSCrashCore + - EmbraceIO/OpenTelemetryApi (6.3.0-rc2) + - EmbraceIO/OpenTelemetrySdk (6.3.0-rc2): + - EmbraceIO/OpenTelemetryApi - FBLazyVector (0.74.2) - fmt (9.1.0) - glog (0.3.5) @@ -1219,7 +1219,7 @@ PODS: DEPENDENCIES: - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - - EmbraceIO-DEV + - EmbraceIO (= 6.3.0-rc2) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - fmt (from `../node_modules/react-native/third-party-podspecs/fmt.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) @@ -1276,8 +1276,8 @@ DEPENDENCIES: - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: - trunk: - - EmbraceIO-DEV + https://github.com/CocoaPods/Specs.git: + - EmbraceIO - SocketRocket EXTERNAL SOURCES: @@ -1394,13 +1394,13 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost: d3f49c53809116a5d38da093a8aa78bf551aed09 DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5 - EmbraceIO-DEV: e5a181403de0321379e825165aacc54b34006fbe + EmbraceIO: 181e207cf37ba753ba4feea3cb90ed75fecdf87d FBLazyVector: 4bc164e5b5e6cfc288d2b5ff28643ea15fa1a589 fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120 glog: fdfdfe5479092de0c4bdbebedd9056951f092c4f hermes-engine: 01d3e052018c2a13937aca1860fbedbccd4a41b7 RCT-Folly: 02617c592a293bd6d418e0a88ff4ee1f88329b47 - RCTDeprecation: e989346ee1f1a0e6c155ac0969f7834b043b2f08 + RCTDeprecation: b03c35057846b685b3ccadc9bfe43e349989cdb2 RCTRequired: 194626909cfa8d39ca6663138c417bc6c431648c RCTTypeSafety: 552aff5b8e8341660594db00e53ac889682bc120 React: a57fe42044fe6ed3e828f8867ce070a6c5872754 @@ -1449,6 +1449,6 @@ SPEC CHECKSUMS: SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d Yoga: 2f71ecf38d934aecb366e686278102a51679c308 -PODFILE CHECKSUM: 787db13145fa01b0f3ed78f910b313a13dfabee3 +PODFILE CHECKSUM: ce7b20e3b58dbda25946831248360e03f30b3976 -COCOAPODS: 1.11.3 +COCOAPODS: 1.15.2 diff --git a/packages/core/test-project/ios/RNEmbraceTestProject.xcodeproj/project.pbxproj b/packages/core/test-project/ios/RNEmbraceTestProject.xcodeproj/project.pbxproj index f7fbf3a2..bc3a6e4b 100644 --- a/packages/core/test-project/ios/RNEmbraceTestProject.xcodeproj/project.pbxproj +++ b/packages/core/test-project/ios/RNEmbraceTestProject.xcodeproj/project.pbxproj @@ -12,8 +12,8 @@ 30DFDA6A2C486677009F2ECC /* RNEmbrace.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30DFDA622C486677009F2ECC /* RNEmbrace.framework */; }; 30DFDA6F2C486677009F2ECC /* RNEmbraceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30DFDA6E2C486677009F2ECC /* RNEmbraceTests.swift */; }; 30DFDA7A2C4866AA009F2ECC /* EmbraceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30DFDA782C4866AA009F2ECC /* EmbraceManager.swift */; }; - 3F9446F81086437913617695 /* libPods-RNEmbrace-RNEmbraceTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 84B378AFFF06A00CDD90700A /* libPods-RNEmbrace-RNEmbraceTests.a */; }; - D18EC446A0FD477DD3C14E3F /* libPods-RNEmbrace.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2971EBAF870951D46C499FF6 /* libPods-RNEmbrace.a */; }; + 90981A0E3E223D9B7EF874DA /* libPods-RNEmbrace-RNEmbraceTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CCD073A43A2F86D1207905EE /* libPods-RNEmbrace-RNEmbraceTests.a */; }; + E7CE82A26358CF89CDA9CED4 /* libPods-RNEmbrace.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CE67B0F47E43D18BABCC7454 /* libPods-RNEmbrace.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -27,18 +27,18 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 2971EBAF870951D46C499FF6 /* libPods-RNEmbrace.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNEmbrace.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1B0AE27C282CB3CF63E4F284 /* Pods-RNEmbrace.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace.debug.xcconfig"; path = "Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace.debug.xcconfig"; sourceTree = ""; }; 308F09282C4EED4200C1EB4C /* EmbraceManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EmbraceManager.m; sourceTree = ""; }; 308F092A2C4EF1FE00C1EB4C /* SpanRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpanRepository.swift; sourceTree = ""; }; 30DFDA622C486677009F2ECC /* RNEmbrace.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RNEmbrace.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 30DFDA692C486677009F2ECC /* RNEmbraceTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNEmbraceTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 30DFDA6E2C486677009F2ECC /* RNEmbraceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNEmbraceTests.swift; sourceTree = ""; }; 30DFDA782C4866AA009F2ECC /* EmbraceManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmbraceManager.swift; sourceTree = ""; }; - 6207261ABCF304D9D0A11328 /* Pods-RNEmbrace.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace.debug.xcconfig"; path = "Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace.debug.xcconfig"; sourceTree = ""; }; - 84B378AFFF06A00CDD90700A /* libPods-RNEmbrace-RNEmbraceTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNEmbrace-RNEmbraceTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 91F66420189F99483A85657C /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig"; path = "Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig"; sourceTree = ""; }; - B22986E47D154AD67F3DD423 /* Pods-RNEmbrace.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace.release.xcconfig"; path = "Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace.release.xcconfig"; sourceTree = ""; }; - DCF1830916CC2D1329507B44 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace-RNEmbraceTests.release.xcconfig"; path = "Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests.release.xcconfig"; sourceTree = ""; }; + 4429624C7D4FD60C6D020CE2 /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig"; path = "Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig"; sourceTree = ""; }; + 9EA561A7D957BE59B3F8CAB4 /* Pods-RNEmbrace.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace.release.xcconfig"; path = "Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace.release.xcconfig"; sourceTree = ""; }; + CCD073A43A2F86D1207905EE /* libPods-RNEmbrace-RNEmbraceTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNEmbrace-RNEmbraceTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + CE67B0F47E43D18BABCC7454 /* libPods-RNEmbrace.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNEmbrace.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + CECDD3B34AFDD805243274E6 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace-RNEmbraceTests.release.xcconfig"; path = "Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -46,7 +46,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D18EC446A0FD477DD3C14E3F /* libPods-RNEmbrace.a in Frameworks */, + E7CE82A26358CF89CDA9CED4 /* libPods-RNEmbrace.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -55,7 +55,7 @@ buildActionMask = 2147483647; files = ( 30DFDA6A2C486677009F2ECC /* RNEmbrace.framework in Frameworks */, - 3F9446F81086437913617695 /* libPods-RNEmbrace-RNEmbraceTests.a in Frameworks */, + 90981A0E3E223D9B7EF874DA /* libPods-RNEmbrace-RNEmbraceTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -65,10 +65,10 @@ 0C8E90FDF3018EA1FCF9459E /* Pods */ = { isa = PBXGroup; children = ( - 6207261ABCF304D9D0A11328 /* Pods-RNEmbrace.debug.xcconfig */, - B22986E47D154AD67F3DD423 /* Pods-RNEmbrace.release.xcconfig */, - 91F66420189F99483A85657C /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */, - DCF1830916CC2D1329507B44 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */, + 1B0AE27C282CB3CF63E4F284 /* Pods-RNEmbrace.debug.xcconfig */, + 9EA561A7D957BE59B3F8CAB4 /* Pods-RNEmbrace.release.xcconfig */, + 4429624C7D4FD60C6D020CE2 /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */, + CECDD3B34AFDD805243274E6 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -80,7 +80,7 @@ 30DFDA6D2C486677009F2ECC /* RNEmbraceTests */, 30DFDA102C485A70009F2ECC /* Products */, 0C8E90FDF3018EA1FCF9459E /* Pods */, - C9F3B360627742333C49BB21 /* Frameworks */, + E5B1071567D885CD37BDEA68 /* Frameworks */, ); sourceTree = ""; }; @@ -112,11 +112,11 @@ path = RNEmbraceTests; sourceTree = ""; }; - C9F3B360627742333C49BB21 /* Frameworks */ = { + E5B1071567D885CD37BDEA68 /* Frameworks */ = { isa = PBXGroup; children = ( - 2971EBAF870951D46C499FF6 /* libPods-RNEmbrace.a */, - 84B378AFFF06A00CDD90700A /* libPods-RNEmbrace-RNEmbraceTests.a */, + CE67B0F47E43D18BABCC7454 /* libPods-RNEmbrace.a */, + CCD073A43A2F86D1207905EE /* libPods-RNEmbrace-RNEmbraceTests.a */, ); name = Frameworks; sourceTree = ""; @@ -138,12 +138,12 @@ isa = PBXNativeTarget; buildConfigurationList = 30DFDA712C486677009F2ECC /* Build configuration list for PBXNativeTarget "RNEmbrace" */; buildPhases = ( - 7D91ADB8297CC292259545D5 /* [CP] Check Pods Manifest.lock */, + 38BE037C70EEF2C63333D2C4 /* [CP] Check Pods Manifest.lock */, 30DFDA5D2C486677009F2ECC /* Headers */, 30DFDA5E2C486677009F2ECC /* Sources */, 30DFDA5F2C486677009F2ECC /* Frameworks */, 30DFDA602C486677009F2ECC /* Resources */, - 1BE76E2FFC098832273CFF81 /* [CP] Copy Pods Resources */, + D8D968B1E719FC35B69D2353 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -158,13 +158,13 @@ isa = PBXNativeTarget; buildConfigurationList = 30DFDA742C486677009F2ECC /* Build configuration list for PBXNativeTarget "RNEmbraceTests" */; buildPhases = ( - 89172ED4C9BA29D058B75BF7 /* [CP] Check Pods Manifest.lock */, + 6866A9F75E458E397EB1A5B8 /* [CP] Check Pods Manifest.lock */, 3023F50B2C52EA4300981C97 /* ShellScript */, 30DFDA652C486677009F2ECC /* Sources */, 30DFDA662C486677009F2ECC /* Frameworks */, 30DFDA672C486677009F2ECC /* Resources */, - 95A88EC839F3EE2753782849 /* [CP] Embed Pods Frameworks */, - 9C5E00AB9FBD971682159A46 /* [CP] Copy Pods Resources */, + 84A3D0A057AE88025F30B1AD /* [CP] Embed Pods Frameworks */, + 298F6EE6E6E51B827AA83A5C /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -232,21 +232,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 1BE76E2FFC098832273CFF81 /* [CP] Copy Pods Resources */ = { + 298F6EE6E6E51B827AA83A5C /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; 3023F50B2C52EA4300981C97 /* ShellScript */ = { @@ -266,7 +266,7 @@ shellPath = /bin/sh; shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; }; - 7D91ADB8297CC292259545D5 /* [CP] Check Pods Manifest.lock */ = { + 38BE037C70EEF2C63333D2C4 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -288,7 +288,7 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 89172ED4C9BA29D058B75BF7 /* [CP] Check Pods Manifest.lock */ = { + 6866A9F75E458E397EB1A5B8 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -310,7 +310,7 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 95A88EC839F3EE2753782849 /* [CP] Embed Pods Frameworks */ = { + 84A3D0A057AE88025F30B1AD /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -327,21 +327,21 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 9C5E00AB9FBD971682159A46 /* [CP] Copy Pods Resources */ = { + D8D968B1E719FC35B69D2353 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace-resources-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace-resources.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -523,7 +523,7 @@ }; 30DFDA722C486677009F2ECC /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6207261ABCF304D9D0A11328 /* Pods-RNEmbrace.debug.xcconfig */; + baseConfigurationReference = 1B0AE27C282CB3CF63E4F284 /* Pods-RNEmbrace.debug.xcconfig */; buildSettings = { BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; @@ -561,7 +561,7 @@ }; 30DFDA732C486677009F2ECC /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B22986E47D154AD67F3DD423 /* Pods-RNEmbrace.release.xcconfig */; + baseConfigurationReference = 9EA561A7D957BE59B3F8CAB4 /* Pods-RNEmbrace.release.xcconfig */; buildSettings = { BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; @@ -598,7 +598,7 @@ }; 30DFDA752C486677009F2ECC /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 91F66420189F99483A85657C /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */; + baseConfigurationReference = 4429624C7D4FD60C6D020CE2 /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; @@ -617,7 +617,7 @@ }; 30DFDA762C486677009F2ECC /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DCF1830916CC2D1329507B44 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */; + baseConfigurationReference = CECDD3B34AFDD805243274E6 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; diff --git a/packages/core/test-project/ios/RNEmbraceTests/RNEmbraceTests.swift b/packages/core/test-project/ios/RNEmbraceTests/RNEmbraceTests.swift index 449c0b4c..6af2c281 100644 --- a/packages/core/test-project/ios/RNEmbraceTests/RNEmbraceTests.swift +++ b/packages/core/test-project/ios/RNEmbraceTests/RNEmbraceTests.swift @@ -41,7 +41,7 @@ class Promise { } } -private let EMBRACE_INTERNAL_SPAN_NAMES = ["emb-session", "emb-sdk-start", "emb-process-launch", +private let EMBRACE_INTERNAL_SPAN_NAMES = ["emb-session", "emb-sdk-start", "emb-setup", "emb-process-launch", "POST /v2/logs", "POST /v2/spans"] class EmbraceManagerTests: XCTestCase { @@ -266,7 +266,8 @@ class EmbraceSpansTests: XCTestCase { XCTAssertEqual(promise.rejectCalls[0], "Could not retrieve a span with the given id") } - func testAddSpanEvent() async throws { + // TODO fails on 6.3 currently due to span.flush call + func skipped_testAddSpanEvent() async throws { module.startSpan("my-span", parentSpanId: "", startTimeMs: 0.0, resolver: promise.resolve, rejecter: promise.reject) XCTAssertEqual(promise.resolveCalls.count, 1) @@ -325,7 +326,8 @@ class EmbraceSpansTests: XCTestCase { XCTAssertEqual(promise.rejectCalls[0], "Could not retrieve a span with the given id") } - func testAddSpanAttribute() async throws { + // TODO fails on 6.3 currently due to span.flush call + func skipped_testAddSpanAttribute() async throws { module.startSpan("my-span", parentSpanId: "", startTimeMs: 0.0, resolver: promise.resolve, rejecter: promise.reject) XCTAssertEqual(promise.resolveCalls.count, 1) @@ -452,7 +454,7 @@ class EmbraceSpansTests: XCTestCase { XCTAssertTrue(exportedSpans[2].hasEnded) } - // TODO fails on 6.2 currently + // TODO fails on 6.3 currently func skipped_testRecordCompletedSpanWithErrorCode() async throws { module.recordCompletedSpan("my-span", startTimeMs: 0.0, endTimeMs: 0.0, errorCodeString: "Failure", parentSpanId: "", @@ -468,7 +470,8 @@ class EmbraceSpansTests: XCTestCase { XCTAssertEqual(exportedSpans[0].attributes["emb.error_code"]!.description, "failure") } - func testCompletedSpansRemovedOnSessionEnd() async throws { + // TODO fails on 6.3 currently due to span.flush call + func skipped_testCompletedSpansRemovedOnSessionEnd() async throws { module.startSpan("stopped-span", parentSpanId: "", startTimeMs: 0.0, resolver: promise.resolve, rejecter: promise.reject) module.startSpan("active-span", parentSpanId: "", startTimeMs: 0.0, From 6f353ccdae9de464f5ae0336554717180d3fb008 Mon Sep 17 00:00:00 2001 From: Jonathan Munz Date: Wed, 7 Aug 2024 13:52:37 -0400 Subject: [PATCH 4/7] EMBR-4612 use nulls for timestamps on android instead of 0 (#64) --- .../embracewrapper/EmbraceManagerModule.java | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/packages/core/android/src/main/java/io/embrace/embracewrapper/EmbraceManagerModule.java b/packages/core/android/src/main/java/io/embrace/embracewrapper/EmbraceManagerModule.java index 7805422e..050c9835 100644 --- a/packages/core/android/src/main/java/io/embrace/embracewrapper/EmbraceManagerModule.java +++ b/packages/core/android/src/main/java/io/embrace/embracewrapper/EmbraceManagerModule.java @@ -434,11 +434,11 @@ public void logNetworkClientError(String url, } @ReactMethod() - public void startSpan(String name, String parentSpanId, Double startTimeNanos, Promise promise) { + public void startSpan(String name, String parentSpanId, Double startTimeMs, Promise promise) { try{ Long startTime = null; - if(startTimeNanos != null){ - startTime = startTimeNanos.longValue(); + if(startTimeMs != null && startTimeMs > 0){ + startTime = startTimeMs.longValue(); } promise.resolve(Embrace.getInstance().getReactNativeInternalInterface().startSpan(name, parentSpanId, startTime)); }catch(Exception e){ @@ -486,9 +486,9 @@ private List> transformListReadableMapToListMap(ReadableArra if (readableMap != null) { Map map = readableMap.toHashMap(); // TODO Change when Android/iOS replace time in nano for ms - if (map.containsKey("timestampNanos") && map.get("timestampNanos") instanceof Double) { - double timestampNanos = (Double) map.get("timestampNanos"); - map.put("timestampNanos", (long) timestampNanos); + if (map.containsKey("timestampMs") && map.get("timestampMs") instanceof Double) { + double timestampMs = (Double) map.get("timestampMs"); + map.put("timestampMs", (long) timestampMs); } objectMapList.add(map); } @@ -501,12 +501,13 @@ private List> transformListReadableMapToListMap(ReadableArra } @ReactMethod() - public void stopSpan(String spanId, String errorCodeString, Double endTimeNanos, Promise promise) { + public void stopSpan(String spanId, String errorCodeString, Double endTimeMs, Promise promise) { try{ Long endTime = null; - if(endTimeNanos != null){ - endTime = endTimeNanos.longValue(); + if(endTimeMs != null && endTimeMs > 0){ + endTime = endTimeMs.longValue(); } + ErrorCode errorCodeInstance = this.getSpanErrorCodebyString(errorCodeString); promise.resolve(Embrace.getInstance().getReactNativeInternalInterface().stopSpan(spanId, errorCodeInstance, endTime)); }catch(Exception e){ @@ -534,11 +535,21 @@ public void addSpanEventToSpan(String spanId, String name, Double time, Readable } @ReactMethod() - public void recordCompletedSpan(String name, Double startTimeNanos, Double endTimeNanos, String errorCodeString, String parentSpanId, ReadableMap attributes, ReadableArray events, Promise promise) { + public void recordCompletedSpan(String name, Double startTimeMs, Double endTimeMs, String errorCodeString, String parentSpanId, ReadableMap attributes, ReadableArray events, Promise promise) { try{ ErrorCode errorCodeInstance = this.getSpanErrorCodebyString(errorCodeString); - promise.resolve(Embrace.getInstance().getReactNativeInternalInterface().recordCompletedSpan(name, startTimeNanos.longValue(), endTimeNanos.longValue(), errorCodeInstance, parentSpanId, this.convertToReadableMap(attributes), this.transformListReadableMapToListMap(events))); + Long startTime = null; + if(startTimeMs != null && startTimeMs > 0){ + startTime = startTimeMs.longValue(); + } + + Long endTime = null; + if(endTimeMs != null && endTimeMs > 0){ + endTime = endTimeMs.longValue(); + } + + promise.resolve(Embrace.getInstance().getReactNativeInternalInterface().recordCompletedSpan(name, startTime, endTime, errorCodeInstance, parentSpanId, this.convertToReadableMap(attributes), this.transformListReadableMapToListMap(events))); }catch(Exception e){ promise.resolve(false); } From 1b42a9b2e800ea5ce8219dec5af26a231a062029 Mon Sep 17 00:00:00 2001 From: Jonathan Munz Date: Thu, 8 Aug 2024 09:42:46 -0400 Subject: [PATCH 5/7] EMBR-4627 fix flaky tests (#67) --- packages/core/src/__tests__/embrace.test.ts | 859 ++++++-------------- packages/core/src/__tests__/network.test.ts | 503 +++--------- packages/core/src/index.ts | 7 +- packages/core/src/utils/ErrorUtil.ts | 7 +- 4 files changed, 378 insertions(+), 998 deletions(-) diff --git a/packages/core/src/__tests__/embrace.test.ts b/packages/core/src/__tests__/embrace.test.ts index 020267af..ec0d1882 100644 --- a/packages/core/src/__tests__/embrace.test.ts +++ b/packages/core/src/__tests__/embrace.test.ts @@ -1,204 +1,228 @@ -//TODO Check why its failing if we import the constants from the index.ts -// import {INFO, ERROR, WARNING} from "../index"; -const WARNING = "warning"; -const INFO = "info"; -const ERROR = "error"; -const testView = "View"; -const testPersona = "Persona"; -const testUserId = "Lucia"; -const testEmail = "lucia@nimble.la"; -const testKey = "Key"; -const testValue = "Value"; -const testPermanent = false; -const testProps = {testKey: testValue}; -const testMessage = "message"; -const testError = new Error(); - -jest.useFakeTimers(); - -beforeEach(() => { - jest.clearAllMocks().resetModules(); -}); +import {MethodType} from "../interfaces/HTTP"; +import { + addBreadcrumb, + addSessionProperty, + addUserPersona, + clearAllUserPersonas, + clearUserAsPayer, + clearUserEmail, + clearUserIdentifier, + clearUsername, + clearUserPersona, + endView, + getCurrentSessionId, + getDeviceId, + getLastRunEndState, + logError, + logHandledError, + logInfo, + logMessage, + logNetworkClientError, + logScreen, + logWarning, + recordNetworkRequest, + removeSessionProperty, + setJavaScriptBundlePath, + setUserAsPayer, + setUserEmail, + setUserIdentifier, + setUsername, + startView, +} from "../index"; + +const mockSetUserIdentifier = jest.fn(); +const mockClearUserIdentifier = jest.fn(); +const mockSetUsername = jest.fn(); +const mockClearUsername = jest.fn(); +const mockSetUserEmail = jest.fn(); +const mockClearUserEmail = jest.fn(); +const mockAddBreadcrumb = jest.fn(); +const mockLogMessageWithSeverityAndProperties = jest.fn(); +const mockLogHandledError = jest.fn(); +const mockAddUserPersona = jest.fn(); +const mockClearUserPersona = jest.fn(); +const mockClearAllUserPersonas = jest.fn(); +const mockStartView = jest.fn(); +const mockEndView = jest.fn(); +const mockAddSessionProperty = jest.fn(); +const mockRemoveSessionProperty = jest.fn(); +const mockSetUserAsPayer = jest.fn(); +const mockClearUserAsPayer = jest.fn(); +const mockSetJavaScriptBundlePath = jest.fn(); +const mockLogNetworkRequest = jest.fn(); +const mockLogNetworkClientError = jest.fn(); +const mockGetLastRunEndState = jest.fn(); +const mockGetDeviceId = jest.fn(); +const mockGetCurrentSessionId = jest.fn(); + +jest.mock("react-native", () => ({ + NativeModules: { + EmbraceManager: { + setUserIdentifier: (userIdentifier: string) => + mockSetUserIdentifier(userIdentifier), + clearUserIdentifier: () => mockClearUserIdentifier(), + setUsername: (username: string) => mockSetUsername(username), + clearUsername: () => mockClearUsername(), + setUserEmail: (userEmail: string) => mockSetUserEmail(userEmail), + clearUserEmail: () => mockClearUserEmail(), + addBreadcrumb: (message: string) => mockAddBreadcrumb(message), + logMessageWithSeverityAndProperties: ( + message: string, + severity: string, + properties: Record, + stacktrace: string, + ) => + mockLogMessageWithSeverityAndProperties( + message, + severity, + properties, + stacktrace, + ), + logHandledError: (message: string, properties?: Record) => + mockLogHandledError(message, properties), + addUserPersona: (persona: string) => mockAddUserPersona(persona), + clearUserPersona: (persona: string) => mockClearUserPersona(persona), + clearAllUserPersonas: () => mockClearAllUserPersonas(), + startView: (view: string) => mockStartView(view), + endView: (view: string) => mockEndView(view), + addSessionProperty: (key: string, value: string, permanent: boolean) => + mockAddSessionProperty(key, value, permanent), + removeSessionProperty: (key: string) => mockRemoveSessionProperty(key), + setUserAsPayer: () => mockSetUserAsPayer(), + clearUserAsPayer: () => mockClearUserAsPayer(), + setJavaScriptBundlePath: (path: string) => + mockSetJavaScriptBundlePath(path), + logNetworkRequest: ( + url: string, + httpMethod: MethodType, + startInMillis: number, + endInMillis: number, + bytesSent: number, + bytesReceived: number, + statusCode: number, + error: string, + ) => + mockLogNetworkRequest( + url, + httpMethod, + startInMillis, + endInMillis, + bytesSent, + bytesReceived, + statusCode, + error, + ), + logNetworkClientError: ( + url: string, + httpMethod: MethodType, + startInMillis: number, + endInMillis: number, + errorType: string, + errorMessage: string, + ) => + mockLogNetworkClientError( + url, + httpMethod, + startInMillis, + endInMillis, + errorType, + errorMessage, + ), + getLastRunEndState: () => mockGetLastRunEndState(), + getDeviceId: () => mockGetDeviceId(), + getCurrentSessionId: () => mockGetCurrentSessionId(), + }, + }, +})); + +const mockSt = "this is a fake stack trace"; +const mockGenerateStackTrace = jest.fn(); +jest.mock("../utils/ErrorUtil", () => ({ + ...jest.requireActual("../utils/ErrorUtil"), + generateStackTrace: () => mockGenerateStackTrace(), +})); describe("User Identifier Tests", () => { + const testUserId = "testUser"; + beforeEach(() => { + jest.resetAllMocks(); + }); + test("setUserIdentifier", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - setUserIdentifier: mock, - }, - }, - }), - {virtual: true}, - ); - const {setUserIdentifier} = require("../index"); await setUserIdentifier(testUserId); - expect(mock).toHaveBeenCalledWith(testUserId); + expect(mockSetUserIdentifier).toHaveBeenCalledWith(testUserId); }); test("clearUserIdentifier", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - clearUserIdentifier: mock, - }, - }, - }), - {virtual: true}, - ); - - const {clearUserIdentifier} = require("../index"); await clearUserIdentifier(); - expect(mock).toHaveBeenCalled(); + expect(mockClearUserIdentifier).toHaveBeenCalled(); }); }); describe("User Data Tests", () => { + const testUserId = "testUser"; + const testEmail = "test@test.com"; + test("setUsername", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - setUsername: mock, - }, - }, - }), - {virtual: true}, - ); - const {setUsername} = require("../index"); await setUsername(testUserId); - expect(mock).toHaveBeenCalledWith(testUserId); + expect(mockSetUsername).toHaveBeenCalledWith(testUserId); }); test("clearUsername", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - clearUsername: mock, - }, - }, - }), - {virtual: true}, - ); - const {clearUsername} = require("../index"); await clearUsername(); - expect(mock).toHaveBeenCalled(); + expect(mockClearUsername).toHaveBeenCalled(); }); test("setUserEmail", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - setUserEmail: mock, - }, - }, - }), - {virtual: true}, - ); - const {setUserEmail} = require("../index"); await setUserEmail(testEmail); - expect(mock).toHaveBeenCalledWith(testEmail); + expect(mockSetUserEmail).toHaveBeenCalledWith(testEmail); }); test("clearUserEmail", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - clearUserEmail: mock, - }, - }, - }), - {virtual: true}, - ); - const {clearUserEmail} = require("../index"); await clearUserEmail(); - expect(mock).toHaveBeenCalled(); + expect(mockClearUserEmail).toHaveBeenCalled(); }); }); describe("Logs Test", () => { + const WARNING = "warning"; + const INFO = "info"; + const ERROR = "error"; + const testView = "View"; + + beforeEach(() => { + mockGenerateStackTrace.mockReturnValue(mockSt); + }); + test("addBreadcrumb", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - addBreadcrumb: mock, - }, - }, - }), - {virtual: true}, - ); - const {addBreadcrumb} = require("../index"); await addBreadcrumb(testView); - expect(mock).toHaveBeenCalledWith(testView); + expect(mockAddBreadcrumb).toHaveBeenCalledWith(testView); }); test("logScreen", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - addBreadcrumb: mock, - }, - }, - }), - {virtual: true}, - ); - const {logScreen} = require("../index"); await logScreen(testView); - expect(mock).toHaveBeenCalledWith(`Opening screen [${testView}]`); + expect(mockAddBreadcrumb).toHaveBeenCalledWith( + `Opening screen [${testView}]`, + ); }); describe("logMessage", () => { - const mockSt = "this is a fake stack trace"; + const testMessage = "message"; + const testProps = {foo: "bar"}; + test.each` - message | severity | properties | allowScreenshot | stackTrace - ${testMessage} | ${INFO} | ${testProps} | ${false} | ${""} - ${testMessage} | ${INFO} | ${testProps} | ${true} | ${""} - ${testMessage} | ${WARNING} | ${testProps} | ${false} | ${mockSt} - ${testMessage} | ${WARNING} | ${testProps} | ${true} | ${mockSt} - ${testMessage} | ${ERROR} | ${testProps} | ${false} | ${mockSt} - ${testMessage} | ${ERROR} | ${testProps} | ${true} | ${mockSt} + message | severity | properties | stackTrace + ${testMessage} | ${INFO} | ${testProps} | ${""} + ${testMessage} | ${INFO} | ${testProps} | ${""} + ${testMessage} | ${WARNING} | ${testProps} | ${mockSt} + ${testMessage} | ${WARNING} | ${testProps} | ${mockSt} + ${testMessage} | ${ERROR} | ${testProps} | ${mockSt} + ${testMessage} | ${ERROR} | ${testProps} | ${mockSt} `( "should run $severity log", - async ({message, severity, properties, allowScreenshot, stackTrace}) => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - logMessageWithSeverityAndProperties: mock, - }, - }, - }), - {virtual: true}, - ); - const embrace = require("../index"); - embrace.generateStackTrace = () => (severity === INFO ? "" : mockSt); - await embrace.logMessage(message, severity, properties); - expect(mock).toHaveBeenCalledWith( + async ({message, severity, properties, stackTrace}) => { + await logMessage(message, severity, properties); + expect(mockLogMessageWithSeverityAndProperties).toHaveBeenCalledWith( message, severity, properties, @@ -209,391 +233,120 @@ describe("Logs Test", () => { }); test("logInfo", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - logMessageWithSeverityAndProperties: mock, - }, - }, - }), - {virtual: true}, - ); - const {logInfo} = require("../index"); await logInfo("test message"); - expect(mock).toHaveBeenCalledWith(`test message`, INFO, undefined, ""); + expect(mockLogMessageWithSeverityAndProperties).toHaveBeenCalledWith( + `test message`, + INFO, + undefined, + "", + ); }); test("logWarning", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - logMessageWithSeverityAndProperties: mock, - }, - }, - }), - {virtual: true}, - ); - const {logWarning} = require("../index"); await logWarning("test message"); - expect(mock).toHaveBeenCalledWith( + expect(mockLogMessageWithSeverityAndProperties).toHaveBeenCalledWith( `test message`, WARNING, undefined, - expect.any(String), + mockSt, ); }); test("logError", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - logMessageWithSeverityAndProperties: mock, - }, - }, - }), - {virtual: true}, - ); - const {logError} = require("../index"); await logError("test message"); - expect(mock).toHaveBeenCalledWith( + expect(mockLogMessageWithSeverityAndProperties).toHaveBeenCalledWith( `test message`, ERROR, undefined, - expect.any(String), + mockSt, ); }); }); describe("Log handled Error Tests", () => { + const testError = new Error(); + const testProps = {foo: "bar"}; + test.each` message | properties | out ${"not an error"} | ${undefined} | ${{}} ${testError} | ${undefined} | ${{message: testError.message, stack: testError.stack}} ${testError} | ${testProps} | ${{message: testError.message, stack: testError.stack, properties: testProps}} `("logHandledError", async ({message, out, properties}) => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - logHandledError: mock, - }, - }, - }), - {virtual: true}, - ); - const {logHandledError} = require("../index"); - const promiseToResolve = logHandledError(message, properties); - - jest.runAllTimers(); - const result = await promiseToResolve; + await logHandledError(message, properties); // TODO uncomment the expect once the method is imeplemented - // if (message instanceof Error) { - // expect(mock).toHaveBeenCalledWith(out.message, out.stack, out.properties); + // expect(mockLogHandledError).toHaveBeenCalledWith(out.message, out.stack, out.properties); // } else { - // expect(mock).not.toHaveBeenCalled(); + // expect(mockLogHandledError).not.toHaveBeenCalled(); // } - expect(result).toBe(false); }); }); describe("Personas Tests", () => { + const testPersona = "Persona"; + test("addUserPersona", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - addUserPersona: mock, - }, - }, - }), - {virtual: true}, - ); - const {addUserPersona} = require("../index"); - const promiseToResolve = addUserPersona(testPersona); - jest.runAllTimers(); - await promiseToResolve; - expect(mock).toHaveBeenCalled(); - expect(mock).toHaveBeenCalledWith(testPersona); + await addUserPersona(testPersona); + expect(mockAddUserPersona).toHaveBeenCalledWith(testPersona); }); test("clearUserPersona", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - clearUserPersona: mock, - }, - }, - }), - {virtual: true}, - ); - const {clearUserPersona} = require("../index"); await clearUserPersona(testPersona); - expect(mock).toHaveBeenCalledWith(testPersona); + expect(mockClearUserPersona).toHaveBeenCalledWith(testPersona); }); test("clearAllUserPersonas", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - clearAllUserPersonas: mock, - }, - }, - }), - {virtual: true}, - ); - const {clearAllUserPersonas} = require("../index"); await clearAllUserPersonas(); - expect(mock).toHaveBeenCalled(); + expect(mockClearAllUserPersonas).toHaveBeenCalled(); }); }); describe("Custom Views Tests", () => { - test("startView", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - startView: mock, - }, - }, - }), - {virtual: true}, - ); - const {startView} = require("../index"); - const promiseToResolve = startView(testView); - // expect(mock).toHaveBeenCalledWith(testView); + const testView = "View"; - jest.runAllTimers(); - const result = await promiseToResolve; - // TODO uncomment the expect once the method is imeplemented - // expect(mock).toHaveBeenCalled(); - expect(result).toBe(false); + test("startView", async () => { + await startView(testView); + // TODO uncomment the expect once the method is implemented + // expect(mockStartView).toHaveBeenCalledWith(testView); }); test("endView", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - endView: mock, - }, - }, - }), - {virtual: true}, - ); - const {endView} = require("../index"); - const promiseToResolve = endView(testView); - // expect(mock).toHaveBeenCalledWith(testView); - jest.runAllTimers(); - const result = await promiseToResolve; - // TODO uncomment the expect once the method is imeplemented - // expect(mock).toHaveBeenCalled(); - expect(result).toBe(false); + await endView(testView); + // TODO uncomment the expect once the method is implemented + // expect(mockEndView).toHaveBeenCalledWith(testView); }); }); describe("Session Properties Tests", () => { test("should call addSessionProperty with values", async () => { - const mock = jest.fn(() => Promise.resolve(true)); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - addSessionProperty: mock, - }, - }, - }), - {virtual: true}, - ); - - const {addSessionProperty} = require("../index"); - await addSessionProperty(testKey, testValue, testPermanent); - expect(mock).toHaveBeenCalledWith(testKey, testValue, testPermanent); - }); - - test("addSessionProperty should return success", async () => { - const mock = jest.fn(() => Promise.resolve(true)); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - addSessionProperty: mock, - }, - }, - }), - {virtual: true}, - ); - - const {addSessionProperty} = require("../index"); - await addSessionProperty(testKey, testValue, testPermanent).then( - (success: boolean) => expect(success).toBeTruthy(), - ); + await addSessionProperty("foo", "bar", true); + expect(mockAddSessionProperty).toHaveBeenCalledWith("foo", "bar", true); }); test("removeSessionProperty", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - removeSessionProperty: mock, - }, - }, - }), - {virtual: true}, - ); - - const {removeSessionProperty} = require("../index"); - await removeSessionProperty(testKey); - expect(mock).toHaveBeenCalledWith(testKey); + await removeSessionProperty("foo"); + expect(mockRemoveSessionProperty).toHaveBeenCalledWith("foo"); }); }); describe("Payers Test", () => { test("setUserAsPayer", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - setUserAsPayer: mock, - }, - }, - }), - {virtual: true}, - ); - const {setUserAsPayer} = require("../index"); - const promiseToResolve = setUserAsPayer(); - // expect(mock).toHaveBeenCalled(); - jest.runAllTimers(); - const result = await promiseToResolve; - // TODO uncomment the expect once the method is imeplemented - // expect(mock).toHaveBeenCalled(); - expect(result).toBe(false); + await setUserAsPayer(); + // TODO uncomment the expect once the method is implemented + // expect(mockSetUserAsPayer).toHaveBeenCalled(); }); test("clearUserAsPayer", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - clearUserAsPayer: mock, - }, - }, - }), - {virtual: true}, - ); - const {clearUserAsPayer} = require("../index"); - const promiseToResolve = clearUserAsPayer(); - // expect(mock).toHaveBeenCalled(); - - jest.runAllTimers(); - const result = await promiseToResolve; - // TODO uncomment the expect once the method is imeplemented - // expect(mock).toHaveBeenCalled(); - expect(result).toBe(false); + await clearUserAsPayer(); + // TODO uncomment the expect once the method is implemented + // expect(mockClearUserAsPayer).toHaveBeenCalled(); }); }); describe("JavaScript bundle", () => { test("setJavaScriptBundlePath", async () => { - const mock = jest.fn(); - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - setJavaScriptBundlePath: mock, - }, - }, - })); - const {setJavaScriptBundlePath} = require("../index"); - const path = "path/to/bundle.bundle"; - - await setJavaScriptBundlePath(path); - expect(mock).toHaveBeenCalledWith(path); - }); -}); - -describe("Log network call", () => { - test("recordNetworkRequest", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - logNetworkRequest: mock, - }, - }, - }), - {virtual: true}, - ); - - const {recordNetworkRequest} = require("../index"); - const url = "https://httpbin.org/get"; - const method = "get"; - const nowdate = new Date(); - const st = nowdate.getTime(); - const et = nowdate.setUTCSeconds(30); - const bytesIn = Number(111); - const bytesOut = Number(222); - const networkStatus = Number(200); - const error = null; - - const promiseToResolve = recordNetworkRequest( - url, - method, - st, - et, - bytesIn, - bytesOut, - networkStatus, - error, - ); - - // expect(mock).toHaveBeenCalledWith( - // url, - // method, - // st, - // et, - // bytesIn, - // bytesOut, - // networkStatus, - // error, - // ); - jest.runAllTimers(); - const result = await promiseToResolve; - // TODO uncomment the expect once the method is imeplemented - // expect(mock).toHaveBeenCalled(); - expect(result).toBe(false); + await setJavaScriptBundlePath("path"); + expect(mockSetJavaScriptBundlePath).toHaveBeenCalledWith("path"); }); }); @@ -609,21 +362,7 @@ describe("Record network call", () => { const error = "error"; test("record completed network request", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - logNetworkRequest: mock, - }, - }, - }), - {virtual: false}, - ); - - const {recordNetworkRequest} = require("../index"); - const promiseToResolve = recordNetworkRequest( + await recordNetworkRequest( url, method, st, @@ -633,7 +372,8 @@ describe("Record network call", () => { networkStatus, ); - // expect(mock).toHaveBeenCalledWith( + // TODO uncomment the expect once the method is implemented + // expect(mockLogNetworkRequest).toHaveBeenCalledWith( // url, // method, // st, @@ -643,136 +383,69 @@ describe("Record network call", () => { // networkStatus, // undefined, // ); - jest.runAllTimers(); - const result = await promiseToResolve; - // TODO uncomment the expect once the method is imeplemented - // expect(mock).toHaveBeenCalled(); - expect(result).toBe(false); }); test("record incomplete network request", async () => { - const mock = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - logNetworkRequest: mock, - }, - }, - }), - {virtual: true}, + await recordNetworkRequest( + url, + method, + st, + et, + undefined, + undefined, + undefined, + error, ); - const {recordNetworkRequest} = require("../index"); - const promiseToResolve = recordNetworkRequest(url, method, st, et, error); - - // expect(mock).toHaveBeenCalledWith( + // TODO uncomment the expect once the method is implemented + // expect(mockLogNetworkRequest).toHaveBeenCalledWith( // url, // method, // st, // et, - // error, // -1, // -1, - // undefined, + // -1, + // error, // ); + }); - jest.runAllTimers(); - const result = await promiseToResolve; - // TODO uncomment the expect once the method is imeplemented - // expect(mock).toHaveBeenCalled(); - expect(result).toBe(false); + test("record network client error", async () => { + await logNetworkClientError( + url, + method, + st, + et, + "error-type", + "error-message", + ); + + // TODO uncomment the expect once the method is implemented + // expect(mockLogNetworkClientError).toHaveBeenCalledWith( + // url, + // method, + // st, + // et, + // "error-type", + // "error-message", + // ); }); }); describe("Test Device Stuffs", () => { test("device Id", async () => { - const mock = jest.fn(); - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - getDeviceId: mock, - }, - }, - })); - const {getDeviceId} = require("../index"); await getDeviceId(); - expect(mock).toHaveBeenCalled(); + expect(mockGetDeviceId).toHaveBeenCalled(); }); test("session Id", async () => { - const mock = jest.fn(); - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - getCurrentSessionId: mock, - }, - }, - })); - const {getCurrentSessionId} = require("../index"); await getCurrentSessionId(); - expect(mock).toHaveBeenCalled(); + expect(mockGetCurrentSessionId).toHaveBeenCalled(); }); }); describe("Last Session Info", () => { - test("last run status - CRASH", async () => { - const mockGetLastRunEndState = jest.fn(() => Promise.resolve("CRASH")); - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - getLastRunEndState: mockGetLastRunEndState, - }, - }, - })); - const {getLastRunEndState} = require("../index"); - expect(await getLastRunEndState()).toBe("CRASH"); - }); - test("last run status - CLEAN_EXIT", async () => { - const mockGetLastRunEndState = jest.fn(() => Promise.resolve("CLEAN_EXIT")); - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - getLastRunEndState: mockGetLastRunEndState, - }, - }, - })); - const {getLastRunEndState} = require("../index"); - expect(await getLastRunEndState()).toBe("CLEAN_EXIT"); - }); - test("last run status - INVALID", async () => { - const mockGetLastRunEndState = jest.fn(() => Promise.resolve("INVALID")); - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - getLastRunEndState: mockGetLastRunEndState, - }, - }, - })); - const {getLastRunEndState} = require("../index"); - expect(await getLastRunEndState()).toBe("INVALID"); - }); -}); - -describe("Test OTA Stuffs", () => { - test("set javascript patch number", async () => { - const mock = jest.fn(); - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - setJavaScriptPatchNumber: mock, - }, - }, - })); - const {setJavaScriptPatch} = require("../index"); - await setJavaScriptPatch(); - expect(mock).toHaveBeenCalled(); - }); -}); - -describe("Test testing purpose functions", () => { - test("get stack trace", () => { - const {generateStackTrace} = require("../index"); - expect(generateStackTrace()).toContain("Error:"); + test("last run status", async () => { + await getLastRunEndState(); + expect(mockGetLastRunEndState).toHaveBeenCalled(); }); }); diff --git a/packages/core/src/__tests__/network.test.ts b/packages/core/src/__tests__/network.test.ts index 9e02d535..774b124c 100644 --- a/packages/core/src/__tests__/network.test.ts +++ b/packages/core/src/__tests__/network.test.ts @@ -1,9 +1,92 @@ -jest.useFakeTimers(); +import {MethodType} from "../interfaces/HTTP"; +import {applyNetworkInterceptors} from "../index"; + +const mockLogNetworkRequest = jest.fn(); +const mockLogNetworkClientError = jest.fn(); + +const ReactNativeMock = jest.requireMock("react-native"); + +jest.mock("react-native", () => ({ + NativeModules: { + EmbraceManager: { + logNetworkRequest: ( + url: string, + httpMethod: MethodType, + startInMillis: number, + endInMillis: number, + bytesSent: number, + bytesReceived: number, + statusCode: number, + error: string, + ) => + mockLogNetworkRequest( + url, + httpMethod, + startInMillis, + endInMillis, + bytesSent, + bytesReceived, + statusCode, + error, + ), + logNetworkClientError: ( + url: string, + httpMethod: MethodType, + startInMillis: number, + endInMillis: number, + errorType: string, + errorMessage: string, + ) => + mockLogNetworkClientError( + url, + httpMethod, + startInMillis, + endInMillis, + errorType, + errorMessage, + ), + }, + }, + Platform: {OS: "android"}, +})); + +const getAxiosMocked = () => { + return { + interceptors: { + request: { + handlers: [] as Record, + use( + requestConfig?: (t: any) => any, + requestOnReject?: (t: any) => any, + ) { + this.handlers.push({ + fulfilled: requestConfig, + rejected: requestOnReject, + }); + }, + }, + response: { + handlers: [] as Record, + use( + responseConfig?: (t: any) => any, + responseOnReject?: (t: any) => any, + ) { + this.handlers.push({ + fulfilled: responseConfig, + rejected: responseOnReject, + }); + }, + }, + }, + }; +}; -beforeEach(() => { - jest.clearAllMocks().resetModules(); -}); describe("Log network call With Axios", () => { + beforeEach(() => { + jest.resetAllMocks(); + ReactNativeMock.Platform.OS = "android"; + }); + test("Verify the instance has an Axios structure", () => { const axiosMockedOK = { interceptors: { @@ -33,14 +116,17 @@ describe("Log network call With Axios", () => { }, }; - const {applyNetworkInterceptors} = require("../index"); expect(applyNetworkInterceptors(axiosMockedOK)).resolves.toEqual(true); + // @ts-expect-error testing invalid case expect(applyNetworkInterceptors()).resolves.toEqual(false); + // @ts-expect-error testing invalid case expect(applyNetworkInterceptors(axiosMockedNOK)).resolves.toEqual(false); expect( + // @ts-expect-error testing invalid case applyNetworkInterceptors(axiosMockedNOKJustInterceptor), ).resolves.toEqual(false); expect( + // @ts-expect-error testing invalid case applyNetworkInterceptors(axiosMockedNOKInterceptorWithRequest), ).resolves.toEqual(false); }); @@ -57,54 +143,14 @@ describe("Log network call With Axios", () => { }, }; - const {applyNetworkInterceptors} = require("../index"); - applyNetworkInterceptors(axiosMocked); - expect(axiosMocked.interceptors.request.use).toHaveBeenCalled(); expect(axiosMocked.interceptors.response.use).toHaveBeenCalled(); }); test("Axios 'use' methods should be called with Func", () => { Promise.reject = jest.fn(); - const mockLogNetworkRequest = jest.fn(); - - const axiosMocked = { - interceptors: { - request: { - handlers: [] as Record, - use(requestConfig: (t: any) => {}, requestOnReject: (t: any) => {}) { - this.handlers.push({ - fulfilled: requestConfig, - rejected: requestOnReject, - }); - }, - }, - response: { - handlers: [] as Record, - use( - responseConfig: (t: any) => {}, - responseOnReject: (t: any) => {}, - ) { - this.handlers.push({ - fulfilled: responseConfig, - rejected: responseOnReject, - }); - }, - }, - }, - }; - - jest.mock("react-native", () => ({ - NativeModules: { - EmbraceManager: { - logNetworkRequest: mockLogNetworkRequest, - }, - }, - })); - - const {applyNetworkInterceptors} = require("../index"); - + const axiosMocked = getAxiosMocked(); applyNetworkInterceptors(axiosMocked); expect(axiosMocked.interceptors.request.handlers.length).toEqual(1); @@ -138,34 +184,7 @@ describe("Log network call With Axios", () => { }); test("Axios Request Config param not set", () => { - const axiosMocked = { - interceptors: { - request: { - handlers: [] as Record, - use(requestConfig: (t: any) => {}, requestOnReject: (t: any) => {}) { - this.handlers.push({ - fulfilled: requestConfig, - rejected: requestOnReject, - }); - }, - }, - response: { - handlers: [] as Record, - use( - responseConfig: (t: any) => {}, - responseOnReject: (t: any) => {}, - ) { - this.handlers.push({ - fulfilled: responseConfig, - rejected: responseOnReject, - }); - }, - }, - }, - }; - - const {applyNetworkInterceptors} = require("../index"); - + const axiosMocked = getAxiosMocked(); applyNetworkInterceptors(axiosMocked); expect(axiosMocked.interceptors.request.handlers[0].fulfilled()).toEqual( @@ -175,46 +194,7 @@ describe("Log network call With Axios", () => { test("Shouldn't track network data", () => { Promise.reject = jest.fn(); - const mockLogNetworkRequest = jest.fn(); - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - logNetworkRequest: mockLogNetworkRequest, - }, - }, - }), - {virtual: true}, - ); - const axiosMocked = { - interceptors: { - request: { - handlers: [] as Record, - use(requestConfig: (t: any) => {}, requestOnReject: (t: any) => {}) { - this.handlers.push({ - fulfilled: requestConfig, - rejected: requestOnReject, - }); - }, - }, - response: { - handlers: [] as Record, - use( - responseConfig: (t: any) => {}, - responseOnReject: (t: any) => {}, - ) { - this.handlers.push({ - fulfilled: responseConfig, - rejected: responseOnReject, - }); - }, - }, - }, - }; - - const {applyNetworkInterceptors} = require("../index"); - + const axiosMocked = getAxiosMocked(); applyNetworkInterceptors(axiosMocked); const responsePropMockWithoutMethod = { @@ -263,34 +243,7 @@ describe("Log network call With Axios", () => { }); test("Not tracking bytes", () => { - const axiosMocked = { - interceptors: { - request: { - handlers: [] as Record, - use(requestConfig: (t: any) => {}, requestOnReject: (t: any) => {}) { - this.handlers.push({ - fulfilled: requestConfig, - rejected: requestOnReject, - }); - }, - }, - response: { - handlers: [] as Record, - use( - responseConfig: (t: any) => {}, - responseOnReject: (t: any) => {}, - ) { - this.handlers.push({ - fulfilled: responseConfig, - rejected: responseOnReject, - }); - }, - }, - }, - }; - - const {applyNetworkInterceptors} = require("../index"); - + const axiosMocked = getAxiosMocked(); applyNetworkInterceptors(axiosMocked); const responsePropMock = { @@ -308,47 +261,7 @@ describe("Log network call With Axios", () => { }); test("Track rejected error", () => { - const mockLogNetworkRequest = jest.fn(); - - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - logNetworkRequest: mockLogNetworkRequest, - }, - }, - }), - {virtual: true}, - ); - const axiosMocked = { - interceptors: { - request: { - handlers: [] as Record, - use(requestConfig: (t: any) => {}, requestOnReject: (t: any) => {}) { - this.handlers.push({ - fulfilled: requestConfig, - rejected: requestOnReject, - }); - }, - }, - response: { - handlers: [] as Record, - use( - responseConfig: (t: any) => {}, - responseOnReject: (t: any) => {}, - ) { - this.handlers.push({ - fulfilled: responseConfig, - rejected: responseOnReject, - }); - }, - }, - }, - }; - - const {applyNetworkInterceptors} = require("../index"); - + const axiosMocked = getAxiosMocked(); applyNetworkInterceptors(axiosMocked); const responseErrorPropMock = { @@ -364,50 +277,8 @@ describe("Log network call With Axios", () => { }); test("Track http code != 2xx iOS", () => { - const mockLogNetworkRequest = jest.fn(); - - jest.mock( - "react-native", - () => ({ - Platform: { - OS: "ios", - }, - NativeModules: { - EmbraceManager: { - logNetworkRequest: mockLogNetworkRequest, - }, - }, - }), - {virtual: true}, - ); - const axiosMocked = { - interceptors: { - request: { - handlers: [] as Record, - use(requestConfig: (t: any) => {}, requestOnReject: (t: any) => {}) { - this.handlers.push({ - fulfilled: requestConfig, - rejected: requestOnReject, - }); - }, - }, - response: { - handlers: [] as Record, - use( - responseConfig: (t: any) => {}, - responseOnReject: (t: any) => {}, - ) { - this.handlers.push({ - fulfilled: responseConfig, - rejected: responseOnReject, - }); - }, - }, - }, - }; - - const {applyNetworkInterceptors} = require("../index"); - + ReactNativeMock.Platform.OS = "ios"; + const axiosMocked = getAxiosMocked(); applyNetworkInterceptors(axiosMocked); const responseErrorPropMock = { @@ -432,50 +303,7 @@ describe("Log network call With Axios", () => { }); test("Track http code != 2xx", () => { - const mockLogNetworkClientError = jest.fn(); - - jest.mock( - "react-native", - () => ({ - Platform: { - OS: "android", - }, - NativeModules: { - EmbraceManager: { - logNetworkClientError: mockLogNetworkClientError, - }, - }, - }), - {virtual: true}, - ); - const axiosMocked = { - interceptors: { - request: { - handlers: [] as Record, - use(requestConfig: (t: any) => {}, requestOnReject: (t: any) => {}) { - this.handlers.push({ - fulfilled: requestConfig, - rejected: requestOnReject, - }); - }, - }, - response: { - handlers: [] as Record, - use( - responseConfig: (t: any) => {}, - responseOnReject: (t: any) => {}, - ) { - this.handlers.push({ - fulfilled: responseConfig, - rejected: responseOnReject, - }); - }, - }, - }, - }; - - const {applyNetworkInterceptors} = require("../index"); - + const axiosMocked = getAxiosMocked(); applyNetworkInterceptors(axiosMocked); const responseErrorPropMock = { @@ -500,52 +328,10 @@ describe("Log network call With Axios", () => { }); test("Error on logNetworkRequest", () => { - const mockLogNetworkClientError = () => { + mockLogNetworkClientError.mockImplementation(() => { throw Error; - }; - - jest.mock( - "react-native", - () => ({ - Platform: { - OS: "ios", - }, - NativeModules: { - EmbraceManager: { - logNetworkClientError: mockLogNetworkClientError, - }, - }, - }), - {virtual: true}, - ); - const axiosMocked = { - interceptors: { - request: { - handlers: [] as Record, - use(requestConfig: (t: any) => {}, requestOnReject: (t: any) => {}) { - this.handlers.push({ - fulfilled: requestConfig, - rejected: requestOnReject, - }); - }, - }, - response: { - handlers: [] as Record, - use( - responseConfig: (t: any) => {}, - responseOnReject: (t: any) => {}, - ) { - this.handlers.push({ - fulfilled: responseConfig, - rejected: responseOnReject, - }); - }, - }, - }, - }; - - const {applyNetworkInterceptors} = require("../index"); - + }); + const axiosMocked = getAxiosMocked(); applyNetworkInterceptors(axiosMocked); const responseErrorPropMock = { @@ -568,47 +354,7 @@ describe("Log network call With Axios", () => { }); test("No Track network because the information was incomplete", () => { - const mockLogNetworkRequest = jest.fn(); - - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - logNetworkRequest: mockLogNetworkRequest, - }, - }, - }), - {virtual: true}, - ); - const axiosMocked = { - interceptors: { - request: { - handlers: [] as Record, - use(requestConfig: (t: any) => {}, requestOnReject: (t: any) => {}) { - this.handlers.push({ - fulfilled: requestConfig, - rejected: requestOnReject, - }); - }, - }, - response: { - handlers: [] as Record, - use( - responseConfig: (t: any) => {}, - responseOnReject: (t: any) => {}, - ) { - this.handlers.push({ - fulfilled: responseConfig, - rejected: responseOnReject, - }); - }, - }, - }, - }; - - const {applyNetworkInterceptors} = require("../index"); - + const axiosMocked = getAxiosMocked(); applyNetworkInterceptors(axiosMocked); const responseErrorPropMock = { @@ -630,45 +376,7 @@ describe("Log network call With Axios", () => { }); test("logNetworkRequest failed", () => { - jest.mock( - "react-native", - () => ({ - NativeModules: { - EmbraceManager: { - logNetworkRequest: undefined, - }, - }, - }), - {virtual: true}, - ); - const axiosMocked = { - interceptors: { - request: { - handlers: [] as Record, - use(requestConfig: (t: any) => {}, requestOnReject: (t: any) => {}) { - this.handlers.push({ - fulfilled: requestConfig, - rejected: requestOnReject, - }); - }, - }, - response: { - handlers: [] as Record, - use( - responseConfig: (t: any) => {}, - responseOnReject: (t: any) => {}, - ) { - this.handlers.push({ - fulfilled: responseConfig, - rejected: responseOnReject, - }); - }, - }, - }, - }; - - const {applyNetworkInterceptors} = require("../index"); - + const axiosMocked = getAxiosMocked(); applyNetworkInterceptors(axiosMocked); const responsePropMock = { @@ -697,8 +405,7 @@ describe("Log network call With Axios", () => { }, }; - const {applyNetworkInterceptors} = require("../index"); - + // @ts-expect-error testing invalid case applyNetworkInterceptors(); expect(axiosMocked.interceptors.request.use).toHaveBeenCalledTimes(0); diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 8fca900e..da1ba78f 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -3,7 +3,7 @@ import {NativeModules, Platform} from "react-native"; import * as embracePackage from "../package.json"; -import {handleGlobalError} from "./utils/ErrorUtil"; +import {generateStackTrace, handleGlobalError} from "./utils/ErrorUtil"; import {ApplyInterceptorStrategy} from "./networkInterceptors/ApplyInterceptor"; import {SessionStatus} from "./interfaces/Types"; import { @@ -248,11 +248,6 @@ export const endView = (view: string): Promise => { return createFalsePromise(); }; -export const generateStackTrace = (): string => { - const err = new Error(); - return err.stack || ""; -}; - export const setJavaScriptPatch = (patch: string) => { return NativeModules.EmbraceManager.setJavaScriptPatchNumber(patch); }; diff --git a/packages/core/src/utils/ErrorUtil.ts b/packages/core/src/utils/ErrorUtil.ts index 68598d42..bbd71bb5 100644 --- a/packages/core/src/utils/ErrorUtil.ts +++ b/packages/core/src/utils/ErrorUtil.ts @@ -15,4 +15,9 @@ const handleGlobalError: GlobalErrorHandler = handleError(error, callback); }; -export {handleGlobalError}; +const generateStackTrace = (): string => { + const err = new Error(); + return err.stack || ""; +}; + +export {handleGlobalError, generateStackTrace}; From 07485176a2e8fc426f7b539ec49f5083356bac6e Mon Sep 17 00:00:00 2001 From: Jonathan Munz Date: Thu, 8 Aug 2024 09:43:01 -0400 Subject: [PATCH 6/7] EMBR-4625 handle removing session properties for all lifespans (#66) --- packages/core/ios/RNEmbrace/EmbraceManager.swift | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/core/ios/RNEmbrace/EmbraceManager.swift b/packages/core/ios/RNEmbrace/EmbraceManager.swift index d1528ced..4a0aa035 100644 --- a/packages/core/ios/RNEmbrace/EmbraceManager.swift +++ b/packages/core/ios/RNEmbrace/EmbraceManager.swift @@ -262,8 +262,11 @@ class EmbraceManager: NSObject { @objc(removeSessionProperty:resolver:rejecter:) func removeSessionProperty(_ key: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { do { - // TODO REfactor to include lifespan - try Embrace.client?.metadata.removeProperty(key: key) + // Depending on on how `addSessionProperty` was called we may have added this key as either + // .session or .permanent so remove both here, multiple calls to remove are safe + try Embrace.client?.metadata.removeProperty(key: key, lifespan: .permanent) + try Embrace.client?.metadata.removeProperty(key: key, lifespan: .session) + resolve(true) } catch let error { reject("REMOVE_SESSION_PROPERTY", "Error removing Session Property", error) From 521b29ea7305e92c2b9f29501f704c7a04bd3ca2 Mon Sep 17 00:00:00 2001 From: Jonathan Munz Date: Fri, 9 Aug 2024 09:26:08 -0400 Subject: [PATCH 7/7] EMBR-4634 update to ios 6.3.0 (#68) --- packages/core/RNEmbrace.podspec | 2 +- .../core/ios/RNEmbrace/EmbraceManager.swift | 25 ++-- packages/core/test-project/ios/Podfile | 2 +- packages/core/test-project/ios/Podfile.lock | 49 ++++---- .../project.pbxproj | 108 +++++++++--------- .../ios/RNEmbraceTests/RNEmbraceTests.swift | 9 +- 6 files changed, 98 insertions(+), 97 deletions(-) diff --git a/packages/core/RNEmbrace.podspec b/packages/core/RNEmbrace.podspec index 75fc14f6..7375f49b 100644 --- a/packages/core/RNEmbrace.podspec +++ b/packages/core/RNEmbrace.podspec @@ -17,5 +17,5 @@ Pod::Spec.new do |s| s.source = {:path => "ios/RNEmbrace/"} s.dependency 'React-Core' - s.dependency 'EmbraceIO-DEV' + s.dependency 'EmbraceIO', '6.3.0' end diff --git a/packages/core/ios/RNEmbrace/EmbraceManager.swift b/packages/core/ios/RNEmbrace/EmbraceManager.swift index 4a0aa035..574a8b9c 100644 --- a/packages/core/ios/RNEmbrace/EmbraceManager.swift +++ b/packages/core/ios/RNEmbrace/EmbraceManager.swift @@ -3,20 +3,16 @@ import React import OSLog import EmbraceIO import EmbraceCrash -import EmbraceCommonInternal // TODO should not be needed -import EmbraceOTelInternal // TODO should not be needed -import EmbraceCaptureService +import EmbraceCommonInternal +import EmbraceOTelInternal #if canImport(CodePush) import CodePush #endif -enum EmbraceKeys: String { - case reactNativeVersion = "io.embrace.reactnative.version" - case embraceReactNativeSdkVersion = "io.embrace.reactnative.sdk.version" - case javaScriptPatchNumber = "io.embrace.javascript.patch" - case javaScriptBundleURL = "io.embrace.jsbundle.url" -} +private let JAVASCRIPT_PATCH_NUMBER_RESOURCE_KEY = "javascript_patch_number" +private let HOSTED_PLATFORM_VERSION_RESOURCE_KEY = "hosted_platform_version" +private let HOSTED_SDK_VERSION_RESOURCE_KEY = "hosted_sdk_version" // Keys defined in packages/spans/interfaces/ISpans.ts private let EVENT_NAME_KEY = "name" @@ -48,7 +44,9 @@ class EmbraceManager: NSObject { @objc(setJavaScriptBundlePath:resolver:rejecter:) func setJavaScriptBundlePath(_ path: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { do { - try Embrace.client?.metadata.addResource(key: EmbraceKeys.javaScriptBundleURL.rawValue, value: path, lifespan: .process) + + // TODO, use path to compute a hash of the assets and add as a 'react_native_bundle_id' key to the resource + // try Embrace.client?.metadata.addResource(key: EmbraceKeys.javaScriptBundleURL.rawValue, value: path, lifespan: .process) resolve(true) } catch let error { reject("SET_JS_BUNDLE_PATH_ERROR", "Error setting JavaScript bundle path", error) @@ -157,7 +155,7 @@ class EmbraceManager: NSObject { @objc(setReactNativeSDKVersion:resolver:rejecter:) func setReactNativeSDKVersion(_ version: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { do { - try Embrace.client?.metadata.addResource(key: EmbraceKeys.embraceReactNativeSdkVersion.rawValue, value: version, lifespan: .process) + try Embrace.client?.metadata.addResource(key: HOSTED_SDK_VERSION_RESOURCE_KEY, value: version, lifespan: .process) resolve(true) } catch let error { reject("SET_RN_SDK_VERSION", "Error setting ReactNative SDK version", error) @@ -180,7 +178,7 @@ class EmbraceManager: NSObject { @objc(setJavaScriptPatchNumber:resolver:rejecter:) func setJavaScriptPatchNumber(_ patch: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { do { - try Embrace.client?.metadata.addResource(key: EmbraceKeys.javaScriptPatchNumber.rawValue, value: patch, lifespan: .process) + try Embrace.client?.metadata.addResource(key: JAVASCRIPT_PATCH_NUMBER_RESOURCE_KEY, value: patch, lifespan: .process) resolve(true) } catch let error { reject("SET_JAVASCRIPT_PATCH_NUMBER", "Error setting JavasScript Patch Number", error) @@ -218,6 +216,7 @@ class EmbraceManager: NSObject { return } + // TODO, use path to compute a hash of the assets and add as a 'react_native_bundle_id' key to the resource try Embrace.client?.metadata.addResource(key: EmbraceKeys.javaScriptBundleURL.rawValue, value: url.path, .process) resolve(true) @@ -252,7 +251,7 @@ class EmbraceManager: NSObject { @objc(setReactNativeVersion:resolver:rejecter:) func setReactNativeVersion(_ version: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) { do { - try Embrace.client?.metadata.addResource(key: EmbraceKeys.reactNativeVersion.rawValue, value: version, lifespan: .process) + try Embrace.client?.metadata.addResource(key: HOSTED_PLATFORM_VERSION_RESOURCE_KEY, value: version, lifespan: .process) resolve(true) } catch let error { reject("SET_RECT_NATIVE_VERSION", "Error setting React Native Number", error) diff --git a/packages/core/test-project/ios/Podfile b/packages/core/test-project/ios/Podfile index e63902dd..d80055ba 100644 --- a/packages/core/test-project/ios/Podfile +++ b/packages/core/test-project/ios/Podfile @@ -25,7 +25,7 @@ target 'RNEmbrace' do :app_path => "#{Pod::Config.instance.installation_root}/.." ) - pod 'EmbraceIO', '6.3.0-rc2' + pod 'EmbraceIO', '6.3.0' target 'RNEmbraceTests' do inherit! :complete diff --git a/packages/core/test-project/ios/Podfile.lock b/packages/core/test-project/ios/Podfile.lock index 5fb7d8a4..59d4fa33 100644 --- a/packages/core/test-project/ios/Podfile.lock +++ b/packages/core/test-project/ios/Podfile.lock @@ -1,54 +1,59 @@ PODS: - boost (1.83.0) - DoubleConversion (1.1.6) - - EmbraceIO (6.3.0-rc2): - - EmbraceIO/EmbraceIO (= 6.3.0-rc2) - - EmbraceIO/EmbraceCaptureService (6.3.0-rc2): + - EmbraceIO (6.3.0): + - EmbraceIO/EmbraceIO (= 6.3.0) + - EmbraceIO/EmbraceCaptureService (6.3.0): - EmbraceIO/EmbraceOTelInternal - EmbraceIO/OpenTelemetrySdk - - EmbraceIO/EmbraceCommonInternal (6.3.0-rc2) - - EmbraceIO/EmbraceConfigInternal (6.3.0-rc2): + - EmbraceIO/EmbraceCommonInternal (6.3.0) + - EmbraceIO/EmbraceConfigInternal (6.3.0): - EmbraceIO/EmbraceCommonInternal - - EmbraceIO/EmbraceCore (6.3.0-rc2): + - EmbraceIO/EmbraceCore (6.3.0): - EmbraceIO/EmbraceCaptureService - EmbraceIO/EmbraceCommonInternal - EmbraceIO/EmbraceConfigInternal - EmbraceIO/EmbraceObjCUtilsInternal - EmbraceIO/EmbraceOTelInternal + - EmbraceIO/EmbraceSemantics - EmbraceIO/EmbraceStorageInternal - EmbraceIO/EmbraceUploadInternal - - EmbraceIO/EmbraceCrash (6.3.0-rc2): + - EmbraceIO/EmbraceCrash (6.3.0): - EmbraceIO/EmbraceCommonInternal - EmbraceIO/KSCrash - - EmbraceIO/EmbraceIO (6.3.0-rc2): + - EmbraceIO/EmbraceIO (6.3.0): - EmbraceIO/EmbraceCaptureService - EmbraceIO/EmbraceCommonInternal - EmbraceIO/EmbraceCore - EmbraceIO/EmbraceCrash - - EmbraceIO/EmbraceObjCUtilsInternal (6.3.0-rc2) - - EmbraceIO/EmbraceOTelInternal (6.3.0-rc2): + - EmbraceIO/EmbraceSemantics + - EmbraceIO/EmbraceObjCUtilsInternal (6.3.0) + - EmbraceIO/EmbraceOTelInternal (6.3.0): - EmbraceIO/EmbraceCommonInternal + - EmbraceIO/EmbraceSemantics - EmbraceIO/OpenTelemetrySdk - - EmbraceIO/EmbraceStorageInternal (6.3.0-rc2): + - EmbraceIO/EmbraceSemantics (6.3.0) + - EmbraceIO/EmbraceStorageInternal (6.3.0): - EmbraceIO/EmbraceCommonInternal + - EmbraceIO/EmbraceSemantics - EmbraceIO/GRDB - EmbraceIO/OpenTelemetryApi - - EmbraceIO/EmbraceUploadInternal (6.3.0-rc2): + - EmbraceIO/EmbraceUploadInternal (6.3.0): - EmbraceIO/EmbraceCommonInternal - EmbraceIO/EmbraceOTelInternal - EmbraceIO/GRDB - - EmbraceIO/GRDB (6.3.0-rc2) - - EmbraceIO/KSCrash (6.3.0-rc2): + - EmbraceIO/GRDB (6.3.0) + - EmbraceIO/KSCrash (6.3.0): - EmbraceIO/KSCrashCore - EmbraceIO/KSCrashRecording - EmbraceIO/KSCrashRecordingCore - - EmbraceIO/KSCrashCore (6.3.0-rc2) - - EmbraceIO/KSCrashRecording (6.3.0-rc2): + - EmbraceIO/KSCrashCore (6.3.0) + - EmbraceIO/KSCrashRecording (6.3.0): - EmbraceIO/KSCrashRecordingCore - - EmbraceIO/KSCrashRecordingCore (6.3.0-rc2): + - EmbraceIO/KSCrashRecordingCore (6.3.0): - EmbraceIO/KSCrashCore - - EmbraceIO/OpenTelemetryApi (6.3.0-rc2) - - EmbraceIO/OpenTelemetrySdk (6.3.0-rc2): + - EmbraceIO/OpenTelemetryApi (6.3.0) + - EmbraceIO/OpenTelemetrySdk (6.3.0): - EmbraceIO/OpenTelemetryApi - FBLazyVector (0.74.2) - fmt (9.1.0) @@ -1219,7 +1224,7 @@ PODS: DEPENDENCIES: - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - - EmbraceIO (= 6.3.0-rc2) + - EmbraceIO (= 6.3.0) - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - fmt (from `../node_modules/react-native/third-party-podspecs/fmt.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) @@ -1394,7 +1399,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost: d3f49c53809116a5d38da093a8aa78bf551aed09 DoubleConversion: 76ab83afb40bddeeee456813d9c04f67f78771b5 - EmbraceIO: 181e207cf37ba753ba4feea3cb90ed75fecdf87d + EmbraceIO: 5a507779ae7f2ca3c33d9ecd58917038e207b11f FBLazyVector: 4bc164e5b5e6cfc288d2b5ff28643ea15fa1a589 fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120 glog: fdfdfe5479092de0c4bdbebedd9056951f092c4f @@ -1449,6 +1454,6 @@ SPEC CHECKSUMS: SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d Yoga: 2f71ecf38d934aecb366e686278102a51679c308 -PODFILE CHECKSUM: ce7b20e3b58dbda25946831248360e03f30b3976 +PODFILE CHECKSUM: 8a247e59201368a342e5530a540a10f61aa7e0f3 COCOAPODS: 1.15.2 diff --git a/packages/core/test-project/ios/RNEmbraceTestProject.xcodeproj/project.pbxproj b/packages/core/test-project/ios/RNEmbraceTestProject.xcodeproj/project.pbxproj index bc3a6e4b..fc5eb4f5 100644 --- a/packages/core/test-project/ios/RNEmbraceTestProject.xcodeproj/project.pbxproj +++ b/packages/core/test-project/ios/RNEmbraceTestProject.xcodeproj/project.pbxproj @@ -12,8 +12,8 @@ 30DFDA6A2C486677009F2ECC /* RNEmbrace.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30DFDA622C486677009F2ECC /* RNEmbrace.framework */; }; 30DFDA6F2C486677009F2ECC /* RNEmbraceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30DFDA6E2C486677009F2ECC /* RNEmbraceTests.swift */; }; 30DFDA7A2C4866AA009F2ECC /* EmbraceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30DFDA782C4866AA009F2ECC /* EmbraceManager.swift */; }; - 90981A0E3E223D9B7EF874DA /* libPods-RNEmbrace-RNEmbraceTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CCD073A43A2F86D1207905EE /* libPods-RNEmbrace-RNEmbraceTests.a */; }; - E7CE82A26358CF89CDA9CED4 /* libPods-RNEmbrace.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CE67B0F47E43D18BABCC7454 /* libPods-RNEmbrace.a */; }; + B4299F22FA7B4BCC15BA5909 /* libPods-RNEmbrace-RNEmbraceTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 558DC3867B10B4FE49B73190 /* libPods-RNEmbrace-RNEmbraceTests.a */; }; + DFB266F6D6D6B83330A0A1C0 /* libPods-RNEmbrace.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FDEF5231D91290910B8BF4B8 /* libPods-RNEmbrace.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -27,18 +27,18 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 1B0AE27C282CB3CF63E4F284 /* Pods-RNEmbrace.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace.debug.xcconfig"; path = "Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace.debug.xcconfig"; sourceTree = ""; }; 308F09282C4EED4200C1EB4C /* EmbraceManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EmbraceManager.m; sourceTree = ""; }; 308F092A2C4EF1FE00C1EB4C /* SpanRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpanRepository.swift; sourceTree = ""; }; 30DFDA622C486677009F2ECC /* RNEmbrace.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RNEmbrace.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 30DFDA692C486677009F2ECC /* RNEmbraceTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNEmbraceTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 30DFDA6E2C486677009F2ECC /* RNEmbraceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNEmbraceTests.swift; sourceTree = ""; }; 30DFDA782C4866AA009F2ECC /* EmbraceManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmbraceManager.swift; sourceTree = ""; }; - 4429624C7D4FD60C6D020CE2 /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig"; path = "Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig"; sourceTree = ""; }; - 9EA561A7D957BE59B3F8CAB4 /* Pods-RNEmbrace.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace.release.xcconfig"; path = "Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace.release.xcconfig"; sourceTree = ""; }; - CCD073A43A2F86D1207905EE /* libPods-RNEmbrace-RNEmbraceTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNEmbrace-RNEmbraceTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - CE67B0F47E43D18BABCC7454 /* libPods-RNEmbrace.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNEmbrace.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - CECDD3B34AFDD805243274E6 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace-RNEmbraceTests.release.xcconfig"; path = "Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests.release.xcconfig"; sourceTree = ""; }; + 558DC3867B10B4FE49B73190 /* libPods-RNEmbrace-RNEmbraceTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNEmbrace-RNEmbraceTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 9A6DF13D181A3FCB1CB97565 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace-RNEmbraceTests.release.xcconfig"; path = "Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests.release.xcconfig"; sourceTree = ""; }; + 9E3D177C261BFCB36EE71F4A /* Pods-RNEmbrace.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace.release.xcconfig"; path = "Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace.release.xcconfig"; sourceTree = ""; }; + 9E7E4CD0FBB3C9DCB48A43EA /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig"; path = "Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig"; sourceTree = ""; }; + E684A9ABE638A46E7DBFE54A /* Pods-RNEmbrace.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNEmbrace.debug.xcconfig"; path = "Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace.debug.xcconfig"; sourceTree = ""; }; + FDEF5231D91290910B8BF4B8 /* libPods-RNEmbrace.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNEmbrace.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -46,7 +46,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E7CE82A26358CF89CDA9CED4 /* libPods-RNEmbrace.a in Frameworks */, + DFB266F6D6D6B83330A0A1C0 /* libPods-RNEmbrace.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -55,20 +55,29 @@ buildActionMask = 2147483647; files = ( 30DFDA6A2C486677009F2ECC /* RNEmbrace.framework in Frameworks */, - 90981A0E3E223D9B7EF874DA /* libPods-RNEmbrace-RNEmbraceTests.a in Frameworks */, + B4299F22FA7B4BCC15BA5909 /* libPods-RNEmbrace-RNEmbraceTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 01FD9E82D434888B87A8D21F /* Frameworks */ = { + isa = PBXGroup; + children = ( + FDEF5231D91290910B8BF4B8 /* libPods-RNEmbrace.a */, + 558DC3867B10B4FE49B73190 /* libPods-RNEmbrace-RNEmbraceTests.a */, + ); + name = Frameworks; + sourceTree = ""; + }; 0C8E90FDF3018EA1FCF9459E /* Pods */ = { isa = PBXGroup; children = ( - 1B0AE27C282CB3CF63E4F284 /* Pods-RNEmbrace.debug.xcconfig */, - 9EA561A7D957BE59B3F8CAB4 /* Pods-RNEmbrace.release.xcconfig */, - 4429624C7D4FD60C6D020CE2 /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */, - CECDD3B34AFDD805243274E6 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */, + E684A9ABE638A46E7DBFE54A /* Pods-RNEmbrace.debug.xcconfig */, + 9E3D177C261BFCB36EE71F4A /* Pods-RNEmbrace.release.xcconfig */, + 9E7E4CD0FBB3C9DCB48A43EA /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */, + 9A6DF13D181A3FCB1CB97565 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -80,7 +89,7 @@ 30DFDA6D2C486677009F2ECC /* RNEmbraceTests */, 30DFDA102C485A70009F2ECC /* Products */, 0C8E90FDF3018EA1FCF9459E /* Pods */, - E5B1071567D885CD37BDEA68 /* Frameworks */, + 01FD9E82D434888B87A8D21F /* Frameworks */, ); sourceTree = ""; }; @@ -112,15 +121,6 @@ path = RNEmbraceTests; sourceTree = ""; }; - E5B1071567D885CD37BDEA68 /* Frameworks */ = { - isa = PBXGroup; - children = ( - CE67B0F47E43D18BABCC7454 /* libPods-RNEmbrace.a */, - CCD073A43A2F86D1207905EE /* libPods-RNEmbrace-RNEmbraceTests.a */, - ); - name = Frameworks; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -138,12 +138,12 @@ isa = PBXNativeTarget; buildConfigurationList = 30DFDA712C486677009F2ECC /* Build configuration list for PBXNativeTarget "RNEmbrace" */; buildPhases = ( - 38BE037C70EEF2C63333D2C4 /* [CP] Check Pods Manifest.lock */, + 36572A76A87BDDAD190FC885 /* [CP] Check Pods Manifest.lock */, 30DFDA5D2C486677009F2ECC /* Headers */, 30DFDA5E2C486677009F2ECC /* Sources */, 30DFDA5F2C486677009F2ECC /* Frameworks */, 30DFDA602C486677009F2ECC /* Resources */, - D8D968B1E719FC35B69D2353 /* [CP] Copy Pods Resources */, + 2EDC0916A6A58D1BA7A5A064 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -158,13 +158,13 @@ isa = PBXNativeTarget; buildConfigurationList = 30DFDA742C486677009F2ECC /* Build configuration list for PBXNativeTarget "RNEmbraceTests" */; buildPhases = ( - 6866A9F75E458E397EB1A5B8 /* [CP] Check Pods Manifest.lock */, + B6286F377DCB4B7C8A2A7A3F /* [CP] Check Pods Manifest.lock */, 3023F50B2C52EA4300981C97 /* ShellScript */, 30DFDA652C486677009F2ECC /* Sources */, 30DFDA662C486677009F2ECC /* Frameworks */, 30DFDA672C486677009F2ECC /* Resources */, - 84A3D0A057AE88025F30B1AD /* [CP] Embed Pods Frameworks */, - 298F6EE6E6E51B827AA83A5C /* [CP] Copy Pods Resources */, + 964A4075AFF1013A5E050989 /* [CP] Embed Pods Frameworks */, + 41EE9EFB891B28E768F91E92 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -232,21 +232,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 298F6EE6E6E51B827AA83A5C /* [CP] Copy Pods Resources */ = { + 2EDC0916A6A58D1BA7A5A064 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace-resources-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace-resources.sh\"\n"; showEnvVarsInLog = 0; }; 3023F50B2C52EA4300981C97 /* ShellScript */ = { @@ -266,7 +266,7 @@ shellPath = /bin/sh; shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; }; - 38BE037C70EEF2C63333D2C4 /* [CP] Check Pods Manifest.lock */ = { + 36572A76A87BDDAD190FC885 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -288,29 +288,24 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 6866A9F75E458E397EB1A5B8 /* [CP] Check Pods Manifest.lock */ = { + 41EE9EFB891B28E768F91E92 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNEmbrace-RNEmbraceTests-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 84A3D0A057AE88025F30B1AD /* [CP] Embed Pods Frameworks */ = { + 964A4075AFF1013A5E050989 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -327,21 +322,26 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNEmbrace-RNEmbraceTests/Pods-RNEmbrace-RNEmbraceTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - D8D968B1E719FC35B69D2353 /* [CP] Copy Pods Resources */ = { + B6286F377DCB4B7C8A2A7A3F /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RNEmbrace-RNEmbraceTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNEmbrace/Pods-RNEmbrace-resources.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -523,7 +523,7 @@ }; 30DFDA722C486677009F2ECC /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 1B0AE27C282CB3CF63E4F284 /* Pods-RNEmbrace.debug.xcconfig */; + baseConfigurationReference = E684A9ABE638A46E7DBFE54A /* Pods-RNEmbrace.debug.xcconfig */; buildSettings = { BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; @@ -561,7 +561,7 @@ }; 30DFDA732C486677009F2ECC /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9EA561A7D957BE59B3F8CAB4 /* Pods-RNEmbrace.release.xcconfig */; + baseConfigurationReference = 9E3D177C261BFCB36EE71F4A /* Pods-RNEmbrace.release.xcconfig */; buildSettings = { BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; @@ -598,7 +598,7 @@ }; 30DFDA752C486677009F2ECC /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4429624C7D4FD60C6D020CE2 /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */; + baseConfigurationReference = 9E7E4CD0FBB3C9DCB48A43EA /* Pods-RNEmbrace-RNEmbraceTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; @@ -617,7 +617,7 @@ }; 30DFDA762C486677009F2ECC /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CECDD3B34AFDD805243274E6 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */; + baseConfigurationReference = 9A6DF13D181A3FCB1CB97565 /* Pods-RNEmbrace-RNEmbraceTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; diff --git a/packages/core/test-project/ios/RNEmbraceTests/RNEmbraceTests.swift b/packages/core/test-project/ios/RNEmbraceTests/RNEmbraceTests.swift index 6af2c281..c3d11bc8 100644 --- a/packages/core/test-project/ios/RNEmbraceTests/RNEmbraceTests.swift +++ b/packages/core/test-project/ios/RNEmbraceTests/RNEmbraceTests.swift @@ -266,8 +266,7 @@ class EmbraceSpansTests: XCTestCase { XCTAssertEqual(promise.rejectCalls[0], "Could not retrieve a span with the given id") } - // TODO fails on 6.3 currently due to span.flush call - func skipped_testAddSpanEvent() async throws { + func testAddSpanEvent() async throws { module.startSpan("my-span", parentSpanId: "", startTimeMs: 0.0, resolver: promise.resolve, rejecter: promise.reject) XCTAssertEqual(promise.resolveCalls.count, 1) @@ -326,8 +325,7 @@ class EmbraceSpansTests: XCTestCase { XCTAssertEqual(promise.rejectCalls[0], "Could not retrieve a span with the given id") } - // TODO fails on 6.3 currently due to span.flush call - func skipped_testAddSpanAttribute() async throws { + func testAddSpanAttribute() async throws { module.startSpan("my-span", parentSpanId: "", startTimeMs: 0.0, resolver: promise.resolve, rejecter: promise.reject) XCTAssertEqual(promise.resolveCalls.count, 1) @@ -470,8 +468,7 @@ class EmbraceSpansTests: XCTestCase { XCTAssertEqual(exportedSpans[0].attributes["emb.error_code"]!.description, "failure") } - // TODO fails on 6.3 currently due to span.flush call - func skipped_testCompletedSpansRemovedOnSessionEnd() async throws { + func testCompletedSpansRemovedOnSessionEnd() async throws { module.startSpan("stopped-span", parentSpanId: "", startTimeMs: 0.0, resolver: promise.resolve, rejecter: promise.reject) module.startSpan("active-span", parentSpanId: "", startTimeMs: 0.0,