diff --git a/sdk-android/TuneMarketingConsoleSDK/src/androidTest/java/com/tune/smartwhere/SmartWhereTuneSingletonIntegrationTests.java b/sdk-android/TuneMarketingConsoleSDK/src/androidTest/java/com/tune/smartwhere/SmartWhereTuneSingletonIntegrationTests.java new file mode 100644 index 0000000..8cdfc13 --- /dev/null +++ b/sdk-android/TuneMarketingConsoleSDK/src/androidTest/java/com/tune/smartwhere/SmartWhereTuneSingletonIntegrationTests.java @@ -0,0 +1,297 @@ +package com.tune.smartwhere; + +import android.content.Context; + +import com.tune.Tune; +import com.tune.TuneTestWrapper; +import com.tune.TuneUnitTest; +import com.tune.ma.analytics.model.TuneAnalyticsVariable; + +import org.mockito.ArgumentMatcher; + +import java.lang.reflect.Field; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.argThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +public class SmartWhereTuneSingletonIntegrationTests extends TuneUnitTest { + private TuneSmartWhere mockTuneSmartwhere; + private TuneSmartwhereConfiguration mockTuneSmartwhereConfiguration; + + @Override + public void setUp() throws Exception { + super.setUp(); + shutdownWaitAndRecreatePubQueue(); + } + + @Override + public void tearDown() throws Exception { + TuneSmartWhere.instance = null; + super.tearDown(); + } + + public void testregisterCustomProfileStringWithDefaultCallsSmartWhereSetAttributeValueWhenAvailable() throws Exception { + setMocksToEnableSmartWhere(); + + String expectedName = "testStringName"; + String expectedValue = "defaultString"; + TuneAnalyticsVariable expectedAnalyticsVariable = new TuneAnalyticsVariable(expectedName, expectedValue); + + TuneTestWrapper.getInstance().registerCustomProfileString(expectedName, expectedValue); + + verify(mockTuneSmartwhere).setAttributeValueFromAnalyticsVariable(eq(mContext), argThat(new TuneAnalyticsVariableMatcher(expectedAnalyticsVariable))); + } + + public void testegisterCustomProfileStringWithDefaultDoesntCallsSmartWhereWhenNotAvailable() throws Exception { + setMocksToDisableSmartWhere(); + + String expectedName = "Name"; + String expectedValue = "defaultString"; + + TuneTestWrapper.getInstance().registerCustomProfileString(expectedName, expectedValue); + + verify(mockTuneSmartwhere, never()).setAttributeValueFromAnalyticsVariable(any(Context.class), any(TuneAnalyticsVariable.class)); + } + + public void testregisterCustomProfileNumberIntWithDefaultCallsSmartWhereSetAttributeValueWhenAvailable() throws Exception { + setMocksToEnableSmartWhere(); + + String expectedName = "number name"; + int expectedValue = 10; + TuneAnalyticsVariable expectedAnalyticsVariable = new TuneAnalyticsVariable(expectedName, expectedValue); + + TuneTestWrapper.getInstance().registerCustomProfileNumber(expectedName, 10); + + verify(mockTuneSmartwhere).setAttributeValueFromAnalyticsVariable(eq(mContext), argThat(new TuneAnalyticsVariableMatcher(expectedAnalyticsVariable))); + } + + public void testregisterCustomProfileNumberIntWithDefaultDoesntCallsSmartWhereSetAttributeValueWhenNotAvailable() throws Exception { + setMocksToDisableSmartWhere(); + + String expectedName = "another number"; + + TuneTestWrapper.getInstance().registerCustomProfileNumber(expectedName, 10); + + verify(mockTuneSmartwhere, never()).setAttributeValueFromAnalyticsVariable(any(Context.class), any(TuneAnalyticsVariable.class)); + } + + public void testregisterCustomProfileNumberDoubleWithDefaultCallsSmartWhereSetAttributeValueWhenAvailable() throws Exception { + setMocksToEnableSmartWhere(); + + String expectedName = "double"; + double expectedValue = 10.2; + TuneAnalyticsVariable expectedAnalyticsVariable = new TuneAnalyticsVariable(expectedName, expectedValue); + + TuneTestWrapper.getInstance().registerCustomProfileNumber(expectedName, expectedValue); + + verify(mockTuneSmartwhere).setAttributeValueFromAnalyticsVariable(eq(mContext), argThat(new TuneAnalyticsVariableMatcher(expectedAnalyticsVariable))); + } + + public void testregisterCustomProfileNumberDoubleWithDefaultDoesntCallsSmartWhereSetAttributeValueWhenNotAvailable() throws Exception { + setMocksToDisableSmartWhere(); + + String expectedName = "no double"; + + TuneTestWrapper.getInstance().registerCustomProfileNumber(expectedName, 10.4); + + verify(mockTuneSmartwhere, never()).setAttributeValueFromAnalyticsVariable(any(Context.class), any(TuneAnalyticsVariable.class)); + } + + public void testregisterCustomProfileNumberFloatWithDefaultCallsSmartWhereSetAttributeValueWhenAvailable() throws Exception { + setMocksToEnableSmartWhere(); + + String expectedName = "registerFloat"; + float expectedValue = 99.9f; + TuneAnalyticsVariable expectedAnalyticsVariable = new TuneAnalyticsVariable(expectedName, expectedValue); + + TuneTestWrapper.getInstance().registerCustomProfileNumber(expectedName, expectedValue); + + verify(mockTuneSmartwhere).setAttributeValueFromAnalyticsVariable(eq(mContext), argThat(new TuneAnalyticsVariableMatcher(expectedAnalyticsVariable))); + } + + public void testregisterCustomProfileNumberfloatWithDefaultDoesntCallsSmartWhereSetAttributeValueWhenNotAvailable() throws Exception { + setMocksToDisableSmartWhere(); + + String expectedName = "shouldntbeafloat"; + + TuneTestWrapper.getInstance().registerCustomProfileNumber(expectedName, 10.43f); + + verify(mockTuneSmartwhere, never()).setAttributeValueFromAnalyticsVariable(any(Context.class), any(TuneAnalyticsVariable.class)); + } + + public void testsetCustomProfileStringValueCallsSmartWhereSetAttributeValueWhenAvailable() throws Exception { + setMocksToEnableSmartWhere(); + + String expectedName = "setString"; + String expectedValue = "stringvalue"; + TuneAnalyticsVariable expectedAnalyticsVariable = new TuneAnalyticsVariable(expectedName, expectedValue); + + TuneTestWrapper.getInstance().setCustomProfileStringValue(expectedName, expectedValue); + + verify(mockTuneSmartwhere).setAttributeValueFromAnalyticsVariable(eq(mContext), argThat(new TuneAnalyticsVariableMatcher(expectedAnalyticsVariable))); + } + + public void testsetCustomProfileStringValueDoesntCallSmartWhereSetAttributeValueWhenNotAvailable() throws Exception { + setMocksToDisableSmartWhere(); + + String expectedName = "dontsetstring"; + String expectedValue = "stringvalue"; + + TuneTestWrapper.getInstance().setCustomProfileStringValue(expectedName, expectedValue); + + verify(mockTuneSmartwhere, never()).setAttributeValueFromAnalyticsVariable(any(Context.class), any(TuneAnalyticsVariable.class)); + } + + public void testsetCustomProfileNumberIntCallsSmartWhereSetAttributeValueWhenAvailable() throws Exception { + setMocksToEnableSmartWhere(); + + String expectedName = "setIntNmme"; + int expectedValue = 23; + TuneAnalyticsVariable expectedAnalyticsVariable = new TuneAnalyticsVariable(expectedName, expectedValue); + + TuneTestWrapper.getInstance().setCustomProfileNumber(expectedName, expectedValue); + + verify(mockTuneSmartwhere).setAttributeValueFromAnalyticsVariable(eq(mContext), argThat(new TuneAnalyticsVariableMatcher(expectedAnalyticsVariable))); + } + + public void testsetCustomProfileNumberIntDoesntCallSmartWhereSetAttributeValueWhenNotAvailable() throws Exception { + setMocksToDisableSmartWhere(); + + String expectedName = "noInt"; + int expectedValue = 333; + + TuneTestWrapper.getInstance().setCustomProfileNumber(expectedName, expectedValue); + + verify(mockTuneSmartwhere, never()).setAttributeValueFromAnalyticsVariable(any(Context.class), any(TuneAnalyticsVariable.class)); + } + + public void testsetCustomProfileNumberDoubleCallsSmartWhereSetAttributeValueWhenAvailable() throws Exception { + setMocksToEnableSmartWhere(); + + String expectedName = "setDoubleName"; + double expectedValue = 23.888; + TuneAnalyticsVariable expectedAnalyticsVariable = new TuneAnalyticsVariable(expectedName, expectedValue); + + TuneTestWrapper.getInstance().setCustomProfileNumber(expectedName, expectedValue); + + verify(mockTuneSmartwhere).setAttributeValueFromAnalyticsVariable(eq(mContext), argThat(new TuneAnalyticsVariableMatcher(expectedAnalyticsVariable))); + } + + public void testsetCustomProfileNumberDoubleDoesntCallSmartWhereSetAttributeValueWhenNotAvailable() throws Exception { + setMocksToDisableSmartWhere(); + + String expectedName = "dontSetDoubleName"; + double expectedValue = 333; + + TuneTestWrapper.getInstance().setCustomProfileNumber(expectedName, expectedValue); + + verify(mockTuneSmartwhere, never()).setAttributeValueFromAnalyticsVariable(any(Context.class), any(TuneAnalyticsVariable.class)); + } + + public void testsetCustomProfileNumberFloatCallsSmartWhereSetAttributeValueWhenAvailable() throws Exception { + setMocksToEnableSmartWhere(); + + String expectedName = "setFloatName"; + float expectedValue = 44.4f; + TuneAnalyticsVariable expectedAnalyticsVariable = new TuneAnalyticsVariable(expectedName, expectedValue); + + TuneTestWrapper.getInstance().setCustomProfileNumber(expectedName, expectedValue); + + verify(mockTuneSmartwhere).setAttributeValueFromAnalyticsVariable(eq(mContext), argThat(new TuneAnalyticsVariableMatcher(expectedAnalyticsVariable))); + } + + public void testsetCustomProfileNumberFloatDoesntCallSmartWhereSetAttributeValueWhenNotAvailable() throws Exception { + setMocksToDisableSmartWhere(); + + String expectedName = "dontSetFloatName"; + float expectedValue = 323.33f; + + TuneTestWrapper.getInstance().setCustomProfileNumber(expectedName, expectedValue); + + verify(mockTuneSmartwhere, never()).setAttributeValueFromAnalyticsVariable(any(Context.class), any(TuneAnalyticsVariable.class)); + } + + public void testclearCustomProfileVariableCallsOnSmartWhereWhenAvailable() throws Exception { + setMocksToEnableSmartWhere(); + + String expectedName = "clear name"; + + TuneTestWrapper.getInstance().clearCustomProfileVariable(expectedName); + verify(mockTuneSmartwhere).clearAttributeValue(mContext, expectedName); + } + + public void testclearCustomProfileVariableDoesntCallOnSmartWhereWhenNotAvailable() throws Exception { + setMocksToDisableSmartWhere(); + + String expectedName = "clear name"; + + TuneTestWrapper.getInstance().clearCustomProfileVariable(expectedName); + verify(mockTuneSmartwhere, never()).clearAttributeValue(any(Context.class), anyString()); + } + + // Helper methods + private void setMocksToEnableSmartWhere() { + mockTuneSmartwhere = mock(TuneSmartWhere.class); + mockTuneSmartwhereConfiguration = mock(TuneSmartwhereConfiguration.class); + TuneSmartWhere.instance = mockTuneSmartwhere; + doReturn(mockTuneSmartwhereConfiguration).when(mockTuneSmartwhere).getConfiguration(); + doReturn(true).when(mockTuneSmartwhereConfiguration).isPermissionGranted(TuneSmartwhereConfiguration.GRANT_SMARTWHERE_TUNE_EVENTS); + } + + private void setMocksToDisableSmartWhere() { + mockTuneSmartwhere = mock(TuneSmartWhere.class); + mockTuneSmartwhereConfiguration = mock(TuneSmartwhereConfiguration.class); + TuneSmartWhere.instance = mockTuneSmartwhere; + doReturn(mockTuneSmartwhereConfiguration).when(mockTuneSmartwhere).getConfiguration(); + doReturn(false).when(mockTuneSmartwhereConfiguration).isPermissionGranted(TuneSmartwhereConfiguration.GRANT_SMARTWHERE_TUNE_EVENTS); + } + + private class TuneAnalyticsVariableMatcher extends ArgumentMatcher { + TuneAnalyticsVariable thisObject; + + TuneAnalyticsVariableMatcher(TuneAnalyticsVariable thisObject) { + this.thisObject = thisObject; + } + + @Override + public boolean matches(Object argument) { + return argument instanceof TuneAnalyticsVariable && + thisObject.getName().equals(((TuneAnalyticsVariable) argument).getName()) && + thisObject.getType().equals(((TuneAnalyticsVariable) argument).getType()) && + thisObject.getValue().equals(((TuneAnalyticsVariable) argument).getValue()) && + thisObject.getHashType().equals(((TuneAnalyticsVariable) argument).getHashType()); + } + } + + private void shutdownWaitAndRecreatePubQueue() throws InterruptedException { + tune.getPubQueue().shutdown(); + tune.getPubQueue().awaitTermination(60, TimeUnit.SECONDS); + Field declaredField = null; + try { + declaredField = Tune.class.getDeclaredField("pubQueue"); + boolean accessible = declaredField.isAccessible(); + + declaredField.setAccessible(true); + + Executor exec = Executors.newSingleThreadExecutor(); + declaredField.set(tune, exec); + + declaredField.setAccessible(accessible); + + } catch (NoSuchFieldException + | SecurityException + | IllegalArgumentException + | IllegalAccessException e) { + e.printStackTrace(); + } + } +} diff --git a/sdk-android/TuneMarketingConsoleSDK/src/androidTest/java/com/tune/smartwhere/TuneSmartWhereFakeAttribute.java b/sdk-android/TuneMarketingConsoleSDK/src/androidTest/java/com/tune/smartwhere/TuneSmartWhereFakeAttribute.java new file mode 100644 index 0000000..e51ae2e --- /dev/null +++ b/sdk-android/TuneMarketingConsoleSDK/src/androidTest/java/com/tune/smartwhere/TuneSmartWhereFakeAttribute.java @@ -0,0 +1,29 @@ +package com.tune.smartwhere; + +import android.content.Context; + +import java.util.HashMap; + +@SuppressWarnings("WeakerAccess") +public class TuneSmartWhereFakeAttribute{ + static TuneSmartWhereFakeAttribute instance; + + public static Object getInstance(Context context) { + return instance; + } + + @SuppressWarnings("unused") + public void setAttributeValue(String name, String value) { + } + + @SuppressWarnings("unused") + public void removeAttributeValue(String name) { + } + + @SuppressWarnings("unused") + public HashMap getAttributes() { + return null; + } +} + + diff --git a/sdk-android/TuneMarketingConsoleSDK/src/androidTest/java/com/tune/smartwhere/TuneSmartWhereFakeTrackingAttribute.java b/sdk-android/TuneMarketingConsoleSDK/src/androidTest/java/com/tune/smartwhere/TuneSmartWhereFakeTrackingAttribute.java new file mode 100644 index 0000000..8b97956 --- /dev/null +++ b/sdk-android/TuneMarketingConsoleSDK/src/androidTest/java/com/tune/smartwhere/TuneSmartWhereFakeTrackingAttribute.java @@ -0,0 +1,18 @@ +package com.tune.smartwhere; + +import android.content.Context; + +@SuppressWarnings("WeakerAccess") +public class TuneSmartWhereFakeTrackingAttribute { + static TuneSmartWhereFakeTrackingAttribute instance; + + public static Object getInstance(Context context) { + return instance; + } + + public void setAttributeValue(String name, String value) { + } + + public void removeAttributeValue(String name) { + } +} diff --git a/sdk-android/TuneMarketingConsoleSDK/src/androidTest/java/com/tune/smartwhere/TuneSmartWhereTests.java b/sdk-android/TuneMarketingConsoleSDK/src/androidTest/java/com/tune/smartwhere/TuneSmartWhereTests.java index c8c7d43..66be256 100644 --- a/sdk-android/TuneMarketingConsoleSDK/src/androidTest/java/com/tune/smartwhere/TuneSmartWhereTests.java +++ b/sdk-android/TuneMarketingConsoleSDK/src/androidTest/java/com/tune/smartwhere/TuneSmartWhereTests.java @@ -3,13 +3,22 @@ import android.annotation.SuppressLint; import android.content.Context; +import com.tune.BuildConfig; +import com.tune.Tune; import com.tune.TuneEvent; import com.tune.TuneUnitTest; +import com.tune.ma.analytics.model.TuneAnalyticsVariable; import java.util.HashMap; +import java.util.HashSet; import static com.tune.TuneEvent.ADD_TO_CART; import static com.tune.TuneEvent.NAME_SESSION; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; /** @@ -22,11 +31,18 @@ public class TuneSmartWhereTests extends TuneUnitTest { private TuneSmartWhere testObj; private Context context; + private TuneSmartWhereFakeAttribute mockAttribute; + private TuneSmartWhereFakeTrackingAttribute mockTrackingAttribute; @Override public void setUp() throws Exception { super.setUp(); FakeProximityControl.reset(); + + mockAttribute = mock(TuneSmartWhereFakeAttribute.class); + TuneSmartWhereFakeAttribute.instance = mockAttribute; + mockTrackingAttribute = mock(TuneSmartWhereFakeTrackingAttribute.class); + TuneSmartWhereFakeTrackingAttribute.instance = mockTrackingAttribute; context = getContext(); testObj = TuneSmartWhereForTest.getInstance(); @@ -39,14 +55,14 @@ public void tearDown() throws Exception { } public void testIsProximityInstalledReturnsFalseWhenProximityControlClassNotFound() throws Exception { - TuneSmartWhereForTest.clazz = null; + TuneSmartWhereForTest.proximityControlClass = null; assertFalse(testObj.isSmartWhereAvailableInternal()); assertEquals("Incorrect class name specified", "com.proximity.library.ProximityControl", TuneSmartWhereForTest.capturedClassNameString); } public void testIsProximityInstalledReturnsTrueWhenProximityControlClassIsFound() throws Exception { - TuneSmartWhereForTest.clazz = this.getClass(); + TuneSmartWhereForTest.proximityControlClass = this.getClass(); assertTrue(testObj.isSmartWhereAvailableInternal()); assertEquals("Incorrect class name specified", "com.proximity.library.ProximityControl", TuneSmartWhereForTest.capturedClassNameString); @@ -137,6 +153,21 @@ public void testStartMonitoringStartsService() throws Exception { assertTrue(FakeProximityControl.hasStartServiceBeenCalled); } + public void testStartMonitoringAddsTrackingMetadata() throws Exception { + String addId = "addId"; + String conversionKey = "conversionKey"; + + testObj.startMonitoring(context, addId, conversionKey, false); + + verify(mockTrackingAttribute).setAttributeValue( + TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + TuneSmartWhere.TUNE_SDK_VERSION_TRACKING_KEY , + BuildConfig.VERSION_NAME); + verify(mockTrackingAttribute).setAttributeValue( + TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + TuneSmartWhere.TUNE_MAT_ID_TRACKING_KEY , + Tune.getInstance().getMatId()); + + } + public void testSetPackageNameCallsConfigureServiceWithPackageName() throws Exception { String packageName = "com.set.package.name"; testObj.setPackageName(context, packageName); @@ -199,7 +230,7 @@ public void testProcessMappedEventDoesntCallOnSmartWhereForSessionEvents() throw } public void testProcessMappedEventDoesntCallOnSmartWhereWhenNotAvailable() throws Exception { - TuneSmartWhereForTest.clazz = null; + TuneSmartWhereForTest.proximityControlClass = null; TuneEvent event = new TuneEvent(ADD_TO_CART); @@ -209,7 +240,7 @@ public void testProcessMappedEventDoesntCallOnSmartWhereWhenNotAvailable() throw } public void testProcessMappedEventDoesntCallOnSmartWhereWhenMethodNotFound() throws Exception { - TuneSmartWhereForTest.clazz = Object.class; + TuneSmartWhereForTest.proximityControlClass = Object.class; TuneEvent event = new TuneEvent(ADD_TO_CART); @@ -218,21 +249,250 @@ public void testProcessMappedEventDoesntCallOnSmartWhereWhenMethodNotFound() thr assertFalse(FakeProximityControl.hasProcessMappedEventBeenCalled); } + + public void testsetAttributeValueFromAnalyticsVariableCallsOnSmartWhereAttributeClass() throws Exception { + String expectedVariableName = "expectedName"; + String expectedValue = "expectedValue"; + + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(expectedVariableName, expectedValue); + + testObj.setAttributeValueFromAnalyticsVariable(context, analyticsVariable); + + verify(mockAttribute).setAttributeValue(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + expectedVariableName, expectedValue); + } + + public void testsetAttributeValueFromAnalyticsVariableDoesntCallSmartWhereWhenAttributeClassIsNotFound() throws Exception { + TuneSmartWhereForTest.attributeClass = null; + String expectedVariableName = "expectedName"; + String expectedValue = "expectedValue"; + + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(expectedVariableName, expectedValue); + + testObj.setAttributeValueFromAnalyticsVariable(context, analyticsVariable); + + verify(mockAttribute, never()).setAttributeValue(anyString(), anyString()); + } + + public void testsetAttributeFromAnalyticsVariableDoesntCallSmartWhereWhenMethodNotFound() throws Exception { + TuneSmartWhereForTest.attributeClass = Object.class; + String expectedVariableName = "expectedName"; + String expectedValue = "expectedValue"; + + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(expectedVariableName, expectedValue); + + testObj.setAttributeValueFromAnalyticsVariable(context, analyticsVariable); + + verify(mockAttribute, never()).setAttributeValue(anyString(), anyString()); + } + + public void testsetAttributeFromAnalyticsVariableChecksThatTheNameExists() throws Exception { + String expectedValue = "expectedValue"; + + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(null, expectedValue); + + testObj.setAttributeValueFromAnalyticsVariable(context, analyticsVariable); + + verify(mockAttribute, never()).setAttributeValue(anyString(), anyString()); + + analyticsVariable = new TuneAnalyticsVariable("", expectedValue); + + testObj.setAttributeValueFromAnalyticsVariable(context, analyticsVariable); + + verify(mockAttribute, never()).setAttributeValue(anyString(), anyString()); + } + + public void testsetAttributeFromAnalyticsVariableRemovesTheAttributeIfTheValueIsNull() throws Exception { + String expectedVariableName = "expectedName"; + + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(expectedVariableName, (String) null); + + testObj.setAttributeValueFromAnalyticsVariable(context, analyticsVariable); + + verify(mockAttribute).removeAttributeValue(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + expectedVariableName); + } + + public void testsetAttributeValuesFromEventTagsCallsSmartWhere() throws Exception { + String expectedName = "name"; + String expectedValue = "value"; + + TuneEvent event = new TuneEvent(TuneEvent.PURCHASE) + .withRevenue(0.99) + .withCurrencyCode("USD") + .withAdvertiserRefId("12999azzzx748531") + .withTagAsString(expectedName, expectedValue); + + testObj.setAttributeValuesFromEventTags(context, event); + + verify(mockAttribute).setAttributeValue(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX+expectedName, expectedValue); + } + + public void testsetAttributeValuesFromEventTagsCallSmartWhereForEachTag() throws Exception { + String expectedName = "name"; + String expectedValue = "value"; + String expectedName2 = "name2"; + String expectedValue2 = "value2"; + + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(expectedName, expectedValue); + TuneAnalyticsVariable analyticsVariable2 = new TuneAnalyticsVariable(expectedName2, expectedValue2); + + TuneEvent mockEvent = mock(TuneEvent.class); + HashSet tags = new HashSet<>(); + tags.add(analyticsVariable); + tags.add(analyticsVariable2); + + when(mockEvent.getTags()).thenReturn(tags); + + testObj.setAttributeValuesFromEventTags(context, mockEvent); + + verify(mockAttribute).setAttributeValue(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + expectedName, expectedValue); + verify(mockAttribute).setAttributeValue(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + expectedName2, expectedValue2); + } + + public void testsetAttributeValuesFromEventTagsDoesntCallSmartWhereWhenNotAvailable() throws Exception { + TuneSmartWhereForTest.attributeClass = null; + String expectedName = "name"; + String expectedValue = "value"; + + TuneEvent event = new TuneEvent(TuneEvent.PURCHASE) + .withRevenue(0.99) + .withCurrencyCode("USD") + .withAdvertiserRefId("12999azzzx748531") + .withTagAsString(expectedName, expectedValue); + + testObj.setAttributeValuesFromEventTags(context, event); + + verify(mockAttribute, never()).setAttributeValue(anyString(),anyString()); + } + + public void testclearAttributeValueCallsSmartWhereToRemoveObject() throws Exception { + String expectedName = "expectedName"; + testObj.clearAttributeValue(context, expectedName); + + verify(mockAttribute).removeAttributeValue(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + expectedName); + } + + public void testclearAttributeValueDoesntCallSmartWhereWhenNotAvailable() throws Exception { + TuneSmartWhereForTest.attributeClass = null; + + String expectedName = "expectedName"; + testObj.clearAttributeValue(context, expectedName); + + verify(mockAttribute,never()).removeAttributeValue(anyString()); + } + + public void testclearAllAttributeValuesCallsSmartWhereForEachValueWithTunePrefix() throws Exception { + HashMap currentlySetAttributes = new HashMap(){{ + put("key1","value1"); + put("key2","value2"); + put("key3","value3"); + put(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + "key1","doesnt matter"); + put(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + "key2","tune value 2"); + }}; + + when(mockAttribute.getAttributes()).thenReturn(currentlySetAttributes); + + testObj.clearAllAttributeValues(context); + + verify(mockAttribute,never()).removeAttributeValue("key1"); + verify(mockAttribute,never()).removeAttributeValue("key2"); + verify(mockAttribute,never()).removeAttributeValue("key3"); + verify(mockAttribute).removeAttributeValue(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + "key1"); + verify(mockAttribute).removeAttributeValue(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + "key2"); + + } + + public void testclearAllAttributeValuesDoesntCallSmartWhereWhenNotAvailable() throws Exception { + TuneSmartWhereForTest.attributeClass = null; + HashMap currentlySetAttributes = new HashMap(){{ + put("key1","value1"); + put("key2","value2"); + put("key3","value3"); + put(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + "key1","doesnt matter"); + put(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + "key2","tune value 2"); + }}; + + when(mockAttribute.getAttributes()).thenReturn(currentlySetAttributes); + + testObj.clearAllAttributeValues(context); + + verify(mockAttribute,never()).removeAttributeValue(anyString()); + } + + public void testsetTrackingAttributeValueCallsOnSmartWhereTrackingAttributeClass() throws Exception { + String expectedVariableName = "expectedName"; + String expectedValue = "expectedValue"; + + testObj.setTrackingAttributeValue(context, expectedVariableName, expectedValue); + + verify(mockTrackingAttribute).setAttributeValue(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + expectedVariableName, expectedValue); + } + + + public void testsetTrackingAttributeValueDoesntCallSmartWhereWhenAttributeClassIsNotFound() throws Exception { + TuneSmartWhereForTest.trackingAttributeClass = null; + String expectedVariableName = "expectedName"; + String expectedValue = "expectedValue"; + + testObj.setTrackingAttributeValue(context, expectedVariableName, expectedValue); + + verify(mockAttribute, never()).setAttributeValue(anyString(), anyString()); + } + + public void testsetTrackingAttributeDoesntCallSmartWhereWhenMethodNotFound() throws Exception { + TuneSmartWhereForTest.trackingAttributeClass = Object.class; + String expectedVariableName = "expectedName"; + String expectedValue = "expectedValue"; + + testObj.setTrackingAttributeValue(context, expectedVariableName, expectedValue); + + verify(mockTrackingAttribute, never()).setAttributeValue(anyString(), anyString()); + } + + public void testsetTrackingAttributeChecksThatTheNameExists() throws Exception { + String expectedValue = "expectedValue"; + + testObj.setTrackingAttributeValue(context, null, expectedValue); + + verify(mockTrackingAttribute, never()).setAttributeValue(anyString(), anyString()); + + testObj.setTrackingAttributeValue(context, "", expectedValue); + + verify(mockTrackingAttribute, never()).setAttributeValue(anyString(), anyString()); + } + + public void testsetTrackingAttributeRemovesTheAttributeIfTheValueIsNull() throws Exception { + String expectedVariableName = "expectedName"; + + testObj.setTrackingAttributeValue(context, expectedVariableName, null); + + verify(mockTrackingAttribute).removeAttributeValue(TuneSmartWhere.TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + expectedVariableName); + } } class TuneSmartWhereForTest extends TuneSmartWhere { - static Class clazz; + static Class proximityControlClass; + static Class attributeClass; + static Class trackingAttributeClass; static String capturedClassNameString; public static synchronized TuneSmartWhere getInstance() { - clazz = FakeProximityControl.class; + proximityControlClass = FakeProximityControl.class; + attributeClass = TuneSmartWhereFakeAttribute.class; + trackingAttributeClass = TuneSmartWhereFakeTrackingAttribute.class; return new TuneSmartWhereForTest(); } @Override protected Class classForName(String name) { TuneSmartWhereForTest.capturedClassNameString = name; - return clazz; + if (name.equalsIgnoreCase(TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_PROXIMITYCONTROL)){ + return proximityControlClass; + } else if (name.equalsIgnoreCase(TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_ATTRIBUTE)){ + return attributeClass; + } else if (name.equalsIgnoreCase(TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_TRACKING_ATTRIBUTE)){ + return trackingAttributeClass; + } + return null; } } diff --git a/sdk-android/TuneMarketingConsoleSDK/src/main/java/com/tune/Tune.java b/sdk-android/TuneMarketingConsoleSDK/src/main/java/com/tune/Tune.java index cb92d3f..18b0d44 100644 --- a/sdk-android/TuneMarketingConsoleSDK/src/main/java/com/tune/Tune.java +++ b/sdk-android/TuneMarketingConsoleSDK/src/main/java/com/tune/Tune.java @@ -462,6 +462,7 @@ private synchronized void measure(TuneEvent eventData) { if (TuneSmartWhere.getInstance().getConfiguration().isPermissionGranted(TuneSmartwhereConfiguration.GRANT_SMARTWHERE_TUNE_EVENTS)) { TuneSmartWhere.getInstance().processMappedEvent(mContext, eventData); + TuneSmartWhere.getInstance().setAttributeValuesFromEventTags(mContext, eventData); } return; @@ -2667,8 +2668,12 @@ public void registerCustomProfileString(String variableName, String defaultValue if (TuneManager.getProfileForUser("registerCustomProfileString") == null) { return; } + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(variableName, defaultValue); + TuneManager.getInstance().getProfileManager().registerCustomProfileVariable(analyticsVariable); - TuneManager.getInstance().getProfileManager().registerCustomProfileVariable(new TuneAnalyticsVariable(variableName, defaultValue)); + if (TuneSmartWhere.getInstance().getConfiguration().isPermissionGranted(TuneSmartwhereConfiguration.GRANT_SMARTWHERE_TUNE_EVENTS)) { + TuneSmartWhere.getInstance().setAttributeValueFromAnalyticsVariable(mContext, analyticsVariable); + } } /** @@ -2711,7 +2716,12 @@ public void registerCustomProfileNumber(String variableName, int defaultValue) { return; } - TuneManager.getInstance().getProfileManager().registerCustomProfileVariable(new TuneAnalyticsVariable(variableName, defaultValue)); + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(variableName, defaultValue); + TuneManager.getInstance().getProfileManager().registerCustomProfileVariable(analyticsVariable); + + if (TuneSmartWhere.getInstance().getConfiguration().isPermissionGranted(TuneSmartwhereConfiguration.GRANT_SMARTWHERE_TUNE_EVENTS)) { + TuneSmartWhere.getInstance().setAttributeValueFromAnalyticsVariable(mContext, analyticsVariable); + } } /** @@ -2733,7 +2743,12 @@ public void registerCustomProfileNumber(String variableName, double defaultValue return; } - TuneManager.getInstance().getProfileManager().registerCustomProfileVariable(new TuneAnalyticsVariable(variableName, defaultValue)); + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(variableName, defaultValue); + TuneManager.getInstance().getProfileManager().registerCustomProfileVariable(analyticsVariable); + + if (TuneSmartWhere.getInstance().getConfiguration().isPermissionGranted(TuneSmartwhereConfiguration.GRANT_SMARTWHERE_TUNE_EVENTS)) { + TuneSmartWhere.getInstance().setAttributeValueFromAnalyticsVariable(mContext, analyticsVariable); + } } /** @@ -2755,7 +2770,12 @@ public void registerCustomProfileNumber(String variableName, float defaultValue) return; } - TuneManager.getInstance().getProfileManager().registerCustomProfileVariable(new TuneAnalyticsVariable(variableName, defaultValue)); + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(variableName, defaultValue); + TuneManager.getInstance().getProfileManager().registerCustomProfileVariable(analyticsVariable); + + if (TuneSmartWhere.getInstance().getConfiguration().isPermissionGranted(TuneSmartwhereConfiguration.GRANT_SMARTWHERE_TUNE_EVENTS)) { + TuneSmartWhere.getInstance().setAttributeValueFromAnalyticsVariable(mContext, analyticsVariable); + } } /** @@ -2797,7 +2817,12 @@ public void setCustomProfileStringValue(String variableName, String value) { return; } - TuneManager.getInstance().getProfileManager().setCustomProfileVariable(new TuneAnalyticsVariable(variableName, value)); + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(variableName, value); + TuneManager.getInstance().getProfileManager().setCustomProfileVariable(analyticsVariable); + + if (TuneSmartWhere.getInstance().getConfiguration().isPermissionGranted(TuneSmartwhereConfiguration.GRANT_SMARTWHERE_TUNE_EVENTS)) { + TuneSmartWhere.getInstance().setAttributeValueFromAnalyticsVariable(mContext, analyticsVariable); + } } /** @@ -2835,7 +2860,12 @@ public void setCustomProfileNumber(String variableName, int value) { return; } - TuneManager.getInstance().getProfileManager().setCustomProfileVariable(new TuneAnalyticsVariable(variableName, value)); + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(variableName, value); + TuneManager.getInstance().getProfileManager().setCustomProfileVariable(analyticsVariable); + + if (TuneSmartWhere.getInstance().getConfiguration().isPermissionGranted(TuneSmartwhereConfiguration.GRANT_SMARTWHERE_TUNE_EVENTS)) { + TuneSmartWhere.getInstance().setAttributeValueFromAnalyticsVariable(mContext, analyticsVariable); + } } /** @@ -2854,7 +2884,12 @@ public void setCustomProfileNumber(String variableName, double value) { return; } - TuneManager.getInstance().getProfileManager().setCustomProfileVariable(new TuneAnalyticsVariable(variableName, value)); + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(variableName, value); + TuneManager.getInstance().getProfileManager().setCustomProfileVariable(analyticsVariable); + + if (TuneSmartWhere.getInstance().getConfiguration().isPermissionGranted(TuneSmartwhereConfiguration.GRANT_SMARTWHERE_TUNE_EVENTS)) { + TuneSmartWhere.getInstance().setAttributeValueFromAnalyticsVariable(mContext, analyticsVariable); + } } /** @@ -2873,7 +2908,12 @@ public void setCustomProfileNumber(String variableName, float value) { return; } - TuneManager.getInstance().getProfileManager().setCustomProfileVariable(new TuneAnalyticsVariable(variableName, value)); + TuneAnalyticsVariable analyticsVariable = new TuneAnalyticsVariable(variableName, value); + TuneManager.getInstance().getProfileManager().setCustomProfileVariable(analyticsVariable); + + if (TuneSmartWhere.getInstance().getConfiguration().isPermissionGranted(TuneSmartwhereConfiguration.GRANT_SMARTWHERE_TUNE_EVENTS)) { + TuneSmartWhere.getInstance().setAttributeValueFromAnalyticsVariable(mContext, analyticsVariable); + } } /** @@ -3019,6 +3059,10 @@ public void clearCustomProfileVariable(String variableName) { } TuneManager.getInstance().getProfileManager().clearCertainCustomProfileVariable(variableName); + + if (TuneSmartWhere.getInstance().getConfiguration().isPermissionGranted(TuneSmartwhereConfiguration.GRANT_SMARTWHERE_TUNE_EVENTS)) { + TuneSmartWhere.getInstance().clearAttributeValue(mContext, variableName); + } } /** @@ -3036,6 +3080,10 @@ public void clearAllCustomProfileVariables() { } TuneManager.getInstance().getProfileManager().clearAllCustomProfileVariables(); + + if (TuneSmartWhere.getInstance().getConfiguration().isPermissionGranted(TuneSmartwhereConfiguration.GRANT_SMARTWHERE_TUNE_EVENTS)) { + TuneSmartWhere.getInstance().clearAllAttributeValues(mContext); + } } /** diff --git a/sdk-android/TuneMarketingConsoleSDK/src/main/java/com/tune/smartwhere/TuneSmartWhere.java b/sdk-android/TuneMarketingConsoleSDK/src/main/java/com/tune/smartwhere/TuneSmartWhere.java index 8753931..391e83e 100644 --- a/sdk-android/TuneMarketingConsoleSDK/src/main/java/com/tune/smartwhere/TuneSmartWhere.java +++ b/sdk-android/TuneMarketingConsoleSDK/src/main/java/com/tune/smartwhere/TuneSmartWhere.java @@ -2,11 +2,14 @@ import android.content.Context; +import com.tune.BuildConfig; import com.tune.Tune; import com.tune.TuneEvent; import com.tune.TuneUtils; +import com.tune.ma.analytics.model.TuneAnalyticsVariable; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.HashMap; import static com.tune.TuneConstants.STRING_FALSE; @@ -22,9 +25,15 @@ */ public class TuneSmartWhere { - private static volatile TuneSmartWhere instance = null; + protected static volatile TuneSmartWhere instance = null; - private static final String TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_PROXIMITYCONTROL = "com.proximity.library.ProximityControl"; + static final String TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX = "T_A_V_"; + static final String TUNE_SDK_VERSION_TRACKING_KEY = "TUNE_SDK_VERSION"; + static final String TUNE_MAT_ID_TRACKING_KEY = "TUNE_MAT_ID"; + + static final String TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_PROXIMITYCONTROL = "com.proximity.library.ProximityControl"; + static final String TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_ATTRIBUTE = "com.proximity.library.Attribute"; + static final String TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_TRACKING_ATTRIBUTE = "com.proximity.library.TrackingAttribute"; private static final String TUNE_SMARTWHERE_NOTIFICATION_SERVICE = "com.tune.smartwhere.TuneSmartWhereNotificationService"; private static final String TUNE_SMARTWHERE_API_KEY = "API_KEY"; @@ -41,6 +50,10 @@ public class TuneSmartWhere { private static final String TUNE_SMARTWHERE_METHOD_START_SERVICE = "startService"; private static final String TUNE_SMARTWHERE_METHOD_STOP_SERVICE = "stopService"; private static final String TUNE_SMARTWHERE_METHOD_PROCESS_MAPPED_EVENT = "processMappedEvent"; + private static final String TUNE_SMARTWHERE_ATTRIBUTE_METHOD_SET_ATTRIBUTE_VALUE = "setAttributeValue"; + private static final String TUNE_SMARTWHERE_ATTRIBUTE_METHOD_REMOVE_ATTRIBUTE_VALUE = "removeAttributeValue"; + private static final String TUNE_SMARTWHERE_ATTRIBUTE_METHOD_GET_ATTRIBUTE_MAP = "getAttributes"; + private static final String TUNE_SMARTWHERE_ATTRIBUTE_METHOD_GET_INSTANCE = "getInstance"; private TuneSmartwhereConfiguration mConfiguration; @@ -92,7 +105,6 @@ public void disable(Context context) { * @return True if Smartwhere is enabled. */ public boolean isEnabled() { - boolean test = (mConfiguration != null); return (mConfiguration != null); } @@ -101,7 +113,7 @@ public boolean isEnabled() { * @return the current {@link TuneSmartwhereConfiguration}. * To make changes to the Smartwhere options, use {@link TuneSmartWhere#configure(TuneSmartwhereConfiguration)} */ - public final TuneSmartwhereConfiguration getConfiguration() { + public TuneSmartwhereConfiguration getConfiguration() { return (mConfiguration == null ? new TuneSmartwhereConfiguration() : mConfiguration); } @@ -122,9 +134,13 @@ public void configure(TuneSmartwhereConfiguration configuration) { * @param tuneConversionKey TUNE Conversion Key * @param debugMode Debug Mode */ - public void startMonitoring(Context context, String tuneAdvertiserId, String tuneConversionKey, boolean debugMode) { + void startMonitoring(Context context, String tuneAdvertiserId, String tuneConversionKey, boolean debugMode) { Class targetClass = classForName(TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_PROXIMITYCONTROL); if (targetClass != null) { + + setTrackingAttributeValue(context, TUNE_SDK_VERSION_TRACKING_KEY, BuildConfig.VERSION_NAME); + setTrackingAttributeValue(context, TUNE_MAT_ID_TRACKING_KEY, Tune.getInstance().getMatId()); + HashMap config = new HashMap<>(); config.put(TUNE_SMARTWHERE_API_KEY, tuneAdvertiserId); @@ -157,7 +173,7 @@ public void startMonitoring(Context context, String tuneAdvertiserId, String tun * Stops SmartWhere proximity monitoring. * @param context Application Context */ - public void stopMonitoring(Context context) { + void stopMonitoring(Context context) { Class targetClass = classForName(TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_PROXIMITYCONTROL); if (targetClass != null) { HashMap config = new HashMap<>(); @@ -241,11 +257,139 @@ public void processMappedEvent(Context context, TuneEvent event) { } } + /** + * Add user attributes that are used for conditions and notification replacements from TuneAnalyticsVariable. + * @param context Application Context + * @param analyticsVariable TuneAnalyticsVariable + */ + public void setAttributeValueFromAnalyticsVariable(Context context, TuneAnalyticsVariable analyticsVariable) { + Class targetClass = classForName(TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_ATTRIBUTE); + if (targetClass == null) return; + + try { + Method getInstance = targetClass.getMethod(TUNE_SMARTWHERE_ATTRIBUTE_METHOD_GET_INSTANCE, Context.class); + Object instanceOfAttributeClass = getInstance.invoke(targetClass,context); + Method setAttributeValue = targetClass.getMethod(TUNE_SMARTWHERE_ATTRIBUTE_METHOD_SET_ATTRIBUTE_VALUE, String.class, String.class); + Method removeAttributeValue = targetClass.getMethod(TUNE_SMARTWHERE_ATTRIBUTE_METHOD_REMOVE_ATTRIBUTE_VALUE, String.class); + String name = analyticsVariable.getName(); + String value = analyticsVariable.getValue(); + if (name != null && name.length() > 0){ + if ( value != null){ + String finalName = TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + name; + setAttributeValue.invoke(instanceOfAttributeClass, finalName, value); + } else { + String finalName = TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + name; + removeAttributeValue.invoke(instanceOfAttributeClass, finalName); + + } + } + } catch (Exception e) { + TuneUtils.log("TuneSmartWhere.setAttributeValueFromAnalyticsVariable: " + e.getLocalizedMessage()); + } + } + + /** + * Add user attributes that are used for conditions and notification replacements from TuneEvent tags. + * @param context Application Context + * @param event TuneEvent + */ + public void setAttributeValuesFromEventTags(Context context, TuneEvent event) { + Class targetClass = classForName(TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_ATTRIBUTE); + if (targetClass == null) return; + + for (TuneAnalyticsVariable tag : event.getTags()) { + setAttributeValueFromAnalyticsVariable(context, tag); + } + } + + /** + * Remove an attribute by name + * @param context Application Context + * @param variableName String + */ + public void clearAttributeValue(Context context, String variableName) { + Class targetClass = classForName(TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_ATTRIBUTE); + if (targetClass == null) return; + + try { + Method getInstance = targetClass.getMethod(TUNE_SMARTWHERE_ATTRIBUTE_METHOD_GET_INSTANCE, Context.class); + Object instanceOfAttributeClass = getInstance.invoke(targetClass,context); + Method removeAttributeValue = targetClass.getMethod(TUNE_SMARTWHERE_ATTRIBUTE_METHOD_REMOVE_ATTRIBUTE_VALUE, String.class); + + String finalName = TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + variableName; + removeAttributeValue.invoke(instanceOfAttributeClass, finalName); + } catch (Exception e) { + TuneUtils.log("TuneSmartWhere.clearAttributeValue: " + e.getLocalizedMessage()); + } + } + + /** + * Remove all attributes + * @param context Application Context + */ + public void clearAllAttributeValues(Context context) { + Class targetClass = classForName(TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_ATTRIBUTE); + if (targetClass == null) return; + + try { + Method getInstance = targetClass.getMethod(TUNE_SMARTWHERE_ATTRIBUTE_METHOD_GET_INSTANCE, Context.class); + Object instanceOfAttributeClass = getInstance.invoke(targetClass,context); + Method removeAttributeValue = targetClass.getMethod(TUNE_SMARTWHERE_ATTRIBUTE_METHOD_REMOVE_ATTRIBUTE_VALUE, String.class); + Method getAttributeMap = targetClass.getMethod(TUNE_SMARTWHERE_ATTRIBUTE_METHOD_GET_ATTRIBUTE_MAP); + Object attributes = getAttributeMap.invoke(instanceOfAttributeClass); + + ArrayList keysToRemove = new ArrayList<>(); + //noinspection unchecked + for (String name : ((HashMap) attributes).keySet()) { + if (name.startsWith(TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX)) { + keysToRemove.add(name); + } + } + for (String name : keysToRemove) { + removeAttributeValue.invoke(instanceOfAttributeClass, name); + } + } catch (Exception e) { + TuneUtils.log("TuneSmartWhere.clearAllAttributeValues: " + e.getLocalizedMessage()); + } + } + + /** + * Add attribute to be sent as metadata with tracking. + * @param context Application Context + * @param name String value of the attribute name + * @param value String value of the attribute value + */ + void setTrackingAttributeValue(Context context, String name, String value) { + Class targetClass = classForName(TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_TRACKING_ATTRIBUTE); + if (targetClass == null) return; + + try { + Method getInstance = targetClass.getMethod(TUNE_SMARTWHERE_ATTRIBUTE_METHOD_GET_INSTANCE, Context.class); + Object instanceOfAttributeClass = getInstance.invoke(targetClass,context); + Method setAttributeValue = targetClass.getMethod(TUNE_SMARTWHERE_ATTRIBUTE_METHOD_SET_ATTRIBUTE_VALUE, String.class, String.class); + Method removeAttributeValue = targetClass.getMethod(TUNE_SMARTWHERE_ATTRIBUTE_METHOD_REMOVE_ATTRIBUTE_VALUE, String.class); + + if (name != null && name.length() > 0){ + if ( value != null){ + String finalName = TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + name; + setAttributeValue.invoke(instanceOfAttributeClass, finalName, value); + } else { + String finalName = TUNE_SMARTWHERE_ANALYTICS_VARIABLE_ATTRIBUTE_PREFIX + name; + removeAttributeValue.invoke(instanceOfAttributeClass, finalName); + + } + } + } catch (Exception e) { + TuneUtils.log("TuneSmartWhere.setTrackingAttributeValue: " + e.getLocalizedMessage()); + } + } + static synchronized void setInstance(TuneSmartWhere tuneProximity) { instance = tuneProximity; } // Required for SmartWhere Unit Tests + @SuppressWarnings("WeakerAccess") protected boolean isSmartWhereAvailableInternal() { return classForName(TUNE_SMARTWHERE_COM_PROXIMITY_LIBRARY_PROXIMITYCONTROL) != null; } @@ -270,6 +414,4 @@ private void stopSmartWhereLocationMonitoring(Context context) { stopMonitoring(context); } } - - } \ No newline at end of file