Bug 1853301 - Refactor ReviewQualityCheckNavigationMiddleware to use TabsUseCases and SessionUseCases

Refactor LinkType class to support instances for each external link accessible from the review quality check feature
fenix/120.0
Alexandru2909 1 year ago committed by mergify[bot]
parent 354be91be7
commit 9cac2fca23

@ -16,8 +16,6 @@ import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.shopping.di.ReviewQualityCheckMiddlewareProvider import org.mozilla.fenix.shopping.di.ReviewQualityCheckMiddlewareProvider
import org.mozilla.fenix.shopping.store.ReviewQualityCheckStore import org.mozilla.fenix.shopping.store.ReviewQualityCheckStore
@ -36,13 +34,6 @@ class ReviewQualityCheckFragment : BottomSheetDialogFragment() {
settings = requireComponents.settings, settings = requireComponents.settings,
browserStore = requireComponents.core.store, browserStore = requireComponents.core.store,
context = requireContext().applicationContext, context = requireContext().applicationContext,
openLink = { link, shouldOpenInNewTab ->
(requireActivity() as HomeActivity).openToBrowserAndLoad(
searchTermOrURL = link,
newTab = shouldOpenInNewTab,
from = BrowserDirection.FromReviewQualityCheck,
)
},
scope = lifecycleScope, scope = lifecycleScope,
), ),
) )

@ -7,6 +7,7 @@ package org.mozilla.fenix.shopping.di
import android.content.Context import android.content.Context
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.feature.tabs.TabsUseCases
import org.mozilla.fenix.shopping.middleware.DefaultNetworkChecker import org.mozilla.fenix.shopping.middleware.DefaultNetworkChecker
import org.mozilla.fenix.shopping.middleware.DefaultReviewQualityCheckPreferences import org.mozilla.fenix.shopping.middleware.DefaultReviewQualityCheckPreferences
import org.mozilla.fenix.shopping.middleware.DefaultReviewQualityCheckService import org.mozilla.fenix.shopping.middleware.DefaultReviewQualityCheckService
@ -27,21 +28,22 @@ object ReviewQualityCheckMiddlewareProvider {
* @param settings The [Settings] instance to use. * @param settings The [Settings] instance to use.
* @param browserStore The [BrowserStore] instance to access state. * @param browserStore The [BrowserStore] instance to access state.
* @param context The [Context] instance to use. * @param context The [Context] instance to use.
* @param openLink Opens a link. The callback is invoked with the URL [String] parameter and
* whether or not it should open in a new or the currently selected tab [Boolean] parameter.
* @param scope The [CoroutineScope] to use for launching coroutines. * @param scope The [CoroutineScope] to use for launching coroutines.
*/ */
fun provideMiddleware( fun provideMiddleware(
settings: Settings, settings: Settings,
browserStore: BrowserStore, browserStore: BrowserStore,
context: Context, context: Context,
openLink: (String, Boolean) -> Unit,
scope: CoroutineScope, scope: CoroutineScope,
): List<ReviewQualityCheckMiddleware> = ): List<ReviewQualityCheckMiddleware> =
listOf( listOf(
providePreferencesMiddleware(settings, scope), providePreferencesMiddleware(settings, scope),
provideNetworkMiddleware(browserStore, context, scope), provideNetworkMiddleware(browserStore, context, scope),
provideNavigationMiddleware(openLink, scope), provideNavigationMiddleware(
TabsUseCases.SelectOrAddUseCase(browserStore),
context,
scope,
),
) )
private fun providePreferencesMiddleware( private fun providePreferencesMiddleware(
@ -63,10 +65,12 @@ object ReviewQualityCheckMiddlewareProvider {
) )
private fun provideNavigationMiddleware( private fun provideNavigationMiddleware(
openLink: (String, Boolean) -> Unit, selectOrAddUseCase: TabsUseCases.SelectOrAddUseCase,
context: Context,
scope: CoroutineScope, scope: CoroutineScope,
) = ReviewQualityCheckNavigationMiddleware( ) = ReviewQualityCheckNavigationMiddleware(
openLink = openLink, selectOrAddUseCase = selectOrAddUseCase,
context = context,
scope = scope, scope = scope,
) )
} }

@ -4,21 +4,28 @@
package org.mozilla.fenix.shopping.middleware package org.mozilla.fenix.shopping.middleware
import android.content.Context
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mozilla.components.feature.tabs.TabsUseCases
import mozilla.components.lib.state.Middleware import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.MiddlewareContext import mozilla.components.lib.state.MiddlewareContext
import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.shopping.store.ReviewQualityCheckAction import org.mozilla.fenix.shopping.store.ReviewQualityCheckAction
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState import org.mozilla.fenix.shopping.store.ReviewQualityCheckState
private const val POWERED_BY_URL = "www.fakespot.com"
/** /**
* Middleware that handles navigation events for the review quality check feature. * Middleware that handles navigation events for the review quality check feature.
* *
* @property openLink Callback used to open an url. * @property selectOrAddUseCase UseCase instance used to open new tabs.
* @property context Context used to get SUMO urls.
* @property scope [CoroutineScope] used to launch coroutines. * @property scope [CoroutineScope] used to launch coroutines.
*/ */
class ReviewQualityCheckNavigationMiddleware( class ReviewQualityCheckNavigationMiddleware(
private val openLink: (String, Boolean) -> Unit, private val selectOrAddUseCase: TabsUseCases.SelectOrAddUseCase,
private val context: Context,
private val scope: CoroutineScope, private val scope: CoroutineScope,
) : Middleware<ReviewQualityCheckState, ReviewQualityCheckAction> { ) : Middleware<ReviewQualityCheckState, ReviewQualityCheckAction> {
@ -39,13 +46,38 @@ class ReviewQualityCheckNavigationMiddleware(
private fun processAction( private fun processAction(
action: ReviewQualityCheckAction.NavigationMiddlewareAction, action: ReviewQualityCheckAction.NavigationMiddlewareAction,
) = scope.launch { ) = scope.launch {
when (action) { selectOrAddUseCase.invoke(actionToUrl(action))
is ReviewQualityCheckAction.OpenLink -> { }
when (action.link) {
is ReviewQualityCheckState.LinkType.ExternalLink -> openLink(action.link.url, true) /**
is ReviewQualityCheckState.LinkType.AnalyzeLink -> openLink(action.link.url, false) * Used to find the corresponding url to the open link action.
} *
} * @param action Used to find the corresponding url.
} */
private fun actionToUrl(
action: ReviewQualityCheckAction.NavigationMiddlewareAction,
) = when (action) {
// Placeholder SUMO urls to be used until the Fakespot SUMO pages are added in 1854277
is ReviewQualityCheckAction.OpenExplainerLearnMoreLink -> SupportUtils.getSumoURLForTopic(
context,
SupportUtils.SumoTopic.HELP,
)
is ReviewQualityCheckAction.OpenOnboardingTermsLink -> SupportUtils.getSumoURLForTopic(
context,
SupportUtils.SumoTopic.HELP,
)
is ReviewQualityCheckAction.OpenOnboardingLearnMoreLink -> SupportUtils.getSumoURLForTopic(
context,
SupportUtils.SumoTopic.HELP,
)
is ReviewQualityCheckAction.OpenOnboardingPrivacyPolicyLink -> SupportUtils.getSumoURLForTopic(
context,
SupportUtils.SumoTopic.HELP,
)
is ReviewQualityCheckAction.OpenPoweredByLink -> POWERED_BY_URL
} }
} }

@ -85,7 +85,27 @@ sealed interface ReviewQualityCheckAction : Action {
object ReanalyzeProduct : NetworkAction, UpdateAction object ReanalyzeProduct : NetworkAction, UpdateAction
/** /**
* Triggered when opening a link from the review quality check feature. * Triggered when the user clicks on learn more link on the explainer card.
*/ */
data class OpenLink(val link: ReviewQualityCheckState.LinkType) : NavigationMiddlewareAction object OpenExplainerLearnMoreLink : NavigationMiddlewareAction
/**
* Triggered when the user clicks on the "Powered by" link in the footer.
*/
object OpenPoweredByLink : NavigationMiddlewareAction
/**
* Triggered when the user clicks on learn more link on the opt in card.
*/
object OpenOnboardingLearnMoreLink : NavigationMiddlewareAction
/**
* Triggered when the user clicks on terms and conditions link on the opt in card.
*/
object OpenOnboardingTermsLink : NavigationMiddlewareAction
/**
* Triggered when the user clicks on privacy policy link on the opt in card.
*/
object OpenOnboardingPrivacyPolicyLink : NavigationMiddlewareAction
} }

@ -151,21 +151,6 @@ sealed interface ReviewQualityCheckState : State {
QUALITY, PRICE, SHIPPING, PACKAGING_AND_APPEARANCE, COMPETITIVENESS QUALITY, PRICE, SHIPPING, PACKAGING_AND_APPEARANCE, COMPETITIVENESS
} }
/**
* Types of links that can be opened from the review quality check feature.
*/
sealed class LinkType {
/**
* Opens a link to analyze a product.
*/
data class AnalyzeLink(val url: String) : LinkType()
/**
* Opens an external "Learn more" link.
*/
data class ExternalLink(val url: String) : LinkType()
}
/** /**
* The state of the recommended product. * The state of the recommended product.
*/ */

@ -52,7 +52,7 @@ fun NoAnalysis(
isAnalyzing: Boolean, isAnalyzing: Boolean,
productRecommendationsEnabled: Boolean?, productRecommendationsEnabled: Boolean?,
onAnalyzeClick: () -> Unit, onAnalyzeClick: () -> Unit,
onReviewGradeLearnMoreClick: (String) -> Unit, onReviewGradeLearnMoreClick: () -> Unit,
onOptOutClick: () -> Unit, onOptOutClick: () -> Unit,
onProductRecommendationsEnabledStateChange: (Boolean) -> Unit, onProductRecommendationsEnabledStateChange: (Boolean) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,

@ -66,8 +66,8 @@ fun ProductAnalysis(
onOptOutClick: () -> Unit, onOptOutClick: () -> Unit,
onReanalyzeClick: () -> Unit, onReanalyzeClick: () -> Unit,
onProductRecommendationsEnabledStateChange: (Boolean) -> Unit, onProductRecommendationsEnabledStateChange: (Boolean) -> Unit,
onReviewGradeLearnMoreClick: (String) -> Unit, onReviewGradeLearnMoreClick: () -> Unit,
onFooterLinkClick: (String) -> Unit, onFooterLinkClick: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Column( Column(

@ -37,10 +37,10 @@ import org.mozilla.fenix.theme.FirefoxTheme
fun ProductAnalysisError( fun ProductAnalysisError(
error: ProductReviewState.Error, error: ProductReviewState.Error,
productRecommendationsEnabled: Boolean?, productRecommendationsEnabled: Boolean?,
onReviewGradeLearnMoreClick: (String) -> Unit, onReviewGradeLearnMoreClick: () -> Unit,
onOptOutClick: () -> Unit, onOptOutClick: () -> Unit,
onProductRecommendationsEnabledStateChange: (Boolean) -> Unit, onProductRecommendationsEnabledStateChange: (Boolean) -> Unit,
onFooterLinkClick: (String) -> Unit, onFooterLinkClick: () -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Column( Column(

@ -25,7 +25,6 @@ import org.mozilla.fenix.shopping.store.ReviewQualityCheckStore
* @param onRequestDismiss Invoked when a user action requests dismissal of the bottom sheet. * @param onRequestDismiss Invoked when a user action requests dismissal of the bottom sheet.
* @param modifier The modifier to be applied to the Composable. * @param modifier The modifier to be applied to the Composable.
*/ */
@Suppress("LongMethod")
@Composable @Composable
fun ReviewQualityCheckBottomSheet( fun ReviewQualityCheckBottomSheet(
store: ReviewQualityCheckStore, store: ReviewQualityCheckStore,
@ -47,26 +46,17 @@ fun ReviewQualityCheckBottomSheet(
onPrimaryButtonClick = { onPrimaryButtonClick = {
store.dispatch(ReviewQualityCheckAction.OptIn) store.dispatch(ReviewQualityCheckAction.OptIn)
}, },
onLearnMoreClick = { url -> onLearnMoreClick = {
store.dispatch( onRequestDismiss()
ReviewQualityCheckAction.OpenLink( store.dispatch(ReviewQualityCheckAction.OpenOnboardingLearnMoreLink)
ReviewQualityCheckState.LinkType.ExternalLink(url),
),
)
}, },
onPrivacyPolicyClick = { url -> onPrivacyPolicyClick = {
store.dispatch( onRequestDismiss()
ReviewQualityCheckAction.OpenLink( store.dispatch(ReviewQualityCheckAction.OpenOnboardingPrivacyPolicyLink)
ReviewQualityCheckState.LinkType.ExternalLink(url),
),
)
}, },
onTermsOfUseClick = { url -> onTermsOfUseClick = {
store.dispatch( onRequestDismiss()
ReviewQualityCheckAction.OpenLink( store.dispatch(ReviewQualityCheckAction.OpenOnboardingTermsLink)
ReviewQualityCheckState.LinkType.ExternalLink(url),
),
)
}, },
onSecondaryButtonClick = onRequestDismiss, onSecondaryButtonClick = onRequestDismiss,
) )
@ -85,19 +75,13 @@ fun ReviewQualityCheckBottomSheet(
onProductRecommendationsEnabledStateChange = { onProductRecommendationsEnabledStateChange = {
store.dispatch(ReviewQualityCheckAction.ToggleProductRecommendation) store.dispatch(ReviewQualityCheckAction.ToggleProductRecommendation)
}, },
onReviewGradeLearnMoreClick = { url -> onReviewGradeLearnMoreClick = {
store.dispatch( onRequestDismiss()
ReviewQualityCheckAction.OpenLink( store.dispatch(ReviewQualityCheckAction.OpenExplainerLearnMoreLink)
ReviewQualityCheckState.LinkType.ExternalLink(url),
),
)
}, },
onFooterLinkClick = { url -> onFooterLinkClick = {
store.dispatch( onRequestDismiss()
ReviewQualityCheckAction.OpenLink( store.dispatch(ReviewQualityCheckAction.OpenPoweredByLink)
ReviewQualityCheckState.LinkType.ExternalLink(url),
),
)
}, },
) )
} }
@ -120,8 +104,8 @@ private fun ProductReview(
onOptOutClick: () -> Unit, onOptOutClick: () -> Unit,
onReanalyzeClick: () -> Unit, onReanalyzeClick: () -> Unit,
onProductRecommendationsEnabledStateChange: (Boolean) -> Unit, onProductRecommendationsEnabledStateChange: (Boolean) -> Unit,
onReviewGradeLearnMoreClick: (String) -> Unit, onReviewGradeLearnMoreClick: () -> Unit,
onFooterLinkClick: (String) -> Unit, onFooterLinkClick: () -> Unit,
) { ) {
Crossfade( Crossfade(
targetState = state.productReviewState, targetState = state.productReviewState,

@ -45,9 +45,9 @@ const val PLACEHOLDER_URL = "www.fakespot.com"
@Composable @Composable
fun ReviewQualityCheckContextualOnboarding( fun ReviewQualityCheckContextualOnboarding(
retailers: List<ProductVendor>, retailers: List<ProductVendor>,
onLearnMoreClick: (String) -> Unit, onLearnMoreClick: () -> Unit,
onPrivacyPolicyClick: (String) -> Unit, onPrivacyPolicyClick: () -> Unit,
onTermsOfUseClick: (String) -> Unit, onTermsOfUseClick: () -> Unit,
onPrimaryButtonClick: () -> Unit, onPrimaryButtonClick: () -> Unit,
onSecondaryButtonClick: () -> Unit, onSecondaryButtonClick: () -> Unit,
) { ) {
@ -85,7 +85,9 @@ fun ReviewQualityCheckContextualOnboarding(
LinkTextState( LinkTextState(
text = learnMoreText, text = learnMoreText,
url = PLACEHOLDER_URL, url = PLACEHOLDER_URL,
onClick = onLearnMoreClick, onClick = {
onLearnMoreClick()
},
), ),
), ),
style = FirefoxTheme.typography.body2.copy( style = FirefoxTheme.typography.body2.copy(
@ -107,12 +109,16 @@ fun ReviewQualityCheckContextualOnboarding(
LinkTextState( LinkTextState(
text = privacyPolicyText, text = privacyPolicyText,
url = PLACEHOLDER_URL, url = PLACEHOLDER_URL,
onClick = onPrivacyPolicyClick, onClick = {
onPrivacyPolicyClick()
},
), ),
LinkTextState( LinkTextState(
text = termsOfUseText, text = termsOfUseText,
url = PLACEHOLDER_URL, url = PLACEHOLDER_URL,
onClick = onTermsOfUseClick, onClick = {
onTermsOfUseClick()
},
), ),
), ),
style = FirefoxTheme.typography.caption style = FirefoxTheme.typography.caption

@ -18,8 +18,6 @@ import org.mozilla.fenix.compose.LinkTextState
import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.theme.FirefoxTheme import org.mozilla.fenix.theme.FirefoxTheme
private const val FOOTER_LINK = "http://fakespot.com/"
/** /**
* Review Quality Check footer with an embedded link to navigate to Fakespot.com. * Review Quality Check footer with an embedded link to navigate to Fakespot.com.
* *
@ -27,7 +25,7 @@ private const val FOOTER_LINK = "http://fakespot.com/"
*/ */
@Composable @Composable
fun ReviewQualityCheckFooter( fun ReviewQualityCheckFooter(
onLinkClick: (String) -> Unit, onLinkClick: () -> Unit,
) { ) {
val poweredByLinkText = stringResource( val poweredByLinkText = stringResource(
id = R.string.review_quality_check_powered_by_link, id = R.string.review_quality_check_powered_by_link,
@ -42,8 +40,10 @@ fun ReviewQualityCheckFooter(
linkTextStates = listOf( linkTextStates = listOf(
LinkTextState( LinkTextState(
text = poweredByLinkText, text = poweredByLinkText,
url = FOOTER_LINK, url = "",
onClick = onLinkClick, onClick = {
onLinkClick()
},
), ),
), ),
style = FirefoxTheme.typography.body2.copy( style = FirefoxTheme.typography.body2.copy(

@ -18,7 +18,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -26,7 +25,6 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.compose.ClickableSubstringLink import org.mozilla.fenix.compose.ClickableSubstringLink
import org.mozilla.fenix.compose.annotation.LightDarkPreview import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.compose.parseHtml import org.mozilla.fenix.compose.parseHtml
import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState import org.mozilla.fenix.shopping.store.ReviewQualityCheckState
import org.mozilla.fenix.theme.FirefoxTheme import org.mozilla.fenix.theme.FirefoxTheme
@ -39,7 +37,7 @@ import org.mozilla.fenix.theme.FirefoxTheme
@Composable @Composable
fun ReviewQualityInfoCard( fun ReviewQualityInfoCard(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onLearnMoreClick: (String) -> Unit, onLearnMoreClick: () -> Unit,
) { ) {
ReviewQualityCheckExpandableCard( ReviewQualityCheckExpandableCard(
title = stringResource(id = R.string.review_quality_check_explanation_title), title = stringResource(id = R.string.review_quality_check_explanation_title),
@ -56,7 +54,7 @@ fun ReviewQualityInfoCard(
@Composable @Composable
private fun ReviewQualityInfo( private fun ReviewQualityInfo(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onLearnMoreClick: (String) -> Unit, onLearnMoreClick: () -> Unit,
) { ) {
Column( Column(
modifier = modifier, modifier = modifier,
@ -81,7 +79,6 @@ private fun ReviewQualityInfo(
stringResource(R.string.shopping_product_name), stringResource(R.string.shopping_product_name),
) )
val text = stringResource(R.string.review_quality_check_info_learn_more, link) val text = stringResource(R.string.review_quality_check_info_learn_more, link)
val context = LocalContext.current
val linkStartIndex = text.indexOf(link) val linkStartIndex = text.indexOf(link)
val linkEndIndex = linkStartIndex + link.length val linkEndIndex = linkStartIndex + link.length
ClickableSubstringLink( ClickableSubstringLink(
@ -89,15 +86,7 @@ private fun ReviewQualityInfo(
textStyle = FirefoxTheme.typography.body2, textStyle = FirefoxTheme.typography.body2,
clickableStartIndex = linkStartIndex, clickableStartIndex = linkStartIndex,
clickableEndIndex = linkEndIndex, clickableEndIndex = linkEndIndex,
onClick = { onClick = onLearnMoreClick,
onLearnMoreClick(
// Placeholder Sumo page
SupportUtils.getSumoURLForTopic(
context,
SupportUtils.SumoTopic.HELP,
),
)
},
) )
ReviewGradingScaleInfo( ReviewGradingScaleInfo(

@ -1,75 +1,56 @@
package org.mozilla.fenix.shopping.middleware package org.mozilla.fenix.shopping.middleware
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.feature.tabs.TabsUseCases
import mozilla.components.support.test.ext.joinBlocking import mozilla.components.support.test.ext.joinBlocking
import mozilla.components.support.test.libstate.ext.waitUntilIdle import mozilla.components.support.test.libstate.ext.waitUntilIdle
import mozilla.components.support.test.robolectric.testContext
import mozilla.components.support.test.rule.MainCoroutineRule import mozilla.components.support.test.rule.MainCoroutineRule
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.shopping.store.ReviewQualityCheckAction import org.mozilla.fenix.shopping.store.ReviewQualityCheckAction
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState
import org.mozilla.fenix.shopping.store.ReviewQualityCheckStore import org.mozilla.fenix.shopping.store.ReviewQualityCheckStore
@RunWith(FenixRobolectricTestRunner::class)
class ReviewQualityCheckNavigationMiddlewareTest { class ReviewQualityCheckNavigationMiddlewareTest {
@get:Rule @get:Rule
val coroutinesTestRule = MainCoroutineRule() val coroutinesTestRule = MainCoroutineRule()
private val dispatcher = coroutinesTestRule.testDispatcher private val dispatcher = coroutinesTestRule.testDispatcher
private val scope = coroutinesTestRule.scope private val scope = coroutinesTestRule.scope
private lateinit var store: ReviewQualityCheckStore
@Test private lateinit var browserStore: BrowserStore
fun `WHEN opening an external link THEN the link should be opened in a new tab`() { private lateinit var addTabUseCase: TabsUseCases.SelectOrAddUseCase
var isOpenedInSelectedTab = false private lateinit var middleware: ReviewQualityCheckNavigationMiddleware
var isOpenedInNewTab = false
val store = ReviewQualityCheckStore( @Before
middleware = listOf( fun setup() {
ReviewQualityCheckNavigationMiddleware( browserStore = BrowserStore()
openLink = { _, openInNewTab -> addTabUseCase = TabsUseCases.SelectOrAddUseCase(browserStore)
if (openInNewTab) { middleware = ReviewQualityCheckNavigationMiddleware(
isOpenedInNewTab = true selectOrAddUseCase = addTabUseCase,
} else { context = testContext,
isOpenedInSelectedTab = true scope = scope,
} )
}, store = ReviewQualityCheckStore(
scope = scope, middleware = listOf(middleware),
),
),
) )
store.waitUntilIdle()
dispatcher.scheduler.advanceUntilIdle()
store.dispatch(ReviewQualityCheckAction.OpenLink(ReviewQualityCheckState.LinkType.ExternalLink("www.mozilla.com"))).joinBlocking()
store.waitUntilIdle()
assertEquals(true, isOpenedInNewTab)
assertEquals(false, isOpenedInSelectedTab)
} }
@Test @Test
fun `WHEN re-analzying a product THEN the link should be opened in the currently selected tab`() { fun `WHEN opening an external link THEN the link should be opened in a new tab`() {
var isOpenedInSelectedTab = false val action = ReviewQualityCheckAction.OpenPoweredByLink
var isOpenedInNewTab = false
val store = ReviewQualityCheckStore(
middleware = listOf(
ReviewQualityCheckNavigationMiddleware(
openLink = { _, openInNewTab ->
if (openInNewTab) {
isOpenedInNewTab = true
} else {
isOpenedInSelectedTab = true
}
},
scope = scope,
),
),
)
store.waitUntilIdle() store.waitUntilIdle()
dispatcher.scheduler.advanceUntilIdle() dispatcher.scheduler.advanceUntilIdle()
assertEquals(0, browserStore.state.tabs.size)
store.dispatch(ReviewQualityCheckAction.OpenLink(ReviewQualityCheckState.LinkType.AnalyzeLink("www.mozilla.com"))).joinBlocking() store.dispatch(action).joinBlocking()
store.waitUntilIdle() store.waitUntilIdle()
assertEquals(true, isOpenedInSelectedTab) assertEquals(1, browserStore.state.tabs.size)
assertEquals(false, isOpenedInNewTab)
} }
} }

Loading…
Cancel
Save