Skip to content

Commit

Permalink
Update unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
toluo-stripe committed Nov 5, 2024
1 parent 07f5c36 commit aa134ed
Show file tree
Hide file tree
Showing 10 changed files with 415 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import javax.inject.Inject
/**
* Manages the Link account for the current user, persisting it across app usages.
*/
@SuppressWarnings("TooManyFunctions")
internal class DefaultLinkAccountManager @Inject constructor(
private val config: LinkConfiguration,
private val linkRepository: LinkRepository,
Expand Down Expand Up @@ -239,7 +240,9 @@ internal class DefaultLinkAccountManager @Inject constructor(
}
}

override suspend fun updatePaymentDetails(updateParams: ConsumerPaymentDetailsUpdateParams): Result<ConsumerPaymentDetails> {
override suspend fun updatePaymentDetails(
updateParams: ConsumerPaymentDetailsUpdateParams
): Result<ConsumerPaymentDetails> {
val clientSecret = linkAccount.value?.clientSecret ?: return Result.failure(Throwable("no link account found"))
return linkRepository.updatePaymentDetails(
updateParams = updateParams,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.stripe.android.model.PaymentMethodCreateParams
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow

@SuppressWarnings("TooManyFunctions")
internal interface LinkAccountManager {
val linkAccount: StateFlow<LinkAccount?>
val accountStatus: Flow<AccountStatus>
Expand Down Expand Up @@ -75,7 +76,7 @@ internal interface LinkAccountManager {
/**
* Update an existing payment method in the signed in consumer account.
*/
suspend fun updatePaymentDetails(updateParams: ConsumerPaymentDetailsUpdateParams): Result<ConsumerPaymentDetails>
suspend fun updatePaymentDetails(updateParams: ConsumerPaymentDetailsUpdateParams): Result<ConsumerPaymentDetails>

/**
* Delete the payment method from the signed in consumer account.
Expand Down
9 changes: 9 additions & 0 deletions link/src/test/java/com/stripe/android/link/TestFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,13 @@ object TestFactory {
paymentMethodCreateParams = PAYMENT_METHOD_CREATE_PARAMS,
originalParams = mock()
)

val CONSUMER_PAYMENT_DETAILS: ConsumerPaymentDetails = ConsumerPaymentDetails(
paymentDetails = listOf(
ConsumerPaymentDetails.Card(
id = "pm_123",
last4 = "4242",
)
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.mockito.Mockito.times
import org.mockito.kotlin.any

class DefaultLinkAccountManagerTest {

Expand Down Expand Up @@ -676,6 +678,93 @@ class DefaultLinkAccountManagerTest {
assertThat(result).isEqualTo(Result.failure<LinkAccount>(error))
}

@Test
fun `deletePaymentDetails 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.deletePaymentDetailsResult = Result.failure(error)

val result = accountManager.deletePaymentDetails("id")

assertThat(result.exceptionOrNull()).isEqualTo(error)
}

@Test
fun `deletePaymentDetails returns success when repository call succeeds`() = runSuspendTest {
val linkRepository = FakeLinkRepository()

val accountManager = accountManager(linkRepository = linkRepository)
accountManager.setAccountNullable(TestFactory.CONSUMER_SESSION, TestFactory.PUBLISHABLE_KEY)

linkRepository.deletePaymentDetailsResult = Result.success(Unit)

val result = accountManager.deletePaymentDetails("id")

assertThat(result.getOrNull()).isEqualTo(Unit)
}

@Test
fun `updatePaymentDetails 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.updatePaymentDetailsResult = Result.failure(error)

val result = accountManager.updatePaymentDetails(any())

assertThat(result.exceptionOrNull()).isEqualTo(error)
}

@Test
fun `updatePaymentDetails returns success when repository call succeeds`() = runSuspendTest {
val linkRepository = FakeLinkRepository()

val accountManager = accountManager(linkRepository = linkRepository)
accountManager.setAccountNullable(TestFactory.CONSUMER_SESSION, TestFactory.PUBLISHABLE_KEY)

linkRepository.updatePaymentDetailsResult = Result.success(TestFactory.CONSUMER_PAYMENT_DETAILS)

val result = accountManager.updatePaymentDetails(any())

assertThat(result.getOrNull()).isEqualTo(TestFactory.CONSUMER_PAYMENT_DETAILS)
}

@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()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
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
import com.stripe.android.link.ui.inline.UserInput
import com.stripe.android.model.ConsumerPaymentDetails
import com.stripe.android.model.ConsumerPaymentDetailsUpdateParams
import com.stripe.android.model.ConsumerSession
import com.stripe.android.model.ConsumerSessionLookup
import com.stripe.android.model.PaymentMethodCreateParams
Expand Down Expand Up @@ -37,6 +39,11 @@ internal open class FakeLinkAccountManager : LinkAccountManager {
)
)
var linkAccountFromLookupResult: LinkAccount? = null
var updatePaymentDetailsResult: Result<ConsumerPaymentDetails> =
Result.success(TestFactory.CONSUMER_PAYMENT_DETAILS)
var deletePaymentDetailsResult: Result<Unit> = Result.success(Unit)
var listPaymentDetailsResult: Result<ConsumerPaymentDetails> = Result.success(TestFactory.CONSUMER_PAYMENT_DETAILS)

override var consumerPublishableKey: String? = null

fun setLinkAccount(account: LinkAccount?) {
Expand Down Expand Up @@ -86,4 +93,12 @@ internal open class FakeLinkAccountManager : LinkAccountManager {
override suspend fun confirmVerification(code: String): Result<LinkAccount> {
return confirmVerification
}

override suspend fun updatePaymentDetails(
updateParams: ConsumerPaymentDetailsUpdateParams
) = updatePaymentDetailsResult

override suspend fun deletePaymentDetails(paymentDetailsId: String) = deletePaymentDetailsResult

override suspend fun listPaymentDetails() = listPaymentDetailsResult
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.stripe.android.link.repositories

import com.stripe.android.link.TestFactory
import com.stripe.android.model.ConsumerPaymentDetailsUpdateParams
import com.stripe.android.model.ConsumerSignUpConsentAction
import com.stripe.android.model.PaymentMethodCreateParams
import com.stripe.android.model.StripeIntent
Expand All @@ -13,6 +14,9 @@ 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)
var deletePaymentDetailsResult = Result.success(Unit)
var updatePaymentDetailsResult = Result.success(TestFactory.CONSUMER_PAYMENT_DETAILS)

override suspend fun lookupConsumer(email: String) = lookupConsumerResult

Expand Down Expand Up @@ -55,4 +59,21 @@ open class FakeLinkRepository : LinkRepository {
consumerSessionClientSecret: String,
consumerPublishableKey: String?
) = confirmVerificationResult

override suspend fun listPaymentDetails(
consumerSessionClientSecret: String,
consumerPublishableKey: String?
) = listPaymentDetailsResult

override suspend fun deletePaymentDetails(
paymentDetailsId: String,
consumerSessionClientSecret: String,
consumerPublishableKey: String?
) = deletePaymentDetailsResult

override suspend fun updatePaymentDetails(
updateParams: ConsumerPaymentDetailsUpdateParams,
consumerSessionClientSecret: String,
consumerPublishableKey: String?
) = updatePaymentDetailsResult
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package com.stripe.android.link.repositories
import com.google.common.truth.Truth.assertThat
import com.stripe.android.core.networking.ApiRequest
import com.stripe.android.link.LinkPaymentDetails
import com.stripe.android.link.TestFactory
import com.stripe.android.link.model.PaymentDetailsFixtures
import com.stripe.android.model.ConsumerPaymentDetails
import com.stripe.android.model.ConsumerPaymentDetailsCreateParams
import com.stripe.android.model.ConsumerPaymentDetailsUpdateParams
import com.stripe.android.model.ConsumerSession
import com.stripe.android.model.ConsumerSessionLookup
import com.stripe.android.model.ConsumerSessionSignup
Expand Down Expand Up @@ -494,6 +496,139 @@ class LinkApiRepositoryTest {
assertThat(result.isFailure).isTrue()
}

@Test
fun `deletePaymentDetails without consumerPublishableKey sends correct parameters`() = runTest {
val secret = "secret"
val id = "payment_details_id"
linkRepository.deletePaymentDetails(id, secret, null)

verify(stripeRepository).deletePaymentDetails(
eq(secret),
eq(id),
eq(ApiRequest.Options(PUBLISHABLE_KEY, STRIPE_ACCOUNT_ID))
)
}

@Test
fun `deletePaymentDetails returns successful result`() = runTest {
whenever(stripeRepository.deletePaymentDetails(any(), any(), any())).thenReturn(Result.success(Unit))

val result = linkRepository.deletePaymentDetails("id", "secret", "key")

assertThat(result.isSuccess).isTrue()
}

@Test
fun `deletePaymentDetails catches exception and returns failure`() = runTest {
whenever(stripeRepository.deletePaymentDetails(any(), any(), any()))
.thenThrow(RuntimeException("error"))

val result = linkRepository.deletePaymentDetails("id", "secret", "key")

assertThat(result.isFailure).isTrue()
}

@Test
fun `updatePaymentDetails sends correct parameters`() = runTest {
val secret = "secret"
val params = ConsumerPaymentDetailsUpdateParams("id")
val consumerKey = "key"

linkRepository.updatePaymentDetails(
params,
secret,
consumerKey
)

verify(stripeRepository).updatePaymentDetails(
eq(secret),
eq(params),
eq(ApiRequest.Options(consumerKey))
)
}

@Test
fun `updatePaymentDetails without consumerPublishableKey sends correct parameters`() = runTest {
val secret = "secret"
val params = ConsumerPaymentDetailsUpdateParams("id")

linkRepository.updatePaymentDetails(
params,
secret,
null
)

verify(stripeRepository).updatePaymentDetails(
eq(secret),
eq(params),
eq(ApiRequest.Options(PUBLISHABLE_KEY, STRIPE_ACCOUNT_ID))
)
}

@Test
fun `updatePaymentDetails returns successful result`() = runTest {
whenever(stripeRepository.updatePaymentDetails(any(), any(), any()))
.thenReturn(Result.success(TestFactory.CONSUMER_PAYMENT_DETAILS))

val result = linkRepository.updatePaymentDetails(
ConsumerPaymentDetailsUpdateParams("id"),
"secret",
"key"
)

assertThat(result.getOrNull()).isEqualTo(TestFactory.CONSUMER_PAYMENT_DETAILS)
}

@Test
fun `updatePaymentDetails catches exception and returns failure`() = runTest {
val error = RuntimeException("error")
whenever(stripeRepository.updatePaymentDetails(any(), any(), any()))
.thenReturn(Result.failure(error))

val result = linkRepository.updatePaymentDetails(
ConsumerPaymentDetailsUpdateParams("id"),
"secret",
"key"
)

assertThat(result.exceptionOrNull()).isEqualTo(error)
}

@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))
)
}

@Test
fun `listPaymentDetails returns successful result`() = runTest {
whenever(stripeRepository.listPaymentDetails(any(), any(), any()))
.thenReturn(Result.success(TestFactory.CONSUMER_PAYMENT_DETAILS))

val result = linkRepository.listPaymentDetails("secret", "key")

assertThat(result.getOrNull()).isEqualTo(TestFactory.CONSUMER_PAYMENT_DETAILS)
}

private val cardPaymentMethodCreateParams =
FieldValuesToParamsMapConverter.transformToPaymentMethodCreateParams(
mapOf(
Expand Down
Loading

0 comments on commit aa134ed

Please sign in to comment.