Skip to content

Commit

Permalink
Enable Session Replay on iOS
Browse files Browse the repository at this point in the history
  • Loading branch information
louiszawadzki committed Oct 27, 2023
1 parent 23e3209 commit 5053048
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 5 deletions.
1 change: 1 addition & 0 deletions example/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ end

target 'ddSdkReactnativeExample' do
pod 'DatadogSDKReactNative', :path => '../../packages/core/DatadogSDKReactNative.podspec', :testspecs => ['Tests']
pod 'DatadogSDKReactNativeSessionReplay', :path => '../../packages/react-native-session-replay/DatadogSDKReactNativeSessionReplay.podspec', :testspecs => ['Tests']

config = use_native_modules!

Expand Down
17 changes: 16 additions & 1 deletion example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ PODS:
- DatadogTrace (~> 2.2.1)
- DatadogWebViewTracking (~> 2.2.1)
- React-Core
- DatadogSDKReactNativeSessionReplay (1.8.5):
- DatadogSessionReplay (~> 2.2.1)
- React-Core
- DatadogSDKReactNativeSessionReplay/Tests (1.8.5):
- DatadogSessionReplay (~> 2.2.1)
- React-Core
- DatadogSessionReplay (2.2.1):
- DatadogInternal (= 2.2.1)
- DatadogTrace (2.2.1):
- DatadogInternal (= 2.2.1)
- DatadogWebViewTracking (2.2.1):
Expand Down Expand Up @@ -411,6 +419,8 @@ DEPENDENCIES:
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
- DatadogSDKReactNative (from `../../packages/core/DatadogSDKReactNative.podspec`)
- DatadogSDKReactNative/Tests (from `../../packages/core/DatadogSDKReactNative.podspec`)
- DatadogSDKReactNativeSessionReplay (from `../../packages/react-native-session-replay/DatadogSDKReactNativeSessionReplay.podspec`)
- DatadogSDKReactNativeSessionReplay/Tests (from `../../packages/react-native-session-replay/DatadogSDKReactNativeSessionReplay.podspec`)
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
Expand Down Expand Up @@ -461,6 +471,7 @@ SPEC REPOS:
- DatadogInternal
- DatadogLogs
- DatadogRUM
- DatadogSessionReplay
- DatadogTrace
- DatadogWebViewTracking
- fmt
Expand All @@ -473,6 +484,8 @@ EXTERNAL SOURCES:
:podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
DatadogSDKReactNative:
:path: "../../packages/core/DatadogSDKReactNative.podspec"
DatadogSDKReactNativeSessionReplay:
:path: "../../packages/react-native-session-replay/DatadogSDKReactNativeSessionReplay.podspec"
DoubleConversion:
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
FBLazyVector:
Expand Down Expand Up @@ -562,6 +575,8 @@ SPEC CHECKSUMS:
DatadogLogs: a0eafa7bd2103511eac07bcd2ff95c851123e29b
DatadogRUM: 1e027ccfe4ba1eb81a185f3c58e0909bb12811be
DatadogSDKReactNative: 6f16f15e8b3d5a60c5799d604843a0feb2010c9b
DatadogSDKReactNativeSessionReplay: ec9e93b87abbb2f4935bd02e651b28a9503b48de
DatadogSessionReplay: 4b29318297ad20189a69153b4b0475f0fab7d3f5
DatadogTrace: 74dc91a7a80e746dc4ef1af6d0db1735b5bfd993
DatadogWebViewTracking: 9ca93299a2c900c68ba080f6e800fae1fa3c6b61
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
Expand Down Expand Up @@ -609,6 +624,6 @@ SPEC CHECKSUMS:
RNScreens: f7ad633b2e0190b77b6a7aab7f914fad6f198d8d
Yoga: e7ea9e590e27460d28911403b894722354d73479

PODFILE CHECKSUM: 59a4878659fbb7b053887dd9eec3df44ca9e0b28
PODFILE CHECKSUM: c13458ce5aca9de130799f13a0494e537a800b3c

COCOAPODS: 1.12.1
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Pod::Spec.new do |s|
s.source_files = "ios/Sources/*.{h,m,mm,swift}"

s.dependency "React-Core"
s.dependency 'DatadogSessionReplay', '~> 2.2.1'

s.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'ios/Tests/*.swift'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,56 @@
*/

import Foundation
import DatadogSessionReplay
import DatadogInternal

@objc
public class DdSessionReplayImplementation: NSObject {
private lazy var sessionReplay: SessionReplayProtocol = sessionReplayProvider()
private let sessionReplayProvider: () -> SessionReplayProtocol

internal init(_ sessionReplayProvider: @escaping () -> SessionReplayProtocol) {
self.sessionReplayProvider = sessionReplayProvider
}

@objc
public override convenience init() {
self.init({ NativeSessionReplay() })
}

@objc
public func enable(replaySampleRate: Double, defaultPrivacyLevel: String, resolve:RCTPromiseResolveBlock, reject:RCTPromiseRejectBlock) -> Void {
sessionReplay.enable(
with: SessionReplay.Configuration(
replaySampleRate: Float(replaySampleRate),
defaultPrivacyLevel: buildPrivacyLevel(privacyLevel: defaultPrivacyLevel as NSString)
)
)
resolve(nil)
}

func buildPrivacyLevel(privacyLevel: NSString) -> SessionReplay.Configuration.PrivacyLevel {
switch privacyLevel.lowercased {
case "mask":
return .mask
case "mask_user_input":
return .maskUserInput
case "allow":
return .allow
default:
return .mask
}
}
}

internal protocol SessionReplayProtocol {
func enable(
with configuration: SessionReplay.Configuration
)
}

internal class NativeSessionReplay: SessionReplayProtocol {
func enable(with configuration: DatadogSessionReplay.SessionReplay.Configuration) {
SessionReplay.enable(with: configuration)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,67 @@
*/

import XCTest
@testable import DatadogSDKReactNativeSessionReplay
import DatadogSessionReplay

internal class DdSessionReplayTests: XCTestCase {
private lazy var sessionReplay = DdSessionReplayImplementation()

private func mockResolve(args: Any?) {}
private func mockReject(args: String?, arg: String?, err: Error?) {}

func testDoesNothing() {
sessionReplay.enable(replaySampleRate: 100, defaultPrivacyLevel: "MASK", resolve: mockResolve, reject: mockReject)
func testEnablesSessionReplayWithZeroReplaySampleRate() {
let sessionReplayMock = MockSessionReplay()
DdSessionReplayImplementation({ sessionReplayMock })
.enable(replaySampleRate: 0, defaultPrivacyLevel: "MASK", resolve: mockResolve, reject: mockReject)

XCTAssertEqual(sessionReplayMock.calledMethods.first, .enable(replaySampleRate: 0.0, privacyLevel: .mask))
}

func testEnablesSessionReplayWithMaskPrivacyLevel() {
let sessionReplayMock = MockSessionReplay()
DdSessionReplayImplementation({ sessionReplayMock })
.enable(replaySampleRate: 100, defaultPrivacyLevel: "MASK", resolve: mockResolve, reject: mockReject)

XCTAssertEqual(sessionReplayMock.calledMethods.first, .enable(replaySampleRate: 100.0, privacyLevel: .mask))
}

func testEnablesSessionReplayWithMaskUserInputPrivacyLevel() {
let sessionReplayMock = MockSessionReplay()
DdSessionReplayImplementation({ sessionReplayMock })
.enable(replaySampleRate: 100, defaultPrivacyLevel: "MASK_USER_INPUT", resolve: mockResolve, reject: mockReject)

XCTAssertEqual(sessionReplayMock.calledMethods.first, .enable(replaySampleRate: 100.0, privacyLevel: .maskUserInput))
}

func testEnablesSessionReplayWithAllowPrivacyLevel() {
let sessionReplayMock = MockSessionReplay()
DdSessionReplayImplementation({ sessionReplayMock })
.enable(replaySampleRate: 100, defaultPrivacyLevel: "ALLOW", resolve: mockResolve, reject: mockReject)

XCTAssertEqual(sessionReplayMock.calledMethods.first, .enable(replaySampleRate: 100.0, privacyLevel: .allow))
}

func testEnablesSessionReplayWithBadPrivacyLevel() {
let sessionReplayMock = MockSessionReplay()
DdSessionReplayImplementation({ sessionReplayMock })
.enable(replaySampleRate: 100, defaultPrivacyLevel: "BAD_VALUE", resolve: mockResolve, reject: mockReject)

XCTAssertEqual(sessionReplayMock.calledMethods.first, .enable(replaySampleRate: 100.0, privacyLevel: .mask))
}
}

private class MockSessionReplay: SessionReplayProtocol {
enum CalledMethod: Equatable {
case enable(replaySampleRate: Float, privacyLevel: SessionReplay.Configuration.PrivacyLevel)
}

public var calledMethods = [CalledMethod]()

func enable(with configuration: SessionReplay.Configuration) {
calledMethods.append(
.enable(
replaySampleRate: configuration.replaySampleRate,
privacyLevel: configuration.defaultPrivacyLevel
)
)
}
}

0 comments on commit 5053048

Please sign in to comment.