From b44837209769befef3534d6049c6590483d96d3f Mon Sep 17 00:00:00 2001 From: brnunes-stripe Date: Mon, 24 Oct 2022 14:36:13 -0700 Subject: [PATCH 1/2] Pass injector to FormViewModel --- paymentsheet/api/paymentsheet.api | 4 - .../BaseAddPaymentMethodFragment.kt | 2 +- .../DefaultPaymentSheetLauncher.kt | 4 +- .../paymentsheet/PaymentOptionsViewModel.kt | 63 +++++++++++---- .../paymentsheet/PaymentSheetViewModel.kt | 51 ++++++++++-- .../flowcontroller/DefaultFlowController.kt | 4 +- .../paymentsheet/forms/FormViewModel.kt | 25 ++---- .../injection/FormViewModelComponent.kt | 32 -------- ...PaymentOptionsViewModelFactoryComponent.kt | 2 + .../PaymentOptionsViewModelModule.kt | 5 +- .../FormFragmentArguments.kt | 2 - .../paymentsheet/ui/PaymentMethodForm.kt | 6 +- .../viewmodels/BaseSheetViewModel.kt | 8 ++ .../PaymentOptionsActivityTest.kt | 12 +-- .../PaymentOptionsViewModelTest.kt | 5 -- .../PaymentOptionsViewModelTestInjection.kt | 18 +++-- .../paymentsheet/PaymentSheetActivityTest.kt | 17 ++-- .../paymentsheet/PaymentSheetFixtures.kt | 3 +- .../paymentsheet/PaymentSheetViewModelTest.kt | 30 ++++---- .../PaymentSheetViewModelTestInjection.kt | 8 +- .../FormFragmentArgumentsTest.kt | 2 - .../ach/USBankAccountFormViewModelTest.kt | 77 ++++++++++++++----- 22 files changed, 222 insertions(+), 158 deletions(-) delete mode 100644 paymentsheet/src/main/java/com/stripe/android/paymentsheet/injection/FormViewModelComponent.kt diff --git a/paymentsheet/api/paymentsheet.api b/paymentsheet/api/paymentsheet.api index ae53e7f399a..ca58bf10b1d 100644 --- a/paymentsheet/api/paymentsheet.api +++ b/paymentsheet/api/paymentsheet.api @@ -1173,10 +1173,6 @@ public final class com/stripe/android/paymentsheet/injection/DaggerFlowControlle public static fun builder ()Lcom/stripe/android/paymentsheet/injection/FlowControllerComponent$Builder; } -public final class com/stripe/android/paymentsheet/injection/DaggerFormViewModelComponent { - public static fun builder ()Lcom/stripe/android/paymentsheet/injection/FormViewModelComponent$Builder; -} - public final class com/stripe/android/paymentsheet/injection/DaggerPaymentOptionsViewModelFactoryComponent { public static fun builder ()Lcom/stripe/android/paymentsheet/injection/PaymentOptionsViewModelFactoryComponent$Builder; } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BaseAddPaymentMethodFragment.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BaseAddPaymentMethodFragment.kt index 5f6cd1b187b..6bfca5232b9 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BaseAddPaymentMethodFragment.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BaseAddPaymentMethodFragment.kt @@ -210,6 +210,7 @@ internal abstract class BaseAddPaymentMethodFragment : Fragment() { enabled = enabled, onFormFieldValuesChanged = onFormFieldValuesChanged, showCheckboxFlow = showCheckboxFlow, + injector = sheetViewModel.injector, modifier = Modifier.padding(horizontal = horizontalPadding) ) } @@ -389,7 +390,6 @@ internal abstract class BaseAddPaymentMethodFragment : Fragment() { amount = amount, billingDetails = config?.defaultBillingDetails, shippingDetails = config?.shippingDetails, - injectorKey = injectorKey, initialPaymentMethodCreateParams = if (newLpm is PaymentSelection.New.LinkInline) { newLpm.linkPaymentDetails.originalParams diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/DefaultPaymentSheetLauncher.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/DefaultPaymentSheetLauncher.kt index 13f2b20ef1a..1c8c4819d3e 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/DefaultPaymentSheetLauncher.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/DefaultPaymentSheetLauncher.kt @@ -6,12 +6,12 @@ import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultRegistry import androidx.fragment.app.Fragment import com.stripe.android.core.injection.Injectable -import com.stripe.android.core.injection.Injector import com.stripe.android.core.injection.InjectorKey import com.stripe.android.core.injection.WeakMapInjectorRegistry import com.stripe.android.paymentsheet.forms.FormViewModel import com.stripe.android.paymentsheet.injection.DaggerPaymentSheetLauncherComponent import com.stripe.android.paymentsheet.injection.PaymentSheetLauncherComponent +import com.stripe.android.ui.core.injection.NonFallbackInjector import org.jetbrains.annotations.TestOnly /** @@ -21,7 +21,7 @@ import org.jetbrains.annotations.TestOnly internal class DefaultPaymentSheetLauncher( private val activityResultLauncher: ActivityResultLauncher, application: Application -) : PaymentSheetLauncher, Injector { +) : PaymentSheetLauncher, NonFallbackInjector { @InjectorKey private val injectorKey: String = WeakMapInjectorRegistry.nextKey(requireNotNull(PaymentSheetLauncher::class.simpleName)) diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentOptionsViewModel.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentOptionsViewModel.kt index 4592e7bc248..1d6a999769a 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentOptionsViewModel.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentOptionsViewModel.kt @@ -11,11 +11,12 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.savedstate.SavedStateRegistryOwner +import com.stripe.android.core.BuildConfig import com.stripe.android.core.Logger import com.stripe.android.core.injection.IOContext import com.stripe.android.core.injection.Injectable import com.stripe.android.core.injection.InjectorKey -import com.stripe.android.core.injection.injectWithFallback +import com.stripe.android.core.injection.WeakMapInjectorRegistry import com.stripe.android.link.LinkPaymentDetails import com.stripe.android.link.LinkPaymentLauncher import com.stripe.android.link.LinkPaymentLauncher.Companion.LINK_ENABLED @@ -24,6 +25,7 @@ import com.stripe.android.model.PaymentMethod import com.stripe.android.model.StripeIntent import com.stripe.android.payments.paymentlauncher.PaymentResult import com.stripe.android.paymentsheet.analytics.EventReporter +import com.stripe.android.paymentsheet.forms.FormViewModel import com.stripe.android.paymentsheet.injection.DaggerPaymentOptionsViewModelFactoryComponent import com.stripe.android.paymentsheet.injection.PaymentOptionsViewModelSubcomponent import com.stripe.android.paymentsheet.model.FragmentConfig @@ -35,6 +37,7 @@ import com.stripe.android.paymentsheet.viewmodels.BaseSheetViewModel import com.stripe.android.ui.core.address.AddressRepository import com.stripe.android.ui.core.forms.resources.LpmRepository import com.stripe.android.ui.core.forms.resources.ResourceRepository +import com.stripe.android.ui.core.injection.NonFallbackInjector import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import javax.inject.Inject @@ -317,17 +320,12 @@ internal class PaymentOptionsViewModel @Inject constructor( val productUsage: Set ) - override fun fallbackInitialize(arg: FallbackInitializeParam) { - DaggerPaymentOptionsViewModelFactoryComponent.builder() - .context(arg.application) - .productUsage(arg.productUsage) - .build().inject(this) - } - @Inject lateinit var subComponentBuilderProvider: Provider + private lateinit var injector: NonFallbackInjector + @Suppress("UNCHECKED_CAST") override fun create( key: String, @@ -336,15 +334,52 @@ internal class PaymentOptionsViewModel @Inject constructor( ): T { val application = applicationSupplier() val starterArgs = starterArgsSupplier() - injectWithFallback( - starterArgsSupplier().injectorKey, - FallbackInitializeParam(application, starterArgs.productUsage) - ) - return subComponentBuilderProvider.get() + val logger = Logger.getInstance(BuildConfig.DEBUG) + + WeakMapInjectorRegistry.retrieve(starterArgs.injectorKey)?.let { + it as? NonFallbackInjector + }?.let { + logger.info( + "Injector available, " + + "injecting dependencies into ${this::class.java.canonicalName}" + ) + injector = it + it.inject(this) + } ?: run { + logger.info( + "Injector unavailable, " + + "initializing dependencies of ${this::class.java.canonicalName}" + ) + fallbackInitialize(FallbackInitializeParam(application, starterArgs.productUsage)) + } + + val subcomponent = subComponentBuilderProvider.get() .application(application) .args(starterArgs) .savedStateHandle(savedStateHandle) - .build().viewModel as T + .build() + val viewModel = subcomponent.viewModel + viewModel.injector = injector + return viewModel as T + } + + override fun fallbackInitialize(arg: FallbackInitializeParam) { + val component = DaggerPaymentOptionsViewModelFactoryComponent.builder() + .context(arg.application) + .productUsage(arg.productUsage) + .build() + + injector = object : NonFallbackInjector { + override fun inject(injectable: Injectable<*>) { + when (injectable) { + is FormViewModel.Factory -> component.inject(injectable) + else -> { + throw IllegalArgumentException("invalid Injectable $injectable requested in $this") + } + } + } + } + component.inject(this) } } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetViewModel.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetViewModel.kt index 4b0f9c26a8d..b26770c4f02 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetViewModel.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheetViewModel.kt @@ -16,12 +16,13 @@ import androidx.lifecycle.distinctUntilChanged import androidx.lifecycle.viewModelScope import androidx.savedstate.SavedStateRegistryOwner import com.stripe.android.PaymentConfiguration +import com.stripe.android.core.BuildConfig import com.stripe.android.core.Logger import com.stripe.android.core.injection.DUMMY_INJECTOR_KEY import com.stripe.android.core.injection.IOContext import com.stripe.android.core.injection.Injectable import com.stripe.android.core.injection.InjectorKey -import com.stripe.android.core.injection.injectWithFallback +import com.stripe.android.core.injection.WeakMapInjectorRegistry import com.stripe.android.googlepaylauncher.GooglePayEnvironment import com.stripe.android.googlepaylauncher.GooglePayPaymentMethodLauncher import com.stripe.android.googlepaylauncher.GooglePayPaymentMethodLauncherContract @@ -48,6 +49,7 @@ import com.stripe.android.paymentsheet.addresselement.toConfirmPaymentIntentShip import com.stripe.android.paymentsheet.analytics.EventReporter import com.stripe.android.paymentsheet.extensions.registerPollingAuthenticator import com.stripe.android.paymentsheet.extensions.unregisterPollingAuthenticator +import com.stripe.android.paymentsheet.forms.FormViewModel import com.stripe.android.paymentsheet.injection.DaggerPaymentSheetLauncherComponent import com.stripe.android.paymentsheet.injection.PaymentSheetViewModelModule import com.stripe.android.paymentsheet.injection.PaymentSheetViewModelSubcomponent @@ -66,6 +68,7 @@ import com.stripe.android.paymentsheet.viewmodels.BaseSheetViewModel import com.stripe.android.ui.core.address.AddressRepository import com.stripe.android.ui.core.forms.resources.LpmRepository import com.stripe.android.ui.core.forms.resources.ResourceRepository +import com.stripe.android.ui.core.injection.NonFallbackInjector import dagger.Lazy import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -686,6 +689,8 @@ internal class PaymentSheetViewModel @Inject internal constructor( lateinit var subComponentBuilderProvider: Provider + private lateinit var injector: NonFallbackInjector + @Suppress("UNCHECKED_CAST") override fun create( key: String, @@ -693,21 +698,53 @@ internal class PaymentSheetViewModel @Inject internal constructor( savedStateHandle: SavedStateHandle ): T { val args = starterArgsSupplier() + val logger = Logger.getInstance(BuildConfig.DEBUG) + + WeakMapInjectorRegistry.retrieve(args.injectorKey)?.let { + it as? NonFallbackInjector + }?.let { + logger.info( + "Injector available, " + + "injecting dependencies into ${this::class.java.canonicalName}" + ) + injector = it + it.inject(this) + } ?: run { + logger.info( + "Injector unavailable, " + + "initializing dependencies of ${this::class.java.canonicalName}" + ) + fallbackInitialize(FallbackInitializeParam(applicationSupplier())) + } - injectWithFallback(args.injectorKey, FallbackInitializeParam(applicationSupplier())) - - return subComponentBuilderProvider.get() + val subcomponent = subComponentBuilderProvider.get() .paymentSheetViewModelModule(PaymentSheetViewModelModule(args)) .savedStateHandle(savedStateHandle) - .build().viewModel as T + .build() + val viewModel = subcomponent.viewModel + viewModel.injector = injector + return viewModel as T } override fun fallbackInitialize(arg: FallbackInitializeParam) { - DaggerPaymentSheetLauncherComponent + val component = DaggerPaymentSheetLauncherComponent .builder() .application(arg.application) .injectorKey(DUMMY_INJECTOR_KEY) - .build().inject(this) + .build() + + injector = object : NonFallbackInjector { + override fun inject(injectable: Injectable<*>) { + when (injectable) { + is FormViewModel.Factory -> component.inject(injectable) + else -> { + throw IllegalArgumentException("invalid Injectable $injectable requested in $this") + } + } + } + } + + component.inject(this) } } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/flowcontroller/DefaultFlowController.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/flowcontroller/DefaultFlowController.kt index 0104cd1d288..7d2f8a06261 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/flowcontroller/DefaultFlowController.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/flowcontroller/DefaultFlowController.kt @@ -12,7 +12,6 @@ import androidx.lifecycle.ViewModelStoreOwner import com.stripe.android.PaymentConfiguration import com.stripe.android.core.injection.ENABLE_LOGGING import com.stripe.android.core.injection.Injectable -import com.stripe.android.core.injection.Injector import com.stripe.android.core.injection.InjectorKey import com.stripe.android.core.injection.UIContext import com.stripe.android.core.injection.WeakMapInjectorRegistry @@ -61,6 +60,7 @@ import com.stripe.android.paymentsheet.validate import com.stripe.android.ui.core.address.AddressRepository import com.stripe.android.ui.core.forms.resources.LpmRepository import com.stripe.android.ui.core.forms.resources.ResourceRepository +import com.stripe.android.ui.core.injection.NonFallbackInjector import dagger.Lazy import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.FlowPreview @@ -107,7 +107,7 @@ internal class DefaultFlowController @Inject internal constructor( @Named(PRODUCT_USAGE) private val productUsage: Set, private val googlePayPaymentMethodLauncherFactory: GooglePayPaymentMethodLauncherFactory, private val linkLauncher: LinkPaymentLauncher -) : PaymentSheet.FlowController, Injector { +) : PaymentSheet.FlowController, NonFallbackInjector { private val paymentOptionActivityLauncher: ActivityResultLauncher private val googlePayActivityLauncher: ActivityResultLauncher diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/forms/FormViewModel.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/forms/FormViewModel.kt index 54a83b6a85a..e5a931f47fe 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/forms/FormViewModel.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/forms/FormViewModel.kt @@ -4,10 +4,7 @@ import android.content.Context import androidx.annotation.VisibleForTesting import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import com.stripe.android.core.injection.Injectable -import com.stripe.android.core.injection.injectWithFallback import com.stripe.android.paymentsheet.addresselement.toIdentifierMap -import com.stripe.android.paymentsheet.injection.DaggerFormViewModelComponent import com.stripe.android.paymentsheet.injection.FormViewModelSubcomponent import com.stripe.android.paymentsheet.model.PaymentSelection import com.stripe.android.paymentsheet.paymentdatacollection.FormFragmentArguments @@ -21,6 +18,8 @@ import com.stripe.android.ui.core.elements.SectionElement import com.stripe.android.ui.core.forms.TransformSpecToElements import com.stripe.android.ui.core.forms.resources.LpmRepository import com.stripe.android.ui.core.forms.resources.ResourceRepository +import com.stripe.android.ui.core.injection.NonFallbackInjectable +import com.stripe.android.ui.core.injection.NonFallbackInjector import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -52,31 +51,19 @@ internal class FormViewModel @Inject internal constructor( internal class Factory( val config: FormFragmentArguments, val showCheckboxFlow: Flow, - private val contextSupplier: () -> Context - ) : ViewModelProvider.Factory, - Injectable { - internal data class FallbackInitializeParam( - val context: Context - ) - + private val injector: NonFallbackInjector + ) : ViewModelProvider.Factory, NonFallbackInjectable { @Inject lateinit var subComponentBuilderProvider: Provider + @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { - val context = contextSupplier() - injectWithFallback(config.injectorKey, FallbackInitializeParam(context)) + injector.inject(this) return subComponentBuilderProvider.get() .formFragmentArguments(config) .showCheckboxFlow(showCheckboxFlow) .build().viewModel as T } - - override fun fallbackInitialize(arg: FallbackInitializeParam) { - DaggerFormViewModelComponent.builder() - .context(arg.context) - .build() - .inject(this) - } } val elementsFlow = flowOf( diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/injection/FormViewModelComponent.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/injection/FormViewModelComponent.kt deleted file mode 100644 index 2f6c6c526f9..00000000000 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/injection/FormViewModelComponent.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.stripe.android.paymentsheet.injection - -import android.content.Context -import com.stripe.android.core.injection.CoreCommonModule -import com.stripe.android.core.injection.CoroutineContextModule -import com.stripe.android.paymentsheet.forms.FormViewModel -import com.stripe.android.ui.core.forms.resources.injection.ResourceRepositoryModule -import dagger.BindsInstance -import dagger.Component -import javax.inject.Singleton - -@Singleton -@Component( - modules = [ - CoroutineContextModule::class, - ResourceRepositoryModule::class, - CoreCommonModule::class - ] -) -internal interface FormViewModelComponent { - val formViewModelSubcomponentBuilder: FormViewModelSubcomponent.Builder - - fun inject(factory: FormViewModel.Factory) - - @Component.Builder - interface Builder { - @BindsInstance - fun context(context: Context): Builder - - fun build(): FormViewModelComponent - } -} diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/injection/PaymentOptionsViewModelFactoryComponent.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/injection/PaymentOptionsViewModelFactoryComponent.kt index 34ea47e2ecc..4ce663c3eaf 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/injection/PaymentOptionsViewModelFactoryComponent.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/injection/PaymentOptionsViewModelFactoryComponent.kt @@ -6,6 +6,7 @@ import com.stripe.android.core.injection.CoroutineContextModule import com.stripe.android.payments.core.injection.PRODUCT_USAGE import com.stripe.android.payments.core.injection.StripeRepositoryModule import com.stripe.android.paymentsheet.PaymentOptionsViewModel +import com.stripe.android.paymentsheet.forms.FormViewModel import com.stripe.android.ui.core.forms.resources.injection.ResourceRepositoryModule import dagger.BindsInstance import dagger.Component @@ -25,6 +26,7 @@ import javax.inject.Singleton ) internal interface PaymentOptionsViewModelFactoryComponent { fun inject(factory: PaymentOptionsViewModel.Factory) + fun inject(factory: FormViewModel.Factory) @Component.Builder interface Builder { diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/injection/PaymentOptionsViewModelModule.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/injection/PaymentOptionsViewModelModule.kt index 7f850423ddc..8aa7d24619f 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/injection/PaymentOptionsViewModelModule.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/injection/PaymentOptionsViewModelModule.kt @@ -15,7 +15,10 @@ import javax.inject.Singleton import kotlin.coroutines.CoroutineContext @Module( - subcomponents = [PaymentOptionsViewModelSubcomponent::class] + subcomponents = [ + PaymentOptionsViewModelSubcomponent::class, + FormViewModelSubcomponent::class + ] ) internal class PaymentOptionsViewModelModule { diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/paymentdatacollection/FormFragmentArguments.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/paymentdatacollection/FormFragmentArguments.kt index b794a394f68..11913945b27 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/paymentdatacollection/FormFragmentArguments.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/paymentdatacollection/FormFragmentArguments.kt @@ -1,7 +1,6 @@ package com.stripe.android.paymentsheet.paymentdatacollection import android.os.Parcelable -import com.stripe.android.core.injection.InjectorKey import com.stripe.android.model.PaymentMethodCode import com.stripe.android.model.PaymentMethodCreateParams import com.stripe.android.paymentsheet.PaymentSheet @@ -20,7 +19,6 @@ internal data class FormFragmentArguments( val amount: Amount? = null, val billingDetails: PaymentSheet.BillingDetails? = null, val shippingDetails: AddressDetails? = null, - @InjectorKey val injectorKey: String, val initialPaymentMethodCreateParams: PaymentMethodCreateParams? = null ) : Parcelable diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/PaymentMethodForm.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/PaymentMethodForm.kt index fde59f708ec..a885ba3ec22 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/PaymentMethodForm.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/ui/PaymentMethodForm.kt @@ -5,12 +5,12 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import androidx.lifecycle.viewmodel.compose.viewModel import com.stripe.android.paymentsheet.forms.FormFieldValues import com.stripe.android.paymentsheet.forms.FormViewModel import com.stripe.android.paymentsheet.paymentdatacollection.FormFragmentArguments import com.stripe.android.ui.core.FormUI +import com.stripe.android.ui.core.injection.NonFallbackInjector import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.Flow @@ -21,15 +21,15 @@ internal fun PaymentMethodForm( enabled: Boolean, onFormFieldValuesChanged: (FormFieldValues?) -> Unit, showCheckboxFlow: Flow, + injector: NonFallbackInjector, modifier: Modifier = Modifier ) { - val context = LocalContext.current val formViewModel: FormViewModel = viewModel( key = args.paymentMethodCode, factory = FormViewModel.Factory( config = args, showCheckboxFlow = showCheckboxFlow, - contextSupplier = { context } + injector = injector ) ) diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/viewmodels/BaseSheetViewModel.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/viewmodels/BaseSheetViewModel.kt index 8bc9e135f70..d629e7a2096 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/viewmodels/BaseSheetViewModel.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/viewmodels/BaseSheetViewModel.kt @@ -44,6 +44,7 @@ import com.stripe.android.ui.core.Amount import com.stripe.android.ui.core.address.AddressRepository import com.stripe.android.ui.core.forms.resources.LpmRepository import com.stripe.android.ui.core.forms.resources.ResourceRepository +import com.stripe.android.ui.core.injection.NonFallbackInjector import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.first @@ -70,6 +71,13 @@ internal abstract class BaseSheetViewModel( val savedStateHandle: SavedStateHandle, val linkLauncher: LinkPaymentLauncher ) : AndroidViewModel(application) { + /** + * This ViewModel exists during the whole user flow, and needs to share the Dagger dependencies + * with the other, screen-specific ViewModels. So it holds a reference to the injector which is + * passed as a parameter to the other ViewModel factories. + */ + lateinit var injector: NonFallbackInjector + internal val customerConfig = config?.customer internal val merchantName = config?.merchantDisplayName ?: application.applicationInfo.loadLabel(application.packageManager).toString() diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsActivityTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsActivityTest.kt index af38cf4a195..a88dd573f03 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsActivityTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsActivityTest.kt @@ -18,7 +18,6 @@ import com.stripe.android.R import com.stripe.android.core.Logger import com.stripe.android.core.injection.DUMMY_INJECTOR_KEY import com.stripe.android.core.injection.Injectable -import com.stripe.android.core.injection.Injector import com.stripe.android.core.injection.WeakMapInjectorRegistry import com.stripe.android.link.LinkPaymentLauncher import com.stripe.android.link.model.AccountStatus @@ -44,6 +43,7 @@ import com.stripe.android.ui.core.elements.SaveForFutureUseSpec import com.stripe.android.ui.core.forms.resources.LpmRepository import com.stripe.android.ui.core.forms.resources.StaticAddressResourceRepository import com.stripe.android.ui.core.forms.resources.StaticLpmResourceRepository +import com.stripe.android.ui.core.injection.NonFallbackInjector import com.stripe.android.utils.InjectableActivityScenario import com.stripe.android.utils.TestUtils.idleLooper import com.stripe.android.utils.TestUtils.viewModelFactoryFor @@ -76,7 +76,7 @@ internal class PaymentOptionsActivityTest { private val testDispatcher = UnconfinedTestDispatcher() private val eventReporter = mock() - private lateinit var injector: Injector + private lateinit var injector: NonFallbackInjector private val addressRepository = AddressRepository(context.resources) private val lpmRepository = mock().apply { whenever(fromCode(any())).thenReturn( @@ -519,7 +519,9 @@ internal class PaymentOptionsActivityTest { addressResourceRepository = StaticAddressResourceRepository(addressRepository), savedStateHandle = SavedStateHandle(), linkLauncher = linkPaymentLauncher - ) + ).also { + it.injector = injector + } } fun registerFormViewModelInjector() { @@ -531,7 +533,6 @@ internal class PaymentOptionsActivityTest { showCheckboxControlledFields = true, merchantName = "Merchant, Inc.", amount = Amount(50, "USD"), - injectorKey = "injectorTestKeyFormFragmentArgumentTest", initialPaymentMethodCreateParams = null ), lpmResourceRepository = StaticLpmResourceRepository(lpmRepository), @@ -549,13 +550,12 @@ internal class PaymentOptionsActivityTest { whenever(mockFormSubcomponent.viewModel).thenReturn(formViewModel) whenever(mockFormSubComponentBuilderProvider.get()).thenReturn(mockFormBuilder) - injector = object : Injector { + injector = object : NonFallbackInjector { override fun inject(injectable: Injectable<*>) { (injectable as? FormViewModel.Factory)?.let { injectable.subComponentBuilderProvider = mockFormSubComponentBuilderProvider } } } - WeakMapInjectorRegistry.register(injector, DUMMY_INJECTOR_KEY) } } diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsViewModelTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsViewModelTest.kt index 2d69ddc6441..c02b605273b 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsViewModelTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsViewModelTest.kt @@ -33,7 +33,6 @@ import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.robolectric.RobolectricTestRunner -import kotlin.test.Ignore import kotlin.test.Test @ExperimentalCoroutinesApi @@ -232,7 +231,6 @@ internal class PaymentOptionsViewModelTest { } @Test - @Ignore("Disabled until Link is enabled") fun `setupLink() selects Link when account status is Verified`() = runTest { whenever(linkLauncher.getAccountStatusFlow(any())).thenReturn(flowOf(AccountStatus.Verified)) val viewModel = createViewModel() @@ -245,7 +243,6 @@ internal class PaymentOptionsViewModelTest { } @Test - @Ignore("Disabled until Link is enabled") fun `setupLink() selects Link when account status is VerificationStarted`() = runTest { whenever(linkLauncher.getAccountStatusFlow(any())).thenReturn(flowOf(AccountStatus.VerificationStarted)) val viewModel = createViewModel() @@ -258,7 +255,6 @@ internal class PaymentOptionsViewModelTest { } @Test - @Ignore("Disabled until Link is enabled") fun `setupLink() selects Link when account status is NeedsVerification`() = runTest { whenever(linkLauncher.getAccountStatusFlow(any())).thenReturn(flowOf(AccountStatus.NeedsVerification)) val viewModel = createViewModel() @@ -271,7 +267,6 @@ internal class PaymentOptionsViewModelTest { } @Test - @Ignore("Disabled until Link is enabled") fun `setupLink() enables Link when account status is SignedOut`() = runTest { whenever(linkLauncher.getAccountStatusFlow(any())).thenReturn(flowOf(AccountStatus.SignedOut)) val viewModel = createViewModel() diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsViewModelTestInjection.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsViewModelTestInjection.kt index ce1425dd90f..dacd084e828 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsViewModelTestInjection.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentOptionsViewModelTestInjection.kt @@ -24,6 +24,7 @@ import com.stripe.android.ui.core.address.AddressRepository import com.stripe.android.ui.core.forms.resources.LpmRepository import com.stripe.android.ui.core.forms.resources.StaticAddressResourceRepository import com.stripe.android.ui.core.forms.resources.StaticLpmResourceRepository +import com.stripe.android.ui.core.injection.NonFallbackInjector import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.flowOf @@ -64,7 +65,13 @@ internal open class PaymentOptionsViewModelTestInjection { ): PaymentOptionsViewModel = runBlocking { val lpmRepository = LpmRepository(LpmRepository.LpmRepositoryArguments(ApplicationProvider.getApplicationContext().resources)) - lpmRepository.forceUpdate(listOf(PaymentMethod.Type.Card.code, PaymentMethod.Type.USBankAccount.code), null) + lpmRepository.forceUpdate( + listOf( + PaymentMethod.Type.Card.code, + PaymentMethod.Type.USBankAccount.code + ), + null + ) PaymentOptionsViewModel( args, prefsRepositoryFactory = { @@ -100,7 +107,6 @@ internal open class PaymentOptionsViewModelTestInjection { showCheckboxControlledFields = true, merchantName = "Merchant, Inc.", amount = Amount(50, "USD"), - injectorKey = "injectorTestKeyFormFragmentArgumentTest", initialPaymentMethodCreateParams = null ), lpmResourceRepository = StaticLpmResourceRepository(lpmRepository), @@ -110,7 +116,8 @@ internal open class PaymentOptionsViewModelTestInjection { ) { val mockBuilder = mock() val mockSubcomponent = mock() - val mockSubComponentBuilderProvider = mock>() + val mockSubComponentBuilderProvider = + mock>() whenever(mockBuilder.build()).thenReturn(mockSubcomponent) whenever(mockBuilder.savedStateHandle(any())).thenReturn(mockBuilder) whenever(mockBuilder.application(any())).thenReturn(mockBuilder) @@ -120,13 +127,14 @@ internal open class PaymentOptionsViewModelTestInjection { val mockFormBuilder = mock() val mockFormSubcomponent = mock() - val mockFormSubComponentBuilderProvider = mock>() + val mockFormSubComponentBuilderProvider = + mock>() whenever(mockFormBuilder.build()).thenReturn(mockFormSubcomponent) whenever(mockFormBuilder.formFragmentArguments(any())).thenReturn(mockFormBuilder) whenever(mockFormSubcomponent.viewModel).thenReturn(formViewModel) whenever(mockFormSubComponentBuilderProvider.get()).thenReturn(mockFormBuilder) - injector = object : Injector { + injector = object : NonFallbackInjector { override fun inject(injectable: Injectable<*>) { (injectable as? PaymentOptionsViewModel.Factory)?.let { injectable.subComponentBuilderProvider = mockSubComponentBuilderProvider diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetActivityTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetActivityTest.kt index 0204d430859..2978b8eb39f 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetActivityTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetActivityTest.kt @@ -15,7 +15,6 @@ import com.stripe.android.PaymentConfiguration import com.stripe.android.core.Logger import com.stripe.android.core.injection.DUMMY_INJECTOR_KEY import com.stripe.android.core.injection.Injectable -import com.stripe.android.core.injection.Injector import com.stripe.android.core.injection.WeakMapInjectorRegistry import com.stripe.android.googlepaylauncher.GooglePayPaymentMethodLauncher import com.stripe.android.googlepaylauncher.GooglePayPaymentMethodLauncherContract @@ -59,6 +58,7 @@ import com.stripe.android.ui.core.elements.SaveForFutureUseSpec import com.stripe.android.ui.core.forms.resources.LpmRepository import com.stripe.android.ui.core.forms.resources.StaticAddressResourceRepository import com.stripe.android.ui.core.forms.resources.StaticLpmResourceRepository +import com.stripe.android.ui.core.injection.NonFallbackInjector import com.stripe.android.utils.InjectableActivityScenario import com.stripe.android.utils.TestUtils.getOrAwaitValue import com.stripe.android.utils.TestUtils.idleLooper @@ -96,7 +96,7 @@ internal class PaymentSheetActivityTest { private val context = ApplicationProvider.getApplicationContext() private val testDispatcher = UnconfinedTestDispatcher() - private lateinit var injector: Injector + private lateinit var injector: NonFallbackInjector private val eventReporter = mock() private val googlePayPaymentMethodLauncherFactory = @@ -1070,7 +1070,9 @@ internal class PaymentSheetActivityTest { DUMMY_INJECTOR_KEY, savedStateHandle = SavedStateHandle(), linkLauncher = linkPaymentLauncher - ) + ).also { + it.injector = injector + } } private fun createGooglePayPaymentMethodLauncherFactory() = @@ -1114,7 +1116,6 @@ internal class PaymentSheetActivityTest { showCheckboxControlledFields = true, merchantName = "Merchant, Inc.", amount = Amount(50, "USD"), - injectorKey = "injectorTestKeyFormFragmentArgumentTest", initialPaymentMethodCreateParams = null ), lpmResourceRepository = StaticLpmResourceRepository(lpmRepository), @@ -1132,14 +1133,12 @@ internal class PaymentSheetActivityTest { whenever(mockFormSubcomponent.viewModel).thenReturn(formViewModel) whenever(mockFormSubComponentBuilderProvider.get()).thenReturn(mockFormBuilder) - injector = object : Injector { + injector = object : NonFallbackInjector { override fun inject(injectable: Injectable<*>) { - (injectable as? FormViewModel.Factory)?.let { - injectable.subComponentBuilderProvider = mockFormSubComponentBuilderProvider - } + (injectable as FormViewModel.Factory).subComponentBuilderProvider = + mockFormSubComponentBuilderProvider } } - WeakMapInjectorRegistry.register(injector, DUMMY_INJECTOR_KEY) } private companion object { diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetFixtures.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetFixtures.kt index 823ec40acc9..8350e25ac4d 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetFixtures.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetFixtures.kt @@ -145,7 +145,6 @@ internal object PaymentSheetFixtures { email = "email", name = "Jenny Rosen", phone = "+18008675309" - ), - injectorKey = DUMMY_INJECTOR_KEY + ) ) } diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTest.kt index a7ddb647768..71ed43f99aa 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTest.kt @@ -57,7 +57,6 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.runTest -import org.junit.Ignore import org.junit.Rule import org.junit.runner.RunWith import org.mockito.ArgumentCaptor @@ -90,18 +89,19 @@ internal class PaymentSheetViewModelTest { private val eventReporter = mock() private val viewModel: PaymentSheetViewModel by lazy { createViewModel() } private val application = ApplicationProvider.getApplicationContext() - private val lpmRepository = LpmRepository(LpmRepository.LpmRepositoryArguments(application.resources)).apply { - this.forceUpdate( - listOf( - PaymentMethod.Type.Card.code, - PaymentMethod.Type.USBankAccount.code, - PaymentMethod.Type.Ideal.code, - PaymentMethod.Type.SepaDebit.code, - PaymentMethod.Type.Sofort.code - ), - null - ) - } + private val lpmRepository = + LpmRepository(LpmRepository.LpmRepositoryArguments(application.resources)).apply { + this.forceUpdate( + listOf( + PaymentMethod.Type.Card.code, + PaymentMethod.Type.USBankAccount.code, + PaymentMethod.Type.Ideal.code, + PaymentMethod.Type.SepaDebit.code, + PaymentMethod.Type.Sofort.code + ), + null + ) + } private val prefsRepository = FakePrefsRepository() private val lpmResourceRepository = StaticLpmResourceRepository(lpmRepository) private val linkLauncher = mock() @@ -423,7 +423,6 @@ internal class PaymentSheetViewModelTest { } @Test - @Ignore("Disabled until Link is enabled") fun `setupLink() launches Link when account status is Verified`() = runTest { whenever(linkLauncher.getAccountStatusFlow(any())).thenReturn(flowOf(AccountStatus.Verified)) val viewModel = createViewModel() @@ -437,7 +436,6 @@ internal class PaymentSheetViewModelTest { } @Test - @Ignore("Disabled until Link is enabled") fun `setupLink() starts verification when account status is NeedsVerification`() = runTest { whenever(linkLauncher.getAccountStatusFlow(any())).thenReturn(flowOf(AccountStatus.NeedsVerification)) val viewModel = createViewModel() @@ -450,7 +448,6 @@ internal class PaymentSheetViewModelTest { } @Test - @Ignore("Disabled until Link is enabled") fun `setupLink() starts verification when account status is VerificationStarted`() = runTest { whenever(linkLauncher.getAccountStatusFlow(any())).thenReturn(flowOf(AccountStatus.VerificationStarted)) val viewModel = createViewModel() @@ -463,7 +460,6 @@ internal class PaymentSheetViewModelTest { } @Test - @Ignore("Disabled until Link is enabled") fun `setupLink() enables Link when account status is SignedOut`() = runTest { whenever(linkLauncher.getAccountStatusFlow(any())).thenReturn(flowOf(AccountStatus.SignedOut)) val viewModel = createViewModel() diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTestInjection.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTestInjection.kt index 1b82df5aac7..e5d7d273301 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTestInjection.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetViewModelTestInjection.kt @@ -10,7 +10,6 @@ import com.stripe.android.ApiKeyFixtures import com.stripe.android.PaymentConfiguration import com.stripe.android.core.Logger import com.stripe.android.core.injection.Injectable -import com.stripe.android.core.injection.Injector import com.stripe.android.core.injection.InjectorKey import com.stripe.android.core.injection.WeakMapInjectorRegistry import com.stripe.android.googlepaylauncher.GooglePayPaymentMethodLauncher @@ -32,6 +31,7 @@ import com.stripe.android.ui.core.address.AddressRepository import com.stripe.android.ui.core.forms.resources.LpmRepository import com.stripe.android.ui.core.forms.resources.StaticAddressResourceRepository import com.stripe.android.ui.core.forms.resources.StaticLpmResourceRepository +import com.stripe.android.ui.core.injection.NonFallbackInjector import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview @@ -57,7 +57,7 @@ internal open class PaymentSheetViewModelTestInjection { createGooglePayPaymentMethodLauncherFactory() private val stripePaymentLauncherAssistedFactory = mock() - private lateinit var injector: Injector + private lateinit var injector: NonFallbackInjector @After open fun after() { @@ -137,7 +137,6 @@ internal open class PaymentSheetViewModelTestInjection { showCheckboxControlledFields = true, merchantName = "Merchant, Inc.", amount = Amount(50, "USD"), - injectorKey = "injectorTestKeyFormFragmentArgumentTest", initialPaymentMethodCreateParams = null ), lpmResourceRepository = StaticLpmResourceRepository(lpmRepository), @@ -145,7 +144,7 @@ internal open class PaymentSheetViewModelTestInjection { showCheckboxFlow = mock() ) ) { - injector = object : Injector { + injector = object : NonFallbackInjector { override fun inject(injectable: Injectable<*>) { (injectable as? PaymentSheetViewModel.Factory)?.let { val mockBuilder = mock() @@ -174,6 +173,7 @@ internal open class PaymentSheetViewModelTestInjection { } } } + viewModel.injector = injector WeakMapInjectorRegistry.register(injector, injectorKey) } } diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/paymentdatacollection/FormFragmentArgumentsTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/paymentdatacollection/FormFragmentArgumentsTest.kt index b86562a34ec..ed8b275398a 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/paymentdatacollection/FormFragmentArgumentsTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/paymentdatacollection/FormFragmentArgumentsTest.kt @@ -61,7 +61,6 @@ class FormFragmentArgumentsTest { merchantName = "Merchant, Inc.", amount = Amount(50, "USD"), billingDetails = billingDetails, - injectorKey = "injectorTestKeyFormFragmentArgumentTest", initialPaymentMethodCreateParams = paymentMethodCreateParams ) @@ -94,7 +93,6 @@ class FormFragmentArgumentsTest { merchantName = "Merchant, Inc.", amount = Amount(50, "USD"), billingDetails = billingDetails, - injectorKey = "injectorTestKeyFormFragmentArgumentTest", initialPaymentMethodCreateParams = null ) diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/paymentdatacollection/ach/USBankAccountFormViewModelTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/paymentdatacollection/ach/USBankAccountFormViewModelTest.kt index b53491f859d..5fc8909f4d1 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/paymentdatacollection/ach/USBankAccountFormViewModelTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/paymentdatacollection/ach/USBankAccountFormViewModelTest.kt @@ -53,7 +53,6 @@ class USBankAccountFormViewModelTest { showCheckboxControlledFields = false, merchantName = MERCHANT_NAME, amount = Amount(5099, "usd"), - injectorKey = INJECTOR_KEY, billingDetails = PaymentSheet.BillingDetails( name = CUSTOMER_NAME, email = CUSTOMER_EMAIL @@ -86,8 +85,12 @@ class USBankAccountFormViewModelTest { runTest(UnconfinedTestDispatcher()) { val viewModel = createViewModel() - assertThat(viewModel.name.stateIn(viewModel.viewModelScope).value).isEqualTo(CUSTOMER_NAME) - assertThat(viewModel.email.stateIn(viewModel.viewModelScope).value).isEqualTo(CUSTOMER_EMAIL) + assertThat(viewModel.name.stateIn(viewModel.viewModelScope).value).isEqualTo( + CUSTOMER_NAME + ) + assertThat(viewModel.email.stateIn(viewModel.viewModelScope).value).isEqualTo( + CUSTOMER_EMAIL + ) assertThat(viewModel.requiredFields.stateIn(viewModel.viewModelScope).value).isTrue() } @@ -118,7 +121,8 @@ class USBankAccountFormViewModelTest { runTest(UnconfinedTestDispatcher()) { val viewModel = createViewModel() viewModel.collectBankAccountLauncher = collectBankAccountLauncher - val currentScreenState = viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value + val currentScreenState = + viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value assertThat( currentScreenState @@ -140,13 +144,15 @@ class USBankAccountFormViewModelTest { mockUnverifiedBankAccount() ) - val currentScreenState = viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value + val currentScreenState = + viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value assertThat(currentScreenState) .isInstanceOf(USBankAccountFormScreenState.VerifyWithMicrodeposits::class.java) viewModel.handlePrimaryButtonClick(currentScreenState as USBankAccountFormScreenState.VerifyWithMicrodeposits) - val newScreenState = viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value + val newScreenState = + viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value assertThat(newScreenState) .isInstanceOf(USBankAccountFormScreenState.VerifyWithMicrodeposits::class.java) @@ -162,13 +168,15 @@ class USBankAccountFormViewModelTest { mockVerifiedBankAccount() ) - val currentScreenState = viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value + val currentScreenState = + viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value assertThat(currentScreenState) .isInstanceOf(USBankAccountFormScreenState.MandateCollection::class.java) viewModel.handlePrimaryButtonClick(currentScreenState as USBankAccountFormScreenState.MandateCollection) - val newScreenState = viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value + val newScreenState = + viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value assertThat(newScreenState) .isInstanceOf(USBankAccountFormScreenState.MandateCollection::class.java) @@ -183,17 +191,20 @@ class USBankAccountFormViewModelTest { viewModel.handleCollectBankAccountResult(bankAccount) - val currentScreenState = viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value + val currentScreenState = + viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value assertThat(currentScreenState) .isInstanceOf(USBankAccountFormScreenState.VerifyWithMicrodeposits::class.java) viewModel.handlePrimaryButtonClick(currentScreenState as USBankAccountFormScreenState.VerifyWithMicrodeposits) - val newScreenState = viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value + val newScreenState = + viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value assertThat(newScreenState) .isInstanceOf(USBankAccountFormScreenState.VerifyWithMicrodeposits::class.java) - val session = (bankAccount as CollectBankAccountResult.Completed).response.financialConnectionsSession + val session = + (bankAccount as CollectBankAccountResult.Completed).response.financialConnectionsSession val expectedBankAccount = session.paymentAccount as BankAccount val argumentCaptor = argumentCaptor() @@ -211,17 +222,20 @@ class USBankAccountFormViewModelTest { viewModel.handleCollectBankAccountResult(bankAccount) - val currentScreenState = viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value + val currentScreenState = + viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value assertThat(currentScreenState) .isInstanceOf(USBankAccountFormScreenState.MandateCollection::class.java) viewModel.handlePrimaryButtonClick(currentScreenState as USBankAccountFormScreenState.MandateCollection) - val newScreenState = viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value + val newScreenState = + viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value assertThat(newScreenState) .isInstanceOf(USBankAccountFormScreenState.MandateCollection::class.java) - val session = (bankAccount as CollectBankAccountResult.Completed).response.financialConnectionsSession + val session = + (bankAccount as CollectBankAccountResult.Completed).response.financialConnectionsSession val expectedBankAccount = session.paymentAccount as FinancialConnectionsAccount val argumentCaptor = argumentCaptor() @@ -238,7 +252,8 @@ class USBankAccountFormViewModelTest { viewModel.collectBankAccountLauncher = collectBankAccountLauncher viewModel.reset() - val currentScreenState = viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value + val currentScreenState = + viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value viewModel.handlePrimaryButtonClick(currentScreenState as USBankAccountFormScreenState.NameAndEmailCollection) @@ -253,11 +268,19 @@ class USBankAccountFormViewModelTest { viewModel.saveForFutureUseElement.controller.onValueChange(false) - assertThat(viewModel.saveForFutureUseElement.controller.saveForFutureUse.stateIn(viewModel.viewModelScope).value).isFalse() + assertThat( + viewModel.saveForFutureUseElement.controller.saveForFutureUse.stateIn( + viewModel.viewModelScope + ).value + ).isFalse() viewModel.reset() - assertThat(viewModel.saveForFutureUseElement.controller.saveForFutureUse.stateIn(viewModel.viewModelScope).value).isTrue() + assertThat( + viewModel.saveForFutureUseElement.controller.saveForFutureUse.stateIn( + viewModel.viewModelScope + ).value + ).isTrue() } } @@ -279,7 +302,8 @@ class USBankAccountFormViewModelTest { ) ) - val currentScreenState = viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value + val currentScreenState = + viewModel.currentScreenState.stateIn(viewModel.viewModelScope).value assertThat( currentScreenState @@ -318,7 +342,13 @@ class USBankAccountFormViewModelTest { ) ) whenever( - stripeRepository.attachFinancialConnectionsSessionToPaymentIntent(any(), any(), any(), any(), any()) + stripeRepository.attachFinancialConnectionsSessionToPaymentIntent( + any(), + any(), + any(), + any(), + any() + ) ).thenReturn(paymentIntent) return CollectBankAccountResult.Completed( @@ -345,7 +375,13 @@ class USBankAccountFormViewModelTest { ) ) whenever( - stripeRepository.attachFinancialConnectionsSessionToPaymentIntent(any(), any(), any(), any(), any()) + stripeRepository.attachFinancialConnectionsSessionToPaymentIntent( + any(), + any(), + any(), + any(), + any() + ) ).thenReturn(paymentIntent) return CollectBankAccountResult.Completed( @@ -357,7 +393,6 @@ class USBankAccountFormViewModelTest { } private companion object { - const val INJECTOR_KEY = "injectorKey" const val MERCHANT_NAME = "merchantName" const val CUSTOMER_NAME = "Jenny Rose" const val CUSTOMER_EMAIL = "email@email.com" From 71a45faa33b75f535cb98392ad1a4845c5974d6d Mon Sep 17 00:00:00 2001 From: brnunes-stripe Date: Mon, 24 Oct 2022 14:39:48 -0700 Subject: [PATCH 2/2] injectorkey --- config/detekt/detekt.yml | 4 ++-- .../android/paymentsheet/BaseAddPaymentMethodFragment.kt | 3 --- .../paymentsheet/PaymentSheetAddPaymentMethodFragmentTest.kt | 2 -- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 4043a4e6a4a..669247a51df 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -42,7 +42,7 @@ console-reports: output-reports: active: true - exclude: +# exclude: # - 'TxtOutputReport' # - 'XmlOutputReport' # - 'HtmlOutputReport' @@ -150,7 +150,7 @@ complexity: thresholdInObjects: 11 thresholdInEnums: 11 ignoreDeprecated: false - ignorePrivate: false + ignorePrivate: true ignoreOverridden: false coroutines: diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BaseAddPaymentMethodFragment.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BaseAddPaymentMethodFragment.kt index 6bfca5232b9..f026b0930eb 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BaseAddPaymentMethodFragment.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/BaseAddPaymentMethodFragment.kt @@ -24,7 +24,6 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidViewBinding import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider -import com.stripe.android.core.injection.InjectorKey import com.stripe.android.link.LinkPaymentLauncher import com.stripe.android.link.model.AccountStatus import com.stripe.android.link.ui.inline.InlineSignupViewState @@ -325,7 +324,6 @@ internal abstract class BaseAddPaymentMethodFragment : Fragment() { config = sheetViewModel.config, merchantName = sheetViewModel.merchantName, amount = sheetViewModel.amount.value, - injectorKey = sheetViewModel.injectorKey, newLpm = sheetViewModel.newPaymentSelection, isShowingLinkInlineSignup = showLinkInlineSignup ) @@ -373,7 +371,6 @@ internal abstract class BaseAddPaymentMethodFragment : Fragment() { config: PaymentSheet.Configuration?, merchantName: String, amount: Amount? = null, - @InjectorKey injectorKey: String, newLpm: PaymentSelection.New?, isShowingLinkInlineSignup: Boolean = false ): FormFragmentArguments { diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetAddPaymentMethodFragmentTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetAddPaymentMethodFragmentTest.kt index 69d3b2dc551..43639deca18 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetAddPaymentMethodFragmentTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/PaymentSheetAddPaymentMethodFragmentTest.kt @@ -85,7 +85,6 @@ internal class PaymentSheetAddPaymentMethodFragmentTest : PaymentSheetViewModelT CONFIG_MINIMUM, MERCHANT_DISPLAY_NAME, Amount(50, "USD"), - "testInjectorKey", PaymentSelection.New.GenericPaymentMethod( context.getString(R.string.stripe_paymentsheet_payment_method_bancontact), R.drawable.stripe_ic_paymentsheet_pm_bancontact, @@ -150,7 +149,6 @@ internal class PaymentSheetAddPaymentMethodFragmentTest : PaymentSheetViewModelT CONFIG_MINIMUM, MERCHANT_DISPLAY_NAME, Amount(50, "USD"), - "testInjectorKey", PaymentSelection.New.Card( paymentMethodCreateParams, CardBrand.Visa,