diff --git a/bitrise.yml b/bitrise.yml index 56dcaf79639..13b0d71d8c2 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -71,6 +71,7 @@ workflows: - opts: is_expand: false NEEDS_ROBOLECTRIC: true + - INCLUDE_PAPARAZZI_ON_FAILURE: true before_run: - prepare_all after_run: diff --git a/payments-core-testing/src/main/java/com/stripe/android/testing/CoroutineTestRule.kt b/payments-core-testing/src/main/java/com/stripe/android/testing/CoroutineTestRule.kt index b4a4f7f88ca..93556834eb6 100644 --- a/payments-core-testing/src/main/java/com/stripe/android/testing/CoroutineTestRule.kt +++ b/payments-core-testing/src/main/java/com/stripe/android/testing/CoroutineTestRule.kt @@ -3,6 +3,7 @@ package com.stripe.android.testing import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestDispatcher +import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.setMain import org.junit.rules.TestWatcher @@ -10,7 +11,7 @@ import org.junit.runner.Description @ExperimentalCoroutinesApi class CoroutineTestRule( - private val testDispatcher: TestDispatcher, + private val testDispatcher: TestDispatcher = UnconfinedTestDispatcher(), ) : TestWatcher() { override fun starting(description: Description) { diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/FakeAddPaymentMethodInteractor.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/FakeAddPaymentMethodInteractor.kt deleted file mode 100644 index 462d287fdae..00000000000 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/FakeAddPaymentMethodInteractor.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.stripe.android.paymentsheet.navigation - -import com.stripe.android.paymentsheet.ui.AddPaymentMethodInteractor -import kotlinx.coroutines.flow.StateFlow - -internal class FakeAddPaymentMethodInteractor( - override val state: StateFlow, -) : AddPaymentMethodInteractor { - override val isLiveMode: Boolean = true - - override fun handleViewAction(viewAction: AddPaymentMethodInteractor.ViewAction) { - // Do nothing. - } - - override fun close() { - // Do nothing. - } -} diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddAnotherPaymentMethodScreenshotTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddAnotherPaymentMethodScreenshotTest.kt new file mode 100644 index 00000000000..437b6faa471 --- /dev/null +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddAnotherPaymentMethodScreenshotTest.kt @@ -0,0 +1,58 @@ +package com.stripe.android.paymentsheet.navigation + +import androidx.compose.foundation.layout.padding +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.stripe.android.core.strings.resolvableString +import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodMetadataFactory +import com.stripe.android.paymentsheet.navigation.PaymentSheetScreen.AddAnotherPaymentMethod +import com.stripe.android.paymentsheet.ui.FakeAddPaymentMethodInteractor +import com.stripe.android.paymentsheet.ui.FakeAddPaymentMethodInteractor.Companion.createState +import com.stripe.android.paymentsheet.ui.PaymentSheetFlowType +import com.stripe.android.paymentsheet.ui.PaymentSheetScreen +import com.stripe.android.paymentsheet.utils.ViewModelStoreOwnerContext +import com.stripe.android.paymentsheet.viewmodels.FakeBaseSheetViewModel +import com.stripe.android.screenshottesting.PaparazziRule +import com.stripe.android.testing.CoroutineTestRule +import org.junit.Rule +import org.junit.Test + +internal class PaymentSheetScreenAddAnotherPaymentMethodScreenshotTest { + @get:Rule + val paparazziRule = PaparazziRule( + boxModifier = Modifier + .padding(16.dp) + ) + + @get:Rule + val coroutineRule = CoroutineTestRule() + + @Test + fun displaysCard() { + val metadata = PaymentMethodMetadataFactory.create() + val interactor = FakeAddPaymentMethodInteractor(initialState = createState()) + val initialScreen = AddAnotherPaymentMethod(interactor) + val viewModel = FakeBaseSheetViewModel.create(metadata, initialScreen) + + paparazziRule.snapshot { + ViewModelStoreOwnerContext { + PaymentSheetScreen(viewModel = viewModel, type = PaymentSheetFlowType.Complete) + } + } + } + + @Test + fun displaysError() { + val metadata = PaymentMethodMetadataFactory.create() + val interactor = FakeAddPaymentMethodInteractor(initialState = createState()) + val initialScreen = AddAnotherPaymentMethod(interactor) + val viewModel = FakeBaseSheetViewModel.create(metadata, initialScreen) + viewModel.onError("An error occurred.".resolvableString) + + paparazziRule.snapshot { + ViewModelStoreOwnerContext { + PaymentSheetScreen(viewModel = viewModel, type = PaymentSheetFlowType.Complete) + } + } + } +} diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddAnotherPaymentMethodTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddAnotherPaymentMethodTest.kt index 93cc72113a5..d93e7f846e0 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddAnotherPaymentMethodTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddAnotherPaymentMethodTest.kt @@ -3,22 +3,24 @@ package com.stripe.android.paymentsheet.navigation import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import com.stripe.android.core.strings.resolvableString -import com.stripe.android.lpmfoundations.luxe.LpmRepositoryTestHelpers -import com.stripe.android.lpmfoundations.luxe.SupportedPaymentMethod -import com.stripe.android.model.PaymentMethod +import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodMetadataFactory +import com.stripe.android.model.PaymentIntentFixtures import com.stripe.android.paymentsheet.R -import com.stripe.android.paymentsheet.ui.AddPaymentMethodInteractor -import com.stripe.android.uicore.utils.stateFlowOf +import com.stripe.android.paymentsheet.ui.FakeAddPaymentMethodInteractor +import com.stripe.android.paymentsheet.ui.FakeAddPaymentMethodInteractor.Companion.createState +import com.stripe.android.testing.CoroutineTestRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test -import org.mockito.kotlin.mock import com.stripe.android.R as PaymentsCoreR internal class PaymentSheetScreenAddAnotherPaymentMethodTest { + @get:Rule + val coroutineRule = CoroutineTestRule() @Test fun `title returns null when isWalletEnabled`() = runTest { - val interactor = FakeAddPaymentMethodInteractor(stateFlowOf(createState())) + val interactor = FakeAddPaymentMethodInteractor(createState()) PaymentSheetScreen.AddAnotherPaymentMethod(interactor) .title(isCompleteFlow = false, isWalletEnabled = true).test { assertThat(awaitItem()).isNull() @@ -27,7 +29,7 @@ internal class PaymentSheetScreenAddAnotherPaymentMethodTest { @Test fun `title returns null when isCompleteFlow`() = runTest { - val interactor = FakeAddPaymentMethodInteractor(stateFlowOf(createState())) + val interactor = FakeAddPaymentMethodInteractor(createState()) PaymentSheetScreen.AddAnotherPaymentMethod(interactor) .title(isCompleteFlow = true, isWalletEnabled = false).test { assertThat(awaitItem()).isNull() @@ -36,8 +38,14 @@ internal class PaymentSheetScreenAddAnotherPaymentMethodTest { @Test fun `title returns add card with one supported payment method`() = runTest { - val state = createState(supportedPaymentMethods = listOf(LpmRepositoryTestHelpers.card)) - val interactor = FakeAddPaymentMethodInteractor(stateFlowOf(state)) + val state = createState( + metadata = PaymentMethodMetadataFactory.create( + stripeIntent = PaymentIntentFixtures.PI_REQUIRES_PAYMENT_METHOD.copy( + paymentMethodTypes = listOf("card") + ) + ) + ) + val interactor = FakeAddPaymentMethodInteractor(state) PaymentSheetScreen.AddAnotherPaymentMethod(interactor) .title(isCompleteFlow = false, isWalletEnabled = false).test { assertThat(awaitItem()).isEqualTo(PaymentsCoreR.string.stripe_title_add_a_card.resolvableString) @@ -46,8 +54,15 @@ internal class PaymentSheetScreenAddAnotherPaymentMethodTest { @Test fun `title returns choose payment method with non card one supported payment method`() = runTest { - val state = createState(supportedPaymentMethods = listOf(LpmRepositoryTestHelpers.usBankAccount)) - val interactor = FakeAddPaymentMethodInteractor(stateFlowOf(state)) + val state = createState( + metadata = PaymentMethodMetadataFactory.create( + stripeIntent = PaymentIntentFixtures.PI_REQUIRES_PAYMENT_METHOD.copy( + paymentMethodTypes = listOf("us_bank_account"), + clientSecret = null, + ), + ) + ) + val interactor = FakeAddPaymentMethodInteractor(state) PaymentSheetScreen.AddAnotherPaymentMethod(interactor) .title(isCompleteFlow = false, isWalletEnabled = false).test { assertThat(awaitItem()).isEqualTo(R.string.stripe_paymentsheet_choose_payment_method.resolvableString) @@ -56,27 +71,10 @@ internal class PaymentSheetScreenAddAnotherPaymentMethodTest { @Test fun `title returns choose payment method with more than one supported payment method`() = runTest { - val interactor = FakeAddPaymentMethodInteractor(stateFlowOf(createState())) + val interactor = FakeAddPaymentMethodInteractor(createState()) PaymentSheetScreen.AddAnotherPaymentMethod(interactor) .title(isCompleteFlow = false, isWalletEnabled = false).test { assertThat(awaitItem()).isEqualTo(R.string.stripe_paymentsheet_choose_payment_method.resolvableString) } } - - private fun createState( - supportedPaymentMethods: List = listOf( - LpmRepositoryTestHelpers.card, - LpmRepositoryTestHelpers.usBankAccount, - ), - ): AddPaymentMethodInteractor.State { - return AddPaymentMethodInteractor.State( - selectedPaymentMethodCode = PaymentMethod.Type.Card.code, - supportedPaymentMethods = supportedPaymentMethods, - arguments = mock(), - formElements = emptyList(), - paymentSelection = null, - processing = false, - usBankAccountFormArguments = mock(), - ) - } } diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddFirstPaymentMethodScreenshotTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddFirstPaymentMethodScreenshotTest.kt new file mode 100644 index 00000000000..0218936251f --- /dev/null +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddFirstPaymentMethodScreenshotTest.kt @@ -0,0 +1,58 @@ +package com.stripe.android.paymentsheet.navigation + +import androidx.compose.foundation.layout.padding +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.stripe.android.core.strings.resolvableString +import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodMetadataFactory +import com.stripe.android.paymentsheet.navigation.PaymentSheetScreen.AddFirstPaymentMethod +import com.stripe.android.paymentsheet.ui.FakeAddPaymentMethodInteractor +import com.stripe.android.paymentsheet.ui.FakeAddPaymentMethodInteractor.Companion.createState +import com.stripe.android.paymentsheet.ui.PaymentSheetFlowType +import com.stripe.android.paymentsheet.ui.PaymentSheetScreen +import com.stripe.android.paymentsheet.utils.ViewModelStoreOwnerContext +import com.stripe.android.paymentsheet.viewmodels.FakeBaseSheetViewModel +import com.stripe.android.screenshottesting.PaparazziRule +import com.stripe.android.testing.CoroutineTestRule +import org.junit.Rule +import org.junit.Test + +internal class PaymentSheetScreenAddFirstPaymentMethodScreenshotTest { + @get:Rule + val paparazziRule = PaparazziRule( + boxModifier = Modifier + .padding(16.dp) + ) + + @get:Rule + val coroutineRule = CoroutineTestRule() + + @Test + fun displaysCard() { + val metadata = PaymentMethodMetadataFactory.create() + val interactor = FakeAddPaymentMethodInteractor(initialState = createState()) + val initialScreen = AddFirstPaymentMethod(interactor) + val viewModel = FakeBaseSheetViewModel.create(metadata, initialScreen) + + paparazziRule.snapshot { + ViewModelStoreOwnerContext { + PaymentSheetScreen(viewModel = viewModel, type = PaymentSheetFlowType.Complete) + } + } + } + + @Test + fun displaysError() { + val metadata = PaymentMethodMetadataFactory.create() + val interactor = FakeAddPaymentMethodInteractor(initialState = createState()) + val initialScreen = AddFirstPaymentMethod(interactor) + val viewModel = FakeBaseSheetViewModel.create(metadata, initialScreen) + viewModel.onError("An error occurred.".resolvableString) + + paparazziRule.snapshot { + ViewModelStoreOwnerContext { + PaymentSheetScreen(viewModel = viewModel, type = PaymentSheetFlowType.Complete) + } + } + } +} diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddFirstPaymentMethodTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddFirstPaymentMethodTest.kt index cf254fec60a..ff0e4d0b8b7 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddFirstPaymentMethodTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenAddFirstPaymentMethodTest.kt @@ -3,22 +3,24 @@ package com.stripe.android.paymentsheet.navigation import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import com.stripe.android.core.strings.resolvableString -import com.stripe.android.lpmfoundations.luxe.LpmRepositoryTestHelpers -import com.stripe.android.lpmfoundations.luxe.SupportedPaymentMethod -import com.stripe.android.model.PaymentMethod +import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodMetadataFactory +import com.stripe.android.model.PaymentIntentFixtures import com.stripe.android.paymentsheet.R -import com.stripe.android.paymentsheet.ui.AddPaymentMethodInteractor -import com.stripe.android.uicore.utils.stateFlowOf +import com.stripe.android.paymentsheet.ui.FakeAddPaymentMethodInteractor +import com.stripe.android.paymentsheet.ui.FakeAddPaymentMethodInteractor.Companion.createState +import com.stripe.android.testing.CoroutineTestRule import kotlinx.coroutines.test.runTest +import org.junit.Rule import org.junit.Test -import org.mockito.kotlin.mock import com.stripe.android.R as PaymentsCoreR internal class PaymentSheetScreenAddFirstPaymentMethodTest { + @get:Rule + val coroutineRule = CoroutineTestRule() @Test fun `title returns null when isWalletEnabled`() = runTest { - val interactor = FakeAddPaymentMethodInteractor(stateFlowOf(createState())) + val interactor = FakeAddPaymentMethodInteractor(createState()) PaymentSheetScreen.AddFirstPaymentMethod(interactor) .title(isCompleteFlow = false, isWalletEnabled = true).test { assertThat(awaitItem()).isNull() @@ -27,7 +29,7 @@ internal class PaymentSheetScreenAddFirstPaymentMethodTest { @Test fun `title returns add payment method when isCompleteFlow`() = runTest { - val interactor = FakeAddPaymentMethodInteractor(stateFlowOf(createState())) + val interactor = FakeAddPaymentMethodInteractor(createState()) PaymentSheetScreen.AddFirstPaymentMethod(interactor) .title(isCompleteFlow = true, isWalletEnabled = false).test { assertThat(awaitItem()) @@ -37,8 +39,14 @@ internal class PaymentSheetScreenAddFirstPaymentMethodTest { @Test fun `title returns add card with one supported payment method`() = runTest { - val state = createState(supportedPaymentMethods = listOf(LpmRepositoryTestHelpers.card)) - val interactor = FakeAddPaymentMethodInteractor(stateFlowOf(state)) + val state = createState( + metadata = PaymentMethodMetadataFactory.create( + stripeIntent = PaymentIntentFixtures.PI_REQUIRES_PAYMENT_METHOD.copy( + paymentMethodTypes = listOf("card") + ) + ) + ) + val interactor = FakeAddPaymentMethodInteractor(state) PaymentSheetScreen.AddFirstPaymentMethod(interactor) .title(isCompleteFlow = false, isWalletEnabled = false).test { assertThat(awaitItem()).isEqualTo(PaymentsCoreR.string.stripe_title_add_a_card.resolvableString) @@ -47,8 +55,15 @@ internal class PaymentSheetScreenAddFirstPaymentMethodTest { @Test fun `title returns choose payment method with non card one supported payment method`() = runTest { - val state = createState(supportedPaymentMethods = listOf(LpmRepositoryTestHelpers.usBankAccount)) - val interactor = FakeAddPaymentMethodInteractor(stateFlowOf(state)) + val state = createState( + metadata = PaymentMethodMetadataFactory.create( + stripeIntent = PaymentIntentFixtures.PI_REQUIRES_PAYMENT_METHOD.copy( + paymentMethodTypes = listOf("us_bank_account"), + clientSecret = null, + ), + ) + ) + val interactor = FakeAddPaymentMethodInteractor(state) PaymentSheetScreen.AddFirstPaymentMethod(interactor) .title(isCompleteFlow = false, isWalletEnabled = false).test { assertThat(awaitItem()).isEqualTo(R.string.stripe_paymentsheet_choose_payment_method.resolvableString) @@ -57,27 +72,10 @@ internal class PaymentSheetScreenAddFirstPaymentMethodTest { @Test fun `title returns choose payment method with more than one supported payment method`() = runTest { - val interactor = FakeAddPaymentMethodInteractor(stateFlowOf(createState())) + val interactor = FakeAddPaymentMethodInteractor(createState()) PaymentSheetScreen.AddFirstPaymentMethod(interactor) .title(isCompleteFlow = false, isWalletEnabled = false).test { assertThat(awaitItem()).isEqualTo(R.string.stripe_paymentsheet_choose_payment_method.resolvableString) } } - - private fun createState( - supportedPaymentMethods: List = listOf( - LpmRepositoryTestHelpers.card, - LpmRepositoryTestHelpers.usBankAccount, - ), - ): AddPaymentMethodInteractor.State { - return AddPaymentMethodInteractor.State( - selectedPaymentMethodCode = PaymentMethod.Type.Card.code, - supportedPaymentMethods = supportedPaymentMethods, - arguments = mock(), - formElements = emptyList(), - paymentSelection = null, - processing = false, - usBankAccountFormArguments = mock(), - ) - } } diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenLoadingScreenshotTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenLoadingScreenshotTest.kt index 82ac9b6ab99..0e7bc20c396 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenLoadingScreenshotTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenLoadingScreenshotTest.kt @@ -11,7 +11,6 @@ import com.stripe.android.paymentsheet.viewmodels.FakeBaseSheetViewModel import com.stripe.android.screenshottesting.PaparazziRule import com.stripe.android.testing.CoroutineTestRule import kotlinx.coroutines.flow.update -import kotlinx.coroutines.test.UnconfinedTestDispatcher import org.junit.Rule import org.junit.Test @@ -23,7 +22,7 @@ internal class PaymentSheetScreenLoadingScreenshotTest { ) @get:Rule - val coroutineRule = CoroutineTestRule(UnconfinedTestDispatcher()) + val coroutineRule = CoroutineTestRule() @Test fun displaysLoading() { diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenSelectSavedPaymentMethodsScreenshotTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenSelectSavedPaymentMethodsScreenshotTest.kt index 54ae92bde6b..0348a7f33c0 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenSelectSavedPaymentMethodsScreenshotTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenSelectSavedPaymentMethodsScreenshotTest.kt @@ -17,7 +17,6 @@ import com.stripe.android.paymentsheet.viewmodels.FakeBaseSheetViewModel import com.stripe.android.screenshottesting.PaparazziRule import com.stripe.android.testing.CoroutineTestRule import kotlinx.coroutines.flow.update -import kotlinx.coroutines.test.UnconfinedTestDispatcher import org.junit.Rule import org.junit.Test @@ -29,7 +28,7 @@ internal class PaymentSheetScreenSelectSavedPaymentMethodsScreenshotTest { ) @get:Rule - val coroutineRule = CoroutineTestRule(UnconfinedTestDispatcher()) + val coroutineRule = CoroutineTestRule() private val savedPaymentOptionItem = PaymentOptionsItem.SavedPaymentMethod( displayableSavedPaymentMethod = DisplayableSavedPaymentMethod( diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenVerticalModeScreenshotTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenVerticalModeScreenshotTest.kt index baa80b6f81b..7b4f864a84a 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenVerticalModeScreenshotTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/navigation/PaymentSheetScreenVerticalModeScreenshotTest.kt @@ -17,7 +17,6 @@ import com.stripe.android.paymentsheet.viewmodels.FakeBaseSheetViewModel import com.stripe.android.screenshottesting.PaparazziRule import com.stripe.android.testing.CoroutineTestRule import kotlinx.coroutines.flow.update -import kotlinx.coroutines.test.UnconfinedTestDispatcher import org.junit.Rule import org.junit.Test @@ -30,7 +29,7 @@ internal class PaymentSheetScreenVerticalModeScreenshotTest { ) @get:Rule - val coroutineRule = CoroutineTestRule(UnconfinedTestDispatcher()) + val coroutineRule = CoroutineTestRule() @Test fun displaysVerticalModeList() { diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/ui/AddPaymentMethodTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/ui/AddPaymentMethodTest.kt index ad6602a0169..edee5ec2b3b 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/ui/AddPaymentMethodTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/ui/AddPaymentMethodTest.kt @@ -24,8 +24,6 @@ import com.stripe.android.uicore.elements.CheckboxFieldElement import com.stripe.android.uicore.elements.DEFAULT_CHECKBOX_TEST_TAG import com.stripe.android.uicore.elements.IdentifierSpec import com.stripe.android.uicore.forms.FormFieldEntry -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.test.runTest import org.junit.Rule import org.junit.runner.RunWith @@ -255,7 +253,7 @@ internal class AddPaymentMethodTest { val viewActionRecorder = ViewActionRecorder() - val addPaymentMethodInteractor = FakeAddPaymentMethodInteractor(viewActionRecorder, initialState) + val addPaymentMethodInteractor = FakeAddPaymentMethodInteractor(initialState, viewActionRecorder) composeRule.setContent { AddPaymentMethod(interactor = addPaymentMethodInteractor) @@ -271,23 +269,6 @@ internal class AddPaymentMethodTest { Scenario(viewActionRecorder).apply(block) } - class FakeAddPaymentMethodInteractor( - private val viewActionRecorder: ViewActionRecorder, - initialState: AddPaymentMethodInteractor.State, - override val isLiveMode: Boolean = true, - ) : AddPaymentMethodInteractor { - - override val state: StateFlow = MutableStateFlow(initialState) - - override fun handleViewAction(viewAction: AddPaymentMethodInteractor.ViewAction) { - viewActionRecorder.record(viewAction) - } - - override fun close() { - // Do nothing. - } - } - private data class Scenario( val viewActionRecorder: ViewActionRecorder, ) diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/ui/FakeAddPaymentMethodInteractor.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/ui/FakeAddPaymentMethodInteractor.kt new file mode 100644 index 00000000000..a9786a65696 --- /dev/null +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/ui/FakeAddPaymentMethodInteractor.kt @@ -0,0 +1,58 @@ +package com.stripe.android.paymentsheet.ui + +import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodMetadata +import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodMetadataFactory +import com.stripe.android.lpmfoundations.paymentmethod.UiDefinitionFactory +import com.stripe.android.model.PaymentMethodCode +import com.stripe.android.paymentsheet.ViewActionRecorder +import com.stripe.android.paymentsheet.forms.FormArgumentsFactory +import com.stripe.android.uicore.utils.stateFlowOf +import com.stripe.android.utils.NullCardAccountRangeRepositoryFactory +import kotlinx.coroutines.flow.StateFlow +import org.mockito.kotlin.mock + +internal class FakeAddPaymentMethodInteractor( + initialState: AddPaymentMethodInteractor.State, + private val viewActionRecorder: ViewActionRecorder = ViewActionRecorder(), +) : AddPaymentMethodInteractor { + override val state: StateFlow = stateFlowOf(initialState) + override val isLiveMode: Boolean = true + + override fun handleViewAction(viewAction: AddPaymentMethodInteractor.ViewAction) { + viewActionRecorder.record(viewAction) + } + + override fun close() { + // Do nothing. + } + + companion object { + fun createState( + metadata: PaymentMethodMetadata = PaymentMethodMetadataFactory.create(), + paymentMethodCode: PaymentMethodCode = metadata.supportedPaymentMethodTypes().first(), + ): AddPaymentMethodInteractor.State { + val formArguments = FormArgumentsFactory.create( + paymentMethodCode = paymentMethodCode, + metadata = metadata, + ) + val uiDefinitionArgumentsFactory = UiDefinitionFactory.Arguments.Factory.Default( + cardAccountRangeRepositoryFactory = NullCardAccountRangeRepositoryFactory, + linkConfigurationCoordinator = null, + onLinkInlineSignupStateChanged = { throw AssertionError("Not expected") }, + ) + + return AddPaymentMethodInteractor.State( + selectedPaymentMethodCode = paymentMethodCode, + supportedPaymentMethods = metadata.sortedSupportedPaymentMethods(), + arguments = formArguments, + formElements = metadata.formElementsForCode( + code = paymentMethodCode, + uiDefinitionFactoryArgumentsFactory = uiDefinitionArgumentsFactory, + ) ?: mock(), + paymentSelection = null, + processing = false, + usBankAccountFormArguments = mock(), + ) + } + } +} diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/utils/ViewModelStoreOwnerContext.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/utils/ViewModelStoreOwnerContext.kt new file mode 100644 index 00000000000..284c58a5519 --- /dev/null +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/utils/ViewModelStoreOwnerContext.kt @@ -0,0 +1,18 @@ +package com.stripe.android.paymentsheet.utils + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.lifecycle.ViewModelStore +import androidx.lifecycle.ViewModelStoreOwner +import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner + +@Composable +fun ViewModelStoreOwnerContext(content: @Composable () -> Unit) { + CompositionLocalProvider( + LocalViewModelStoreOwner provides object : ViewModelStoreOwner { + override val viewModelStore: ViewModelStore = ViewModelStore() + } + ) { + content() + } +} diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/verticalmode/VerticalModeFormUIScreenshotTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/verticalmode/VerticalModeFormUIScreenshotTest.kt index 7f17a5055f0..e06f4200039 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/verticalmode/VerticalModeFormUIScreenshotTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/verticalmode/VerticalModeFormUIScreenshotTest.kt @@ -2,12 +2,8 @@ package com.stripe.android.paymentsheet.verticalmode import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import androidx.lifecycle.ViewModelStore -import androidx.lifecycle.ViewModelStoreOwner -import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner import com.stripe.android.core.strings.resolvableString import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodMetadata import com.stripe.android.lpmfoundations.paymentmethod.PaymentMethodMetadataFactory @@ -20,11 +16,11 @@ import com.stripe.android.paymentsheet.navigation.PaymentSheetScreen.VerticalMod import com.stripe.android.paymentsheet.state.WalletsState import com.stripe.android.paymentsheet.ui.PaymentSheetFlowType import com.stripe.android.paymentsheet.ui.PaymentSheetScreen +import com.stripe.android.paymentsheet.utils.ViewModelStoreOwnerContext import com.stripe.android.paymentsheet.viewmodels.FakeBaseSheetViewModel import com.stripe.android.screenshottesting.PaparazziRule import com.stripe.android.testing.CoroutineTestRule import kotlinx.coroutines.flow.update -import kotlinx.coroutines.test.UnconfinedTestDispatcher import org.junit.Rule import org.junit.Test @@ -37,7 +33,7 @@ internal class VerticalModeFormUIScreenshotTest { ) @get:Rule - val coroutineRule = CoroutineTestRule(UnconfinedTestDispatcher()) + val coroutineRule = CoroutineTestRule() @Test fun cardFormIsDisplayed() { @@ -183,17 +179,6 @@ internal class VerticalModeFormUIScreenshotTest { } } - @Composable - private fun ViewModelStoreOwnerContext(content: @Composable () -> Unit) { - CompositionLocalProvider( - LocalViewModelStoreOwner provides object : ViewModelStoreOwner { - override val viewModelStore: ViewModelStore = ViewModelStore() - } - ) { - content() - } - } - @Composable private fun CreateTestScenario( paymentMethodCode: PaymentMethodCode, diff --git a/paymentsheet/src/test/snapshots/images/com.stripe.android.paymentsheet.navigation_PaymentSheetScreenAddAnotherPaymentMethodScreenshotTest_displaysCard[].png b/paymentsheet/src/test/snapshots/images/com.stripe.android.paymentsheet.navigation_PaymentSheetScreenAddAnotherPaymentMethodScreenshotTest_displaysCard[].png new file mode 100644 index 00000000000..76c0875cb6a Binary files /dev/null and b/paymentsheet/src/test/snapshots/images/com.stripe.android.paymentsheet.navigation_PaymentSheetScreenAddAnotherPaymentMethodScreenshotTest_displaysCard[].png differ diff --git a/paymentsheet/src/test/snapshots/images/com.stripe.android.paymentsheet.navigation_PaymentSheetScreenAddAnotherPaymentMethodScreenshotTest_displaysError[].png b/paymentsheet/src/test/snapshots/images/com.stripe.android.paymentsheet.navigation_PaymentSheetScreenAddAnotherPaymentMethodScreenshotTest_displaysError[].png new file mode 100644 index 00000000000..b18ab0bfde4 Binary files /dev/null and b/paymentsheet/src/test/snapshots/images/com.stripe.android.paymentsheet.navigation_PaymentSheetScreenAddAnotherPaymentMethodScreenshotTest_displaysError[].png differ diff --git a/paymentsheet/src/test/snapshots/images/com.stripe.android.paymentsheet.navigation_PaymentSheetScreenAddFirstPaymentMethodScreenshotTest_displaysCard[].png b/paymentsheet/src/test/snapshots/images/com.stripe.android.paymentsheet.navigation_PaymentSheetScreenAddFirstPaymentMethodScreenshotTest_displaysCard[].png new file mode 100644 index 00000000000..5c88bb1308c Binary files /dev/null and b/paymentsheet/src/test/snapshots/images/com.stripe.android.paymentsheet.navigation_PaymentSheetScreenAddFirstPaymentMethodScreenshotTest_displaysCard[].png differ diff --git a/paymentsheet/src/test/snapshots/images/com.stripe.android.paymentsheet.navigation_PaymentSheetScreenAddFirstPaymentMethodScreenshotTest_displaysError[].png b/paymentsheet/src/test/snapshots/images/com.stripe.android.paymentsheet.navigation_PaymentSheetScreenAddFirstPaymentMethodScreenshotTest_displaysError[].png new file mode 100644 index 00000000000..452085997eb Binary files /dev/null and b/paymentsheet/src/test/snapshots/images/com.stripe.android.paymentsheet.navigation_PaymentSheetScreenAddFirstPaymentMethodScreenshotTest_displaysError[].png differ diff --git a/scripts/copy_test_results_to_tmp.sh b/scripts/copy_test_results_to_tmp.sh index c6c84808675..30e8154903c 100755 --- a/scripts/copy_test_results_to_tmp.sh +++ b/scripts/copy_test_results_to_tmp.sh @@ -23,7 +23,12 @@ if [ "$INCLUDE_SCREENSHOT_ON_FAILURE" == "true" ] && [ "$BITRISE_BUILD_STATUS" = copy_test_results ".*/screenshots/debug$" fi -# If dependenciesĪ€ were requested, and it's a failure. +# If paparazzi screenshots were requested, and it's a failure. +if [ "$INCLUDE_PAPARAZZI_ON_FAILURE" == "true" ] && [ "$BITRISE_BUILD_STATUS" == 1 ]; then + copy_test_results ".*/build/paparazzi/failures$" +fi + +# If dependencies were requested, and it's a failure. if [ "$INCLUDE_DEPENDENCIES_ON_FAILURE" == "true" ] && [ "$BITRISE_BUILD_STATUS" == 1 ]; then copy_test_results ".*/dependencies$" fi