From 161011402635edebaf4a452d3e6e3757787fbf7b Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Thu, 30 May 2024 10:39:44 -0700 Subject: [PATCH 1/4] Add IAM basic test scaffolding and migrate build tests --- .../internal/InAppMessagesTests.kt | 134 +++++++++++++ .../internal/InAppMessagingHelpers.kt | 176 ++++++++++++++++++ 2 files changed, 310 insertions(+) create mode 100644 OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt create mode 100644 OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt diff --git a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt new file mode 100644 index 0000000000..d8ace92962 --- /dev/null +++ b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt @@ -0,0 +1,134 @@ +package com.onesignal.inAppMessages.internal + +import com.onesignal.debug.LogLevel +import com.onesignal.debug.internal.logging.Logging +import com.onesignal.inAppMessages.internal.InAppMessagingHelpers.Companion.buildTestMessageWithRedisplay +import io.kotest.core.spec.style.FunSpec +import io.kotest.matchers.shouldBe +import io.kotest.matchers.shouldNotBe +import java.util.UUID + + +class InAppMessagesTests : FunSpec({ + val IAM_CLICK_ID = "button_id_123" + val LIMIT = 5 + val DELAY: Long = 60 + +// Define message at class level with lazy initialization + val message: InAppMessagingHelpers.OSTestInAppMessageInternal by lazy { + InAppMessagingHelpers.buildTestMessageWithSingleTrigger( + Trigger.OSTriggerKind.SESSION_TIME, + null, + Trigger.OSTriggerOperator.GREATER_THAN_OR_EQUAL_TO.toString(), + 3 + ) + } + + beforeAny { + Logging.logLevel = LogLevel.NONE + // TODO: add more from Player Model @BeforeClass in InAppMessagingUnitTests.java + } + + beforeTest { + // TODO: add more from Player Model @BeforeTest in InAppMessagingUnitTests.java + } + + afterTest { + // TODO: reset back to default: clear timers and clean up helpers + } + + test("testBuiltMessage") { + // Given + val messageId = message.messageId + val variants = message.variants + + // Then + UUID.fromString(messageId) // Throws if invalid + variants shouldNotBe null + } + + test("testBuiltMessageVariants") { + message.variants["android"]?.get("es") shouldBe InAppMessagingHelpers.TEST_SPANISH_ANDROID_VARIANT_ID + message.variants["android"]?.get("en") shouldBe InAppMessagingHelpers.TEST_ENGLISH_ANDROID_VARIANT_ID + } + + test("testBuiltMessageReDisplay") { + // Given + val message = buildTestMessageWithRedisplay(LIMIT, DELAY) + + // Then + message.redisplayStats.isRedisplayEnabled shouldBe true + message.redisplayStats.displayLimit shouldBe LIMIT + message.redisplayStats.displayDelay shouldBe DELAY + message.redisplayStats.lastDisplayTime shouldBe -1 + message.redisplayStats.displayQuantity shouldBe 0 + + // When + val messageWithoutDisplay: InAppMessagingHelpers.OSTestInAppMessageInternal = + InAppMessagingHelpers.buildTestMessageWithSingleTrigger( + Trigger.OSTriggerKind.SESSION_TIME, + null, + Trigger.OSTriggerOperator.GREATER_THAN_OR_EQUAL_TO.toString(), + 3 + ) + + // Then + messageWithoutDisplay.redisplayStats.isRedisplayEnabled shouldBe false + messageWithoutDisplay.redisplayStats.displayLimit shouldBe 1 + messageWithoutDisplay.redisplayStats.displayDelay shouldBe 0 + messageWithoutDisplay.redisplayStats.lastDisplayTime shouldBe -1 + messageWithoutDisplay.redisplayStats.displayQuantity shouldBe 0 + } + + test("testBuiltMessageRedisplayLimit") { + val message: InAppMessagingHelpers.OSTestInAppMessageInternal = + buildTestMessageWithRedisplay( + LIMIT, + DELAY + ) + for (i in 0 until LIMIT) { + message.redisplayStats.shouldDisplayAgain() shouldBe true + message.redisplayStats.incrementDisplayQuantity() + } + message.redisplayStats.incrementDisplayQuantity() + message.redisplayStats.shouldDisplayAgain() shouldBe false + } + + + test("testBuiltMessageRedisplayDelay") { + // TODO + } + + test("testBuiltMessageRedisplayCLickId") { + val message: InAppMessagingHelpers.OSTestInAppMessageInternal = + buildTestMessageWithRedisplay( + LIMIT, + DELAY + ) + + message.clickedClickIds.isEmpty() shouldBe true + message.isClickAvailable(IAM_CLICK_ID) + + message.addClickId(IAM_CLICK_ID) + message.clearClickIds() + + message.clickedClickIds.isEmpty() shouldBe true + + message.addClickId(IAM_CLICK_ID) + message.addClickId(IAM_CLICK_ID) + message.clickedClickIds.size shouldBe 1 + + message.isClickAvailable(IAM_CLICK_ID) shouldBe false + + val messageWithoutDisplay2: InAppMessagingHelpers.OSTestInAppMessageInternal = + InAppMessagingHelpers.buildTestMessageWithSingleTrigger( + Trigger.OSTriggerKind.SESSION_TIME, + null, + Trigger.OSTriggerOperator.GREATER_THAN_OR_EQUAL_TO.toString(), + 3 + ) + + messageWithoutDisplay2.addClickId(IAM_CLICK_ID) + messageWithoutDisplay2.isClickAvailable(IAM_CLICK_ID) shouldBe false + } +}) diff --git a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt new file mode 100644 index 0000000000..d618946b4c --- /dev/null +++ b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt @@ -0,0 +1,176 @@ +package com.onesignal.inAppMessages.internal + +import com.onesignal.core.internal.time.ITime +import org.json.JSONArray +import org.json.JSONObject +import java.util.UUID + +class InAppMessagingHelpers { + companion object { + const val TEST_SPANISH_ANDROID_VARIANT_ID = "d8cc-11e4-bed1-df8f05be55ba-a4b3gj7f" + const val TEST_ENGLISH_ANDROID_VARIANT_ID = "11e4-bed1-df8f05be55ba-a4b3gj7f-d8cc" + const val IAM_CLICK_ID = "12345678-1234-1234-1234-123456789012" + const val IAM_PAGE_ID = "12345678-1234-ABCD-1234-123456789012" + + // Most tests build a test message using only one trigger. + // This convenience method makes it easy to build such a message + internal fun buildTestMessageWithSingleTrigger(kind: Trigger.OSTriggerKind, key: String?, operator: String, value: Any): OSTestInAppMessageInternal { + val triggersJson = basicTrigger(kind, key, operator, value) + return buildTestMessage(triggersJson) + } + + private fun buildTestMessage(triggerJson: JSONArray?): OSTestInAppMessageInternal { + return OSTestInAppMessageInternal(basicIAMJSONObject(triggerJson)) + } + + private fun basicTrigger( + kind: Trigger.OSTriggerKind, + key: String?, + operator: String, + value: Any + ): JSONArray { + val triggerJson: JSONObject = object : JSONObject() { + init { + put("id", UUID.randomUUID().toString()) + put("kind", kind.toString()) + put("property", key) + put("operator", operator) + put("value", value) + } + } + + return wrap(wrap(triggerJson)) + } + + private fun wrap(`object`: Any?): JSONArray { + return object : JSONArray() { + init { + put(`object`) + } + } + } + + fun buildTestMessageWithRedisplay(limit: Int, delay: Long): OSTestInAppMessageInternal { + return buildTestMessageWithMultipleDisplays(null, limit, delay) + } + + private fun buildTestMessageWithMultipleDisplays( + triggerJson: JSONArray?, + limit: Int, + delay: Long + ): OSTestInAppMessageInternal { + val json = basicIAMJSONObject(triggerJson) + json.put("redisplay", object : JSONObject() { + init { + put("limit", limit) + put("delay", delay) //in seconds + } + }) + + return OSTestInAppMessageInternal(json) + } + + private fun basicIAMJSONObject(triggerJson: JSONArray?): JSONObject { + val jsonObject = JSONObject() + jsonObject.put("id", UUID.randomUUID().toString()) + jsonObject.put("clickIds", JSONArray(listOf("clickId1", "clickId2", "clickId3"))) + // shouldn't hard-code? + jsonObject.put("displayedInSession", true) + jsonObject.put("variants", JSONObject().apply { + put("android", JSONObject().apply { + put("es", TEST_SPANISH_ANDROID_VARIANT_ID) + put("en", TEST_ENGLISH_ANDROID_VARIANT_ID) + }) + }) + jsonObject.put("max_display_time", 30) + if (triggerJson != null) { + jsonObject.put("triggers", triggerJson) + } else { + jsonObject.put("triggers", JSONArray()) + } + jsonObject.put("actions", JSONArray().apply { + put(buildTestActionJson()) + }) + + return jsonObject + } + + fun buildTestActionJson(): JSONObject { + return object : JSONObject() { + init { + put("click_type", "button") + put("id", IAM_CLICK_ID) + put("name", "click_name") + put("url", "https://www.onesignal.com") + put("url_target", "webview") + put("close", true) + put("pageId", IAM_PAGE_ID) + put("data", object : JSONObject() { + init { + put("test", "value") + } + }) + } + } + } + } + + class OSTestInAppMessageInternal( + private val jsonObject: JSONObject + ) { + private val inAppMessage: InAppMessage by lazy { + initializeInAppMessage() + } + + private fun initializeInAppMessage(): InAppMessage { + val time = object : ITime { + override val currentTimeMillis: Long + get() = System.currentTimeMillis() + } + + return InAppMessage(jsonObject, time) + } + + val messageId: String + get() = inAppMessage.messageId + + val variants: Map> + get() = inAppMessage.variants + + val clickedClickIds: MutableSet + get() = inAppMessage.clickedClickIds + + var isDisplayedInSession: Boolean + get() = inAppMessage.isDisplayedInSession + set(value) { + inAppMessage.isDisplayedInSession = value + } + + internal val redisplayStats: InAppMessageRedisplayStats + get() = inAppMessage.redisplayStats + + // Extract limit and delay from the JSON object + private val redisplayLimit: Int + get() = jsonObject.optJSONObject("redisplay")?.optInt("limit", -1) ?: -1 + + private val redisplayDelay: Long + get() = jsonObject.optJSONObject("redisplay")?.optLong("delay", -1L) ?: -1L + + fun isClickAvailable(clickId: String?): Boolean { + return !clickedClickIds.contains(clickId) + } + + fun addClickId(clickId: String) { + clickedClickIds.add(clickId) + } + + fun clearClickIds() { + clickedClickIds.clear() + } + + override fun toString(): String { + return "OSTestInAppMessageInternal(jsonObject=$jsonObject, redisplayLimit=$redisplayLimit, redisplayDelay=$redisplayDelay)" + } + } +} + From 94a0d3060671307c2844ec28e23abd2c129a9c20 Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Thu, 30 May 2024 10:49:30 -0700 Subject: [PATCH 2/4] WIP Add additional test migration todos - begin WIP testing Trigger & Lifecycle --- .../internal/InAppMessagesTests.kt | 168 ++++++++++++++++++ .../internal/InAppMessagingHelpers.kt | 63 ++++++- 2 files changed, 230 insertions(+), 1 deletion(-) diff --git a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt index d8ace92962..280709467f 100644 --- a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt +++ b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt @@ -1,7 +1,13 @@ package com.onesignal.inAppMessages.internal +import com.onesignal.OneSignal import com.onesignal.debug.LogLevel import com.onesignal.debug.internal.logging.Logging +import com.onesignal.inAppMessages.IInAppMessageDidDismissEvent +import com.onesignal.inAppMessages.IInAppMessageDidDisplayEvent +import com.onesignal.inAppMessages.IInAppMessageLifecycleListener +import com.onesignal.inAppMessages.IInAppMessageWillDismissEvent +import com.onesignal.inAppMessages.IInAppMessageWillDisplayEvent import com.onesignal.inAppMessages.internal.InAppMessagingHelpers.Companion.buildTestMessageWithRedisplay import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe @@ -14,6 +20,32 @@ class InAppMessagesTests : FunSpec({ val LIMIT = 5 val DELAY: Long = 60 + fun setLocalTriggerValue(key: String, localValue: String) { + if (localValue != null) OneSignal.InAppMessages.addTrigger( + key, + localValue + ) else OneSignal.InAppMessages.removeTrigger(key) + } + + fun comparativeOperatorTest( + operator: Trigger.OSTriggerOperator, + triggerValue: String, + localValue: String + ): Boolean { +// TODO +// setLocalTriggerValue("test_property", localValue) +// val testMessage: InAppMessagingHelpers.OSTestInAppMessageInternal = +// InAppMessagingHelpers.buildTestMessageWithSingleTrigger( +// Trigger.OSTriggerKind.CUSTOM, +// "test_property", +// operator.toString(), +// triggerValue +// ) +// +// return InAppMessagingHelpers.evaluateMessage(testMessage) + return true + } + // Define message at class level with lazy initialization val message: InAppMessagingHelpers.OSTestInAppMessageInternal by lazy { InAppMessagingHelpers.buildTestMessageWithSingleTrigger( @@ -31,6 +63,7 @@ class InAppMessagesTests : FunSpec({ beforeTest { // TODO: add more from Player Model @BeforeTest in InAppMessagingUnitTests.java + var iamLifecycleCounter = 0 } afterTest { @@ -131,4 +164,139 @@ class InAppMessagesTests : FunSpec({ messageWithoutDisplay2.addClickId(IAM_CLICK_ID) messageWithoutDisplay2.isClickAvailable(IAM_CLICK_ID) shouldBe false } + + test ("testBuiltMessageTrigger") { + // TODO + } + + test("testParsesMessageActions") { + // TODO + } + + test("testSaveMultipleTriggerValuesGetTrigger") { + // TODO + // Since trigger getter method no longer exists, will need to refactor + } + + test("testSaveMultipleTriggerValues") { + // TODO + } + + // removed tests checking for non-string trigger values + + // create new test for ensuring only string trigger value + test("testTriggerValuesAreStrings") { + // TODO + } + + test("testDeleteSavedTriggerValueGetTriggers") { + // TODO + } + + test("testDeleteSavedTriggerValue") { + // TODO + } + + test("testDeleteMultipleTriggers") { + // TODO + } + + test("testDeleteAllTriggers") { + // TODO + } + + test("testGreaterThanOperator") { + // TODO + } + + test("testGreaterThanOperatorWithString") { + // TODO + } + + // add more operator tests + + test("testMessageSchedulesSessionDurationTimer") { + // TODO + } + + // more trigger tests + + test("testOnMessageActionOccurredOnMessage") { + // TODO: + + // add clickListener + + // val clickListener = object : IInAppMessageClickListener { + // override fun onClick(event: IInAppMessageClickEvent) { + // print(event.result.actionId) + // } + // } + // OneSignal.InAppMessages.addClickListener(clickListener) + + + //assertMainThread() + //threadAndTaskWait() + + // call onMessageActionOccurredOnMessage + + // Ensure we make REST call to OneSignal to report click. + + + // Ensure we fire public callback that In-App was clicked. + } + + test("testOnMessageWasShown") { + // TODO: +// threadAndTaskWait() +// InAppMessagingHelpers.onMessageWasDisplayed(message) +// +// Compare Shadow Rest Client request + } + + test("testOnPageChanged") { + // TODO + } + + + /* Tests for IAM Lifecycle */ +// var iamLifecycleCounter = 0 + + test("testIAMLifecycleEventsFlow") { + // TODO + // add listener and incremenet counter +// val lifecycleListener = object : IInAppMessageLifecycleListener { +// override fun onWillDisplay(event: IInAppMessageWillDisplayEvent) { +// iamLifecycleCounter++ +// } +// +// override fun onDidDisplay(event: IInAppMessageDidDisplayEvent) { +// iamLifecycleCounter++ +// } +// +// override fun onWillDismiss(event: IInAppMessageWillDismissEvent) { +// iamLifecycleCounter++ +// } +// +// override fun onDidDismiss(event: IInAppMessageDidDismissEvent) { +// iamLifecycleCounter++ +// } +// } +// OneSignal.InAppMessages.addLifecycleListener(lifecycleListener) + +// threadAndTaskWait() +// iamLifecycleCounter shouldBe 0 +// // maybe need threadAndTaskWait +// +// InAppMessagingHelpers.onMessageWillDisplay(message) +// iamLifecycleCounter shouldBe 1 +// +// InAppMessagingHelpers.onMessageWasDisplayed(message) +// iamLifecycleCounter shouldBe 2 +// +// InAppMessagingHelpers.onMessageWillDismiss(message) +// iamLifecycleCounter shouldBe 3 +// +// InAppMessagingHelpers.onMessageDidDismiss(message) +// iamLifecycleCounter shouldBe 4 + } }) diff --git a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt index d618946b4c..c3dbf9748b 100644 --- a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt +++ b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt @@ -1,6 +1,7 @@ package com.onesignal.inAppMessages.internal import com.onesignal.core.internal.time.ITime +import io.mockk.mockk import org.json.JSONArray import org.json.JSONObject import java.util.UUID @@ -11,6 +12,43 @@ class InAppMessagingHelpers { const val TEST_ENGLISH_ANDROID_VARIANT_ID = "11e4-bed1-df8f05be55ba-a4b3gj7f-d8cc" const val IAM_CLICK_ID = "12345678-1234-1234-1234-123456789012" const val IAM_PAGE_ID = "12345678-1234-ABCD-1234-123456789012" + const val IAM_HAS_LIQUID = "has_liquid" + + internal fun evaluateMessage(message: InAppMessage) { + // TODO + } + + internal fun onMessageWasDisplayed(message: InAppMessage) { + val mockInAppMessageManager = mockk() + mockInAppMessageManager.onMessageWasDisplayed(message) + } + + internal fun onMessageActionOccurredOnMessage( + message: InAppMessage, + clickResult: InAppMessageClickResult + ) { + val mockInAppMessageManager = mockk() + mockInAppMessageManager.onMessageActionOccurredOnMessage(message, clickResult) + } + + fun buildTestMessageWithLiquid(triggerJson: JSONArray?): OSTestInAppMessageInternal { + val json = basicIAMJSONObject(triggerJson) + json.put(IAM_HAS_LIQUID, true) + return OSTestInAppMessageInternal(json) + } + + internal fun buildTestMessageWithSingleTriggerAndLiquid( + kind: Trigger.OSTriggerKind, + key: String?, + operator: String?, + value: Any? + ): OSTestInAppMessageInternal { + val triggersJson = basicTrigger( + kind, key, + operator!!, value!! + ) + return buildTestMessageWithLiquid(triggersJson) + } // Most tests build a test message using only one trigger. // This convenience method makes it easy to build such a message @@ -115,6 +153,30 @@ class InAppMessagingHelpers { } } + // WIP + /** IAM Lifecycle */ + internal fun onMessageWillDisplay(message: InAppMessage) { + val mockInAppMessageManager = mockk() + mockInAppMessageManager.onMessageWillDisplay(message) + } + + internal fun onMessageDidDisplay(message: InAppMessage) { + val mockInAppMessageManager = mockk() + mockInAppMessageManager.onMessageWasDisplayed(message) + } + + internal fun onMessageWillDismiss(message: InAppMessage) { + val mockInAppMessageManager = mockk() + mockInAppMessageManager.onMessageWillDismiss(message) + } + + internal fun onMessageDidDismiss(message: InAppMessage) { + val mockInAppMessageManager = mockk() + mockInAppMessageManager.onMessageWasDismissed(message) + } + + // End IAM Lifecycle + class OSTestInAppMessageInternal( private val jsonObject: JSONObject ) { @@ -173,4 +235,3 @@ class InAppMessagingHelpers { } } } - From 544bce193e68a7fcf3ce55701d60b0b9049b45ee Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Tue, 23 Jul 2024 11:24:11 -0700 Subject: [PATCH 3/4] Fix linting errors --- .../internal/InAppMessagesTests.kt | 82 ++++++------- .../internal/InAppMessagingHelpers.kt | 115 +++++++++++------- 2 files changed, 112 insertions(+), 85 deletions(-) diff --git a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt index 280709467f..04f45ce397 100644 --- a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt +++ b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt @@ -3,34 +3,35 @@ package com.onesignal.inAppMessages.internal import com.onesignal.OneSignal import com.onesignal.debug.LogLevel import com.onesignal.debug.internal.logging.Logging -import com.onesignal.inAppMessages.IInAppMessageDidDismissEvent -import com.onesignal.inAppMessages.IInAppMessageDidDisplayEvent -import com.onesignal.inAppMessages.IInAppMessageLifecycleListener -import com.onesignal.inAppMessages.IInAppMessageWillDismissEvent -import com.onesignal.inAppMessages.IInAppMessageWillDisplayEvent import com.onesignal.inAppMessages.internal.InAppMessagingHelpers.Companion.buildTestMessageWithRedisplay import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import java.util.UUID - class InAppMessagesTests : FunSpec({ - val IAM_CLICK_ID = "button_id_123" - val LIMIT = 5 - val DELAY: Long = 60 - - fun setLocalTriggerValue(key: String, localValue: String) { - if (localValue != null) OneSignal.InAppMessages.addTrigger( - key, - localValue - ) else OneSignal.InAppMessages.removeTrigger(key) + val iamClickId = "button_id_123" + val limit = 5 + val delay: Long = 60 + + fun setLocalTriggerValue( + key: String, + localValue: String, + ) { + if (localValue != null) { + OneSignal.InAppMessages.addTrigger( + key, + localValue, + ) + } else { + OneSignal.InAppMessages.removeTrigger(key) + } } fun comparativeOperatorTest( operator: Trigger.OSTriggerOperator, triggerValue: String, - localValue: String + localValue: String, ): Boolean { // TODO // setLocalTriggerValue("test_property", localValue) @@ -52,7 +53,7 @@ class InAppMessagesTests : FunSpec({ Trigger.OSTriggerKind.SESSION_TIME, null, Trigger.OSTriggerOperator.GREATER_THAN_OR_EQUAL_TO.toString(), - 3 + 3, ) } @@ -87,12 +88,12 @@ class InAppMessagesTests : FunSpec({ test("testBuiltMessageReDisplay") { // Given - val message = buildTestMessageWithRedisplay(LIMIT, DELAY) + val message = buildTestMessageWithRedisplay(limit, delay) // Then message.redisplayStats.isRedisplayEnabled shouldBe true - message.redisplayStats.displayLimit shouldBe LIMIT - message.redisplayStats.displayDelay shouldBe DELAY + message.redisplayStats.displayLimit shouldBe limit + message.redisplayStats.displayDelay shouldBe delay message.redisplayStats.lastDisplayTime shouldBe -1 message.redisplayStats.displayQuantity shouldBe 0 @@ -102,7 +103,7 @@ class InAppMessagesTests : FunSpec({ Trigger.OSTriggerKind.SESSION_TIME, null, Trigger.OSTriggerOperator.GREATER_THAN_OR_EQUAL_TO.toString(), - 3 + 3, ) // Then @@ -116,10 +117,10 @@ class InAppMessagesTests : FunSpec({ test("testBuiltMessageRedisplayLimit") { val message: InAppMessagingHelpers.OSTestInAppMessageInternal = buildTestMessageWithRedisplay( - LIMIT, - DELAY + limit, + delay, ) - for (i in 0 until LIMIT) { + for (i in 0 until limit) { message.redisplayStats.shouldDisplayAgain() shouldBe true message.redisplayStats.incrementDisplayQuantity() } @@ -127,7 +128,6 @@ class InAppMessagesTests : FunSpec({ message.redisplayStats.shouldDisplayAgain() shouldBe false } - test("testBuiltMessageRedisplayDelay") { // TODO } @@ -135,37 +135,37 @@ class InAppMessagesTests : FunSpec({ test("testBuiltMessageRedisplayCLickId") { val message: InAppMessagingHelpers.OSTestInAppMessageInternal = buildTestMessageWithRedisplay( - LIMIT, - DELAY + limit, + delay, ) message.clickedClickIds.isEmpty() shouldBe true - message.isClickAvailable(IAM_CLICK_ID) + message.isClickAvailable(iamClickId) - message.addClickId(IAM_CLICK_ID) + message.addClickId(iamClickId) message.clearClickIds() message.clickedClickIds.isEmpty() shouldBe true - message.addClickId(IAM_CLICK_ID) - message.addClickId(IAM_CLICK_ID) + message.addClickId(iamClickId) + message.addClickId(iamClickId) message.clickedClickIds.size shouldBe 1 - message.isClickAvailable(IAM_CLICK_ID) shouldBe false + message.isClickAvailable(iamClickId) shouldBe false val messageWithoutDisplay2: InAppMessagingHelpers.OSTestInAppMessageInternal = InAppMessagingHelpers.buildTestMessageWithSingleTrigger( Trigger.OSTriggerKind.SESSION_TIME, null, Trigger.OSTriggerOperator.GREATER_THAN_OR_EQUAL_TO.toString(), - 3 + 3, ) - messageWithoutDisplay2.addClickId(IAM_CLICK_ID) - messageWithoutDisplay2.isClickAvailable(IAM_CLICK_ID) shouldBe false + messageWithoutDisplay2.addClickId(iamClickId) + messageWithoutDisplay2.isClickAvailable(iamClickId) shouldBe false } - test ("testBuiltMessageTrigger") { + test("testBuiltMessageTrigger") { // TODO } @@ -233,15 +233,13 @@ class InAppMessagesTests : FunSpec({ // } // OneSignal.InAppMessages.addClickListener(clickListener) - - //assertMainThread() - //threadAndTaskWait() + // assertMainThread() + // threadAndTaskWait() // call onMessageActionOccurredOnMessage // Ensure we make REST call to OneSignal to report click. - // Ensure we fire public callback that In-App was clicked. } @@ -257,11 +255,11 @@ class InAppMessagesTests : FunSpec({ // TODO } - - /* Tests for IAM Lifecycle */ + // Tests for IAM Lifecycle // var iamLifecycleCounter = 0 test("testIAMLifecycleEventsFlow") { + // TODO // add listener and incremenet counter // val lifecycleListener = object : IInAppMessageLifecycleListener { diff --git a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt index c3dbf9748b..24f521f77a 100644 --- a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt +++ b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt @@ -25,7 +25,7 @@ class InAppMessagingHelpers { internal fun onMessageActionOccurredOnMessage( message: InAppMessage, - clickResult: InAppMessageClickResult + clickResult: InAppMessageClickResult, ) { val mockInAppMessageManager = mockk() mockInAppMessageManager.onMessageActionOccurredOnMessage(message, clickResult) @@ -41,18 +41,26 @@ class InAppMessagingHelpers { kind: Trigger.OSTriggerKind, key: String?, operator: String?, - value: Any? + value: Any?, ): OSTestInAppMessageInternal { - val triggersJson = basicTrigger( - kind, key, - operator!!, value!! - ) + val triggersJson = + basicTrigger( + kind, + key, + operator!!, + value!!, + ) return buildTestMessageWithLiquid(triggersJson) } // Most tests build a test message using only one trigger. // This convenience method makes it easy to build such a message - internal fun buildTestMessageWithSingleTrigger(kind: Trigger.OSTriggerKind, key: String?, operator: String, value: Any): OSTestInAppMessageInternal { + internal fun buildTestMessageWithSingleTrigger( + kind: Trigger.OSTriggerKind, + key: String?, + operator: String, + value: Any, + ): OSTestInAppMessageInternal { val triggersJson = basicTrigger(kind, key, operator, value) return buildTestMessage(triggersJson) } @@ -65,17 +73,18 @@ class InAppMessagingHelpers { kind: Trigger.OSTriggerKind, key: String?, operator: String, - value: Any + value: Any, ): JSONArray { - val triggerJson: JSONObject = object : JSONObject() { - init { - put("id", UUID.randomUUID().toString()) - put("kind", kind.toString()) - put("property", key) - put("operator", operator) - put("value", value) + val triggerJson: JSONObject = + object : JSONObject() { + init { + put("id", UUID.randomUUID().toString()) + put("kind", kind.toString()) + put("property", key) + put("operator", operator) + put("value", value) + } } - } return wrap(wrap(triggerJson)) } @@ -88,22 +97,28 @@ class InAppMessagingHelpers { } } - fun buildTestMessageWithRedisplay(limit: Int, delay: Long): OSTestInAppMessageInternal { + fun buildTestMessageWithRedisplay( + limit: Int, + delay: Long, + ): OSTestInAppMessageInternal { return buildTestMessageWithMultipleDisplays(null, limit, delay) } private fun buildTestMessageWithMultipleDisplays( triggerJson: JSONArray?, limit: Int, - delay: Long + delay: Long, ): OSTestInAppMessageInternal { val json = basicIAMJSONObject(triggerJson) - json.put("redisplay", object : JSONObject() { - init { - put("limit", limit) - put("delay", delay) //in seconds - } - }) + json.put( + "redisplay", + object : JSONObject() { + init { + put("limit", limit) + put("delay", delay) // in seconds + } + }, + ) return OSTestInAppMessageInternal(json) } @@ -114,21 +129,30 @@ class InAppMessagingHelpers { jsonObject.put("clickIds", JSONArray(listOf("clickId1", "clickId2", "clickId3"))) // shouldn't hard-code? jsonObject.put("displayedInSession", true) - jsonObject.put("variants", JSONObject().apply { - put("android", JSONObject().apply { - put("es", TEST_SPANISH_ANDROID_VARIANT_ID) - put("en", TEST_ENGLISH_ANDROID_VARIANT_ID) - }) - }) + jsonObject.put( + "variants", + JSONObject().apply { + put( + "android", + JSONObject().apply { + put("es", TEST_SPANISH_ANDROID_VARIANT_ID) + put("en", TEST_ENGLISH_ANDROID_VARIANT_ID) + }, + ) + }, + ) jsonObject.put("max_display_time", 30) if (triggerJson != null) { jsonObject.put("triggers", triggerJson) } else { jsonObject.put("triggers", JSONArray()) } - jsonObject.put("actions", JSONArray().apply { - put(buildTestActionJson()) - }) + jsonObject.put( + "actions", + JSONArray().apply { + put(buildTestActionJson()) + }, + ) return jsonObject } @@ -143,17 +167,21 @@ class InAppMessagingHelpers { put("url_target", "webview") put("close", true) put("pageId", IAM_PAGE_ID) - put("data", object : JSONObject() { - init { - put("test", "value") - } - }) + put( + "data", + object : JSONObject() { + init { + put("test", "value") + } + }, + ) } } } } // WIP + /** IAM Lifecycle */ internal fun onMessageWillDisplay(message: InAppMessage) { val mockInAppMessageManager = mockk() @@ -178,17 +206,18 @@ class InAppMessagingHelpers { // End IAM Lifecycle class OSTestInAppMessageInternal( - private val jsonObject: JSONObject + private val jsonObject: JSONObject, ) { private val inAppMessage: InAppMessage by lazy { initializeInAppMessage() } private fun initializeInAppMessage(): InAppMessage { - val time = object : ITime { - override val currentTimeMillis: Long - get() = System.currentTimeMillis() - } + val time = + object : ITime { + override val currentTimeMillis: Long + get() = System.currentTimeMillis() + } return InAppMessage(jsonObject, time) } From 495013b320c03712611c75553d4716e217fd7051 Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Tue, 30 Jul 2024 16:38:35 -0700 Subject: [PATCH 4/4] Add Trigger Tests - Add Robolectric --- .../inAppMessages/internal/InAppMessagesTests.kt | 11 +++++++++-- .../inAppMessages/internal/InAppMessagingHelpers.kt | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt index 04f45ce397..dc875dd84a 100644 --- a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt +++ b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagesTests.kt @@ -1,5 +1,6 @@ package com.onesignal.inAppMessages.internal +import br.com.colman.kotest.android.extensions.robolectric.RobolectricTest import com.onesignal.OneSignal import com.onesignal.debug.LogLevel import com.onesignal.debug.internal.logging.Logging @@ -9,6 +10,7 @@ import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import java.util.UUID +@RobolectricTest class InAppMessagesTests : FunSpec({ val iamClickId = "button_id_123" val limit = 5 @@ -58,7 +60,7 @@ class InAppMessagesTests : FunSpec({ } beforeAny { - Logging.logLevel = LogLevel.NONE + Logging.logLevel = LogLevel.VERBOSE // TODO: add more from Player Model @BeforeClass in InAppMessagingUnitTests.java } @@ -166,7 +168,12 @@ class InAppMessagesTests : FunSpec({ } test("testBuiltMessageTrigger") { - // TODO + val trigger = message.triggers[0][0] + + trigger.kind shouldBe Trigger.OSTriggerKind.SESSION_TIME + trigger.operatorType shouldBe Trigger.OSTriggerOperator.GREATER_THAN_OR_EQUAL_TO + trigger.property shouldBe null + trigger.value shouldBe 3 } test("testParsesMessageActions") { diff --git a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt index 24f521f77a..9474362400 100644 --- a/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt +++ b/OneSignalSDK/onesignal/in-app-messages/src/test/java/com/onesignal/inAppMessages/internal/InAppMessagingHelpers.kt @@ -228,6 +228,9 @@ class InAppMessagingHelpers { val variants: Map> get() = inAppMessage.variants + internal val triggers: List> + get() = inAppMessage.triggers + val clickedClickIds: MutableSet get() = inAppMessage.clickedClickIds