From b8cebdecaf9fcb442340c99b986e2f4fff7a7115 Mon Sep 17 00:00:00 2001 From: markvdouw Date: Wed, 28 Jun 2023 15:09:34 -0300 Subject: [PATCH 1/5] fix: Manually adding custom attributes for NON PURCHASE EVENTS (#147) * Manually adding custom attributes for NON PURCHASE EVENTS * Adding commented test --- .../kotlin/com/mparticle/kits/AppboyKit.kt | 29 +++- .../com/mparticle/kits/AppboyKitTest.kt | 128 ++++++++++++++++-- 2 files changed, 135 insertions(+), 22 deletions(-) diff --git a/src/main/kotlin/com/mparticle/kits/AppboyKit.kt b/src/main/kotlin/com/mparticle/kits/AppboyKit.kt index 1e7984c..5e1e216 100644 --- a/src/main/kotlin/com/mparticle/kits/AppboyKit.kt +++ b/src/main/kotlin/com/mparticle/kits/AppboyKit.kt @@ -236,7 +236,13 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener, if (eventList != null) { for (i in eventList.indices) { try { - logEvent(eventList[i]) + val e = eventList[i] + val map = mutableMapOf() + event.customAttributeStrings?.let { map.putAll(it) } + for (pair in map) { + e.customAttributes?.put(pair.key, pair.value) + } + logEvent(e) messages.add(ReportingMessage.fromEvent(this, event)) } catch (e: Exception) { Logger.warning("Failed to call logCustomEvent to Appboy kit: $e") @@ -523,7 +529,7 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener, val eventName = "eCommerce - %s" if (!KitUtils.isEmpty(event?.productAction) && - event?.productAction.equals(Product.PURCHASE,true) + event?.productAction.equals(Product.PURCHASE, true) ) { Braze.Companion.getInstance(context).logPurchase( String.format(eventName, event?.productAction), @@ -534,11 +540,14 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener, ) } else { if (!KitUtils.isEmpty(event?.productAction)) { - Braze.getInstance(context).logCustomEvent(String.format(eventName, event?.productAction), properties) + Braze.getInstance(context) + .logCustomEvent(String.format(eventName, event?.productAction), properties) } else if (!KitUtils.isEmpty(event?.promotionAction)) { - Braze.getInstance(context).logCustomEvent(String.format(eventName, event?.promotionAction), properties) + Braze.getInstance(context) + .logCustomEvent(String.format(eventName, event?.promotionAction), properties) } else { - Braze.getInstance(context).logCustomEvent(String.format(eventName, "Impression"), properties) + Braze.getInstance(context) + .logCustomEvent(String.format(eventName, "Impression"), properties) } } } @@ -763,7 +772,10 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener, for ((i, promotion) in promotionList.withIndex()) { val promotionProperties = BrazeProperties() promotion.creative?.let { - promotionProperties.addProperty(CommerceEventUtils.Constants.ATT_PROMOTION_CREATIVE, it) + promotionProperties.addProperty( + CommerceEventUtils.Constants.ATT_PROMOTION_CREATIVE, + it + ) } promotion.id?.let { promotionProperties.addProperty(CommerceEventUtils.Constants.ATT_PROMOTION_ID, it) @@ -772,7 +784,10 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener, promotionProperties.addProperty(CommerceEventUtils.Constants.ATT_PROMOTION_NAME, it) } promotion.position?.let { - promotionProperties.addProperty(CommerceEventUtils.Constants.ATT_PROMOTION_POSITION, it) + promotionProperties.addProperty( + CommerceEventUtils.Constants.ATT_PROMOTION_POSITION, + it + ) } promotionArray[i] = promotionProperties } diff --git a/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt b/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt index 078be2c..0068304 100644 --- a/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt +++ b/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt @@ -494,11 +494,26 @@ class AppboyKitTests { val productBrazeProperties = productArray[0] if (productBrazeProperties is BrazeProperties) { val productProperties = productBrazeProperties.properties - Assert.assertEquals(productProperties.remove(CommerceEventUtils.Constants.ATT_PRODUCT_TOTAL_AMOUNT), 22.5) - Assert.assertEquals(productProperties.remove(CommerceEventUtils.Constants.ATT_PRODUCT_PRICE), 4.5) - Assert.assertEquals(productProperties.remove(CommerceEventUtils.Constants.ATT_PRODUCT_QUANTITY), 5.0) - Assert.assertEquals(productProperties.remove(CommerceEventUtils.Constants.ATT_PRODUCT_ID), "sku1") - Assert.assertEquals(productProperties.remove(CommerceEventUtils.Constants.ATT_PRODUCT_NAME), "product name") + Assert.assertEquals( + productProperties.remove(CommerceEventUtils.Constants.ATT_PRODUCT_TOTAL_AMOUNT), + 22.5 + ) + Assert.assertEquals( + productProperties.remove(CommerceEventUtils.Constants.ATT_PRODUCT_PRICE), + 4.5 + ) + Assert.assertEquals( + productProperties.remove(CommerceEventUtils.Constants.ATT_PRODUCT_QUANTITY), + 5.0 + ) + Assert.assertEquals( + productProperties.remove(CommerceEventUtils.Constants.ATT_PRODUCT_ID), + "sku1" + ) + Assert.assertEquals( + productProperties.remove(CommerceEventUtils.Constants.ATT_PRODUCT_NAME), + "product name" + ) Assert.assertEquals(emptyAttributes, productProperties) } } @@ -584,7 +599,7 @@ class AppboyKitTests { id = "my_promo_1" creative = "sale_banner_1" name = "App-wide 50% off sale" - position ="dashboard_bottom" + position = "dashboard_bottom" } val commerceEvent = CommerceEvent.Builder(Promotion.VIEW, promotion) .customAttributes(customAttributes) @@ -604,10 +619,22 @@ class AppboyKitTests { val promotionBrazeProperties = promotionArray[0] if (promotionBrazeProperties is BrazeProperties) { val promotionProperties = promotionBrazeProperties.properties - Assert.assertEquals(promotionProperties.remove(CommerceEventUtils.Constants.ATT_PROMOTION_ID), "my_promo_1") - Assert.assertEquals(promotionProperties.remove(CommerceEventUtils.Constants.ATT_PROMOTION_NAME), "App-wide 50% off sale") - Assert.assertEquals(promotionProperties.remove(CommerceEventUtils.Constants.ATT_PROMOTION_POSITION), "dashboard_bottom") - Assert.assertEquals(promotionProperties.remove(CommerceEventUtils.Constants.ATT_PROMOTION_CREATIVE), "sale_banner_1") + Assert.assertEquals( + promotionProperties.remove(CommerceEventUtils.Constants.ATT_PROMOTION_ID), + "my_promo_1" + ) + Assert.assertEquals( + promotionProperties.remove(CommerceEventUtils.Constants.ATT_PROMOTION_NAME), + "App-wide 50% off sale" + ) + Assert.assertEquals( + promotionProperties.remove(CommerceEventUtils.Constants.ATT_PROMOTION_POSITION), + "dashboard_bottom" + ) + Assert.assertEquals( + promotionProperties.remove(CommerceEventUtils.Constants.ATT_PROMOTION_CREATIVE), + "sale_banner_1" + ) Assert.assertEquals(emptyAttributes, promotionProperties) } } @@ -697,7 +724,10 @@ class AppboyKitTests { val impressionBrazeProperties = impressionArray[0] if (impressionBrazeProperties is BrazeProperties) { val impressionProperties = impressionBrazeProperties.properties - Assert.assertEquals(impressionProperties.remove("Product Impression List"), "Suggested Products List") + Assert.assertEquals( + impressionProperties.remove("Product Impression List"), + "Suggested Products List" + ) val productArray = impressionProperties.remove(AppboyKit.PRODUCT_KEY) Assert.assertTrue(productArray is Array<*>) if (productArray is Array<*>) { @@ -725,11 +755,19 @@ class AppboyKitTests { productProperties.remove(CommerceEventUtils.Constants.ATT_PRODUCT_PRICE), 4.5 ) - val brazeProductCustomAttributesDictionary = productProperties.remove(AppboyKit.CUSTOM_ATTRIBUTES_KEY) + val brazeProductCustomAttributesDictionary = + productProperties.remove(AppboyKit.CUSTOM_ATTRIBUTES_KEY) if (brazeProductCustomAttributesDictionary is BrazeProperties) { - val customProductAttributesDictionary = brazeProductCustomAttributesDictionary.properties - Assert.assertEquals(customProductAttributesDictionary.remove("key1"), "value1") - Assert.assertEquals(customProductAttributesDictionary.remove("key #2"), "value #3") + val customProductAttributesDictionary = + brazeProductCustomAttributesDictionary.properties + Assert.assertEquals( + customProductAttributesDictionary.remove("key1"), + "value1" + ) + Assert.assertEquals( + customProductAttributesDictionary.remove("key #2"), + "value #3" + ) Assert.assertEquals(emptyAttributes, customProductAttributesDictionary) } Assert.assertEquals(emptyAttributes, productProperties) @@ -797,6 +835,66 @@ class AppboyKitTests { // Assert.assertEquals(0, properties.size.toLong()) // } +// @Test +// fun testLogCommerceEvent() { +// val kit = MockAppboyKit() +// +// val product: Product = Product.Builder("La Enchilada", "13061043670", 12.5) +// .quantity(1.0) +// .build() +// +// val txAttributes = TransactionAttributes() +// .setRevenue(product.getTotalAmount()) +// +// kit.configuration = MockKitConfiguration() +// val customAttributes: MutableMap = HashMap() +// customAttributes["currentLocationLongitude"] = "2.1811267" +// customAttributes["country"] = "ES" +// customAttributes["deliveryLocationLatitude"] = "41.4035798" +// customAttributes["appVersion"] = "5.201.0" +// customAttributes["city"] = "BCN" +// customAttributes["deviceId"] = "1104442582" +// customAttributes["platform"] = "android" +// customAttributes["isAuthorized"] = "true" +// customAttributes["productSelectionOrigin"] = "Catalogue" +// customAttributes["currentLocationLatitude"] = "41.4035798" +// customAttributes["collectionId"] = "1180889389" +// customAttributes["multiplatformVersion"] = "1.0.288" +// customAttributes["deliveryLocationTimestamp"] = "1675344636685" +// customAttributes["productId"] = "13061043670" +// customAttributes["storeAddressId"] = "300482" +// customAttributes["currentLocationAccuracy"] = "19.278" +// customAttributes["productAddedOrigin"] = "Item Detail Add to Order" +// customAttributes["deliveryLocationLongitude"] = "2.1811267" +// customAttributes["currentLocationTimestamp"] = "1675344636685" +// customAttributes["dynamicSessionId"] = "67f8fb8d-8d14-4f0e-bf1a-73fb8e6eed95" +// customAttributes["deliveryLocationAccuracy"] = "19.278" +// customAttributes["categoryId"] = "1" +// customAttributes["isSponsored"] = "false" +// +// val commerceEvent: CommerceEvent = CommerceEvent.Builder(Product.ADD_TO_CART, product) +// .currency("EUR") +// .customAttributes(customAttributes) +// .transactionAttributes(txAttributes) +// .build() +// kit.logEvent(commerceEvent) +// +// val braze = Braze +// val events = braze.events +// Assert.assertEquals(1, events.size.toLong()) +// val event = events.values.iterator().next() +// Assert.assertNotNull(event.properties) +// val properties = event.properties +// +// Assert.assertEquals(properties.remove("Name"), "La Enchilada") +// Assert.assertEquals(properties.remove("Total Product Amount"), "12.5") +// Assert.assertEquals(properties.remove("Id"), "13061043670") +// for (item in customAttributes) { +// Assert.assertTrue(properties.containsKey(item.key)) +// Assert.assertTrue(properties.containsValue(item.value)) +// } +// } + // @Test // fun testEventStringTypeNotEnabled() { // val kit = MockAppboyKit() From 5395cbc845c398860b547ff73dfb19e0117193a0 Mon Sep 17 00:00:00 2001 From: Brandon Stalnaker <33703490+BrandonStalnaker@users.noreply.github.com> Date: Mon, 17 Jul 2023 19:50:52 -0400 Subject: [PATCH 2/5] fix: Forward Custom Attributes for all Commerce Events (#150) --- src/main/kotlin/com/mparticle/kits/AppboyKit.kt | 7 +++++++ src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/src/main/kotlin/com/mparticle/kits/AppboyKit.kt b/src/main/kotlin/com/mparticle/kits/AppboyKit.kt index 5e1e216..682cb48 100644 --- a/src/main/kotlin/com/mparticle/kits/AppboyKit.kt +++ b/src/main/kotlin/com/mparticle/kits/AppboyKit.kt @@ -451,6 +451,13 @@ open class AppboyKit : KitIntegration(), AttributeListener, CommerceListener, if (KitUtils.isEmpty(currencyValue)) { currencyValue = CommerceEventUtils.Constants.DEFAULT_CURRENCY_CODE } + + event?.customAttributes?.let { + for ((key, value) in it) { + purchaseProperties.addProperty(key, value) + } + } + Braze.Companion.getInstance(context).logPurchase( product.sku, currencyValue, diff --git a/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt b/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt index 0068304..9e4c994 100644 --- a/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt +++ b/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt @@ -449,6 +449,11 @@ class AppboyKitTests { properties.remove(CommerceEventUtils.Constants.ATT_AFFILIATION), "the affiliation" ) + + //Custom Attributes + Assert.assertEquals(properties.remove("key1"), "value1") + Assert.assertEquals(properties.remove("key #2"), "value #3") + val emptyAttributes = HashMap() Assert.assertEquals(emptyAttributes, properties) } From 3d8431e331ab263110fbd54741795c9a855d6663 Mon Sep 17 00:00:00 2001 From: markvdouw Date: Thu, 20 Jul 2023 23:56:27 -0300 Subject: [PATCH 3/5] feat: SQDSDKS-5551 Changing test for sideloading kits feature (#151) Fixing test to accomodate new architecture change for sideloaded kits --- src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt b/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt index 9e4c994..64ca1fb 100644 --- a/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt +++ b/src/test/kotlin/com/mparticle/kits/AppboyKitTest.kt @@ -7,6 +7,7 @@ import com.mparticle.MPEvent import com.mparticle.MParticle import com.mparticle.MParticle.IdentityType import com.mparticle.MParticle.LogLevel +import com.mparticle.MParticleOptions import com.mparticle.commerce.CommerceEvent import com.mparticle.commerce.Impression import com.mparticle.commerce.Product @@ -74,11 +75,12 @@ class AppboyKitTests { @Test @Throws(Exception::class) fun testClassName() { - val factory = KitIntegrationFactory() - val integrations = factory.knownIntegrations + val options = Mockito.mock(MParticleOptions::class.java) + val factory = KitIntegrationFactory(options) + val integrations = factory.supportedKits.values val className = kit.javaClass.name for (integration in integrations) { - if (integration.value == className) { + if (integration.name == className) { return } } From 3d6f516b1ed284b49edf14600a195546a7fe6bde Mon Sep 17 00:00:00 2001 From: Klemen Tusar Date: Tue, 1 Aug 2023 23:41:01 +0200 Subject: [PATCH 4/5] chore: bump android-sdk-ui from 24.3.0 to 25.0.0 (#133) :arrow_up: Upgrade Braze Android SDK from v24 to v25 --- build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 7c9f260..aa15b21 100644 --- a/build.gradle +++ b/build.gradle @@ -43,12 +43,11 @@ android { } repositories { - maven { url "https://appboy.github.io/appboy-android-sdk/sdk" } mavenCentral() } dependencies { compileOnly 'com.google.firebase:firebase-messaging:[10.2.1, )' - api 'com.appboy:android-sdk-ui:24.3.0' + api 'com.braze:android-sdk-ui:25.0.0' testImplementation files('libs/java-json.jar') } From 2d3d0f3ec84f7acb5bf656683e382837ba38bb7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 01:55:18 +0000 Subject: [PATCH 5/5] chore: bump com.braze:android-sdk-ui from 25.0.0 to 27.0.1 Bumps [com.braze:android-sdk-ui](https://github.com/braze-inc/braze-android-sdk) from 25.0.0 to 27.0.1. - [Changelog](https://github.com/braze-inc/braze-android-sdk/blob/master/CHANGELOG.md) - [Commits](https://github.com/braze-inc/braze-android-sdk/commits) --- updated-dependencies: - dependency-name: com.braze:android-sdk-ui dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index aa15b21..cadc98c 100644 --- a/build.gradle +++ b/build.gradle @@ -48,6 +48,6 @@ repositories { dependencies { compileOnly 'com.google.firebase:firebase-messaging:[10.2.1, )' - api 'com.braze:android-sdk-ui:25.0.0' + api 'com.braze:android-sdk-ui:27.0.1' testImplementation files('libs/java-json.jar') }