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

add addon feature flag to moving flow and change tier flow #2365

Merged
merged 1 commit into from
Jan 2, 2025
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
mutation ChangeTierDeductibleCreateIntent($contractId: ID!, $source: ChangeTierDeductibleSource!) {
mutation ChangeTierDeductibleCreateIntent($contractId: ID!,
$source: ChangeTierDeductibleSource!,
$addonsFlagOn: Boolean!) {
changeTierDeductibleCreateIntent(input:{ contractId: $contractId, source: $source }) {
intent {
activationDate
Expand Down Expand Up @@ -34,7 +36,7 @@ mutation ChangeTierDeductibleCreateIntent($contractId: ID!, $source: ChangeTierD
}
tierLevel
tierName
addons {
addons @include(if: $addonsFlagOn) {
addonId
displayName
displayItems {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ internal class CreateChangeTierDeductibleIntentUseCaseImpl(
): Either<ErrorMessage, ChangeTierDeductibleIntent> {
return either {
val isTierEnabled = featureManager.isFeatureEnabled(Feature.TIER).first()
val isAddonFlagEnabled = featureManager.isFeatureEnabled(Feature.TRAVEL_ADDON).first()
if (!isTierEnabled) {
logcat(ERROR) { "Tried to get changeTierQuotes when feature flag is disabled!" }
raise(ErrorMessage())
Expand All @@ -45,6 +46,7 @@ internal class CreateChangeTierDeductibleIntentUseCaseImpl(
ChangeTierDeductibleCreateIntentMutation(
contractId = insuranceId,
source = source.toSource(),
addonsFlagOn = isAddonFlagEnabled,
),
)
.safeExecute()
Expand Down Expand Up @@ -92,7 +94,7 @@ internal class CreateChangeTierDeductibleIntentUseCaseImpl(
tierDescription = it.productVariant.tierDescription,
tierDisplayName = it.productVariant.displayNameTier,
),
addons = it.addons.map { addon ->
addons = it.addons?.map { addon ->
ChangeTierDeductibleAddonQuote(
addonId = addon.addonId,
displayName = addon.displayName,
Expand All @@ -101,7 +103,7 @@ internal class CreateChangeTierDeductibleIntentUseCaseImpl(
premium = UiMoney.fromMoneyFragment(addon.premium),
addonVariant = addon.addonVariant.toAddonVariant(),
)
},
} ?: emptyList(),
)
}
val intentResult = ChangeTierDeductibleIntent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {
operation = ChangeTierDeductibleCreateIntentMutation(
contractId = testId,
source = testSource,
addonsFlagOn = true,
),
errors = listOf(com.apollographql.apollo.api.Error.Builder(message = "Bad message").build()),
)
Expand All @@ -65,6 +66,7 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {
operation = ChangeTierDeductibleCreateIntentMutation(
contractId = testId,
source = testSource,
addonsFlagOn = true,
),
data = ChangeTierDeductibleCreateIntentMutation.Data(OctopusFakeResolver) {
changeTierDeductibleCreateIntent = buildChangeTierDeductibleCreateIntentOutput {
Expand All @@ -81,6 +83,7 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {
operation = ChangeTierDeductibleCreateIntentMutation(
contractId = testId,
source = testSource,
addonsFlagOn = true,
),
data = ChangeTierDeductibleCreateIntentMutation.Data(OctopusFakeResolver) {
changeTierDeductibleCreateIntent = buildChangeTierDeductibleCreateIntentOutput {
Expand Down Expand Up @@ -156,6 +159,7 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {
operation = ChangeTierDeductibleCreateIntentMutation(
contractId = testId,
source = testSource,
addonsFlagOn = true,
),
data = ChangeTierDeductibleCreateIntentMutation.Data(OctopusFakeResolver) {
changeTierDeductibleCreateIntent = buildChangeTierDeductibleCreateIntentOutput {
Expand Down Expand Up @@ -231,6 +235,7 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {
operation = ChangeTierDeductibleCreateIntentMutation(
contractId = testId,
source = testSource,
addonsFlagOn = true,
),
data = ChangeTierDeductibleCreateIntentMutation.Data(OctopusFakeResolver) {
changeTierDeductibleCreateIntent = buildChangeTierDeductibleCreateIntentOutput {
Expand Down Expand Up @@ -277,6 +282,7 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {
operation = ChangeTierDeductibleCreateIntentMutation(
contractId = testId,
source = testSource,
addonsFlagOn = true,
),
data = ChangeTierDeductibleCreateIntentMutation.Data(OctopusFakeResolver) {
changeTierDeductibleCreateIntent = buildChangeTierDeductibleCreateIntentOutput {
Expand Down Expand Up @@ -347,7 +353,7 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {

@Test
fun `when BE response has empty quotes return intent with empty quotes`() = runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to true))
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to true, Feature.TRAVEL_ADDON to true))
val createChangeTierDeductibleIntentUseCase = CreateChangeTierDeductibleIntentUseCaseImpl(
apolloClient = apolloClientWithGoodResponseButEmptyQuotes,
featureManager = featureManager,
Expand All @@ -362,7 +368,12 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {

@Test
fun `when response is fine and tier feature flag is on get a good result`() = runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to true))
val featureManager = FakeFeatureManager2(
fixedMap = mapOf(
Feature.TIER to true,
Feature.TRAVEL_ADDON to true,
),
)
val createChangeTierDeductibleIntentUseCase = CreateChangeTierDeductibleIntentUseCaseImpl(
apolloClient = apolloClientWithGoodResponse,
featureManager = featureManager,
Expand Down Expand Up @@ -390,7 +401,7 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {

@Test
fun `when response is fine but tier feature flag is off the result is ErrorMessage`() = runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to false))
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to false, Feature.TRAVEL_ADDON to true))
val createChangeTierDeductibleIntentUseCase = CreateChangeTierDeductibleIntentUseCaseImpl(
apolloClient = apolloClientWithGoodResponse,
featureManager = featureManager,
Expand All @@ -404,7 +415,7 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {

@Test
fun `when response is bad and tier feature flag is on the result is ErrorMessage`() = runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to true))
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to true, Feature.TRAVEL_ADDON to true))
val createChangeTierDeductibleIntentUseCase = CreateChangeTierDeductibleIntentUseCaseImpl(
apolloClient = apolloClientWithBadResponse,
featureManager = featureManager,
Expand All @@ -418,7 +429,7 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {

@Test
fun `when response is otherwise good but the intent is null the result is ErrorMessage`() = runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to true))
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to true, Feature.TRAVEL_ADDON to true))
val createChangeTierDeductibleIntentUseCase = CreateChangeTierDeductibleIntentUseCaseImpl(
apolloClient = apolloClientWithGoodButNullResponse,
featureManager = featureManager,
Expand All @@ -433,7 +444,7 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {
@Test
fun `when response is otherwise good but the tierName in existing agreement is null the result is ErrorMessage`() =
runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to true))
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to true, Feature.TRAVEL_ADDON to true))
val createChangeTierDeductibleIntentUseCase = CreateChangeTierDeductibleIntentUseCaseImpl(
apolloClient = apolloClientWithGoodResponseButNullTierNameInExisting,
featureManager = featureManager,
Expand All @@ -448,7 +459,7 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {
@Test
fun `when response is otherwise good but the tierName in one of the quotes is null the result is ErrorMessage`() =
runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to true))
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to true, Feature.TRAVEL_ADDON to true))
val createChangeTierDeductibleIntentUseCase = CreateChangeTierDeductibleIntentUseCaseImpl(
apolloClient = apolloClientWithGoodResponseButNullTierNameInOneQuote,
featureManager = featureManager,
Expand All @@ -462,7 +473,7 @@ class CreateChangeTierDeductibleIntentUseCaseImplTest {

@Test
fun `in good response one of the quotes should have the current const id`() = runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to true))
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TIER to true, Feature.TRAVEL_ADDON to true))
val createChangeTierDeductibleIntentUseCase = CreateChangeTierDeductibleIntentUseCaseImpl(
apolloClient = apolloClientWithGoodResponse,
featureManager = featureManager,
Expand Down
3 changes: 3 additions & 0 deletions app/feature/feature-movingflow/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.fir.expressions.builder.buildImplicitInvokeCall

plugins {
id("hedvig.gradle.plugin")
id("hedvig.android.library")
Expand Down Expand Up @@ -39,4 +41,5 @@ dependencies {
implementation(projects.uiTiersAndAddons)
implementation(libs.compose.richtext)
implementation(libs.compose.richtextCommonmark)
implementation(projects.featureFlagsPublic)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
mutation MoveIntentV2Request($intentId: ID!, $moveIntentRequestInput: MoveIntentRequestInput!) {
mutation MoveIntentV2Request($intentId: ID!,
$moveIntentRequestInput: MoveIntentRequestInput!,
$addonsFlagOn: Boolean!) {
moveIntentRequest(intentId: $intentId, input: $moveIntentRequestInput) {
moveIntent {
...MoveIntentQuotesFragment
Expand Down Expand Up @@ -34,7 +36,7 @@ fragment MoveIntentQuotesFragment on MoveIntent {
...ProductVariantFragment
# todo This is not in the fragment, why? -> displayNameSubtype
}
addons {
addons @include(if: $addonsFlagOn) {
...MoveAddonQuoteFragment
}
}
Expand All @@ -50,7 +52,7 @@ fragment MoveIntentQuotesFragment on MoveIntent {
productVariant {
...ProductVariantFragment
}
addons {
addons @include(if: $addonsFlagOn) {
...MoveAddonQuoteFragment
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ internal fun MoveIntentQuotesFragment.toMovingFlowQuotes(): MovingFlowQuotes {
)
},
defaultChoice = houseQuote.defaultChoice,
relatedAddonQuotes = houseQuote.addons.map { addon ->
relatedAddonQuotes = houseQuote.addons?.map { addon ->
MovingFlowQuotes.AddonQuote(
premium = UiMoney.fromMoneyFragment(addon.premium),
startDate = addon.startDate,
Expand All @@ -114,7 +114,7 @@ internal fun MoveIntentQuotesFragment.toMovingFlowQuotes(): MovingFlowQuotes {
},
addonVariant = addon.addonVariant.toAddonVariant(),
)
},
} ?: emptyList(),
)
},
mtaQuotes = (mtaQuotes ?: emptyList()).map { mtaQuote ->
Expand All @@ -124,7 +124,7 @@ internal fun MoveIntentQuotesFragment.toMovingFlowQuotes(): MovingFlowQuotes {
productVariant = mtaQuote.productVariant.toProductVariant(),
startDate = mtaQuote.startDate,
displayItems = mtaQuote.displayItems.map { it.toDisplayItem() },
relatedAddonQuotes = mtaQuote.addons.map { addon ->
relatedAddonQuotes = mtaQuote.addons?.map { addon ->
MovingFlowQuotes.AddonQuote(
premium = UiMoney.fromMoneyFragment(addon.premium),
startDate = addon.startDate,
Expand All @@ -138,7 +138,7 @@ internal fun MoveIntentQuotesFragment.toMovingFlowQuotes(): MovingFlowQuotes {
},
addonVariant = addon.addonVariant.toAddonVariant(),
)
},
} ?: emptyList(),
)
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.hedvig.android.feature.movingflow.ui.chosecoveragelevelanddeductible.
import com.hedvig.android.feature.movingflow.ui.enternewaddress.EnterNewAddressViewModel
import com.hedvig.android.feature.movingflow.ui.start.StartViewModel
import com.hedvig.android.feature.movingflow.ui.summary.SummaryViewModel
import com.hedvig.android.featureflags.FeatureManager
import org.koin.core.module.dsl.viewModel
import org.koin.dsl.module

Expand All @@ -29,13 +30,19 @@ val movingFlowModule = module {
}
viewModel<EnterNewAddressViewModel> {
EnterNewAddressViewModel(
get<SavedStateHandle>(),
get<MovingFlowRepository>(),
get<ApolloClient>(),
savedStateHandle = get<SavedStateHandle>(),
movingFlowRepository = get<MovingFlowRepository>(),
apolloClient = get<ApolloClient>(),
featureManager = get<FeatureManager>(),
)
}
viewModel<AddHouseInformationViewModel> {
AddHouseInformationViewModel(get(), get(), get())
AddHouseInformationViewModel(
savedStateHandle = get<SavedStateHandle>(),
movingFlowRepository = get<MovingFlowRepository>(),
apolloClient = get<ApolloClient>(),
featureManager = get<FeatureManager>(),
)
}
viewModel<ChoseCoverageLevelAndDeductibleViewModel> {
ChoseCoverageLevelAndDeductibleViewModel(get<MovingFlowRepository>())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ import com.hedvig.android.feature.movingflow.ui.addhouseinformation.AddHouseInfo
import com.hedvig.android.feature.movingflow.ui.addhouseinformation.AddHouseInformationUiState.Content.SubmittingInfoFailure.NetworkFailure
import com.hedvig.android.feature.movingflow.ui.addhouseinformation.AddHouseInformationUiState.Loading
import com.hedvig.android.feature.movingflow.ui.addhouseinformation.AddHouseInformationUiState.MissingOngoingMovingFlow
import com.hedvig.android.featureflags.FeatureManager
import com.hedvig.android.featureflags.flags.Feature
import com.hedvig.android.molecule.android.MoleculeViewModel
import com.hedvig.android.molecule.public.MoleculePresenter
import com.hedvig.android.molecule.public.MoleculePresenterScope
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import octopus.feature.movingflow.MoveIntentV2RequestMutation
import octopus.type.MoveApiVersion
Expand All @@ -79,19 +82,22 @@ internal class AddHouseInformationViewModel(
savedStateHandle: SavedStateHandle,
movingFlowRepository: MovingFlowRepository,
apolloClient: ApolloClient,
featureManager: FeatureManager,
) : MoleculeViewModel<AddHouseInformationEvent, AddHouseInformationUiState>(
AddHouseInformationUiState.Loading,
AddHouseInformationPresenter(
savedStateHandle.toRoute<MovingFlowDestinations.AddHouseInformation>().moveIntentId,
movingFlowRepository,
apolloClient,
featureManager,
),
)

internal class AddHouseInformationPresenter(
private val moveIntentId: String,
private val movingFlowRepository: MovingFlowRepository,
private val apolloClient: ApolloClient,
private val featureManager: FeatureManager,
) : MoleculePresenter<AddHouseInformationEvent, AddHouseInformationUiState> {
@Composable
override fun MoleculePresenterScope<AddHouseInformationEvent>.present(
Expand Down Expand Up @@ -156,8 +162,15 @@ internal class AddHouseInformationPresenter(
LaunchedEffect(inputForSubmission) {
@Suppress("NAME_SHADOWING")
val inputForSubmissionValue = inputForSubmission ?: return@LaunchedEffect
val isAddonFlagEnabled = featureManager.isFeatureEnabled(Feature.TRAVEL_ADDON).first()
apolloClient
.mutation(MoveIntentV2RequestMutation(moveIntentId, inputForSubmissionValue.moveIntentRequestInput))
.mutation(
MoveIntentV2RequestMutation(
moveIntentId,
inputForSubmissionValue.moveIntentRequestInput,
isAddonFlagEnabled,
),
)
.safeExecute()
.map { it.moveIntentRequest }
.fold(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,13 @@ import com.hedvig.android.feature.movingflow.ui.enternewaddress.EnterNewAddressV
import com.hedvig.android.feature.movingflow.ui.enternewaddress.EnterNewAddressValidationError.InvalidPostalCode.Missing
import com.hedvig.android.feature.movingflow.ui.enternewaddress.EnterNewAddressValidationError.InvalidPostalCode.MustBeOnlyDigits
import com.hedvig.android.feature.movingflow.ui.enternewaddress.EnterNewAddressValidationError.InvalidSquareMeters
import com.hedvig.android.featureflags.FeatureManager
import com.hedvig.android.featureflags.flags.Feature
import com.hedvig.android.molecule.android.MoleculeViewModel
import com.hedvig.android.molecule.public.MoleculePresenter
import com.hedvig.android.molecule.public.MoleculePresenterScope
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.datetime.LocalDate
import octopus.feature.movingflow.MoveIntentV2RequestMutation
Expand All @@ -70,19 +73,22 @@ internal class EnterNewAddressViewModel(
savedStateHandle: SavedStateHandle,
movingFlowRepository: MovingFlowRepository,
apolloClient: ApolloClient,
featureManager: FeatureManager,
) : MoleculeViewModel<EnterNewAddressEvent, EnterNewAddressUiState>(
EnterNewAddressUiState.Loading,
EnterNewAddressPresenter(
savedStateHandle.toRoute<MovingFlowDestinations.EnterNewAddress>().moveIntentId,
movingFlowRepository,
apolloClient,
featureManager,
),
)

private class EnterNewAddressPresenter(
private val moveIntentId: String,
private val movingFlowRepository: MovingFlowRepository,
private val apolloClient: ApolloClient,
private val featureManager: FeatureManager,
) : MoleculePresenter<EnterNewAddressEvent, EnterNewAddressUiState> {
@Composable
override fun MoleculePresenterScope<EnterNewAddressEvent>.present(
Expand Down Expand Up @@ -157,8 +163,15 @@ private class EnterNewAddressPresenter(
LaunchedEffect(inputForSubmission) {
@Suppress("NAME_SHADOWING")
val inputForSubmissionValue = inputForSubmission ?: return@LaunchedEffect
val isAddonFlagEnabled = featureManager.isFeatureEnabled(Feature.TRAVEL_ADDON).first()
apolloClient
.mutation(MoveIntentV2RequestMutation(moveIntentId, inputForSubmissionValue.moveIntentRequestInput))
.mutation(
MoveIntentV2RequestMutation(
intentId = moveIntentId,
moveIntentRequestInput = inputForSubmissionValue.moveIntentRequestInput,
addonsFlagOn = isAddonFlagEnabled,
),
)
.safeExecute()
.map { it.moveIntentRequest }
.fold(
Expand Down
Loading