Skip to content

Commit

Permalink
Merge pull request #2358 from HedvigInsurance/feature/addon-tests
Browse files Browse the repository at this point in the history
addon unit tests - data usecases
  • Loading branch information
panasetskaya authored Dec 16, 2024
2 parents dc327f6 + 7d21e0e commit 276a4f1
Show file tree
Hide file tree
Showing 5 changed files with 679 additions and 90 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import arrow.core.nonEmptyListOf
import arrow.core.raise.either
import assertk.assertions.isEqualTo
import assertk.assertions.isNotNull
import assertk.assertions.isNull
import assertk.assertions.isTrue
import com.apollographql.apollo.ApolloClient
import com.apollographql.apollo.annotations.ApolloExperimental
import com.apollographql.apollo.testing.registerTestResponse
import com.hedvig.android.apollo.octopus.test.OctopusFakeResolver
import com.hedvig.android.apollo.test.TestApolloClientRule
import com.hedvig.android.apollo.test.TestNetworkTransportType
import com.hedvig.android.data.addons.data.GetTravelAddonBannerInfoUseCaseImpl
import com.hedvig.android.data.addons.data.TravelAddonBannerInfo
import com.hedvig.android.data.addons.data.TravelAddonBannerSource
import com.hedvig.android.featureflags.flags.Feature
import com.hedvig.android.featureflags.test.FakeFeatureManager2
import com.hedvig.android.logger.TestLogcatLoggingRule
import kotlinx.coroutines.test.runTest
import octopus.TravelAddonBannerQuery
import octopus.type.UpsellTravelAddonFlow
import octopus.type.buildMember
import octopus.type.buildUpsellTravelAddonBanner
import org.junit.Rule
import org.junit.Test

Expand All @@ -21,18 +32,171 @@ class GetTravelAddonBannerInfoUseCaseImplTest {
val testApolloClientRule = TestApolloClientRule(TestNetworkTransportType.MAP)

@OptIn(ApolloExperimental::class)
private val apolloClient: ApolloClient
get() = testApolloClientRule.apolloClient
private val apolloClientWithError: ApolloClient
get() = testApolloClientRule.apolloClient.apply {
registerTestResponse(
operation = TravelAddonBannerQuery(UpsellTravelAddonFlow.APP_UPSELL_UPGRADE),
errors = listOf(com.apollographql.apollo.api.Error.Builder(message = "Bad message").build()),
)
}

@OptIn(ApolloExperimental::class)
private val apolloClientWithNullBannerData: ApolloClient
get() = testApolloClientRule.apolloClient.apply {
registerTestResponse(
operation = TravelAddonBannerQuery(UpsellTravelAddonFlow.APP_UPSELL_UPGRADE),
data = TravelAddonBannerQuery.Data(OctopusFakeResolver) {
currentMember = buildMember {
upsellTravelAddonBanner = null
}
},
)
}

@OptIn(ApolloExperimental::class)
private val apolloClientWithTwoFlows: ApolloClient
get() = testApolloClientRule.apolloClient.apply {
registerTestResponse(
operation = TravelAddonBannerQuery(UpsellTravelAddonFlow.APP_UPSELL_UPGRADE),
data = TravelAddonBannerQuery.Data(OctopusFakeResolver) {
currentMember = buildMember {
upsellTravelAddonBanner = buildUpsellTravelAddonBanner {
badges = buildList {
add("60 days")
}
contractIds = buildList {
add("ContractId")
}
descriptionDisplayName = "Description"
titleDisplayName = "Title"
}
}
},
)
registerTestResponse(
operation = TravelAddonBannerQuery(UpsellTravelAddonFlow.APP_ONLY_UPSALE),
data = TravelAddonBannerQuery.Data(OctopusFakeResolver) {
currentMember = buildMember {
upsellTravelAddonBanner = null
}
},
)
}

@OptIn(ApolloExperimental::class)
private val apolloClientWithEmptyContracts: ApolloClient
get() = testApolloClientRule.apolloClient.apply {
registerTestResponse(
operation = TravelAddonBannerQuery(UpsellTravelAddonFlow.APP_UPSELL_UPGRADE),
data = TravelAddonBannerQuery.Data(OctopusFakeResolver) {
currentMember = buildMember {
upsellTravelAddonBanner = buildUpsellTravelAddonBanner {
badges = buildList {
add("60 days")
}
contractIds = listOf()
descriptionDisplayName = "Description"
titleDisplayName = "Title"
}
}
},
)
}

@OptIn(ApolloExperimental::class)
private val apolloClientWithFullBannerData: ApolloClient
get() = testApolloClientRule.apolloClient.apply {
registerTestResponse(
operation = TravelAddonBannerQuery(UpsellTravelAddonFlow.APP_UPSELL_UPGRADE),
data = TravelAddonBannerQuery.Data(OctopusFakeResolver) {
currentMember = buildMember {
upsellTravelAddonBanner = buildUpsellTravelAddonBanner {
badges = buildList {
add("60 days")
}
contractIds = buildList {
add("ContractId")
}
descriptionDisplayName = "Description"
titleDisplayName = "Title"
}
}
},
)
}

@Test
fun `if FF for addons is off return null`() = runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TRAVEL_ADDON to false))
val sut = GetTravelAddonBannerInfoUseCaseImpl(apolloClient, featureManager)
val resultFromInsurances = sut.invoke(TravelAddonBannerSource.INSURANCES_TAB)
val sut = GetTravelAddonBannerInfoUseCaseImpl(apolloClientWithFullBannerData, featureManager)
val resultFromInsurances = sut.invoke(TravelAddonBannerSource.TRAVEL_CERTIFICATES)
assertk.assertThat(resultFromInsurances)
.isEqualTo(either { null })
val resultFromTravel = sut.invoke(TravelAddonBannerSource.TRAVEL_CERTIFICATES)
assertk.assertThat(resultFromTravel)
.isEqualTo(either { null })
}

@Test
fun `if get null bannerData from BE return null`() = runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TRAVEL_ADDON to true))
val sut = GetTravelAddonBannerInfoUseCaseImpl(apolloClientWithNullBannerData, featureManager)
val result = sut.invoke(TravelAddonBannerSource.TRAVEL_CERTIFICATES)
assertk.assertThat(result)
.isEqualTo(either { null })
}

@Test
fun `the source is mapped to the correct flow for the query`() = runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TRAVEL_ADDON to true))
val sut = GetTravelAddonBannerInfoUseCaseImpl(apolloClientWithTwoFlows, featureManager)
val resultFromTravelCertificates = sut.invoke(TravelAddonBannerSource.TRAVEL_CERTIFICATES).getOrNull()
assertk.assertThat(resultFromTravelCertificates).isNotNull()
val resultFromInsurances = sut.invoke(TravelAddonBannerSource.INSURANCES_TAB).getOrNull()
assertk.assertThat(resultFromInsurances).isNull()
}

@Test
fun `if get bannerData from BE is not null but contractIds are empty return null`() = runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TRAVEL_ADDON to true))
val sut = GetTravelAddonBannerInfoUseCaseImpl(apolloClientWithEmptyContracts, featureManager)
val result = sut.invoke(TravelAddonBannerSource.TRAVEL_CERTIFICATES)
assertk.assertThat(result)
.isEqualTo(either { null })
}

@Test
fun `if get error from BE return ErrorMessage`() = runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TRAVEL_ADDON to true))
val sut = GetTravelAddonBannerInfoUseCaseImpl(apolloClientWithError, featureManager)
val resultFromTravels = sut.invoke(TravelAddonBannerSource.TRAVEL_CERTIFICATES).isLeft()
assertk.assertThat(resultFromTravels)
.isTrue()
}

@Test
fun `if get full banner data from BE return TravelAddonBannerInfo`() = runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TRAVEL_ADDON to true))
val sut = GetTravelAddonBannerInfoUseCaseImpl(apolloClientWithFullBannerData, featureManager)
val resultFromTravel = sut.invoke(TravelAddonBannerSource.TRAVEL_CERTIFICATES).getOrNull()
assertk.assertThat(resultFromTravel)
.isNotNull()
}

@Test
fun `the received data is passed correctly and in full`() = runTest {
val featureManager = FakeFeatureManager2(fixedMap = mapOf(Feature.TRAVEL_ADDON to true))
val sut = GetTravelAddonBannerInfoUseCaseImpl(apolloClientWithFullBannerData, featureManager)
val resultFromTravel = sut.invoke(TravelAddonBannerSource.TRAVEL_CERTIFICATES).getOrNull()
assertk.assertThat(resultFromTravel)
.isEqualTo(
TravelAddonBannerInfo(
title = "Title",
description = "Description",
labels = listOf("60 days"),
eligibleInsurancesIds = nonEmptyListOf("ContractId"),
bannerSource = UpsellTravelAddonFlow.APP_UPSELL_UPGRADE,
),
)
}
}
13 changes: 13 additions & 0 deletions app/feature/feature-addon-purchase/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,17 @@ dependencies {
implementation(projects.navigationComposeTyped)
implementation(projects.navigationCore)
implementation(projects.uiTiersAndAddons)

testImplementation(libs.apollo.testingSupport)
testImplementation(libs.assertK)
testImplementation(libs.coroutines.test)
testImplementation(libs.junit)
testImplementation(libs.turbine)
testImplementation(projects.apolloOctopusTest)
testImplementation(projects.apolloTest)
testImplementation(projects.coreCommonTest)
testImplementation(projects.featureFlagsTest)
testImplementation(projects.languageTest)
testImplementation(projects.loggingTest)
testImplementation(projects.moleculeTest)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,19 @@ package com.hedvig.android.feature.addon.purchase.data

import arrow.core.Either
import arrow.core.NonEmptyList
import arrow.core.nonEmptyListOf
import arrow.core.raise.either
import arrow.core.toNonEmptyListOrNull
import com.apollographql.apollo.ApolloClient
import com.hedvig.android.apollo.safeExecute
import com.hedvig.android.core.common.ErrorMessage
import com.hedvig.android.core.uidata.UiCurrencyCode
import com.hedvig.android.core.uidata.UiMoney
import com.hedvig.android.data.productvariant.InsuranceVariantDocument
import com.hedvig.android.feature.addon.purchase.data.Addon.TravelAddonOffer
import com.hedvig.android.featureflags.FeatureManager
import com.hedvig.android.featureflags.flags.Feature
import com.hedvig.android.logger.LogPriority
import com.hedvig.android.logger.logcat
import kotlin.String
import kotlinx.coroutines.flow.first
import kotlinx.datetime.LocalDate
import octopus.UpsellAddonOfferMutation

internal interface GetTravelAddonOfferUseCase {
Expand Down Expand Up @@ -99,85 +95,3 @@ private fun UpsellAddonOfferMutation.Data.UpsellTravelAddonOffer.Offer.CurrentAd
)
}
}

// todo: remove mocks when not needed
private val mockWithoutUpgrade = TravelAddonOffer(
addonOptions = nonEmptyListOf(
TravelAddonQuote(
quoteId = "id",
addonId = "addonId1",
displayName = "45 days",
addonVariant = AddonVariant(
termsVersion = "terms",
documents = listOf(
InsuranceVariantDocument(
"Terms and conditions",
"www.url.com",
InsuranceVariantDocument.InsuranceDocumentType.TERMS_AND_CONDITIONS,
),
),
displayDetails = listOf("Coverage" to "45 days", "Insured people" to "You+1"),
),
price = UiMoney(
49.0,
UiCurrencyCode.SEK,
),
),
TravelAddonQuote(
displayName = "60 days",
addonId = "addonId1",
quoteId = "id",
addonVariant = AddonVariant(
termsVersion = "terms",
documents = listOf(
InsuranceVariantDocument(
"Terms and conditions",
"www.url.com",
InsuranceVariantDocument.InsuranceDocumentType.TERMS_AND_CONDITIONS,
),
),
displayDetails = listOf("Coverage" to "60 days", "Insured people" to "You+1"),
),
price = UiMoney(
60.0,
UiCurrencyCode.SEK,
),
),
),
title = "Travel plus",
description = "For those who travel often: luggage protection and 24/7 assistance worldwide",
activationDate = LocalDate(2025, 1, 1),
currentTravelAddon = null,
)

private val mockWithUpgrade = TravelAddonOffer(
addonOptions = nonEmptyListOf(
TravelAddonQuote(
displayName = "60 days",
addonId = "addonId1",
quoteId = "id",
addonVariant = AddonVariant(
termsVersion = "terms",
documents = listOf(
InsuranceVariantDocument(
"Terms and conditions",
"www.url.com",
InsuranceVariantDocument.InsuranceDocumentType.TERMS_AND_CONDITIONS,
),
),
displayDetails = listOf("Coverage" to "60 days", "Insured people" to "You+1"),
),
price = UiMoney(
60.0,
UiCurrencyCode.SEK,
),
),
),
title = "Travel plus",
description = "For those who travel often: luggage protection and 24/7 assistance worldwide",
activationDate = LocalDate(2025, 1, 1),
currentTravelAddon = CurrentTravelAddon(
UiMoney(49.0, UiCurrencyCode.SEK),
listOf("Coverage" to "45 days", "Insured people" to "You+1"),
),
)
Loading

0 comments on commit 276a4f1

Please sign in to comment.