From 9bb88ff7db4ec760da0f4c49930133a73e60191a Mon Sep 17 00:00:00 2001 From: toluo-stripe Date: Wed, 13 Nov 2024 13:56:01 -0500 Subject: [PATCH 1/2] LinkAccount payment methods list --- .../stripe/android/link/NoLinkAccountFound.kt | 3 -- .../link/NoLinkAccountFoundException.kt | 3 ++ .../link/account/DefaultLinkAccountManager.kt | 10 ++++++ .../link/account/LinkAccountManager.kt | 6 ++++ .../link/repositories/LinkApiRepository.kt | 16 +++++++++ .../link/repositories/LinkRepository.kt | 9 +++++ .../com/stripe/android/link/ui/LinkContent.kt | 4 +-- .../com/stripe/android/link/TestFactory.kt | 9 +++++ .../account/DefaultLinkAccountManagerTest.kt | 29 ++++++++++++++++ .../link/account/FakeLinkAccountManager.kt | 6 ++++ .../link/repositories/FakeLinkRepository.kt | 6 ++++ .../repositories/LinkApiRepositoryTest.kt | 25 ++++++++++++++ .../testing/AbsFakeStripeRepository.kt | 9 +++++ .../android/networking/StripeApiRepository.kt | 23 +++++++++++++ .../android/networking/StripeRepository.kt | 8 +++++ .../networking/StripeApiRepositoryTest.kt | 34 +++++++++++++++++++ 16 files changed, 195 insertions(+), 5 deletions(-) delete mode 100644 link/src/main/java/com/stripe/android/link/NoLinkAccountFound.kt create mode 100644 link/src/main/java/com/stripe/android/link/NoLinkAccountFoundException.kt diff --git a/link/src/main/java/com/stripe/android/link/NoLinkAccountFound.kt b/link/src/main/java/com/stripe/android/link/NoLinkAccountFound.kt deleted file mode 100644 index 91720bcac22..00000000000 --- a/link/src/main/java/com/stripe/android/link/NoLinkAccountFound.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.stripe.android.link - -internal class NoLinkAccountFound : IllegalStateException("No link account found") diff --git a/link/src/main/java/com/stripe/android/link/NoLinkAccountFoundException.kt b/link/src/main/java/com/stripe/android/link/NoLinkAccountFoundException.kt new file mode 100644 index 00000000000..68818690c9c --- /dev/null +++ b/link/src/main/java/com/stripe/android/link/NoLinkAccountFoundException.kt @@ -0,0 +1,3 @@ +package com.stripe.android.link + +internal class NoLinkAccountFoundException : IllegalStateException("No link account found") diff --git a/link/src/main/java/com/stripe/android/link/account/DefaultLinkAccountManager.kt b/link/src/main/java/com/stripe/android/link/account/DefaultLinkAccountManager.kt index f96ec5c6afa..998dc65712e 100644 --- a/link/src/main/java/com/stripe/android/link/account/DefaultLinkAccountManager.kt +++ b/link/src/main/java/com/stripe/android/link/account/DefaultLinkAccountManager.kt @@ -6,12 +6,14 @@ import com.stripe.android.core.exception.StripeException import com.stripe.android.link.BuildConfig import com.stripe.android.link.LinkConfiguration import com.stripe.android.link.LinkPaymentDetails +import com.stripe.android.link.NoLinkAccountFoundException import com.stripe.android.link.analytics.LinkEventsReporter import com.stripe.android.link.model.AccountStatus import com.stripe.android.link.model.LinkAccount import com.stripe.android.link.repositories.LinkRepository import com.stripe.android.link.ui.inline.SignUpConsentAction import com.stripe.android.link.ui.inline.UserInput +import com.stripe.android.model.ConsumerPaymentDetails import com.stripe.android.model.ConsumerSession import com.stripe.android.model.ConsumerSessionLookup import com.stripe.android.model.ConsumerSignUpConsentAction @@ -242,6 +244,14 @@ internal class DefaultLinkAccountManager @Inject constructor( } } + override suspend fun listPaymentDetails(): Result { + val clientSecret = linkAccount.value?.clientSecret ?: return Result.failure(NoLinkAccountFoundException()) + return linkRepository.listPaymentDetails( + consumerSessionClientSecret = clientSecret, + consumerPublishableKey = consumerPublishableKey + ) + } + @VisibleForTesting internal fun setAccountNullable( consumerSession: ConsumerSession?, diff --git a/link/src/main/java/com/stripe/android/link/account/LinkAccountManager.kt b/link/src/main/java/com/stripe/android/link/account/LinkAccountManager.kt index 3c8f2630d8d..678b5946bea 100644 --- a/link/src/main/java/com/stripe/android/link/account/LinkAccountManager.kt +++ b/link/src/main/java/com/stripe/android/link/account/LinkAccountManager.kt @@ -5,6 +5,7 @@ import com.stripe.android.link.model.AccountStatus import com.stripe.android.link.model.LinkAccount import com.stripe.android.link.ui.inline.SignUpConsentAction import com.stripe.android.link.ui.inline.UserInput +import com.stripe.android.model.ConsumerPaymentDetails import com.stripe.android.model.ConsumerSession import com.stripe.android.model.ConsumerSessionLookup import com.stripe.android.model.PaymentMethodCreateParams @@ -69,4 +70,9 @@ internal interface LinkAccountManager { * Confirms a verification code sent to the user. */ suspend fun confirmVerification(code: String): Result + + /** + * Fetch all saved payment methods for the signed in consumer. + */ + suspend fun listPaymentDetails(): Result } diff --git a/link/src/main/java/com/stripe/android/link/repositories/LinkApiRepository.kt b/link/src/main/java/com/stripe/android/link/repositories/LinkApiRepository.kt index b91d3e63d70..1fe7ea38aba 100644 --- a/link/src/main/java/com/stripe/android/link/repositories/LinkApiRepository.kt +++ b/link/src/main/java/com/stripe/android/link/repositories/LinkApiRepository.kt @@ -200,6 +200,22 @@ internal class LinkApiRepository @Inject constructor( } } + override suspend fun listPaymentDetails( + consumerSessionClientSecret: String, + consumerPublishableKey: String? + ): Result { + return stripeRepository.listPaymentDetails( + clientSecret = consumerSessionClientSecret, + paymentMethodTypes = emptySet(), + requestOptions = consumerPublishableKey?.let { + ApiRequest.Options(it) + } ?: ApiRequest.Options( + publishableKeyProvider(), + stripeAccountIdProvider() + ) + ) + } + private fun buildRequestOptions( consumerAccountPublishableKey: String? = null, ): ApiRequest.Options { diff --git a/link/src/main/java/com/stripe/android/link/repositories/LinkRepository.kt b/link/src/main/java/com/stripe/android/link/repositories/LinkRepository.kt index 26ff5841bcb..d706ff300b6 100644 --- a/link/src/main/java/com/stripe/android/link/repositories/LinkRepository.kt +++ b/link/src/main/java/com/stripe/android/link/repositories/LinkRepository.kt @@ -1,6 +1,7 @@ package com.stripe.android.link.repositories import com.stripe.android.link.LinkPaymentDetails +import com.stripe.android.model.ConsumerPaymentDetails import com.stripe.android.model.ConsumerSession import com.stripe.android.model.ConsumerSessionLookup import com.stripe.android.model.ConsumerSessionSignup @@ -71,4 +72,12 @@ internal interface LinkRepository { consumerSessionClientSecret: String, consumerPublishableKey: String?, ): Result + + /** + * Fetch all saved payment methods for the signed in consumer. + */ + suspend fun listPaymentDetails( + consumerSessionClientSecret: String, + consumerPublishableKey: String? + ): Result } diff --git a/link/src/main/java/com/stripe/android/link/ui/LinkContent.kt b/link/src/main/java/com/stripe/android/link/ui/LinkContent.kt index 40d932ee949..70aa7d81108 100644 --- a/link/src/main/java/com/stripe/android/link/ui/LinkContent.kt +++ b/link/src/main/java/com/stripe/android/link/ui/LinkContent.kt @@ -24,7 +24,7 @@ import com.stripe.android.link.LinkAction import com.stripe.android.link.LinkActivityResult import com.stripe.android.link.LinkActivityViewModel import com.stripe.android.link.LinkScreen -import com.stripe.android.link.NoLinkAccountFound +import com.stripe.android.link.NoLinkAccountFoundException import com.stripe.android.link.linkViewModel import com.stripe.android.link.model.LinkAccount import com.stripe.android.link.theme.DefaultLinkTheme @@ -142,7 +142,7 @@ private fun Screens( composable(LinkScreen.Verification.route) { val linkAccount = getLinkAccount() - ?: return@composable dismissWithResult(LinkActivityResult.Failed(NoLinkAccountFound())) + ?: return@composable dismissWithResult(LinkActivityResult.Failed(NoLinkAccountFoundException())) val viewModel: VerificationViewModel = linkViewModel { parentComponent -> VerificationViewModel.factory( parentComponent = parentComponent, diff --git a/link/src/test/java/com/stripe/android/link/TestFactory.kt b/link/src/test/java/com/stripe/android/link/TestFactory.kt index f8d1809480b..c65a9468b79 100644 --- a/link/src/test/java/com/stripe/android/link/TestFactory.kt +++ b/link/src/test/java/com/stripe/android/link/TestFactory.kt @@ -69,4 +69,13 @@ internal object TestFactory { ) val LINK_ACCOUNT = LinkAccount(CONSUMER_SESSION) + + val CONSUMER_PAYMENT_DETAILS: ConsumerPaymentDetails = ConsumerPaymentDetails( + paymentDetails = listOf( + ConsumerPaymentDetails.Card( + id = "pm_123", + last4 = "4242", + ) + ) + ) } diff --git a/link/src/test/java/com/stripe/android/link/account/DefaultLinkAccountManagerTest.kt b/link/src/test/java/com/stripe/android/link/account/DefaultLinkAccountManagerTest.kt index 965ee569ec8..652bf46ffc6 100644 --- a/link/src/test/java/com/stripe/android/link/account/DefaultLinkAccountManagerTest.kt +++ b/link/src/test/java/com/stripe/android/link/account/DefaultLinkAccountManagerTest.kt @@ -699,6 +699,35 @@ class DefaultLinkAccountManagerTest { assertThat(linkEventsReporter.callCount).isEqualTo(1) } + @Test + fun `listPaymentDetails returns error when repository call fails`() = runSuspendTest { + val error = AuthenticationException(StripeError()) + val linkRepository = FakeLinkRepository() + + val accountManager = accountManager(linkRepository = linkRepository) + accountManager.setAccountNullable(TestFactory.CONSUMER_SESSION, TestFactory.PUBLISHABLE_KEY) + + linkRepository.listPaymentDetailsResult = Result.failure(error) + + val result = accountManager.listPaymentDetails() + + assertThat(result.exceptionOrNull()).isEqualTo(error) + } + + @Test + fun `listPaymentDetails returns success when repository call succeeds`() = runSuspendTest { + val linkRepository = FakeLinkRepository() + + val accountManager = accountManager(linkRepository = linkRepository) + accountManager.setAccountNullable(TestFactory.CONSUMER_SESSION, TestFactory.PUBLISHABLE_KEY) + + linkRepository.listPaymentDetailsResult = Result.success(TestFactory.CONSUMER_PAYMENT_DETAILS) + + val result = accountManager.listPaymentDetails() + + assertThat(result.getOrNull()).isEqualTo(TestFactory.CONSUMER_PAYMENT_DETAILS) + } + private fun runSuspendTest(testBody: suspend TestScope.() -> Unit) = runTest { testBody() } diff --git a/link/src/test/java/com/stripe/android/link/account/FakeLinkAccountManager.kt b/link/src/test/java/com/stripe/android/link/account/FakeLinkAccountManager.kt index b054d13af7d..2c0da1231f9 100644 --- a/link/src/test/java/com/stripe/android/link/account/FakeLinkAccountManager.kt +++ b/link/src/test/java/com/stripe/android/link/account/FakeLinkAccountManager.kt @@ -1,6 +1,7 @@ package com.stripe.android.link.account import com.stripe.android.link.LinkPaymentDetails +import com.stripe.android.link.TestFactory import com.stripe.android.link.model.AccountStatus import com.stripe.android.link.model.LinkAccount import com.stripe.android.link.ui.inline.SignUpConsentAction @@ -36,6 +37,7 @@ internal open class FakeLinkAccountManager : LinkAccountManager { paymentMethodCreateParams = mock(), ) ) + var listPaymentDetailsResult: Result = Result.success(TestFactory.CONSUMER_PAYMENT_DETAILS) var linkAccountFromLookupResult: LinkAccount? = null override var consumerPublishableKey: String? = null @@ -86,4 +88,8 @@ internal open class FakeLinkAccountManager : LinkAccountManager { override suspend fun confirmVerification(code: String): Result { return confirmVerificationResult } + + override suspend fun listPaymentDetails(): Result { + return listPaymentDetailsResult + } } diff --git a/link/src/test/java/com/stripe/android/link/repositories/FakeLinkRepository.kt b/link/src/test/java/com/stripe/android/link/repositories/FakeLinkRepository.kt index 6cc1972813b..c2b0e84b3bb 100644 --- a/link/src/test/java/com/stripe/android/link/repositories/FakeLinkRepository.kt +++ b/link/src/test/java/com/stripe/android/link/repositories/FakeLinkRepository.kt @@ -13,6 +13,7 @@ open class FakeLinkRepository : LinkRepository { var logOutResult = Result.success(TestFactory.CONSUMER_SESSION) var startVerificationResult = Result.success(TestFactory.CONSUMER_SESSION) var confirmVerificationResult = Result.success(TestFactory.CONSUMER_SESSION) + var listPaymentDetailsResult = Result.success(TestFactory.CONSUMER_PAYMENT_DETAILS) override suspend fun lookupConsumer(email: String) = lookupConsumerResult @@ -55,4 +56,9 @@ open class FakeLinkRepository : LinkRepository { consumerSessionClientSecret: String, consumerPublishableKey: String? ) = confirmVerificationResult + + override suspend fun listPaymentDetails( + consumerSessionClientSecret: String, + consumerPublishableKey: String? + ) = listPaymentDetailsResult } diff --git a/link/src/test/java/com/stripe/android/link/repositories/LinkApiRepositoryTest.kt b/link/src/test/java/com/stripe/android/link/repositories/LinkApiRepositoryTest.kt index fea9b6c26ce..7b083c6d27a 100644 --- a/link/src/test/java/com/stripe/android/link/repositories/LinkApiRepositoryTest.kt +++ b/link/src/test/java/com/stripe/android/link/repositories/LinkApiRepositoryTest.kt @@ -494,6 +494,31 @@ class LinkApiRepositoryTest { assertThat(result.isFailure).isTrue() } + @Test + fun `listPaymentDetails sends correct parameters`() = runTest { + val secret = "secret" + val consumerKey = "key" + linkRepository.listPaymentDetails(secret, consumerKey) + + verify(stripeRepository).listPaymentDetails( + eq(secret), + eq(emptySet()), + eq(ApiRequest.Options(consumerKey)) + ) + } + + @Test + fun `listPaymentDetails without consumerPublishableKey sends correct parameters`() = runTest { + val secret = "secret" + linkRepository.listPaymentDetails(secret, null) + + verify(stripeRepository).listPaymentDetails( + eq(secret), + eq(emptySet()), + eq(ApiRequest.Options(PUBLISHABLE_KEY, STRIPE_ACCOUNT_ID)) + ) + } + private val cardPaymentMethodCreateParams = FieldValuesToParamsMapConverter.transformToPaymentMethodCreateParams( mapOf( diff --git a/payments-core-testing/src/main/java/com/stripe/android/testing/AbsFakeStripeRepository.kt b/payments-core-testing/src/main/java/com/stripe/android/testing/AbsFakeStripeRepository.kt index 8a7af4786cf..5fd60062996 100644 --- a/payments-core-testing/src/main/java/com/stripe/android/testing/AbsFakeStripeRepository.kt +++ b/payments-core-testing/src/main/java/com/stripe/android/testing/AbsFakeStripeRepository.kt @@ -9,6 +9,7 @@ import com.stripe.android.model.BankStatuses import com.stripe.android.model.CardMetadata import com.stripe.android.model.ConfirmPaymentIntentParams import com.stripe.android.model.ConfirmSetupIntentParams +import com.stripe.android.model.ConsumerPaymentDetails import com.stripe.android.model.ConsumerSession import com.stripe.android.model.CreateFinancialConnectionsSessionForDeferredPaymentParams import com.stripe.android.model.CreateFinancialConnectionsSessionParams @@ -421,4 +422,12 @@ abstract class AbsFakeStripeRepository : StripeRepository { override fun buildPaymentUserAgent(attribution: Set): String { TODO("Not yet implemented") } + + override suspend fun listPaymentDetails( + clientSecret: String, + paymentMethodTypes: Set, + requestOptions: ApiRequest.Options + ): Result { + TODO("Not yet implemented") + } } diff --git a/payments-core/src/main/java/com/stripe/android/networking/StripeApiRepository.kt b/payments-core/src/main/java/com/stripe/android/networking/StripeApiRepository.kt index 38afab12282..f0407f01fce 100644 --- a/payments-core/src/main/java/com/stripe/android/networking/StripeApiRepository.kt +++ b/payments-core/src/main/java/com/stripe/android/networking/StripeApiRepository.kt @@ -52,6 +52,7 @@ import com.stripe.android.model.ConfirmPaymentIntentParams import com.stripe.android.model.ConfirmSetupIntentParams import com.stripe.android.model.ConfirmStripeIntentParams import com.stripe.android.model.ConfirmStripeIntentParams.Companion.PARAM_CLIENT_SECRET +import com.stripe.android.model.ConsumerPaymentDetails import com.stripe.android.model.ConsumerSession import com.stripe.android.model.CreateFinancialConnectionsSessionForDeferredPaymentParams import com.stripe.android.model.CreateFinancialConnectionsSessionParams @@ -77,6 +78,7 @@ import com.stripe.android.model.StripeIntent import com.stripe.android.model.Token import com.stripe.android.model.TokenParams import com.stripe.android.model.parsers.CardMetadataJsonParser +import com.stripe.android.model.parsers.ConsumerPaymentDetailsJsonParser import com.stripe.android.model.parsers.ConsumerPaymentDetailsShareJsonParser import com.stripe.android.model.parsers.ConsumerSessionJsonParser import com.stripe.android.model.parsers.CustomerJsonParser @@ -1435,6 +1437,27 @@ class StripeApiRepository @JvmOverloads internal constructor( ) } + override suspend fun listPaymentDetails( + clientSecret: String, + paymentMethodTypes: Set, + requestOptions: ApiRequest.Options + ): Result { + return fetchStripeModelResult( + apiRequestFactory.createPost( + listConsumerPaymentDetailsUrl, + requestOptions, + mapOf( + "request_surface" to "android_payment_element", + "credentials" to mapOf( + "consumer_session_client_secret" to clientSecret + ), + "types" to paymentMethodTypes.toList() + ) + ), + ConsumerPaymentDetailsJsonParser + ) + } + private suspend fun retrieveElementsSession( params: ElementsSessionParams, options: ApiRequest.Options, diff --git a/payments-core/src/main/java/com/stripe/android/networking/StripeRepository.kt b/payments-core/src/main/java/com/stripe/android/networking/StripeRepository.kt index 1fc4f741ffc..2d74b2fdae6 100644 --- a/payments-core/src/main/java/com/stripe/android/networking/StripeRepository.kt +++ b/payments-core/src/main/java/com/stripe/android/networking/StripeRepository.kt @@ -10,6 +10,7 @@ import com.stripe.android.model.BankStatuses import com.stripe.android.model.CardMetadata import com.stripe.android.model.ConfirmPaymentIntentParams import com.stripe.android.model.ConfirmSetupIntentParams +import com.stripe.android.model.ConsumerPaymentDetails import com.stripe.android.model.ConsumerSession import com.stripe.android.model.CreateFinancialConnectionsSessionForDeferredPaymentParams import com.stripe.android.model.CreateFinancialConnectionsSessionParams @@ -380,6 +381,13 @@ interface StripeRepository { params: Map? = null ): Result + @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) + suspend fun listPaymentDetails( + clientSecret: String, + paymentMethodTypes: Set, + requestOptions: ApiRequest.Options + ): Result + @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) fun buildPaymentUserAgent(attribution: Set = emptySet()): String } diff --git a/payments-core/src/test/java/com/stripe/android/networking/StripeApiRepositoryTest.kt b/payments-core/src/test/java/com/stripe/android/networking/StripeApiRepositoryTest.kt index a5fad7a9202..efdbe425bfd 100644 --- a/payments-core/src/test/java/com/stripe/android/networking/StripeApiRepositoryTest.kt +++ b/payments-core/src/test/java/com/stripe/android/networking/StripeApiRepositoryTest.kt @@ -2717,6 +2717,40 @@ internal class StripeApiRepositoryTest { } } + @Test + fun `listPaymentDetails() sends all parameters`() = + runTest { + val stripeResponse = StripeResponse( + 200, + ConsumerFixtures.CONSUMER_PAYMENT_DETAILS_JSON.toString(), + emptyMap() + ) + whenever(stripeNetworkClient.executeRequest(any())) + .thenReturn(stripeResponse) + + val clientSecret = "secret" + val paymentMethodTypes = setOf("type1") + create().listPaymentDetails( + clientSecret, + paymentMethodTypes, + DEFAULT_OPTIONS + ) + + verify(stripeNetworkClient).executeRequest(apiRequestArgumentCaptor.capture()) + val request = apiRequestArgumentCaptor.firstValue + val params = requireNotNull(request.params) + + assertThat( + "https://api.stripe.com/v1/consumers/payment_details/list", + ).isEqualTo(request.baseUrl) + assertThat(request.method).isEqualTo(StripeRequest.Method.POST) + + assertThat(params["request_surface"]).isEqualTo("android_payment_element") + val credentials = params["credentials"] as Map<*, *> + assertThat(credentials["consumer_session_client_secret"]).isEqualTo(clientSecret) + assertThat(params["types"] as? List<*>).containsExactlyElementsIn(paymentMethodTypes.toList()) + } + /** * Helper DSL to validate nested params. */ From 14de1f05862045eff5842ad422e7c9660069141e Mon Sep 17 00:00:00 2001 From: toluo-stripe Date: Wed, 13 Nov 2024 16:20:55 -0500 Subject: [PATCH 2/2] Add paymentMethod types param --- .../link/account/DefaultLinkAccountManager.kt | 3 +- .../link/account/LinkAccountManager.kt | 2 +- .../link/repositories/LinkApiRepository.kt | 3 +- .../link/repositories/LinkRepository.kt | 1 + .../account/DefaultLinkAccountManagerTest.kt | 35 ++++++++++++++----- .../link/account/FakeLinkAccountManager.kt | 2 +- .../link/repositories/FakeLinkRepository.kt | 4 ++- .../repositories/LinkApiRepositoryTest.kt | 8 ++--- 8 files changed, 41 insertions(+), 17 deletions(-) diff --git a/link/src/main/java/com/stripe/android/link/account/DefaultLinkAccountManager.kt b/link/src/main/java/com/stripe/android/link/account/DefaultLinkAccountManager.kt index 998dc65712e..69193116e37 100644 --- a/link/src/main/java/com/stripe/android/link/account/DefaultLinkAccountManager.kt +++ b/link/src/main/java/com/stripe/android/link/account/DefaultLinkAccountManager.kt @@ -244,9 +244,10 @@ internal class DefaultLinkAccountManager @Inject constructor( } } - override suspend fun listPaymentDetails(): Result { + override suspend fun listPaymentDetails(paymentMethodTypes: Set): Result { val clientSecret = linkAccount.value?.clientSecret ?: return Result.failure(NoLinkAccountFoundException()) return linkRepository.listPaymentDetails( + paymentMethodTypes = paymentMethodTypes, consumerSessionClientSecret = clientSecret, consumerPublishableKey = consumerPublishableKey ) diff --git a/link/src/main/java/com/stripe/android/link/account/LinkAccountManager.kt b/link/src/main/java/com/stripe/android/link/account/LinkAccountManager.kt index 678b5946bea..349e6b37970 100644 --- a/link/src/main/java/com/stripe/android/link/account/LinkAccountManager.kt +++ b/link/src/main/java/com/stripe/android/link/account/LinkAccountManager.kt @@ -74,5 +74,5 @@ internal interface LinkAccountManager { /** * Fetch all saved payment methods for the signed in consumer. */ - suspend fun listPaymentDetails(): Result + suspend fun listPaymentDetails(paymentMethodTypes: Set): Result } diff --git a/link/src/main/java/com/stripe/android/link/repositories/LinkApiRepository.kt b/link/src/main/java/com/stripe/android/link/repositories/LinkApiRepository.kt index 1fe7ea38aba..57f6d4dfb8c 100644 --- a/link/src/main/java/com/stripe/android/link/repositories/LinkApiRepository.kt +++ b/link/src/main/java/com/stripe/android/link/repositories/LinkApiRepository.kt @@ -201,12 +201,13 @@ internal class LinkApiRepository @Inject constructor( } override suspend fun listPaymentDetails( + paymentMethodTypes: Set, consumerSessionClientSecret: String, consumerPublishableKey: String? ): Result { return stripeRepository.listPaymentDetails( clientSecret = consumerSessionClientSecret, - paymentMethodTypes = emptySet(), + paymentMethodTypes = paymentMethodTypes, requestOptions = consumerPublishableKey?.let { ApiRequest.Options(it) } ?: ApiRequest.Options( diff --git a/link/src/main/java/com/stripe/android/link/repositories/LinkRepository.kt b/link/src/main/java/com/stripe/android/link/repositories/LinkRepository.kt index d706ff300b6..023f7ef94e1 100644 --- a/link/src/main/java/com/stripe/android/link/repositories/LinkRepository.kt +++ b/link/src/main/java/com/stripe/android/link/repositories/LinkRepository.kt @@ -77,6 +77,7 @@ internal interface LinkRepository { * Fetch all saved payment methods for the signed in consumer. */ suspend fun listPaymentDetails( + paymentMethodTypes: Set, consumerSessionClientSecret: String, consumerPublishableKey: String? ): Result diff --git a/link/src/test/java/com/stripe/android/link/account/DefaultLinkAccountManagerTest.kt b/link/src/test/java/com/stripe/android/link/account/DefaultLinkAccountManagerTest.kt index 652bf46ffc6..b14943c5d7e 100644 --- a/link/src/test/java/com/stripe/android/link/account/DefaultLinkAccountManagerTest.kt +++ b/link/src/test/java/com/stripe/android/link/account/DefaultLinkAccountManagerTest.kt @@ -14,6 +14,7 @@ import com.stripe.android.link.repositories.FakeLinkRepository import com.stripe.android.link.repositories.LinkRepository import com.stripe.android.link.ui.inline.SignUpConsentAction import com.stripe.android.link.ui.inline.UserInput +import com.stripe.android.model.ConsumerPaymentDetails import com.stripe.android.model.ConsumerSession import com.stripe.android.model.ConsumerSessionLookup import com.stripe.android.model.ConsumerSessionSignup @@ -702,30 +703,48 @@ class DefaultLinkAccountManagerTest { @Test fun `listPaymentDetails returns error when repository call fails`() = runSuspendTest { val error = AuthenticationException(StripeError()) - val linkRepository = FakeLinkRepository() + val linkRepository = object : FakeLinkRepository() { + var paymentMethodTypes: Set? = null + override suspend fun listPaymentDetails( + paymentMethodTypes: Set, + consumerSessionClientSecret: String, + consumerPublishableKey: String? + ): Result { + this.paymentMethodTypes = paymentMethodTypes + return Result.failure(error) + } + } val accountManager = accountManager(linkRepository = linkRepository) accountManager.setAccountNullable(TestFactory.CONSUMER_SESSION, TestFactory.PUBLISHABLE_KEY) - linkRepository.listPaymentDetailsResult = Result.failure(error) - - val result = accountManager.listPaymentDetails() + val result = accountManager.listPaymentDetails(setOf("card")) assertThat(result.exceptionOrNull()).isEqualTo(error) + assertThat(linkRepository.paymentMethodTypes).isEqualTo(setOf("card")) } @Test fun `listPaymentDetails returns success when repository call succeeds`() = runSuspendTest { - val linkRepository = FakeLinkRepository() + val linkRepository = object : FakeLinkRepository() { + var paymentMethodTypes: Set? = null + override suspend fun listPaymentDetails( + paymentMethodTypes: Set, + consumerSessionClientSecret: String, + consumerPublishableKey: String? + ): Result { + this.paymentMethodTypes = paymentMethodTypes + return Result.success(TestFactory.CONSUMER_PAYMENT_DETAILS) + } + } val accountManager = accountManager(linkRepository = linkRepository) accountManager.setAccountNullable(TestFactory.CONSUMER_SESSION, TestFactory.PUBLISHABLE_KEY) - linkRepository.listPaymentDetailsResult = Result.success(TestFactory.CONSUMER_PAYMENT_DETAILS) - - val result = accountManager.listPaymentDetails() + val result = accountManager.listPaymentDetails(setOf("card")) assertThat(result.getOrNull()).isEqualTo(TestFactory.CONSUMER_PAYMENT_DETAILS) + assertThat(linkRepository.paymentMethodTypes).isEqualTo(setOf("card")) } private fun runSuspendTest(testBody: suspend TestScope.() -> Unit) = runTest { diff --git a/link/src/test/java/com/stripe/android/link/account/FakeLinkAccountManager.kt b/link/src/test/java/com/stripe/android/link/account/FakeLinkAccountManager.kt index 2c0da1231f9..d3ce7b79960 100644 --- a/link/src/test/java/com/stripe/android/link/account/FakeLinkAccountManager.kt +++ b/link/src/test/java/com/stripe/android/link/account/FakeLinkAccountManager.kt @@ -89,7 +89,7 @@ internal open class FakeLinkAccountManager : LinkAccountManager { return confirmVerificationResult } - override suspend fun listPaymentDetails(): Result { + override suspend fun listPaymentDetails(paymentMethodTypes: Set): Result { return listPaymentDetailsResult } } diff --git a/link/src/test/java/com/stripe/android/link/repositories/FakeLinkRepository.kt b/link/src/test/java/com/stripe/android/link/repositories/FakeLinkRepository.kt index c2b0e84b3bb..067c4dc600f 100644 --- a/link/src/test/java/com/stripe/android/link/repositories/FakeLinkRepository.kt +++ b/link/src/test/java/com/stripe/android/link/repositories/FakeLinkRepository.kt @@ -1,6 +1,7 @@ package com.stripe.android.link.repositories import com.stripe.android.link.TestFactory +import com.stripe.android.model.ConsumerPaymentDetails import com.stripe.android.model.ConsumerSignUpConsentAction import com.stripe.android.model.PaymentMethodCreateParams import com.stripe.android.model.StripeIntent @@ -58,7 +59,8 @@ open class FakeLinkRepository : LinkRepository { ) = confirmVerificationResult override suspend fun listPaymentDetails( + paymentMethodTypes: Set, consumerSessionClientSecret: String, consumerPublishableKey: String? - ) = listPaymentDetailsResult + ): Result = listPaymentDetailsResult } diff --git a/link/src/test/java/com/stripe/android/link/repositories/LinkApiRepositoryTest.kt b/link/src/test/java/com/stripe/android/link/repositories/LinkApiRepositoryTest.kt index 7b083c6d27a..ebd242101d6 100644 --- a/link/src/test/java/com/stripe/android/link/repositories/LinkApiRepositoryTest.kt +++ b/link/src/test/java/com/stripe/android/link/repositories/LinkApiRepositoryTest.kt @@ -498,11 +498,11 @@ class LinkApiRepositoryTest { fun `listPaymentDetails sends correct parameters`() = runTest { val secret = "secret" val consumerKey = "key" - linkRepository.listPaymentDetails(secret, consumerKey) + linkRepository.listPaymentDetails(setOf("card"), secret, consumerKey) verify(stripeRepository).listPaymentDetails( eq(secret), - eq(emptySet()), + eq(setOf("card")), eq(ApiRequest.Options(consumerKey)) ) } @@ -510,11 +510,11 @@ class LinkApiRepositoryTest { @Test fun `listPaymentDetails without consumerPublishableKey sends correct parameters`() = runTest { val secret = "secret" - linkRepository.listPaymentDetails(secret, null) + linkRepository.listPaymentDetails(setOf("card"), secret, null) verify(stripeRepository).listPaymentDetails( eq(secret), - eq(emptySet()), + eq(setOf("card")), eq(ApiRequest.Options(PUBLISHABLE_KEY, STRIPE_ACCOUNT_ID)) ) }