Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
nzagorchev committed Nov 26, 2024
1 parent b9887c1 commit f14afad
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 77 deletions.
6 changes: 6 additions & 0 deletions CleverTapSDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@
6B32A0AD2B9DBE31009ADC57 /* CTTemplatePresenterMock.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B32A0AC2B9DBE31009ADC57 /* CTTemplatePresenterMock.m */; };
6B32A0B02B9DC374009ADC57 /* CTTemplateArgumentTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B32A0AF2B9DC374009ADC57 /* CTTemplateArgumentTest.m */; };
6B32A0B42B9F2E8F009ADC57 /* CTTestTemplateProducer.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B32A0B32B9F2E8F009ADC57 /* CTTestTemplateProducer.m */; };
6B453EF92CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B453EF82CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.m */; };
6B4A0F912B45EF6D00A42C6D /* CTInAppTriggerManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B4A0F902B45EF6D00A42C6D /* CTInAppTriggerManagerTest.m */; };
6B535FB62AD56C60002A2663 /* CTMultiDelegateManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B535FB42AD56C60002A2663 /* CTMultiDelegateManager.h */; };
6B535FB72AD56C60002A2663 /* CTMultiDelegateManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B535FB42AD56C60002A2663 /* CTMultiDelegateManager.h */; };
Expand Down Expand Up @@ -913,6 +914,8 @@
6B32A0B12B9F2A75009ADC57 /* CTCustomTemplatesManager+Tests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CTCustomTemplatesManager+Tests.h"; sourceTree = "<group>"; };
6B32A0B22B9F2E8F009ADC57 /* CTTestTemplateProducer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CTTestTemplateProducer.h; sourceTree = "<group>"; };
6B32A0B32B9F2E8F009ADC57 /* CTTestTemplateProducer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTTestTemplateProducer.m; sourceTree = "<group>"; };
6B453EF72CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CTInAppDisplayViewControllerMock.h; sourceTree = "<group>"; };
6B453EF82CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTInAppDisplayViewControllerMock.m; sourceTree = "<group>"; };
6B4A0F902B45EF6D00A42C6D /* CTInAppTriggerManagerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTInAppTriggerManagerTest.m; sourceTree = "<group>"; };
6B535FB42AD56C60002A2663 /* CTMultiDelegateManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CTMultiDelegateManager.h; sourceTree = "<group>"; };
6B535FB52AD56C60002A2663 /* CTMultiDelegateManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTMultiDelegateManager.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1474,6 +1477,8 @@
6B4A0F902B45EF6D00A42C6D /* CTInAppTriggerManagerTest.m */,
6BB778CF2BEE4C3400A41628 /* CTNotificationActionTest.m */,
4806346E2CEB620400E39E9B /* CTInAppDisplayViewControllerTests.m */,
6B453EF72CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.h */,
6B453EF82CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.m */,
);
path = InApps;
sourceTree = "<group>";
Expand Down Expand Up @@ -2528,6 +2533,7 @@
6B32A0A32B99EA9D009ADC57 /* CTCustomTemplateBuilderTest.m in Sources */,
6B9E95B52C29C2F40002D557 /* NSFileManagerMock.m in Sources */,
6A7BB8DC29E47CFF00651584 /* CTVarTest.m in Sources */,
6B453EF92CF621E3003C7A89 /* CTInAppDisplayViewControllerMock.m in Sources */,
6B32A0AD2B9DBE31009ADC57 /* CTTemplatePresenterMock.m in Sources */,
6A2E0B9129CCCC8600FCEA5F /* ContentMergerTest.m in Sources */,
6A2E0B9529D49D0200FCEA5F /* CTVariables+Tests.m in Sources */,
Expand Down
2 changes: 2 additions & 0 deletions CleverTapSDK/CTConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ extern NSString *CLTAP_PROFILE_IDENTITY_KEY;
#define CLTAP_INAPP_HTML_SPLIT @"\"##Vars##\""
#define CLTAP_INAPP_IMAGE_INTERSTITIAL_HTML_NAME @"image_interstitial"

#define CLTAP_URL_PARAM_DL_SEPARATOR @"__dl__"

#pragma mark Constants for persisting system data
#define CLTAP_SYS_CARRIER @"sysCarrier"
#define CLTAP_SYS_CC @"sysCountryCode"
Expand Down
12 changes: 6 additions & 6 deletions CleverTapSDK/CTInAppDisplayViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -315,27 +315,27 @@ - (void)handleButtonClickFromIndex:(int)index {

- (void)triggerInAppAction:(CTNotificationAction *)action callToAction:(NSString *)callToAction buttonId:(NSString *)buttonId {
NSMutableDictionary *extras = [NSMutableDictionary new];
NSString *urlString = [action.actionURL absoluteString];

if (action.type == CTInAppActionTypeOpenURL) {
NSString *urlString = [action.actionURL absoluteString];
NSMutableDictionary *mutableParams = [CTInAppUtils getParametersFromURL:urlString];

if (mutableParams[@"params"]) {
extras = [mutableParams[@"params"] mutableCopy];

// Use the url from the callToAction param to update action
// Use the url from the deeplink to update the action if such is set
if (mutableParams[@"deeplink"]) {
action = [[CTNotificationAction alloc] initWithOpenURL:mutableParams[@"deeplink"]];
}
}
}

// Added NSNull class check as we may receive callToAction value as NULL class
// when null is passed as value for key callToAction in webView message.
if (callToAction && ![callToAction isKindOfClass:[NSNull class]]) {
// callToAction, buttonId and notification id take precedence over
// the URL parameters if those have been set in the URL
if (callToAction) {
extras[CLTAP_PROP_WZRK_CTA] = callToAction;
}
if (buttonId && ![buttonId isKindOfClass:[NSNull class]]) {
if (buttonId) {
extras[@"button_id"] = buttonId;
}
NSString *campaignId = self.notification.campaignId;
Expand Down
11 changes: 8 additions & 3 deletions CleverTapSDK/CTInAppUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ typedef NS_ENUM(NSUInteger, CTInAppActionType){
+ (NSString * _Nonnull)inAppTypeString:(CTInAppType)type;
+ (CTInAppActionType)inAppActionTypeFromString:(NSString *_Nonnull)type;
+ (NSString * _Nonnull)inAppActionTypeString:(CTInAppActionType)type;
+ (NSBundle *_Nullable)bundle;
+ (NSString *_Nullable)getXibNameForControllerName:(NSString *_Nonnull)controllerName;
+ (NSMutableDictionary *_Nonnull)getParametersFromURL:(NSString *_Nonnull)url;
+ (NSBundle * _Nullable)bundle;
+ (NSString * _Nullable)getXibNameForControllerName:(NSString * _Nonnull)controllerName;
/**
* Extracts the parameters from the URL and extracts the deeplink from the call to action if applicable.
* @param url The URL to process.
* @return Returns a dictionary with "deeplink" and "params" keys holding the respective values.
*/
+ (NSMutableDictionary * _Nonnull)getParametersFromURL:(NSString * _Nonnull)url;

@end
7 changes: 3 additions & 4 deletions CleverTapSDK/CTInAppUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@ + (NSString *)getXibNameForControllerName:(NSString *)controllerName {
}

+ (NSMutableDictionary *)getParametersFromURL:(NSString *)urlString {
NSMutableDictionary *mutableParams = [NSMutableDictionary new];

NSMutableDictionary *mutableParams = [[NSMutableDictionary alloc] init];
// Try to extract the parameters from the URL and overrite default dl if applicable
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
NSArray *comps = [urlString componentsSeparatedByString:@"?"];
Expand All @@ -137,13 +136,13 @@ + (NSMutableDictionary *)getParametersFromURL:(NSString *)urlString {
NSArray *elts = [param componentsSeparatedByString:@"="];
if ([elts count] < 2) continue;
params[elts[0]] = [elts[1] stringByRemovingPercentEncoding];
};
}

// Check for wzrk_c2a key, if present update its value after parsing with __dl__
NSString *c2a = params[CLTAP_PROP_WZRK_CTA];
if (c2a) {
c2a = [c2a stringByRemovingPercentEncoding];
NSArray *parts = [c2a componentsSeparatedByString:@"__dl__"];
NSArray *parts = [c2a componentsSeparatedByString:CLTAP_URL_PARAM_DL_SEPARATOR];
if (parts && [parts count] == 2) {
params[CLTAP_PROP_WZRK_CTA] = parts[0];
mutableParams[@"deeplink"] = [NSURL URLWithString:parts[1]];
Expand Down
8 changes: 8 additions & 0 deletions CleverTapSDK/CleverTapJSInterface.m
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ - (void)triggerInAppAction:(NSDictionary *)actionJson callToAction:(NSString *)c
return;
}

// Check for NSNull in case null is passed from the WebView message
if ([callToAction isKindOfClass:[NSNull class]]) {
callToAction = nil;
}
if ([buttonId isKindOfClass:[NSNull class]]) {
buttonId = nil;
}

CTNotificationAction *action = [[CTNotificationAction alloc] initWithJSON:actionJson];
if (action && !action.error) {
[self.controller triggerInAppAction:action callToAction:callToAction buttonId:buttonId];
Expand Down
18 changes: 18 additions & 0 deletions CleverTapSDKTests/InApps/CTInAppDisplayViewControllerMock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// CTInAppDisplayViewControllerMock.h
// CleverTapSDKTests
//
// Created by Nikola Zagorchev on 26.11.24.
// Copyright © 2024 CleverTap. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "CTInAppDisplayViewController.h"

NS_ASSUME_NONNULL_BEGIN

@interface CTInAppDisplayViewControllerMock : CTInAppDisplayViewController

@end

NS_ASSUME_NONNULL_END
19 changes: 19 additions & 0 deletions CleverTapSDKTests/InApps/CTInAppDisplayViewControllerMock.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// CTInAppDisplayViewControllerMock.m
// CleverTapSDKTests
//
// Created by Nikola Zagorchev on 26.11.24.
// Copyright © 2024 CleverTap. All rights reserved.
//

#import "CTInAppDisplayViewControllerMock.h"

@implementation CTInAppDisplayViewControllerMock

- (void)show:(BOOL)animated {
}

- (void)hide:(BOOL)animated {
}

@end
75 changes: 11 additions & 64 deletions CleverTapSDKTests/InApps/CTInAppDisplayViewControllerTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
//

#import <XCTest/XCTest.h>
#import <OCMock/OCMock.h>
#import "CTInAppDisplayViewController.h"
#import "CTInAppDisplayViewControllerMock.h"
#import "CTInAppNotificationDisplayDelegateMock.h"

@interface CTInAppDisplayViewControllerTests : XCTestCase

@property (nonatomic, strong) CTInAppDisplayViewController *viewController;
@property (nonatomic, strong) CTInAppDisplayViewControllerMock *viewController;
@property (nonatomic, strong) CTInAppNotification *inAppNotification;

@end
Expand All @@ -27,7 +26,7 @@ - (void)setUp {
@"ti": @1
};
self.inAppNotification = [[CTInAppNotification alloc] initWithJSON:inApp];
self.viewController = [[CTInAppDisplayViewController alloc] initWithNotification:self.inAppNotification];
self.viewController = [[CTInAppDisplayViewControllerMock alloc] initWithNotification:self.inAppNotification];
}

- (void)tearDown {
Expand All @@ -52,18 +51,15 @@ - (void)testAddURLParamsOnly {

CTInAppNotificationDisplayDelegateMock *delegate = [[CTInAppNotificationDisplayDelegateMock alloc] init];
[delegate setHandleNotificationAction:^(CTNotificationAction *action, CTInAppNotification *notification, NSDictionary *extras) {
XCTAssertEqualObjects(url, action.actionURL);
XCTAssertEqualObjects(expectedExtras, extras);
}];
self.viewController.delegate = delegate;
id mockViewController = OCMPartialMock(self.viewController);
OCMExpect([mockViewController hide:YES]);

// Trigger the action
[self.viewController triggerInAppAction:action callToAction:nil buttonId:nil];
OCMVerifyAll(mockViewController);
}

- (void)testAddURLParamsAlongWithC2A {
- (void)testAddURLParamsAndC2A {
// triggerAction should add url parameters along with callToAction and buttonId
// in extras dictionary.
NSURL *url = [NSURL URLWithString:@"https://clevertap.com?param1=value1&param2=value2"];
Expand All @@ -81,42 +77,38 @@ - (void)testAddURLParamsAlongWithC2A {

CTInAppNotificationDisplayDelegateMock *delegate = [[CTInAppNotificationDisplayDelegateMock alloc] init];
[delegate setHandleNotificationAction:^(CTNotificationAction *action, CTInAppNotification *notification, NSDictionary *extras) {
XCTAssertEqualObjects(url, action.actionURL);
XCTAssertEqualObjects(expectedExtras, extras);
}];
self.viewController.delegate = delegate;
id mockViewController = OCMPartialMock(self.viewController);
OCMExpect([mockViewController hide:YES]);

// Trigger the action
[self.viewController triggerInAppAction:action callToAction:callToAction buttonId:buttonId];
OCMVerifyAll(mockViewController);
}

- (void)testC2AParamsParseFromDL {
// triggerAction should parse c2a url params with __dl__ data
// when callToAction is not provided.
NSURL *url = [NSURL URLWithString:@"https://clevertap.com?wzrk_c2a=c2aParam__dl__https%3A%2F%2Fdeeplink.com%3Fparam1%3Dasd%26param2%3Dvalue2&asd=value"];

NSString *buttonId = @"button1";
NSDictionary *expectedExtras = @{
@"wzrk_id": @"",
@"wzrk_c2a": @"c2aParam",
@"button_id": buttonId,
@"asd": @"value"
};
NSURL *expectedURL = [NSURL URLWithString:@"https://deeplink.com?param1=asd&param2=value2"];

CTNotificationAction *action = [[CTNotificationAction alloc] initWithOpenURL:url];

CTInAppNotificationDisplayDelegateMock *delegate = [[CTInAppNotificationDisplayDelegateMock alloc] init];
[delegate setHandleNotificationAction:^(CTNotificationAction *action, CTInAppNotification *notification, NSDictionary *extras) {
XCTAssertEqualObjects(expectedURL, action.actionURL);
XCTAssertEqualObjects(expectedExtras, extras);
}];
self.viewController.delegate = delegate;
id mockViewController = OCMPartialMock(self.viewController);
OCMExpect([mockViewController hide:YES]);

// Trigger the action
[self.viewController triggerInAppAction:action callToAction:nil buttonId:buttonId];
OCMVerifyAll(mockViewController);
}

- (void)testC2AParamsDoesNotParseFromDL {
Expand All @@ -131,63 +123,18 @@ - (void)testC2AParamsDoesNotParseFromDL {
@"button_id": buttonId,
@"asd": @"value"
};

CTNotificationAction *action = [[CTNotificationAction alloc] initWithOpenURL:url];

CTInAppNotificationDisplayDelegateMock *delegate = [[CTInAppNotificationDisplayDelegateMock alloc] init];
[delegate setHandleNotificationAction:^(CTNotificationAction *action, CTInAppNotification *notification, NSDictionary *extras) {
XCTAssertEqualObjects(expectedExtras, extras);
}];
self.viewController.delegate = delegate;
id mockViewController = OCMPartialMock(self.viewController);
OCMExpect([mockViewController hide:YES]);

// Trigger the action
[self.viewController triggerInAppAction:action callToAction:callToAction buttonId:buttonId];
OCMVerifyAll(mockViewController);
}

- (void)testActionURLWhenDLDataPresent {
// triggerAction should open deeplink url if __dl__ data is present.
NSURL *url = [NSURL URLWithString:@"https://clevertap.com?wzrk_c2a=c2aParam__dl__https%3A%2F%2Fdeeplink.com%3Fparam1%3Dasd%26param2%3Dvalue2&asd=value"];
NSString *callToAction = @"Test CTA";
NSString *buttonId = @"button1";
NSURL *expectedURL = [NSURL URLWithString:@"https://deeplink.com?param1=asd&param2=value2"];

CTNotificationAction *action = [[CTNotificationAction alloc] initWithOpenURL:url];

CTInAppNotificationDisplayDelegateMock *delegate = [[CTInAppNotificationDisplayDelegateMock alloc] init];
[delegate setHandleNotificationAction:^(CTNotificationAction *action, CTInAppNotification *notification, NSDictionary *extras) {
XCTAssertEqualObjects(action.actionURL, expectedURL);
}];
self.viewController.delegate = delegate;
id mockViewController = OCMPartialMock(self.viewController);
OCMExpect([mockViewController hide:YES]);

// Trigger the action
[self.viewController triggerInAppAction:action callToAction:callToAction buttonId:buttonId];
OCMVerifyAll(mockViewController);
}

- (void)testActionURLWhenDLDataNotPresent {
// triggerAction should open original url if __dl__ data is not present.
NSURL *url = [NSURL URLWithString:@"https://clevertap.com?param1=value1&param2=value2"];
NSString *callToAction = @"Test CTA";
NSString *buttonId = @"button1";
NSURL *expectedURL = url;
CTNotificationAction *action = [[CTNotificationAction alloc] initWithOpenURL:url];

CTInAppNotificationDisplayDelegateMock *delegate = [[CTInAppNotificationDisplayDelegateMock alloc] init];
[delegate setHandleNotificationAction:^(CTNotificationAction *action, CTInAppNotification *notification, NSDictionary *extras) {
XCTAssertEqualObjects(action.actionURL, expectedURL);
XCTAssertEqualObjects(expectedURL, action.actionURL);
XCTAssertEqualObjects(expectedExtras, extras);
}];
self.viewController.delegate = delegate;
id mockViewController = OCMPartialMock(self.viewController);
OCMExpect([mockViewController hide:YES]);

// Trigger the action
[self.viewController triggerInAppAction:action callToAction:callToAction buttonId:buttonId];
OCMVerifyAll(mockViewController);
}

@end

0 comments on commit f14afad

Please sign in to comment.