From 711826851955df68415c0664345bfcebbff7fd85 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 13:41:55 -0500 Subject: [PATCH 01/20] Rename DropInIntentData to DropInLaunchIntent. --- .../api/DropInActivityResultContract.java | 4 ++-- .../com/braintreepayments/api/DropInClient.java | 12 ++++++------ ...opInIntentData.java => DropInLaunchIntent.java} | 4 ++-- .../api/DropInLifecycleObserver.java | 4 ++-- .../api/DropInActivityResultContractUnitTest.java | 2 +- .../api/DropInClientUnitTestKt.kt | 4 ++-- .../api/DropInLifecycleObserverUnitTest.kt | 14 +++++++++----- 7 files changed, 24 insertions(+), 20 deletions(-) rename Drop-In/src/main/java/com/braintreepayments/api/{DropInIntentData.java => DropInLaunchIntent.java} (80%) diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java index 881ac99bc..e1b4b36ce 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java @@ -15,11 +15,11 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -class DropInActivityResultContract extends ActivityResultContract { +class DropInActivityResultContract extends ActivityResultContract { @NonNull @Override - public Intent createIntent(@NonNull Context context, DropInIntentData input) { + public Intent createIntent(@NonNull Context context, DropInLaunchIntent input) { Bundle dropInRequestBundle = new Bundle(); dropInRequestBundle.putParcelable(EXTRA_CHECKOUT_REQUEST, input.getDropInRequest()); return new Intent(context, DropInActivity.class) diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java index 92fbe631c..114226e8a 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java @@ -211,8 +211,8 @@ public void launchDropInForResult(FragmentActivity activity, int requestCode) { getAuthorization((authorization, authorizationError) -> { if (authorization != null) { if (observer != null) { - DropInIntentData intentData = - new DropInIntentData(dropInRequest, authorization, braintreeClient.getSessionId()); + DropInLaunchIntent intentData = + new DropInLaunchIntent(dropInRequest, authorization, braintreeClient.getSessionId()); observer.launch(intentData); } else { Bundle dropInRequestBundle = new Bundle(); @@ -250,8 +250,8 @@ public void launchDropInForResult(FragmentActivity activity, int requestCode) { public void launchDropIn() { getAuthorization((authorization, authorizationError) -> { if (authorization != null && observer != null) { - DropInIntentData intentData = - new DropInIntentData(dropInRequest, authorization, braintreeClient.getSessionId()); + DropInLaunchIntent intentData = + new DropInLaunchIntent(dropInRequest, authorization, braintreeClient.getSessionId()); observer.launch(intentData); } else if (authorizationError != null && listener != null) { listener.onDropInFailure(authorizationError); @@ -273,8 +273,8 @@ public void launchDropIn() { public void launchDropIn(DropInRequest request) { getAuthorization((authorization, authorizationError) -> { if (authorization != null && observer != null) { - DropInIntentData intentData = - new DropInIntentData(request, authorization, braintreeClient.getSessionId()); + DropInLaunchIntent intentData = + new DropInLaunchIntent(request, authorization, braintreeClient.getSessionId()); observer.launch(intentData); } else if (authorizationError != null && listener != null) { listener.onDropInFailure(authorizationError); diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInIntentData.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java similarity index 80% rename from Drop-In/src/main/java/com/braintreepayments/api/DropInIntentData.java rename to Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java index 79edccdfa..fa40af731 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInIntentData.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java @@ -1,12 +1,12 @@ package com.braintreepayments.api; -class DropInIntentData { +class DropInLaunchIntent { private final Authorization authorization; private final DropInRequest dropInRequest; private final String sessionId; - DropInIntentData(DropInRequest dropInRequest, Authorization authorization, String sessionId) { + DropInLaunchIntent(DropInRequest dropInRequest, Authorization authorization, String sessionId) { this.sessionId = sessionId; this.dropInRequest = dropInRequest; this.authorization = authorization; diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLifecycleObserver.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLifecycleObserver.java index 99d753525..936d0db4d 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLifecycleObserver.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLifecycleObserver.java @@ -18,7 +18,7 @@ class DropInLifecycleObserver implements DefaultLifecycleObserver { final ActivityResultRegistry activityResultRegistry; @VisibleForTesting - ActivityResultLauncher activityLauncher; + ActivityResultLauncher activityLauncher; DropInLifecycleObserver(ActivityResultRegistry activityResultRegistry, DropInClient dropInClient) { this.dropInClient = dropInClient; @@ -34,7 +34,7 @@ public void onCreate(@NonNull LifecycleOwner owner) { dropInResult -> dropInClient.onDropInResult(dropInResult)); } - void launch(DropInIntentData intentData) { + void launch(DropInLaunchIntent intentData) { activityLauncher.launch(intentData); } } diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java b/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java index 16ae70412..aa8a80fed 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java @@ -42,7 +42,7 @@ public void createIntent_returnsIntentWithExtras() { DropInRequest dropInRequest = new DropInRequest(); Authorization authorization = Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN); - DropInIntentData input = new DropInIntentData(dropInRequest, authorization, sessionId); + DropInLaunchIntent input = new DropInLaunchIntent(dropInRequest, authorization, sessionId); Intent intent = sut.createIntent(context, input); diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTestKt.kt b/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTestKt.kt index f55e98549..951c56eb4 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTestKt.kt +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTestKt.kt @@ -128,7 +128,7 @@ class DropInClientUnitTestKt { val sut = DropInClient(params) sut.observer = mockk() - val intentDataSlot = slot() + val intentDataSlot = slot() justRun { sut.observer.launch(capture(intentDataSlot)) } sut.launchDropInForResult(activity, 123) @@ -154,7 +154,7 @@ class DropInClientUnitTestKt { val sut = DropInClient(params) sut.observer = mockk() - val intentDataSlot = slot() + val intentDataSlot = slot() justRun { sut.observer.launch(capture(intentDataSlot)) } sut.launchDropIn() diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInLifecycleObserverUnitTest.kt b/Drop-In/src/test/java/com/braintreepayments/api/DropInLifecycleObserverUnitTest.kt index a9cd4def9..cb28f8433 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInLifecycleObserverUnitTest.kt +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInLifecycleObserverUnitTest.kt @@ -43,7 +43,7 @@ class DropInLifecycleObserverUnitTest : TestCase() { val dropInClient = mockk(relaxed = true) val callbackSlot = slot>() - val activityLauncher: ActivityResultLauncher = mockk(relaxed = true) + val activityLauncher: ActivityResultLauncher = mockk(relaxed = true) every { activityResultRegistry.register( any(), @@ -70,7 +70,7 @@ class DropInLifecycleObserverUnitTest : TestCase() { val activityResultRegistry = mockk(relaxed = true) val dropInClient = mockk(relaxed = true) - val activityLauncher: ActivityResultLauncher = mockk(relaxed = true) + val activityLauncher: ActivityResultLauncher = mockk(relaxed = true) every { activityResultRegistry.register( any(), @@ -85,9 +85,13 @@ class DropInLifecycleObserverUnitTest : TestCase() { val lifecycleOwner = FragmentActivity() sut.onCreate(lifecycleOwner) - val dropInIntentData = DropInIntentData(dropInRequest, authorization, "sample-session-id") - sut.launch(dropInIntentData) + val dropInLaunchIntent = DropInLaunchIntent( + dropInRequest, + authorization, + "sample-session-id" + ) + sut.launch(dropInLaunchIntent) - verify { activityLauncher.launch(dropInIntentData) } + verify { activityLauncher.launch(dropInLaunchIntent) } } } \ No newline at end of file From 257d30ef6f0550c8ce002781549740705bb56366 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 13:44:32 -0500 Subject: [PATCH 02/20] Remove deprecated DropInClient methods. --- .../braintreepayments/api/DropInClient.java | 123 ------------------ 1 file changed, 123 deletions(-) diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java index 114226e8a..acfd28d7c 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java @@ -58,32 +58,6 @@ private static DropInClientParams createDefaultParams(Context context, String au .dropInSharedPreferences(DropInSharedPreferences.getInstance(context.getApplicationContext())); } - /** - * @param context a {@link Context} - * @param authorization a Tokenization Key or Client Token authorization String. - * @param dropInRequest a {@link DropInRequest} configured with options for launching Drop-in - * @deprecated use {@link #DropInClient(FragmentActivity, String)} or {@link #DropInClient(Fragment, String)} instead. - *

- * Create a new instance of {@link DropInClient}. - */ - @Deprecated - public DropInClient(Context context, String authorization, DropInRequest dropInRequest) { - this(createDefaultParams(context, authorization, null, dropInRequest, null, null)); - } - - /** - * @param activity a {@link FragmentActivity} - * @param dropInRequest a {@link DropInRequest} configured with options for launching Drop-in - * @param authorization a Tokenization Key authorization string - * @deprecated use {@link #DropInClient(FragmentActivity, String)} instead. - *

- * Create a new instance of {@link DropInClient} from within an Activity using a Tokenization Key authorization. - */ - @Deprecated - public DropInClient(FragmentActivity activity, DropInRequest dropInRequest, String authorization) { - this(activity, activity.getLifecycle(), authorization, dropInRequest); - } - /** * Create a new instance of {@link DropInClient} from within an Activity using a Tokenization Key authorization. * @@ -94,19 +68,6 @@ public DropInClient(FragmentActivity activity, String authorization) { this(activity, activity.getLifecycle(), authorization, null); } - /** - * @param fragment a {@link Fragment} - * @param dropInRequest a {@link DropInRequest} configured with options for launching Drop-in - * @param authorization a Tokenization Key authorization string - * @deprecated use {@link #DropInClient(Fragment, String)} instead. - *

- * Create a new instance of {@link DropInClient} from within a Fragment using a Tokenization Key authorization. - */ - @Deprecated - public DropInClient(Fragment fragment, DropInRequest dropInRequest, String authorization) { - this(fragment.requireActivity(), fragment.getLifecycle(), authorization, dropInRequest); - } - /** * Create a new instance of {@link DropInClient} from within a Fragment using a Tokenization Key authorization. * @@ -117,19 +78,6 @@ public DropInClient(Fragment fragment, String authorization) { this(fragment.requireActivity(), fragment.getLifecycle(), authorization, null); } - /** - * @param activity a {@link FragmentActivity} - * @param dropInRequest a {@link DropInRequest} configured with options for launching Drop-in - * @param clientTokenProvider a {@link ClientTokenProvider} - * @deprecated use {@link #DropInClient(FragmentActivity, ClientTokenProvider)} instead. - *

- * Create a new instance of {@link DropInClient} from within an Activity using a {@link ClientTokenProvider} to fetch authorization. - */ - @Deprecated - public DropInClient(FragmentActivity activity, DropInRequest dropInRequest, ClientTokenProvider clientTokenProvider) { - this(createDefaultParams(activity, null, clientTokenProvider, dropInRequest, activity, activity.getLifecycle())); - } - /** * Create a new instance of {@link DropInClient} from within an Activity using a {@link ClientTokenProvider} to fetch authorization. * @@ -140,19 +88,6 @@ public DropInClient(FragmentActivity activity, ClientTokenProvider clientTokenPr this(createDefaultParams(activity, null, clientTokenProvider, null, activity, activity.getLifecycle())); } - /** - * @param fragment a {@link Fragment} - * @param dropInRequest a {@link DropInRequest} configured with options for launching Drop-in - * @param clientTokenProvider a {@link ClientTokenProvider} - * @deprecated use {@link #DropInClient(Fragment, ClientTokenProvider)} instead. - *

- * Create a new instance of {@link DropInClient} from within a Fragment using a {@link ClientTokenProvider} to fetch authorization. - */ - @Deprecated - public DropInClient(Fragment fragment, DropInRequest dropInRequest, ClientTokenProvider clientTokenProvider) { - this(createDefaultParams(fragment.requireActivity(), null, clientTokenProvider, dropInRequest, fragment.requireActivity(), fragment.getLifecycle())); - } - /** * Create a new instance of {@link DropInClient} from within a Fragment using a {@link ClientTokenProvider} to fetch authorization. * @@ -201,64 +136,6 @@ void getAuthorization(AuthorizationCallback callback) { braintreeClient.getAuthorization(callback); } - /** - * @param activity the current {@link FragmentActivity} - * @param requestCode the request code for the activity that will be launched - * @deprecated use {@link #launchDropIn(DropInRequest)} instead - */ - @Deprecated - public void launchDropInForResult(FragmentActivity activity, int requestCode) { - getAuthorization((authorization, authorizationError) -> { - if (authorization != null) { - if (observer != null) { - DropInLaunchIntent intentData = - new DropInLaunchIntent(dropInRequest, authorization, braintreeClient.getSessionId()); - observer.launch(intentData); - } else { - Bundle dropInRequestBundle = new Bundle(); - dropInRequestBundle.putParcelable(EXTRA_CHECKOUT_REQUEST, dropInRequest); - Intent intent = new Intent(activity, DropInActivity.class) - .putExtra(EXTRA_CHECKOUT_REQUEST_BUNDLE, dropInRequestBundle) - .putExtra(EXTRA_SESSION_ID, braintreeClient.getSessionId()) - .putExtra(EXTRA_AUTHORIZATION, authorization.toString()); - activity.startActivityForResult(intent, requestCode); - } - } else if (authorizationError != null) { - if (listener != null) { - listener.onDropInFailure(authorizationError); - } else { - Intent intent = new Intent(activity, DropInActivity.class) - .putExtra(EXTRA_AUTHORIZATION_ERROR, authorizationError); - activity.startActivityForResult(intent, requestCode); - } - } - }); - } - - /** - * @see #DropInClient(Fragment, DropInRequest, String) - * @see #DropInClient(Fragment, DropInRequest, ClientTokenProvider) - * @see #DropInClient(FragmentActivity, DropInRequest, String) - * @see #DropInClient(FragmentActivity, DropInRequest, ClientTokenProvider) - * @deprecated use {@link #launchDropIn(DropInRequest)} instead. - * Called to launch a {@link DropInActivity}. - *

- * NOTE: This method requires {@link DropInClient} to be instantiated with either an Activity - * or with a Fragment. - */ - @Deprecated - public void launchDropIn() { - getAuthorization((authorization, authorizationError) -> { - if (authorization != null && observer != null) { - DropInLaunchIntent intentData = - new DropInLaunchIntent(dropInRequest, authorization, braintreeClient.getSessionId()); - observer.launch(intentData); - } else if (authorizationError != null && listener != null) { - listener.onDropInFailure(authorizationError); - } - }); - } - /** * Called to launch a {@link DropInActivity}. *

From e6a98ac5e6d9268ae7c97aab216d858e177e69dc Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 13:53:12 -0500 Subject: [PATCH 03/20] Rename DropInLifecycleObserver to DropInLauncher. --- .../com/braintreepayments/api/DropInClient.java | 6 ++---- ...fecycleObserver.java => DropInLauncher.java} | 4 ++-- .../api/DropInClientUnitTestKt.kt | 4 ++-- ...verUnitTest.kt => DropInLauncherUnitTest.kt} | 17 +++++++++++++---- 4 files changed, 19 insertions(+), 12 deletions(-) rename Drop-In/src/main/java/com/braintreepayments/api/{DropInLifecycleObserver.java => DropInLauncher.java} (87%) rename Drop-In/src/test/java/com/braintreepayments/api/{DropInLifecycleObserverUnitTest.kt => DropInLauncherUnitTest.kt} (89%) diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java index acfd28d7c..ea2d113fe 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java @@ -1,8 +1,6 @@ package com.braintreepayments.api; import android.content.Context; -import android.content.Intent; -import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -35,7 +33,7 @@ public class DropInClient { private DropInListener listener; @VisibleForTesting - DropInLifecycleObserver observer; + DropInLauncher observer; private static DropInClientParams createDefaultParams(Context context, String authorization, ClientTokenProvider clientTokenProvider, DropInRequest dropInRequest, FragmentActivity activity, Lifecycle lifecycle) { @@ -118,7 +116,7 @@ public DropInClient(Fragment fragment, ClientTokenProvider clientTokenProvider) } private void addObserver(@NonNull FragmentActivity activity, @NonNull Lifecycle lifecycle) { - observer = new DropInLifecycleObserver(activity.getActivityResultRegistry(), this); + observer = new DropInLauncher(activity.getActivityResultRegistry(), this); lifecycle.addObserver(observer); } diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLifecycleObserver.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java similarity index 87% rename from Drop-In/src/main/java/com/braintreepayments/api/DropInLifecycleObserver.java rename to Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java index 936d0db4d..c3a3ac49f 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLifecycleObserver.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java @@ -7,7 +7,7 @@ import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; -class DropInLifecycleObserver implements DefaultLifecycleObserver { +class DropInLauncher implements DefaultLifecycleObserver { private static final String DROP_IN_RESULT = "com.braintreepayments.api.DropIn.RESULT"; @@ -20,7 +20,7 @@ class DropInLifecycleObserver implements DefaultLifecycleObserver { @VisibleForTesting ActivityResultLauncher activityLauncher; - DropInLifecycleObserver(ActivityResultRegistry activityResultRegistry, DropInClient dropInClient) { + DropInLauncher(ActivityResultRegistry activityResultRegistry, DropInClient dropInClient) { this.dropInClient = dropInClient; this.activityResultRegistry = activityResultRegistry; } diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTestKt.kt b/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTestKt.kt index 951c56eb4..2606ff726 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTestKt.kt +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTestKt.kt @@ -83,7 +83,7 @@ class DropInClientUnitTestKt { @Test fun constructor_withFragment_registersLifecycleObserver() { - val observerSlot = slot() + val observerSlot = slot() justRun { fragmentLifecycle.addObserver(capture(observerSlot)) } val sut = DropInClient(fragment, dropInRequest, clientTokenProvider) @@ -96,7 +96,7 @@ class DropInClientUnitTestKt { @Test fun constructor_withActivity_registersLifecycleObserver() { - val observerSlot = slot() + val observerSlot = slot() justRun { activityLifecycle.addObserver(capture(observerSlot)) } val sut = DropInClient(activity, dropInRequest, clientTokenProvider) diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInLifecycleObserverUnitTest.kt b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt similarity index 89% rename from Drop-In/src/test/java/com/braintreepayments/api/DropInLifecycleObserverUnitTest.kt rename to Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt index cb28f8433..7078d7e8a 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInLifecycleObserverUnitTest.kt +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt @@ -14,14 +14,17 @@ import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) -class DropInLifecycleObserverUnitTest : TestCase() { +class DropInLauncherUnitTest : TestCase() { @Test fun onCreate_registersForAnActivityResult() { val activityResultRegistry = mockk(relaxed = true) val dropInClient = mockk(relaxed = true) - val sut = DropInLifecycleObserver(activityResultRegistry, dropInClient) + val sut = DropInLauncher( + activityResultRegistry, + dropInClient + ) val lifecycleOwner = FragmentActivity() sut.onCreate(lifecycleOwner) @@ -54,7 +57,10 @@ class DropInLifecycleObserverUnitTest : TestCase() { } returns activityLauncher val lifecycleOwner = FragmentActivity() - val sut = DropInLifecycleObserver(activityResultRegistry, dropInClient) + val sut = DropInLauncher( + activityResultRegistry, + dropInClient + ) sut.onCreate(lifecycleOwner) val dropInResult = DropInResult() @@ -80,7 +86,10 @@ class DropInLifecycleObserverUnitTest : TestCase() { ) } returns activityLauncher - val sut = DropInLifecycleObserver(activityResultRegistry, dropInClient) + val sut = DropInLauncher( + activityResultRegistry, + dropInClient + ) val lifecycleOwner = FragmentActivity() sut.onCreate(lifecycleOwner) From 7a70517048bd04a944c0b122ebe4c1efb0fb23ce Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 14:06:06 -0500 Subject: [PATCH 04/20] Extract DropInLauncher success and error handling logic from DropInClient. --- .../braintreepayments/demo/MainActivity.java | 51 ++++-- .../braintreepayments/api/DropInClient.java | 153 +++--------------- .../api/DropInLaunchIntent.java | 2 +- .../braintreepayments/api/DropInLauncher.java | 33 ++-- .../api/DropInLauncherCallback.java | 9 ++ .../braintreepayments/api/DropInResult.java | 3 +- 6 files changed, 84 insertions(+), 167 deletions(-) create mode 100644 Drop-In/src/main/java/com/braintreepayments/api/DropInLauncherCallback.java diff --git a/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java b/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java index 2e226de98..2105d74fe 100644 --- a/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java +++ b/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java @@ -16,7 +16,10 @@ import androidx.cardview.widget.CardView; import com.braintreepayments.api.CardNonce; +import com.braintreepayments.api.ClientTokenCallback; import com.braintreepayments.api.DropInClient; +import com.braintreepayments.api.DropInLaunchIntent; +import com.braintreepayments.api.DropInLauncher; import com.braintreepayments.api.DropInListener; import com.braintreepayments.api.DropInPaymentMethod; import com.braintreepayments.api.DropInRequest; @@ -36,6 +39,8 @@ import com.google.android.gms.wallet.TransactionInfo; import com.google.android.gms.wallet.WalletConstants; +import java.lang.ref.WeakReference; + public class MainActivity extends BaseActivity implements DropInListener { private static final String KEY_NONCE = "nonce"; @@ -59,11 +64,24 @@ public class MainActivity extends BaseActivity implements DropInListener { private SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener; + private DemoClientTokenProvider clientTokenProvider; + + private final DropInLauncher dropInLauncher = new DropInLauncher(this, (dropInResult) -> { + Exception error = dropInResult.getError(); + if (error != null) { + onDropInFailure(error); + } else { + onDropInSuccess(dropInResult); + } + }); + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); + clientTokenProvider = new DemoClientTokenProvider(this); + paymentMethod = findViewById(R.id.payment_method); paymentMethodIcon = findViewById(R.id.payment_method_icon); paymentMethodTitle = findViewById(R.id.payment_method_title); @@ -122,16 +140,30 @@ private void configureDropInClient() { if (Settings.useTokenizationKey(this)) { String tokenizationKey = Settings.getEnvironmentTokenizationKey(this); dropInClient = new DropInClient(this, tokenizationKey); - dropInClient.setListener(this); addPaymentMethodButton.setVisibility(VISIBLE); } else { - dropInClient = new DropInClient(this, new DemoClientTokenProvider(this)); - dropInClient.setListener(this); - dropInClient.fetchMostRecentPaymentMethod(this, (dropInResult, error) -> { - if (dropInResult != null) { - handleDropInResult(dropInResult); - } else { - addPaymentMethodButton.setVisibility(VISIBLE); + WeakReference activityRef = new WeakReference<>(this); + clientTokenProvider.getClientToken(new ClientTokenCallback() { + @Override + public void onSuccess(@NonNull String clientToken) { + MainActivity activity = activityRef.get(); + if (activity != null) { + dropInClient = new DropInClient(activity, clientToken); + activity.addPaymentMethodButton.setVisibility(VISIBLE); + + dropInClient.fetchMostRecentPaymentMethod(activity, (dropInResult, error) -> { + if (dropInResult != null) { + handleDropInResult(dropInResult); + } else { + addPaymentMethodButton.setVisibility(VISIBLE); + } + }); + } + } + + @Override + public void onFailure(@NonNull Exception e) { + onDropInFailure(e); } }); } @@ -152,7 +184,8 @@ public void launchDropIn(View v) { dropInRequest.setThreeDSecureRequest(demoThreeDSecureRequest()); } - dropInClient.launchDropIn(dropInRequest); + DropInLaunchIntent launchIntent = dropInClient.createLaunchIntent(dropInRequest); + dropInLauncher.launchDropIn(launchIntent); } private ThreeDSecureRequest demoThreeDSecureRequest() { diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java index ea2d113fe..d4856b63c 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java @@ -2,12 +2,10 @@ import android.content.Context; -import androidx.annotation.NonNull; +import androidx.activity.ComponentActivity; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; -import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; -import androidx.lifecycle.Lifecycle; /** * Used to launch Drop-in and handle results @@ -26,135 +24,37 @@ public class DropInClient { private final PaymentMethodClient paymentMethodClient; private final GooglePayClient googlePayClient; - private final DropInRequest dropInRequest; + private final Authorization authorization; private final DropInSharedPreferences dropInSharedPreferences; - private DropInListener listener; - - @VisibleForTesting - DropInLauncher observer; - - private static DropInClientParams createDefaultParams(Context context, String authorization, ClientTokenProvider clientTokenProvider, DropInRequest dropInRequest, FragmentActivity activity, Lifecycle lifecycle) { - - String customUrlScheme = null; - if (dropInRequest != null) { - customUrlScheme = dropInRequest.getCustomUrlScheme(); - } - - BraintreeOptions braintreeOptions = - new BraintreeOptions(context, null, customUrlScheme, authorization, clientTokenProvider, IntegrationType.DROP_IN); - - BraintreeClient braintreeClient = new BraintreeClient(braintreeOptions); - return new DropInClientParams() - .activity(activity) - .lifecycle(lifecycle) - .dropInRequest(dropInRequest) - .braintreeClient(braintreeClient) - .paymentMethodClient(new PaymentMethodClient(braintreeClient)) - .googlePayClient(new GooglePayClient(braintreeClient)) - .dropInSharedPreferences(DropInSharedPreferences.getInstance(context.getApplicationContext())); + public DropInClient(ComponentActivity activity, String authorization) { + this(activity, authorization, null); } - /** - * Create a new instance of {@link DropInClient} from within an Activity using a Tokenization Key authorization. - * - * @param activity a {@link FragmentActivity} - * @param authorization a Tokenization Key authorization string - */ - public DropInClient(FragmentActivity activity, String authorization) { - this(activity, activity.getLifecycle(), authorization, null); - } - - /** - * Create a new instance of {@link DropInClient} from within a Fragment using a Tokenization Key authorization. - * - * @param fragment a {@link Fragment} - * @param authorization a Tokenization Key authorization string - */ - public DropInClient(Fragment fragment, String authorization) { - this(fragment.requireActivity(), fragment.getLifecycle(), authorization, null); - } - - /** - * Create a new instance of {@link DropInClient} from within an Activity using a {@link ClientTokenProvider} to fetch authorization. - * - * @param activity a {@link FragmentActivity} - * @param clientTokenProvider a {@link ClientTokenProvider} - */ - public DropInClient(FragmentActivity activity, ClientTokenProvider clientTokenProvider) { - this(createDefaultParams(activity, null, clientTokenProvider, null, activity, activity.getLifecycle())); - } - - /** - * Create a new instance of {@link DropInClient} from within a Fragment using a {@link ClientTokenProvider} to fetch authorization. - * - * @param fragment a {@link Fragment} - * @param clientTokenProvider a {@link ClientTokenProvider} - */ - public DropInClient(Fragment fragment, ClientTokenProvider clientTokenProvider) { - this(createDefaultParams(fragment.requireActivity(), null, clientTokenProvider, null, fragment.requireActivity(), fragment.getLifecycle())); - } - - DropInClient(FragmentActivity activity, Lifecycle lifecycle, String authorization, DropInRequest dropInRequest) { - this(createDefaultParams(activity, authorization, null, dropInRequest, activity, lifecycle)); - } - - @VisibleForTesting - DropInClient(DropInClientParams params) { - this.dropInRequest = params.getDropInRequest(); - this.braintreeClient = params.getBraintreeClient(); - this.googlePayClient = params.getGooglePayClient(); - this.paymentMethodClient = params.getPaymentMethodClient(); - this.dropInSharedPreferences = params.getDropInSharedPreferences(); - - FragmentActivity activity = params.getActivity(); - Lifecycle lifecycle = params.getLifecycle(); - if (activity != null && lifecycle != null) { - addObserver(activity, lifecycle); - } - } - - private void addObserver(@NonNull FragmentActivity activity, @NonNull Lifecycle lifecycle) { - observer = new DropInLauncher(activity.getActivityResultRegistry(), this); - lifecycle.addObserver(observer); - } - - /** - * Add a {@link DropInListener} to your client to receive results or errors from DropIn. - * Must be used with a {@link DropInClient} constructed with a {@link Fragment} or {@link FragmentActivity}. - * - * @param listener a {@link DropInListener} - */ - public void setListener(DropInListener listener) { - this.listener = listener; + public DropInClient(ComponentActivity activity, String authorization, String customUrlScheme) { + Context applicationContext = activity.getApplicationContext(); + BraintreeOptions braintreeOptions = new BraintreeOptions( + applicationContext, + null, + customUrlScheme, + authorization, + null, + IntegrationType.DROP_IN + ); + this.braintreeClient = new BraintreeClient(braintreeOptions); + this.googlePayClient = new GooglePayClient(braintreeClient); + this.paymentMethodClient = new PaymentMethodClient(braintreeClient); + this.dropInSharedPreferences = DropInSharedPreferences.getInstance(applicationContext); + this.authorization = Authorization.fromString(authorization); } void getAuthorization(AuthorizationCallback callback) { braintreeClient.getAuthorization(callback); } - /** - * Called to launch a {@link DropInActivity}. - *

- * NOTE: This method requires {@link DropInClient} to be instantiated with either an Activity - * or with a Fragment. - * - * @see #DropInClient(Fragment, String) - * @see #DropInClient(Fragment, ClientTokenProvider) - * @see #DropInClient(FragmentActivity, String) - * @see #DropInClient(FragmentActivity, ClientTokenProvider) - */ - public void launchDropIn(DropInRequest request) { - getAuthorization((authorization, authorizationError) -> { - if (authorization != null && observer != null) { - DropInLaunchIntent intentData = - new DropInLaunchIntent(request, authorization, braintreeClient.getSessionId()); - observer.launch(intentData); - } else if (authorizationError != null && listener != null) { - listener.onDropInFailure(authorizationError); - } - }); + public DropInLaunchIntent createLaunchIntent(DropInRequest dropInRequest) { + return new DropInLaunchIntent(dropInRequest, authorization, braintreeClient.getSessionId()); } /** @@ -222,17 +122,6 @@ private void getPaymentMethodNonces(final FetchMostRecentPaymentMethodCallback c }); } - void onDropInResult(DropInResult dropInResult) { - if (dropInResult != null && listener != null) { - Exception error = dropInResult.getError(); - if (error != null) { - listener.onDropInFailure(error); - } else { - listener.onDropInSuccess(dropInResult); - } - } - } - /** * For clients using a {@link ClientTokenProvider}, call this method to invalidate the existing, * cached client token. A new client token will be fetched by the SDK when it is needed. diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java index fa40af731..68ec62f8d 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java @@ -1,6 +1,6 @@ package com.braintreepayments.api; -class DropInLaunchIntent { +public class DropInLaunchIntent { private final Authorization authorization; private final DropInRequest dropInRequest; diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java index c3a3ac49f..f7465430a 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java @@ -1,40 +1,25 @@ package com.braintreepayments.api; +import androidx.activity.ComponentActivity; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.ActivityResultRegistry; -import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.DefaultLifecycleObserver; -import androidx.lifecycle.LifecycleOwner; -class DropInLauncher implements DefaultLifecycleObserver { +public class DropInLauncher implements DefaultLifecycleObserver { private static final String DROP_IN_RESULT = "com.braintreepayments.api.DropIn.RESULT"; @VisibleForTesting - DropInClient dropInClient; + private ActivityResultLauncher activityLauncher; - @VisibleForTesting - final ActivityResultRegistry activityResultRegistry; - - @VisibleForTesting - ActivityResultLauncher activityLauncher; - - DropInLauncher(ActivityResultRegistry activityResultRegistry, DropInClient dropInClient) { - this.dropInClient = dropInClient; - this.activityResultRegistry = activityResultRegistry; - } - - @Override - public void onCreate(@NonNull LifecycleOwner owner) { - activityLauncher = activityResultRegistry.register( - DROP_IN_RESULT, - owner, - new DropInActivityResultContract(), - dropInResult -> dropInClient.onDropInResult(dropInResult)); + public DropInLauncher(ComponentActivity activity, DropInLauncherCallback callback) { + ActivityResultRegistry registry = activity.getActivityResultRegistry(); + activityLauncher = registry.register( + DROP_IN_RESULT, activity, new DropInActivityResultContract(), callback); } - void launch(DropInLaunchIntent intentData) { - activityLauncher.launch(intentData); + public void launchDropIn(DropInLaunchIntent launchIntent) { + activityLauncher.launch(launchIntent); } } diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncherCallback.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncherCallback.java new file mode 100644 index 000000000..036bf356c --- /dev/null +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncherCallback.java @@ -0,0 +1,9 @@ +package com.braintreepayments.api; + +import androidx.activity.result.ActivityResultCallback; + +public interface DropInLauncherCallback extends ActivityResultCallback { + + @Override + void onActivityResult(DropInResult result); +} \ No newline at end of file diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInResult.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInResult.java index 78da796d6..30cca4c3a 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInResult.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInResult.java @@ -90,7 +90,8 @@ public String getDeviceData() { return deviceData; } - Exception getError() { + @Nullable + public Exception getError() { return error; } From 7ca4634da4e6afb9bd1580607396ab4dc002a733 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 14:10:57 -0500 Subject: [PATCH 05/20] Remove invalidateClientToken() method. --- .../java/com/braintreepayments/api/DropInClient.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java index d4856b63c..7028cc36b 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java @@ -121,14 +121,4 @@ private void getPaymentMethodNonces(final FetchMostRecentPaymentMethodCallback c } }); } - - /** - * For clients using a {@link ClientTokenProvider}, call this method to invalidate the existing, - * cached client token. A new client token will be fetched by the SDK when it is needed. - *

- * For clients not using a {@link ClientTokenProvider}, this method does nothing. - */ - public void invalidateClientToken() { - braintreeClient.invalidateClientToken(); - } } From 7ad19eb23b123178aad6acd69c6c74217d0756b6 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 14:17:38 -0500 Subject: [PATCH 06/20] Remove DropInClient#getAuthorization() internal call. --- .../braintreepayments/api/DropInClient.java | 66 ++++++++----------- 1 file changed, 26 insertions(+), 40 deletions(-) diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java index 7028cc36b..665c0ca3d 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java @@ -3,7 +3,7 @@ import android.content.Context; import androidx.activity.ComponentActivity; -import androidx.annotation.Nullable; +import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.fragment.app.FragmentActivity; @@ -28,11 +28,11 @@ public class DropInClient { private final DropInSharedPreferences dropInSharedPreferences; - public DropInClient(ComponentActivity activity, String authorization) { + public DropInClient(@NonNull ComponentActivity activity, @NonNull String authorization) { this(activity, authorization, null); } - public DropInClient(ComponentActivity activity, String authorization, String customUrlScheme) { + public DropInClient(@NonNull ComponentActivity activity, @NonNull String authorization, @NonNull String customUrlScheme) { Context applicationContext = activity.getApplicationContext(); BraintreeOptions braintreeOptions = new BraintreeOptions( applicationContext, @@ -49,10 +49,6 @@ public DropInClient(ComponentActivity activity, String authorization, String cus this.authorization = Authorization.fromString(authorization); } - void getAuthorization(AuthorizationCallback callback) { - braintreeClient.getAuthorization(callback); - } - public DropInLaunchIntent createLaunchIntent(DropInRequest dropInRequest) { return new DropInLaunchIntent(dropInRequest, authorization, braintreeClient.getSessionId()); } @@ -70,41 +66,31 @@ public DropInLaunchIntent createLaunchIntent(DropInRequest dropInRequest) { */ // NEXT_MAJOR_VERSION: - update this function name to more accurately represent the behavior of the function public void fetchMostRecentPaymentMethod(FragmentActivity activity, final FetchMostRecentPaymentMethodCallback callback) { - getAuthorization(new AuthorizationCallback() { - @Override - public void onAuthorizationResult(@Nullable Authorization authorization, @Nullable Exception authError) { - if (authorization != null) { - - boolean isClientToken = (authorization instanceof ClientToken); - if (!isClientToken) { - InvalidArgumentException clientTokenRequiredError = - new InvalidArgumentException("DropInClient#fetchMostRecentPaymentMethods() must " + - "be called with a client token"); - callback.onResult(null, clientTokenRequiredError); - return; - } - - DropInPaymentMethod lastUsedPaymentMethod = - dropInSharedPreferences.getLastUsedPaymentMethod(); - - if (lastUsedPaymentMethod == DropInPaymentMethod.GOOGLE_PAY) { - googlePayClient.isReadyToPay(activity, (isReadyToPay, isReadyToPayError) -> { - if (isReadyToPay) { - DropInResult result = new DropInResult(); - result.setPaymentMethodType(DropInPaymentMethod.GOOGLE_PAY); - callback.onResult(result, null); - } else { - getPaymentMethodNonces(callback); - } - }); - } else { - getPaymentMethodNonces(callback); - } + boolean isClientToken = (authorization instanceof ClientToken); + if (!isClientToken) { + InvalidArgumentException clientTokenRequiredError = + new InvalidArgumentException("DropInClient#fetchMostRecentPaymentMethods() must " + + "be called with a client token"); + callback.onResult(null, clientTokenRequiredError); + return; + } + + DropInPaymentMethod lastUsedPaymentMethod = + dropInSharedPreferences.getLastUsedPaymentMethod(); + + if (lastUsedPaymentMethod == DropInPaymentMethod.GOOGLE_PAY) { + googlePayClient.isReadyToPay(activity, (isReadyToPay, isReadyToPayError) -> { + if (isReadyToPay) { + DropInResult result = new DropInResult(); + result.setPaymentMethodType(DropInPaymentMethod.GOOGLE_PAY); + callback.onResult(result, null); } else { - callback.onResult(null, authError); + getPaymentMethodNonces(callback); } - } - }); + }); + } else { + getPaymentMethodNonces(callback); + } } private void getPaymentMethodNonces(final FetchMostRecentPaymentMethodCallback callback) { From 3247387b4a5a671bead6639e478fcddff7f917d8 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 14:51:47 -0500 Subject: [PATCH 07/20] Fix DropInLauncherUnitTest. --- .../api/DropInLauncherUnitTest.kt | 77 +++++-------------- 1 file changed, 18 insertions(+), 59 deletions(-) diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt index 7078d7e8a..c90f51fa5 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt @@ -1,80 +1,45 @@ package com.braintreepayments.api -import androidx.activity.result.ActivityResultCallback +import androidx.activity.ComponentActivity import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultRegistry -import androidx.fragment.app.FragmentActivity import io.mockk.every import io.mockk.mockk -import io.mockk.slot import io.mockk.verify import junit.framework.TestCase import org.junit.Test import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.same import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) class DropInLauncherUnitTest : TestCase() { @Test - fun onCreate_registersForAnActivityResult() { + fun constructor_registersForActivityResultAndForwardsResultCallback() { + val activity = mockk(relaxed = true) val activityResultRegistry = mockk(relaxed = true) - val dropInClient = mockk(relaxed = true) + every { activity.activityResultRegistry } returns activityResultRegistry - val sut = DropInLauncher( - activityResultRegistry, - dropInClient - ) - - val lifecycleOwner = FragmentActivity() - sut.onCreate(lifecycleOwner) + val callback = mockk(relaxed = true) + DropInLauncher(activity, callback) val expectedKey = "com.braintreepayments.api.DropIn.RESULT" verify { activityResultRegistry.register( expectedKey, - lifecycleOwner, + activity, any(), - any() + same(callback) ) } } - @Test - fun onCreate_whenActivityResultReceived_forwardsResultToDropInClient() { - val activityResultRegistry = mockk(relaxed = true) - val dropInClient = mockk(relaxed = true) - - val callbackSlot = slot>() - val activityLauncher: ActivityResultLauncher = mockk(relaxed = true) - every { - activityResultRegistry.register( - any(), - any(), - any(), - capture(callbackSlot) - ) - } returns activityLauncher - - val lifecycleOwner = FragmentActivity() - val sut = DropInLauncher( - activityResultRegistry, - dropInClient - ) - sut.onCreate(lifecycleOwner) - - val dropInResult = DropInResult() - callbackSlot.captured.onActivityResult(dropInResult) - verify { dropInClient.onDropInResult(dropInResult) } - } - @Test fun launch_launchesActivity() { - val dropInRequest = DropInRequest() - val authorization = Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN) - + val activity = mockk(relaxed = true) val activityResultRegistry = mockk(relaxed = true) - val dropInClient = mockk(relaxed = true) + every { activity.activityResultRegistry } returns activityResultRegistry val activityLauncher: ActivityResultLauncher = mockk(relaxed = true) every { @@ -86,21 +51,15 @@ class DropInLauncherUnitTest : TestCase() { ) } returns activityLauncher - val sut = DropInLauncher( - activityResultRegistry, - dropInClient - ) - - val lifecycleOwner = FragmentActivity() - sut.onCreate(lifecycleOwner) + val callback = mockk(relaxed = true) + val sut = DropInLauncher(activity, callback) - val dropInLaunchIntent = DropInLaunchIntent( - dropInRequest, - authorization, - "sample-session-id" - ) - sut.launch(dropInLaunchIntent) + val dropInRequest = DropInRequest() + val authorization = Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN) + val dropInLaunchIntent = + DropInLaunchIntent(dropInRequest, authorization, "fake-session-id") + sut.launchDropIn(dropInLaunchIntent) verify { activityLauncher.launch(dropInLaunchIntent) } } } \ No newline at end of file From 7978016203588712eb2dd8c01e3c8766ab66926e Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 14:52:57 -0500 Subject: [PATCH 08/20] Migrate DropInClient to using context. --- .../java/com/braintreepayments/api/DropInClient.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java index 665c0ca3d..b7da31238 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java @@ -2,7 +2,6 @@ import android.content.Context; -import androidx.activity.ComponentActivity; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.fragment.app.FragmentActivity; @@ -28,12 +27,12 @@ public class DropInClient { private final DropInSharedPreferences dropInSharedPreferences; - public DropInClient(@NonNull ComponentActivity activity, @NonNull String authorization) { - this(activity, authorization, null); + public DropInClient(@NonNull Context context, @NonNull String authorization) { + this(context, authorization, null); } - public DropInClient(@NonNull ComponentActivity activity, @NonNull String authorization, @NonNull String customUrlScheme) { - Context applicationContext = activity.getApplicationContext(); + public DropInClient(@NonNull Context context, @NonNull String authorization, @NonNull String customUrlScheme) { + Context applicationContext = context.getApplicationContext(); BraintreeOptions braintreeOptions = new BraintreeOptions( applicationContext, null, From 4ae9532310e53c97281516405581747dd241ee7d Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 15:11:47 -0500 Subject: [PATCH 09/20] Migrate fetch method to a RecentPaymentMethodsClient. --- .../api/RecentPaymentMethodsClient.java | 110 ++++++++ .../RecentPaymentMethodsClientUnitTest.java | 265 ++++++++++++++++++ 2 files changed, 375 insertions(+) create mode 100644 Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java create mode 100644 Drop-In/src/test/java/com/braintreepayments/api/RecentPaymentMethodsClientUnitTest.java diff --git a/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java b/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java new file mode 100644 index 000000000..db69816ff --- /dev/null +++ b/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java @@ -0,0 +1,110 @@ +package com.braintreepayments.api; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; +import androidx.fragment.app.FragmentActivity; + +public class RecentPaymentMethodsClient { + + private final BraintreeClient braintreeClient; + + private final GooglePayClient googlePayClient; + + private final PaymentMethodClient paymentMethodClient; + private final DropInSharedPreferences sharedPreferences; + + RecentPaymentMethodsClient(@NonNull Context context, @NonNull String authorization) { + this(context, new BraintreeClient(context, authorization)); + } + + private RecentPaymentMethodsClient( + @NonNull Context context, + @NonNull BraintreeClient braintreeClient + ) { + this( + context, + braintreeClient, + new GooglePayClient(braintreeClient), + new PaymentMethodClient(braintreeClient), + DropInSharedPreferences.getInstance(context) + ); + } + + @VisibleForTesting + RecentPaymentMethodsClient( + @NonNull Context context, + @NonNull BraintreeClient braintreeClient, + @NonNull GooglePayClient googlePayClient, + @NonNull PaymentMethodClient paymentMethodClient, + @NonNull DropInSharedPreferences sharedPreferences + ) { + this.braintreeClient = braintreeClient; + this.googlePayClient = new GooglePayClient(braintreeClient); + this.paymentMethodClient = new PaymentMethodClient(braintreeClient); + this.sharedPreferences = sharedPreferences; + } + + /** + * Called to get a user's existing payment method, if any. + * The payment method returned is not guaranteed to be the most recently added payment method. + * If your user already has an existing payment method, you may not need to show Drop-In. + *

+ * Note: a client token must be used and will only return a payment method if it contains a + * customer id. + * + * @param activity the current {@link FragmentActivity} + * @param callback callback for handling result + */ + // NEXT_MAJOR_VERSION: - update this function name to more accurately represent the behavior of the function + public void fetchMostRecentPaymentMethod(FragmentActivity activity, final FetchMostRecentPaymentMethodCallback callback) { + braintreeClient.getAuthorization((authorization, authError) -> { + if (authorization != null) { + + boolean isClientToken = (authorization instanceof ClientToken); + if (!isClientToken) { + InvalidArgumentException clientTokenRequiredError = + new InvalidArgumentException("DropInClient#fetchMostRecentPaymentMethods() must " + + "be called with a client token"); + callback.onResult(null, clientTokenRequiredError); + return; + } + + DropInPaymentMethod lastUsedPaymentMethod = + sharedPreferences.getLastUsedPaymentMethod(); + + if (lastUsedPaymentMethod == DropInPaymentMethod.GOOGLE_PAY) { + googlePayClient.isReadyToPay(activity, (isReadyToPay, isReadyToPayError) -> { + if (isReadyToPay) { + DropInResult result = new DropInResult(); + result.setPaymentMethodType(DropInPaymentMethod.GOOGLE_PAY); + callback.onResult(result, null); + } else { + getPaymentMethodNonces(callback); + } + }); + } else { + getPaymentMethodNonces(callback); + } + } else { + callback.onResult(null, authError); + } + }); + } + + private void getPaymentMethodNonces(final FetchMostRecentPaymentMethodCallback callback) { + paymentMethodClient.getPaymentMethodNonces((paymentMethodNonceList, error) -> { + if (paymentMethodNonceList != null) { + DropInResult result = new DropInResult(); + if (paymentMethodNonceList.size() > 0) { + PaymentMethodNonce paymentMethod = paymentMethodNonceList.get(0); + result.setPaymentMethodNonce(paymentMethod); + } + callback.onResult(result, null); + } else if (error != null) { + callback.onResult(null, error); + } + }); + } +} diff --git a/Drop-In/src/test/java/com/braintreepayments/api/RecentPaymentMethodsClientUnitTest.java b/Drop-In/src/test/java/com/braintreepayments/api/RecentPaymentMethodsClientUnitTest.java new file mode 100644 index 000000000..4737ee9fd --- /dev/null +++ b/Drop-In/src/test/java/com/braintreepayments/api/RecentPaymentMethodsClientUnitTest.java @@ -0,0 +1,265 @@ +package com.braintreepayments.api; + +import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; + +import androidx.fragment.app.FragmentActivity; +import androidx.test.core.app.ApplicationProvider; +import androidx.work.testing.WorkManagerTestInitHelper; + +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.android.controller.ActivityController; + +import java.util.ArrayList; + +@RunWith(RobolectricTestRunner.class) +public class RecentPaymentMethodsClientUnitTest { + + private FragmentActivity activity; + + private Context context; + private DropInSharedPreferences dropInSharedPreferences; + + @Before + public void beforeEach() { + context = ApplicationProvider.getApplicationContext(); + dropInSharedPreferences = mock(DropInSharedPreferences.class); + + ActivityController activityController = + Robolectric.buildActivity(FragmentActivity.class); + activity = activityController.get(); + + // This suppresses errors from WorkManager initialization within BraintreeClient initialization (AnalyticsClient) + WorkManagerTestInitHelper.initializeTestWorkManager(context); + } + + @Test + public void fetchMostRecentPaymentMethod_forwardsAuthorizationFetchErrors() { + Exception authError = new Exception("auth error"); + BraintreeClient braintreeClient = new MockBraintreeClientBuilder() + .authorizationError(authError) + .build(); + + RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( + context, + braintreeClient, + new GooglePayClient(braintreeClient), + new PaymentMethodClient(braintreeClient), + dropInSharedPreferences + ); + + FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); + sut.fetchMostRecentPaymentMethod(activity, callback); + + verify(callback).onResult(null, authError); + } + + @Test + public void fetchMostRecentPaymentMethod_callsBackWithErrorIfInvalidClientTokenWasUsed() { + BraintreeClient braintreeClient = new MockBraintreeClientBuilder() + .authorizationSuccess(Authorization.fromString(Fixtures.TOKENIZATION_KEY)) + .build(); + + RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( + context, + braintreeClient, + new GooglePayClient(braintreeClient), + new PaymentMethodClient(braintreeClient), + dropInSharedPreferences + ); + + FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); + sut.fetchMostRecentPaymentMethod(activity, callback); + + ArgumentCaptor captor = ArgumentCaptor.forClass(InvalidArgumentException.class); + verify(callback).onResult((DropInResult) isNull(), captor.capture()); + + InvalidArgumentException exception = captor.getValue(); + assertEquals("DropInClient#fetchMostRecentPaymentMethods() must be called with a client token", exception.getMessage()); + } + + @Test + public void fetchMostRecentPaymentMethod_callsBackWithResultIfLastUsedPaymentMethodTypeWasPayWithGoogle() throws JSONException, JSONException { + + GooglePayClient googlePayClient = new MockGooglePayClientBuilder() + .isReadyToPaySuccess(true) + .build(); + BraintreeClient braintreeClient = new MockBraintreeClientBuilder() + .authorizationSuccess(Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN)) + .configuration(Configuration.fromJson(Fixtures.CONFIGURATION_WITH_GOOGLE_PAY)) + .build(); + + RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( + context, + braintreeClient, + googlePayClient, + new PaymentMethodClient(braintreeClient), + dropInSharedPreferences + ); + + when( + dropInSharedPreferences.getLastUsedPaymentMethod() + ).thenReturn(DropInPaymentMethod.GOOGLE_PAY); + + FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); + sut.fetchMostRecentPaymentMethod(activity, callback); + + ArgumentCaptor captor = ArgumentCaptor.forClass(DropInResult.class); + verify(callback).onResult(captor.capture(), (Exception) isNull()); + + DropInResult result = captor.getValue(); + assertEquals(DropInPaymentMethod.GOOGLE_PAY, result.getPaymentMethodType()); + assertNull(result.getPaymentMethodNonce()); + } + + @Test + public void fetchMostRecentPaymentMethod_doesNotCallBackWithPayWithGoogleIfPayWithGoogleIsNotAvailable() throws JSONException { + + GooglePayClient googlePayClient = new MockGooglePayClientBuilder() + .isReadyToPaySuccess(false) + .build(); + BraintreeClient braintreeClient = new MockBraintreeClientBuilder() + .authorizationSuccess(Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN)) + .configuration(Configuration.fromJson(Fixtures.CONFIGURATION_WITH_GOOGLE_PAY)) + .build(); + + ArrayList paymentMethods = new ArrayList<>(); + paymentMethods.add(CardNonce.fromJSON(new JSONObject(Fixtures.VISA_CREDIT_CARD_RESPONSE))); + paymentMethods.add(GooglePayCardNonce.fromJSON(new JSONObject(Fixtures.GOOGLE_PAY_NETWORK_TOKENIZED_RESPONSE))); + PaymentMethodClient paymentMethodClient = new MockPaymentMethodClientBuilder() + .getPaymentMethodNoncesSuccess(paymentMethods) + .build(); + + when( + dropInSharedPreferences.getLastUsedPaymentMethod() + ).thenReturn(DropInPaymentMethod.GOOGLE_PAY); + + RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( + context, + braintreeClient, + googlePayClient, + paymentMethodClient, + dropInSharedPreferences + ); + + FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); + sut.fetchMostRecentPaymentMethod(activity, callback); + + ArgumentCaptor captor = ArgumentCaptor.forClass(DropInResult.class); + verify(callback).onResult(captor.capture(), (Exception) isNull()); + + DropInResult result = captor.getValue(); + assertEquals(DropInPaymentMethod.VISA, result.getPaymentMethodType()); + assertNotNull(result.getPaymentMethodNonce()); + assertEquals("11", ((CardNonce) result.getPaymentMethodNonce()).getLastTwo()); + } + + @Test + public void fetchMostRecentPaymentMethod_callsBackWithErrorOnGetPaymentMethodsError() { + BraintreeClient braintreeClient = new MockBraintreeClientBuilder() + .authorizationSuccess(Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN)) + .build(); + + PaymentMethodClient paymentMethodClient = new MockPaymentMethodClientBuilder() + .getPaymentMethodNoncesError(new BraintreeException("Error occurred")) + .build(); + + RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( + context, + braintreeClient, + new GooglePayClient(braintreeClient), + paymentMethodClient, + dropInSharedPreferences + ); + + FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); + sut.fetchMostRecentPaymentMethod(activity, callback); + + ArgumentCaptor captor = ArgumentCaptor.forClass(BraintreeException.class); + verify(callback).onResult((DropInResult) isNull(), captor.capture()); + + BraintreeException exception = captor.getValue(); + assertEquals("Error occurred", exception.getMessage()); + } + + @Test + public void fetchMostRecentPaymentMethod_callsBackWithResultWhenThereIsAPaymentMethod() + throws JSONException { + BraintreeClient braintreeClient = new MockBraintreeClientBuilder() + .authorizationSuccess(Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN)) + .configuration(Configuration.fromJson(Fixtures.CONFIGURATION_WITH_GOOGLE_PAY)) + .build(); + + ArrayList paymentMethods = new ArrayList<>(); + paymentMethods.add(CardNonce.fromJSON(new JSONObject(Fixtures.VISA_CREDIT_CARD_RESPONSE))); + + PaymentMethodClient paymentMethodClient = new MockPaymentMethodClientBuilder() + .getPaymentMethodNoncesSuccess(paymentMethods) + .build(); + + RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( + context, + braintreeClient, + new GooglePayClient(braintreeClient), + paymentMethodClient, + dropInSharedPreferences + ); + + FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); + sut.fetchMostRecentPaymentMethod(activity, callback); + + ArgumentCaptor captor = ArgumentCaptor.forClass(DropInResult.class); + verify(callback).onResult(captor.capture(), (Exception) isNull()); + + DropInResult result = captor.getValue(); + assertEquals(DropInPaymentMethod.VISA, result.getPaymentMethodType()); + assertNotNull(result.getPaymentMethodNonce()); + assertEquals("11", ((CardNonce) result.getPaymentMethodNonce()).getLastTwo()); + } + + @Test + public void fetchMostRecentPaymentMethod_callsBackWithNullResultWhenThereAreNoPaymentMethods() throws JSONException { + BraintreeClient braintreeClient = new MockBraintreeClientBuilder() + .authorizationSuccess(Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN)) + .configuration(Configuration.fromJson(Fixtures.CONFIGURATION_WITH_GOOGLE_PAY)) + .build(); + + ArrayList paymentMethods = new ArrayList<>(); + + PaymentMethodClient paymentMethodClient = new MockPaymentMethodClientBuilder() + .getPaymentMethodNoncesSuccess(paymentMethods) + .build(); + + RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( + context, + braintreeClient, + new GooglePayClient(braintreeClient), + paymentMethodClient, + dropInSharedPreferences + ); + + FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); + sut.fetchMostRecentPaymentMethod(activity, callback); + + ArgumentCaptor captor = ArgumentCaptor.forClass(DropInResult.class); + verify(callback).onResult(captor.capture(), (Exception) isNull()); + + DropInResult result = captor.getValue(); + assertNull(result.getPaymentMethodType()); + assertNull(result.getPaymentMethodNonce()); + } +} From 4f85b19d3c84da53ef06f88c79dbd2d2476d1b57 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 15:36:22 -0500 Subject: [PATCH 10/20] Remove DropInClient and fix broken imports. --- .../braintreepayments/demo/BaseActivity.java | 9 - .../braintreepayments/demo/MainActivity.java | 22 +- .../braintreepayments/api/DropInActivity.java | 16 +- .../api/DropInActivityResultContract.java | 8 +- .../braintreepayments/api/DropInClient.java | 109 ----- .../braintreepayments/api/DropInLauncher.java | 12 +- .../api/RecentPaymentMethodsClient.java | 2 +- .../DropInActivityResultContractUnitTest.java | 8 +- .../api/DropInActivityUnitTest.kt | 8 +- .../api/DropInClientUnitTest.java | 438 ------------------ .../api/DropInClientUnitTestKt.kt | 223 --------- .../api/DropInLauncherUnitTest.kt | 16 +- 12 files changed, 58 insertions(+), 813 deletions(-) delete mode 100644 Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java delete mode 100644 Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTest.java delete mode 100644 Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTestKt.kt diff --git a/Demo/src/main/java/com/braintreepayments/demo/BaseActivity.java b/Demo/src/main/java/com/braintreepayments/demo/BaseActivity.java index 952e6c5d0..420d74200 100644 --- a/Demo/src/main/java/com/braintreepayments/demo/BaseActivity.java +++ b/Demo/src/main/java/com/braintreepayments/demo/BaseActivity.java @@ -5,8 +5,6 @@ import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.os.Bundle; -import android.text.TextUtils; -import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.ArrayAdapter; @@ -16,13 +14,6 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback; -import com.braintreepayments.api.DropInClient; -import com.braintreepayments.demo.models.ClientToken; - -import retrofit.Callback; -import retrofit.RetrofitError; -import retrofit.client.Response; - @SuppressWarnings("deprecation") public abstract class BaseActivity extends AppCompatActivity implements OnRequestPermissionsResultCallback, ActionBar.OnNavigationListener { diff --git a/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java b/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java index 2105d74fe..f9c3e8cee 100644 --- a/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java +++ b/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java @@ -3,6 +3,7 @@ import static android.view.View.GONE; import static android.view.View.VISIBLE; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; @@ -17,8 +18,6 @@ import com.braintreepayments.api.CardNonce; import com.braintreepayments.api.ClientTokenCallback; -import com.braintreepayments.api.DropInClient; -import com.braintreepayments.api.DropInLaunchIntent; import com.braintreepayments.api.DropInLauncher; import com.braintreepayments.api.DropInListener; import com.braintreepayments.api.DropInPaymentMethod; @@ -29,6 +28,7 @@ import com.braintreepayments.api.PayPalAccountNonce; import com.braintreepayments.api.PaymentMethodNonce; import com.braintreepayments.api.PostalAddress; +import com.braintreepayments.api.RecentPaymentMethodsClient; import com.braintreepayments.api.ThreeDSecureAdditionalInformation; import com.braintreepayments.api.ThreeDSecurePostalAddress; import com.braintreepayments.api.ThreeDSecureRequest; @@ -58,7 +58,7 @@ public class MainActivity extends BaseActivity implements DropInListener { private Button addPaymentMethodButton; private Button purchaseButton; - private DropInClient dropInClient; + private RecentPaymentMethodsClient recentPaymentMethodsClient; private boolean purchased = false; @@ -66,6 +66,8 @@ public class MainActivity extends BaseActivity implements DropInListener { private DemoClientTokenProvider clientTokenProvider; + private String authString; + private final DropInLauncher dropInLauncher = new DropInLauncher(this, (dropInResult) -> { Exception error = dropInResult.getError(); if (error != null) { @@ -138,20 +140,21 @@ private void registerSharedPreferencesListener() { private void configureDropInClient() { if (Settings.useTokenizationKey(this)) { - String tokenizationKey = Settings.getEnvironmentTokenizationKey(this); - dropInClient = new DropInClient(this, tokenizationKey); + authString = Settings.getEnvironmentTokenizationKey(this); addPaymentMethodButton.setVisibility(VISIBLE); } else { + Context appContext = getApplicationContext(); WeakReference activityRef = new WeakReference<>(this); clientTokenProvider.getClientToken(new ClientTokenCallback() { @Override public void onSuccess(@NonNull String clientToken) { MainActivity activity = activityRef.get(); if (activity != null) { - dropInClient = new DropInClient(activity, clientToken); + authString = clientToken; + recentPaymentMethodsClient = new RecentPaymentMethodsClient(appContext, clientToken); activity.addPaymentMethodButton.setVisibility(VISIBLE); - dropInClient.fetchMostRecentPaymentMethod(activity, (dropInResult, error) -> { + recentPaymentMethodsClient.fetchMostRecentPaymentMethod(activity, (dropInResult, error) -> { if (dropInResult != null) { handleDropInResult(dropInResult); } else { @@ -184,8 +187,7 @@ public void launchDropIn(View v) { dropInRequest.setThreeDSecureRequest(demoThreeDSecureRequest()); } - DropInLaunchIntent launchIntent = dropInClient.createLaunchIntent(dropInRequest); - dropInLauncher.launchDropIn(launchIntent); + dropInLauncher.launchDropIn(authString, dropInRequest); } private ThreeDSecureRequest demoThreeDSecureRequest() { @@ -224,7 +226,7 @@ public void purchase(View v) { public void handleDropInResult(DropInResult result) { if (result.getPaymentMethodType() == null - || result.getPaymentMethodType() == DropInPaymentMethod.GOOGLE_PAY) { + || result.getPaymentMethodType() == DropInPaymentMethod.GOOGLE_PAY) { // google pay doesn't have a payment method nonce to display; fallback to OG ui addPaymentMethodButton.setVisibility(VISIBLE); } else { diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java index c42e71155..af130d74e 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java @@ -1,5 +1,11 @@ package com.braintreepayments.api; +import static com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION; +import static com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION_ERROR; +import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST; +import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST_BUNDLE; +import static com.braintreepayments.api.DropInLauncher.EXTRA_SESSION_ID; + import android.content.Intent; import android.os.Bundle; @@ -65,7 +71,7 @@ protected void onCreate(Bundle savedInstanceState) { Intent intent = getIntent(); Exception error = - (Exception) intent.getSerializableExtra(DropInClient.EXTRA_AUTHORIZATION_ERROR); + (Exception) intent.getSerializableExtra(EXTRA_AUTHORIZATION_ERROR); if (error != null) { // echo back error to merchant via activity result finishDropInWithError(error); @@ -73,8 +79,8 @@ protected void onCreate(Bundle savedInstanceState) { } if (dropInInternalClient == null) { - String authorization = intent.getStringExtra(DropInClient.EXTRA_AUTHORIZATION); - String sessionId = intent.getStringExtra(DropInClient.EXTRA_SESSION_ID); + String authorization = intent.getStringExtra(EXTRA_AUTHORIZATION); + String sessionId = intent.getStringExtra(EXTRA_SESSION_ID); DropInRequest dropInRequest = getDropInRequest(intent); dropInInternalClient = new DropInInternalClient(this, authorization, sessionId, dropInRequest); } @@ -120,9 +126,9 @@ void finishDropInWithError(Exception e) { } private DropInRequest getDropInRequest(Intent intent) { - Bundle bundle = intent.getParcelableExtra(DropInClient.EXTRA_CHECKOUT_REQUEST_BUNDLE); + Bundle bundle = intent.getParcelableExtra(EXTRA_CHECKOUT_REQUEST_BUNDLE); bundle.setClassLoader(DropInRequest.class.getClassLoader()); - return bundle.getParcelable(DropInClient.EXTRA_CHECKOUT_REQUEST); + return bundle.getParcelable(EXTRA_CHECKOUT_REQUEST); } @VisibleForTesting diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java index e1b4b36ce..6dc2bd0dc 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java @@ -1,9 +1,9 @@ package com.braintreepayments.api; -import static com.braintreepayments.api.DropInClient.EXTRA_AUTHORIZATION; -import static com.braintreepayments.api.DropInClient.EXTRA_CHECKOUT_REQUEST; -import static com.braintreepayments.api.DropInClient.EXTRA_CHECKOUT_REQUEST_BUNDLE; -import static com.braintreepayments.api.DropInClient.EXTRA_SESSION_ID; +import static com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION; +import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST; +import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST_BUNDLE; +import static com.braintreepayments.api.DropInLauncher.EXTRA_SESSION_ID; import static com.braintreepayments.api.DropInResult.EXTRA_ERROR; import android.content.Context; diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java deleted file mode 100644 index b7da31238..000000000 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInClient.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.braintreepayments.api; - -import android.content.Context; - -import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; -import androidx.fragment.app.FragmentActivity; - -/** - * Used to launch Drop-in and handle results - */ -public class DropInClient { - - static final String EXTRA_CHECKOUT_REQUEST = "com.braintreepayments.api.EXTRA_CHECKOUT_REQUEST"; - static final String EXTRA_CHECKOUT_REQUEST_BUNDLE = "com.braintreepayments.api.EXTRA_CHECKOUT_REQUEST_BUNDLE"; - static final String EXTRA_SESSION_ID = "com.braintreepayments.api.EXTRA_SESSION_ID"; - static final String EXTRA_AUTHORIZATION = "com.braintreepayments.api.EXTRA_AUTHORIZATION"; - static final String EXTRA_AUTHORIZATION_ERROR = "com.braintreepayments.api.EXTRA_AUTHORIZATION_ERROR"; - - @VisibleForTesting - final BraintreeClient braintreeClient; - - private final PaymentMethodClient paymentMethodClient; - private final GooglePayClient googlePayClient; - - private final Authorization authorization; - - private final DropInSharedPreferences dropInSharedPreferences; - - public DropInClient(@NonNull Context context, @NonNull String authorization) { - this(context, authorization, null); - } - - public DropInClient(@NonNull Context context, @NonNull String authorization, @NonNull String customUrlScheme) { - Context applicationContext = context.getApplicationContext(); - BraintreeOptions braintreeOptions = new BraintreeOptions( - applicationContext, - null, - customUrlScheme, - authorization, - null, - IntegrationType.DROP_IN - ); - this.braintreeClient = new BraintreeClient(braintreeOptions); - this.googlePayClient = new GooglePayClient(braintreeClient); - this.paymentMethodClient = new PaymentMethodClient(braintreeClient); - this.dropInSharedPreferences = DropInSharedPreferences.getInstance(applicationContext); - this.authorization = Authorization.fromString(authorization); - } - - public DropInLaunchIntent createLaunchIntent(DropInRequest dropInRequest) { - return new DropInLaunchIntent(dropInRequest, authorization, braintreeClient.getSessionId()); - } - - /** - * Called to get a user's existing payment method, if any. - * The payment method returned is not guaranteed to be the most recently added payment method. - * If your user already has an existing payment method, you may not need to show Drop-In. - *

- * Note: a client token must be used and will only return a payment method if it contains a - * customer id. - * - * @param activity the current {@link FragmentActivity} - * @param callback callback for handling result - */ - // NEXT_MAJOR_VERSION: - update this function name to more accurately represent the behavior of the function - public void fetchMostRecentPaymentMethod(FragmentActivity activity, final FetchMostRecentPaymentMethodCallback callback) { - boolean isClientToken = (authorization instanceof ClientToken); - if (!isClientToken) { - InvalidArgumentException clientTokenRequiredError = - new InvalidArgumentException("DropInClient#fetchMostRecentPaymentMethods() must " + - "be called with a client token"); - callback.onResult(null, clientTokenRequiredError); - return; - } - - DropInPaymentMethod lastUsedPaymentMethod = - dropInSharedPreferences.getLastUsedPaymentMethod(); - - if (lastUsedPaymentMethod == DropInPaymentMethod.GOOGLE_PAY) { - googlePayClient.isReadyToPay(activity, (isReadyToPay, isReadyToPayError) -> { - if (isReadyToPay) { - DropInResult result = new DropInResult(); - result.setPaymentMethodType(DropInPaymentMethod.GOOGLE_PAY); - callback.onResult(result, null); - } else { - getPaymentMethodNonces(callback); - } - }); - } else { - getPaymentMethodNonces(callback); - } - } - - private void getPaymentMethodNonces(final FetchMostRecentPaymentMethodCallback callback) { - paymentMethodClient.getPaymentMethodNonces((paymentMethodNonceList, error) -> { - if (paymentMethodNonceList != null) { - DropInResult result = new DropInResult(); - if (paymentMethodNonceList.size() > 0) { - PaymentMethodNonce paymentMethod = paymentMethodNonceList.get(0); - result.setPaymentMethodNonce(paymentMethod); - } - callback.onResult(result, null); - } else if (error != null) { - callback.onResult(null, error); - } - }); - } -} diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java index f7465430a..0bf137395 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java @@ -10,6 +10,13 @@ public class DropInLauncher implements DefaultLifecycleObserver { private static final String DROP_IN_RESULT = "com.braintreepayments.api.DropIn.RESULT"; + static final String EXTRA_CHECKOUT_REQUEST = "com.braintreepayments.api.EXTRA_CHECKOUT_REQUEST"; + static final String EXTRA_CHECKOUT_REQUEST_BUNDLE = "com.braintreepayments.api.EXTRA_CHECKOUT_REQUEST_BUNDLE"; + static final String EXTRA_SESSION_ID = "com.braintreepayments.api.EXTRA_SESSION_ID"; + static final String EXTRA_AUTHORIZATION = "com.braintreepayments.api.EXTRA_AUTHORIZATION"; + static final String EXTRA_AUTHORIZATION_ERROR = "com.braintreepayments.api.EXTRA_AUTHORIZATION_ERROR"; + + @VisibleForTesting private ActivityResultLauncher activityLauncher; @@ -19,7 +26,10 @@ public DropInLauncher(ComponentActivity activity, DropInLauncherCallback callbac DROP_IN_RESULT, activity, new DropInActivityResultContract(), callback); } - public void launchDropIn(DropInLaunchIntent launchIntent) { + public void launchDropIn(String authString, DropInRequest dropInRequest) { + Authorization authorization = Authorization.fromString(authString); + DropInLaunchIntent launchIntent = + new DropInLaunchIntent(dropInRequest, authorization, ""); activityLauncher.launch(launchIntent); } } diff --git a/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java b/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java index db69816ff..a60bcc60b 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java @@ -15,7 +15,7 @@ public class RecentPaymentMethodsClient { private final PaymentMethodClient paymentMethodClient; private final DropInSharedPreferences sharedPreferences; - RecentPaymentMethodsClient(@NonNull Context context, @NonNull String authorization) { + public RecentPaymentMethodsClient(@NonNull Context context, @NonNull String authorization) { this(context, new BraintreeClient(context, authorization)); } diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java b/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java index aa8a80fed..e44092f0a 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java @@ -3,10 +3,10 @@ import static android.app.Activity.RESULT_CANCELED; import static android.app.Activity.RESULT_FIRST_USER; import static android.app.Activity.RESULT_OK; -import static com.braintreepayments.api.DropInClient.EXTRA_AUTHORIZATION; -import static com.braintreepayments.api.DropInClient.EXTRA_CHECKOUT_REQUEST; -import static com.braintreepayments.api.DropInClient.EXTRA_CHECKOUT_REQUEST_BUNDLE; -import static com.braintreepayments.api.DropInClient.EXTRA_SESSION_ID; +import static com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION; +import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST; +import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST_BUNDLE; +import static com.braintreepayments.api.DropInLauncher.EXTRA_SESSION_ID; import static com.braintreepayments.api.DropInResult.EXTRA_DROP_IN_RESULT; import static com.braintreepayments.api.DropInResult.EXTRA_ERROR; import static org.junit.Assert.assertEquals; diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityUnitTest.kt b/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityUnitTest.kt index 9d22afb14..18b811c18 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityUnitTest.kt +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityUnitTest.kt @@ -7,7 +7,9 @@ import android.content.Intent import android.net.Uri import android.os.Bundle import androidx.test.platform.app.InstrumentationRegistry -import com.braintreepayments.api.DropInClient.EXTRA_CHECKOUT_REQUEST +import com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION_ERROR +import com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST +import com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST_BUNDLE import com.braintreepayments.cardform.utils.CardType import org.json.JSONObject import org.junit.After @@ -1125,7 +1127,7 @@ class DropInActivityUnitTest { private fun setupDropInActivityWithError(authError: Exception) { val context = InstrumentationRegistry.getInstrumentation().targetContext val intent = Intent(context, DropInActivity::class.java) - .putExtra(DropInClient.EXTRA_AUTHORIZATION_ERROR, authError) + .putExtra(EXTRA_AUTHORIZATION_ERROR, authError) activityController = buildActivity(DropInActivity::class.java, intent) activity = activityController.get() @@ -1137,7 +1139,7 @@ class DropInActivityUnitTest { val dropInRequestBundle = Bundle() dropInRequestBundle.putParcelable(EXTRA_CHECKOUT_REQUEST, dropInRequest) val intent = Intent(context, DropInActivity::class.java) - intent.putExtra(DropInClient.EXTRA_CHECKOUT_REQUEST_BUNDLE, dropInRequestBundle) + intent.putExtra(EXTRA_CHECKOUT_REQUEST_BUNDLE, dropInRequestBundle) activityController = buildActivity(DropInActivity::class.java, intent) activity = activityController.get() diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTest.java b/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTest.java deleted file mode 100644 index 7aeb7c834..000000000 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTest.java +++ /dev/null @@ -1,438 +0,0 @@ -package com.braintreepayments.api; - -import static junit.framework.TestCase.assertNotNull; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.when; - -import android.content.Intent; -import android.os.Bundle; - -import androidx.fragment.app.FragmentActivity; -import androidx.test.core.app.ApplicationProvider; -import androidx.work.testing.WorkManagerTestInitHelper; - -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.android.controller.ActivityController; - -import java.util.ArrayList; - -@RunWith(RobolectricTestRunner.class) -public class DropInClientUnitTest { - - private FragmentActivity activity; - private DropInSharedPreferences dropInSharedPreferences; - - @Before - public void beforeEach() { - - dropInSharedPreferences = mock(DropInSharedPreferences.class); - ActivityController activityController = - Robolectric.buildActivity(FragmentActivity.class); - activity = activityController.get(); - // This suppresses errors from WorkManager initialization within BraintreeClient initialization (AnalyticsClient) - WorkManagerTestInitHelper.initializeTestWorkManager(ApplicationProvider.getApplicationContext()); - } - - @Test - public void constructor_setsIntegrationTypeDropIn() { - DropInClient sut = new DropInClient(ApplicationProvider.getApplicationContext(), Fixtures.TOKENIZATION_KEY, new DropInRequest()); - assertEquals(IntegrationType.DROP_IN, sut.braintreeClient.getIntegrationType()); - } - - @Test - public void publicConstructor_setsBraintreeClientWithSessionId() { - DropInClient sut = new DropInClient(ApplicationProvider.getApplicationContext(), Fixtures.TOKENIZATION_KEY, new DropInRequest()); - assertNotNull(sut.braintreeClient.getSessionId()); - } - - @Test - public void getAuthorization_forwardsInvocationToBraintreeClient() { - Authorization authorization = mock(Authorization.class); - BraintreeClient braintreeClient = new MockBraintreeClientBuilder() - .authorizationSuccess(authorization) - .build(); - - DropInClientParams params = new DropInClientParams() - .braintreeClient(braintreeClient); - - DropInClient sut = new DropInClient(params); - - AuthorizationCallback callback = mock(AuthorizationCallback.class); - sut.getAuthorization(callback); - verify(braintreeClient).getAuthorization(callback); - } - - @Test - public void fetchMostRecentPaymentMethod_forwardsAuthorizationFetchErrors() { - Exception authError = new Exception("auth error"); - BraintreeClient braintreeClient = new MockBraintreeClientBuilder() - .authorizationError(authError) - .build(); - - DropInClientParams params = new DropInClientParams() - .braintreeClient(braintreeClient) - .dropInRequest(new DropInRequest()); - - DropInClient sut = new DropInClient(params); - - FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); - sut.fetchMostRecentPaymentMethod(activity, callback); - - verify(callback).onResult(null, authError); - } - - @Test - public void fetchMostRecentPaymentMethod_callsBackWithErrorIfInvalidClientTokenWasUsed() { - BraintreeClient braintreeClient = new MockBraintreeClientBuilder() - .authorizationSuccess(Authorization.fromString(Fixtures.TOKENIZATION_KEY)) - .build(); - - DropInClientParams params = new DropInClientParams() - .braintreeClient(braintreeClient) - .dropInRequest(new DropInRequest()); - - DropInClient sut = new DropInClient(params); - - FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); - sut.fetchMostRecentPaymentMethod(activity, callback); - - ArgumentCaptor captor = ArgumentCaptor.forClass(InvalidArgumentException.class); - verify(callback).onResult((DropInResult) isNull(), captor.capture()); - - InvalidArgumentException exception = captor.getValue(); - assertEquals("DropInClient#fetchMostRecentPaymentMethods() must be called with a client token", exception.getMessage()); - } - - @Test - public void fetchMostRecentPaymentMethod_callsBackWithResultIfLastUsedPaymentMethodTypeWasPayWithGoogle() throws JSONException { - - GooglePayClient googlePayClient = new MockGooglePayClientBuilder() - .isReadyToPaySuccess(true) - .build(); - BraintreeClient braintreeClient = new MockBraintreeClientBuilder() - .authorizationSuccess(Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN)) - .configuration(Configuration.fromJson(Fixtures.CONFIGURATION_WITH_GOOGLE_PAY)) - .build(); - - DropInClientParams params = new DropInClientParams() - .dropInRequest(new DropInRequest()) - .braintreeClient(braintreeClient) - .dropInSharedPreferences(dropInSharedPreferences) - .googlePayClient(googlePayClient); - - when( - dropInSharedPreferences.getLastUsedPaymentMethod() - ).thenReturn(DropInPaymentMethod.GOOGLE_PAY); - - DropInClient sut = new DropInClient(params); - - FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); - sut.fetchMostRecentPaymentMethod(activity, callback); - - ArgumentCaptor captor = ArgumentCaptor.forClass(DropInResult.class); - verify(callback).onResult(captor.capture(), (Exception) isNull()); - - DropInResult result = captor.getValue(); - assertEquals(DropInPaymentMethod.GOOGLE_PAY, result.getPaymentMethodType()); - assertNull(result.getPaymentMethodNonce()); - } - - @Test - public void fetchMostRecentPaymentMethod_doesNotCallBackWithPayWithGoogleIfPayWithGoogleIsNotAvailable() throws JSONException { - - GooglePayClient googlePayClient = new MockGooglePayClientBuilder() - .isReadyToPaySuccess(false) - .build(); - BraintreeClient braintreeClient = new MockBraintreeClientBuilder() - .authorizationSuccess(Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN)) - .configuration(Configuration.fromJson(Fixtures.CONFIGURATION_WITH_GOOGLE_PAY)) - .build(); - - ArrayList paymentMethods = new ArrayList<>(); - paymentMethods.add(CardNonce.fromJSON(new JSONObject(Fixtures.VISA_CREDIT_CARD_RESPONSE))); - paymentMethods.add(GooglePayCardNonce.fromJSON(new JSONObject(Fixtures.GOOGLE_PAY_NETWORK_TOKENIZED_RESPONSE))); - PaymentMethodClient paymentMethodClient = new MockPaymentMethodClientBuilder() - .getPaymentMethodNoncesSuccess(paymentMethods) - .build(); - - DropInClientParams params = new DropInClientParams() - .dropInRequest(new DropInRequest()) - .braintreeClient(braintreeClient) - .paymentMethodClient(paymentMethodClient) - .googlePayClient(googlePayClient) - .dropInSharedPreferences(dropInSharedPreferences); - - when( - dropInSharedPreferences.getLastUsedPaymentMethod() - ).thenReturn(DropInPaymentMethod.GOOGLE_PAY); - - DropInClient sut = new DropInClient(params); - - FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); - sut.fetchMostRecentPaymentMethod(activity, callback); - - ArgumentCaptor captor = ArgumentCaptor.forClass(DropInResult.class); - verify(callback).onResult(captor.capture(), (Exception) isNull()); - - DropInResult result = captor.getValue(); - assertEquals(DropInPaymentMethod.VISA, result.getPaymentMethodType()); - assertNotNull(result.getPaymentMethodNonce()); - assertEquals("11", ((CardNonce) result.getPaymentMethodNonce()).getLastTwo()); - } - - @Test - public void fetchMostRecentPaymentMethod_callsBackWithErrorOnGetPaymentMethodsError() { - BraintreeClient braintreeClient = new MockBraintreeClientBuilder() - .authorizationSuccess(Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN)) - .build(); - - PaymentMethodClient paymentMethodClient = new MockPaymentMethodClientBuilder() - .getPaymentMethodNoncesError(new BraintreeException("Error occurred")) - .build(); - DropInClientParams params = new DropInClientParams() - .braintreeClient(braintreeClient) - .paymentMethodClient(paymentMethodClient) - .dropInSharedPreferences(dropInSharedPreferences) - .dropInRequest(new DropInRequest()); - - DropInClient sut = new DropInClient(params); - - FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); - sut.fetchMostRecentPaymentMethod(activity, callback); - - ArgumentCaptor captor = ArgumentCaptor.forClass(BraintreeException.class); - verify(callback).onResult((DropInResult) isNull(), captor.capture()); - - BraintreeException exception = captor.getValue(); - assertEquals("Error occurred", exception.getMessage()); - } - - @Test - public void fetchMostRecentPaymentMethod_callsBackWithResultWhenThereIsAPaymentMethod() - throws JSONException { - BraintreeClient braintreeClient = new MockBraintreeClientBuilder() - .authorizationSuccess(Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN)) - .configuration(Configuration.fromJson(Fixtures.CONFIGURATION_WITH_GOOGLE_PAY)) - .build(); - - ArrayList paymentMethods = new ArrayList<>(); - paymentMethods.add(CardNonce.fromJSON(new JSONObject(Fixtures.VISA_CREDIT_CARD_RESPONSE))); - - PaymentMethodClient paymentMethodClient = new MockPaymentMethodClientBuilder() - .getPaymentMethodNoncesSuccess(paymentMethods) - .build(); - - DropInClientParams params = new DropInClientParams() - .dropInRequest(new DropInRequest()) - .braintreeClient(braintreeClient) - .dropInSharedPreferences(dropInSharedPreferences) - .paymentMethodClient(paymentMethodClient); - - DropInClient sut = new DropInClient(params); - - FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); - sut.fetchMostRecentPaymentMethod(activity, callback); - - ArgumentCaptor captor = ArgumentCaptor.forClass(DropInResult.class); - verify(callback).onResult(captor.capture(), (Exception) isNull()); - - DropInResult result = captor.getValue(); - assertEquals(DropInPaymentMethod.VISA, result.getPaymentMethodType()); - assertNotNull(result.getPaymentMethodNonce()); - assertEquals("11", ((CardNonce) result.getPaymentMethodNonce()).getLastTwo()); - } - - @Test - public void fetchMostRecentPaymentMethod_callsBackWithNullResultWhenThereAreNoPaymentMethods() throws JSONException { - BraintreeClient braintreeClient = new MockBraintreeClientBuilder() - .authorizationSuccess(Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN)) - .configuration(Configuration.fromJson(Fixtures.CONFIGURATION_WITH_GOOGLE_PAY)) - .build(); - - ArrayList paymentMethods = new ArrayList<>(); - - PaymentMethodClient paymentMethodClient = new MockPaymentMethodClientBuilder() - .getPaymentMethodNoncesSuccess(paymentMethods) - .build(); - - DropInClientParams params = new DropInClientParams() - .dropInRequest(new DropInRequest()) - .braintreeClient(braintreeClient) - .dropInSharedPreferences(dropInSharedPreferences) - .paymentMethodClient(paymentMethodClient); - - DropInClient sut = new DropInClient(params); - - FetchMostRecentPaymentMethodCallback callback = mock(FetchMostRecentPaymentMethodCallback.class); - sut.fetchMostRecentPaymentMethod(activity, callback); - - ArgumentCaptor captor = ArgumentCaptor.forClass(DropInResult.class); - verify(callback).onResult(captor.capture(), (Exception) isNull()); - - DropInResult result = captor.getValue(); - assertNull(result.getPaymentMethodType()); - assertNull(result.getPaymentMethodNonce()); - } - - @Test - public void legacy_launchDropInForResult_withListener_forwardsAuthorizationFetchErrors() { - Exception authError = new Exception("auth error"); - BraintreeClient braintreeClient = new MockBraintreeClientBuilder() - .sessionId("session-id") - .authorizationError(authError) - .build(); - - DropInRequest dropInRequest = new DropInRequest(); - DropInClientParams params = new DropInClientParams() - .braintreeClient(braintreeClient) - .dropInRequest(dropInRequest); - - DropInClient sut = new DropInClient(params); - - DropInListener listener = mock(DropInListener.class); - sut.setListener(listener); - - FragmentActivity activity = mock(FragmentActivity.class); - sut.launchDropInForResult(activity, 123); - - verify(listener).onDropInFailure(authError); - } - - @Test - public void legacy_launchDropInForResult_withoutListener_launchesDropInActivityWithError() { - Exception authError = new Exception("auth error"); - BraintreeClient braintreeClient = new MockBraintreeClientBuilder() - .sessionId("session-id") - .authorizationError(authError) - .build(); - - DropInRequest dropInRequest = new DropInRequest(); - DropInClientParams params = new DropInClientParams() - .braintreeClient(braintreeClient) - .dropInRequest(dropInRequest); - - DropInClient sut = new DropInClient(params); - - FragmentActivity activity = mock(FragmentActivity.class); - sut.launchDropInForResult(activity, 123); - - ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - verify(activity).startActivityForResult(captor.capture(), eq(123)); - - Intent intent = captor.getValue(); - Exception error = (Exception) intent.getSerializableExtra(DropInClient.EXTRA_AUTHORIZATION_ERROR); - assertEquals("auth error", error.getMessage()); - } - - @Test - public void legacy_launchDropInForResult_launchesDropInActivityWithIntentExtras() { - Authorization authorization = mock(Authorization.class); - when(authorization.toString()).thenReturn("authorization"); - - BraintreeClient braintreeClient = new MockBraintreeClientBuilder() - .sessionId("session-id") - .authorizationSuccess(authorization) - .build(); - - DropInRequest dropInRequest = new DropInRequest(); - dropInRequest.setVaultManagerEnabled(true); - - DropInClientParams params = new DropInClientParams() - .braintreeClient(braintreeClient) - .dropInRequest(dropInRequest); - - DropInClient sut = new DropInClient(params); - - FragmentActivity activity = mock(FragmentActivity.class); - sut.launchDropInForResult(activity, 123); - - ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - verify(activity).startActivityForResult(captor.capture(), eq(123)); - - Intent intent = captor.getValue(); - assertEquals("session-id", intent.getStringExtra(DropInClient.EXTRA_SESSION_ID)); - assertEquals("authorization", intent.getStringExtra(DropInClient.EXTRA_AUTHORIZATION)); - - Bundle bundle = intent.getParcelableExtra(DropInClient.EXTRA_CHECKOUT_REQUEST_BUNDLE); - bundle.setClassLoader(DropInRequest.class.getClassLoader()); - DropInRequest dropInRequestExtra = bundle.getParcelable(DropInClient.EXTRA_CHECKOUT_REQUEST); - assertTrue(dropInRequestExtra.isVaultManagerEnabled()); - } - - @Test - public void onDropInResult_whenResultHasNoError_notifiesListenerOfSuccessViaCallback() { - DropInClientParams params = new DropInClientParams(); - DropInClient sut = new DropInClient(params); - - DropInListener listener = mock(DropInListener.class); - sut.setListener(listener); - - DropInResult dropInResult = new DropInResult(); - sut.onDropInResult(dropInResult); - - verify(listener).onDropInSuccess(dropInResult); - } - - @Test - public void onDropInResult_whenResultHasError_notifiesListenerOfErrorViaCallback() { - DropInClientParams params = new DropInClientParams(); - DropInClient sut = new DropInClient(params); - - DropInListener listener = mock(DropInListener.class); - sut.setListener(listener); - - DropInResult dropInResult = new DropInResult(); - Exception error = new Exception("sample error"); - dropInResult.setError(error); - - sut.onDropInResult(dropInResult); - verify(listener).onDropInFailure(error); - } - - @Test - public void onDropInResult_whenResultIsNull_doesNothing() { - DropInClientParams params = new DropInClientParams(); - DropInClient sut = new DropInClient(params); - - DropInListener listener = mock(DropInListener.class); - sut.setListener(listener); - - sut.onDropInResult(null); - verifyNoInteractions(listener); - } - - @Test - public void onDropInResult_whenListenerIsNull_doesNothing() { - DropInClientParams params = new DropInClientParams(); - DropInClient sut = new DropInClient(params); - - - DropInResult dropInResult = new DropInResult(); - sut.onDropInResult(dropInResult); - } - - @Test - public void invalidateClientToken_forwardsInvocationIntoBraintreeClient() { - BraintreeClient braintreeClient = new MockBraintreeClientBuilder().build(); - DropInClientParams params = new DropInClientParams() - .braintreeClient(braintreeClient); - DropInClient sut = new DropInClient(params); - - sut.invalidateClientToken(); - verify(braintreeClient).invalidateClientToken(); - } -} \ No newline at end of file diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTestKt.kt b/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTestKt.kt deleted file mode 100644 index 2606ff726..000000000 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInClientUnitTestKt.kt +++ /dev/null @@ -1,223 +0,0 @@ -package com.braintreepayments.api - -import android.content.Context -import androidx.activity.result.ActivityResultRegistry -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentActivity -import androidx.lifecycle.Lifecycle -import androidx.test.core.app.ApplicationProvider -import androidx.work.testing.WorkManagerTestInitHelper -import io.mockk.* -import org.json.JSONObject -import org.junit.Assert.* -import org.junit.Before -import org.junit.BeforeClass -import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner - -// TODO: Slowly migrate the entire DropInClientUnitTest to Kotlin -@RunWith(RobolectricTestRunner::class) -class DropInClientUnitTestKt { - - companion object { - - @BeforeClass - @JvmStatic - fun beforeAll() { - // required for mockk since AuthorizationCallback is package-private - registerInstanceFactory { mockk() } - } - } - - private val applicationContext: Context = ApplicationProvider.getApplicationContext() - - private lateinit var fragment: Fragment - private lateinit var fragmentLifecycle: Lifecycle - - private lateinit var activity: FragmentActivity - private lateinit var activityLifecycle: Lifecycle - - private lateinit var resultRegistry: ActivityResultRegistry - - private lateinit var dropInRequest: DropInRequest - private lateinit var braintreeClient: BraintreeClient - - private lateinit var clientToken: Authorization - private lateinit var clientTokenProvider: ClientTokenProvider - - @Before - fun beforeEach() { - - dropInRequest = DropInRequest() - braintreeClient = mockk() - - clientToken = Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN) - clientTokenProvider = mockk() - - activity = mockk(relaxed = true) - every { activity.applicationContext } returns applicationContext - - resultRegistry = mockk() - every { activity.activityResultRegistry } returns resultRegistry - - activityLifecycle = mockk(relaxed = true) - every { activity.lifecycle } returns activityLifecycle - - fragment = mockk() - every { fragment.requireActivity() } returns activity - - fragmentLifecycle = mockk() - every { fragment.lifecycle } returns fragmentLifecycle - - // This suppresses errors from WorkManager initialization within BraintreeClient - // initialization (AnalyticsClient) - WorkManagerTestInitHelper.initializeTestWorkManager(applicationContext) - } - - @Test - fun constructor_setsIntegrationTypeDropIn() { - val sut = DropInClient(activity, dropInRequest, clientTokenProvider) - assertEquals(IntegrationType.DROP_IN, sut.braintreeClient.integrationType) - } - - @Test - fun constructor_withFragment_registersLifecycleObserver() { - val observerSlot = slot() - justRun { fragmentLifecycle.addObserver(capture(observerSlot)) } - - val sut = DropInClient(fragment, dropInRequest, clientTokenProvider) - val capturedObserver = observerSlot.captured - - assertSame(capturedObserver, sut.observer) - assertSame(resultRegistry, capturedObserver.activityResultRegistry) - assertSame(sut, capturedObserver.dropInClient) - } - - @Test - fun constructor_withActivity_registersLifecycleObserver() { - val observerSlot = slot() - justRun { activityLifecycle.addObserver(capture(observerSlot)) } - - val sut = DropInClient(activity, dropInRequest, clientTokenProvider) - val capturedObserver = observerSlot.captured - - assertSame(capturedObserver, sut.observer) - assertSame(resultRegistry, capturedObserver.activityResultRegistry) - assertSame(sut, capturedObserver.dropInClient) - } - - @Test - fun constructor_withContext_doesNotRegisterLifecycleObserver() { - val sut = DropInClient(applicationContext, Fixtures.TOKENIZATION_KEY, dropInRequest) - assertNull(sut.observer) - } - - @Test - fun legacy_launchDropInForResult_withObserver_launchesWithObserver() { - every { braintreeClient.sessionId } returns "sample-session-id" - - every { braintreeClient.getAuthorization(any()) } answers { call -> - val callback = call.invocation.args[0] as AuthorizationCallback - callback.onAuthorizationResult(clientToken, null) - } - - val params = DropInClientParams() - .dropInRequest(dropInRequest) - .braintreeClient(braintreeClient) - val sut = DropInClient(params) - sut.observer = mockk() - - val intentDataSlot = slot() - justRun { sut.observer.launch(capture(intentDataSlot)) } - - sut.launchDropInForResult(activity, 123) - val capturedIntentData = intentDataSlot.captured - - assertEquals("sample-session-id", capturedIntentData.sessionId) - assertEquals(clientToken.toString(), capturedIntentData.authorization.toString()) - assertNotNull(capturedIntentData.dropInRequest) - } - - @Test - fun launchDropIn_withObserver_launchesWithObserver() { - every { braintreeClient.sessionId } returns "sample-session-id" - - every { braintreeClient.getAuthorization(any()) } answers { call -> - val callback = call.invocation.args[0] as AuthorizationCallback - callback.onAuthorizationResult(clientToken, null) - } - - val params = DropInClientParams() - .dropInRequest(dropInRequest) - .braintreeClient(braintreeClient) - val sut = DropInClient(params) - sut.observer = mockk() - - val intentDataSlot = slot() - justRun { sut.observer.launch(capture(intentDataSlot)) } - - sut.launchDropIn() - val capturedIntentData = intentDataSlot.captured - - assertEquals("sample-session-id", capturedIntentData.sessionId) - assertEquals(clientToken.toString(), capturedIntentData.authorization.toString()) - assertNotNull(capturedIntentData.dropInRequest) - } - - @Test - fun launchDropIn_forwardsAuthorizationFetchErrorsToListener() { - every { braintreeClient.sessionId } returns "sample-session-id" - - val authError = Exception("auth error") - every { braintreeClient.getAuthorization(any()) } answers { call -> - val callback = call.invocation.args[0] as AuthorizationCallback - callback.onAuthorizationResult(null, authError) - } - - val params = DropInClientParams() - .dropInRequest(dropInRequest) - .braintreeClient(braintreeClient) - val sut = DropInClient(params) - - val listener = mockk(relaxed = true) - sut.setListener(listener) - - sut.launchDropIn() - verify { listener.onDropInFailure(authError)} - } - - @Test - fun onDropInResult_notifiesListenerOfSuccess() { - val params = DropInClientParams() - .dropInRequest(dropInRequest) - val sut = DropInClient(params) - - val listener = mockk(relaxed = true) - sut.setListener(listener) - - val dropInResult = DropInResult() - dropInResult.paymentMethodNonce = - CardNonce.fromJSON(JSONObject(Fixtures.PAYMENT_METHODS_VISA_CREDIT_CARD)) - - sut.onDropInResult(dropInResult) - verify { listener.onDropInSuccess(dropInResult) } - } - - @Test - fun onDropInResult_notifiesListenerOfFailure() { - val params = DropInClientParams() - .dropInRequest(dropInRequest) - val sut = DropInClient(params) - - val listener = mockk(relaxed = true) - sut.setListener(listener) - - val dropInResult = DropInResult() - val error = Exception("error") - dropInResult.error = error - - sut.onDropInResult(dropInResult) - verify { listener.onDropInFailure(error) } - } -} diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt index c90f51fa5..289f6be64 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt @@ -5,6 +5,7 @@ import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultRegistry import io.mockk.every import io.mockk.mockk +import io.mockk.slot import io.mockk.verify import junit.framework.TestCase import org.junit.Test @@ -28,7 +29,7 @@ class DropInLauncherUnitTest : TestCase() { verify { activityResultRegistry.register( expectedKey, - activity, + same(activity), any(), same(callback) ) @@ -55,11 +56,14 @@ class DropInLauncherUnitTest : TestCase() { val sut = DropInLauncher(activity, callback) val dropInRequest = DropInRequest() - val authorization = Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN) - val dropInLaunchIntent = - DropInLaunchIntent(dropInRequest, authorization, "fake-session-id") + sut.launchDropIn(Fixtures.BASE64_CLIENT_TOKEN, dropInRequest) - sut.launchDropIn(dropInLaunchIntent) - verify { activityLauncher.launch(dropInLaunchIntent) } + val slot = slot() + verify { activityLauncher.launch(capture(slot)) } + + val capturedLaunchIntent = slot.captured + assertSame(capturedLaunchIntent.dropInRequest, dropInRequest) + assertEquals(Fixtures.BASE64_CLIENT_TOKEN, capturedLaunchIntent.authorization.toString()) + assertEquals("fake-session-id", capturedLaunchIntent.sessionId) } } \ No newline at end of file From 9d00464b0a6c559067b35a09a8211d2fab9d6d65 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 15:43:00 -0500 Subject: [PATCH 11/20] Fix unit tests. --- .../com/braintreepayments/api/DropInActivity.java | 4 +--- .../api/DropInActivityResultContract.java | 2 -- .../braintreepayments/api/DropInInternalClient.java | 8 ++++---- .../braintreepayments/api/DropInLaunchIntent.java | 8 +------- .../com/braintreepayments/api/DropInLauncher.java | 3 +-- .../api/RecentPaymentMethodsClient.java | 6 ++---- .../api/DropInActivityResultContractUnitTest.java | 4 +--- .../api/DropInInternalClientUnitTest.java | 13 +++---------- .../braintreepayments/api/DropInLauncherUnitTest.kt | 6 ++---- .../api/RecentPaymentMethodsClientUnitTest.java | 7 ------- 10 files changed, 15 insertions(+), 46 deletions(-) diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java index af130d74e..b720f6335 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java @@ -4,7 +4,6 @@ import static com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION_ERROR; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST_BUNDLE; -import static com.braintreepayments.api.DropInLauncher.EXTRA_SESSION_ID; import android.content.Intent; import android.os.Bundle; @@ -80,9 +79,8 @@ protected void onCreate(Bundle savedInstanceState) { if (dropInInternalClient == null) { String authorization = intent.getStringExtra(EXTRA_AUTHORIZATION); - String sessionId = intent.getStringExtra(EXTRA_SESSION_ID); DropInRequest dropInRequest = getDropInRequest(intent); - dropInInternalClient = new DropInInternalClient(this, authorization, sessionId, dropInRequest); + dropInInternalClient = new DropInInternalClient(this, authorization, dropInRequest); } alertPresenter = new AlertPresenter(); diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java index 6dc2bd0dc..ef0353362 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java @@ -3,7 +3,6 @@ import static com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST_BUNDLE; -import static com.braintreepayments.api.DropInLauncher.EXTRA_SESSION_ID; import static com.braintreepayments.api.DropInResult.EXTRA_ERROR; import android.content.Context; @@ -24,7 +23,6 @@ public Intent createIntent(@NonNull Context context, DropInLaunchIntent input) { dropInRequestBundle.putParcelable(EXTRA_CHECKOUT_REQUEST, input.getDropInRequest()); return new Intent(context, DropInActivity.class) .putExtra(EXTRA_CHECKOUT_REQUEST_BUNDLE, dropInRequestBundle) - .putExtra(EXTRA_SESSION_ID, input.getSessionId()) .putExtra(EXTRA_AUTHORIZATION, input.getAuthorization().toString()); } diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInInternalClient.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInInternalClient.java index 0560ea8c9..e63ea12aa 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInInternalClient.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInInternalClient.java @@ -37,11 +37,11 @@ class DropInInternalClient { private final PaymentMethodInspector paymentMethodInspector = new PaymentMethodInspector(); - private static DropInInternalClientParams createDefaultParams(Context context, String authorization, DropInRequest dropInRequest, String sessionId) { + private static DropInInternalClientParams createDefaultParams(Context context, String authorization, DropInRequest dropInRequest) { String customUrlScheme = dropInRequest.getCustomUrlScheme(); BraintreeOptions braintreeOptions = - new BraintreeOptions(context, sessionId, customUrlScheme, authorization, null, IntegrationType.DROP_IN); + new BraintreeOptions(context, null, customUrlScheme, authorization, null, IntegrationType.DROP_IN); BraintreeClient braintreeClient = new BraintreeClient(braintreeOptions); @@ -59,8 +59,8 @@ private static DropInInternalClientParams createDefaultParams(Context context, S .dropInSharedPreferences(DropInSharedPreferences.getInstance(context.getApplicationContext())); } - DropInInternalClient(FragmentActivity activity, String authorization, String sessionId, DropInRequest dropInRequest) { - this(createDefaultParams(activity, authorization, dropInRequest, sessionId)); + DropInInternalClient(FragmentActivity activity, String authorization, DropInRequest dropInRequest) { + this(createDefaultParams(activity, authorization, dropInRequest)); } @VisibleForTesting diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java index 68ec62f8d..5fbbff329 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java @@ -4,10 +4,8 @@ public class DropInLaunchIntent { private final Authorization authorization; private final DropInRequest dropInRequest; - private final String sessionId; - DropInLaunchIntent(DropInRequest dropInRequest, Authorization authorization, String sessionId) { - this.sessionId = sessionId; + DropInLaunchIntent(DropInRequest dropInRequest, Authorization authorization) { this.dropInRequest = dropInRequest; this.authorization = authorization; } @@ -19,8 +17,4 @@ DropInRequest getDropInRequest() { Authorization getAuthorization() { return authorization; } - - String getSessionId() { - return sessionId; - } } diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java index 0bf137395..a7ab84047 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java @@ -12,7 +12,6 @@ public class DropInLauncher implements DefaultLifecycleObserver { static final String EXTRA_CHECKOUT_REQUEST = "com.braintreepayments.api.EXTRA_CHECKOUT_REQUEST"; static final String EXTRA_CHECKOUT_REQUEST_BUNDLE = "com.braintreepayments.api.EXTRA_CHECKOUT_REQUEST_BUNDLE"; - static final String EXTRA_SESSION_ID = "com.braintreepayments.api.EXTRA_SESSION_ID"; static final String EXTRA_AUTHORIZATION = "com.braintreepayments.api.EXTRA_AUTHORIZATION"; static final String EXTRA_AUTHORIZATION_ERROR = "com.braintreepayments.api.EXTRA_AUTHORIZATION_ERROR"; @@ -29,7 +28,7 @@ public DropInLauncher(ComponentActivity activity, DropInLauncherCallback callbac public void launchDropIn(String authString, DropInRequest dropInRequest) { Authorization authorization = Authorization.fromString(authString); DropInLaunchIntent launchIntent = - new DropInLaunchIntent(dropInRequest, authorization, ""); + new DropInLaunchIntent(dropInRequest, authorization); activityLauncher.launch(launchIntent); } } diff --git a/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java b/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java index a60bcc60b..cea9b903e 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java @@ -24,7 +24,6 @@ private RecentPaymentMethodsClient( @NonNull BraintreeClient braintreeClient ) { this( - context, braintreeClient, new GooglePayClient(braintreeClient), new PaymentMethodClient(braintreeClient), @@ -34,15 +33,14 @@ private RecentPaymentMethodsClient( @VisibleForTesting RecentPaymentMethodsClient( - @NonNull Context context, @NonNull BraintreeClient braintreeClient, @NonNull GooglePayClient googlePayClient, @NonNull PaymentMethodClient paymentMethodClient, @NonNull DropInSharedPreferences sharedPreferences ) { this.braintreeClient = braintreeClient; - this.googlePayClient = new GooglePayClient(braintreeClient); - this.paymentMethodClient = new PaymentMethodClient(braintreeClient); + this.googlePayClient = googlePayClient; + this.paymentMethodClient = paymentMethodClient; this.sharedPreferences = sharedPreferences; } diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java b/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java index e44092f0a..49e06f447 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java @@ -6,7 +6,6 @@ import static com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST_BUNDLE; -import static com.braintreepayments.api.DropInLauncher.EXTRA_SESSION_ID; import static com.braintreepayments.api.DropInResult.EXTRA_DROP_IN_RESULT; import static com.braintreepayments.api.DropInResult.EXTRA_ERROR; import static org.junit.Assert.assertEquals; @@ -42,14 +41,13 @@ public void createIntent_returnsIntentWithExtras() { DropInRequest dropInRequest = new DropInRequest(); Authorization authorization = Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN); - DropInLaunchIntent input = new DropInLaunchIntent(dropInRequest, authorization, sessionId); + DropInLaunchIntent input = new DropInLaunchIntent(dropInRequest, authorization); Intent intent = sut.createIntent(context, input); String expectedClass = "com.braintreepayments.api.DropInActivity"; assertEquals(expectedClass, intent.getComponent().getClassName()); - assertEquals("sample-session-id", intent.getStringExtra(EXTRA_SESSION_ID)); assertEquals(Fixtures.BASE64_CLIENT_TOKEN, intent.getStringExtra(EXTRA_AUTHORIZATION)); Bundle requestBundle = intent.getBundleExtra(EXTRA_CHECKOUT_REQUEST_BUNDLE); diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInInternalClientUnitTest.java b/Drop-In/src/test/java/com/braintreepayments/api/DropInInternalClientUnitTest.java index c9d6233ec..f7163efeb 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInInternalClientUnitTest.java +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInInternalClientUnitTest.java @@ -63,21 +63,14 @@ public void beforeEach() { @Test public void constructor_setsIntegrationTypeDropIn() { DropInInternalClient sut = - new DropInInternalClient(activity, Fixtures.TOKENIZATION_KEY, "session-id", new DropInRequest()); + new DropInInternalClient(activity, Fixtures.TOKENIZATION_KEY, new DropInRequest()); assertEquals(IntegrationType.DROP_IN, sut.braintreeClient.getIntegrationType()); } - @Test - public void internalConstructor_setsBraintreeClientWithSessionId() { - DropInInternalClient sut = - new DropInInternalClient(activity, Fixtures.TOKENIZATION_KEY, "session-id", new DropInRequest()); - assertEquals("session-id", sut.braintreeClient.getSessionId()); - } - @Test public void internalConstructor_usesDefaultBraintreeCustomUrlScheme() { DropInInternalClient sut = - new DropInInternalClient(activity, Fixtures.TOKENIZATION_KEY, "session-id", new DropInRequest()); + new DropInInternalClient(activity, Fixtures.TOKENIZATION_KEY, new DropInRequest()); assertEquals("com.braintreepayments.api.dropin.test.braintree", sut.braintreeClient.getReturnUrlScheme()); } @@ -86,7 +79,7 @@ public void internalConstructor_overridesBraintreeCustomUrlSchemeIfSet() { DropInRequest request = new DropInRequest(); request.setCustomUrlScheme("sample-custom-url-scheme"); DropInInternalClient sut = - new DropInInternalClient(activity, Fixtures.TOKENIZATION_KEY, "session-id", request); + new DropInInternalClient(activity, Fixtures.TOKENIZATION_KEY, request); assertEquals("sample-custom-url-scheme", sut.braintreeClient.getReturnUrlScheme()); } diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt index 289f6be64..9c3d90097 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt @@ -10,7 +10,6 @@ import io.mockk.verify import junit.framework.TestCase import org.junit.Test import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.same import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -29,9 +28,9 @@ class DropInLauncherUnitTest : TestCase() { verify { activityResultRegistry.register( expectedKey, - same(activity), + activity, any(), - same(callback) + callback ) } } @@ -64,6 +63,5 @@ class DropInLauncherUnitTest : TestCase() { val capturedLaunchIntent = slot.captured assertSame(capturedLaunchIntent.dropInRequest, dropInRequest) assertEquals(Fixtures.BASE64_CLIENT_TOKEN, capturedLaunchIntent.authorization.toString()) - assertEquals("fake-session-id", capturedLaunchIntent.sessionId) } } \ No newline at end of file diff --git a/Drop-In/src/test/java/com/braintreepayments/api/RecentPaymentMethodsClientUnitTest.java b/Drop-In/src/test/java/com/braintreepayments/api/RecentPaymentMethodsClientUnitTest.java index 4737ee9fd..a234d0c92 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/RecentPaymentMethodsClientUnitTest.java +++ b/Drop-In/src/test/java/com/braintreepayments/api/RecentPaymentMethodsClientUnitTest.java @@ -55,7 +55,6 @@ public void fetchMostRecentPaymentMethod_forwardsAuthorizationFetchErrors() { .build(); RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( - context, braintreeClient, new GooglePayClient(braintreeClient), new PaymentMethodClient(braintreeClient), @@ -75,7 +74,6 @@ public void fetchMostRecentPaymentMethod_callsBackWithErrorIfInvalidClientTokenW .build(); RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( - context, braintreeClient, new GooglePayClient(braintreeClient), new PaymentMethodClient(braintreeClient), @@ -104,7 +102,6 @@ public void fetchMostRecentPaymentMethod_callsBackWithResultIfLastUsedPaymentMet .build(); RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( - context, braintreeClient, googlePayClient, new PaymentMethodClient(braintreeClient), @@ -149,7 +146,6 @@ public void fetchMostRecentPaymentMethod_doesNotCallBackWithPayWithGoogleIfPayWi ).thenReturn(DropInPaymentMethod.GOOGLE_PAY); RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( - context, braintreeClient, googlePayClient, paymentMethodClient, @@ -179,7 +175,6 @@ public void fetchMostRecentPaymentMethod_callsBackWithErrorOnGetPaymentMethodsEr .build(); RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( - context, braintreeClient, new GooglePayClient(braintreeClient), paymentMethodClient, @@ -212,7 +207,6 @@ public void fetchMostRecentPaymentMethod_callsBackWithResultWhenThereIsAPaymentM .build(); RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( - context, braintreeClient, new GooglePayClient(braintreeClient), paymentMethodClient, @@ -245,7 +239,6 @@ public void fetchMostRecentPaymentMethod_callsBackWithNullResultWhenThereAreNoPa .build(); RecentPaymentMethodsClient sut = new RecentPaymentMethodsClient( - context, braintreeClient, new GooglePayClient(braintreeClient), paymentMethodClient, From 6457aa50172dad9df457b202f6ea8629b2b4eed6 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 15:55:01 -0500 Subject: [PATCH 12/20] Remove DropInClientParams class. --- .../api/DropInClientParams.java | 79 ------------------- 1 file changed, 79 deletions(-) delete mode 100644 Drop-In/src/main/java/com/braintreepayments/api/DropInClientParams.java diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInClientParams.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInClientParams.java deleted file mode 100644 index d76cd0ae7..000000000 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInClientParams.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.braintreepayments.api; - -import androidx.fragment.app.FragmentActivity; -import androidx.lifecycle.Lifecycle; - -class DropInClientParams { - - private DropInRequest dropInRequest; - - private BraintreeClient braintreeClient; - private GooglePayClient googlePayClient; - private PaymentMethodClient paymentMethodClient; - private DropInSharedPreferences dropInSharedPreferences; - private FragmentActivity activity; - private Lifecycle lifecycle; - - DropInRequest getDropInRequest() { - return dropInRequest; - } - - DropInClientParams dropInRequest(DropInRequest dropInRequest) { - this.dropInRequest = dropInRequest; - return this; - } - - BraintreeClient getBraintreeClient() { - return braintreeClient; - } - - DropInClientParams braintreeClient(BraintreeClient braintreeClient) { - this.braintreeClient = braintreeClient; - return this; - } - - GooglePayClient getGooglePayClient() { - return googlePayClient; - } - - DropInClientParams googlePayClient(GooglePayClient googlePayClient) { - this.googlePayClient = googlePayClient; - return this; - } - - PaymentMethodClient getPaymentMethodClient() { - return paymentMethodClient; - } - - DropInClientParams paymentMethodClient(PaymentMethodClient paymentMethodClient) { - this.paymentMethodClient = paymentMethodClient; - return this; - } - - DropInClientParams dropInSharedPreferences(DropInSharedPreferences dropInSharedPreferences) { - this.dropInSharedPreferences = dropInSharedPreferences; - return this; - } - - DropInSharedPreferences getDropInSharedPreferences() { - return dropInSharedPreferences; - } - - DropInClientParams activity(FragmentActivity activity) { - this.activity = activity; - return this; - } - - FragmentActivity getActivity() { - return activity; - } - - DropInClientParams lifecycle(Lifecycle lifecycle) { - this.lifecycle = lifecycle; - return this; - } - - Lifecycle getLifecycle() { - return lifecycle; - } -} From 6810ac73008f5a45193742f398e897ee232e3d4c Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 16:01:18 -0500 Subject: [PATCH 13/20] Add class and constructor documentation to RecentPaymentMethodsClient. --- .../api/RecentPaymentMethodsClient.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java b/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java index cea9b903e..73ef5517d 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/RecentPaymentMethodsClient.java @@ -6,6 +6,9 @@ import androidx.annotation.VisibleForTesting; import androidx.fragment.app.FragmentActivity; +/** + * Fetches recently used payment method nonces for the user associated with a given client token. + */ public class RecentPaymentMethodsClient { private final BraintreeClient braintreeClient; @@ -15,8 +18,14 @@ public class RecentPaymentMethodsClient { private final PaymentMethodClient paymentMethodClient; private final DropInSharedPreferences sharedPreferences; - public RecentPaymentMethodsClient(@NonNull Context context, @NonNull String authorization) { - this(context, new BraintreeClient(context, authorization)); + /** + * Create a new instance of {@link RecentPaymentMethodsClient}. + * + * @param context Android context + * @param clientToken Client Token + */ + public RecentPaymentMethodsClient(@NonNull Context context, @NonNull String clientToken) { + this(context, new BraintreeClient(context, clientToken)); } private RecentPaymentMethodsClient( From 1a842ce03f5043ecbdc2173c9d5a464781885a35 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 16:05:31 -0500 Subject: [PATCH 14/20] Provide documentation for DropInLauncherCallback. --- .../com/braintreepayments/api/DropInLauncherCallback.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncherCallback.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncherCallback.java index 036bf356c..8b8c0bb12 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncherCallback.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncherCallback.java @@ -2,8 +2,16 @@ import androidx.activity.result.ActivityResultCallback; +/** + * Callback used to receive an Activity result from {@link DropInLauncher}. + */ public interface DropInLauncherCallback extends ActivityResultCallback { + /** + * Provides the result of launching {@link DropInActivity}. + * + * @param result DropInResult + */ @Override void onActivityResult(DropInResult result); } \ No newline at end of file From 82204587d9703f821351b6b6837907448f4da778 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 27 Mar 2024 16:11:46 -0500 Subject: [PATCH 15/20] Rename DropInLaunchIntent to DropInLaunchInput and make it package private. --- .../braintreepayments/api/DropInActivityResultContract.java | 4 ++-- .../api/{DropInLaunchIntent.java => DropInLaunchInput.java} | 4 ++-- .../main/java/com/braintreepayments/api/DropInLauncher.java | 6 +++--- .../api/DropInActivityResultContractUnitTest.java | 2 +- .../com/braintreepayments/api/DropInLauncherUnitTest.kt | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) rename Drop-In/src/main/java/com/braintreepayments/api/{DropInLaunchIntent.java => DropInLaunchInput.java} (76%) diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java index ef0353362..6bea3f21a 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java @@ -14,11 +14,11 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -class DropInActivityResultContract extends ActivityResultContract { +class DropInActivityResultContract extends ActivityResultContract { @NonNull @Override - public Intent createIntent(@NonNull Context context, DropInLaunchIntent input) { + public Intent createIntent(@NonNull Context context, DropInLaunchInput input) { Bundle dropInRequestBundle = new Bundle(); dropInRequestBundle.putParcelable(EXTRA_CHECKOUT_REQUEST, input.getDropInRequest()); return new Intent(context, DropInActivity.class) diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchInput.java similarity index 76% rename from Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java rename to Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchInput.java index 5fbbff329..4d0fc5fee 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchIntent.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchInput.java @@ -1,11 +1,11 @@ package com.braintreepayments.api; -public class DropInLaunchIntent { +class DropInLaunchInput { private final Authorization authorization; private final DropInRequest dropInRequest; - DropInLaunchIntent(DropInRequest dropInRequest, Authorization authorization) { + DropInLaunchInput(DropInRequest dropInRequest, Authorization authorization) { this.dropInRequest = dropInRequest; this.authorization = authorization; } diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java index a7ab84047..9760d320d 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java @@ -17,7 +17,7 @@ public class DropInLauncher implements DefaultLifecycleObserver { @VisibleForTesting - private ActivityResultLauncher activityLauncher; + private ActivityResultLauncher activityLauncher; public DropInLauncher(ComponentActivity activity, DropInLauncherCallback callback) { ActivityResultRegistry registry = activity.getActivityResultRegistry(); @@ -27,8 +27,8 @@ public DropInLauncher(ComponentActivity activity, DropInLauncherCallback callbac public void launchDropIn(String authString, DropInRequest dropInRequest) { Authorization authorization = Authorization.fromString(authString); - DropInLaunchIntent launchIntent = - new DropInLaunchIntent(dropInRequest, authorization); + DropInLaunchInput launchIntent = + new DropInLaunchInput(dropInRequest, authorization); activityLauncher.launch(launchIntent); } } diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java b/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java index 49e06f447..e47b50cf6 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInActivityResultContractUnitTest.java @@ -41,7 +41,7 @@ public void createIntent_returnsIntentWithExtras() { DropInRequest dropInRequest = new DropInRequest(); Authorization authorization = Authorization.fromString(Fixtures.BASE64_CLIENT_TOKEN); - DropInLaunchIntent input = new DropInLaunchIntent(dropInRequest, authorization); + DropInLaunchInput input = new DropInLaunchInput(dropInRequest, authorization); Intent intent = sut.createIntent(context, input); diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt index 9c3d90097..ea16ee5ab 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt @@ -41,7 +41,7 @@ class DropInLauncherUnitTest : TestCase() { val activityResultRegistry = mockk(relaxed = true) every { activity.activityResultRegistry } returns activityResultRegistry - val activityLauncher: ActivityResultLauncher = mockk(relaxed = true) + val activityLauncher: ActivityResultLauncher = mockk(relaxed = true) every { activityResultRegistry.register( any(), @@ -57,7 +57,7 @@ class DropInLauncherUnitTest : TestCase() { val dropInRequest = DropInRequest() sut.launchDropIn(Fixtures.BASE64_CLIENT_TOKEN, dropInRequest) - val slot = slot() + val slot = slot() verify { activityLauncher.launch(capture(slot)) } val capturedLaunchIntent = slot.captured From e0658c346193a2432422e61d78628807e799fd94 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 3 Apr 2024 11:38:01 -0500 Subject: [PATCH 16/20] Add place authorization string in DropInRequest. --- .../braintreepayments/demo/MainActivity.java | 4 ++-- .../braintreepayments/api/DropInActivity.java | 4 +--- .../api/DropInActivityResultContract.java | 10 ++++------ .../api/DropInInternalClient.java | 7 ++++--- .../api/DropInLaunchInput.java | 20 ------------------- .../braintreepayments/api/DropInLauncher.java | 10 +++------- .../braintreepayments/api/DropInRequest.java | 14 ++++++++++++- .../api/DropInInternalClientUnitTest.java | 6 +++--- .../api/DropInLauncherUnitTest.kt | 2 +- 9 files changed, 31 insertions(+), 46 deletions(-) delete mode 100644 Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchInput.java diff --git a/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java b/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java index f9c3e8cee..385e97bad 100644 --- a/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java +++ b/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java @@ -173,7 +173,7 @@ public void onFailure(@NonNull Exception e) { } public void launchDropIn(View v) { - DropInRequest dropInRequest = new DropInRequest(); + DropInRequest dropInRequest = new DropInRequest(authString); dropInRequest.setGooglePayRequest(getGooglePayRequest()); dropInRequest.setVenmoRequest(new VenmoRequest(VenmoPaymentMethodUsage.SINGLE_USE)); dropInRequest.setMaskCardNumber(true); @@ -187,7 +187,7 @@ public void launchDropIn(View v) { dropInRequest.setThreeDSecureRequest(demoThreeDSecureRequest()); } - dropInLauncher.launchDropIn(authString, dropInRequest); + dropInLauncher.launchDropIn(dropInRequest); } private ThreeDSecureRequest demoThreeDSecureRequest() { diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java index b720f6335..76aec661f 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java @@ -1,6 +1,5 @@ package com.braintreepayments.api; -import static com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION; import static com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION_ERROR; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST_BUNDLE; @@ -78,9 +77,8 @@ protected void onCreate(Bundle savedInstanceState) { } if (dropInInternalClient == null) { - String authorization = intent.getStringExtra(EXTRA_AUTHORIZATION); DropInRequest dropInRequest = getDropInRequest(intent); - dropInInternalClient = new DropInInternalClient(this, authorization, dropInRequest); + dropInInternalClient = new DropInInternalClient(this, dropInRequest); } alertPresenter = new AlertPresenter(); diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java index 6bea3f21a..3d59873a0 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java @@ -1,6 +1,5 @@ package com.braintreepayments.api; -import static com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST_BUNDLE; import static com.braintreepayments.api.DropInResult.EXTRA_ERROR; @@ -14,16 +13,15 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -class DropInActivityResultContract extends ActivityResultContract { +class DropInActivityResultContract extends ActivityResultContract { @NonNull @Override - public Intent createIntent(@NonNull Context context, DropInLaunchInput input) { + public Intent createIntent(@NonNull Context context, DropInRequest dropInRequest) { Bundle dropInRequestBundle = new Bundle(); - dropInRequestBundle.putParcelable(EXTRA_CHECKOUT_REQUEST, input.getDropInRequest()); + dropInRequestBundle.putParcelable(EXTRA_CHECKOUT_REQUEST, dropInRequest); return new Intent(context, DropInActivity.class) - .putExtra(EXTRA_CHECKOUT_REQUEST_BUNDLE, dropInRequestBundle) - .putExtra(EXTRA_AUTHORIZATION, input.getAuthorization().toString()); + .putExtra(EXTRA_CHECKOUT_REQUEST_BUNDLE, dropInRequestBundle); } @Override diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInInternalClient.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInInternalClient.java index e63ea12aa..8e4a701ef 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInInternalClient.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInInternalClient.java @@ -37,9 +37,10 @@ class DropInInternalClient { private final PaymentMethodInspector paymentMethodInspector = new PaymentMethodInspector(); - private static DropInInternalClientParams createDefaultParams(Context context, String authorization, DropInRequest dropInRequest) { + private static DropInInternalClientParams createDefaultParams(Context context, DropInRequest dropInRequest) { String customUrlScheme = dropInRequest.getCustomUrlScheme(); + String authorization = dropInRequest.getAuthorization(); BraintreeOptions braintreeOptions = new BraintreeOptions(context, null, customUrlScheme, authorization, null, IntegrationType.DROP_IN); @@ -59,8 +60,8 @@ private static DropInInternalClientParams createDefaultParams(Context context, S .dropInSharedPreferences(DropInSharedPreferences.getInstance(context.getApplicationContext())); } - DropInInternalClient(FragmentActivity activity, String authorization, DropInRequest dropInRequest) { - this(createDefaultParams(activity, authorization, dropInRequest)); + DropInInternalClient(FragmentActivity activity, DropInRequest dropInRequest) { + this(createDefaultParams(activity, dropInRequest)); } @VisibleForTesting diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchInput.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchInput.java deleted file mode 100644 index 4d0fc5fee..000000000 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchInput.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.braintreepayments.api; - -class DropInLaunchInput { - - private final Authorization authorization; - private final DropInRequest dropInRequest; - - DropInLaunchInput(DropInRequest dropInRequest, Authorization authorization) { - this.dropInRequest = dropInRequest; - this.authorization = authorization; - } - - DropInRequest getDropInRequest() { - return dropInRequest; - } - - Authorization getAuthorization() { - return authorization; - } -} diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java index 9760d320d..038281e5f 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java @@ -12,12 +12,11 @@ public class DropInLauncher implements DefaultLifecycleObserver { static final String EXTRA_CHECKOUT_REQUEST = "com.braintreepayments.api.EXTRA_CHECKOUT_REQUEST"; static final String EXTRA_CHECKOUT_REQUEST_BUNDLE = "com.braintreepayments.api.EXTRA_CHECKOUT_REQUEST_BUNDLE"; - static final String EXTRA_AUTHORIZATION = "com.braintreepayments.api.EXTRA_AUTHORIZATION"; static final String EXTRA_AUTHORIZATION_ERROR = "com.braintreepayments.api.EXTRA_AUTHORIZATION_ERROR"; @VisibleForTesting - private ActivityResultLauncher activityLauncher; + private ActivityResultLauncher activityLauncher; public DropInLauncher(ComponentActivity activity, DropInLauncherCallback callback) { ActivityResultRegistry registry = activity.getActivityResultRegistry(); @@ -25,10 +24,7 @@ public DropInLauncher(ComponentActivity activity, DropInLauncherCallback callbac DROP_IN_RESULT, activity, new DropInActivityResultContract(), callback); } - public void launchDropIn(String authString, DropInRequest dropInRequest) { - Authorization authorization = Authorization.fromString(authString); - DropInLaunchInput launchIntent = - new DropInLaunchInput(dropInRequest, authorization); - activityLauncher.launch(launchIntent); + public void launchDropIn(DropInRequest dropInRequest) { + activityLauncher.launch(dropInRequest); } } diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInRequest.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInRequest.java index 93f7e0a62..ea275ac96 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInRequest.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInRequest.java @@ -3,6 +3,7 @@ import android.os.Parcel; import android.os.Parcelable; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.braintreepayments.cardform.view.CardForm; @@ -30,9 +31,13 @@ public class DropInRequest implements Parcelable { private String customUrlScheme = null; + private String authorization; + private int cardholderNameStatus = CardForm.FIELD_DISABLED; - public DropInRequest() {} + public DropInRequest(@NonNull String authorization) { + this.authorization = authorization; + } /** * This method is optional. @@ -303,6 +308,11 @@ public void setCustomUrlScheme(@Nullable String customUrlScheme) { this.customUrlScheme = customUrlScheme; } + @NonNull + public String getAuthorization() { + return authorization; + } + /** * @return If set, the custom return url scheme used for browser-based flows. */ @@ -334,6 +344,7 @@ public void writeToParcel(Parcel dest, int flags) { dest.writeByte(vaultCardDefaultValue ? (byte) 1 : (byte) 0); dest.writeByte(allowVaultCardOverride ? (byte) 1 : (byte) 0); dest.writeString(customUrlScheme); + dest.writeString(authorization); } protected DropInRequest(Parcel in) { @@ -353,6 +364,7 @@ protected DropInRequest(Parcel in) { vaultCardDefaultValue = in.readByte() != 0; allowVaultCardOverride = in.readByte() != 0; customUrlScheme = in.readString(); + authorization = in.readString(); } public static final Creator CREATOR = new Creator() { diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInInternalClientUnitTest.java b/Drop-In/src/test/java/com/braintreepayments/api/DropInInternalClientUnitTest.java index f7163efeb..96914b8f3 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInInternalClientUnitTest.java +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInInternalClientUnitTest.java @@ -63,14 +63,14 @@ public void beforeEach() { @Test public void constructor_setsIntegrationTypeDropIn() { DropInInternalClient sut = - new DropInInternalClient(activity, Fixtures.TOKENIZATION_KEY, new DropInRequest()); + new DropInInternalClient(activity, new DropInRequest()); assertEquals(IntegrationType.DROP_IN, sut.braintreeClient.getIntegrationType()); } @Test public void internalConstructor_usesDefaultBraintreeCustomUrlScheme() { DropInInternalClient sut = - new DropInInternalClient(activity, Fixtures.TOKENIZATION_KEY, new DropInRequest()); + new DropInInternalClient(activity, new DropInRequest()); assertEquals("com.braintreepayments.api.dropin.test.braintree", sut.braintreeClient.getReturnUrlScheme()); } @@ -79,7 +79,7 @@ public void internalConstructor_overridesBraintreeCustomUrlSchemeIfSet() { DropInRequest request = new DropInRequest(); request.setCustomUrlScheme("sample-custom-url-scheme"); DropInInternalClient sut = - new DropInInternalClient(activity, Fixtures.TOKENIZATION_KEY, request); + new DropInInternalClient(activity, request); assertEquals("sample-custom-url-scheme", sut.braintreeClient.getReturnUrlScheme()); } diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt index ea16ee5ab..b156770c3 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt @@ -55,7 +55,7 @@ class DropInLauncherUnitTest : TestCase() { val sut = DropInLauncher(activity, callback) val dropInRequest = DropInRequest() - sut.launchDropIn(Fixtures.BASE64_CLIENT_TOKEN, dropInRequest) + sut.launchDropIn(dropInRequest) val slot = slot() verify { activityLauncher.launch(capture(slot)) } From 7bdd2ac6975e3450a031379b537a8a96d847c6af Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 3 Apr 2024 11:53:29 -0500 Subject: [PATCH 17/20] Revert "Add place authorization string in DropInRequest." This reverts commit e0658c346193a2432422e61d78628807e799fd94. --- .../braintreepayments/demo/MainActivity.java | 4 ++-- .../braintreepayments/api/DropInActivity.java | 4 +++- .../api/DropInActivityResultContract.java | 10 ++++++---- .../api/DropInInternalClient.java | 7 +++---- .../api/DropInLaunchInput.java | 20 +++++++++++++++++++ .../braintreepayments/api/DropInLauncher.java | 10 +++++++--- .../braintreepayments/api/DropInRequest.java | 14 +------------ .../api/DropInInternalClientUnitTest.java | 6 +++--- .../api/DropInLauncherUnitTest.kt | 2 +- 9 files changed, 46 insertions(+), 31 deletions(-) create mode 100644 Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchInput.java diff --git a/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java b/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java index 385e97bad..f9c3e8cee 100644 --- a/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java +++ b/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java @@ -173,7 +173,7 @@ public void onFailure(@NonNull Exception e) { } public void launchDropIn(View v) { - DropInRequest dropInRequest = new DropInRequest(authString); + DropInRequest dropInRequest = new DropInRequest(); dropInRequest.setGooglePayRequest(getGooglePayRequest()); dropInRequest.setVenmoRequest(new VenmoRequest(VenmoPaymentMethodUsage.SINGLE_USE)); dropInRequest.setMaskCardNumber(true); @@ -187,7 +187,7 @@ public void launchDropIn(View v) { dropInRequest.setThreeDSecureRequest(demoThreeDSecureRequest()); } - dropInLauncher.launchDropIn(dropInRequest); + dropInLauncher.launchDropIn(authString, dropInRequest); } private ThreeDSecureRequest demoThreeDSecureRequest() { diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java index 76aec661f..b720f6335 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivity.java @@ -1,5 +1,6 @@ package com.braintreepayments.api; +import static com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION; import static com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION_ERROR; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST_BUNDLE; @@ -77,8 +78,9 @@ protected void onCreate(Bundle savedInstanceState) { } if (dropInInternalClient == null) { + String authorization = intent.getStringExtra(EXTRA_AUTHORIZATION); DropInRequest dropInRequest = getDropInRequest(intent); - dropInInternalClient = new DropInInternalClient(this, dropInRequest); + dropInInternalClient = new DropInInternalClient(this, authorization, dropInRequest); } alertPresenter = new AlertPresenter(); diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java index 3d59873a0..6bea3f21a 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInActivityResultContract.java @@ -1,5 +1,6 @@ package com.braintreepayments.api; +import static com.braintreepayments.api.DropInLauncher.EXTRA_AUTHORIZATION; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST; import static com.braintreepayments.api.DropInLauncher.EXTRA_CHECKOUT_REQUEST_BUNDLE; import static com.braintreepayments.api.DropInResult.EXTRA_ERROR; @@ -13,15 +14,16 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -class DropInActivityResultContract extends ActivityResultContract { +class DropInActivityResultContract extends ActivityResultContract { @NonNull @Override - public Intent createIntent(@NonNull Context context, DropInRequest dropInRequest) { + public Intent createIntent(@NonNull Context context, DropInLaunchInput input) { Bundle dropInRequestBundle = new Bundle(); - dropInRequestBundle.putParcelable(EXTRA_CHECKOUT_REQUEST, dropInRequest); + dropInRequestBundle.putParcelable(EXTRA_CHECKOUT_REQUEST, input.getDropInRequest()); return new Intent(context, DropInActivity.class) - .putExtra(EXTRA_CHECKOUT_REQUEST_BUNDLE, dropInRequestBundle); + .putExtra(EXTRA_CHECKOUT_REQUEST_BUNDLE, dropInRequestBundle) + .putExtra(EXTRA_AUTHORIZATION, input.getAuthorization().toString()); } @Override diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInInternalClient.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInInternalClient.java index 8e4a701ef..e63ea12aa 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInInternalClient.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInInternalClient.java @@ -37,10 +37,9 @@ class DropInInternalClient { private final PaymentMethodInspector paymentMethodInspector = new PaymentMethodInspector(); - private static DropInInternalClientParams createDefaultParams(Context context, DropInRequest dropInRequest) { + private static DropInInternalClientParams createDefaultParams(Context context, String authorization, DropInRequest dropInRequest) { String customUrlScheme = dropInRequest.getCustomUrlScheme(); - String authorization = dropInRequest.getAuthorization(); BraintreeOptions braintreeOptions = new BraintreeOptions(context, null, customUrlScheme, authorization, null, IntegrationType.DROP_IN); @@ -60,8 +59,8 @@ private static DropInInternalClientParams createDefaultParams(Context context, D .dropInSharedPreferences(DropInSharedPreferences.getInstance(context.getApplicationContext())); } - DropInInternalClient(FragmentActivity activity, DropInRequest dropInRequest) { - this(createDefaultParams(activity, dropInRequest)); + DropInInternalClient(FragmentActivity activity, String authorization, DropInRequest dropInRequest) { + this(createDefaultParams(activity, authorization, dropInRequest)); } @VisibleForTesting diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchInput.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchInput.java new file mode 100644 index 000000000..4d0fc5fee --- /dev/null +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLaunchInput.java @@ -0,0 +1,20 @@ +package com.braintreepayments.api; + +class DropInLaunchInput { + + private final Authorization authorization; + private final DropInRequest dropInRequest; + + DropInLaunchInput(DropInRequest dropInRequest, Authorization authorization) { + this.dropInRequest = dropInRequest; + this.authorization = authorization; + } + + DropInRequest getDropInRequest() { + return dropInRequest; + } + + Authorization getAuthorization() { + return authorization; + } +} diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java index 038281e5f..9760d320d 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java @@ -12,11 +12,12 @@ public class DropInLauncher implements DefaultLifecycleObserver { static final String EXTRA_CHECKOUT_REQUEST = "com.braintreepayments.api.EXTRA_CHECKOUT_REQUEST"; static final String EXTRA_CHECKOUT_REQUEST_BUNDLE = "com.braintreepayments.api.EXTRA_CHECKOUT_REQUEST_BUNDLE"; + static final String EXTRA_AUTHORIZATION = "com.braintreepayments.api.EXTRA_AUTHORIZATION"; static final String EXTRA_AUTHORIZATION_ERROR = "com.braintreepayments.api.EXTRA_AUTHORIZATION_ERROR"; @VisibleForTesting - private ActivityResultLauncher activityLauncher; + private ActivityResultLauncher activityLauncher; public DropInLauncher(ComponentActivity activity, DropInLauncherCallback callback) { ActivityResultRegistry registry = activity.getActivityResultRegistry(); @@ -24,7 +25,10 @@ public DropInLauncher(ComponentActivity activity, DropInLauncherCallback callbac DROP_IN_RESULT, activity, new DropInActivityResultContract(), callback); } - public void launchDropIn(DropInRequest dropInRequest) { - activityLauncher.launch(dropInRequest); + public void launchDropIn(String authString, DropInRequest dropInRequest) { + Authorization authorization = Authorization.fromString(authString); + DropInLaunchInput launchIntent = + new DropInLaunchInput(dropInRequest, authorization); + activityLauncher.launch(launchIntent); } } diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInRequest.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInRequest.java index ea275ac96..93f7e0a62 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInRequest.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInRequest.java @@ -3,7 +3,6 @@ import android.os.Parcel; import android.os.Parcelable; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.braintreepayments.cardform.view.CardForm; @@ -31,13 +30,9 @@ public class DropInRequest implements Parcelable { private String customUrlScheme = null; - private String authorization; - private int cardholderNameStatus = CardForm.FIELD_DISABLED; - public DropInRequest(@NonNull String authorization) { - this.authorization = authorization; - } + public DropInRequest() {} /** * This method is optional. @@ -308,11 +303,6 @@ public void setCustomUrlScheme(@Nullable String customUrlScheme) { this.customUrlScheme = customUrlScheme; } - @NonNull - public String getAuthorization() { - return authorization; - } - /** * @return If set, the custom return url scheme used for browser-based flows. */ @@ -344,7 +334,6 @@ public void writeToParcel(Parcel dest, int flags) { dest.writeByte(vaultCardDefaultValue ? (byte) 1 : (byte) 0); dest.writeByte(allowVaultCardOverride ? (byte) 1 : (byte) 0); dest.writeString(customUrlScheme); - dest.writeString(authorization); } protected DropInRequest(Parcel in) { @@ -364,7 +353,6 @@ protected DropInRequest(Parcel in) { vaultCardDefaultValue = in.readByte() != 0; allowVaultCardOverride = in.readByte() != 0; customUrlScheme = in.readString(); - authorization = in.readString(); } public static final Creator CREATOR = new Creator() { diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInInternalClientUnitTest.java b/Drop-In/src/test/java/com/braintreepayments/api/DropInInternalClientUnitTest.java index 96914b8f3..f7163efeb 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInInternalClientUnitTest.java +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInInternalClientUnitTest.java @@ -63,14 +63,14 @@ public void beforeEach() { @Test public void constructor_setsIntegrationTypeDropIn() { DropInInternalClient sut = - new DropInInternalClient(activity, new DropInRequest()); + new DropInInternalClient(activity, Fixtures.TOKENIZATION_KEY, new DropInRequest()); assertEquals(IntegrationType.DROP_IN, sut.braintreeClient.getIntegrationType()); } @Test public void internalConstructor_usesDefaultBraintreeCustomUrlScheme() { DropInInternalClient sut = - new DropInInternalClient(activity, new DropInRequest()); + new DropInInternalClient(activity, Fixtures.TOKENIZATION_KEY, new DropInRequest()); assertEquals("com.braintreepayments.api.dropin.test.braintree", sut.braintreeClient.getReturnUrlScheme()); } @@ -79,7 +79,7 @@ public void internalConstructor_overridesBraintreeCustomUrlSchemeIfSet() { DropInRequest request = new DropInRequest(); request.setCustomUrlScheme("sample-custom-url-scheme"); DropInInternalClient sut = - new DropInInternalClient(activity, request); + new DropInInternalClient(activity, Fixtures.TOKENIZATION_KEY, request); assertEquals("sample-custom-url-scheme", sut.braintreeClient.getReturnUrlScheme()); } diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt index b156770c3..ea16ee5ab 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt @@ -55,7 +55,7 @@ class DropInLauncherUnitTest : TestCase() { val sut = DropInLauncher(activity, callback) val dropInRequest = DropInRequest() - sut.launchDropIn(dropInRequest) + sut.launchDropIn(Fixtures.BASE64_CLIENT_TOKEN, dropInRequest) val slot = slot() verify { activityLauncher.launch(capture(slot)) } From 618d3f8dc2b2cbef38c46ab3a269a51fae982515 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 3 Apr 2024 11:58:18 -0500 Subject: [PATCH 18/20] Add TODO. --- Demo/src/main/java/com/braintreepayments/demo/MainActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java b/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java index f9c3e8cee..a03133d4a 100644 --- a/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java +++ b/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java @@ -187,6 +187,7 @@ public void launchDropIn(View v) { dropInRequest.setThreeDSecureRequest(demoThreeDSecureRequest()); } + // TODO: make auth string a required DropInRequest constructor parameter dropInLauncher.launchDropIn(authString, dropInRequest); } From 821b249ed1002156924bcfcde8f3b9deaa9e4539 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Wed, 3 Apr 2024 12:02:27 -0500 Subject: [PATCH 19/20] Update CHANGELOG. --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a369268fd..8eba1767a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Braintree Android Drop-In Release Notes +## unreleased + +* Breaking Changes + * Remove `DropInClient` and replace it with `DropInLauncher` + * Add `DropInLauncherCallback` to receive a result from `DropInActivity` via the Activity Result API + * Create `RecentPaymentMethodsClient` with `fetchMostRecentPaymentMethod()` + ## 6.15.0 * Refresh vaulted payment methods list after 3DS is canceled (fixes #455) From 1977a954f64d1475fce1a5153e9390ec83d6b976 Mon Sep 17 00:00:00 2001 From: sshropshire Date: Mon, 8 Apr 2024 09:53:56 -0500 Subject: [PATCH 20/20] Rename launchDropIn to start on DropInLauncher. --- Demo/src/main/java/com/braintreepayments/demo/MainActivity.java | 2 +- .../src/main/java/com/braintreepayments/api/DropInLauncher.java | 2 +- .../java/com/braintreepayments/api/DropInLauncherUnitTest.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java b/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java index a03133d4a..d65ae10ac 100644 --- a/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java +++ b/Demo/src/main/java/com/braintreepayments/demo/MainActivity.java @@ -188,7 +188,7 @@ public void launchDropIn(View v) { } // TODO: make auth string a required DropInRequest constructor parameter - dropInLauncher.launchDropIn(authString, dropInRequest); + dropInLauncher.start(authString, dropInRequest); } private ThreeDSecureRequest demoThreeDSecureRequest() { diff --git a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java index 9760d320d..b22de8365 100644 --- a/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java +++ b/Drop-In/src/main/java/com/braintreepayments/api/DropInLauncher.java @@ -25,7 +25,7 @@ public DropInLauncher(ComponentActivity activity, DropInLauncherCallback callbac DROP_IN_RESULT, activity, new DropInActivityResultContract(), callback); } - public void launchDropIn(String authString, DropInRequest dropInRequest) { + public void start(String authString, DropInRequest dropInRequest) { Authorization authorization = Authorization.fromString(authString); DropInLaunchInput launchIntent = new DropInLaunchInput(dropInRequest, authorization); diff --git a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt index ea16ee5ab..6539cbcb8 100644 --- a/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt +++ b/Drop-In/src/test/java/com/braintreepayments/api/DropInLauncherUnitTest.kt @@ -55,7 +55,7 @@ class DropInLauncherUnitTest : TestCase() { val sut = DropInLauncher(activity, callback) val dropInRequest = DropInRequest() - sut.launchDropIn(Fixtures.BASE64_CLIENT_TOKEN, dropInRequest) + sut.start(Fixtures.BASE64_CLIENT_TOKEN, dropInRequest) val slot = slot() verify { activityLauncher.launch(capture(slot)) }