From e946e51a0a6cf5155e151857acd9a8421b9515f9 Mon Sep 17 00:00:00 2001 From: Gordon Stewart Date: Fri, 6 Oct 2017 11:54:19 -0700 Subject: [PATCH 1/4] Pass custom user string and number to smartwhere when permitted. Default notifications to tray. Add tune version number to smartwhere tracking. --- sdk-ios/Tune/Tune/Tune.m | 28 + sdk-ios/Tune/Tune/TuneSmartWhereHelper.h | 39 ++ sdk-ios/Tune/Tune/TuneSmartWhereHelper.m | 90 +++- .../TuneSmartWhereTriggeredEventManager.m | 1 + .../TuneSmartWhereHelperTests.m | 501 +++++++++++++++++- ...TuneSmartWhereTriggeredEventManagerTests.m | 4 +- 6 files changed, 656 insertions(+), 7 deletions(-) diff --git a/sdk-ios/Tune/Tune/Tune.m b/sdk-ios/Tune/Tune/Tune.m index 9aa4f1c..941d6fb 100644 --- a/sdk-ios/Tune/Tune/Tune.m +++ b/sdk-ios/Tune/Tune/Tune.m @@ -436,10 +436,18 @@ + (void)registerCustomProfileVersion:(NSString *)variableName { + (void)registerCustomProfileString:(NSString *)variableName withDefault:(NSString *)value { [[TuneManager currentManager].userProfile registerString:variableName withDefault:value]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper setAttributeValue:value forKey:variableName]; + } } + (void)registerCustomProfileString:(NSString *)variableName withDefault:(NSString *)value hashed:(BOOL)shouldHash { [[TuneManager currentManager].userProfile registerString:variableName withDefault:value hashed:shouldHash]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper setAttributeValue:value forKey:variableName]; + } } + (void)registerCustomProfileBoolean:(NSString *)variableName withDefault:(NSNumber *)value { @@ -452,6 +460,10 @@ + (void)registerCustomProfileDateTime:(NSString *)variableName withDefault:(NSDa + (void)registerCustomProfileNumber:(NSString *)variableName withDefault:(NSNumber *)value { [[TuneManager currentManager].userProfile registerNumber:variableName withDefault:value]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper setAttributeValue:[value stringValue] forKey:variableName]; + } } + (void)registerCustomProfileGeolocation:(NSString *)variableName withDefault:(TuneLocation *)value { @@ -464,6 +476,10 @@ + (void)registerCustomProfileVersion:(NSString *)variableName withDefault:(NSStr + (void)setCustomProfileStringValue:(NSString *)value forVariable:(NSString *)name { [[TuneManager currentManager].userProfile setStringValue:value forVariable:name]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper setAttributeValue:value forKey:name]; + } } + (void)setCustomProfileBooleanValue:(NSNumber *)value forVariable:(NSString *)name { @@ -476,6 +492,10 @@ + (void)setCustomProfileDateTimeValue:(NSDate *)value forVariable:(NSString *)na + (void)setCustomProfileNumberValue:(NSNumber *)value forVariable:(NSString *)name { [[TuneManager currentManager].userProfile setNumberValue:value forVariable:name]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper setAttributeValue:[value stringValue] forKey:name]; + } } + (void)setCustomProfileGeolocationValue:(TuneLocation *)value forVariable:(NSString *)name { @@ -504,10 +524,18 @@ + (TuneLocation *)getCustomProfileGeolocation:(NSString *)name { + (void)clearCustomProfileVariable:(NSString *)name { [[TuneManager currentManager].userProfile clearCustomVariables:[NSSet setWithObject:name]]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper clearAttributeValue:name]; + } } + (void)clearAllCustomProfileVariables { [[TuneManager currentManager].userProfile clearCustomProfile]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper clearAllAttributeValues]; + } } #pragma mark - Getter Methods diff --git a/sdk-ios/Tune/Tune/TuneSmartWhereHelper.h b/sdk-ios/Tune/Tune/TuneSmartWhereHelper.h index 105c0b2..84a6718 100644 --- a/sdk-ios/Tune/Tune/TuneSmartWhereHelper.h +++ b/sdk-ios/Tune/Tune/TuneSmartWhereHelper.h @@ -8,6 +8,7 @@ #import #import "TuneSkyhookPayload.h" +#import "TuneAnalyticsVariable.h" @protocol SmartWhereDelegate @end @@ -70,6 +71,43 @@ */ - (void)processMappedEvent:(TuneSkyhookPayload*) payload; +/*! + * Set custom user attributes for use in notification replacements and event conditions. + * @param value String value of the attribute value + * @param key Strting value of the attribute name + */ +- (void) setAttributeValue:(NSString*) value forKey: (NSString*) key; + +/*! + * Set custom user attributes for use in notification replacements and event conditions. + * @param tuneAnalyticsVariable TuneAnalyticsVariable + */ +- (void)setAttributeValueFromAnalyticsVariable:(TuneAnalyticsVariable *)tuneAnalyticsVariable; + +/*! + * Set custom user attributes for use in notification replacements and event conditions. + * @param payload TuneSkyhookPayload containing a TuneEvent with tags + */ +- (void)setAttributeValuesFromPayload:(TuneSkyhookPayload*) payload; + +/*! + * Clear a custom user attribute. + * @param variableName String value of the attribute name + */ +- (void)clearAttributeValue:(NSString*) variableName; + +/*! + * Clear all custom user attributes. + */ +- (void)clearAllAttributeValues; + +/*! + * Set custom user tracking attributes that will be sent as metadata in tracking calls. + * @param value String value of the attribute value + * @param key Strting value of the attribute name + */ +- (void) setTrackingAttributeValue:(NSString*) value forKey: (NSString*) key; + @end #ifndef TUNE_SW_EventActionType_Defined @@ -100,6 +138,7 @@ typedef enum TUNE_SW_EventActionType : NSInteger { typedef enum TUNE_SW_ProximityTriggerType : NSInteger { TUNE_SW_swNfcTap = 0, TUNE_SW_swQRScan = 1, + TUNE_SW_swNfcTapCancel = 2, TUNE_SW_swBleEnter = 10, TUNE_SW_swBleHover = 11, TUNE_SW_swBleDwell = 12, diff --git a/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m b/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m index f06dea0..1d19fa4 100644 --- a/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m +++ b/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m @@ -7,10 +7,11 @@ // #import "TuneSmartWhereHelper.h" -#import "TuneEvent.h" +#import "TuneEvent+Internal.h" #import "TuneSkyhookPayloadConstants.h" #import "TuneKeyStrings.h" #import "TuneUtils.h" +#import "Tune.h" static id _smartWhere; static TuneSmartWhereHelper *tuneSharedSmartWhereHelper = nil; @@ -18,6 +19,7 @@ NSString * const TUNE_SMARTWHERE_CLASS_NAME = @"SmartWhere"; +NSString * const TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX = @"T_A_V_"; NSString * const TUNE_SMARTWHERE_ENABLE_NOTIFICATION_PERMISSION_PROMPTING = @"ENABLE_NOTIFICATION_PERMISSION_PROMPTING"; NSString * const TUNE_SMARTWHERE_ENABLE_LOCATION_PERMISSION_PROMPTING = @"ENABLE_LOCATION_PERMISSION_PROMPTING"; NSString * const TUNE_SMARTWHERE_ENABLE_GEOFENCE_RANGING = @"ENABLE_GEOFENCE_RANGING"; @@ -25,6 +27,8 @@ NSString * const TUNE_SMARTWHERE_DEBUG_LOGGING = @"DEBUG_LOGGING"; NSString * const TUNE_SMARTWHERE_PACKAGE_NAME = @"PACKAGE_NAME"; +NSString * const TUNE_VERSION_STRING = @"TUNE_SDK_VERSION"; + @interface TuneSmartWhereHelper() /*! @@ -69,13 +73,15 @@ - (void)startMonitoring { config[TUNE_SMARTWHERE_ENABLE_NOTIFICATION_PERMISSION_PROMPTING] = TUNE_STRING_FALSE; config[TUNE_SMARTWHERE_ENABLE_LOCATION_PERMISSION_PROMPTING] = TUNE_STRING_FALSE; config[TUNE_SMARTWHERE_ENABLE_GEOFENCE_RANGING] = TUNE_STRING_TRUE; - config[TUNE_SMARTWHERE_DELEGATE_NOTIFICATIONS] = TUNE_STRING_TRUE; + config[TUNE_SMARTWHERE_DELEGATE_NOTIFICATIONS] = TUNE_STRING_FALSE; config[TUNE_SMARTWHERE_PACKAGE_NAME] = _packageName; if ([[TuneManager currentManager].configuration.debugMode boolValue]) { config[TUNE_SMARTWHERE_DEBUG_LOGGING] = TUNE_STRING_TRUE; } + [self setTrackingAttributeValue:TUNEVERSION forKey:TUNE_VERSION_STRING]; + WarnLog(@"TUNE: Starting SmartWhere Proximity Monitoring"); [self startProximityMonitoringWithAppId:_aid withApiKey:_aid withApiSecret:_key withConfig:config]; @@ -130,6 +136,86 @@ - (void)setPackageName:(NSString *)packageName { } } +#pragma mark - local attribute methods + +- (void)setAttributeValuesFromPayload:(TuneSkyhookPayload*) payload{ + NSDictionary *userInfo = payload.userInfo; + if (userInfo){ + TuneEvent *event = userInfo[TunePayloadCustomEvent]; + if (event){ + // Add user attributes for any tags + NSMutableArray* tags = event.tags; + for (TuneAnalyticsVariable *analyticsVariable in tags) { + [self setAttributeValueFromAnalyticsVariable:analyticsVariable]; + } + } + } +} + +- (void) setAttributeValueFromAnalyticsVariable:(TuneAnalyticsVariable *)tuneAnalyticsVariable{ + [self setAttributeValue:tuneAnalyticsVariable.convertValueToString forKey:tuneAnalyticsVariable.name]; +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" +- (void) setAttributeValue:(NSString*) value forKey: (NSString*) key{ + id SmartWhereClass = [TuneUtils getClassFromString:TUNE_SMARTWHERE_CLASS_NAME]; + if (SmartWhereClass != nil && self.enableSmartWhereEventSharing) { + if (key != nil && key.length >0){ + NSString *swKey = [NSString stringWithFormat:@"%@%@", TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX, key]; + if (value != nil){ + [SmartWhereClass performSelector:@selector(setUserString:forKey:) withObject:value withObject:swKey]; + } else { + [SmartWhereClass performSelector:@selector(removeUserValueForKey:) withObject:swKey]; + } + } + } +} +#pragma clang diagnostic pop + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" +- (void) clearAttributeValue:(NSString*) variableName{ + id SmartWhereClass = [TuneUtils getClassFromString:TUNE_SMARTWHERE_CLASS_NAME]; + if (SmartWhereClass != nil && self.enableSmartWhereEventSharing) { + NSString *key = [NSString stringWithFormat:@"%@%@", TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX, variableName]; + [SmartWhereClass performSelector:@selector(removeUserValueForKey:) withObject:key]; + } +} +#pragma clang diagnostic pop + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" +- (void) clearAllAttributeValues{ + id SmartWhereClass = [TuneUtils getClassFromString:TUNE_SMARTWHERE_CLASS_NAME]; + if (SmartWhereClass != nil && self.enableSmartWhereEventSharing){ + NSDictionary *currentlySetAttributes = [SmartWhereClass performSelector:@selector(getUserAttributes)]; + for (NSString *key in currentlySetAttributes.allKeys) { + if ([key hasPrefix: TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX]){ + [SmartWhereClass performSelector:@selector(removeUserValueForKey:) withObject:key]; + } + } + } +} +#pragma clang diagnostic pop + +#pragma mark - tracking attribute methods +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" +- (void) setTrackingAttributeValue:(NSString*) value forKey: (NSString*) key{ + id SmartWhereClass = [TuneUtils getClassFromString:TUNE_SMARTWHERE_CLASS_NAME]; + if (SmartWhereClass != nil && self.enableSmartWhereEventSharing) { + if (key != nil && key.length >0){ + NSString *swKey = [NSString stringWithFormat:@"%@%@", TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX, key]; + if (value != nil){ + [SmartWhereClass performSelector:@selector(setUserTrackingString:forKey:) withObject:value withObject:swKey]; + } else { + [SmartWhereClass performSelector:@selector(removeUserTrackingValueForKey:) withObject:swKey]; + } + } + } +} +#pragma clang diagnostic pop #pragma mark - SmartWhere methods diff --git a/sdk-ios/Tune/Tune/TuneSmartWhereTriggeredEventManager.m b/sdk-ios/Tune/Tune/TuneSmartWhereTriggeredEventManager.m index 9929c58..f138607 100644 --- a/sdk-ios/Tune/Tune/TuneSmartWhereTriggeredEventManager.m +++ b/sdk-ios/Tune/Tune/TuneSmartWhereTriggeredEventManager.m @@ -32,6 +32,7 @@ - (void)registerSkyhooks{ - (void)handleTriggeredEvent:(TuneSkyhookPayload*)payload { if ([TuneSmartWhereHelper isSmartWhereAvailable]){ TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper setAttributeValuesFromPayload:payload]; [tuneSmartWhereHelper processMappedEvent:payload]; } } diff --git a/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m b/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m index c1e01fd..e31a7f6 100644 --- a/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m +++ b/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m @@ -14,15 +14,27 @@ #import "TuneUtils.h" #import "TuneEvent.h" #import "TuneSkyhookPayloadConstants.h" +#import "Tune.h" @interface SmartWhereForTest : NSObject - (void)invalidate; - (void)processMappedEvent:(TuneSkyhookPayload*) payload; ++ (void)setUserString:(NSString*)value forKey:(NSString*)key; ++ (void)removeUserValueForKey:(NSString*)key; ++ (NSDictionary*) getUserAttributes; ++ (void)setUserTrackingString:(NSString *)value forKey:(NSString *)key; ++ (void)removeUserTrackingValueForKey:(NSString*)key; @end @implementation SmartWhereForTest - (void)invalidate {} - (void)processMappedEvent:(TuneSkyhookPayload*) payload{} ++ (void)setUserString:(NSString*)value forKey:(NSString*)key{} ++ (void)removeUserValueForKey:(NSString*)key{} ++ (NSDictionary*) getUserAttributes{return nil;} ++ (void)setUserTrackingString:(NSString *)value forKey:(NSString *)key{} ++ (void)removeUserTrackingValueForKey:(NSString*)key{} + @end @interface TuneSmartWhereHelper (Testing) @@ -35,6 +47,7 @@ - (void)setSmartWhere:(id)smartWhere; - (id)getSmartWhere; - (void)setConfig:(NSDictionary *)config; + (void)invalidateForTesting; + @end @interface TuneSmartWhereHelperTests : XCTestCase { @@ -100,7 +113,6 @@ - (void)testIsSmartWhereAvailableReturnsTrueWhenSmartWhereClassIsFound { [mockTuneUtils verify]; } - #pragma mark - startMonitoringWithTuneAdvertiserId:tuneConversionKey: tests - (void)testStartMonitoringStartsProximityMonitoringWithAdIdAndConversionKey { @@ -122,10 +134,11 @@ - (void)testStartMonitoringStartsProximityMonitoringWithAdIdAndConversionKey { return (actualConfig[@"ENABLE_NOTIFICATION_PERMISSION_PROMPTING"] && [actualConfig[@"ENABLE_NOTIFICATION_PERMISSION_PROMPTING"] isEqual:@"false"]) && (actualConfig[@"ENABLE_LOCATION_PERMISSION_PROMPTING"] && [actualConfig[@"ENABLE_LOCATION_PERMISSION_PROMPTING"] isEqual:@"false"]) && (actualConfig[@"ENABLE_GEOFENCE_RANGING"] && [actualConfig[@"ENABLE_GEOFENCE_RANGING"] isEqual:@"true"]) && - (actualConfig[@"DELEGATE_NOTIFICATIONS"] && [actualConfig[@"DELEGATE_NOTIFICATIONS"] isEqual:@"true"]); + (actualConfig[@"DELEGATE_NOTIFICATIONS"] && [actualConfig[@"DELEGATE_NOTIFICATIONS"] isEqual:@"false"]); } return NO; }]]; + [[mockTestObj expect] setTrackingAttributeValue:TUNEVERSION forKey:@"TUNE_SDK_VERSION"]; [mockTestObj startMonitoringWithTuneAdvertiserId:@"aid" tuneConversionKey:@"key" packageName:@"packageName"]; @@ -380,6 +393,486 @@ - (void)testprocessMappedEventDoesntCallOnSmartWhereWhenUserInfoIsNil { [mockSmartWhere verify]; } +#pragma mark - set Attribute Value tests + +- (void)testsetAttributeValueFromAnalyticsVariableCallsSmartWhereWhenAvailable { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = @"expectedValue"; + + TuneAnalyticsVariable *analyticsVariable = [TuneAnalyticsVariable analyticsVariableWithName:variableName value:expectedValue]; + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(setUserString:forKey:) withObject:expectedValue withObject:expectedVariableName]; + + [testObj setAttributeValueFromAnalyticsVariable:analyticsVariable]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeVAlueFromAnalyticsVariableDoenstCallSmartWhereWhenNotAvailable { + [[[[mockTuneUtils expect] classMethod] andReturn:nil] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedValue = @"expectedValue"; + + TuneAnalyticsVariable *analyticsVariable = [TuneAnalyticsVariable analyticsVariableWithName:variableName value:expectedValue]; + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValueFromAnalyticsVariable:analyticsVariable]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeValueFromAnalyticsVariableDoesntCallSmartWhereWhenEventSharingIsDisabled { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedValue = @"expectedValue"; + + TuneAnalyticsVariable *analyticsVariable = [TuneAnalyticsVariable analyticsVariableWithName:variableName value:expectedValue]; + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = NO; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValueFromAnalyticsVariable:analyticsVariable]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeFromAnalyticsVariableChecksThatTheNameExists { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = nil; + NSString *expectedValue = @"expectedValue"; + + TuneAnalyticsVariable *analyticsVariable = [TuneAnalyticsVariable analyticsVariableWithName:variableName value:expectedValue]; + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValueFromAnalyticsVariable:analyticsVariable]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeFromAnalyticsVariableChecksThatTheNameIsntEmpty { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @""; + NSString *expectedValue = @"expectedValue"; + + TuneAnalyticsVariable *analyticsVariable = [TuneAnalyticsVariable analyticsVariableWithName:variableName value:expectedValue]; + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValueFromAnalyticsVariable:analyticsVariable]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeFromAnalyticsVariableRemovesTheAttributeIfTheValueIsNull { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = nil; + + TuneAnalyticsVariable *analyticsVariable = [TuneAnalyticsVariable analyticsVariableWithName:variableName value:expectedValue]; + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:expectedVariableName]; + + [testObj setAttributeValueFromAnalyticsVariable:analyticsVariable]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeValueCallsSmartWhereWhenAvailable { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(setUserString:forKey:) withObject:expectedValue withObject:expectedVariableName]; + + [testObj setAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeValueDoenstCallSmartWhereWhenNotAvailable { + [[[[mockTuneUtils expect] classMethod] andReturn:nil] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValue:variableName forKey:expectedValue]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeValueDoesntCallSmartWhereWhenEventSharingIsDisabled { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = NO; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeChecksThatTheNameExists { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = nil; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeChecksThatTheNameIsntEmpty { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @""; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeRemovesTheAttributeIfTheValueIsNull { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = nil; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:expectedVariableName]; + + [testObj setAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +#pragma setAttributeValuesFromPayload tests + +- (void)testsetAttributeValuesFromEventTagsCallsSmartWhere { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + NSString *variableName = @"key"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = @"value"; + + TuneEvent *expectedEvent = [TuneEvent eventWithName:TUNE_EVENT_ADD_TO_CART]; + [expectedEvent addTag:variableName withStringValue:expectedValue]; + TuneSkyhookPayload *payload = [[TuneSkyhookPayload alloc] initWithName:@"name" object:[NSObject new] userInfo:@{TunePayloadCustomEvent: expectedEvent }]; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(setUserString:forKey:) withObject:expectedValue withObject:expectedVariableName]; + + [testObj setAttributeValuesFromPayload:payload]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeValuesFromEventTagsCallSmartWhereForEachTag { + [[[[mockTuneUtils stub] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + NSString *variableName = @"key"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = @"value"; + NSString *variableName2 = @"key2"; + NSString *expectedVariableName2 = [NSString stringWithFormat:@"T_A_V_%@", variableName2]; + NSString *expectedValue2 = @"value2"; + + TuneEvent *expectedEvent = [TuneEvent eventWithName:TUNE_EVENT_ADD_TO_CART]; + [expectedEvent addTag:variableName withStringValue:expectedValue]; + [expectedEvent addTag:variableName2 withStringValue:expectedValue2]; + TuneSkyhookPayload *payload = [[TuneSkyhookPayload alloc] initWithName:@"name" object:[NSObject new] userInfo:@{TunePayloadCustomEvent: expectedEvent }]; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(setUserString:forKey:) withObject:expectedValue withObject:expectedVariableName]; + [[[mockSmartWhere expect] classMethod] performSelector:@selector(setUserString:forKey:) withObject:expectedValue2 withObject:expectedVariableName2]; + + [testObj setAttributeValuesFromPayload:payload]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeValuesFromEventTagsDoesntCallSmartWhereWhenNotAvailable { + [[[[mockTuneUtils stub] classMethod] andReturn:nil] getClassFromString:@"SmartWhere"]; + NSString *variableName = @"key"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = @"value"; + + TuneEvent *expectedEvent = [TuneEvent eventWithName:TUNE_EVENT_ADD_TO_CART]; + [expectedEvent addTag:variableName withStringValue:expectedValue]; + TuneSkyhookPayload *payload = [[TuneSkyhookPayload alloc] initWithName:@"name" object:[NSObject new] userInfo:@{TunePayloadCustomEvent: expectedEvent }]; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:expectedValue withObject:expectedVariableName]; + + [testObj setAttributeValuesFromPayload:payload]; + + [mockSmartWhere verify];; +} + +#pragma mark - clear attribute tests + +- (void)testclearAttributeValueCallsSmartWhereToRemoveObject { + [[[[mockTuneUtils stub] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + NSString *variableName = @"expectedName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:expectedVariableName]; + + testObj.enableSmartWhereEventSharing = YES; + [testObj clearAttributeValue:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testclearAttributeValueDoesntCallSmartWhereWhenNotAvailable { + [[[[mockTuneUtils stub] classMethod] andReturn:nil] getClassFromString:@"SmartWhere"]; + NSString *expectedName = @"expectedName"; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:OCMOCK_ANY]; + + testObj.enableSmartWhereEventSharing = YES; + [testObj clearAttributeValue:expectedName]; + + [mockSmartWhere verify]; +} + +- (void)testtestclearAttributeValueDoesntCallSmartWhereWhenSharingIsntEnabled { + [[[[mockTuneUtils stub] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + NSString *variableName = @"expectedName"; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:OCMOCK_ANY]; + + testObj.enableSmartWhereEventSharing = NO; + [testObj clearAttributeValue:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testtestclearAllAttributeValuesCallsSmartWhereForEachValueWithTunePrefix { + [[[[mockTuneUtils stub] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + NSMutableDictionary *currentlySetAttributes = [NSMutableDictionary new]; + currentlySetAttributes[@"key1"] = @"value1"; + currentlySetAttributes[@"key2"] = @"value2"; + currentlySetAttributes[@"key3"] = @"value3"; + currentlySetAttributes[@"T_A_V_key4"]= @"a value"; + currentlySetAttributes[@"T_A_V_key5"] = @"abc 123"; + + [[[[mockSmartWhere expect] classMethod] andReturn:currentlySetAttributes] performSelector:@selector(getUserAttributes)]; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key1"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key2"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key3"]; + [[[mockSmartWhere expect] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"T_A_V_key4"]; + [[[mockSmartWhere expect] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"T_A_V_key5"]; + + testObj.enableSmartWhereEventSharing = YES; + [testObj clearAllAttributeValues]; + + [mockSmartWhere verify]; +} + +- (void)testtestclearAllAttributeValuesDoesntCallSmartWhereWhenNotAvailable { + [[[[mockTuneUtils stub] classMethod] andReturn:nil] getClassFromString:@"SmartWhere"]; + NSMutableDictionary *currentlySetAttributes = [NSMutableDictionary new]; + currentlySetAttributes[@"key1"] = @"value1"; + currentlySetAttributes[@"key2"] = @"value2"; + currentlySetAttributes[@"key3"] = @"value3"; + currentlySetAttributes[@"T_A_V_key4"]= @"a value"; + currentlySetAttributes[@"T_A_V_key5"] = @"abc 123"; + + [[[[mockSmartWhere reject] classMethod] andReturn:currentlySetAttributes] performSelector:@selector(getUserAttributes)]; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key1"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key2"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key3"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"T_A_V_key4"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"T_A_V_key5"]; + + testObj.enableSmartWhereEventSharing = YES; + [testObj clearAllAttributeValues]; + + [mockSmartWhere verify]; +} + +- (void)testtestclearAllAttributeValuesDoesntCallSmartWhereWhenSharingIsntEnabled { + [[[[mockTuneUtils stub] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + NSMutableDictionary *currentlySetAttributes = [NSMutableDictionary new]; + currentlySetAttributes[@"key1"] = @"value1"; + currentlySetAttributes[@"key2"] = @"value2"; + currentlySetAttributes[@"key3"] = @"value3"; + currentlySetAttributes[@"T_A_V_key4"]= @"a value"; + currentlySetAttributes[@"T_A_V_key5"] = @"abc 123"; + + [[[[mockSmartWhere reject] classMethod] andReturn:currentlySetAttributes] performSelector:@selector(getUserAttributes)]; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key1"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key2"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key3"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"T_A_V_key4"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"T_A_V_key5"]; + + testObj.enableSmartWhereEventSharing = NO; + [testObj clearAllAttributeValues]; + + [mockSmartWhere verify]; +} + +#pragma mark - set tracking attribute value tests + +- (void)testSetTrackingAttributeValueCallsSmartWhereWhenAvailable { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(setUserTrackingString:forKey:) withObject:expectedValue withObject:expectedVariableName]; + + [testObj setTrackingAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testSetTrackingAttributeValueDoesntCallSmartWhereWhenNotAvailable { + [[[[mockTuneUtils expect] classMethod] andReturn:nil] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserTrackingString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setTrackingAttributeValue:variableName forKey:expectedValue]; + + [mockSmartWhere verify]; +} + +- (void)testSetTrackingAttributeValueDoesntCallSmartWhereWhenEventSharingIsDisabled { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = NO; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserTrackingString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setTrackingAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testSetTrackingAttributeChecksThatTheNameExists { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = nil; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserTrackingString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setTrackingAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testSetTrackingAttributeChecksThatTheNameIsntEmpty{ + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @""; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserTrackingString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setTrackingAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; + +} +- (void)testSetTrackingAttributeRemovesTheAttributeIfTheValueIsNull { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = nil; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(removeUserTrackingValueForKey:) withObject:expectedVariableName]; + + [testObj setTrackingAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + + #pragma mark - test helpers - (void)setTuneConfigurationMockWithDebug:(BOOL)debug { @@ -390,8 +883,8 @@ - (void)setTuneConfigurationMockWithDebug:(BOOL)debug { } - (void)setTuneUtilsGetClassFromStringToAnObject { - id obj = [NSObject new]; - [[[[mockTuneUtils expect] classMethod] andReturn:obj] getClassFromString:@"SmartWhere"]; +// id obj = [NSObject new]; + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; } @end diff --git a/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereTriggeredEventManagerTests.m b/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereTriggeredEventManagerTests.m index 0d9eb9e..d2a1241 100644 --- a/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereTriggeredEventManagerTests.m +++ b/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereTriggeredEventManagerTests.m @@ -98,9 +98,10 @@ - (void)testBringDownUnRegistersSkyhooks { #pragma mark - handleTriggeredEvent tests -- (void)testhandleTriggeredEventCallsProcessMappedEvent { +- (void)testhandleTriggeredEventCallsSetAttributeValuesFromPayloadAndProcessMappedEvent { [[[[mockTuneSmartWhereHelper stub] classMethod] andReturnValue:OCMOCK_VALUE(YES)] isSmartWhereAvailable]; + [[mockTuneSmartWhereHelper expect] setAttributeValuesFromPayload:mockPayload]; [[mockTuneSmartWhereHelper expect] processMappedEvent:mockPayload]; [testObj handleTriggeredEvent: mockPayload]; @@ -111,6 +112,7 @@ - (void)testhandleTriggeredEventCallsProcessMappedEvent { - (void)testhandleTriggeredEventDoesntCallProcessMappedEventWhenNotAvailable { [[[[mockTuneSmartWhereHelper stub] classMethod] andReturnValue:OCMOCK_VALUE(NO)] isSmartWhereAvailable]; + [[mockTuneSmartWhereHelper reject] setAttributeValuesFromPayload:mockPayload]; [[mockTuneSmartWhereHelper reject] processMappedEvent:OCMOCK_ANY]; [testObj handleTriggeredEvent: mockPayload]; From db6c04433f969d4afdf591e3460e732f1502f81b Mon Sep 17 00:00:00 2001 From: Gordon Stewart Date: Tue, 10 Oct 2017 16:07:40 -0700 Subject: [PATCH 2/4] Add Tune mat id as tracking metadata --- sdk-ios/Tune/Tune/TuneSmartWhereHelper.m | 2 ++ .../TuneSmartWhereHelperTests.m | 32 ++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m b/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m index 1d19fa4..1327be2 100644 --- a/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m +++ b/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m @@ -28,6 +28,7 @@ NSString * const TUNE_SMARTWHERE_PACKAGE_NAME = @"PACKAGE_NAME"; NSString * const TUNE_VERSION_STRING = @"TUNE_SDK_VERSION"; +NSString * const TUNE_MAT_ID_STRING = @"TUNE_MAT_ID"; @interface TuneSmartWhereHelper() @@ -81,6 +82,7 @@ - (void)startMonitoring { } [self setTrackingAttributeValue:TUNEVERSION forKey:TUNE_VERSION_STRING]; + [self setTrackingAttributeValue:[Tune tuneId] forKey:TUNE_MAT_ID_STRING]; WarnLog(@"TUNE: Starting SmartWhere Proximity Monitoring"); diff --git a/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m b/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m index e31a7f6..0a49fd2 100644 --- a/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m +++ b/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m @@ -13,6 +13,7 @@ #import "TuneSmartWhereHelper.h" #import "TuneUtils.h" #import "TuneEvent.h" +#import "TuneUserProfile.h" #import "TuneSkyhookPayloadConstants.h" #import "Tune.h" @@ -53,6 +54,7 @@ + (void)invalidateForTesting; @interface TuneSmartWhereHelperTests : XCTestCase { TuneSmartWhereHelper *testObj; id mockTuneManager; + id mockUserProfile; id mockTuneUtils; id mockSmartWhere; } @@ -65,8 +67,10 @@ - (void)setUp { [super setUp]; mockTuneUtils = OCMStrictClassMock([TuneUtils class]); - mockTuneManager = OCMStrictClassMock([TuneManager class]); + mockTuneManager = OCMClassMock([TuneManager class]); mockSmartWhere = OCMStrictClassMock([SmartWhereForTest class]); + mockUserProfile = OCMClassMock([TuneUserProfile class]); + [[[mockTuneManager stub] andReturn:mockUserProfile] userProfile]; [TuneSmartWhereHelper invalidateForTesting]; testObj = [TuneSmartWhereHelper getInstance]; @@ -76,6 +80,7 @@ - (void)tearDown { [mockTuneManager stopMocking]; [mockTuneUtils stopMocking]; [mockSmartWhere stopMocking]; + [mockUserProfile stopMocking]; [TuneSmartWhereHelper invalidateForTesting]; @@ -246,6 +251,26 @@ - (void)testStartMonitoringSetsPackageName { [mockTestObj verify]; } +- (void)testStartMonitoringAddsTrackingMetadata { + [self setTuneConfigurationMockWithDebug:YES]; + [self setTuneUtilsGetClassFromStringToAnObject]; + + NSString *expectedMatId = @"my mat id"; + [[[mockUserProfile expect] andReturn:expectedMatId] tuneId]; + + id mockTestObj = OCMPartialMock(testObj); + [[mockTestObj stub] startProximityMonitoringWithAppId:OCMOCK_ANY + withApiKey:OCMOCK_ANY + withApiSecret:OCMOCK_ANY + withConfig:OCMOCK_ANY]; + [[mockTestObj expect] setTrackingAttributeValue:TUNEVERSION forKey:@"TUNE_SDK_VERSION"]; + [[mockTestObj expect] setTrackingAttributeValue: expectedMatId forKey:@"TUNE_MAT_ID"]; + + [mockTestObj startMonitoringWithTuneAdvertiserId:@"aid" tuneConversionKey:@"key" packageName:@"package_name"]; + + [mockTestObj verify]; +} + #pragma mark - setDebugMode tests - (void)testSetDebugModeSetsDebugLoggingConfigAndInvokesSmartWhereConfigWhenYES { @@ -880,6 +905,11 @@ - (void)setTuneConfigurationMockWithDebug:(BOOL)debug { config.debugMode = @(debug); [[[[mockTuneManager stub] classMethod] andReturn:mockTuneManager] currentManager]; [[[mockTuneManager stub] andReturn:config] configuration]; + [[mockTuneManager stub] setUserProfile:OCMOCK_ANY]; + [[mockTuneManager stub] setConfiguration:OCMOCK_ANY]; +// [[mockUserProfile stub] registerSkyhooks]; +// [[mockUserProfile stub] setJailbroken:OCMOCK_ANY]; +// [[mockUserProfile stub] } - (void)setTuneUtilsGetClassFromStringToAnObject { From c44a38af2ae1689a08f576ed7af884014da022d1 Mon Sep 17 00:00:00 2001 From: Gordon Stewart Date: Fri, 6 Oct 2017 11:54:19 -0700 Subject: [PATCH 3/4] Pass custom user string and number to smartwhere when permitted. Default notifications to tray. Add tune version number to smartwhere tracking. --- sdk-ios/Tune/Tune/Tune.m | 28 + sdk-ios/Tune/Tune/TuneSmartWhereHelper.h | 39 ++ sdk-ios/Tune/Tune/TuneSmartWhereHelper.m | 90 +++- .../TuneSmartWhereTriggeredEventManager.m | 1 + .../TuneSmartWhereHelperTests.m | 501 +++++++++++++++++- ...TuneSmartWhereTriggeredEventManagerTests.m | 4 +- 6 files changed, 656 insertions(+), 7 deletions(-) diff --git a/sdk-ios/Tune/Tune/Tune.m b/sdk-ios/Tune/Tune/Tune.m index 9aa4f1c..941d6fb 100644 --- a/sdk-ios/Tune/Tune/Tune.m +++ b/sdk-ios/Tune/Tune/Tune.m @@ -436,10 +436,18 @@ + (void)registerCustomProfileVersion:(NSString *)variableName { + (void)registerCustomProfileString:(NSString *)variableName withDefault:(NSString *)value { [[TuneManager currentManager].userProfile registerString:variableName withDefault:value]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper setAttributeValue:value forKey:variableName]; + } } + (void)registerCustomProfileString:(NSString *)variableName withDefault:(NSString *)value hashed:(BOOL)shouldHash { [[TuneManager currentManager].userProfile registerString:variableName withDefault:value hashed:shouldHash]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper setAttributeValue:value forKey:variableName]; + } } + (void)registerCustomProfileBoolean:(NSString *)variableName withDefault:(NSNumber *)value { @@ -452,6 +460,10 @@ + (void)registerCustomProfileDateTime:(NSString *)variableName withDefault:(NSDa + (void)registerCustomProfileNumber:(NSString *)variableName withDefault:(NSNumber *)value { [[TuneManager currentManager].userProfile registerNumber:variableName withDefault:value]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper setAttributeValue:[value stringValue] forKey:variableName]; + } } + (void)registerCustomProfileGeolocation:(NSString *)variableName withDefault:(TuneLocation *)value { @@ -464,6 +476,10 @@ + (void)registerCustomProfileVersion:(NSString *)variableName withDefault:(NSStr + (void)setCustomProfileStringValue:(NSString *)value forVariable:(NSString *)name { [[TuneManager currentManager].userProfile setStringValue:value forVariable:name]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper setAttributeValue:value forKey:name]; + } } + (void)setCustomProfileBooleanValue:(NSNumber *)value forVariable:(NSString *)name { @@ -476,6 +492,10 @@ + (void)setCustomProfileDateTimeValue:(NSDate *)value forVariable:(NSString *)na + (void)setCustomProfileNumberValue:(NSNumber *)value forVariable:(NSString *)name { [[TuneManager currentManager].userProfile setNumberValue:value forVariable:name]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper setAttributeValue:[value stringValue] forKey:name]; + } } + (void)setCustomProfileGeolocationValue:(TuneLocation *)value forVariable:(NSString *)name { @@ -504,10 +524,18 @@ + (TuneLocation *)getCustomProfileGeolocation:(NSString *)name { + (void)clearCustomProfileVariable:(NSString *)name { [[TuneManager currentManager].userProfile clearCustomVariables:[NSSet setWithObject:name]]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper clearAttributeValue:name]; + } } + (void)clearAllCustomProfileVariables { [[TuneManager currentManager].userProfile clearCustomProfile]; + if ([TuneSmartWhereHelper isSmartWhereAvailable]){ + TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper clearAllAttributeValues]; + } } #pragma mark - Getter Methods diff --git a/sdk-ios/Tune/Tune/TuneSmartWhereHelper.h b/sdk-ios/Tune/Tune/TuneSmartWhereHelper.h index 105c0b2..84a6718 100644 --- a/sdk-ios/Tune/Tune/TuneSmartWhereHelper.h +++ b/sdk-ios/Tune/Tune/TuneSmartWhereHelper.h @@ -8,6 +8,7 @@ #import #import "TuneSkyhookPayload.h" +#import "TuneAnalyticsVariable.h" @protocol SmartWhereDelegate @end @@ -70,6 +71,43 @@ */ - (void)processMappedEvent:(TuneSkyhookPayload*) payload; +/*! + * Set custom user attributes for use in notification replacements and event conditions. + * @param value String value of the attribute value + * @param key Strting value of the attribute name + */ +- (void) setAttributeValue:(NSString*) value forKey: (NSString*) key; + +/*! + * Set custom user attributes for use in notification replacements and event conditions. + * @param tuneAnalyticsVariable TuneAnalyticsVariable + */ +- (void)setAttributeValueFromAnalyticsVariable:(TuneAnalyticsVariable *)tuneAnalyticsVariable; + +/*! + * Set custom user attributes for use in notification replacements and event conditions. + * @param payload TuneSkyhookPayload containing a TuneEvent with tags + */ +- (void)setAttributeValuesFromPayload:(TuneSkyhookPayload*) payload; + +/*! + * Clear a custom user attribute. + * @param variableName String value of the attribute name + */ +- (void)clearAttributeValue:(NSString*) variableName; + +/*! + * Clear all custom user attributes. + */ +- (void)clearAllAttributeValues; + +/*! + * Set custom user tracking attributes that will be sent as metadata in tracking calls. + * @param value String value of the attribute value + * @param key Strting value of the attribute name + */ +- (void) setTrackingAttributeValue:(NSString*) value forKey: (NSString*) key; + @end #ifndef TUNE_SW_EventActionType_Defined @@ -100,6 +138,7 @@ typedef enum TUNE_SW_EventActionType : NSInteger { typedef enum TUNE_SW_ProximityTriggerType : NSInteger { TUNE_SW_swNfcTap = 0, TUNE_SW_swQRScan = 1, + TUNE_SW_swNfcTapCancel = 2, TUNE_SW_swBleEnter = 10, TUNE_SW_swBleHover = 11, TUNE_SW_swBleDwell = 12, diff --git a/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m b/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m index f06dea0..1d19fa4 100644 --- a/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m +++ b/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m @@ -7,10 +7,11 @@ // #import "TuneSmartWhereHelper.h" -#import "TuneEvent.h" +#import "TuneEvent+Internal.h" #import "TuneSkyhookPayloadConstants.h" #import "TuneKeyStrings.h" #import "TuneUtils.h" +#import "Tune.h" static id _smartWhere; static TuneSmartWhereHelper *tuneSharedSmartWhereHelper = nil; @@ -18,6 +19,7 @@ NSString * const TUNE_SMARTWHERE_CLASS_NAME = @"SmartWhere"; +NSString * const TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX = @"T_A_V_"; NSString * const TUNE_SMARTWHERE_ENABLE_NOTIFICATION_PERMISSION_PROMPTING = @"ENABLE_NOTIFICATION_PERMISSION_PROMPTING"; NSString * const TUNE_SMARTWHERE_ENABLE_LOCATION_PERMISSION_PROMPTING = @"ENABLE_LOCATION_PERMISSION_PROMPTING"; NSString * const TUNE_SMARTWHERE_ENABLE_GEOFENCE_RANGING = @"ENABLE_GEOFENCE_RANGING"; @@ -25,6 +27,8 @@ NSString * const TUNE_SMARTWHERE_DEBUG_LOGGING = @"DEBUG_LOGGING"; NSString * const TUNE_SMARTWHERE_PACKAGE_NAME = @"PACKAGE_NAME"; +NSString * const TUNE_VERSION_STRING = @"TUNE_SDK_VERSION"; + @interface TuneSmartWhereHelper() /*! @@ -69,13 +73,15 @@ - (void)startMonitoring { config[TUNE_SMARTWHERE_ENABLE_NOTIFICATION_PERMISSION_PROMPTING] = TUNE_STRING_FALSE; config[TUNE_SMARTWHERE_ENABLE_LOCATION_PERMISSION_PROMPTING] = TUNE_STRING_FALSE; config[TUNE_SMARTWHERE_ENABLE_GEOFENCE_RANGING] = TUNE_STRING_TRUE; - config[TUNE_SMARTWHERE_DELEGATE_NOTIFICATIONS] = TUNE_STRING_TRUE; + config[TUNE_SMARTWHERE_DELEGATE_NOTIFICATIONS] = TUNE_STRING_FALSE; config[TUNE_SMARTWHERE_PACKAGE_NAME] = _packageName; if ([[TuneManager currentManager].configuration.debugMode boolValue]) { config[TUNE_SMARTWHERE_DEBUG_LOGGING] = TUNE_STRING_TRUE; } + [self setTrackingAttributeValue:TUNEVERSION forKey:TUNE_VERSION_STRING]; + WarnLog(@"TUNE: Starting SmartWhere Proximity Monitoring"); [self startProximityMonitoringWithAppId:_aid withApiKey:_aid withApiSecret:_key withConfig:config]; @@ -130,6 +136,86 @@ - (void)setPackageName:(NSString *)packageName { } } +#pragma mark - local attribute methods + +- (void)setAttributeValuesFromPayload:(TuneSkyhookPayload*) payload{ + NSDictionary *userInfo = payload.userInfo; + if (userInfo){ + TuneEvent *event = userInfo[TunePayloadCustomEvent]; + if (event){ + // Add user attributes for any tags + NSMutableArray* tags = event.tags; + for (TuneAnalyticsVariable *analyticsVariable in tags) { + [self setAttributeValueFromAnalyticsVariable:analyticsVariable]; + } + } + } +} + +- (void) setAttributeValueFromAnalyticsVariable:(TuneAnalyticsVariable *)tuneAnalyticsVariable{ + [self setAttributeValue:tuneAnalyticsVariable.convertValueToString forKey:tuneAnalyticsVariable.name]; +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" +- (void) setAttributeValue:(NSString*) value forKey: (NSString*) key{ + id SmartWhereClass = [TuneUtils getClassFromString:TUNE_SMARTWHERE_CLASS_NAME]; + if (SmartWhereClass != nil && self.enableSmartWhereEventSharing) { + if (key != nil && key.length >0){ + NSString *swKey = [NSString stringWithFormat:@"%@%@", TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX, key]; + if (value != nil){ + [SmartWhereClass performSelector:@selector(setUserString:forKey:) withObject:value withObject:swKey]; + } else { + [SmartWhereClass performSelector:@selector(removeUserValueForKey:) withObject:swKey]; + } + } + } +} +#pragma clang diagnostic pop + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" +- (void) clearAttributeValue:(NSString*) variableName{ + id SmartWhereClass = [TuneUtils getClassFromString:TUNE_SMARTWHERE_CLASS_NAME]; + if (SmartWhereClass != nil && self.enableSmartWhereEventSharing) { + NSString *key = [NSString stringWithFormat:@"%@%@", TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX, variableName]; + [SmartWhereClass performSelector:@selector(removeUserValueForKey:) withObject:key]; + } +} +#pragma clang diagnostic pop + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" +- (void) clearAllAttributeValues{ + id SmartWhereClass = [TuneUtils getClassFromString:TUNE_SMARTWHERE_CLASS_NAME]; + if (SmartWhereClass != nil && self.enableSmartWhereEventSharing){ + NSDictionary *currentlySetAttributes = [SmartWhereClass performSelector:@selector(getUserAttributes)]; + for (NSString *key in currentlySetAttributes.allKeys) { + if ([key hasPrefix: TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX]){ + [SmartWhereClass performSelector:@selector(removeUserValueForKey:) withObject:key]; + } + } + } +} +#pragma clang diagnostic pop + +#pragma mark - tracking attribute methods +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" +- (void) setTrackingAttributeValue:(NSString*) value forKey: (NSString*) key{ + id SmartWhereClass = [TuneUtils getClassFromString:TUNE_SMARTWHERE_CLASS_NAME]; + if (SmartWhereClass != nil && self.enableSmartWhereEventSharing) { + if (key != nil && key.length >0){ + NSString *swKey = [NSString stringWithFormat:@"%@%@", TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX, key]; + if (value != nil){ + [SmartWhereClass performSelector:@selector(setUserTrackingString:forKey:) withObject:value withObject:swKey]; + } else { + [SmartWhereClass performSelector:@selector(removeUserTrackingValueForKey:) withObject:swKey]; + } + } + } +} +#pragma clang diagnostic pop #pragma mark - SmartWhere methods diff --git a/sdk-ios/Tune/Tune/TuneSmartWhereTriggeredEventManager.m b/sdk-ios/Tune/Tune/TuneSmartWhereTriggeredEventManager.m index 9929c58..f138607 100644 --- a/sdk-ios/Tune/Tune/TuneSmartWhereTriggeredEventManager.m +++ b/sdk-ios/Tune/Tune/TuneSmartWhereTriggeredEventManager.m @@ -32,6 +32,7 @@ - (void)registerSkyhooks{ - (void)handleTriggeredEvent:(TuneSkyhookPayload*)payload { if ([TuneSmartWhereHelper isSmartWhereAvailable]){ TuneSmartWhereHelper *tuneSmartWhereHelper = [TuneSmartWhereHelper getInstance]; + [tuneSmartWhereHelper setAttributeValuesFromPayload:payload]; [tuneSmartWhereHelper processMappedEvent:payload]; } } diff --git a/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m b/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m index c1e01fd..e31a7f6 100644 --- a/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m +++ b/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m @@ -14,15 +14,27 @@ #import "TuneUtils.h" #import "TuneEvent.h" #import "TuneSkyhookPayloadConstants.h" +#import "Tune.h" @interface SmartWhereForTest : NSObject - (void)invalidate; - (void)processMappedEvent:(TuneSkyhookPayload*) payload; ++ (void)setUserString:(NSString*)value forKey:(NSString*)key; ++ (void)removeUserValueForKey:(NSString*)key; ++ (NSDictionary*) getUserAttributes; ++ (void)setUserTrackingString:(NSString *)value forKey:(NSString *)key; ++ (void)removeUserTrackingValueForKey:(NSString*)key; @end @implementation SmartWhereForTest - (void)invalidate {} - (void)processMappedEvent:(TuneSkyhookPayload*) payload{} ++ (void)setUserString:(NSString*)value forKey:(NSString*)key{} ++ (void)removeUserValueForKey:(NSString*)key{} ++ (NSDictionary*) getUserAttributes{return nil;} ++ (void)setUserTrackingString:(NSString *)value forKey:(NSString *)key{} ++ (void)removeUserTrackingValueForKey:(NSString*)key{} + @end @interface TuneSmartWhereHelper (Testing) @@ -35,6 +47,7 @@ - (void)setSmartWhere:(id)smartWhere; - (id)getSmartWhere; - (void)setConfig:(NSDictionary *)config; + (void)invalidateForTesting; + @end @interface TuneSmartWhereHelperTests : XCTestCase { @@ -100,7 +113,6 @@ - (void)testIsSmartWhereAvailableReturnsTrueWhenSmartWhereClassIsFound { [mockTuneUtils verify]; } - #pragma mark - startMonitoringWithTuneAdvertiserId:tuneConversionKey: tests - (void)testStartMonitoringStartsProximityMonitoringWithAdIdAndConversionKey { @@ -122,10 +134,11 @@ - (void)testStartMonitoringStartsProximityMonitoringWithAdIdAndConversionKey { return (actualConfig[@"ENABLE_NOTIFICATION_PERMISSION_PROMPTING"] && [actualConfig[@"ENABLE_NOTIFICATION_PERMISSION_PROMPTING"] isEqual:@"false"]) && (actualConfig[@"ENABLE_LOCATION_PERMISSION_PROMPTING"] && [actualConfig[@"ENABLE_LOCATION_PERMISSION_PROMPTING"] isEqual:@"false"]) && (actualConfig[@"ENABLE_GEOFENCE_RANGING"] && [actualConfig[@"ENABLE_GEOFENCE_RANGING"] isEqual:@"true"]) && - (actualConfig[@"DELEGATE_NOTIFICATIONS"] && [actualConfig[@"DELEGATE_NOTIFICATIONS"] isEqual:@"true"]); + (actualConfig[@"DELEGATE_NOTIFICATIONS"] && [actualConfig[@"DELEGATE_NOTIFICATIONS"] isEqual:@"false"]); } return NO; }]]; + [[mockTestObj expect] setTrackingAttributeValue:TUNEVERSION forKey:@"TUNE_SDK_VERSION"]; [mockTestObj startMonitoringWithTuneAdvertiserId:@"aid" tuneConversionKey:@"key" packageName:@"packageName"]; @@ -380,6 +393,486 @@ - (void)testprocessMappedEventDoesntCallOnSmartWhereWhenUserInfoIsNil { [mockSmartWhere verify]; } +#pragma mark - set Attribute Value tests + +- (void)testsetAttributeValueFromAnalyticsVariableCallsSmartWhereWhenAvailable { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = @"expectedValue"; + + TuneAnalyticsVariable *analyticsVariable = [TuneAnalyticsVariable analyticsVariableWithName:variableName value:expectedValue]; + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(setUserString:forKey:) withObject:expectedValue withObject:expectedVariableName]; + + [testObj setAttributeValueFromAnalyticsVariable:analyticsVariable]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeVAlueFromAnalyticsVariableDoenstCallSmartWhereWhenNotAvailable { + [[[[mockTuneUtils expect] classMethod] andReturn:nil] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedValue = @"expectedValue"; + + TuneAnalyticsVariable *analyticsVariable = [TuneAnalyticsVariable analyticsVariableWithName:variableName value:expectedValue]; + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValueFromAnalyticsVariable:analyticsVariable]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeValueFromAnalyticsVariableDoesntCallSmartWhereWhenEventSharingIsDisabled { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedValue = @"expectedValue"; + + TuneAnalyticsVariable *analyticsVariable = [TuneAnalyticsVariable analyticsVariableWithName:variableName value:expectedValue]; + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = NO; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValueFromAnalyticsVariable:analyticsVariable]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeFromAnalyticsVariableChecksThatTheNameExists { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = nil; + NSString *expectedValue = @"expectedValue"; + + TuneAnalyticsVariable *analyticsVariable = [TuneAnalyticsVariable analyticsVariableWithName:variableName value:expectedValue]; + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValueFromAnalyticsVariable:analyticsVariable]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeFromAnalyticsVariableChecksThatTheNameIsntEmpty { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @""; + NSString *expectedValue = @"expectedValue"; + + TuneAnalyticsVariable *analyticsVariable = [TuneAnalyticsVariable analyticsVariableWithName:variableName value:expectedValue]; + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValueFromAnalyticsVariable:analyticsVariable]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeFromAnalyticsVariableRemovesTheAttributeIfTheValueIsNull { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = nil; + + TuneAnalyticsVariable *analyticsVariable = [TuneAnalyticsVariable analyticsVariableWithName:variableName value:expectedValue]; + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:expectedVariableName]; + + [testObj setAttributeValueFromAnalyticsVariable:analyticsVariable]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeValueCallsSmartWhereWhenAvailable { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(setUserString:forKey:) withObject:expectedValue withObject:expectedVariableName]; + + [testObj setAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeValueDoenstCallSmartWhereWhenNotAvailable { + [[[[mockTuneUtils expect] classMethod] andReturn:nil] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValue:variableName forKey:expectedValue]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeValueDoesntCallSmartWhereWhenEventSharingIsDisabled { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = NO; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeChecksThatTheNameExists { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = nil; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeChecksThatTheNameIsntEmpty { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @""; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeRemovesTheAttributeIfTheValueIsNull { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = nil; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:expectedVariableName]; + + [testObj setAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +#pragma setAttributeValuesFromPayload tests + +- (void)testsetAttributeValuesFromEventTagsCallsSmartWhere { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + NSString *variableName = @"key"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = @"value"; + + TuneEvent *expectedEvent = [TuneEvent eventWithName:TUNE_EVENT_ADD_TO_CART]; + [expectedEvent addTag:variableName withStringValue:expectedValue]; + TuneSkyhookPayload *payload = [[TuneSkyhookPayload alloc] initWithName:@"name" object:[NSObject new] userInfo:@{TunePayloadCustomEvent: expectedEvent }]; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(setUserString:forKey:) withObject:expectedValue withObject:expectedVariableName]; + + [testObj setAttributeValuesFromPayload:payload]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeValuesFromEventTagsCallSmartWhereForEachTag { + [[[[mockTuneUtils stub] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + NSString *variableName = @"key"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = @"value"; + NSString *variableName2 = @"key2"; + NSString *expectedVariableName2 = [NSString stringWithFormat:@"T_A_V_%@", variableName2]; + NSString *expectedValue2 = @"value2"; + + TuneEvent *expectedEvent = [TuneEvent eventWithName:TUNE_EVENT_ADD_TO_CART]; + [expectedEvent addTag:variableName withStringValue:expectedValue]; + [expectedEvent addTag:variableName2 withStringValue:expectedValue2]; + TuneSkyhookPayload *payload = [[TuneSkyhookPayload alloc] initWithName:@"name" object:[NSObject new] userInfo:@{TunePayloadCustomEvent: expectedEvent }]; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(setUserString:forKey:) withObject:expectedValue withObject:expectedVariableName]; + [[[mockSmartWhere expect] classMethod] performSelector:@selector(setUserString:forKey:) withObject:expectedValue2 withObject:expectedVariableName2]; + + [testObj setAttributeValuesFromPayload:payload]; + + [mockSmartWhere verify]; +} + +- (void)testsetAttributeValuesFromEventTagsDoesntCallSmartWhereWhenNotAvailable { + [[[[mockTuneUtils stub] classMethod] andReturn:nil] getClassFromString:@"SmartWhere"]; + NSString *variableName = @"key"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = @"value"; + + TuneEvent *expectedEvent = [TuneEvent eventWithName:TUNE_EVENT_ADD_TO_CART]; + [expectedEvent addTag:variableName withStringValue:expectedValue]; + TuneSkyhookPayload *payload = [[TuneSkyhookPayload alloc] initWithName:@"name" object:[NSObject new] userInfo:@{TunePayloadCustomEvent: expectedEvent }]; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserString:forKey:) withObject:expectedValue withObject:expectedVariableName]; + + [testObj setAttributeValuesFromPayload:payload]; + + [mockSmartWhere verify];; +} + +#pragma mark - clear attribute tests + +- (void)testclearAttributeValueCallsSmartWhereToRemoveObject { + [[[[mockTuneUtils stub] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + NSString *variableName = @"expectedName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:expectedVariableName]; + + testObj.enableSmartWhereEventSharing = YES; + [testObj clearAttributeValue:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testclearAttributeValueDoesntCallSmartWhereWhenNotAvailable { + [[[[mockTuneUtils stub] classMethod] andReturn:nil] getClassFromString:@"SmartWhere"]; + NSString *expectedName = @"expectedName"; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:OCMOCK_ANY]; + + testObj.enableSmartWhereEventSharing = YES; + [testObj clearAttributeValue:expectedName]; + + [mockSmartWhere verify]; +} + +- (void)testtestclearAttributeValueDoesntCallSmartWhereWhenSharingIsntEnabled { + [[[[mockTuneUtils stub] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + NSString *variableName = @"expectedName"; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:OCMOCK_ANY]; + + testObj.enableSmartWhereEventSharing = NO; + [testObj clearAttributeValue:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testtestclearAllAttributeValuesCallsSmartWhereForEachValueWithTunePrefix { + [[[[mockTuneUtils stub] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + NSMutableDictionary *currentlySetAttributes = [NSMutableDictionary new]; + currentlySetAttributes[@"key1"] = @"value1"; + currentlySetAttributes[@"key2"] = @"value2"; + currentlySetAttributes[@"key3"] = @"value3"; + currentlySetAttributes[@"T_A_V_key4"]= @"a value"; + currentlySetAttributes[@"T_A_V_key5"] = @"abc 123"; + + [[[[mockSmartWhere expect] classMethod] andReturn:currentlySetAttributes] performSelector:@selector(getUserAttributes)]; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key1"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key2"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key3"]; + [[[mockSmartWhere expect] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"T_A_V_key4"]; + [[[mockSmartWhere expect] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"T_A_V_key5"]; + + testObj.enableSmartWhereEventSharing = YES; + [testObj clearAllAttributeValues]; + + [mockSmartWhere verify]; +} + +- (void)testtestclearAllAttributeValuesDoesntCallSmartWhereWhenNotAvailable { + [[[[mockTuneUtils stub] classMethod] andReturn:nil] getClassFromString:@"SmartWhere"]; + NSMutableDictionary *currentlySetAttributes = [NSMutableDictionary new]; + currentlySetAttributes[@"key1"] = @"value1"; + currentlySetAttributes[@"key2"] = @"value2"; + currentlySetAttributes[@"key3"] = @"value3"; + currentlySetAttributes[@"T_A_V_key4"]= @"a value"; + currentlySetAttributes[@"T_A_V_key5"] = @"abc 123"; + + [[[[mockSmartWhere reject] classMethod] andReturn:currentlySetAttributes] performSelector:@selector(getUserAttributes)]; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key1"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key2"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key3"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"T_A_V_key4"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"T_A_V_key5"]; + + testObj.enableSmartWhereEventSharing = YES; + [testObj clearAllAttributeValues]; + + [mockSmartWhere verify]; +} + +- (void)testtestclearAllAttributeValuesDoesntCallSmartWhereWhenSharingIsntEnabled { + [[[[mockTuneUtils stub] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + NSMutableDictionary *currentlySetAttributes = [NSMutableDictionary new]; + currentlySetAttributes[@"key1"] = @"value1"; + currentlySetAttributes[@"key2"] = @"value2"; + currentlySetAttributes[@"key3"] = @"value3"; + currentlySetAttributes[@"T_A_V_key4"]= @"a value"; + currentlySetAttributes[@"T_A_V_key5"] = @"abc 123"; + + [[[[mockSmartWhere reject] classMethod] andReturn:currentlySetAttributes] performSelector:@selector(getUserAttributes)]; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key1"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key2"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"key3"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"T_A_V_key4"]; + [[[mockSmartWhere reject] classMethod] performSelector:@selector(removeUserValueForKey:) withObject:@"T_A_V_key5"]; + + testObj.enableSmartWhereEventSharing = NO; + [testObj clearAllAttributeValues]; + + [mockSmartWhere verify]; +} + +#pragma mark - set tracking attribute value tests + +- (void)testSetTrackingAttributeValueCallsSmartWhereWhenAvailable { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(setUserTrackingString:forKey:) withObject:expectedValue withObject:expectedVariableName]; + + [testObj setTrackingAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testSetTrackingAttributeValueDoesntCallSmartWhereWhenNotAvailable { + [[[[mockTuneUtils expect] classMethod] andReturn:nil] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserTrackingString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setTrackingAttributeValue:variableName forKey:expectedValue]; + + [mockSmartWhere verify]; +} + +- (void)testSetTrackingAttributeValueDoesntCallSmartWhereWhenEventSharingIsDisabled { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = NO; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserTrackingString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setTrackingAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testSetTrackingAttributeChecksThatTheNameExists { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = nil; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserTrackingString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setTrackingAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + +- (void)testSetTrackingAttributeChecksThatTheNameIsntEmpty{ + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @""; + NSString *expectedValue = @"expectedValue"; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere reject] classMethod] performSelector:@selector(setUserTrackingString:forKey:) withObject:OCMOCK_ANY withObject:OCMOCK_ANY]; + + [testObj setTrackingAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; + +} +- (void)testSetTrackingAttributeRemovesTheAttributeIfTheValueIsNull { + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; + + NSString *variableName = @"variableName"; + NSString *expectedVariableName = [NSString stringWithFormat:@"T_A_V_%@", variableName]; + NSString *expectedValue = nil; + + [testObj setSmartWhere:mockSmartWhere]; + testObj.enableSmartWhereEventSharing = YES; + + [[[mockSmartWhere expect] classMethod] performSelector:@selector(removeUserTrackingValueForKey:) withObject:expectedVariableName]; + + [testObj setTrackingAttributeValue:expectedValue forKey:variableName]; + + [mockSmartWhere verify]; +} + + #pragma mark - test helpers - (void)setTuneConfigurationMockWithDebug:(BOOL)debug { @@ -390,8 +883,8 @@ - (void)setTuneConfigurationMockWithDebug:(BOOL)debug { } - (void)setTuneUtilsGetClassFromStringToAnObject { - id obj = [NSObject new]; - [[[[mockTuneUtils expect] classMethod] andReturn:obj] getClassFromString:@"SmartWhere"]; +// id obj = [NSObject new]; + [[[[mockTuneUtils expect] classMethod] andReturn:[mockSmartWhere class]] getClassFromString:@"SmartWhere"]; } @end diff --git a/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereTriggeredEventManagerTests.m b/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereTriggeredEventManagerTests.m index 0d9eb9e..d2a1241 100644 --- a/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereTriggeredEventManagerTests.m +++ b/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereTriggeredEventManagerTests.m @@ -98,9 +98,10 @@ - (void)testBringDownUnRegistersSkyhooks { #pragma mark - handleTriggeredEvent tests -- (void)testhandleTriggeredEventCallsProcessMappedEvent { +- (void)testhandleTriggeredEventCallsSetAttributeValuesFromPayloadAndProcessMappedEvent { [[[[mockTuneSmartWhereHelper stub] classMethod] andReturnValue:OCMOCK_VALUE(YES)] isSmartWhereAvailable]; + [[mockTuneSmartWhereHelper expect] setAttributeValuesFromPayload:mockPayload]; [[mockTuneSmartWhereHelper expect] processMappedEvent:mockPayload]; [testObj handleTriggeredEvent: mockPayload]; @@ -111,6 +112,7 @@ - (void)testhandleTriggeredEventCallsProcessMappedEvent { - (void)testhandleTriggeredEventDoesntCallProcessMappedEventWhenNotAvailable { [[[[mockTuneSmartWhereHelper stub] classMethod] andReturnValue:OCMOCK_VALUE(NO)] isSmartWhereAvailable]; + [[mockTuneSmartWhereHelper reject] setAttributeValuesFromPayload:mockPayload]; [[mockTuneSmartWhereHelper reject] processMappedEvent:OCMOCK_ANY]; [testObj handleTriggeredEvent: mockPayload]; From 5102eb73da68dba0dfc2287145d329a324e44f51 Mon Sep 17 00:00:00 2001 From: Gordon Stewart Date: Tue, 10 Oct 2017 16:07:40 -0700 Subject: [PATCH 4/4] Add Tune mat id as tracking metadata --- sdk-ios/Tune/Tune/TuneSmartWhereHelper.m | 2 ++ .../TuneSmartWhereHelperTests.m | 32 ++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m b/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m index 1d19fa4..1327be2 100644 --- a/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m +++ b/sdk-ios/Tune/Tune/TuneSmartWhereHelper.m @@ -28,6 +28,7 @@ NSString * const TUNE_SMARTWHERE_PACKAGE_NAME = @"PACKAGE_NAME"; NSString * const TUNE_VERSION_STRING = @"TUNE_SDK_VERSION"; +NSString * const TUNE_MAT_ID_STRING = @"TUNE_MAT_ID"; @interface TuneSmartWhereHelper() @@ -81,6 +82,7 @@ - (void)startMonitoring { } [self setTrackingAttributeValue:TUNEVERSION forKey:TUNE_VERSION_STRING]; + [self setTrackingAttributeValue:[Tune tuneId] forKey:TUNE_MAT_ID_STRING]; WarnLog(@"TUNE: Starting SmartWhere Proximity Monitoring"); diff --git a/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m b/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m index e31a7f6..0a49fd2 100644 --- a/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m +++ b/sdk-ios/Tune/TuneMarketingConsoleSDKTests/TuneSmartWhereHelperTests.m @@ -13,6 +13,7 @@ #import "TuneSmartWhereHelper.h" #import "TuneUtils.h" #import "TuneEvent.h" +#import "TuneUserProfile.h" #import "TuneSkyhookPayloadConstants.h" #import "Tune.h" @@ -53,6 +54,7 @@ + (void)invalidateForTesting; @interface TuneSmartWhereHelperTests : XCTestCase { TuneSmartWhereHelper *testObj; id mockTuneManager; + id mockUserProfile; id mockTuneUtils; id mockSmartWhere; } @@ -65,8 +67,10 @@ - (void)setUp { [super setUp]; mockTuneUtils = OCMStrictClassMock([TuneUtils class]); - mockTuneManager = OCMStrictClassMock([TuneManager class]); + mockTuneManager = OCMClassMock([TuneManager class]); mockSmartWhere = OCMStrictClassMock([SmartWhereForTest class]); + mockUserProfile = OCMClassMock([TuneUserProfile class]); + [[[mockTuneManager stub] andReturn:mockUserProfile] userProfile]; [TuneSmartWhereHelper invalidateForTesting]; testObj = [TuneSmartWhereHelper getInstance]; @@ -76,6 +80,7 @@ - (void)tearDown { [mockTuneManager stopMocking]; [mockTuneUtils stopMocking]; [mockSmartWhere stopMocking]; + [mockUserProfile stopMocking]; [TuneSmartWhereHelper invalidateForTesting]; @@ -246,6 +251,26 @@ - (void)testStartMonitoringSetsPackageName { [mockTestObj verify]; } +- (void)testStartMonitoringAddsTrackingMetadata { + [self setTuneConfigurationMockWithDebug:YES]; + [self setTuneUtilsGetClassFromStringToAnObject]; + + NSString *expectedMatId = @"my mat id"; + [[[mockUserProfile expect] andReturn:expectedMatId] tuneId]; + + id mockTestObj = OCMPartialMock(testObj); + [[mockTestObj stub] startProximityMonitoringWithAppId:OCMOCK_ANY + withApiKey:OCMOCK_ANY + withApiSecret:OCMOCK_ANY + withConfig:OCMOCK_ANY]; + [[mockTestObj expect] setTrackingAttributeValue:TUNEVERSION forKey:@"TUNE_SDK_VERSION"]; + [[mockTestObj expect] setTrackingAttributeValue: expectedMatId forKey:@"TUNE_MAT_ID"]; + + [mockTestObj startMonitoringWithTuneAdvertiserId:@"aid" tuneConversionKey:@"key" packageName:@"package_name"]; + + [mockTestObj verify]; +} + #pragma mark - setDebugMode tests - (void)testSetDebugModeSetsDebugLoggingConfigAndInvokesSmartWhereConfigWhenYES { @@ -880,6 +905,11 @@ - (void)setTuneConfigurationMockWithDebug:(BOOL)debug { config.debugMode = @(debug); [[[[mockTuneManager stub] classMethod] andReturn:mockTuneManager] currentManager]; [[[mockTuneManager stub] andReturn:config] configuration]; + [[mockTuneManager stub] setUserProfile:OCMOCK_ANY]; + [[mockTuneManager stub] setConfiguration:OCMOCK_ANY]; +// [[mockUserProfile stub] registerSkyhooks]; +// [[mockUserProfile stub] setJailbroken:OCMOCK_ANY]; +// [[mockUserProfile stub] } - (void)setTuneUtilsGetClassFromStringToAnObject {