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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 107 additions & 3 deletions UnitTests/ObjCTests/MPRoktTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@
#import "MParticleSwift.h"
#import "MPIConstants.h"

// Rokt kit identifier for testing
static NSNumber * const kTestRoktKitId = @181;

// Test helper class that simulates a kit with getSessionId method
@interface MPRoktTestKitInstance : NSObject
@property (nonatomic, copy) NSString *sessionIdToReturn;
- (NSString *)getSessionId;
@end

@implementation MPRoktTestKitInstance
- (NSString *)getSessionId {
return self.sessionIdToReturn;
}
@end

@interface MPRokt ()
- (NSArray<NSDictionary<NSString *, NSString *> *> *)getRoktPlacementAttributesMapping;
- (NSNumber *)getRoktHashedEmailUserIdentityType;
Expand Down Expand Up @@ -293,7 +308,7 @@ - (void)testGetRoktPlacementAttributesMapping {
self.mockInstance = OCMPartialMock(instance);
self.mockContainer = OCMClassMock([MPKitContainer_PRIVATE class]);
NSArray *kitConfig = @[@{
@"id": @181,
@"id": kTestRoktKitId,
kMPRemoteConfigKitConfigurationKey: @{
@"AllowJavaScriptResponse": @"True",
@"accountId": @12345,
Expand Down Expand Up @@ -322,7 +337,7 @@ - (void)testGetRoktHashedEmailUserIdentityType {
self.mockInstance = OCMPartialMock(instance);
self.mockContainer = OCMClassMock([MPKitContainer_PRIVATE class]);
NSArray *kitConfig = @[@{
@"id": @181,
@"id": kTestRoktKitId,
kMPRemoteConfigKitConfigurationKey: @{
@"AllowJavaScriptResponse": @"True",
@"accountId": @12345,
Expand All @@ -344,7 +359,7 @@ - (void)testGetRoktHashedEmailUserIdentityTypeReturnsNilWhenNotConfigured {
self.mockInstance = OCMPartialMock(instance);
self.mockContainer = OCMClassMock([MPKitContainer_PRIVATE class]);
NSArray *kitConfig = @[@{
@"id": @181,
@"id": kTestRoktKitId,
kMPRemoteConfigKitConfigurationKey: @{
@"AllowJavaScriptResponse": @"True",
@"accountId": @12345,
Expand Down Expand Up @@ -745,4 +760,93 @@ - (void)testEventsWithIdentifierCallbackInvocation {
OCMVerifyAll(self.mockContainer);
}

#pragma mark - setSessionId Tests

- (void)testSetSessionIdForwardsToKitContainer {
MParticle *instance = [MParticle sharedInstance];
self.mockInstance = OCMPartialMock(instance);
self.mockContainer = OCMClassMock([MPKitContainer_PRIVATE class]);
[[[self.mockInstance stub] andReturn:self.mockContainer] kitContainer_PRIVATE];
[[[self.mockInstance stub] andReturn:self.mockInstance] sharedInstance];

// Set up test parameters
NSString *sessionId = @"test-session-id-12345";

// Set up expectations for kit container
XCTestExpectation *expectation = [self expectationWithDescription:@"Wait for async operation"];
SEL roktSelector = @selector(setSessionId:);
OCMExpect([self.mockContainer forwardSDKCall:roktSelector
event:nil
parameters:[OCMArg checkWithBlock:^BOOL(MPForwardQueueParameters *params) {
XCTAssertEqualObjects(params[0], sessionId);
return true;
}]
messageType:MPMessageTypeEvent
userInfo:nil]).andDo(^(NSInvocation *invocation) {
[expectation fulfill];
});

// Execute method
[self.rokt setSessionId:sessionId];

// Wait for async operation
[self waitForExpectationsWithTimeout:0.2 handler:nil];

// Verify
OCMVerifyAll(self.mockContainer);
}

#pragma mark - getSessionId Tests

- (void)testGetSessionIdReturnsSessionIdFromKit {
MParticle *instance = [MParticle sharedInstance];
self.mockInstance = OCMPartialMock(instance);
self.mockContainer = OCMClassMock([MPKitContainer_PRIVATE class]);
[[[self.mockInstance stub] andReturn:self.mockContainer] kitContainer_PRIVATE];
[[[self.mockInstance stub] andReturn:self.mockInstance] sharedInstance];

// Create a mock kit register with Rokt kit code
id mockKitRegister = OCMProtocolMock(@protocol(MPExtensionKitProtocol));
OCMStub([(id<MPExtensionKitProtocol>)mockKitRegister code]).andReturn(kTestRoktKitId);

// Create a real kit instance that responds to getSessionId
NSString *expectedSessionId = @"mock-session-id-67890";
MPRoktTestKitInstance *kitInstance = [[MPRoktTestKitInstance alloc] init];
kitInstance.sessionIdToReturn = expectedSessionId;
OCMStub([mockKitRegister wrapperInstance]).andReturn(kitInstance);

// Return the mock kit register from activeKitsRegistry
NSArray *activeKits = @[mockKitRegister];
OCMStub([self.mockContainer activeKitsRegistry]).andReturn(activeKits);

// Execute method
NSString *result = [self.rokt getSessionId];

// Verify
XCTAssertEqualObjects(result, expectedSessionId, @"Should return the session id from the kit");
}

- (void)testGetSessionIdReturnsNilWhenKitInstanceIsNil {
MParticle *instance = [MParticle sharedInstance];
self.mockInstance = OCMPartialMock(instance);
self.mockContainer = OCMClassMock([MPKitContainer_PRIVATE class]);
[[[self.mockInstance stub] andReturn:self.mockContainer] kitContainer_PRIVATE];
[[[self.mockInstance stub] andReturn:self.mockInstance] sharedInstance];

// Create a mock kit register with Rokt kit code but nil wrapperInstance
id mockKitRegister = OCMProtocolMock(@protocol(MPExtensionKitProtocol));
OCMStub([(id<MPExtensionKitProtocol>)mockKitRegister code]).andReturn(kTestRoktKitId);
OCMStub([mockKitRegister wrapperInstance]).andReturn(nil);

// Return the mock kit register from activeKitsRegistry
NSArray *activeKits = @[mockKitRegister];
OCMStub([self.mockContainer activeKitsRegistry]).andReturn(activeKits);

// Execute method
NSString *result = [self.rokt getSessionId];

// Verify
XCTAssertNil(result, @"Should return nil when kit wrapper instance is nil");
}

@end
18 changes: 18 additions & 0 deletions mParticle-Apple-SDK/Include/MPRokt.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,22 @@ typedef NS_ENUM(NSInteger, MPColorMode) {
*/
- (void)close;

/**
* Set the session id to use for the next execute call.
* This is useful for cases where you have a session id from a non-native integration,
* e.g. WebView, and you want the session to be consistent across integrations.
*
* @note Empty strings are ignored and will not update the session.
*
* @param sessionId The session id to be set. Must be a non-empty string.
*/
- (void)setSessionId:(NSString * _Nonnull)sessionId;

/**
* Get the session id to use within a non-native integration e.g. WebView.
*
* @return The session id or nil if no session is present.
*/
- (NSString * _Nullable)getSessionId;

@end
40 changes: 40 additions & 0 deletions mParticle-Apple-SDK/MPRokt.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#import "MPILogger.h"
#import "MPIConstants.h"
#import "MPIdentityDTO.h"
#import "MPExtensionProtocol.h"

// Constants for kit configuration keys
static NSString * const kMPKitConfigurationIdKey = @"id";
Expand Down Expand Up @@ -172,6 +173,45 @@ - (void)close {
});
}

/// Set the session id to use for the next execute call.
/// This is useful for cases where you have a session id from a non-native integration,
/// e.g. WebView, and you want the session to be consistent across integrations.
/// - Note: Empty strings are ignored and will not update the session.
/// - Parameters:
/// - sessionId: The session id to be set. Must be a non-empty string.
- (void)setSessionId:(NSString * _Nonnull)sessionId {
dispatch_async(dispatch_get_main_queue(), ^{
MPForwardQueueParameters *queueParameters = [[MPForwardQueueParameters alloc] init];
[queueParameters addParameter:sessionId];

[[MParticle sharedInstance].kitContainer_PRIVATE forwardSDKCall:@selector(setSessionId:)
event:nil
parameters:queueParameters
messageType:MPMessageTypeEvent
userInfo:nil
];
});
}

/// Get the session id to use within a non-native integration e.g. WebView.
/// - Returns: The session id or nil if no session is present.
- (NSString * _Nullable)getSessionId {
__block NSString *result = nil;

NSArray<id<MPExtensionKitProtocol>> *activeKits = [[MParticle sharedInstance].kitContainer_PRIVATE activeKitsRegistry];
for (id<MPExtensionKitProtocol> kitRegister in activeKits) {
if ([kitRegister.code integerValue] == kMPRoktKitId) {
id kitInstance = kitRegister.wrapperInstance;
if (kitInstance && [kitInstance respondsToSelector:@selector(getSessionId)]) {
result = [kitInstance performSelector:@selector(getSessionId)];
break;
}
}
}

return result;
}

#pragma mark - Private Helper Methods

/// Retrieves the Rokt Kit configuration from the kit container.
Expand Down
Loading