Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FC] Unify sync API calls and add refetch strategy #8317

Merged
merged 7 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ import com.stripe.android.financialconnections.di.APPLICATION_ID
import com.stripe.android.financialconnections.di.DaggerFinancialConnectionsSheetComponent
import com.stripe.android.financialconnections.domain.FetchFinancialConnectionsSession
import com.stripe.android.financialconnections.domain.FetchFinancialConnectionsSessionForToken
import com.stripe.android.financialconnections.domain.GetOrFetchSync
import com.stripe.android.financialconnections.domain.GetOrFetchSync.RefetchCondition.Always
import com.stripe.android.financialconnections.domain.NativeAuthFlowCoordinator
import com.stripe.android.financialconnections.domain.NativeAuthFlowRouter
import com.stripe.android.financialconnections.domain.SynchronizeFinancialConnectionsSession
import com.stripe.android.financialconnections.exception.AppInitializationError
import com.stripe.android.financialconnections.exception.CustomManualEntryRequiredError
import com.stripe.android.financialconnections.features.manualentry.isCustomManualEntryError
Expand Down Expand Up @@ -62,7 +63,7 @@ import javax.inject.Named
internal class FinancialConnectionsSheetViewModel @Inject constructor(
@Named(APPLICATION_ID) private val applicationId: String,
savedStateHandle: SavedStateHandle,
private val synchronizeFinancialConnectionsSession: SynchronizeFinancialConnectionsSession,
private val getOrFetchSync: GetOrFetchSync,
private val fetchFinancialConnectionsSession: FetchFinancialConnectionsSession,
private val fetchFinancialConnectionsSessionForToken: FetchFinancialConnectionsSessionForToken,
private val logger: Logger,
Expand Down Expand Up @@ -106,7 +107,7 @@ internal class FinancialConnectionsSheetViewModel @Inject constructor(
private fun fetchManifest() {
viewModelScope.launch {
kotlin.runCatching {
synchronizeFinancialConnectionsSession()
getOrFetchSync(refetchCondition = Always)
}.onFailure {
finishWithResult(stateFlow.value, Failed(it))
}.onSuccess {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.stripe.android.financialconnections.FinancialConnections
import com.stripe.android.financialconnections.FinancialConnectionsSheet
import com.stripe.android.financialconnections.analytics.FinancialConnectionsEvent.ErrorCode
import com.stripe.android.financialconnections.analytics.FinancialConnectionsResponseEventEmitter.Companion.EVENTS_TO_EMIT
import com.stripe.android.financialconnections.domain.GetManifest
import com.stripe.android.financialconnections.domain.GetOrFetchSync
import com.stripe.android.financialconnections.exception.AppInitializationError
import com.stripe.android.financialconnections.model.FinancialConnectionsSessionManifest.Pane
import kotlinx.coroutines.DelicateCoroutinesApi
Expand Down Expand Up @@ -81,7 +81,7 @@ private fun emitPublicClientErrorEventIfNeeded(error: Throwable) {
}

internal class FinancialConnectionsAnalyticsTrackerImpl(
private val getManifest: GetManifest,
private val getOrFetchSync: GetOrFetchSync,
private val configuration: FinancialConnectionsSheet.Configuration,
private val locale: Locale,
context: Context,
Expand All @@ -107,7 +107,7 @@ internal class FinancialConnectionsAnalyticsTrackerImpl(
}

private suspend fun commonParams(): Map<String, String?> {
val manifest = getManifest()
val manifest = getOrFetchSync().manifest
return mapOf(
"las_client_secret" to configuration.financialConnectionsSessionClientSecret,
// "las_creator_client_secret": this.linkAccountSessionCreatorClientSecret,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import com.stripe.android.financialconnections.analytics.DefaultFinancialConnect
import com.stripe.android.financialconnections.analytics.FinancialConnectionsAnalyticsTracker
import com.stripe.android.financialconnections.analytics.FinancialConnectionsAnalyticsTrackerImpl
import com.stripe.android.financialconnections.analytics.FinancialConnectionsEventReporter
import com.stripe.android.financialconnections.domain.GetManifest
import com.stripe.android.financialconnections.domain.GetOrFetchSync
import com.stripe.android.financialconnections.features.common.enableWorkManager
import com.stripe.android.financialconnections.repository.FinancialConnectionsRepository
import com.stripe.android.financialconnections.repository.FinancialConnectionsRepositoryImpl
Expand Down Expand Up @@ -95,14 +95,14 @@ internal interface FinancialConnectionsSheetSharedModule {
@Provides
fun providesAnalyticsTracker(
context: Application,
getManifest: GetManifest,
getOrFetchSync: GetOrFetchSync,
locale: Locale?,
configuration: FinancialConnectionsSheet.Configuration,
requestExecutor: AnalyticsRequestV2Executor,
): FinancialConnectionsAnalyticsTracker = FinancialConnectionsAnalyticsTrackerImpl(
context = context,
configuration = configuration,
getManifest = getManifest,
getOrFetchSync = getOrFetchSync,
locale = locale ?: Locale.getDefault(),
requestExecutor = requestExecutor,
)
Expand Down Expand Up @@ -149,10 +149,10 @@ internal interface FinancialConnectionsSheetSharedModule {
@Provides
@Singleton
internal fun providesIsWorkManagerAvailable(
getManifest: GetManifest,
getOrFetchSync: GetOrFetchSync,
): IsWorkManagerAvailable {
return RealIsWorkManagerAvailable(
isEnabledForMerchant = { getManifest().enableWorkManager() },
isEnabledForMerchant = { getOrFetchSync().manifest.enableWorkManager() },
)
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,44 @@ internal class GetOrFetchSync @Inject constructor(
@Named(APPLICATION_ID) private val applicationId: String,
) {

suspend operator fun invoke(): SynchronizeSessionResponse {
return repository.getOrFetchSynchronizeFinancialConnectionsSession(
suspend operator fun invoke(
refetchCondition: RefetchCondition = RefetchCondition.None
): SynchronizeSessionResponse {
return repository.getOrSynchronizeFinancialConnectionsSession(
clientSecret = configuration.financialConnectionsSessionClientSecret,
applicationId = applicationId
applicationId = applicationId,
reFetchCondition = refetchCondition::shouldReFetch,
)
}

sealed interface RefetchCondition {
fun shouldReFetch(response: SynchronizeSessionResponse): Boolean

/**
* Session won't be re-fetched if it's already cached.
*/
data object None : RefetchCondition {
override fun shouldReFetch(response: SynchronizeSessionResponse): Boolean {
return false
}
}

/**
* Session will always be fetched, even if a cached version exists.
*/
data object Always : RefetchCondition {
override fun shouldReFetch(response: SynchronizeSessionResponse): Boolean {
return true
}
}

/**
* Session will be fetched only if there's no active auth session on the cached manifest.
*/
data object IfMissingActiveAuthSession : RefetchCondition {
override fun shouldReFetch(response: SynchronizeSessionResponse): Boolean {
return response.manifest.activeAuthSession == null
}
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.stripe.android.core.Logger
import com.stripe.android.financialconnections.analytics.FinancialConnectionsAnalyticsTracker
import com.stripe.android.financialconnections.analytics.logError
import com.stripe.android.financialconnections.di.FinancialConnectionsSheetNativeComponent
import com.stripe.android.financialconnections.domain.GetManifest
import com.stripe.android.financialconnections.domain.GetOrFetchSync
import com.stripe.android.financialconnections.domain.NativeAuthFlowCoordinator
import com.stripe.android.financialconnections.domain.NativeAuthFlowCoordinator.Message
import com.stripe.android.financialconnections.model.FinancialConnectionsSessionManifest.Pane
Expand All @@ -29,7 +29,7 @@ import kotlinx.coroutines.launch
internal class ErrorViewModel @AssistedInject constructor(
@Assisted initialState: ErrorState,
private val coordinator: NativeAuthFlowCoordinator,
private val getManifest: GetManifest,
private val getOrFetchSync: GetOrFetchSync,
private val errorRepository: FinancialConnectionsErrorRepository,
private val eventTracker: FinancialConnectionsAnalyticsTracker,
private val navigationManager: NavigationManager,
Expand All @@ -42,10 +42,11 @@ internal class ErrorViewModel @AssistedInject constructor(
// Clear the partner web auth state if it exists, so that if the user lands back in the partner_auth
// pane after an error, they will be able to start over.
coordinator().emit(Message.ClearPartnerWebAuth)
val manifest = getOrFetchSync().manifest
ErrorState.Payload(
error = requireNotNull(errorRepository.get()?.error),
disableLinkMoreAccounts = getManifest().disableLinkMoreAccounts,
allowManualEntry = getManifest().allowManualEntry
disableLinkMoreAccounts = manifest.disableLinkMoreAccounts,
allowManualEntry = manifest.allowManualEntry
)
}.execute { copy(payload = it) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.stripe.android.financialconnections.R
import com.stripe.android.financialconnections.analytics.FinancialConnectionsAnalyticsTracker
import com.stripe.android.financialconnections.analytics.logError
import com.stripe.android.financialconnections.di.FinancialConnectionsSheetNativeComponent
import com.stripe.android.financialconnections.domain.GetManifest
import com.stripe.android.financialconnections.domain.GetOrFetchSync
import com.stripe.android.financialconnections.domain.NativeAuthFlowCoordinator
import com.stripe.android.financialconnections.domain.NativeAuthFlowCoordinator.Message
import com.stripe.android.financialconnections.features.common.getBusinessName
Expand All @@ -29,7 +29,7 @@ import kotlinx.coroutines.launch
internal class ExitViewModel @AssistedInject constructor(
@Assisted initialState: ExitState,
nativeAuthFlowCoordinator: NativeAuthFlowCoordinator,
private val getManifest: GetManifest,
private val getOrFetchSync: GetOrFetchSync,
private val coordinator: NativeAuthFlowCoordinator,
private val eventTracker: FinancialConnectionsAnalyticsTracker,
private val navigationManager: NavigationManager,
Expand All @@ -39,7 +39,7 @@ internal class ExitViewModel @AssistedInject constructor(
init {
logErrors()
suspend {
val manifest = kotlin.runCatching { getManifest() }.getOrNull()
val manifest = kotlin.runCatching { getOrFetchSync().manifest }.getOrNull()
val businessName = manifest?.getBusinessName()
val isNetworkingSignupPane =
manifest?.isNetworkingUserFlow == true && stateFlow.value.referrer == Pane.NETWORKING_LINK_SIGNUP_PANE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import com.stripe.android.financialconnections.analytics.logError
import com.stripe.android.financialconnections.di.FinancialConnectionsSheetNativeComponent
import com.stripe.android.financialconnections.domain.ConfirmVerification
import com.stripe.android.financialconnections.domain.GetCachedAccounts
import com.stripe.android.financialconnections.domain.GetManifest
import com.stripe.android.financialconnections.domain.GetOrFetchSync
import com.stripe.android.financialconnections.domain.LookupConsumerAndStartVerification
import com.stripe.android.financialconnections.domain.MarkLinkStepUpVerified
import com.stripe.android.financialconnections.domain.NativeAuthFlowCoordinator
Expand Down Expand Up @@ -50,7 +50,7 @@ internal class LinkStepUpVerificationViewModel @AssistedInject constructor(
@Assisted initialState: LinkStepUpVerificationState,
nativeAuthFlowCoordinator: NativeAuthFlowCoordinator,
private val eventTracker: FinancialConnectionsAnalyticsTracker,
private val getManifest: GetManifest,
private val getOrFetchSync: GetOrFetchSync,
private val lookupConsumerAndStartVerification: LookupConsumerAndStartVerification,
private val confirmVerification: ConfirmVerification,
private val selectNetworkedAccounts: SelectNetworkedAccounts,
Expand All @@ -74,7 +74,7 @@ internal class LinkStepUpVerificationViewModel @AssistedInject constructor(
}

private suspend fun lookupAndStartVerification() = runCatching {
getManifest().also { requireNotNull(it.accountholderCustomerEmailAddress) }
getOrFetchSync().manifest.also { requireNotNull(it.accountholderCustomerEmailAddress) }
}
.onFailure { setState { copy(payload = Fail(it)) } }
.onSuccess { manifest ->
Expand Down Expand Up @@ -184,7 +184,7 @@ internal class LinkStepUpVerificationViewModel @AssistedInject constructor(
}

private suspend fun onResendOtp() = runCatching {
getManifest().also { requireNotNull(it.accountholderCustomerEmailAddress) }
getOrFetchSync().manifest.also { requireNotNull(it.accountholderCustomerEmailAddress) }
}
.onFailure { setState { copy(resendOtp = Fail(it)) } }
.onSuccess { manifest ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.stripe.android.financialconnections.analytics.FinancialConnectionsAna
import com.stripe.android.financialconnections.analytics.FinancialConnectionsAnalyticsEvent.PaneLoaded
import com.stripe.android.financialconnections.analytics.FinancialConnectionsAnalyticsTracker
import com.stripe.android.financialconnections.di.FinancialConnectionsSheetNativeComponent
import com.stripe.android.financialconnections.domain.GetManifest
import com.stripe.android.financialconnections.domain.GetOrFetchSync
import com.stripe.android.financialconnections.domain.NativeAuthFlowCoordinator
import com.stripe.android.financialconnections.features.success.SuccessState
import com.stripe.android.financialconnections.model.FinancialConnectionsSession
Expand All @@ -27,15 +27,15 @@ import kotlinx.coroutines.launch

internal class ManualEntrySuccessViewModel @AssistedInject constructor(
@Assisted initialState: ManualEntrySuccessState,
private val getManifest: GetManifest,
private val getOrFetchSync: GetOrFetchSync,
private val successContentRepository: SuccessContentRepository,
private val eventTracker: FinancialConnectionsAnalyticsTracker,
private val nativeAuthFlowCoordinator: NativeAuthFlowCoordinator,
) : FinancialConnectionsViewModel<ManualEntrySuccessState>(initialState, nativeAuthFlowCoordinator) {

init {
suspend {
val manifest = getManifest()
val manifest = getOrFetchSync().manifest
SuccessState.Payload(
businessName = manifest.businessName,
customSuccessMessage = successContentRepository.get()?.customSuccessMessage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import com.stripe.android.financialconnections.analytics.FinancialConnectionsAna
import com.stripe.android.financialconnections.analytics.FinancialConnectionsAnalyticsTracker
import com.stripe.android.financialconnections.di.FinancialConnectionsSheetNativeComponent
import com.stripe.android.financialconnections.domain.DisableNetworking
import com.stripe.android.financialconnections.domain.GetManifest
import com.stripe.android.financialconnections.domain.GetOrFetchSync
import com.stripe.android.financialconnections.domain.HandleError
import com.stripe.android.financialconnections.domain.NativeAuthFlowCoordinator
import com.stripe.android.financialconnections.features.common.getBusinessName
Expand All @@ -35,15 +35,15 @@ internal class NetworkingLinkLoginWarmupViewModel @AssistedInject constructor(
nativeAuthFlowCoordinator: NativeAuthFlowCoordinator,
private val eventTracker: FinancialConnectionsAnalyticsTracker,
private val handleError: HandleError,
private val getManifest: GetManifest,
private val getOrFetchSync: GetOrFetchSync,
private val disableNetworking: DisableNetworking,
private val navigationManager: NavigationManager
) : FinancialConnectionsViewModel<NetworkingLinkLoginWarmupState>(initialState, nativeAuthFlowCoordinator) {

init {
logErrors()
suspend {
val manifest = getManifest()
val manifest = getOrFetchSync().manifest
eventTracker.track(PaneLoaded(PANE))
NetworkingLinkLoginWarmupState.Payload(
merchantName = manifest.getBusinessName(),
Expand Down