diff --git a/Adjust/test/build.gradle b/Adjust/test/build.gradle index f5e38ad7a..719d6da23 100644 --- a/Adjust/test/build.gradle +++ b/Adjust/test/build.gradle @@ -16,6 +16,7 @@ repositories { dependencies { compile 'com.google.code.gson:gson:2.4' + compile 'com.google.android.gms:play-services-analytics:8.4.0' compile fileTree(dir: 'libs', include: ['*.jar']) compile project(':adjust') } diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/AssertUtil.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/AssertUtil.java index 85e06f1cc..c6638fb3c 100644 --- a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/AssertUtil.java +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/AssertUtil.java @@ -21,99 +21,109 @@ public AssertUtil(MockLogger mockLogger) { this.mockLogger = mockLogger; } - public void test(String message, Object... parameters) { - Assert.assertTrue(mockLogger.toString(), - mockLogger.containsTestMessage(String.format(Locale.US, message, parameters))); + public String test(String message, Object... parameters) { + MockLogger.ContainsReturn containsTestMessage = mockLogger.containsTestMessage(String.format(Locale.US, message, parameters)); + Assert.assertTrue(mockLogger.toString(), containsTestMessage.containsMessage); + return containsTestMessage.matchMessage; } - public void verbose(String message, Object... parameters) { - Assert.assertTrue(mockLogger.toString(), - mockLogger.containsMessage(VERBOSE, String.format(Locale.US, message, parameters))); + public String verbose(String message, Object... parameters) { + MockLogger.ContainsReturn containsVerboseMessage = mockLogger.containsMessage(VERBOSE, String.format(Locale.US, message, parameters)); + Assert.assertTrue(mockLogger.toString(), containsVerboseMessage.containsMessage); + return containsVerboseMessage.matchMessage; } - public void debug(String message, Object... parameters) { - Assert.assertTrue(mockLogger.toString(), - mockLogger.containsMessage(DEBUG, String.format(Locale.US, message, parameters))); + public String debug(String message, Object... parameters) { + MockLogger.ContainsReturn containsDebugMessage = mockLogger.containsMessage(DEBUG, String.format(Locale.US, message, parameters)); + Assert.assertTrue(mockLogger.toString(), containsDebugMessage.containsMessage); + return containsDebugMessage.matchMessage; } - public void info(String message, Object... parameters) { - Assert.assertTrue(mockLogger.toString(), - mockLogger.containsMessage(INFO, String.format(Locale.US, message, parameters))); + public String info(String message, Object... parameters) { + MockLogger.ContainsReturn containsInfoMessage = mockLogger.containsMessage(INFO, String.format(Locale.US, message, parameters)); + Assert.assertTrue(mockLogger.toString(), containsInfoMessage.containsMessage); + return containsInfoMessage.matchMessage; } - public void warn(String message, Object... parameters) { - Assert.assertTrue(mockLogger.toString(), - mockLogger.containsMessage(WARN, String.format(Locale.US, message, parameters))); + public String warn(String message, Object... parameters) { + MockLogger.ContainsReturn containsWarnMessage = mockLogger.containsMessage(WARN, String.format(Locale.US, message, parameters)); + Assert.assertTrue(mockLogger.toString(), containsWarnMessage.containsMessage); + return containsWarnMessage.matchMessage; } - public void error(String message, Object... parameters) { - Assert.assertTrue(mockLogger.toString(), - mockLogger.containsMessage(ERROR, String.format(Locale.US, message, parameters))); + public String error(String message, Object... parameters) { + MockLogger.ContainsReturn containsErrorMessage = mockLogger.containsMessage(ERROR, String.format(Locale.US, message, parameters)); + Assert.assertTrue(mockLogger.toString(), containsErrorMessage.containsMessage); + return containsErrorMessage.matchMessage; } - public void Assert(String message, Object... parameters) { - Assert.assertTrue(mockLogger.toString(), - mockLogger.containsMessage(ASSERT, String.format(Locale.US, message, parameters))); + public String Assert(String message, Object... parameters) { + MockLogger.ContainsReturn containsAssertMessage = mockLogger.containsMessage(ASSERT, String.format(Locale.US, message, parameters)); + Assert.assertTrue(mockLogger.toString(), containsAssertMessage.containsMessage); + return containsAssertMessage.matchMessage; } public void notInTest(String message, Object... parameters) { - Assert.assertFalse(mockLogger.toString(), - mockLogger.containsTestMessage(message)); + MockLogger.ContainsReturn containsTestMessage = mockLogger.containsTestMessage(String.format(Locale.US, message, parameters)); + Assert.assertFalse(mockLogger.toString(), containsTestMessage.containsMessage); } public void notInVerbose(String message, Object... parameters) { - Assert.assertFalse(mockLogger.toString(), - mockLogger.containsMessage(VERBOSE, String.format(Locale.US, message, parameters))); + MockLogger.ContainsReturn containsVerboseMessage = mockLogger.containsMessage(VERBOSE, String.format(Locale.US, message, parameters)); + Assert.assertFalse(mockLogger.toString(), containsVerboseMessage.containsMessage); } public void notInDebug(String message, Object... parameters) { - Assert.assertFalse(mockLogger.toString(), - mockLogger.containsMessage(DEBUG, String.format(Locale.US, message, parameters))); + MockLogger.ContainsReturn containsDebugMessage = mockLogger.containsMessage(DEBUG, String.format(Locale.US, message, parameters)); + Assert.assertFalse(mockLogger.toString(), containsDebugMessage.containsMessage); } public void notInInfo(String message, Object... parameters) { - Assert.assertFalse(mockLogger.toString(), - mockLogger.containsMessage(INFO, String.format(Locale.US, message, parameters))); + MockLogger.ContainsReturn containsInfoMessage = mockLogger.containsMessage(INFO, String.format(Locale.US, message, parameters)); + Assert.assertFalse(mockLogger.toString(), containsInfoMessage.containsMessage); } public void notInWarn(String message, Object... parameters) { - Assert.assertFalse(mockLogger.toString(), - mockLogger.containsMessage(WARN, String.format(Locale.US, message, parameters))); + MockLogger.ContainsReturn containsWarnMessage = mockLogger.containsMessage(WARN, String.format(Locale.US, message, parameters)); + Assert.assertFalse(mockLogger.toString(), containsWarnMessage.containsMessage); } public void notInError(String message, Object... parameters) { - Assert.assertFalse(mockLogger.toString(), - mockLogger.containsMessage(ERROR, String.format(Locale.US, message, parameters))); + MockLogger.ContainsReturn containsErrorMessage = mockLogger.containsMessage(ERROR, String.format(Locale.US, message, parameters)); + Assert.assertFalse(mockLogger.toString(), containsErrorMessage.containsMessage); } public void notInAssert(String message, Object... parameters) { - Assert.assertFalse(mockLogger.toString(), - mockLogger.containsMessage(ASSERT, String.format(Locale.US, message, parameters))); + MockLogger.ContainsReturn containsAssertMessage = mockLogger.containsMessage(ASSERT, String.format(Locale.US, message, parameters)); + Assert.assertFalse(mockLogger.toString(), containsAssertMessage.containsMessage); } public void isNull(Object object) { - Assert.assertNull(mockLogger.toString(), - object); + Assert.assertNull(mockLogger.toString(), object); } public void isNotNull(Object object) { - Assert.assertNotNull(mockLogger.toString(), - object); + Assert.assertNotNull(mockLogger.toString(), object); } public void isTrue(boolean value) { - Assert.assertTrue(mockLogger.toString(), - value); + Assert.assertTrue(mockLogger.toString(), value); } public void isFalse(boolean value) { - Assert.assertFalse(mockLogger.toString(), - value); + Assert.assertFalse(mockLogger.toString(), value); } public void isEqual(String expected, String actual) { - Assert.assertEquals(mockLogger.toString(), - expected, actual); + Assert.assertEquals(mockLogger.toString(), expected, actual); + } + + public void isEqual(boolean expected, boolean actual) { + Assert.assertEquals(mockLogger.toString(), expected, actual); + } + + public void isEqual(int expected, int actual) { + Assert.assertEquals(mockLogger.toString(), expected, actual); } public void fail() { diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockActivityHandler.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockActivityHandler.java index a8b08bf8e..47fd6cd21 100644 --- a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockActivityHandler.java +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockActivityHandler.java @@ -33,13 +33,13 @@ public void init(AdjustConfig config) { } @Override - public void trackSubsessionStart() { - testLogger.test(prefix + "trackSubsessionStart"); + public void onResume() { + testLogger.test(prefix + "onResume"); } @Override - public void trackSubsessionEnd() { - testLogger.test(prefix + "trackSubsessionEnd"); + public void onPause() { + testLogger.test(prefix + "onPause"); } @Override @@ -107,10 +107,4 @@ public void setOfflineMode(boolean enabled) { public void setAskingAttribution(boolean askingAttribution) { testLogger.test(prefix + "setAskingAttribution, " + askingAttribution); } - - @Override - public ActivityPackage getAttributionPackage() { - testLogger.test(prefix + "getAttributionPackage"); - return null; - } } diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockAttributionHandler.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockAttributionHandler.java index 654ae2dae..81a8ee01e 100644 --- a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockAttributionHandler.java +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockAttributionHandler.java @@ -22,9 +22,9 @@ public MockAttributionHandler(MockLogger testLogger) { @Override public void init(IActivityHandler activityHandler, ActivityPackage attributionPackage, - boolean startPaused, + boolean startsSending, boolean hasListener) { - testLogger.test(prefix + "init, startPaused: " + startPaused + + testLogger.test(prefix + "init, startsSending: " + startsSending + ", hasListener: " + hasListener); this.activityHandler = activityHandler; this.attributionPackage = attributionPackage; diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockHttpsURLConnection.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockHttpsURLConnection.java index e4e799e55..b2e5cbbaa 100644 --- a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockHttpsURLConnection.java +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockHttpsURLConnection.java @@ -29,6 +29,7 @@ public class MockHttpsURLConnection extends HttpsURLConnection { private ByteArrayOutputStream outputStream; public ResponseType responseType; public boolean timeout; + public Long waitingTime; protected MockHttpsURLConnection(URL url) { super(url); @@ -46,6 +47,10 @@ public InputStream getInputStream() throws IOException { SystemClock.sleep(10000); } + if (waitingTime != null) { + SystemClock.sleep(waitingTime); + } + if (responseType == ResponseType.CLIENT_PROTOCOL_EXCEPTION) { throw new IOException ("testResponseError"); } else if (responseType == ResponseType.WRONG_JSON) { @@ -272,7 +277,12 @@ public String getRequestProperty(String field) { public URL getURL() { testLogger.test(prefix + "getURL"); - return null; + return this.url; + } + + public void setURL(URL url) { + testLogger.test(prefix + "setURL, " + url); + } public boolean getUseCaches() { diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockLogger.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockLogger.java index 2b14647b0..e477fcb58 100644 --- a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockLogger.java +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockLogger.java @@ -17,22 +17,38 @@ public class MockLogger implements ILogger { private StringBuffer logBuffer; private SparseArray> logMap; + public static final int TEST_LEVEL = 6; + public static final int CHECK_LEVEL = 7; + private long startTime; + private long lastTime; + + public class ContainsReturn { + boolean containsMessage; + String matchMessage; + ContainsReturn(boolean containsMessage, String matchMessage) { + this.containsMessage = containsMessage; + this.matchMessage = matchMessage; + } + } public MockLogger() { reset(); } public void reset() { + startTime = System.currentTimeMillis(); + lastTime = startTime; + logBuffer = new StringBuffer(); - logMap = new SparseArray>(7); - logMap.put(LogLevel.ASSERT.getAndroidLogLevel(), new ArrayList()); + logMap = new SparseArray>(8); + logMap.put(LogLevel.VERBOSE.getAndroidLogLevel(), new ArrayList()); logMap.put(LogLevel.DEBUG.getAndroidLogLevel(), new ArrayList()); - logMap.put(LogLevel.ERROR.getAndroidLogLevel(), new ArrayList()); logMap.put(LogLevel.INFO.getAndroidLogLevel(), new ArrayList()); - logMap.put(LogLevel.VERBOSE.getAndroidLogLevel(), new ArrayList()); logMap.put(LogLevel.WARN.getAndroidLogLevel(), new ArrayList()); - // logging test level == 1 - logMap.put(1, new ArrayList()); + logMap.put(LogLevel.ERROR.getAndroidLogLevel(), new ArrayList()); + logMap.put(LogLevel.ASSERT.getAndroidLogLevel(), new ArrayList()); + logMap.put(TEST_LEVEL, new ArrayList()); + logMap.put(CHECK_LEVEL, new ArrayList()); test("Logger reset"); } @@ -54,18 +70,29 @@ public void setLogLevelString(String logLevelString) { } private void logMessage(String message, Integer iLoglevel, String messagePrefix, int priority) { - logBuffer.append(messagePrefix + message + System.getProperty("line.separator")); - Log.println(priority, LOGTAG, messagePrefix + message); + long now = System.currentTimeMillis(); + long milliSecondsPassed = now - startTime; + long lastTimePassed = now - lastTime; + lastTime = now; List prefixedList = logMap.get(iLoglevel); prefixedList.add(message); + + String longMessage = String.format("%d %d %s %s", milliSecondsPassed, lastTimePassed, messagePrefix, message); + Log.println(priority, LOGTAG, longMessage); + + String logBufferMessage = String.format("%s%s", longMessage, System.getProperty("line.separator")); + logBuffer.append(logBufferMessage); + //String sList = Arrays.toString(prefixedList.toArray()); + //String logBufferList = String.format("In %s", sList); + //logBuffer.append(logBufferList); } @Override public void verbose(String message, Object... parameters) { logMessage(String.format(Locale.US, message, parameters), LogLevel.VERBOSE.getAndroidLogLevel(), - "v ", + "v", Log.VERBOSE); } @@ -73,7 +100,7 @@ public void verbose(String message, Object... parameters) { public void debug(String message, Object... parameters) { logMessage(String.format(Locale.US, message, parameters), LogLevel.DEBUG.getAndroidLogLevel(), - "d ", + "d", Log.DEBUG); } @@ -81,7 +108,7 @@ public void debug(String message, Object... parameters) { public void info(String message, Object... parameters) { logMessage(String.format(Locale.US, message, parameters), LogLevel.INFO.getAndroidLogLevel(), - "i ", + "i", Log.INFO); } @@ -89,7 +116,7 @@ public void info(String message, Object... parameters) { public void warn(String message, Object... parameters) { logMessage(String.format(Locale.US, message, parameters), LogLevel.WARN.getAndroidLogLevel(), - "w ", + "w", Log.WARN); } @@ -97,7 +124,7 @@ public void warn(String message, Object... parameters) { public void error(String message, Object... parameters) { logMessage(String.format(Locale.US, message, parameters), LogLevel.ERROR.getAndroidLogLevel(), - "e ", + "e", Log.ERROR); } @@ -105,38 +132,53 @@ public void error(String message, Object... parameters) { public void Assert(String message, Object... parameters) { logMessage(String.format(Locale.US, message, parameters), LogLevel.ASSERT.getAndroidLogLevel(), - "a ", + "a", Log.ASSERT); } public void test(String message) { - logMessage(message, 1, "t ", Log.VERBOSE); + logMessage(message, TEST_LEVEL, "t", Log.VERBOSE); } - private Boolean mapContainsMessage(int level, String beginsWith) { + private void check(String message) { + logMessage(message, CHECK_LEVEL, "c", Log.VERBOSE); + } + + private ContainsReturn mapContainsMessage(int level, String beginsWith) { ArrayList list = logMap.get(level); @SuppressWarnings("unchecked") - ArrayList listCopy = (ArrayList) list.clone(); + ArrayList listCopy = new ArrayList(list); String sList = Arrays.toString(list.toArray()); for (String log : list) { listCopy.remove(0); if (log.startsWith(beginsWith)) { - //test(log + " found"); - Log.println(Log.ASSERT, LOGTAG, String.format(Locale.US, "%s found", log)); + String foundMessage = String.format(Locale.US, "%s found", log); + //Log.println(Log.ASSERT, LOGTAG, foundMessage); + check(foundMessage); logMap.put(level, listCopy); - return true; + return new ContainsReturn(true, log); } } - Log.println(Log.ASSERT, LOGTAG, String.format(Locale.US, "%s does not contain %s", sList, beginsWith)); + String notFoundMessage = String.format(Locale.US, "%s is not in %s", beginsWith, sList); + check(notFoundMessage); + //Log.println(Log.ASSERT, LOGTAG, notFoundMessage); - return false; + return new ContainsReturn(false, null); } - public Boolean containsMessage(LogLevel level, String beginsWith) { + public ContainsReturn containsMessage(LogLevel level, String beginsWith) { return mapContainsMessage(level.getAndroidLogLevel(), beginsWith); } - public Boolean containsTestMessage(String beginsWith) { - return mapContainsMessage(1, beginsWith); + public ContainsReturn containsTestMessage(String beginsWith) { + return mapContainsMessage(TEST_LEVEL, beginsWith); + } + + public void printLogMap(int level) { + ArrayList list = logMap.get(level); + String sList = Arrays.toString(list.toArray()); + + String message = String.format(Locale.US, "list level %d: %s", level, sList); + check(message); } } diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockPackageHandler.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockPackageHandler.java index bbb960ca4..5e8ef21b0 100644 --- a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockPackageHandler.java +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockPackageHandler.java @@ -23,8 +23,8 @@ public MockPackageHandler(MockLogger testLogger) { } @Override - public void init(IActivityHandler activityHandler, Context context, boolean startPaused) { - testLogger.test(prefix + "init, startPaused: " + startPaused); + public void init(IActivityHandler activityHandler, Context context, boolean startsSending) { + testLogger.test(prefix + "init, startsSending: " + startsSending); this.activityHandler = activityHandler; this.context = context; } @@ -51,8 +51,9 @@ public void sendNextPackage(ResponseData responseData) { } @Override - public void closeFirstPackage(ResponseData responseData) { - testLogger.test(prefix + "closeFirstPackage, " + responseData); + public void closeFirstPackage(ResponseData responseData, ActivityPackage activityPackage) { + testLogger.test(prefix + "closeFirstPackage, responseData" + responseData); + testLogger.test(prefix + "closeFirstPackage, activityPackage" + activityPackage); } @Override diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockRequestHandler.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockRequestHandler.java index 0cdfa9132..9944b70a4 100644 --- a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockRequestHandler.java +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockRequestHandler.java @@ -20,8 +20,10 @@ public void init(IPackageHandler packageHandler) { } @Override - public void sendPackage(ActivityPackage pack) { - testLogger.test(prefix + "sendPackage, " + pack); + public void sendPackage(ActivityPackage activityPackage, int queueSize) { + testLogger.test(prefix + "sendPackage, activityPackage " + activityPackage); + testLogger.test(prefix + "sendPackage, queueSize " + queueSize); + /* // respond successfully to the package handler if (packageHandler != null && !errorNextSend) { diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockSdkClickHandler.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockSdkClickHandler.java new file mode 100644 index 000000000..df4a65ba2 --- /dev/null +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/MockSdkClickHandler.java @@ -0,0 +1,41 @@ +package com.adjust.sdk.test; + +import com.adjust.sdk.ActivityPackage; +import com.adjust.sdk.ISdkClickHandler; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by pfms on 01/04/16. + */ +public class MockSdkClickHandler implements ISdkClickHandler { + private MockLogger testLogger; + private String prefix = "SdkClickHandler "; + List queue; + + public MockSdkClickHandler(MockLogger testLogger) { + this.testLogger = testLogger; + queue = new ArrayList(); + } + @Override + public void init(boolean startsSending) { + testLogger.test(prefix + "init, startsSending: " + startsSending); + } + + @Override + public void pauseSending() { + testLogger.test(prefix + "pauseSending"); + } + + @Override + public void resumeSending() { + testLogger.test(prefix + "resumeSending"); + } + + @Override + public void sendSdkClick(ActivityPackage sdkClick) { + testLogger.test(prefix + "sendSdkClick"); + queue.add(sdkClick); + } +} diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestActivityHandler.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestActivityHandler.java index 85d6bba20..91eb21e29 100644 --- a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestActivityHandler.java +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestActivityHandler.java @@ -8,7 +8,9 @@ import android.test.mock.MockContext; import com.adjust.sdk.ActivityHandler; +import com.adjust.sdk.ActivityHandler.InternalState; import com.adjust.sdk.ActivityPackage; +import com.adjust.sdk.Adjust; import com.adjust.sdk.AdjustAttribution; import com.adjust.sdk.AdjustConfig; import com.adjust.sdk.AdjustEvent; @@ -23,6 +25,7 @@ import com.adjust.sdk.EventResponseData; import com.adjust.sdk.LogLevel; import com.adjust.sdk.OnAttributionChangedListener; +import com.adjust.sdk.OnDeeplinkResponseListener; import com.adjust.sdk.OnEventTrackingFailedListener; import com.adjust.sdk.OnEventTrackingSucceededListener; import com.adjust.sdk.OnSessionTrackingFailedListener; @@ -38,6 +41,7 @@ public class TestActivityHandler extends ActivityInstrumentationTestCase2 0; i--) { - assertUtil.test("PackageHandler addPackage"); - assertUtil.test("PackageHandler sendFirstPackage"); + for (int i = 7; i > 0; i--) { + assertUtil.test("SdkClickHandler sendSdkClick"); } - // checking the default values of the first session package - // 1 session + 3 click - assertEquals(4, mockPackageHandler.queue.size()); + assertUtil.notInTest("SdkClickHandler sendSdkClick"); + + // 7 clicks + assertEquals(7, mockSdkClickHandler.queue.size()); // get the click package - ActivityPackage attributionClickPackage = mockPackageHandler.queue.get(1); + ActivityPackage attributionClickPackage = mockSdkClickHandler.queue.get(0); // create activity package test TestActivityPackage testAttributionClickPackage = new TestActivityPackage(attributionClickPackage); @@ -805,23 +847,27 @@ public void testOpenUrl() { // and set it testAttributionClickPackage.attribution = firstAttribution; + testAttributionClickPackage.deeplink = attributions.toString(); + // test the first deeplink testAttributionClickPackage.testClickPackage("deeplink"); // get the click package - ActivityPackage extraParamsClickPackage = mockPackageHandler.queue.get(2); + ActivityPackage extraParamsClickPackage = mockSdkClickHandler.queue.get(1); // create activity package test TestActivityPackage testExtraParamsClickPackage = new TestActivityPackage(extraParamsClickPackage); // other deep link parameters - testExtraParamsClickPackage.deepLinkParameters = "{\"key\":\"value\",\"foo\":\"bar\"}"; + testExtraParamsClickPackage.otherParameters = "{\"key\":\"value\",\"foo\":\"bar\"}"; + + testExtraParamsClickPackage.deeplink = extraParams.toString(); // test the second deeplink testExtraParamsClickPackage.testClickPackage("deeplink"); // get the click package - ActivityPackage mixedClickPackage = mockPackageHandler.queue.get(3); + ActivityPackage mixedClickPackage = mockSdkClickHandler.queue.get(2); // create activity package test TestActivityPackage testMixedClickPackage = new TestActivityPackage(mixedClickPackage); @@ -836,10 +882,52 @@ public void testOpenUrl() { testMixedClickPackage.attribution = secondAttribution; // other deep link parameters - testMixedClickPackage.deepLinkParameters = "{\"foo\":\"bar\"}"; + testMixedClickPackage.otherParameters = "{\"foo\":\"bar\"}"; + + testMixedClickPackage.deeplink = mixed.toString(); // test the third deeplink testMixedClickPackage.testClickPackage("deeplink"); + + // get the click package + ActivityPackage emptyQueryStringClickPackage = mockSdkClickHandler.queue.get(3); + + // create activity package test + TestActivityPackage testEmptyQueryStringClickPackage = new TestActivityPackage(emptyQueryStringClickPackage); + + testEmptyQueryStringClickPackage.deeplink = emptyQueryString.toString(); + + testEmptyQueryStringClickPackage.testClickPackage("deeplink"); + + // get the click package + ActivityPackage singleClickPackage = mockSdkClickHandler.queue.get(4); + + // create activity package test + TestActivityPackage testSingleClickPackage = new TestActivityPackage(singleClickPackage); + + testSingleClickPackage.deeplink = single.toString(); + + testSingleClickPackage.testClickPackage("deeplink"); + + // get the click package + ActivityPackage prefixClickPackage = mockSdkClickHandler.queue.get(5); + + // create activity package test + TestActivityPackage testPrefixClickPackage = new TestActivityPackage(prefixClickPackage); + + testPrefixClickPackage.deeplink = prefix.toString(); + + testPrefixClickPackage.testClickPackage("deeplink"); + + // get the click package + ActivityPackage incompleteClickPackage = mockSdkClickHandler.queue.get(6); + + // create activity package test + TestActivityPackage testIncompleteClickPackage = new TestActivityPackage(incompleteClickPackage ); + + testIncompleteClickPackage.deeplink = incomplete.toString(); + + testIncompleteClickPackage.testClickPackage("deeplink"); } public void testAttributionDelegate() { @@ -856,12 +944,9 @@ public void onAttributionChanged(AdjustAttribution attribution) { } }); - checkFinishTasks(config, - true, // attributionDelegatePresent - false, // eventSuccessDelegatePresent - false, // eventFailureDelegatePresent - false, // sessionSuccessDelegatePresent - false); // sessionFailureDelegatePresent + DelegatesPresent attributionDelegatePresent = new DelegatesPresent(); + attributionDelegatePresent.attributionDelegatePresent = true; + checkFinishTasks(config, attributionDelegatePresent); } public void testSuccessDelegates() { @@ -885,12 +970,11 @@ public void onFinishedSessionTrackingSucceeded(AdjustSessionSuccess sessionSucce } }); - checkFinishTasks(config, - false, // attributionDelegatePresent - true, // eventSuccessDelegatePresent - false, // eventFailureDelegatePresent - true, // sessionSuccessDelegatePresent - false); // sessionFailureDelegatePresent + DelegatesPresent successDelegatesPresent = new DelegatesPresent(); + successDelegatesPresent.eventSuccessDelegatePresent = true; + successDelegatesPresent.sessionSuccessDelegatePresent = true; + + checkFinishTasks(config, successDelegatesPresent); } public void testFailureDelegates() { @@ -914,186 +998,138 @@ public void onFinishedSessionTrackingFailed(AdjustSessionFailure failureResponse } }); - checkFinishTasks(config, - false, // attributionDelegatePresent - false, // eventSuccessDelegatePresent - true, // eventFailureDelegatePresent - false, // sessionSuccessDelegatePresent - true); // sessionFailureDelegatePresent + DelegatesPresent failureDelegatesPresent = new DelegatesPresent(); + failureDelegatesPresent.sessionFailureDelegatePresent = true; + failureDelegatesPresent.eventFailureDelegatePresent = true; + + checkFinishTasks(config, failureDelegatesPresent); } - public void checkFinishTasks(AdjustConfig config, - boolean attributionDelegatePresent, - boolean eventSuccessDelegatePresent, - boolean eventFailureDelegatePresent, - boolean sessionSuccessDelegatePresent, - boolean sessionFailureDelegatePresent) - { - ActivityHandler activityHandler = getActivityHandler(config); + public void testLaunchDeepLink() { + // assert test name to read better in logcat + mockLogger.Assert("TestActivityHandler testLaunchDeepLink"); - activityHandler.trackSubsessionStart(); + // create the config to start the session + AdjustConfig config = getConfig(LogLevel.VERBOSE, AdjustConfig.ENVIRONMENT_PRODUCTION, "123456789012", context); - SystemClock.sleep(3000); + // start activity handler with config + ActivityHandler activityHandler = getActivityHandler(config, + true, // startEnabled, + null, // readActivityState, + null, // readAttribution, + true, // isProductionEnvironment, + LogLevel.VERBOSE); // logLevel - checkInitAndFirstSession(); + SystemClock.sleep(2000); - // test first session package - ActivityPackage firstSessionPackage = mockPackageHandler.queue.get(0); + checkInitTests( + false, // eventBuffering + null, // defaultTracker + false); // startsSending - // create activity package test - TestActivityPackage testActivityPackage = new TestActivityPackage(firstSessionPackage); + startActivity(activityHandler); - testActivityPackage.needsResponseDetails = - attributionDelegatePresent || - eventSuccessDelegatePresent || - eventFailureDelegatePresent || - sessionSuccessDelegatePresent || - sessionFailureDelegatePresent; + SystemClock.sleep(2000); - // set first session - testActivityPackage.testSessionPackage(1); + // test first session start + checkFirstSession(); - // simulate a successful session - SessionResponseData successSessionResponseData = (SessionResponseData)ResponseData.buildResponseData(firstSessionPackage); - successSessionResponseData.success = true; + ResponseData responseDataNull = null; - activityHandler.finishedTrackingActivity(successSessionResponseData); + //activityHandler.finishedTrackingActivity(responseDataNull); SystemClock.sleep(1000); - // attribution handler should always receive the session response - assertUtil.test("AttributionHandler checkSessionResponse"); - // the first session does not trigger the event response delegate - - assertUtil.notInDebug("Launching success event tracking listener"); - assertUtil.notInDebug("Launching failed event tracking listener"); - - activityHandler.launchSessionResponseTasks(successSessionResponseData); - SystemClock.sleep(1000); + // if the response is null + assertUtil.notInTest("AttributionHandler checkAttribution"); + assertUtil.notInError("Unable to open deep link"); + assertUtil.notInInfo("Open deep link"); - // if present, the first session triggers the success session delegate - if (sessionSuccessDelegatePresent) { - assertUtil.debug("Launching success session tracking listener"); - } else { - assertUtil.notInDebug("Launching success session tracking delegate"); + // set package handler to respond with a valid attribution + ResponseData wrongDeeplinkResponseData = ResponseData.buildResponseData(mockPackageHandler.queue.get(0)); + try { + wrongDeeplinkResponseData.jsonResponse = new JSONObject("{ " + + "\"deeplink\" : \"wrongDeeplink://\" }"); + } catch (JSONException e) { + fail(e.getMessage()); } - // it doesn't trigger the failure session delegate - assertUtil.notInDebug("Launching failed session tracking listener"); - // simulate a failure session - SessionResponseData failureSessionResponseData = (SessionResponseData)ResponseData.buildResponseData(firstSessionPackage); - failureSessionResponseData.success = false; + activityHandler.launchSessionResponseTasks((SessionResponseData) wrongDeeplinkResponseData); + SystemClock.sleep(2000); - activityHandler.launchSessionResponseTasks(failureSessionResponseData); - SystemClock.sleep(1000); + // check that it was unable to open the url + assertUtil.error("Unable to open deep link (wrongDeeplink://)"); - // it doesn't trigger the success session delegate - assertUtil.notInDebug("Launching success session tracking listener"); + // TODO add test that opens url - // if present, the first session triggers the failure session delegate - if (sessionFailureDelegatePresent) { - assertUtil.debug("Launching failed session tracking listener"); - } else { - assertUtil.notInDebug("Launching failed session tracking listener"); - } + // checking the default values of the first session package + // should only have one package + assertEquals(1, mockPackageHandler.queue.size()); - // test success event response data - activityHandler.trackEvent(new AdjustEvent("abc123")); - SystemClock.sleep(1000); + ActivityPackage activityPackage = mockPackageHandler.queue.get(0); - ActivityPackage eventPackage = mockPackageHandler.queue.get(1); - EventResponseData eventSuccessResponseData = (EventResponseData)ResponseData.buildResponseData(eventPackage); - eventSuccessResponseData.success = true; + // create activity package test + TestActivityPackage testActivityPackage = new TestActivityPackage(activityPackage); - activityHandler.finishedTrackingActivity(eventSuccessResponseData); - SystemClock.sleep(1000); + testActivityPackage.environment = AdjustConfig.ENVIRONMENT_PRODUCTION; - // attribution handler should never receive the event response - assertUtil.notInTest("AttributionHandler checkSessionResponse"); + // set first session + testActivityPackage.testSessionPackage(1); + } - // if present, the success event triggers the success event delegate - if (eventSuccessDelegatePresent) { - assertUtil.debug("Launching success event tracking listener"); - } else { - assertUtil.notInDebug("Launching success event tracking listener"); - } - // it doesn't trigger the failure event delegate - assertUtil.notInDebug("Launching failed event tracking listener"); + public void testNotLaunchDeeplinkCallback() { + // assert test name to read better in logcat + mockLogger.Assert("TestActivityHandler testNotLaunchDeeplinkCallback"); - // test failure event response data - EventResponseData eventFailureResponseData = (EventResponseData)ResponseData.buildResponseData(eventPackage); - eventFailureResponseData.success = false; + // create the config to start the session + AdjustConfig config = getConfig(); - activityHandler.finishedTrackingActivity(eventFailureResponseData); - SystemClock.sleep(1000); + config.setOnDeeplinkResponseListener(new OnDeeplinkResponseListener() { + @Override + public boolean launchReceivedDeeplink(Uri deeplink) { + mockLogger.test("launchReceivedDeeplink, " + deeplink); + return false; + } + }); - // attribution handler should never receive the event response - assertUtil.notInTest("AttributionHandler checkSessionResponse"); + // start activity handler with config + ActivityHandler activityHandler = startAndCheckFirstSession(config); - // if present, the failure event triggers the failure event delegate - if (eventFailureDelegatePresent) { - assertUtil.debug("Launching failed event tracking listener"); - } else { - assertUtil.notInDebug("Launching failed event tracking listener"); + // set package handler to respond with a valid attribution + ResponseData wrongDeeplinkResponseData = ResponseData.buildResponseData(mockPackageHandler.queue.get(0)); + try { + wrongDeeplinkResponseData.jsonResponse = new JSONObject("{ " + + "\"deeplink\" : \"wrongDeeplink://\" }"); + } catch (JSONException e) { + fail(e.getMessage()); } - // it doesn't trigger the success event delegate - assertUtil.notInDebug("Launching success event tracking listener"); - // test click - Uri attributions = Uri.parse("AdjustTests://example.com/path/inApp?adjust_tracker=trackerValue&other=stuff&adjust_campaign=campaignValue&adjust_adgroup=adgroupValue&adjust_creative=creativeValue"); - long now = System.currentTimeMillis(); - - activityHandler.readOpenUrl(attributions, now); - SystemClock.sleep(1000); - - assertUtil.test("PackageHandler addPackage"); - assertUtil.test("PackageHandler sendFirstPackage"); - - // test sdk_click response data - ActivityPackage sdkClickPackage = mockPackageHandler.queue.get(2); - ClickResponseData clickResponseData = (ClickResponseData)ResponseData.buildResponseData(sdkClickPackage); + activityHandler.launchSessionResponseTasks((SessionResponseData) wrongDeeplinkResponseData); + SystemClock.sleep(2000); - activityHandler.finishedTrackingActivity(clickResponseData); - SystemClock.sleep(1000); + // callback called + assertUtil.test("launchReceivedDeeplink, wrongDeeplink://"); - // attribution handler should never receive the click response - assertUtil.notInTest("AttributionHandler checkSessionResponse"); - // it doesn't trigger the any event delegate - assertUtil.notInDebug("Launching success event tracking listener"); - assertUtil.notInDebug("Launching failed event tracking listener"); + // but deeplink not launched + assertUtil.notInError("Unable to open deep link"); } - public void testLaunchDeepLink() { + public void testDeeplinkCallback() { // assert test name to read better in logcat - mockLogger.Assert("TestActivityHandler testLaunchDeepLink"); + mockLogger.Assert("TestActivityHandler testDeeplinkCallback"); // create the config to start the session - AdjustConfig config = new AdjustConfig(context, "123456789012", AdjustConfig.ENVIRONMENT_PRODUCTION); + AdjustConfig config = getConfig(); - // set verbose log level - config.setLogLevel(LogLevel.VERBOSE); + config.setOnDeeplinkResponseListener(new OnDeeplinkResponseListener() { + @Override + public boolean launchReceivedDeeplink(Uri deeplink) { + mockLogger.test("launchReceivedDeeplink, " + deeplink); + return true; + } + }); // start activity handler with config - ActivityHandler activityHandler = getActivityHandler(config); - - activityHandler.trackSubsessionStart(); - - SystemClock.sleep(3000); - - // test init values - checkInitTests(AdjustConfig.ENVIRONMENT_PRODUCTION, "ASSERT", false); - - // test first session start - checkFirstSession(); - - ResponseData responseDataNull = null; - - //activityHandler.finishedTrackingActivity(responseDataNull); - SystemClock.sleep(1000); - - // if the response is null - assertUtil.notInTest("AttributionHandler checkAttribution"); - assertUtil.notInError("Unable to open deep link"); - assertUtil.notInInfo("Open deep link"); + ActivityHandler activityHandler = startAndCheckFirstSession(config); // set package handler to respond with a valid attribution ResponseData wrongDeeplinkResponseData = ResponseData.buildResponseData(mockPackageHandler.queue.get(0)); @@ -1105,26 +1141,13 @@ public void testLaunchDeepLink() { } activityHandler.launchSessionResponseTasks((SessionResponseData) wrongDeeplinkResponseData); - SystemClock.sleep(3000); - - // check that it was unable to open the url - assertUtil.error("Unable to open deep link (wrongDeeplink://)"); - - // TODO add test that opens url - - // checking the default values of the first session package - // should only have one package - assertEquals(1, mockPackageHandler.queue.size()); - - ActivityPackage activityPackage = mockPackageHandler.queue.get(0); - - // create activity package test - TestActivityPackage testActivityPackage = new TestActivityPackage(activityPackage); + SystemClock.sleep(2000); - testActivityPackage.environment = AdjustConfig.ENVIRONMENT_PRODUCTION; + // callback called + assertUtil.test("launchReceivedDeeplink, wrongDeeplink://"); - // set first session - testActivityPackage.testSessionPackage(1); + // but deeplink not launched + assertUtil.error("Unable to open deep link"); } public void testUpdateAttribution() { @@ -1132,18 +1155,10 @@ public void testUpdateAttribution() { mockLogger.Assert("TestActivityHandler testUpdateAttribution"); // create the config to start the session - AdjustConfig config = new AdjustConfig(context, "123456789012", AdjustConfig.ENVIRONMENT_SANDBOX); + AdjustConfig config = getConfig(); // start activity handler with config - ActivityHandler firstActivityHandler = getActivityHandler(config); - - SystemClock.sleep(3000); - - // test init values - checkInitTests(); - - // test first session start - checkFirstSession(); + ActivityHandler firstActivityHandler = startAndCheckFirstSession(config); JSONObject nullJsonObject = null; AdjustAttribution nullAttribution = AdjustAttribution.fromJson(nullJsonObject); @@ -1182,13 +1197,13 @@ public void testUpdateAttribution() { assertUtil.notInDebug("Wrote Attribution"); // end session - firstActivityHandler.trackSubsessionEnd(); + firstActivityHandler.onPause(); SystemClock.sleep(1000); checkEndSession(); // create the new config - config = new AdjustConfig(context, "123456789012", AdjustConfig.ENVIRONMENT_SANDBOX); + config = getConfig(); config.setOnAttributionChangedListener(new OnAttributionChangedListener() { @Override @@ -1197,14 +1212,26 @@ public void onAttributionChanged(AdjustAttribution attribution) { } }); - ActivityHandler restartActivityHandler = getActivityHandler(config); + ActivityHandler restartActivityHandler = getActivityHandler (config, + true, // startEnabled + "ec:0 sc:1 ssc:1", // readActivityState + "tt:null tn:null net:null cam:null adg:null cre:null cl:null", // readAttribution + false, // isProductionEnvironment + LogLevel.INFO); // loglevel - SystemClock.sleep(3000); + SystemClock.sleep(2000); // test init values - checkInitTests(AdjustConfig.ENVIRONMENT_SANDBOX, "INFO", false, "ec:0 sc:1 ssc:1", "tt:null tn:null net:null cam:null adg:null cre:null cl:null"); + checkInitTests(); + + startActivity(restartActivityHandler); + + SystemClock.sleep(2000); - checkFirstSessionSubsession(2); + SessionState firstRestart = new SessionState(SessionType.NEW_SUBSESSION); + firstRestart.subsessionCount = 2; + firstRestart.timerAlreadyStarted = false; + checkStartInternal(firstRestart); // check that it does not update the attribution after the restart assertUtil.isFalse(restartActivityHandler.updateAttribution(emptyAttribution)); @@ -1247,12 +1274,12 @@ public void onAttributionChanged(AdjustAttribution attribution) { assertUtil.notInDebug("Wrote Attribution"); // end session - restartActivityHandler.trackSubsessionEnd(); + restartActivityHandler.onPause(); SystemClock.sleep(1000); checkEndSession(); - config = new AdjustConfig(context, "123456789012", AdjustConfig.ENVIRONMENT_SANDBOX); + config = getConfig(); config.setOnAttributionChangedListener(new OnAttributionChangedListener() { @Override @@ -1261,14 +1288,27 @@ public void onAttributionChanged(AdjustAttribution attribution) { } }); - ActivityHandler secondRestartActivityHandler = getActivityHandler(config); + ActivityHandler secondRestartActivityHandler = getActivityHandler(config, + true, // startEnabled + "ec:0 sc:1 ssc:2", // readActivityState + "tt:ttValue tn:tnValue net:nValue cam:cpValue adg:aValue cre:ctValue cl:clValue", // readAttribution + false, // isProductionEnvironment + LogLevel.INFO); // loglevel - SystemClock.sleep(3000); + SystemClock.sleep(2000); // test init values - checkInitTests(AdjustConfig.ENVIRONMENT_SANDBOX, "INFO", false, "ec:0 sc:1 ssc:2", "tt:ttValue tn:tnValue net:nValue cam:cpValue adg:aValue cre:ctValue cl:clValue"); + checkInitTests(); + + startActivity(secondRestartActivityHandler); - checkFirstSessionSubsession(3); + SystemClock.sleep(2000); + + SessionState secondRestart = new SessionState(SessionType.NEW_SUBSESSION); + secondRestart.subsessionCount = 3; + secondRestart.timerAlreadyStarted = false; + + checkStartInternal(secondRestart); // check that it does not update the attribution after the restart assertUtil.isFalse(secondRestartActivityHandler.updateAttribution(firstAttribution)); @@ -1314,27 +1354,57 @@ public void testOfflineMode() { AdjustFactory.setSubsessionInterval(500); // create the config to start the session - AdjustConfig config = new AdjustConfig(context, "123456789012", AdjustConfig.ENVIRONMENT_SANDBOX); + AdjustConfig config = getConfig(); // start activity handler with config - ActivityHandler activityHandler = getActivityHandler(config); + ActivityHandler activityHandler = getFirstActivityHandler(config); // put SDK offline activityHandler.setOfflineMode(true); - SystemClock.sleep(3000); + InternalState internalState = activityHandler.getInternalState(); + + // check if it's offline before the sdk starts + assertUtil.isTrue(internalState.isOffline()); + + SystemClock.sleep(2000); + + // not writing activity state because it set enable does not start the sdk + assertUtil.notInDebug("Wrote Activity state"); // check if message the disable of the SDK - assertUtil.info("Pausing package and attribution handler to put in offline mode"); + assertUtil.info("Package handler and attribution handler will start paused due to SDK being offline"); // test init values - checkInitTests(); + checkInitTests(false); + + checkHandlerStatus(true); + + // start the sdk + // foreground timer does not start because it's paused + startActivity(activityHandler, + true, // checkLog + false, // foregroundTimerStarts + false); // foregroundTimerAlreadyStarted + + SystemClock.sleep(2000); // test first session start - checkFirstSession(true); + SessionState firstSessionStartPaused = new SessionState(SessionType.NEW_SESSION); + firstSessionStartPaused.paused = true; + firstSessionStartPaused.toSend = false; - // test end of session logs - checkEndSession(); + // check session that is paused + checkStartInternal(firstSessionStartPaused); + + stopActivity(activityHandler); + + SystemClock.sleep(1000); + + // test end session of disable + checkEndSession(true, //pausing + false, // updateActivityState + false); // eventBufferingEnabled // disable the SDK activityHandler.setEnabled(false); @@ -1346,32 +1416,30 @@ public void testOfflineMode() { assertUtil.debug("Wrote Activity state: ec:0 sc:1 ssc:1"); // check if message the disable of the SDK - assertUtil.info("Pausing package handler and attribution handler to disable the SDK"); + assertUtil.info("Pausing package handler and attribution handler due to SDK being disabled"); SystemClock.sleep(1000); - // test end session logs - checkEndSession(false); + checkHandlerStatus(true); // put SDK back online activityHandler.setOfflineMode(false); - assertUtil.info("Package and attribution handler remain paused because the SDK is disabled"); + assertUtil.info("Package and attribution handler remain paused due to SDK being disabled"); SystemClock.sleep(1000); // test the update status, still paused - assertUtil.notInTest("AttributionHandler pauseSending"); - assertUtil.notInTest("PackageHandler pauseSending"); + checkHandlerStatus(null); // try to do activities while SDK disabled - activityHandler.trackSubsessionStart(); + activityHandler.onResume(); activityHandler.trackEvent(new AdjustEvent("event1")); SystemClock.sleep(3000); // check that timer was not executed - checkTimerIsFired(false); + checkForegroundTimerFired(false); // check that it did not wrote activity state from new session or subsession assertUtil.notInDebug("Wrote Activity state"); @@ -1379,16 +1447,36 @@ public void testOfflineMode() { // check that it did not add any package assertUtil.notInTest("PackageHandler addPackage"); + // end the session + stopActivity(activityHandler); + + SystemClock.sleep(1000); + + checkEndSession(false); + // enable the SDK again activityHandler.setEnabled(true); // check that is enabled assertUtil.isTrue(activityHandler.isEnabled()); + assertUtil.debug("Wrote Activity state"); + + assertUtil.info("Resuming package handler and attribution handler due to SDK being enabled"); + SystemClock.sleep(1000); + // it is still paused because it's on the background + checkHandlerStatus(true); + + startActivity(activityHandler); + + SystemClock.sleep(1000); + + SessionState secondSessionState = new SessionState(SessionType.NEW_SESSION); + secondSessionState.sessionCount = 2; // test that is not paused anymore - checkNewSession(false, 2, 0); + checkStartInternal(secondSessionState); } public void testSendReferrer() { @@ -1396,18 +1484,10 @@ public void testSendReferrer() { mockLogger.Assert("TestActivityHandler testSendReferrer"); // create the config to start the session - AdjustConfig config = new AdjustConfig(context, "123456789012", AdjustConfig.ENVIRONMENT_SANDBOX); + AdjustConfig config = getConfig(); // start activity handler with config - ActivityHandler activityHandler = getActivityHandler(config); - - SystemClock.sleep(3000); - - // test init values - checkInitTests(); - - // test first session start - checkFirstSession(); + ActivityHandler activityHandler = startAndCheckFirstSession(config); long now = System.currentTimeMillis(); @@ -1437,21 +1517,18 @@ public void testSendReferrer() { activityHandler.sendReferrer(incomplete, now); SystemClock.sleep(1000); - // three click packages: reftag, extraParams and mixed - for (int i = 3; i > 0; i--) { - //assertUtil.test("AttributionHandler getAttribution"); - assertUtil.test("PackageHandler addPackage"); - assertUtil.test("PackageHandler sendFirstPackage"); + // three click packages: reftag, extraParams, mixed, empty, single, prefix and incomplete + for (int i = 6; i > 0; i--) { + assertUtil.test("SdkClickHandler sendSdkClick"); } // check that it did not send any other click package - assertUtil.notInTest("PackageHandler sendClickPackage"); + assertUtil.notInTest("SdkClickHandler sendSdkClick"); - // checking the default values of the first session package - // 1 session + 3 click - assertEquals(4, mockPackageHandler.queue.size()); + // 6 click + assertEquals(6, mockSdkClickHandler.queue.size()); - ActivityPackage reftagClickPackage = mockPackageHandler.queue.get(1); + ActivityPackage reftagClickPackage = mockSdkClickHandler.queue.get(0); TestActivityPackage reftagClickPackageTest = new TestActivityPackage(reftagClickPackage); @@ -1461,13 +1538,13 @@ public void testSendReferrer() { reftagClickPackageTest.testClickPackage("reftag"); // get the click package - ActivityPackage extraParamsClickPackage = mockPackageHandler.queue.get(2); + ActivityPackage extraParamsClickPackage = mockSdkClickHandler.queue.get(1); // create activity package test TestActivityPackage testExtraParamsClickPackage = new TestActivityPackage(extraParamsClickPackage); // other deep link parameters - testExtraParamsClickPackage.deepLinkParameters = "{\"key\":\"value\",\"foo\":\"bar\"}"; + testExtraParamsClickPackage.otherParameters = "{\"key\":\"value\",\"foo\":\"bar\"}"; testExtraParamsClickPackage.referrer = extraParams; @@ -1475,7 +1552,7 @@ public void testSendReferrer() { testExtraParamsClickPackage.testClickPackage("reftag"); // get the click package - ActivityPackage mixedClickPackage = mockPackageHandler.queue.get(3); + ActivityPackage mixedClickPackage = mockSdkClickHandler.queue.get(2); // create activity package test TestActivityPackage testMixedClickPackage = new TestActivityPackage(mixedClickPackage); @@ -1484,10 +1561,40 @@ public void testSendReferrer() { testMixedClickPackage.referrer = mixed; // other deep link parameters - testMixedClickPackage.deepLinkParameters = "{\"foo\":\"bar\"}"; + testMixedClickPackage.otherParameters = "{\"foo\":\"bar\"}"; // test the third deeplink testMixedClickPackage.testClickPackage("reftag"); + + // get the click package + ActivityPackage singleClickPackage = mockSdkClickHandler.queue.get(3); + + // create activity package test + TestActivityPackage testSingleClickPackage = new TestActivityPackage(singleClickPackage); + + testSingleClickPackage.referrer = single; + + testSingleClickPackage.testClickPackage("reftag"); + + // get the click package + ActivityPackage prefixClickPackage = mockSdkClickHandler.queue.get(4); + + // create activity package test + TestActivityPackage testPrefixClickPackage = new TestActivityPackage(prefixClickPackage); + + testPrefixClickPackage.referrer = prefix; + + testPrefixClickPackage.testClickPackage("reftag"); + + // get the click package + ActivityPackage incompleteClickPackage = mockSdkClickHandler.queue.get(5); + + // create activity package test + TestActivityPackage testIncompleteClickPackage = new TestActivityPackage(incompleteClickPackage); + + testIncompleteClickPackage.referrer = incomplete; + + testIncompleteClickPackage.testClickPackage("reftag"); } public void testGetAttribution() { @@ -1496,16 +1603,15 @@ public void testGetAttribution() { //AdjustFactory.setTimerStart(500); AdjustFactory.setSessionInterval(4000); - /*** - * if (activityState.subsessionCount > 1) { - * if (attribution == null || activityState.askingAttribution) { - * getAttributionHandler().getAttribution(); - * } - * } - */ + + /// if (activityState.subsessionCount > 1) { + /// if (attribution == null || activityState.askingAttribution) { + /// getAttributionHandler().getAttribution(); + /// } + /// } // create the config to start the session - AdjustConfig config = new AdjustConfig(context, "123456789012", AdjustConfig.ENVIRONMENT_SANDBOX); + AdjustConfig config = getConfig(); config.setOnAttributionChangedListener(new OnAttributionChangedListener() { @Override @@ -1515,23 +1621,26 @@ public void onAttributionChanged(AdjustAttribution attribution) { }); // start activity handler with config - ActivityHandler activityHandler = getActivityHandler(config); + ActivityHandler activityHandler = getFirstActivityHandler(config); - SystemClock.sleep(3000); + SystemClock.sleep(2000); // test init values checkInitTests(); + startActivity(activityHandler); + + SystemClock.sleep(2000); + // subsession count is 1 // attribution is null, // askingAttribution is false by default, // -> Not called // test first session start - checkFirstSession(); - - // test that get attribution wasn't called - assertUtil.notInTest("AttributionHandler getAttribution"); + SessionState newSessionState = new SessionState(SessionType.NEW_SESSION); + newSessionState.getAttributionIsCalled = false; + checkStartInternal(newSessionState); // subsession count increased to 2 // attribution is still null, @@ -1539,10 +1648,10 @@ public void onAttributionChanged(AdjustAttribution attribution) { // -> Called // trigger a new sub session - activityHandler.trackSubsessionStart(); + activityHandler.onResume(); SystemClock.sleep(2000); - checkSubsession(1, 2, true, true); + checkSubSession(1, 2, true); // subsession count increased to 3 // attribution is still null, @@ -1554,10 +1663,10 @@ public void onAttributionChanged(AdjustAttribution attribution) { assertUtil.debug("Wrote Activity state: ec:0 sc:1 ssc:2"); // trigger a new session - activityHandler.trackSubsessionStart(); + activityHandler.onResume(); SystemClock.sleep(2000); - checkSubsession(1, 3, true, true); + checkSubSession(1, 3, true); // subsession is reset to 1 with new session // attribution is still null, @@ -1565,10 +1674,10 @@ public void onAttributionChanged(AdjustAttribution attribution) { // -> Not called SystemClock.sleep(3000); // 5 seconds = 2 + 3 - activityHandler.trackSubsessionStart(); + activityHandler.onResume(); SystemClock.sleep(2000); - checkSubsession(2, 1, true, false); + checkFurtherSessions(2, false); // subsession count increased to 2 // attribution is set, @@ -1598,20 +1707,20 @@ public void onAttributionChanged(AdjustAttribution attribution) { assertUtil.debug("Wrote Attribution: tt:ttValue tn:tnValue net:nValue cam:cpValue adg:aValue cre:ctValue cl:clValue"); // trigger a new sub session - activityHandler.trackSubsessionStart(); + activityHandler.onResume(); SystemClock.sleep(2000); - checkSubsession(2, 2, true, true); + checkSubSession(2, 2, true); // subsession count is reset to 1 // attribution is set, // askingAttribution is set to true, // -> Not called SystemClock.sleep(3000); // 5 seconds = 2 + 3 - activityHandler.trackSubsessionStart(); + activityHandler.onResume(); SystemClock.sleep(2000); - checkSubsession(3, 1, true, false); + checkFurtherSessions(3, false); // subsession increased to 2 // attribution is set, // askingAttribution is set to false @@ -1621,10 +1730,10 @@ public void onAttributionChanged(AdjustAttribution attribution) { assertUtil.debug("Wrote Activity state: ec:0 sc:3 ssc:1"); // trigger a new sub session - activityHandler.trackSubsessionStart(); + activityHandler.onResume(); SystemClock.sleep(2000); - checkSubsession(3, 2, true, false); + checkSubSession(3, 2, false); // subsession is reset to 1 // attribution is set, @@ -1632,114 +1741,489 @@ public void onAttributionChanged(AdjustAttribution attribution) { // -> Not called SystemClock.sleep(3000); // 5 seconds = 2 + 3 - activityHandler.trackSubsessionStart(); + activityHandler.onResume(); SystemClock.sleep(2000); - checkSubsession(4, 1, true, false); + checkFurtherSessions(4, false); } - public void testTimer() { + public void testForegroundTimer() { // assert test name to read better in logcat - mockLogger.Assert("TestActivityHandler testTimer"); + mockLogger.Assert("TestActivityHandler testForegroundTimer"); AdjustFactory.setTimerInterval(4000); - AdjustFactory.setTimerStart(0); + AdjustFactory.setTimerStart(4000); // create the config to start the session - AdjustConfig config = new AdjustConfig(context, "123456789012", AdjustConfig.ENVIRONMENT_SANDBOX); + AdjustConfig config = getConfig(); // start activity handler with config - ActivityHandler activityHandler = getActivityHandler(config); - - SystemClock.sleep(2000); - - // test init values - checkInitTests(); - - // test first session start - checkFirstSession(); + ActivityHandler activityHandler = startAndCheckFirstSession(config); // wait enough to fire the first cycle SystemClock.sleep(3000); - checkTimerIsFired(true); + checkForegroundTimerFired(true); // end subsession to stop timer - activityHandler.trackSubsessionEnd(); + activityHandler.onPause(); // wait enough for a new cycle SystemClock.sleep(6000); - activityHandler.trackSubsessionStart(); + // start a new session + activityHandler.onResume(); SystemClock.sleep(1000); - checkTimerIsFired(false); + // check that not enough time passed to fire again + checkForegroundTimerFired(false); } - private void checkFirstSessionSubsession(int subsessionCount) { - checkSubsession(1, subsessionCount); + public void testSendBackground() { + // assert test name to read better in logcat + mockLogger.Assert("TestActivityHandler testSendBackground"); + + AdjustFactory.setTimerInterval(4000); + + // create the config to start the session + AdjustConfig config = getConfig(); + + // enable send in the background + config.setSendInBackground(true); + + // create activity handler without starting + ActivityHandler activityHandler = getActivityHandler(config, + true, // startEnabled + null, // readActivityState + null, // readAttribution + false, // isProductionEnvironment + LogLevel.INFO); // logLevel + + SystemClock.sleep(2000); + + // handlers start sending + checkInitTests( + false, // eventBuffering + null, // defaultTracker + true); // startsSending + + startActivity(activityHandler); + + SystemClock.sleep(2000); + + // test session + checkFirstSession(); + + // end subsession + // background timer starts + stopActivity(activityHandler, + true, // checkLog, + false, // forgroundAlreadySuspended, + true); // backgroundTimerStarts + + SystemClock.sleep(1000); + + // session end does not pause the handlers + checkEndSession(false, //pausing + true, // updateActivityState + false); // eventBufferingEnabled + + // end subsession again + // to test if background timer starts again + stopActivity(activityHandler, + true, // checkLog, + true, // forgroundAlreadySuspended, + false); // backgroundTimerStarts + + SystemClock.sleep(1000); + + // session end does not pause the handlers + checkEndSession(false, //pausing + true, // updateActivityState + false); // eventBufferingEnabled + + // wait for background timer launch + SystemClock.sleep(3000); + + // background timer fired + assertUtil.test("PackageHandler sendFirstPackage"); + + // wait enough time + SystemClock.sleep(3000); + + // check that background timer does not fire again + assertUtil.notInTest("PackageHandler sendFirstPackage"); + + activityHandler.trackEvent(new AdjustEvent("abc123")); + + SystemClock.sleep(1000); + + // check that event package was added + assertUtil.test("PackageHandler addPackage"); + + // check that event was sent to package handler + assertUtil.test("PackageHandler sendFirstPackage"); + + // and not buffered + assertUtil.notInInfo("Buffered event"); + + // does fire background timer + assertUtil.verbose("Background timer starting. Launching in 4.0 seconds"); + + // after tracking the event it should write the activity state + assertUtil.debug("Wrote Activity state"); + + // disable and enable the sdk while in the background + activityHandler.setEnabled(false); + + // check that it is disabled + assertUtil.isFalse(activityHandler.isEnabled()); + + // check if message the disable of the SDK + assertUtil.info("Pausing package handler and attribution handler due to SDK being disabled"); + + SystemClock.sleep(1000); + + // handlers being paused because of the disable + checkHandlerStatus(true); + + activityHandler.setEnabled(true); + + // check that it is enabled + assertUtil.isTrue(activityHandler.isEnabled()); + + // check if message the enable of the SDK + assertUtil.info("Resuming package handler and attribution handler due to SDK being enabled"); + + SystemClock.sleep(1000); + + // handlers being resumed because of the enable + // even in the background because of the sendInBackground option + checkHandlerStatus(false); + + // set offline and online the sdk while in the background + activityHandler.setOfflineMode(true); + + InternalState internalState = activityHandler.getInternalState(); + + // check that it is offline + assertUtil.isTrue(internalState.isOffline()); + + // check if message the offline of the SDK + assertUtil.info("Pausing package and attribution handler to put SDK offline mode"); + + SystemClock.sleep(1000); + + // handlers being paused because of the offline + checkHandlerStatus(true); + + activityHandler.setOfflineMode(false); + + // check that it is online + assertUtil.isTrue(internalState.isOnline()); + + // check if message the online of the SDK + assertUtil.info("Resuming package handler and attribution handler to put SDK in online mode"); + + SystemClock.sleep(1000); + + // handlers being resumed because of the online + // even in the background because of the sendInBackground option + checkHandlerStatus(false); } - private void checkSubsession(int sessionCount, - int subsessionCount, - boolean timerAlreadyStarted, - boolean getAttributionIsCalled) { - checkSubsession(sessionCount, subsessionCount); + public void checkFinishTasks(AdjustConfig config, + DelegatesPresent delegatesPresent) + { + ActivityHandler activityHandler = startAndCheckFirstSession(config); - if (getAttributionIsCalled) { - assertUtil.test("AttributionHandler getAttribution"); + // test first session package + ActivityPackage firstSessionPackage = mockPackageHandler.queue.get(0); + + // create activity package test + TestActivityPackage testActivityPackage = new TestActivityPackage(firstSessionPackage); + + testActivityPackage.needsResponseDetails = + delegatesPresent.attributionDelegatePresent || + delegatesPresent.eventSuccessDelegatePresent || + delegatesPresent.eventFailureDelegatePresent || + delegatesPresent.sessionSuccessDelegatePresent || + delegatesPresent.sessionFailureDelegatePresent; + + // set first session + testActivityPackage.testSessionPackage(1); + + // simulate a successful session + SessionResponseData successSessionResponseData = (SessionResponseData) ResponseData.buildResponseData(firstSessionPackage); + successSessionResponseData.success = true; + + activityHandler.finishedTrackingActivity(successSessionResponseData); + SystemClock.sleep(1000); + + // attribution handler should always receive the session response + assertUtil.test("AttributionHandler checkSessionResponse"); + // the first session does not trigger the event response delegate + + assertUtil.notInDebug("Launching success event tracking listener"); + assertUtil.notInDebug("Launching failed event tracking listener"); + + activityHandler.launchSessionResponseTasks(successSessionResponseData); + SystemClock.sleep(1000); + + // if present, the first session triggers the success session delegate + if (delegatesPresent.sessionSuccessDelegatePresent) { + assertUtil.debug("Launching success session tracking listener"); } else { - assertUtil.notInTest("AttributionHandler getAttribution"); + assertUtil.notInDebug("Launching success session tracking delegate"); } + // it doesn't trigger the failure session delegate + assertUtil.notInDebug("Launching failed session tracking listener"); - checkTimerIsFired(!timerAlreadyStarted); - } + // simulate a failure session + SessionResponseData failureSessionResponseData = (SessionResponseData)ResponseData.buildResponseData(firstSessionPackage); + failureSessionResponseData.success = false; - private void checkSubsession(int sessionCount, int subsessionCount, boolean timerAlreadyStarted) { - checkSubsession(sessionCount, subsessionCount); + activityHandler.launchSessionResponseTasks(failureSessionResponseData); + SystemClock.sleep(1000); - checkTimerIsFired(!timerAlreadyStarted); - } + // it doesn't trigger the success session delegate + assertUtil.notInDebug("Launching success session tracking listener"); - private void checkSubsession(int sessionCount, int subsessionCount) { - // test the new sub session - assertUtil.test("PackageHandler resumeSending"); + // if present, the first session triggers the failure session delegate + if (delegatesPresent.sessionFailureDelegatePresent) { + assertUtil.debug("Launching failed session tracking listener"); + } else { + assertUtil.notInDebug("Launching failed session tracking listener"); + } + + // test success event response data + activityHandler.trackEvent(new AdjustEvent("abc123")); + SystemClock.sleep(1000); + + ActivityPackage eventPackage = mockPackageHandler.queue.get(1); + EventResponseData eventSuccessResponseData = (EventResponseData)ResponseData.buildResponseData(eventPackage); + eventSuccessResponseData.success = true; + + activityHandler.finishedTrackingActivity(eventSuccessResponseData); + SystemClock.sleep(1000); + + // attribution handler should never receive the event response + assertUtil.notInTest("AttributionHandler checkSessionResponse"); + + // if present, the success event triggers the success event delegate + if (delegatesPresent.eventSuccessDelegatePresent) { + assertUtil.debug("Launching success event tracking listener"); + } else { + assertUtil.notInDebug("Launching success event tracking listener"); + } + // it doesn't trigger the failure event delegate + assertUtil.notInDebug("Launching failed event tracking listener"); + + // test failure event response data + EventResponseData eventFailureResponseData = (EventResponseData)ResponseData.buildResponseData(eventPackage); + eventFailureResponseData.success = false; + + activityHandler.finishedTrackingActivity(eventFailureResponseData); + SystemClock.sleep(1000); - // save activity state - assertUtil.debug("Wrote Activity state: ec:0 sc:" + sessionCount + " ssc:" + subsessionCount); + // attribution handler should never receive the event response + assertUtil.notInTest("AttributionHandler checkSessionResponse"); - if (subsessionCount > 1) { - // test the subsession message - assertUtil.info("Started subsession " + subsessionCount + " of session " + sessionCount); + // if present, the failure event triggers the failure event delegate + if (delegatesPresent.eventFailureDelegatePresent) { + assertUtil.debug("Launching failed event tracking listener"); } else { - // test the subsession message - assertUtil.notInInfo("Started subsession "); + assertUtil.notInDebug("Launching failed event tracking listener"); } + // it doesn't trigger the success event delegate + assertUtil.notInDebug("Launching success event tracking listener"); + + // test click + Uri attributions = Uri.parse("AdjustTests://example.com/path/inApp?adjust_tracker=trackerValue&other=stuff&adjust_campaign=campaignValue&adjust_adgroup=adgroupValue&adjust_creative=creativeValue"); + long now = System.currentTimeMillis(); + + activityHandler.readOpenUrl(attributions, now); + SystemClock.sleep(1000); + + assertUtil.test("PackageHandler addPackage"); + assertUtil.test("PackageHandler sendFirstPackage"); + + // test sdk_click response data + ActivityPackage sdkClickPackage = mockSdkClickHandler.queue.get(0); + ClickResponseData clickResponseData = (ClickResponseData)ResponseData.buildResponseData(sdkClickPackage); + + activityHandler.finishedTrackingActivity(clickResponseData); + SystemClock.sleep(1000); + + // attribution handler should never receive the click response + assertUtil.notInTest("AttributionHandler checkSessionResponse"); + // it doesn't trigger the any event delegate + assertUtil.notInDebug("Launching success event tracking listener"); + assertUtil.notInDebug("Launching failed event tracking listener"); } - private void checkInitTests() { - checkInitTests("sandbox", "INFO", false, null, null); + private class DelegatesPresent { + boolean attributionDelegatePresent; + boolean eventSuccessDelegatePresent; + boolean eventFailureDelegatePresent; + boolean sessionSuccessDelegatePresent; + boolean sessionFailureDelegatePresent; + } + + private class SessionState { + boolean toSend = true; + boolean paused = false; + int sessionCount = 1; + int subsessionCount = 1; + SessionType sessionType = null; + int eventCount = 0; + Boolean getAttributionIsCalled = null; + Boolean timerAlreadyStarted = false; + boolean eventBufferingIsEnabled = false; + + SessionState(SessionType sessionType) { + switch (sessionType) { + case NEW_SUBSESSION: + case NONSESSION: + timerAlreadyStarted = true; + break; + } + this.sessionType = sessionType; + } } - private void checkInitTests(String environment, String logLevel, boolean eventBuffering) { - checkInitTests(environment, logLevel, eventBuffering, null, null); + private enum SessionType { + NEW_SESSION, + NEW_SUBSESSION, + TIME_TRAVEL, + NONSESSION; + } + + private void checkFirstSession() { + SessionState newSessionState = new SessionState(SessionType.NEW_SESSION); + checkStartInternal(newSessionState); + } + + private void checkSubSession(int sessionCount, int subsessionCount, boolean getAttributionIsCalled) { + SessionState subSessionState = new SessionState(SessionType.NEW_SUBSESSION); + subSessionState.sessionCount = sessionCount; + subSessionState.subsessionCount = subsessionCount; + subSessionState.getAttributionIsCalled = getAttributionIsCalled; + checkStartInternal(subSessionState); + } + + private void checkFurtherSessions(int sessionCount, boolean getAttributionIsCalled) { + SessionState subSessionState = new SessionState(SessionType.NEW_SESSION); + subSessionState.sessionCount = sessionCount; + subSessionState.timerAlreadyStarted = true; + subSessionState.getAttributionIsCalled = getAttributionIsCalled; + checkStartInternal(subSessionState); + + } + + private void checkStartDisable() { + assertUtil.notInTest("AttributionHandler resumeSending"); + assertUtil.notInTest("PackageHandler resumeSending"); + assertUtil.notInTest("SdkClickHandler resumeSending"); + assertUtil.notInTest("AttributionHandler pauseSending"); + assertUtil.notInTest("PackageHandler pauseSending"); + assertUtil.notInTest("SdkClickHandler pauseSending"); + assertUtil.notInTest("PackageHandler addPackage"); + assertUtil.notInTest("PackageHandler sendFirstPackage"); + assertUtil.notInVerbose("Started subsession"); + assertUtil.notInVerbose("Time span since last activity too short for a new subsession"); + assertUtil.notInError("Time travel!"); + assertUtil.notInDebug("Wrote Activity state: "); + assertUtil.notInTest("AttributionHandler getAttribution"); + checkForegroundTimerFired(false); } - private void checkInitTests(String environment, String logLevel, boolean eventBuffering, - String readActivityState, String readAttribution) { - // check environment level - if (environment == "sandbox") { - assertUtil.Assert("SANDBOX: Adjust is running in Sandbox mode. Use this setting for testing. Don't forget to set the environment to `production` before publishing!"); - } else if (environment == "production") { - assertUtil.Assert("PRODUCTION: Adjust is running in Production mode. Use this setting only for the build that you want to publish. Set the environment to `sandbox` if you want to test your app!"); + private void checkStartInternal(SessionState sessionState) + { + // update Handlers Status + checkHandlerStatus(!sessionState.toSend, sessionState.eventBufferingIsEnabled); + + // process Session + switch (sessionState.sessionType) { + case NEW_SESSION: + // if the package was build, it was sent to the Package Handler + assertUtil.test("PackageHandler addPackage"); + + // after adding, the activity handler ping the Package handler to send the package + assertUtil.test("PackageHandler sendFirstPackage"); + break; + case NEW_SUBSESSION: + // test the subsession message + assertUtil.verbose("Started subsession " + sessionState.subsessionCount + " of session " + sessionState.sessionCount); + break; + case NONSESSION: + // stopped for a short time, not enough for a new sub subsession + assertUtil.verbose("Time span since last activity too short for a new subsession"); + break; + case TIME_TRAVEL: + assertUtil.error("Time travel!"); + break; + } + + // after processing the session, writes the activity state + if (sessionState.sessionType != SessionType.NONSESSION) { + assertUtil.debug("Wrote Activity state: " + + "ec:" + sessionState.eventCount + " sc:" + sessionState.sessionCount + " ssc:" + sessionState.subsessionCount); + } + // check Attribution State + if (sessionState.getAttributionIsCalled != null) { + if (sessionState.getAttributionIsCalled) { + assertUtil.test("AttributionHandler getAttribution"); + } else { + assertUtil.notInTest("AttributionHandler getAttribution"); + } + } + + /* + // start Foreground Timer + if (sessionState.paused) { + // foreground timer doesn't start when it's paused + assertUtil.notInDebug("Foreground timer started"); + checkForegroundTimerFired(false); + } else if (sessionState.timerAlreadyStarted != null) { + checkForegroundTimerFired(!sessionState.timerAlreadyStarted); + } + */ + } +/* + private void checkInitAndFirstSession() { + SessionState newSessionState = new SessionState(SessionType.NEW_SESSION); + checkInitAndFirstSession(newSessionState); + } + + private void checkInitAndFirstSession(SessionState sessionState) { + checkInitTests(sessionState.toSend); + checkStartInternal(sessionState); + } +*/ + private void checkForegroundTimerFired(boolean timerFired) { + // timer fired + if (timerFired) { + assertUtil.verbose("Foreground timer fired"); } else { - fail(); + assertUtil.notInVerbose("Foreground timer fired"); } + } - // check log level - assertUtil.test("MockLogger setLogLevel: " + logLevel); + private void checkInitTests() { + checkInitTests(false); + } + + private void checkInitTests(boolean startsSending) { + checkInitTests(false, null, startsSending); + } + + private void checkInitTests(boolean eventBuffering, + String defaultTracker, + boolean startsSending) + { // check event buffering if (eventBuffering) { assertUtil.info("Event buffering is enabled"); @@ -1748,114 +2232,257 @@ private void checkInitTests(String environment, String logLevel, boolean eventBu } // check Google play is not set - assertUtil.info("Unable to get Google Play Services Advertising ID at start time"); - - checkReadFiles(readActivityState, readAttribution); - } + assertUtil.info("Google Play Services Advertising ID read correctly at start time"); - private void checkReadFiles(String readActivityState, String readAttribution) { - if (readAttribution == null) { - // test that the attribution file did not exist in the first run of the application - assertUtil.verbose("Attribution file not found"); - } else { - assertUtil.debug("Read Attribution: " + readAttribution); + // check default tracker + if (defaultTracker != null) { + assertUtil.info("Default tracker: '%s'", defaultTracker); } - if (readActivityState == null) { - // test that the activity state file did not exist in the first run of the application - assertUtil.verbose("Activity state file not found"); + if (startsSending) { + assertUtil.test("PackageHandler init, startsSending: true"); + assertUtil.test("AttributionHandler init, startsSending: true"); + assertUtil.test("SdkClickHandler init, startsSending: true"); } else { - assertUtil.debug("Read Activity state: " + readActivityState); + assertUtil.test("PackageHandler init, startsSending: false"); + assertUtil.test("AttributionHandler init, startsSending: false"); + assertUtil.test("SdkClickHandler init, startsSending: false"); } } - private void checkFirstSession() { - checkFirstSession(false); + private void checkEndSession() { + checkEndSession(true); + } + + private void checkEndSession(boolean updateActivityState) { + checkEndSession(true, updateActivityState, false); } - private void checkFirstSession(boolean paused) { - if (paused) { - assertUtil.test("PackageHandler init, startPaused: true"); + private void checkEndSession(boolean pausing, boolean updateActivityState, boolean eventBufferingEnabled) { + if (pausing) { + checkHandlerStatus(true, eventBufferingEnabled); + } + + if (updateActivityState) { + assertUtil.debug("Wrote Activity state: "); } else { - assertUtil.test("PackageHandler init, startPaused: false"); + assertUtil.notInDebug("Wrote Activity state: "); } + } + - checkNewSession(paused, 1, 0, false); + private AdjustConfig getConfig() { + return getConfig(null); } - private void checkNewSession(boolean paused, - int sessionCount, - int eventCount) { - checkNewSession(paused, sessionCount, eventCount, false); + private AdjustConfig getConfig(LogLevel logLevel) { + return getConfig(logLevel, "sandbox", "123456789012", context); } - private void checkNewSession(boolean paused, - int sessionCount, - int eventCount, - boolean timerAlreadyStarted) + private AdjustConfig getConfig(LogLevel logLevel, + String environment, + String appToken, + Context context) { - // when a session package is being sent the attribution handler should resume sending - if (paused) { - assertUtil.test("AttributionHandler pauseSending"); - } else { - assertUtil.test("AttributionHandler resumeSending"); - } + AdjustConfig adjustConfig = new AdjustConfig(context, appToken, environment); + + if (adjustConfig != null) { + if (environment == "sandbox") { + assertUtil.Assert("SANDBOX: Adjust is running in Sandbox mode. Use this setting for testing. Don't forget to set the environment to `production` before publishing!"); + } else if (environment == "production") { + assertUtil.Assert("PRODUCTION: Adjust is running in Production mode. Use this setting only for the build that you want to publish. Set the environment to `sandbox` if you want to test your app!"); + } else { + fail(); + } - // when a session package is being sent the package handler should resume sending - if (paused) { - assertUtil.test("PackageHandler pauseSending"); - } else { - assertUtil.test("PackageHandler resumeSending"); + if (logLevel != null) { + adjustConfig.setLogLevel(logLevel); + } } - // if the package was build, it was sent to the Package Handler - assertUtil.test("PackageHandler addPackage"); + return adjustConfig; + } - // after adding, the activity handler ping the Package handler to send the package - assertUtil.test("PackageHandler sendFirstPackage"); + private ActivityHandler getFirstActivityHandler(AdjustConfig config) { + return getActivityHandler(config, true, null, null, false, LogLevel.INFO); + } + + private ActivityHandler getFirstActivityHandler(AdjustConfig config, + LogLevel logLevel) { + return getActivityHandler(config, true, null, null, false, logLevel); + } - // after sending a package saves the activity state - assertUtil.debug("Wrote Activity state: " + - "ec:" + eventCount + " sc:" + sessionCount + " ssc:1" ); + private ActivityHandler getActivityHandler(AdjustConfig config, + boolean startEnabled, + String readActivityState, + String readAttribution, + boolean isProductionEnvironment, + LogLevel logLevel) { + ActivityHandler activityHandler = ActivityHandler.getInstance(config); + + if (activityHandler != null) { + // check log level + if (isProductionEnvironment) { + assertUtil.test("MockLogger setLogLevel: " + LogLevel.ASSERT); + } else { + assertUtil.test("MockLogger setLogLevel: " + logLevel); + } - checkTimerIsFired(!(paused || timerAlreadyStarted)); + // check if files are read in constructor + checkReadFiles(readActivityState, readAttribution); + + InternalState internalState = activityHandler.getInternalState(); + // test default values + assertUtil.isEqual(startEnabled, internalState.isEnabled()); + assertUtil.isTrue(internalState.isOnline()); + assertUtil.isTrue(internalState.isBackground()); + } + + return activityHandler; } - private void checkInitAndFirstSession() { + private ActivityHandler startAndCheckFirstSession(AdjustConfig config) { + return startAndCheckFirstSession(config, LogLevel.INFO); + } + + private ActivityHandler startAndCheckFirstSession(AdjustConfig config, LogLevel logLevel) { + // start activity handler with config + ActivityHandler activityHandler = getFirstActivityHandler(config, logLevel); + + SystemClock.sleep(2000); + + // test init values checkInitTests(); + + startActivity(activityHandler); + + SystemClock.sleep(2000); + + // test session checkFirstSession(); + + return activityHandler; } - private void checkTimerIsFired(boolean timerFired) { - // timer fired - if (timerFired) { - assertUtil.debug("Session timer fired"); - } else { - assertUtil.notInDebug("Session timer fired"); + private void startActivity(ActivityHandler activityHandler) { + startActivity(activityHandler, true); + } + + private void startActivity(ActivityHandler activityHandler, boolean checkLog) { + startActivity(activityHandler, checkLog, true, false); + } + + private void startActivity(ActivityHandler activityHandler, + boolean checkLog, + boolean foregroundTimerStarts, + boolean foregroundTimerAlreadyStarted) { + // start activity + activityHandler.onResume(); + + InternalState internalState = activityHandler.getInternalState(); + + // comes to the foreground + assertUtil.isTrue(internalState.isForeground()); + + if (checkLog) { + // stops background timer + assertUtil.verbose("Background timer canceled"); + + // start foreground timer + if (foregroundTimerStarts) { + if (foregroundTimerAlreadyStarted) { + assertUtil.verbose("Foreground timer is already started"); + } else { + assertUtil.verbose("Foreground timer starting"); + } + } else { + assertUtil.notInVerbose("Foreground timer is already started"); + assertUtil.notInVerbose("Foreground timer starting"); + } + + // starts the subsession + assertUtil.verbose("Subsession start"); } } - private void checkEndSession() { - checkEndSession(true); + private void stopActivity(ActivityHandler activityHandler) { + stopActivity(activityHandler, false, false, false); } - private void checkEndSession(boolean updateActivityState) { - assertUtil.test("PackageHandler pauseSending"); + private void stopActivity(ActivityHandler activityHandler, + boolean checkLog, + boolean forgroundAlreadySuspended, + boolean backgroundTimerStarts) { + // stop activity + activityHandler.onPause(); - assertUtil.test("AttributionHandler pauseSending"); + InternalState internalState = activityHandler.getInternalState(); - if (updateActivityState) { - assertUtil.debug("Wrote Activity state: "); + // goes to the background + assertUtil.isTrue(internalState.isBackground()); + + if (checkLog) { + // stop foreground timer + if (forgroundAlreadySuspended) { + assertUtil.verbose("Foreground timer is already suspended"); + } else { + assertUtil.verbose("Foreground timer suspended"); + } + + // start background timer + if (backgroundTimerStarts) { + assertUtil.verbose("Background timer starting."); + } else { + assertUtil.notInVerbose("Background timer starting."); + } + + // starts the subsession + assertUtil.verbose("Subsession end"); } } - private ActivityHandler getActivityHandler(AdjustConfig config) { - ActivityHandler activityHandler = ActivityHandler.getInstance(config); + private void checkReadFiles(String readActivityState, String readAttribution) { + if (readAttribution == null) { + // test that the attribution file did not exist in the first run of the application + assertUtil.debug("Attribution file not found"); + } else { + assertUtil.debug("Read Attribution: " + readAttribution); + } - if (activityHandler != null) { - activityHandler.trackSubsessionStart(); + if (readActivityState == null) { + // test that the activity state file did not exist in the first run of the application + assertUtil.debug("Activity state file not found"); + } else { + assertUtil.debug("Read Activity state: " + readActivityState); } + } - return activityHandler; + private void checkHandlerStatus(Boolean pausing) { + checkHandlerStatus(pausing, false); + } + + + private void checkHandlerStatus(Boolean pausing, boolean eventBufferingEnabled) { + if (pausing == null) { + assertUtil.notInTest("AttributionHandler pauseSending"); + assertUtil.notInTest("PackageHandler pauseSending"); + assertUtil.notInTest("SdkClickHandler pauseSending"); + assertUtil.notInTest("AttributionHandler resumeSending"); + assertUtil.notInTest("PackageHandler resumeSending"); + assertUtil.notInTest("SdkClickHandler resumeSending"); + return; + } + if (pausing) { + assertUtil.test("AttributionHandler pauseSending"); + assertUtil.test("PackageHandler pauseSending"); + assertUtil.test("SdkClickHandler pauseSending"); + } else { + assertUtil.test("AttributionHandler resumeSending"); + assertUtil.test("PackageHandler resumeSending"); + assertUtil.test("SdkClickHandler resumeSending"); + if (!eventBufferingEnabled) { + assertUtil.test("PackageHandler sendFirstPackage"); + } + } } } diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestActivityPackage.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestActivityPackage.java index 464e08434..fd0f12518 100644 --- a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestActivityPackage.java +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestActivityPackage.java @@ -24,6 +24,7 @@ public class TestActivityPackage { public Boolean deviceKnow; public boolean needsResponseDetails; public boolean playServices; + public boolean eventBufferingEnabled; // session public Integer sessionCount; public String defaultTracker; @@ -38,9 +39,10 @@ public class TestActivityPackage { public String partnerParams; // click public String reftag; - public String deepLinkParameters; + public String otherParameters; public AdjustAttribution attribution; public String referrer; + public String deeplink; public TestActivityPackage(ActivityPackage activityPackage) { this.activityPackage = activityPackage; @@ -52,6 +54,7 @@ public TestActivityPackage(ActivityPackage activityPackage) { clientSdk = "android4.6.0"; suffix = ""; attribution = new AdjustAttribution(); + playServices = true; } public void testSessionPackage(int sessionCount) { @@ -129,12 +132,16 @@ public void testClickPackage(String source) { if (source == Constants.REFTAG) { assertParameterEquals("referrer", referrer); - } else { + assertParameterNull("deeplink"); + } else if (source == Constants.DEEPLINK) { + assertParameterEquals("deeplink", deeplink); assertParameterNull("referrer"); + } else { + assertFail(); } // params - assertJsonParameterEquals("params", deepLinkParameters); + assertJsonParameterEquals("params", otherParameters); // click_time // TODO add string click time to compare @@ -160,6 +167,41 @@ public void testAttributionPackage() { testDeviceIdsParameters(); } + public static void testQueryStringRequest(String queryStringRequest, Integer queueSize) { + String[] queryPairs = queryStringRequest.split("&"); + boolean wasSentAtFound = false; + boolean wasQueueSizeFound = false; + int queueSizeFound = -1; + + for (String pair : queryPairs) { + String[] pairComponents = pair.split("="); + String key = pairComponents[0]; + String value = pairComponents[1]; + if (key.equals("sent_at")) { + wasSentAtFound = true; + } + if (key.equals("queue_size")) { + wasQueueSizeFound = true; + queueSizeFound = Integer.parseInt(value); + } + } + if (!wasSentAtFound) { + Assert.fail(queryStringRequest); + } + + if (queueSize == null) { + Assert.assertFalse(queryStringRequest, wasQueueSizeFound); + return; + } + + if (!wasQueueSizeFound) { + Assert.fail(queryStringRequest); + } else { + Assert.assertEquals(queryStringRequest, + queueSize.intValue(), queueSizeFound); + } + } + private void testDefaultAttributes(String path, ActivityKind activityKind, String activityKindString) { // check the Sdk version is being tested assertEquals(activityPackage.getClientSdk(), clientSdk); @@ -225,6 +267,10 @@ private void testDeviceInfo() { assertParameterNotNull("display_width"); // display_height assertParameterNotNull("display_height"); + // hardware_name + assertParameterNotNull("hardware_name"); + // cpu_type + assertParameterNotNull("cpu_type"); } private void testDeviceInfoIds() { @@ -267,6 +313,7 @@ private void testConfig() { // tracking_enabled assertParameterNull("tracking_enabled"); } + testParameterBoolean("event_buffering_enabled", eventBufferingEnabled); } private void testActivityState() { diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestAttributionHandler.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestAttributionHandler.java index b906ea7be..04f4a4dca 100644 --- a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestAttributionHandler.java +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestAttributionHandler.java @@ -47,7 +47,7 @@ protected void setUp() throws Exception { AdjustFactory.setLogger(mockLogger); AdjustFactory.setActivityHandler(mockActivityHandler); - AdjustFactory.setMockHttpsURLConnection(mockHttpsURLConnection); + AdjustFactory.setHttpsURLConnection(mockHttpsURLConnection); activity = getActivity(); context = activity.getApplicationContext(); @@ -95,7 +95,7 @@ private void savePackages() { protected void tearDown() throws Exception { super.tearDown(); - AdjustFactory.setMockHttpsURLConnection(null); + AdjustFactory.setHttpsURLConnection(null); AdjustFactory.setActivityHandler(null); AdjustFactory.setLogger(null); @@ -108,7 +108,7 @@ public void testGetAttribution() { mockLogger.Assert("TestAttributionHandler testGetAttribution"); AttributionHandler attributionHandler = new AttributionHandler(mockActivityHandler, - attributionPackage, false, true); + attributionPackage, true, true); // test null client nullClientTest(attributionHandler); @@ -127,7 +127,6 @@ public void testGetAttribution() { // test ok response with message okMessageTest(attributionHandler); - } public void testCheckSessionResponse() { @@ -135,7 +134,7 @@ public void testCheckSessionResponse() { mockLogger.Assert("TestAttributionHandler testCheckSessionResponse"); AttributionHandler attributionHandler = new AttributionHandler(mockActivityHandler, - attributionPackage, false, true); + attributionPackage, true, true); // new attribution JSONObject attributionJson = null; @@ -177,7 +176,7 @@ public void testAskIn() { mockLogger.Assert("TestAttributionHandler testAskIn"); AttributionHandler attributionHandler = new AttributionHandler(mockActivityHandler, - attributionPackage, false, true); + attributionPackage, true, true); String response = "Response: { \"ask_in\" : 4000 }"; @@ -208,7 +207,7 @@ public void testAskIn() { assertUtil.test("ActivityHandler setAskingAttribution, true"); // and waited to for query - assertUtil.debug("Waiting to query attribution in 4000 milliseconds"); + assertUtil.debug("Waiting to query attribution in 4.0 seconds"); SystemClock.sleep(2000); @@ -229,7 +228,7 @@ public void testAskIn() { assertUtil.test("ActivityHandler setAskingAttribution, true"); // and waited to for query - assertUtil.debug("Waiting to query attribution in 5000 milliseconds"); + assertUtil.debug("Waiting to query attribution in 5.0 seconds"); // it was been waiting for 1000 + 2000 + 3000 = 6 seconds // check that the mock http client was not called because the original clock was reseted @@ -238,7 +237,7 @@ public void testAskIn() { // check that it was finally called after 6 seconds after the second ask_in SystemClock.sleep(4000); - okMessageTestLogs(); + okMessageTestLogs(attributionHandler); //requestTest(mockHttpClient.lastRequest); } @@ -248,7 +247,7 @@ public void testPause() { mockLogger.Assert("TestAttributionHandler testPause"); AttributionHandler attributionHandler = new AttributionHandler(mockActivityHandler, - attributionPackage, true, true); + attributionPackage, false, true); mockHttpsURLConnection.responseType = ResponseType.MESSAGE; @@ -270,7 +269,7 @@ public void testWithoutListener() { mockLogger.Assert("TestAttributionHandler testPause"); AttributionHandler attributionHandler = new AttributionHandler(mockActivityHandler, - attributionPackage, false, false); + attributionPackage, true, false); mockHttpsURLConnection.responseType = ResponseType.MESSAGE; @@ -349,10 +348,12 @@ private void serverErrorTest(AttributionHandler attributionHandler) { private void okMessageTest(AttributionHandler attributionHandler) { startGetAttributionTest(attributionHandler, ResponseType.MESSAGE); - okMessageTestLogs(); + okMessageTestLogs(attributionHandler); } - private void okMessageTestLogs() { + private void okMessageTestLogs(AttributionHandler attributionHandler) { + TestActivityPackage.testQueryStringRequest(attributionHandler.lastUrlUsed.getQuery(), null); + // check that the mock http client was called assertUtil.test("MockHttpsURLConnection getInputStream"); diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestPackageHandler.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestPackageHandler.java index c7f805eed..f8963aae0 100644 --- a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestPackageHandler.java +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestPackageHandler.java @@ -7,10 +7,15 @@ import com.adjust.sdk.ActivityKind; import com.adjust.sdk.ActivityPackage; import com.adjust.sdk.AdjustFactory; +import com.adjust.sdk.BackoffStrategy; +import com.adjust.sdk.Constants; import com.adjust.sdk.PackageHandler; import com.adjust.sdk.ResponseData; import com.adjust.sdk.UnknownResponseData; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * Created by pfms on 30/01/15. */ @@ -83,19 +88,22 @@ public void testAddPackage() { secondPackageHandler.sendFirstPackage(); SystemClock.sleep(1000); - assertUtil.test("RequestHandler sendPackage, clickFirstPackage"); + assertUtil.test("RequestHandler sendPackage, activityPackage clickFirstPackage"); + assertUtil.test("RequestHandler sendPackage, queueSize 2"); // send the second click package/ third package secondPackageHandler.sendNextPackage(null); SystemClock.sleep(1000); - assertUtil.test("RequestHandler sendPackage, clickThirdPackage"); + assertUtil.test("RequestHandler sendPackage, activityPackage unknownSecondPackage"); + assertUtil.test("RequestHandler sendPackage, queueSize 1"); // send the unknow package/ second package secondPackageHandler.sendNextPackage(null); SystemClock.sleep(1000); - assertUtil.test("RequestHandler sendPackage, unknownSecondPackage"); + assertUtil.test("RequestHandler sendPackage, activityPackage clickThirdPackage"); + assertUtil.test("RequestHandler sendPackage, queueSize 0"); } public void testSendFirst() { @@ -107,7 +115,7 @@ public void testSendFirst() { packageHandler.sendFirstPackage(); SystemClock.sleep(1000); - sendFirstTests(SendFirstState.EMPTY_QUEUE, null); + sendFirstTests(SendFirstState.EMPTY_QUEUE, null, null); addAndSendFirstPackageTest(packageHandler); @@ -115,30 +123,30 @@ public void testSendFirst() { packageHandler.sendFirstPackage(); SystemClock.sleep(1000); - sendFirstTests(SendFirstState.IS_SENDING, null); + sendFirstTests(SendFirstState.IS_SENDING, null, null); // try to send paused packageHandler.pauseSending(); packageHandler.sendFirstPackage(); SystemClock.sleep(1000); - sendFirstTests(SendFirstState.PAUSED, null); + sendFirstTests(SendFirstState.PAUSED, null, null); // unpause, it's still sending packageHandler.resumeSending(); packageHandler.sendFirstPackage(); SystemClock.sleep(1000); - sendFirstTests(SendFirstState.IS_SENDING, null); + sendFirstTests(SendFirstState.IS_SENDING, null, null); // verify that both paused and isSending are reset with a new session - PackageHandler secondSessionPackageHandler = new PackageHandler(mockActivityHandler, context, false); + PackageHandler secondSessionPackageHandler = new PackageHandler(mockActivityHandler, context, true); secondSessionPackageHandler.sendFirstPackage(); SystemClock.sleep(1000); // send the package to request handler - sendFirstTests(SendFirstState.SEND, "unknownFirstPackage"); + sendFirstTests(SendFirstState.SEND, "unknownFirstPackage", 0); } public void testSendNext() { @@ -155,7 +163,7 @@ public void testSendNext() { packageHandler.sendFirstPackage(); SystemClock.sleep(1000); - sendFirstTests(SendFirstState.IS_SENDING, null); + sendFirstTests(SendFirstState.IS_SENDING, null, null); // add a second package addSecondPackageTest(packageHandler); @@ -167,12 +175,13 @@ public void testSendNext() { assertUtil.debug("Package handler wrote 1 packages"); // try to send the second package - sendFirstTests(SendFirstState.SEND, "unknownSecondPackage"); + sendFirstTests(SendFirstState.SEND, "unknownSecondPackage", 0); } public void testCloseFirstPackage() { // assert test name to read better in logcat mockLogger.Assert("TestPackageHandler testCloseFirstPackage"); + AdjustFactory.setPackageHandlerBackoffStrategy(BackoffStrategy.NO_WAIT); PackageHandler packageHandler = startPackageHandler(); @@ -182,39 +191,138 @@ public void testCloseFirstPackage() { packageHandler.sendFirstPackage(); SystemClock.sleep(1000); - sendFirstTests(SendFirstState.IS_SENDING, null); + sendFirstTests(SendFirstState.IS_SENDING, null, null); //send next package ActivityPackage activityPackage = new ActivityPackage(ActivityKind.UNKNOWN); UnknownResponseData unknownResponseData = (UnknownResponseData) ResponseData.buildResponseData(activityPackage); - packageHandler.closeFirstPackage(unknownResponseData); + packageHandler.closeFirstPackage(unknownResponseData, null); SystemClock.sleep(2000); + assertUtil.verbose("Package handler can send"); + assertUtil.test("ActivityHandler finishedTrackingActivity, message:null timestamp:null json:null"); assertUtil.notInDebug("Package handler wrote"); - packageHandler.sendFirstPackage(); - SystemClock.sleep(2000); + // tries to send the next package after sleeping + sendFirstTests(SendFirstState.SEND, "unknownFirstPackage", 0); + } + + public void testBackoffJitter() { + // assert test name to read better in logcat + mockLogger.Assert("TestPackageHandler testBackoffJitter"); + + AdjustFactory.setPackageHandlerBackoffStrategy(BackoffStrategy.TEST_WAIT); + + PackageHandler packageHandler = startPackageHandler(); + + ActivityPackage activityPackage = new ActivityPackage(ActivityKind.UNKNOWN); + UnknownResponseData unknownResponseData = (UnknownResponseData) ResponseData.buildResponseData(activityPackage); + Pattern pattern = Pattern.compile("Sleeping for (\\d+\\.\\d) seconds before retrying the (\\d+) time"); + + // 1st + packageHandler.closeFirstPackage(unknownResponseData, activityPackage); + SystemClock.sleep(1500); + + String matchingString = assertUtil.verbose("Sleeping for "); + // Sleeping for 0.1 seconds before retrying the 1 time + + checkSleeping(pattern, matchingString, 0.1, 0.2, 1, 0.5, 1); + + // 2nd + packageHandler.closeFirstPackage(unknownResponseData, activityPackage); + SystemClock.sleep(1500); + + matchingString = assertUtil.verbose("Sleeping for "); + + checkSleeping(pattern, matchingString, 0.2, 0.4, 1, 0.5, 2); + + // 3rd + packageHandler.closeFirstPackage(unknownResponseData, activityPackage); + SystemClock.sleep(1500); + + matchingString = assertUtil.verbose("Sleeping for "); + + checkSleeping(pattern, matchingString, 0.4, 0.8, 1, 0.5, 3); + + // 4th + packageHandler.closeFirstPackage(unknownResponseData, activityPackage); + SystemClock.sleep(1500); + + matchingString = assertUtil.verbose("Sleeping for "); + + checkSleeping(pattern, matchingString, 0.8, 1.6, 1, 0.5, 4); + + // 5th + packageHandler.closeFirstPackage(unknownResponseData, activityPackage); + SystemClock.sleep(1500); + + matchingString = assertUtil.verbose("Sleeping for "); + + checkSleeping(pattern, matchingString, 1.6, 3.2, 1, 0.5, 5); + + // 6th + packageHandler.closeFirstPackage(unknownResponseData, activityPackage); + SystemClock.sleep(1500); + + matchingString = assertUtil.verbose("Sleeping for "); + + checkSleeping(pattern, matchingString, 6.4, 12.8, 1, 0.5, 6); + } + + private void checkSleeping(Pattern pattern, + String sleepingLog, + double minRange, + double maxRange, + long maxCeiling, + double minCeiling, + int numberRetries) + { + Matcher matcher = pattern.matcher(sleepingLog); + + if (!matcher.matches()) { + assertUtil.fail(); + } + Double sleepingTime = Double.valueOf(matcher.group(1)); + + boolean failsCeiling = sleepingTime > maxCeiling; + assertUtil.isFalse(failsCeiling); + + if (maxRange < maxCeiling) { + boolean failsMinRange = sleepingTime < minRange; + assertUtil.isFalse(failsMinRange); + } else { + boolean failsMinRange = sleepingTime < minCeiling ; + assertUtil.isFalse(failsMinRange); + } + + if (maxRange < maxCeiling) { + boolean failsMaxRange = sleepingTime > maxRange; + assertUtil.isFalse(failsMaxRange); + } else { + boolean failsMaxRange = sleepingTime > maxCeiling; + assertUtil.isFalse(failsMaxRange); + } - // try to send the first package again - sendFirstTests(SendFirstState.SEND, "unknownFirstPackage"); + Integer retryTime = Integer.valueOf(matcher.group(2)); + assertUtil.isEqual(numberRetries, retryTime); } private PackageHandler startPackageHandler() { // delete package queue for fresh start deletePackageQueue(); - PackageHandler packageHandler = new PackageHandler(mockActivityHandler, context, false); + PackageHandler packageHandler = new PackageHandler(mockActivityHandler, context, true); SystemClock.sleep(1000); - assertUtil.verbose("Package queue file not found"); + assertUtil.debug("Package queue file not found"); return packageHandler; } private PackageHandler addSecondPackageTest(PackageHandler packageHandler) { if (packageHandler == null) { - packageHandler = new PackageHandler(mockActivityHandler, context, false); + packageHandler = new PackageHandler(mockActivityHandler, context, true); SystemClock.sleep(1000); @@ -251,14 +359,14 @@ private void addAndSendFirstPackageTest(PackageHandler packageHandler) { addPackageTests(1, "unknownFirstPackage"); - sendFirstTests(SendFirstState.SEND, "unknownFirstPackage"); + sendFirstTests(SendFirstState.SEND, "unknownFirstPackage", 0); } private enum SendFirstState { EMPTY_QUEUE, PAUSED, IS_SENDING, SEND } - private void sendFirstTests(SendFirstState sendFirstState, String packageString) { + private void sendFirstTests(SendFirstState sendFirstState, String packageString, Integer queueSize) { if (sendFirstState == SendFirstState.PAUSED) { assertUtil.debug("Package handler is paused"); } else { @@ -272,7 +380,8 @@ private void sendFirstTests(SendFirstState sendFirstState, String packageString) } if (sendFirstState == SendFirstState.SEND) { - assertUtil.test("RequestHandler sendPackage, " + packageString); + assertUtil.test("RequestHandler sendPackage, activityPackage " + packageString); + assertUtil.test("RequestHandler sendPackage, queueSize " + queueSize); } else { assertUtil.notInTest("RequestHandler sendPackage"); } diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestRequestHandler.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestRequestHandler.java index 3ce918590..81c89d7d5 100644 --- a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestRequestHandler.java +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestRequestHandler.java @@ -43,7 +43,7 @@ protected void setUp() throws Exception { AdjustFactory.setLogger(mockLogger); AdjustFactory.setPackageHandler(mockPackageHandler); - AdjustFactory.setMockHttpsURLConnection(mockHttpsURLConnection); + AdjustFactory.setHttpsURLConnection(mockHttpsURLConnection); activity = getActivity(); context = activity.getApplicationContext(); @@ -55,7 +55,7 @@ protected void setUp() throws Exception { protected void tearDown() throws Exception { super.tearDown(); - AdjustFactory.setMockHttpsURLConnection(null); + AdjustFactory.setHttpsURLConnection(null); AdjustFactory.setPackageHandler(null); AdjustFactory.setLogger(null); } @@ -101,14 +101,14 @@ public void testTimeout() { private void nullResponseTest() { mockHttpsURLConnection.responseType = null; - requestHandler.sendPackage(sessionPackage); + requestHandler.sendPackage(sessionPackage, -1); SystemClock.sleep(1000); assertUtil.test("MockHttpsURLConnection getInputStream, responseType: null"); - assertUtil.error("Failed to read response. (lock == null)"); + assertUtil.error("Failed to read response. (null)"); - assertUtil.error("Failed to track session. (Runtime exception: java.lang.NullPointerException: lock == null)"); + assertUtil.error("Failed to track session. (Runtime exception: java.lang.NullPointerException)"); assertUtil.test("PackageHandler sendNextPackage"); } @@ -116,7 +116,7 @@ private void nullResponseTest() { private void clientExceptionTest() { mockHttpsURLConnection.responseType = ResponseType.CLIENT_PROTOCOL_EXCEPTION; - requestHandler.sendPackage(sessionPackage); + requestHandler.sendPackage(sessionPackage, -1); SystemClock.sleep(1000); assertUtil.test("MockHttpsURLConnection getInputStream, responseType: CLIENT_PROTOCOL_EXCEPTION"); @@ -129,7 +129,7 @@ private void clientExceptionTest() { private void serverErrorTest() { mockHttpsURLConnection.responseType = ResponseType.INTERNAL_SERVER_ERROR; - requestHandler.sendPackage(sessionPackage); + requestHandler.sendPackage(sessionPackage, -1); SystemClock.sleep(1000); assertUtil.test("MockHttpsURLConnection getErrorStream, responseType: INTERNAL_SERVER_ERROR"); @@ -144,7 +144,7 @@ private void serverErrorTest() { private void wrongJsonTest() { mockHttpsURLConnection.responseType = ResponseType.WRONG_JSON; - requestHandler.sendPackage(sessionPackage); + requestHandler.sendPackage(sessionPackage, -1); SystemClock.sleep(1000); assertUtil.test("MockHttpsURLConnection getInputStream, responseType: WRONG_JSON"); @@ -159,7 +159,7 @@ private void wrongJsonTest() { private void emptyJsonTest() { mockHttpsURLConnection.responseType = ResponseType.EMPTY_JSON; - requestHandler.sendPackage(sessionPackage); + requestHandler.sendPackage(sessionPackage, -1); SystemClock.sleep(1000); assertUtil.test("MockHttpsURLConnection getInputStream, responseType: EMPTY_JSON"); @@ -174,10 +174,10 @@ private void emptyJsonTest() { private void messageTest() { mockHttpsURLConnection.responseType = ResponseType.MESSAGE; - requestHandler.sendPackage(sessionPackage); + requestHandler.sendPackage(sessionPackage, 1); SystemClock.sleep(1000); - mockLogger.test(mockHttpsURLConnection.readRequest()); + TestActivityPackage.testQueryStringRequest(mockHttpsURLConnection.readRequest(), 1); assertUtil.test("MockHttpsURLConnection getInputStream, responseType: MESSAGE"); diff --git a/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestSdkClickHandler.java b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestSdkClickHandler.java new file mode 100644 index 000000000..a95f938c2 --- /dev/null +++ b/Adjust/test/src/androidTest/java/com/adjust/sdk/test/TestSdkClickHandler.java @@ -0,0 +1,318 @@ +package com.adjust.sdk.test; + +import android.content.Context; +import android.net.Uri; +import android.os.SystemClock; +import android.test.ActivityInstrumentationTestCase2; + +import com.adjust.sdk.ActivityHandler; +import com.adjust.sdk.ActivityPackage; +import com.adjust.sdk.AdjustConfig; +import com.adjust.sdk.AdjustFactory; +import com.adjust.sdk.BackoffStrategy; +import com.adjust.sdk.SdkClickHandler; + +/** + * Created by pfms on 14/04/16. + */ +public class TestSdkClickHandler extends ActivityInstrumentationTestCase2 { + private MockLogger mockLogger; + private AssertUtil assertUtil; + private MockHttpsURLConnection mockHttpsURLConnection; + private UnitTestActivity activity; + private Context context; + private ActivityPackage sdkClickPackage; + + public TestSdkClickHandler() { + super(UnitTestActivity.class); + } + + public TestSdkClickHandler(Class activityClass) { + super(activityClass); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + mockLogger = new MockLogger(); + mockHttpsURLConnection = new MockHttpsURLConnection(null, mockLogger); + + assertUtil = new AssertUtil(mockLogger); + + AdjustFactory.setLogger(mockLogger); + AdjustFactory.setHttpsURLConnection(mockHttpsURLConnection); + + activity = getActivity(); + context = activity.getApplicationContext(); + sdkClickPackage = getClickPackage(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + + AdjustFactory.setHttpsURLConnection(null); + AdjustFactory.setLogger(null); + } + + private ActivityPackage getClickPackage() { + MockSdkClickHandler mockSdkClickHandler = new MockSdkClickHandler(mockLogger); + MockAttributionHandler mockAttributionHandler = new MockAttributionHandler(mockLogger); + MockPackageHandler mockPackageHandler = new MockPackageHandler(mockLogger); + + AdjustFactory.setPackageHandler(mockPackageHandler); + AdjustFactory.setSdkClickHandler(mockSdkClickHandler); + AdjustFactory.setAttributionHandler(mockAttributionHandler); + + // create the config to start the session + AdjustConfig config = new AdjustConfig(context, "123456789012", AdjustConfig.ENVIRONMENT_SANDBOX); + + // start activity handler with config + ActivityHandler activityHandler = ActivityHandler.getInstance(config); + activityHandler.onResume(); + activityHandler.readOpenUrl(Uri.parse("AdjustTests://"), System.currentTimeMillis()); + SystemClock.sleep(2000); + + ActivityPackage sdkClickPackage = mockSdkClickHandler.queue.get(0); + mockLogger.reset(); + + return sdkClickPackage; + } + + public void testPaused() { + sdkClickPackage.setClientSdk("Test-First-Click"); + ActivityPackage secondSdkClickPackage = getClickPackage(); + secondSdkClickPackage.setClientSdk("Test-Second-Click"); + + AdjustFactory.setSdkClickBackoffStrategy(BackoffStrategy.NO_WAIT); + + // assert test name to read better in logcat + mockLogger.Assert("TestRequestHandler testPaused"); + + SdkClickHandler sdkClickHandler = new SdkClickHandler(false); + + mockHttpsURLConnection.responseType = ResponseType.CLIENT_PROTOCOL_EXCEPTION; + + sdkClickHandler.sendSdkClick(sdkClickPackage); + SystemClock.sleep(1000); + + // added first click package to the queue + assertUtil.debug("Added sdk_click 1"); + + assertUtil.verbose("Path: /sdk_click\n" + + "ClientSdk: Test-First-Click"); + + // but not send because it's paused + assertUtil.notInTest("MockHttpsURLConnection getInputStream"); + + // send second sdk click + sdkClickHandler.sendSdkClick(secondSdkClickPackage); + SystemClock.sleep(1000); + + // added second click package to the queue + assertUtil.debug("Added sdk_click 2"); + + assertUtil.verbose("Path: /sdk_click\n" + + "ClientSdk: Test-Second-Click"); + + // wait two seconds before sending + mockHttpsURLConnection.waitingTime = 2000L; + + // try to send first package + checkSendFirstPackage(sdkClickHandler, 1); + // and then the second + checkSendSecondPackage(sdkClickHandler, 1); + + // try to send first package again + checkSendFirstPackage(sdkClickHandler, 2); + // and then the second again + checkSendSecondPackage(sdkClickHandler, 2); + } + + private void checkSendFirstPackage(SdkClickHandler sdkClickHandler, int retries) { + // try to send the first package + sdkClickHandler.resumeSending(); + + SystemClock.sleep(1000); + + // prevent sending next again + sdkClickHandler.pauseSending(); + + SystemClock.sleep(2000); + + // check that it tried to send the first package + assertUtil.test("MockHttpsURLConnection setRequestProperty, field Client-SDK, newValue Test-First-Click"); + + // and that it will try to send it again + assertUtil.error("Retrying sdk_click package for the " + retries + " time"); + + // first package added again on the end of the queue + assertUtil.debug("Added sdk_click 2"); + + assertUtil.verbose("Path: /sdk_click\n" + + "ClientSdk: Test-First-Click"); + + // does not continue to send because it was paused + assertUtil.notInTest("MockHttpsURLConnection setRequestProperty"); + } + + private void checkSendSecondPackage(SdkClickHandler sdkClickHandler, int retries) { + // try to send the second package that is at the start of the queue + sdkClickHandler.resumeSending(); + + SystemClock.sleep(1000); + + // prevent sending next again + sdkClickHandler.pauseSending(); + + SystemClock.sleep(2000); + + // check that it tried to send the second package + assertUtil.test("MockHttpsURLConnection setRequestProperty, field Client-SDK, newValue Test-Second-Click"); + + // and that it will try to send it again + assertUtil.error("Retrying sdk_click package for the " + retries + " time"); + + // second package added again on the end of the queue + assertUtil.debug("Added sdk_click 2"); + + assertUtil.verbose("Path: /sdk_click\n" + + "ClientSdk: Test-Second-Click"); + + // does not continue to send because it was paused + assertUtil.notInTest("MockHttpsURLConnection setRequestProperty"); + } + + public void testNullResponse() { + // assert test name to read better in logcat + mockLogger.Assert("TestRequestHandler testNullResponse"); + + AdjustFactory.setSdkClickBackoffStrategy(BackoffStrategy.NO_WAIT); + + SdkClickHandler sdkClickHandler = new SdkClickHandler(true); + + mockHttpsURLConnection.responseType = null; + + sdkClickHandler.sendSdkClick(sdkClickPackage); + + SystemClock.sleep(1000); + + assertUtil.debug("Added sdk_click 1"); + + assertUtil.test("MockHttpsURLConnection getInputStream, responseType: null"); + + assertUtil.error("Failed to read response. (null)"); + + assertUtil.error("Failed to track click. (Sdk_click runtime exception: java.lang.NullPointerException)"); + + // does not to try to retry + assertUtil.notInError("Retrying sdk_click package for the"); + assertUtil.notInDebug("Added sdk_click"); + } + + public void testClientException() { + // assert test name to read better in logcat + mockLogger.Assert("TestRequestHandler testClientException"); + + AdjustFactory.setSdkClickBackoffStrategy(BackoffStrategy.NO_WAIT); + + SdkClickHandler sdkClickHandler = new SdkClickHandler(true); + + mockHttpsURLConnection.responseType = ResponseType.CLIENT_PROTOCOL_EXCEPTION; + + sdkClickHandler.sendSdkClick(sdkClickPackage); + SystemClock.sleep(1000); + + assertUtil.test("MockHttpsURLConnection getInputStream, responseType: CLIENT_PROTOCOL_EXCEPTION"); + + assertUtil.error("Failed to track click. (Sdk_click request failed. Will retry later: java.io.IOException: testResponseError)"); + + // tries to retry + assertUtil.error("Retrying sdk_click package for the 1 time"); + + // adds to end of the queue + assertUtil.debug("Added sdk_click"); + } + + public void testServerError() { + // assert test name to read better in logcat + mockLogger.Assert("TestRequestHandler testServerError"); + + AdjustFactory.setSdkClickBackoffStrategy(BackoffStrategy.NO_WAIT); + + SdkClickHandler sdkClickHandler = new SdkClickHandler(true); + + mockHttpsURLConnection.responseType = ResponseType.INTERNAL_SERVER_ERROR; + + sdkClickHandler.sendSdkClick(sdkClickPackage); + SystemClock.sleep(1000); + + assertUtil.test("MockHttpsURLConnection getErrorStream, responseType: INTERNAL_SERVER_ERROR"); + + assertUtil.verbose("Response: { \"message\": \"testResponseError\"}"); + + assertUtil.error("testResponseError"); + } + + public void testWrongJson() { + // assert test name to read better in logcat + mockLogger.Assert("TestRequestHandler testWrongJson"); + + AdjustFactory.setSdkClickBackoffStrategy(BackoffStrategy.NO_WAIT); + + SdkClickHandler sdkClickHandler = new SdkClickHandler(true); + + mockHttpsURLConnection.responseType = ResponseType.WRONG_JSON; + + sdkClickHandler.sendSdkClick(sdkClickPackage); + SystemClock.sleep(1000); + + assertUtil.test("MockHttpsURLConnection getInputStream, responseType: WRONG_JSON"); + + assertUtil.verbose("Response: not a json response"); + + assertUtil.error("Failed to parse json response. (Value not of type java.lang.String cannot be converted to JSONObject)"); + } + + public void testEmptyJson() { + // assert test name to read better in logcat + mockLogger.Assert("TestRequestHandler testWrongJson"); + + AdjustFactory.setSdkClickBackoffStrategy(BackoffStrategy.NO_WAIT); + + SdkClickHandler sdkClickHandler = new SdkClickHandler(true); + + mockHttpsURLConnection.responseType = ResponseType.EMPTY_JSON; + + sdkClickHandler.sendSdkClick(sdkClickPackage); + SystemClock.sleep(1000); + + assertUtil.test("MockHttpsURLConnection getInputStream, responseType: EMPTY_JSON"); + + assertUtil.verbose("Response: { }"); + + assertUtil.info("No message found"); + } + + public void testMessage() { + // assert test name to read better in logcat + mockLogger.Assert("TestRequestHandler testWrongJson"); + + AdjustFactory.setSdkClickBackoffStrategy(BackoffStrategy.NO_WAIT); + + SdkClickHandler sdkClickHandler = new SdkClickHandler(true); + + mockHttpsURLConnection.responseType = ResponseType.MESSAGE; + + sdkClickHandler.sendSdkClick(sdkClickPackage); + SystemClock.sleep(1000); + + TestActivityPackage.testQueryStringRequest(mockHttpsURLConnection.readRequest(), 0); + + assertUtil.test("MockHttpsURLConnection getInputStream, responseType: MESSAGE"); + + assertUtil.verbose("Response: { \"message\" : \"response OK\"}"); + + assertUtil.info("response OK"); + } +}