diff --git a/kits/braze/braze-42/src/main/kotlin/com/mparticle/kits/AppboyKit.kt b/kits/braze/braze-42/src/main/kotlin/com/mparticle/kits/AppboyKit.kt index 9dc545da9..73ffc31f5 100644 --- a/kits/braze/braze-42/src/main/kotlin/com/mparticle/kits/AppboyKit.kt +++ b/kits/braze/braze-42/src/main/kotlin/com/mparticle/kits/AppboyKit.kt @@ -190,7 +190,7 @@ open class AppboyKit : } else { val properties = BrazeProperties() val brazePropertiesSetter = BrazePropertiesSetter(properties, enableTypeDetection) - event.customAttributeStrings?.let { it -> + event.customAttributeStrings?.let { for ((key, value) in it) { newAttributes[key] = brazePropertiesSetter.parseValue(key, value) } @@ -202,7 +202,7 @@ open class AppboyKit : object : IValueCallback { override fun onSuccess(value: BrazeUser) { val userAttributeSetter = UserAttributeSetter(value, enableTypeDetection) - event.customAttributeStrings?.let { it -> + event.customAttributeStrings?.let { for ((key, attributeValue) in it) { val hashedKey = KitUtils.hashForFiltering(event.eventType.value.toString() + event.eventName + key) @@ -1018,7 +1018,7 @@ open class AppboyKit : for (product in products) { braze.logEcommerceEvent( ProductViewedEvent( - productId = product.sku, + productId = recommendedProductId(product), productName = product.name, variantId = recommendedVariantId(product), price = product.unitPrice, @@ -1100,6 +1100,14 @@ open class AppboyKit : return if (variant.isNullOrEmpty()) product.sku else variant } + private fun recommendedProductId(product: Product): String = + try { + if (settings[REPLACE_SKU_AS_PRODUCT_NAME] == "True") product.name else product.sku + } catch (e: Exception) { + Logger.error(e, "The Braze kit threw an exception while searching for forward sku as product name flag.") + product.sku + } + private fun recommendedImageUrl(product: Product): String? = recommendedProductAttribute(product, IMAGE_URL_ATTRIBUTES) private fun recommendedProductUrl(product: Product): String? = recommendedProductAttribute(product, PRODUCT_URL_ATTRIBUTES) @@ -1136,7 +1144,7 @@ open class AppboyKit : private fun recommendedLineItems(products: List): List = products.map { product -> EcommerceProduct( - productId = product.sku, + productId = recommendedProductId(product), productName = product.name, variantId = recommendedVariantId(product), price = product.unitPrice, @@ -1151,7 +1159,7 @@ open class AppboyKit : val array = JSONArray() for (product in products) { val obj = JSONObject() - obj.put(RECOMMENDED_PRODUCT_ID_KEY, product.sku) + obj.put(RECOMMENDED_PRODUCT_ID_KEY, recommendedProductId(product)) obj.put(RECOMMENDED_PRODUCT_NAME_KEY, product.name) obj.put(RECOMMENDED_VARIANT_ID_KEY, recommendedVariantId(product)) obj.put(RECOMMENDED_QUANTITY_KEY, product.quantity.toLong().coerceAtLeast(1L)) diff --git a/kits/braze/braze-42/src/test/kotlin/com/mparticle/kits/RecommendedEcommerceTests.kt b/kits/braze/braze-42/src/test/kotlin/com/mparticle/kits/RecommendedEcommerceTests.kt index fcf18f810..7f47b8863 100644 --- a/kits/braze/braze-42/src/test/kotlin/com/mparticle/kits/RecommendedEcommerceTests.kt +++ b/kits/braze/braze-42/src/test/kotlin/com/mparticle/kits/RecommendedEcommerceTests.kt @@ -14,6 +14,8 @@ import com.mparticle.commerce.TransactionAttributes import com.mparticle.identity.IdentityApi import com.mparticle.kits.mocks.MockAppboyKit import com.mparticle.kits.mocks.MockKitConfiguration +import org.json.JSONArray +import org.json.JSONObject import org.junit.Assert import org.junit.Before import org.junit.Test @@ -58,6 +60,14 @@ class RecommendedEcommerceTests { ), ).build() + private fun kitWithReplaceSkuFlag(): MockAppboyKit { + val settings = hashMapOf(AppboyKit.REPLACE_SKU_AS_PRODUCT_NAME to "True") + return MockAppboyKit().apply { + configuration = KitConfiguration.createKitConfiguration(JSONObject().put("as", JSONObject(settings as Map<*, *>))) + useEcommerceRecommendedEvents = true + } + } + @Test fun testAddToCartLogsCartUpdatedAddEvent() { kit.logEvent( @@ -145,6 +155,33 @@ class RecommendedEcommerceTests { Assert.assertEquals("sku2", second.variantId) } + @Test + fun testViewDetailHonorsReplaceSkuWithProductNameFlag() { + kitWithReplaceSkuFlag().logEvent( + CommerceEvent + .Builder(Product.DETAIL, productWithUrls()) + .currency("USD") + .build(), + ) + Assert.assertEquals(1, Braze.ecommerceEvents.size) + val event = Braze.ecommerceEvents[0] as ProductViewedEvent + Assert.assertEquals("product name", event.productId) + Assert.assertEquals("product name", event.productName) + } + + @Test + fun testLineItemsHonorReplaceSkuWithProductNameFlag() { + kitWithReplaceSkuFlag().logEvent( + CommerceEvent + .Builder(Product.ADD_TO_CART, productWithUrls()) + .currency("USD") + .build(), + ) + Assert.assertEquals(1, Braze.ecommerceEvents.size) + val event = Braze.ecommerceEvents[0] as CartUpdatedEvent + Assert.assertEquals("product name", event.products[0].productId) + } + @Test fun testPurchaseLogsOrderPlacedEvent() { val transactionAttributes = @@ -196,6 +233,20 @@ class RecommendedEcommerceTests { Assert.assertNotNull(refund?.properties?.get("products")) } + @Test + fun testRefundProductsJsonHonorsReplaceSkuWithProductNameFlag() { + kitWithReplaceSkuFlag().logEvent( + CommerceEvent + .Builder(Product.REFUND, productWithUrls()) + .currency("USD") + .transactionAttributes(TransactionAttributes("order-42").setRevenue(99.0)) + .build(), + ) + val refund = Braze.events["ecommerce.order_refunded"] + val products = refund?.properties?.get("products") as JSONArray + Assert.assertEquals("product name", products.getJSONObject(0).getString("product_id")) + } + @Test fun testToggleOffFallsBackToLegacyPurchase() { val kit =