From 1f37c59c14e773b74dfbf68b675a182610045e38 Mon Sep 17 00:00:00 2001 From: Sarah Koop Date: Thu, 7 Dec 2023 09:34:56 -0600 Subject: [PATCH 1/9] Replace Venmo analytics with FPTI events --- .../braintreepayments/api/VenmoClient.java | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java b/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java index 4077548d4d..aecc893f94 100644 --- a/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java +++ b/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java @@ -80,25 +80,26 @@ public void showVenmoInGooglePlayStore(@NonNull FragmentActivity activity) { public void createPaymentAuthRequest(@NonNull final FragmentActivity activity, @NonNull final VenmoRequest request, @NonNull VenmoPaymentAuthRequestCallback callback) { - braintreeClient.sendAnalyticsEvent("pay-with-venmo.selected"); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED.event); braintreeClient.getConfiguration((configuration, error) -> { if (configuration == null && error != null) { callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.Failure(error)); - braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.failed"); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); return; } String exceptionMessage = null; if (!configuration.isVenmoEnabled()) { exceptionMessage = "Venmo is not enabled"; + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); } else if (!deviceInspector.isVenmoAppSwitchAvailable(activity)) { exceptionMessage = "Venmo is not installed"; + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED.event); } if (exceptionMessage != null) { callback.onVenmoPaymentAuthRequest( new VenmoPaymentAuthRequest.Failure(new AppSwitchNotAvailableException(exceptionMessage))); - braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.failed"); return; } @@ -110,7 +111,7 @@ public void createPaymentAuthRequest(@NonNull final FragmentActivity activity, callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.Failure(new BraintreeException( "Cannot collect customer data when ECD is disabled. Enable this feature " + "in the Control Panel to collect this data."))); - braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.failed"); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); return; } @@ -128,7 +129,7 @@ public void createPaymentAuthRequest(@NonNull final FragmentActivity activity, paymentContextId, callback); } else { callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.Failure(exception)); - braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.failed"); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); } }); }); @@ -150,7 +151,6 @@ private void createPaymentAuthRequest( new VenmoPaymentAuthRequestParams(configuration, venmoProfileId, paymentContextId, braintreeClient.getSessionId(), braintreeClient.getIntegrationType()); callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.ReadyToLaunch(params)); - braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.started"); } /** @@ -166,7 +166,7 @@ private void createPaymentAuthRequest( public void tokenize(@NonNull final VenmoPaymentAuthResult venmoPaymentAuthResult, @NonNull VenmoTokenizeCallback callback) { if (venmoPaymentAuthResult.getError() == null) { - braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.success"); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED.event); final boolean isClientTokenAuth = (braintreeClient.getAuthorization() instanceof ClientToken); @@ -181,19 +181,19 @@ public void tokenize(@NonNull final VenmoPaymentAuthResult venmoPaymentAuthResul vaultVenmoAccountNonce(nonce.getString(), (venmoAccountNonce, vaultError) -> { if (venmoAccountNonce != null) { + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); callback.onVenmoResult(new VenmoResult.Success(venmoAccountNonce)); } else if (vaultError != null) { + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); callback.onVenmoResult(new VenmoResult.Failure(vaultError)); } }); } else { - braintreeClient.sendAnalyticsEvent( - "pay-with-venmo.app-switch.failure"); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); callback.onVenmoResult(new VenmoResult.Success(nonce)); } } else if (error != null) { - braintreeClient.sendAnalyticsEvent( - "pay-with-venmo.app-switch.failure"); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); callback.onVenmoResult(new VenmoResult.Failure(error)); } }); @@ -205,8 +205,10 @@ public void tokenize(@NonNull final VenmoPaymentAuthResult venmoPaymentAuthResul if (shouldVault && isClientTokenAuth) { vaultVenmoAccountNonce(nonce, (venmoAccountNonce, error) -> { if (venmoAccountNonce != null) { + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); callback.onVenmoResult(new VenmoResult.Success(venmoAccountNonce)); } else if (error != null) { + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); callback.onVenmoResult(new VenmoResult.Failure(error)); } }); @@ -214,27 +216,24 @@ public void tokenize(@NonNull final VenmoPaymentAuthResult venmoPaymentAuthResul String venmoUsername = venmoPaymentAuthResult.getVenmoUsername(); VenmoAccountNonce venmoAccountNonce = new VenmoAccountNonce(nonce, venmoUsername, false); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); callback.onVenmoResult(new VenmoResult.Success(venmoAccountNonce)); } } } else if (venmoPaymentAuthResult.getError() != null) { if (venmoPaymentAuthResult.getError() instanceof UserCanceledException) { - braintreeClient.sendAnalyticsEvent("pay-with-venmo.app-switch.canceled"); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_CANCELED.event); + callback.onVenmoResult(VenmoResult.Cancel.INSTANCE); + } else { + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + callback.onVenmoResult(new VenmoResult.Failure(venmoPaymentAuthResult.getError())); } - callback.onVenmoResult(VenmoResult.Cancel.INSTANCE); } } private void vaultVenmoAccountNonce(String nonce, final VenmoInternalCallback callback) { - venmoApi.vaultVenmoAccountNonce(nonce, (venmoAccountNonce, error) -> { - if (venmoAccountNonce != null) { - braintreeClient.sendAnalyticsEvent("pay-with-venmo.vault.success"); - } else { - braintreeClient.sendAnalyticsEvent("pay-with-venmo.vault.failed"); - } - callback.onResult(venmoAccountNonce, error); - }); + venmoApi.vaultVenmoAccountNonce(nonce, (venmoAccountNonce, error) -> callback.onResult(venmoAccountNonce, error)); } /** From e13dc5dd01ea5985602fb0c8317deb2e8ae073de Mon Sep 17 00:00:00 2001 From: Sarah Koop Date: Thu, 7 Dec 2023 09:44:06 -0600 Subject: [PATCH 2/9] Update unit tests --- .../api/VenmoClientUnitTest.java | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java b/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java index 12287c463c..9055a9df00 100644 --- a/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java +++ b/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java @@ -4,7 +4,6 @@ import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.endsWith; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.same; import static org.mockito.Mockito.inOrder; @@ -87,7 +86,6 @@ public void showVenmoInGooglePlayStore_sendsAnalyticsEvent() { ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); verify(activity).startActivity(captor.capture()); - verify(braintreeClient).sendAnalyticsEvent("android.pay-with-venmo.app-store.invoked"); } @Test @@ -117,7 +115,7 @@ public void createPaymentAuthRequest_whenCreatePaymentContextFails_collectAddres sut.createPaymentAuthRequest(activity, request, venmoPaymentAuthRequestCallback); verify(venmoPaymentAuthRequestCallback).onVenmoPaymentAuthRequest(captor.capture()); - verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.app-switch.failed"); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); VenmoPaymentAuthRequest paymentAuthRequest = captor.getValue(); assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.Failure); assertEquals( @@ -149,12 +147,12 @@ public void createPaymentAuthRequest_whenCreatePaymentContextSucceeds_createsVen sut.createPaymentAuthRequest(activity, request, venmoPaymentAuthRequestCallback); InOrder inOrder = Mockito.inOrder(venmoPaymentAuthRequestCallback, braintreeClient); + inOrder.verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED.event); ArgumentCaptor captor = ArgumentCaptor.forClass(VenmoPaymentAuthRequest.class); inOrder.verify(venmoPaymentAuthRequestCallback).onVenmoPaymentAuthRequest(captor.capture()); - inOrder.verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.app-switch.started"); VenmoPaymentAuthRequest paymentAuthRequest = captor.getValue(); assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.ReadyToLaunch); @@ -186,7 +184,7 @@ public void createPaymentAuthRequest_whenConfigurationException_forwardsExceptio VenmoPaymentAuthRequest paymentAuthRequest = captor.getValue(); assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.Failure); assertEquals("Configuration fetching error", ((VenmoPaymentAuthRequest.Failure) paymentAuthRequest).getError().getMessage()); - verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.app-switch.failed"); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); } @Test @@ -209,7 +207,7 @@ public void createPaymentAuthRequest_whenVenmoNotEnabled_forwardsExceptionToList VenmoPaymentAuthRequest paymentAuthRequest = captor.getValue(); assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.Failure); assertEquals("Venmo is not enabled", ((VenmoPaymentAuthRequest.Failure) paymentAuthRequest).getError().getMessage()); - verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.app-switch.failed"); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); } @Test @@ -236,7 +234,7 @@ public void createPaymentAuthRequest_whenVenmoNotInstalled_forwardsExceptionToLi VenmoPaymentAuthRequest paymentAuthRequest = captor.getValue(); assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.Failure); assertEquals("Venmo is not installed", ((VenmoPaymentAuthRequest.Failure) paymentAuthRequest).getError().getMessage()); - verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.app-switch.failed"); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED.event); } @Test @@ -323,7 +321,7 @@ public void createPaymentAuthRequest_sendsAnalyticsEvent() { new VenmoClient(braintreeClient, venmoApi, sharedPrefsWriter, deviceInspector); sut.createPaymentAuthRequest(activity, request, venmoPaymentAuthRequestCallback); - verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.selected"); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED.event); } @Test @@ -347,8 +345,7 @@ public void createPaymentAuthRequest_sendsAnalyticsEventWhenStarted() { new VenmoClient(braintreeClient, venmoApi, sharedPrefsWriter, deviceInspector); sut.createPaymentAuthRequest(activity, request, venmoPaymentAuthRequestCallback); - verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.selected"); - verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.app-switch.started"); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED.event); } @Test @@ -453,8 +450,8 @@ public void createPaymentAuthRequest_sendsAnalyticsEventWhenUnavailableAndPostEx assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.Failure); assertEquals("Venmo is not installed", ((VenmoPaymentAuthRequest.Failure) paymentAuthRequest).getError().getMessage()); - order.verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.selected"); - order.verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.app-switch.failed"); + order.verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED.event); + order.verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED.event); } @Test @@ -482,7 +479,7 @@ public void createPaymentAuthRequest_whenVenmoApiError_forwardsErrorToListener_a VenmoPaymentAuthRequest paymentAuthRequest = captor.getValue(); assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.Failure); assertEquals(graphQLError, ((VenmoPaymentAuthRequest.Failure) paymentAuthRequest).getError()); - verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.app-switch.failed"); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); } @Test @@ -599,7 +596,7 @@ public void tokenize_onGraphQLPostSuccess_returnsNonceToListener_andSendsAnalyti assertEquals("fake-venmo-nonce", nonce.getString()); assertEquals("venmojoe", nonce.getUsername()); - verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.app-switch.success"); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED.event); } @Test @@ -629,7 +626,7 @@ public void tokenize_onGraphQLPostFailure_forwardsExceptionToListener_andSendsAn VenmoResult result = captor.getValue(); assertTrue(result instanceof VenmoResult.Failure); assertEquals(graphQLError, ((VenmoResult.Failure) result).getError()); - verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.app-switch.failure"); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); } @Test @@ -694,7 +691,7 @@ public void tokenize_sendsAnalyticsEventOnSuccess() { null); sut.tokenize(venmoPaymentAuthResult, venmoTokenizeCallback); - verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.app-switch.success"); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED.event); } @Test @@ -707,7 +704,7 @@ public void tokenize_sendsAnalyticsEventOnCancel() { new UserCanceledException("User canceled Venmo.")); sut.tokenize(venmoPaymentAuthResult, venmoTokenizeCallback); - verify(braintreeClient).sendAnalyticsEvent("pay-with-venmo.app-switch.canceled"); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_CANCELED.event); } @Test @@ -814,7 +811,7 @@ public void tokenize_withSuccessfulVaultCall_forwardsResultToActivityResultListe assertTrue(result instanceof VenmoResult.Success); VenmoAccountNonce nonce = ((VenmoResult.Success) result).getNonce(); assertEquals(venmoAccountNonce, nonce); - verify(braintreeClient).sendAnalyticsEvent(endsWith("pay-with-venmo.vault.success")); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); } @Test @@ -854,7 +851,7 @@ public void tokenize_withPaymentContext_withSuccessfulVaultCall_forwardsNonceToC assertTrue(result instanceof VenmoResult.Success); VenmoAccountNonce nonce = ((VenmoResult.Success) result).getNonce(); assertEquals(venmoAccountNonce, nonce); - verify(braintreeClient).sendAnalyticsEvent(endsWith("pay-with-venmo.vault.success")); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); } @Test @@ -887,7 +884,7 @@ public void tokenize_withFailedVaultCall_forwardsErrorToActivityResultListener_a VenmoResult result = captor.getValue(); assertTrue(result instanceof VenmoResult.Failure); assertEquals(error, ((VenmoResult.Failure) result).getError()); - verify(braintreeClient).sendAnalyticsEvent(endsWith("pay-with-venmo.vault.failed")); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); } @Test @@ -927,6 +924,6 @@ public void tokenize_withPaymentContext_withFailedVaultCall_forwardsErrorToCallb VenmoResult result = captor.getValue(); assertTrue(result instanceof VenmoResult.Failure); assertEquals(error, ((VenmoResult.Failure) result).getError()); - verify(braintreeClient).sendAnalyticsEvent(endsWith("pay-with-venmo.vault.failed")); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); } } \ No newline at end of file From c722c9d5b6f291ed4fe91cc30f78d0e7da934576 Mon Sep 17 00:00:00 2001 From: Sarah Koop Date: Thu, 7 Dec 2023 10:16:57 -0600 Subject: [PATCH 3/9] Add new unit tests --- .../api/VenmoClientUnitTest.java | 88 +++++++++++-------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java b/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java index 9055a9df00..98597b3d81 100644 --- a/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java +++ b/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java @@ -76,18 +76,6 @@ public void showVenmoInGooglePlayStore_opensVenmoAppStoreURL() { "https://play.google.com/store/apps/details?id=com.venmo"); } - @Test - public void showVenmoInGooglePlayStore_sendsAnalyticsEvent() { - VenmoClient sut = - new VenmoClient(braintreeClient, venmoApi, sharedPrefsWriter, deviceInspector); - - sut.showVenmoInGooglePlayStore(activity); - - ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - - verify(activity).startActivity(captor.capture()); - } - @Test public void createPaymentAuthRequest_whenCreatePaymentContextFails_collectAddressWithEcdDisabled() { BraintreeClient braintreeClient = new MockBraintreeClientBuilder() @@ -324,30 +312,6 @@ public void createPaymentAuthRequest_sendsAnalyticsEvent() { verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED.event); } - @Test - public void createPaymentAuthRequest_sendsAnalyticsEventWhenStarted() { - BraintreeClient braintreeClient = new MockBraintreeClientBuilder() - .configuration(venmoEnabledConfiguration) - .authorizationSuccess(clientToken) - .build(); - - VenmoApi venmoApi = new MockVenmoApiBuilder() - .createPaymentContextSuccess("venmo-payment-context-id") - .build(); - - VenmoRequest request = new VenmoRequest(VenmoPaymentMethodUsage.SINGLE_USE); - request.setProfileId(null); - request.setShouldVault(false); - - when(deviceInspector.isVenmoAppSwitchAvailable(activity)).thenReturn(true); - - VenmoClient sut = - new VenmoClient(braintreeClient, venmoApi, sharedPrefsWriter, deviceInspector); - sut.createPaymentAuthRequest(activity, request, venmoPaymentAuthRequestCallback); - - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED.event); - } - @Test public void createPaymentAuthRequest_whenShouldVaultIsTrue_persistsVenmoVaultTrue() { BraintreeClient braintreeClient = new MockBraintreeClientBuilder() @@ -564,6 +528,55 @@ public void tokenize_withPaymentContextId_requestFromVenmoApi() { verify(venmoApi).createNonceFromPaymentContext(eq("payment-context-id"), any(VenmoInternalCallback.class)); + + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED.event); + } + + @Test + public void tokenize_withPaymentAuthResultError_whenUserCanceledError_returnsCancelAndSendsAnalytics() { + BraintreeClient braintreeClient = new MockBraintreeClientBuilder() + .configuration(venmoEnabledConfiguration) + .authorizationSuccess(clientToken) + .build(); + + VenmoClient sut = + new VenmoClient(braintreeClient, venmoApi, sharedPrefsWriter, deviceInspector); + + VenmoPaymentAuthResult venmoPaymentAuthResult = + new VenmoPaymentAuthResult(null, null, null, new UserCanceledException("User canceled Venmo.")); + sut.tokenize(venmoPaymentAuthResult, venmoTokenizeCallback); + + ArgumentCaptor captor = ArgumentCaptor.forClass(VenmoResult.class); + verify(venmoTokenizeCallback).onVenmoResult(captor.capture()); + + VenmoResult result = captor.getValue(); + assertTrue(result instanceof VenmoResult.Cancel); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + + } + + @Test + public void tokenize_withPaymentAuthResultError_returnsErrorAndSendsAnalytics() { + BraintreeClient braintreeClient = new MockBraintreeClientBuilder() + .configuration(venmoEnabledConfiguration) + .authorizationSuccess(clientToken) + .build(); + + VenmoClient sut = + new VenmoClient(braintreeClient, venmoApi, sharedPrefsWriter, deviceInspector); + + BraintreeException error = new BraintreeException("Error"); + VenmoPaymentAuthResult venmoPaymentAuthResult = + new VenmoPaymentAuthResult(null, null, null, error); + sut.tokenize(venmoPaymentAuthResult, venmoTokenizeCallback); + + ArgumentCaptor captor = ArgumentCaptor.forClass(VenmoResult.class); + verify(venmoTokenizeCallback).onVenmoResult(captor.capture()); + + VenmoResult result = captor.getValue(); + assertTrue(result instanceof VenmoResult.Failure); + assertEquals(error, ((VenmoResult.Failure) result).getError()); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); } @Test @@ -596,7 +609,7 @@ public void tokenize_onGraphQLPostSuccess_returnsNonceToListener_andSendsAnalyti assertEquals("fake-venmo-nonce", nonce.getString()); assertEquals("venmojoe", nonce.getUsername()); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); } @Test @@ -692,6 +705,7 @@ public void tokenize_sendsAnalyticsEventOnSuccess() { sut.tokenize(venmoPaymentAuthResult, venmoTokenizeCallback); verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); } @Test From 5bb6ce5fcca08244b4d2361b5460cc5970949c56 Mon Sep 17 00:00:00 2001 From: Sarah Koop Date: Thu, 7 Dec 2023 11:01:40 -0600 Subject: [PATCH 4/9] Fix unit tests --- .../java/com/braintreepayments/api/VenmoClientUnitTest.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java b/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java index 98597b3d81..7ba223c76f 100644 --- a/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java +++ b/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java @@ -551,7 +551,7 @@ public void tokenize_withPaymentAuthResultError_whenUserCanceledError_returnsCan VenmoResult result = captor.getValue(); assertTrue(result instanceof VenmoResult.Cancel); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_CANCELED.event); } @@ -695,7 +695,7 @@ public void tokenize_postsPaymentMethodNonceOnSuccess() { } @Test - public void tokenize_sendsAnalyticsEventOnSuccess() { + public void tokenize_sendsAnalyticsEventOnSuccessfulStart() { VenmoClient sut = new VenmoClient(braintreeClient, venmoApi, sharedPrefsWriter, deviceInspector); @@ -705,7 +705,6 @@ public void tokenize_sendsAnalyticsEventOnSuccess() { sut.tokenize(venmoPaymentAuthResult, venmoTokenizeCallback); verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED.event); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); } @Test From 7a9fec839d17f02c2a5e6d0413f65b499c205533 Mon Sep 17 00:00:00 2001 From: Sarah Koop Date: Thu, 7 Dec 2023 11:45:55 -0600 Subject: [PATCH 5/9] Convert VenmoAnalytics to class --- .../braintreepayments/api/VenmoAnalytics.kt | 20 +++++----- .../braintreepayments/api/VenmoClient.java | 32 +++++++-------- .../api/VenmoAnalyticsUnitTest.kt | 12 +++--- .../api/VenmoClientUnitTest.java | 40 +++++++++---------- 4 files changed, 53 insertions(+), 51 deletions(-) diff --git a/Venmo/src/main/java/com/braintreepayments/api/VenmoAnalytics.kt b/Venmo/src/main/java/com/braintreepayments/api/VenmoAnalytics.kt index 8dd26de38b..9f7392a61c 100644 --- a/Venmo/src/main/java/com/braintreepayments/api/VenmoAnalytics.kt +++ b/Venmo/src/main/java/com/braintreepayments/api/VenmoAnalytics.kt @@ -1,14 +1,16 @@ package com.braintreepayments.api -internal enum class VenmoAnalytics(@JvmField val event: String) { +internal class VenmoAnalytics { - // Conversion Events - TOKENIZE_STARTED("venmo:tokenize:started"), - TOKENIZE_FAILED("venmo:tokenize:failed"), - TOKENIZE_SUCCEEDED("venmo:tokenize:succeeded"), - APP_SWITCH_CANCELED("venmo:tokenize:app-switch:canceled"), + companion object { + // Conversion Events + const val TOKENIZE_STARTED = "venmo:tokenize:started" + const val TOKENIZE_FAILED = "venmo:tokenize:failed" + const val TOKENIZE_SUCCEEDED = "venmo:tokenize:succeeded" + const val APP_SWITCH_CANCELED = "venmo:tokenize:app-switch:canceled" - // Additional Detail Events - APP_SWITCH_SUCCEEDED("venmo:tokenize:app-switch:succeeded"), - APP_SWITCH_FAILED("venmo:tokenize:app-switch:failed") + // Additional Detail Events + const val APP_SWITCH_SUCCEEDED = "venmo:tokenize:app-switch:succeeded" + const val APP_SWITCH_FAILED = "venmo:tokenize:app-switch:failed" + } } diff --git a/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java b/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java index aecc893f94..8a79767ccd 100644 --- a/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java +++ b/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java @@ -80,21 +80,21 @@ public void showVenmoInGooglePlayStore(@NonNull FragmentActivity activity) { public void createPaymentAuthRequest(@NonNull final FragmentActivity activity, @NonNull final VenmoRequest request, @NonNull VenmoPaymentAuthRequestCallback callback) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED); braintreeClient.getConfiguration((configuration, error) -> { if (configuration == null && error != null) { callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.Failure(error)); - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); return; } String exceptionMessage = null; if (!configuration.isVenmoEnabled()) { exceptionMessage = "Venmo is not enabled"; - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); } else if (!deviceInspector.isVenmoAppSwitchAvailable(activity)) { exceptionMessage = "Venmo is not installed"; - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED); } if (exceptionMessage != null) { @@ -111,7 +111,7 @@ public void createPaymentAuthRequest(@NonNull final FragmentActivity activity, callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.Failure(new BraintreeException( "Cannot collect customer data when ECD is disabled. Enable this feature " + "in the Control Panel to collect this data."))); - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); return; } @@ -129,7 +129,7 @@ public void createPaymentAuthRequest(@NonNull final FragmentActivity activity, paymentContextId, callback); } else { callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.Failure(exception)); - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); } }); }); @@ -166,7 +166,7 @@ private void createPaymentAuthRequest( public void tokenize(@NonNull final VenmoPaymentAuthResult venmoPaymentAuthResult, @NonNull VenmoTokenizeCallback callback) { if (venmoPaymentAuthResult.getError() == null) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED); final boolean isClientTokenAuth = (braintreeClient.getAuthorization() instanceof ClientToken); @@ -181,19 +181,19 @@ public void tokenize(@NonNull final VenmoPaymentAuthResult venmoPaymentAuthResul vaultVenmoAccountNonce(nonce.getString(), (venmoAccountNonce, vaultError) -> { if (venmoAccountNonce != null) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED); callback.onVenmoResult(new VenmoResult.Success(venmoAccountNonce)); } else if (vaultError != null) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); callback.onVenmoResult(new VenmoResult.Failure(vaultError)); } }); } else { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED); callback.onVenmoResult(new VenmoResult.Success(nonce)); } } else if (error != null) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); callback.onVenmoResult(new VenmoResult.Failure(error)); } }); @@ -205,10 +205,10 @@ public void tokenize(@NonNull final VenmoPaymentAuthResult venmoPaymentAuthResul if (shouldVault && isClientTokenAuth) { vaultVenmoAccountNonce(nonce, (venmoAccountNonce, error) -> { if (venmoAccountNonce != null) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED); callback.onVenmoResult(new VenmoResult.Success(venmoAccountNonce)); } else if (error != null) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); callback.onVenmoResult(new VenmoResult.Failure(error)); } }); @@ -216,17 +216,17 @@ public void tokenize(@NonNull final VenmoPaymentAuthResult venmoPaymentAuthResul String venmoUsername = venmoPaymentAuthResult.getVenmoUsername(); VenmoAccountNonce venmoAccountNonce = new VenmoAccountNonce(nonce, venmoUsername, false); - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED); callback.onVenmoResult(new VenmoResult.Success(venmoAccountNonce)); } } } else if (venmoPaymentAuthResult.getError() != null) { if (venmoPaymentAuthResult.getError() instanceof UserCanceledException) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_CANCELED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_CANCELED); callback.onVenmoResult(VenmoResult.Cancel.INSTANCE); } else { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); callback.onVenmoResult(new VenmoResult.Failure(venmoPaymentAuthResult.getError())); } } diff --git a/Venmo/src/test/java/com/braintreepayments/api/VenmoAnalyticsUnitTest.kt b/Venmo/src/test/java/com/braintreepayments/api/VenmoAnalyticsUnitTest.kt index 81c9334c34..a8e0a97fa9 100644 --- a/Venmo/src/test/java/com/braintreepayments/api/VenmoAnalyticsUnitTest.kt +++ b/Venmo/src/test/java/com/braintreepayments/api/VenmoAnalyticsUnitTest.kt @@ -9,18 +9,18 @@ class VenmoAnalyticsUnitTest { fun testAnalyticsEvents_sendsExpectedEventNames() { assertEquals( "venmo:tokenize:app-switch:canceled", - VenmoAnalytics.APP_SWITCH_CANCELED.event + VenmoAnalytics.APP_SWITCH_CANCELED ) assertEquals( "venmo:tokenize:app-switch:failed", - VenmoAnalytics.APP_SWITCH_FAILED.event + VenmoAnalytics.APP_SWITCH_FAILED ) assertEquals( "venmo:tokenize:app-switch:succeeded", - VenmoAnalytics.APP_SWITCH_SUCCEEDED.event + VenmoAnalytics.APP_SWITCH_SUCCEEDED ) - assertEquals("venmo:tokenize:failed", VenmoAnalytics.TOKENIZE_FAILED.event) - assertEquals("venmo:tokenize:started", VenmoAnalytics.TOKENIZE_STARTED.event) - assertEquals("venmo:tokenize:succeeded", VenmoAnalytics.TOKENIZE_SUCCEEDED.event) + assertEquals("venmo:tokenize:failed", VenmoAnalytics.TOKENIZE_FAILED) + assertEquals("venmo:tokenize:started", VenmoAnalytics.TOKENIZE_STARTED) + assertEquals("venmo:tokenize:succeeded", VenmoAnalytics.TOKENIZE_SUCCEEDED) } } diff --git a/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java b/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java index 7ba223c76f..8a8d252c04 100644 --- a/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java +++ b/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java @@ -103,7 +103,7 @@ public void createPaymentAuthRequest_whenCreatePaymentContextFails_collectAddres sut.createPaymentAuthRequest(activity, request, venmoPaymentAuthRequestCallback); verify(venmoPaymentAuthRequestCallback).onVenmoPaymentAuthRequest(captor.capture()); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); VenmoPaymentAuthRequest paymentAuthRequest = captor.getValue(); assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.Failure); assertEquals( @@ -135,7 +135,7 @@ public void createPaymentAuthRequest_whenCreatePaymentContextSucceeds_createsVen sut.createPaymentAuthRequest(activity, request, venmoPaymentAuthRequestCallback); InOrder inOrder = Mockito.inOrder(venmoPaymentAuthRequestCallback, braintreeClient); - inOrder.verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED.event); + inOrder.verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED); ArgumentCaptor captor = ArgumentCaptor.forClass(VenmoPaymentAuthRequest.class); @@ -172,7 +172,7 @@ public void createPaymentAuthRequest_whenConfigurationException_forwardsExceptio VenmoPaymentAuthRequest paymentAuthRequest = captor.getValue(); assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.Failure); assertEquals("Configuration fetching error", ((VenmoPaymentAuthRequest.Failure) paymentAuthRequest).getError().getMessage()); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); } @Test @@ -195,7 +195,7 @@ public void createPaymentAuthRequest_whenVenmoNotEnabled_forwardsExceptionToList VenmoPaymentAuthRequest paymentAuthRequest = captor.getValue(); assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.Failure); assertEquals("Venmo is not enabled", ((VenmoPaymentAuthRequest.Failure) paymentAuthRequest).getError().getMessage()); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); } @Test @@ -222,7 +222,7 @@ public void createPaymentAuthRequest_whenVenmoNotInstalled_forwardsExceptionToLi VenmoPaymentAuthRequest paymentAuthRequest = captor.getValue(); assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.Failure); assertEquals("Venmo is not installed", ((VenmoPaymentAuthRequest.Failure) paymentAuthRequest).getError().getMessage()); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED); } @Test @@ -309,7 +309,7 @@ public void createPaymentAuthRequest_sendsAnalyticsEvent() { new VenmoClient(braintreeClient, venmoApi, sharedPrefsWriter, deviceInspector); sut.createPaymentAuthRequest(activity, request, venmoPaymentAuthRequestCallback); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED); } @Test @@ -414,8 +414,8 @@ public void createPaymentAuthRequest_sendsAnalyticsEventWhenUnavailableAndPostEx assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.Failure); assertEquals("Venmo is not installed", ((VenmoPaymentAuthRequest.Failure) paymentAuthRequest).getError().getMessage()); - order.verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED.event); - order.verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED.event); + order.verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED); + order.verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED); } @Test @@ -443,7 +443,7 @@ public void createPaymentAuthRequest_whenVenmoApiError_forwardsErrorToListener_a VenmoPaymentAuthRequest paymentAuthRequest = captor.getValue(); assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.Failure); assertEquals(graphQLError, ((VenmoPaymentAuthRequest.Failure) paymentAuthRequest).getError()); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); } @Test @@ -529,7 +529,7 @@ public void tokenize_withPaymentContextId_requestFromVenmoApi() { verify(venmoApi).createNonceFromPaymentContext(eq("payment-context-id"), any(VenmoInternalCallback.class)); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED); } @Test @@ -551,7 +551,7 @@ public void tokenize_withPaymentAuthResultError_whenUserCanceledError_returnsCan VenmoResult result = captor.getValue(); assertTrue(result instanceof VenmoResult.Cancel); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_CANCELED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_CANCELED); } @@ -576,7 +576,7 @@ public void tokenize_withPaymentAuthResultError_returnsErrorAndSendsAnalytics() VenmoResult result = captor.getValue(); assertTrue(result instanceof VenmoResult.Failure); assertEquals(error, ((VenmoResult.Failure) result).getError()); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); } @Test @@ -609,7 +609,7 @@ public void tokenize_onGraphQLPostSuccess_returnsNonceToListener_andSendsAnalyti assertEquals("fake-venmo-nonce", nonce.getString()); assertEquals("venmojoe", nonce.getUsername()); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED); } @Test @@ -639,7 +639,7 @@ public void tokenize_onGraphQLPostFailure_forwardsExceptionToListener_andSendsAn VenmoResult result = captor.getValue(); assertTrue(result instanceof VenmoResult.Failure); assertEquals(graphQLError, ((VenmoResult.Failure) result).getError()); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); } @Test @@ -704,7 +704,7 @@ public void tokenize_sendsAnalyticsEventOnSuccessfulStart() { null); sut.tokenize(venmoPaymentAuthResult, venmoTokenizeCallback); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_SUCCEEDED); } @Test @@ -717,7 +717,7 @@ public void tokenize_sendsAnalyticsEventOnCancel() { new UserCanceledException("User canceled Venmo.")); sut.tokenize(venmoPaymentAuthResult, venmoTokenizeCallback); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_CANCELED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_CANCELED); } @Test @@ -824,7 +824,7 @@ public void tokenize_withSuccessfulVaultCall_forwardsResultToActivityResultListe assertTrue(result instanceof VenmoResult.Success); VenmoAccountNonce nonce = ((VenmoResult.Success) result).getNonce(); assertEquals(venmoAccountNonce, nonce); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED); } @Test @@ -864,7 +864,7 @@ public void tokenize_withPaymentContext_withSuccessfulVaultCall_forwardsNonceToC assertTrue(result instanceof VenmoResult.Success); VenmoAccountNonce nonce = ((VenmoResult.Success) result).getNonce(); assertEquals(venmoAccountNonce, nonce); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED); } @Test @@ -897,7 +897,7 @@ public void tokenize_withFailedVaultCall_forwardsErrorToActivityResultListener_a VenmoResult result = captor.getValue(); assertTrue(result instanceof VenmoResult.Failure); assertEquals(error, ((VenmoResult.Failure) result).getError()); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); } @Test @@ -937,6 +937,6 @@ public void tokenize_withPaymentContext_withFailedVaultCall_forwardsErrorToCallb VenmoResult result = captor.getValue(); assertTrue(result instanceof VenmoResult.Failure); assertEquals(error, ((VenmoResult.Failure) result).getError()); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED.event); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); } } \ No newline at end of file From 2d5cfe0fb1d0b61224103ad6a4a7f2148cd3797e Mon Sep 17 00:00:00 2001 From: Sarah Koop Date: Thu, 7 Dec 2023 11:56:46 -0600 Subject: [PATCH 6/9] Remove companion object --- .../braintreepayments/api/VenmoAnalytics.kt | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Venmo/src/main/java/com/braintreepayments/api/VenmoAnalytics.kt b/Venmo/src/main/java/com/braintreepayments/api/VenmoAnalytics.kt index 9f7392a61c..bf42cd4d0c 100644 --- a/Venmo/src/main/java/com/braintreepayments/api/VenmoAnalytics.kt +++ b/Venmo/src/main/java/com/braintreepayments/api/VenmoAnalytics.kt @@ -1,16 +1,14 @@ package com.braintreepayments.api -internal class VenmoAnalytics { +internal object VenmoAnalytics { - companion object { - // Conversion Events - const val TOKENIZE_STARTED = "venmo:tokenize:started" - const val TOKENIZE_FAILED = "venmo:tokenize:failed" - const val TOKENIZE_SUCCEEDED = "venmo:tokenize:succeeded" - const val APP_SWITCH_CANCELED = "venmo:tokenize:app-switch:canceled" + // Conversion Events + const val TOKENIZE_STARTED = "venmo:tokenize:started" + const val TOKENIZE_FAILED = "venmo:tokenize:failed" + const val TOKENIZE_SUCCEEDED = "venmo:tokenize:succeeded" + const val APP_SWITCH_CANCELED = "venmo:tokenize:app-switch:canceled" - // Additional Detail Events - const val APP_SWITCH_SUCCEEDED = "venmo:tokenize:app-switch:succeeded" - const val APP_SWITCH_FAILED = "venmo:tokenize:app-switch:failed" - } + // Additional Detail Events + const val APP_SWITCH_SUCCEEDED = "venmo:tokenize:app-switch:succeeded" + const val APP_SWITCH_FAILED = "venmo:tokenize:app-switch:failed" } From ef8b821f1dd1049293a73880cfbaae19e9041bd4 Mon Sep 17 00:00:00 2001 From: Sarah Koop Date: Thu, 7 Dec 2023 14:44:40 -0600 Subject: [PATCH 7/9] Add helper analtyics methods --- .../braintreepayments/api/VenmoClient.java | 77 +++++++++++-------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java b/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java index 8a79767ccd..8dbd8c532a 100644 --- a/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java +++ b/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java @@ -83,23 +83,18 @@ public void createPaymentAuthRequest(@NonNull final FragmentActivity activity, braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_STARTED); braintreeClient.getConfiguration((configuration, error) -> { if (configuration == null && error != null) { - callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.Failure(error)); - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); + callbackPaymentAuthFailure(callback, new VenmoPaymentAuthRequest.Failure(error)); return; } - String exceptionMessage = null; if (!configuration.isVenmoEnabled()) { - exceptionMessage = "Venmo is not enabled"; - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); - } else if (!deviceInspector.isVenmoAppSwitchAvailable(activity)) { - exceptionMessage = "Venmo is not installed"; - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED); + callbackPaymentAuthFailure(callback, + new VenmoPaymentAuthRequest.Failure(new AppSwitchNotAvailableException("Venmo is not enabled"))); + return; } - - if (exceptionMessage != null) { - callback.onVenmoPaymentAuthRequest( - new VenmoPaymentAuthRequest.Failure(new AppSwitchNotAvailableException(exceptionMessage))); + if (!deviceInspector.isVenmoAppSwitchAvailable(activity)) { + callbackPaymentAuthAppSwitchFailure(callback, + new VenmoPaymentAuthRequest.Failure(new AppSwitchNotAvailableException("Venmo is not installed"))); return; } @@ -108,10 +103,9 @@ public void createPaymentAuthRequest(@NonNull final FragmentActivity activity, if ((request.getCollectCustomerShippingAddress() || request.getCollectCustomerBillingAddress()) && !configuration.getVenmoEnrichedCustomerDataEnabled()) { - callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.Failure(new BraintreeException( + callbackPaymentAuthFailure(callback, new VenmoPaymentAuthRequest.Failure(new BraintreeException( "Cannot collect customer data when ECD is disabled. Enable this feature " + "in the Control Panel to collect this data."))); - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); return; } @@ -128,8 +122,7 @@ public void createPaymentAuthRequest(@NonNull final FragmentActivity activity, braintreeClient.getAuthorization(), finalVenmoProfileId, paymentContextId, callback); } else { - callback.onVenmoPaymentAuthRequest(new VenmoPaymentAuthRequest.Failure(exception)); - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); + callbackPaymentAuthFailure(callback, new VenmoPaymentAuthRequest.Failure(exception)); } }); }); @@ -181,20 +174,16 @@ public void tokenize(@NonNull final VenmoPaymentAuthResult venmoPaymentAuthResul vaultVenmoAccountNonce(nonce.getString(), (venmoAccountNonce, vaultError) -> { if (venmoAccountNonce != null) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED); - callback.onVenmoResult(new VenmoResult.Success(venmoAccountNonce)); + callbackSuccess(callback, new VenmoResult.Success(venmoAccountNonce)); } else if (vaultError != null) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); - callback.onVenmoResult(new VenmoResult.Failure(vaultError)); + callbackTokenizeFailure(callback, new VenmoResult.Failure(vaultError)); } }); } else { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED); - callback.onVenmoResult(new VenmoResult.Success(nonce)); + callbackSuccess(callback, new VenmoResult.Success(nonce)); } } else if (error != null) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); - callback.onVenmoResult(new VenmoResult.Failure(error)); + callbackTokenizeFailure(callback, new VenmoResult.Failure(error)); } }); } else { @@ -205,29 +194,24 @@ public void tokenize(@NonNull final VenmoPaymentAuthResult venmoPaymentAuthResul if (shouldVault && isClientTokenAuth) { vaultVenmoAccountNonce(nonce, (venmoAccountNonce, error) -> { if (venmoAccountNonce != null) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED); - callback.onVenmoResult(new VenmoResult.Success(venmoAccountNonce)); + callbackSuccess(callback, new VenmoResult.Success(venmoAccountNonce)); } else if (error != null) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); - callback.onVenmoResult(new VenmoResult.Failure(error)); + callbackTokenizeFailure(callback, new VenmoResult.Failure(error)); } }); } else { String venmoUsername = venmoPaymentAuthResult.getVenmoUsername(); VenmoAccountNonce venmoAccountNonce = new VenmoAccountNonce(nonce, venmoUsername, false); - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED); - callback.onVenmoResult(new VenmoResult.Success(venmoAccountNonce)); + callbackSuccess(callback, new VenmoResult.Success(venmoAccountNonce)); } } } else if (venmoPaymentAuthResult.getError() != null) { if (venmoPaymentAuthResult.getError() instanceof UserCanceledException) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_CANCELED); - callback.onVenmoResult(VenmoResult.Cancel.INSTANCE); + callbackTokenizeCancel(callback); } else { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); - callback.onVenmoResult(new VenmoResult.Failure(venmoPaymentAuthResult.getError())); + callbackTokenizeFailure(callback, new VenmoResult.Failure(venmoPaymentAuthResult.getError())); } } } @@ -269,4 +253,29 @@ public void isReadyToPay(final Context context, final VenmoIsReadyToPayCallback } }); } + + private void callbackPaymentAuthAppSwitchFailure(VenmoPaymentAuthRequestCallback callback, VenmoPaymentAuthRequest request) { + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED); + callback.onVenmoPaymentAuthRequest(request); + } + + private void callbackPaymentAuthFailure(VenmoPaymentAuthRequestCallback callback, VenmoPaymentAuthRequest request) { + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); + callback.onVenmoPaymentAuthRequest(request); + } + + private void callbackSuccess(VenmoTokenizeCallback callback, VenmoResult venmoResult) { + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_SUCCEEDED); + callback.onVenmoResult(venmoResult); + } + + private void callbackTokenizeCancel(VenmoTokenizeCallback callback) { + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_CANCELED); + callback.onVenmoResult(VenmoResult.Cancel.INSTANCE); + } + + private void callbackTokenizeFailure(VenmoTokenizeCallback callback, VenmoResult venmoResult) { + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); + callback.onVenmoResult(venmoResult); + } } From 8de3d07f4f9353af819f40ae16d08412e6a19d1d Mon Sep 17 00:00:00 2001 From: Sarah Koop Date: Mon, 11 Dec 2023 09:34:21 -0600 Subject: [PATCH 8/9] Update app switch failure analytics --- .../main/java/com/braintreepayments/api/VenmoClient.java | 8 ++------ .../com/braintreepayments/api/VenmoClientUnitTest.java | 3 ++- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java b/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java index 8dbd8c532a..93c0df4557 100644 --- a/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java +++ b/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java @@ -93,7 +93,8 @@ public void createPaymentAuthRequest(@NonNull final FragmentActivity activity, return; } if (!deviceInspector.isVenmoAppSwitchAvailable(activity)) { - callbackPaymentAuthAppSwitchFailure(callback, + braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED); + callbackPaymentAuthFailure(callback, new VenmoPaymentAuthRequest.Failure(new AppSwitchNotAvailableException("Venmo is not installed"))); return; } @@ -254,11 +255,6 @@ public void isReadyToPay(final Context context, final VenmoIsReadyToPayCallback }); } - private void callbackPaymentAuthAppSwitchFailure(VenmoPaymentAuthRequestCallback callback, VenmoPaymentAuthRequest request) { - braintreeClient.sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED); - callback.onVenmoPaymentAuthRequest(request); - } - private void callbackPaymentAuthFailure(VenmoPaymentAuthRequestCallback callback, VenmoPaymentAuthRequest request) { braintreeClient.sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); callback.onVenmoPaymentAuthRequest(request); diff --git a/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java b/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java index 8a8d252c04..38e5f2e3ae 100644 --- a/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java +++ b/Venmo/src/test/java/com/braintreepayments/api/VenmoClientUnitTest.java @@ -216,13 +216,14 @@ public void createPaymentAuthRequest_whenVenmoNotInstalled_forwardsExceptionToLi verify(deviceInspector).isVenmoAppSwitchAvailable(same(activity)); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED); ArgumentCaptor captor = ArgumentCaptor.forClass(VenmoPaymentAuthRequest.class); verify(venmoPaymentAuthRequestCallback).onVenmoPaymentAuthRequest(captor.capture()); VenmoPaymentAuthRequest paymentAuthRequest = captor.getValue(); assertTrue(paymentAuthRequest instanceof VenmoPaymentAuthRequest.Failure); assertEquals("Venmo is not installed", ((VenmoPaymentAuthRequest.Failure) paymentAuthRequest).getError().getMessage()); - verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.APP_SWITCH_FAILED); + verify(braintreeClient).sendAnalyticsEvent(VenmoAnalytics.TOKENIZE_FAILED); } @Test From de18ecd0ac069bd04f22fb22f1623228c7d01c63 Mon Sep 17 00:00:00 2001 From: Sarah Koop Date: Mon, 11 Dec 2023 11:27:48 -0600 Subject: [PATCH 9/9] Remove extra analytics event --- Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java | 1 - 1 file changed, 1 deletion(-) diff --git a/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java b/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java index 93c0df4557..7f7399472a 100644 --- a/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java +++ b/Venmo/src/main/java/com/braintreepayments/api/VenmoClient.java @@ -57,7 +57,6 @@ public VenmoClient(@NonNull Context context, @NonNull String authorization) { * @param activity used to open the Venmo's Google Play Store */ public void showVenmoInGooglePlayStore(@NonNull FragmentActivity activity) { - braintreeClient.sendAnalyticsEvent("android.pay-with-venmo.app-store.invoked"); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse( "https://play.google.com/store/apps/details?id=" + VENMO_PACKAGE_NAME));