mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-19 09:25:34 +00:00
Bug 1853299 - Part 2: Update rc non error states for reanalysis
This commit is contained in:
parent
9b4f4e7d1e
commit
2316c8a96d
@ -10,6 +10,7 @@ import mozilla.components.concept.engine.shopping.ProductAnalysis
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.HighlightType
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.OptedIn.ProductReviewState
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.OptedIn.ProductReviewState.AnalysisPresent.AnalysisStatus
|
||||
|
||||
/**
|
||||
* Maps [ProductAnalysis] to [ProductReviewState].
|
||||
@ -33,12 +34,12 @@ private fun GeckoProductAnalysis.toProductReview(): ProductReviewState =
|
||||
val mappedHighlights = highlights?.toHighlights()?.toSortedMap()
|
||||
|
||||
if (mappedGrade == null && mappedRating == null && mappedHighlights == null) {
|
||||
ProductReviewState.NoAnalysisPresent
|
||||
ProductReviewState.NoAnalysisPresent()
|
||||
} else {
|
||||
ProductReviewState.AnalysisPresent(
|
||||
productId = productId!!,
|
||||
reviewGrade = mappedGrade,
|
||||
needsAnalysis = needsAnalysis,
|
||||
analysisStatus = needsAnalysis.toAnalysisStatus(),
|
||||
adjustedRating = mappedRating,
|
||||
productUrl = analysisURL!!,
|
||||
highlights = mappedHighlights,
|
||||
@ -53,6 +54,12 @@ private fun String.toGrade(): ReviewQualityCheckState.Grade? =
|
||||
null
|
||||
}
|
||||
|
||||
private fun Boolean.toAnalysisStatus(): AnalysisStatus =
|
||||
when (this) {
|
||||
true -> AnalysisStatus.NEEDS_ANALYSIS
|
||||
false -> AnalysisStatus.UP_TO_DATE
|
||||
}
|
||||
|
||||
private fun Highlight.toHighlights(): Map<HighlightType, List<String>>? =
|
||||
HighlightType.values()
|
||||
.associateWith { highlightsForType(it) }
|
||||
|
@ -51,6 +51,10 @@ class ReviewQualityCheckNetworkMiddleware(
|
||||
store.dispatch(ReviewQualityCheckAction.UpdateProductReview(productReviewState))
|
||||
}
|
||||
}
|
||||
|
||||
ReviewQualityCheckAction.ReanalyzeProduct -> {
|
||||
// Bug 1853311 - Integrate analyze and analysis_status
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,6 +79,11 @@ sealed interface ReviewQualityCheckAction : Action {
|
||||
*/
|
||||
object RetryProductAnalysis : NetworkAction, UpdateAction
|
||||
|
||||
/**
|
||||
* Triggered when the user triggers product re-analysis.
|
||||
*/
|
||||
object ReanalyzeProduct : NetworkAction, UpdateAction
|
||||
|
||||
/**
|
||||
* Triggered when opening a link from the review quality check feature.
|
||||
*/
|
||||
|
@ -54,15 +54,16 @@ sealed interface ReviewQualityCheckState : State {
|
||||
/**
|
||||
* Denotes no analysis is present for the product the user is browsing.
|
||||
*/
|
||||
object NoAnalysisPresent : ProductReviewState
|
||||
data class NoAnalysisPresent(
|
||||
val isReanalyzing: Boolean = false,
|
||||
) : ProductReviewState
|
||||
|
||||
/**
|
||||
* Denotes the state where analysis of the product is fetched and present.
|
||||
*
|
||||
* @property productId The id of the product, e.g ASIN, SKU.
|
||||
* @property reviewGrade The review grade of the product.
|
||||
* @property needsAnalysis If true, the analysis is stale and that to get the fresh
|
||||
* data, re–analysis is needed.
|
||||
* @property analysisStatus The status of the product analysis.
|
||||
* @property adjustedRating The adjusted rating taking review quality into consideration.
|
||||
* @property productUrl The url of the product the user is browsing.
|
||||
* @property highlights Optional highlights based on recent reviews of the product.
|
||||
@ -71,7 +72,7 @@ sealed interface ReviewQualityCheckState : State {
|
||||
data class AnalysisPresent(
|
||||
val productId: String,
|
||||
val reviewGrade: Grade?,
|
||||
val needsAnalysis: Boolean,
|
||||
val analysisStatus: AnalysisStatus,
|
||||
val adjustedRating: Float?,
|
||||
val productUrl: String,
|
||||
val highlights: SortedMap<HighlightType, List<String>>?,
|
||||
@ -90,6 +91,13 @@ sealed interface ReviewQualityCheckState : State {
|
||||
val highlightsFadeVisible: Boolean =
|
||||
highlights != null && showMoreButtonVisible &&
|
||||
highlights.forCompactMode().entries.first().value.size > 1
|
||||
|
||||
/**
|
||||
* The status of the product analysis.
|
||||
*/
|
||||
enum class AnalysisStatus {
|
||||
NEEDS_ANALYSIS, REANALYZING, UP_TO_DATE, COMPLETED
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
package org.mozilla.fenix.shopping.store
|
||||
|
||||
import mozilla.components.lib.state.Store
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.OptedIn.ProductReviewState.AnalysisPresent.AnalysisStatus
|
||||
|
||||
/**
|
||||
* Store for review quality check feature.
|
||||
@ -76,5 +77,25 @@ private fun mapStateForUpdateAction(
|
||||
it.copy(productReviewState = ReviewQualityCheckState.OptedIn.ProductReviewState.Loading)
|
||||
}
|
||||
}
|
||||
|
||||
ReviewQualityCheckAction.ReanalyzeProduct -> {
|
||||
state.mapIfOptedIn {
|
||||
when (it.productReviewState) {
|
||||
is ReviewQualityCheckState.OptedIn.ProductReviewState.AnalysisPresent -> {
|
||||
val productReviewState =
|
||||
it.productReviewState.copy(analysisStatus = AnalysisStatus.REANALYZING)
|
||||
it.copy(productReviewState = productReviewState)
|
||||
}
|
||||
|
||||
is ReviewQualityCheckState.OptedIn.ProductReviewState.NoAnalysisPresent -> {
|
||||
it.copy(productReviewState = it.productReviewState.copy(isReanalyzing = true))
|
||||
}
|
||||
|
||||
else -> {
|
||||
it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ import org.mozilla.fenix.compose.button.SecondaryButton
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.HighlightType
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.OptedIn.ProductReviewState.AnalysisPresent
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.OptedIn.ProductReviewState.AnalysisPresent.AnalysisStatus
|
||||
import org.mozilla.fenix.shopping.store.forCompactMode
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
|
||||
@ -71,10 +72,22 @@ fun ProductAnalysis(
|
||||
modifier = modifier,
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
if (productAnalysis.needsAnalysis) {
|
||||
ReanalyzeCard(
|
||||
onReanalyzeClick = onReanalyzeClick,
|
||||
)
|
||||
when (productAnalysis.analysisStatus) {
|
||||
AnalysisStatus.NEEDS_ANALYSIS -> {
|
||||
ReanalyzeCard(onReanalyzeClick = onReanalyzeClick)
|
||||
}
|
||||
|
||||
AnalysisStatus.REANALYZING -> {
|
||||
// TBD
|
||||
}
|
||||
|
||||
AnalysisStatus.COMPLETED -> {
|
||||
// TBD
|
||||
}
|
||||
|
||||
AnalysisStatus.UP_TO_DATE -> {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
if (productAnalysis.reviewGrade != null) {
|
||||
@ -367,7 +380,7 @@ private fun ProductAnalysisPreview() {
|
||||
productAnalysis = AnalysisPresent(
|
||||
productId = "123",
|
||||
reviewGrade = ReviewQualityCheckState.Grade.B,
|
||||
needsAnalysis = false,
|
||||
analysisStatus = AnalysisStatus.UP_TO_DATE,
|
||||
adjustedRating = 3.6f,
|
||||
productUrl = "123",
|
||||
highlights = sortedMapOf(
|
||||
|
@ -56,7 +56,9 @@ fun ReviewQualityCheckBottomSheet(
|
||||
onRequestDismiss()
|
||||
store.dispatch(ReviewQualityCheckAction.OptOut)
|
||||
},
|
||||
onReanalyzeClick = {},
|
||||
onReanalyzeClick = {
|
||||
store.dispatch(ReviewQualityCheckAction.ReanalyzeProduct)
|
||||
},
|
||||
onProductRecommendationsEnabledStateChange = {
|
||||
store.dispatch(ReviewQualityCheckAction.ToggleProductRecommendation)
|
||||
},
|
||||
|
@ -7,6 +7,7 @@ package org.mozilla.fenix.shopping
|
||||
import mozilla.components.browser.engine.gecko.shopping.GeckoProductAnalysis
|
||||
import mozilla.components.browser.engine.gecko.shopping.Highlight
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.OptedIn.ProductReviewState.AnalysisPresent.AnalysisStatus
|
||||
import java.util.SortedMap
|
||||
|
||||
object ProductAnalysisTestData {
|
||||
@ -38,7 +39,7 @@ object ProductAnalysisTestData {
|
||||
productUrl: String = "https://test.com",
|
||||
reviewGrade: ReviewQualityCheckState.Grade? = ReviewQualityCheckState.Grade.A,
|
||||
adjustedRating: Float? = 4.5f,
|
||||
needsAnalysis: Boolean = false,
|
||||
analysisStatus: AnalysisStatus = AnalysisStatus.UP_TO_DATE,
|
||||
highlights: SortedMap<ReviewQualityCheckState.HighlightType, List<String>>? = null,
|
||||
): ReviewQualityCheckState.OptedIn.ProductReviewState.AnalysisPresent =
|
||||
ReviewQualityCheckState.OptedIn.ProductReviewState.AnalysisPresent(
|
||||
@ -46,7 +47,7 @@ object ProductAnalysisTestData {
|
||||
productUrl = productUrl,
|
||||
reviewGrade = reviewGrade,
|
||||
adjustedRating = adjustedRating,
|
||||
needsAnalysis = needsAnalysis,
|
||||
analysisStatus = analysisStatus,
|
||||
highlights = highlights,
|
||||
)
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import org.junit.Test
|
||||
import org.mozilla.fenix.shopping.ProductAnalysisTestData
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.HighlightType
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.OptedIn.ProductReviewState.AnalysisPresent.AnalysisStatus
|
||||
|
||||
class ProductAnalysisMapperTest {
|
||||
|
||||
@ -34,7 +35,7 @@ class ProductAnalysisMapperTest {
|
||||
val expected = ProductAnalysisTestData.analysisPresent(
|
||||
productId = "id1",
|
||||
reviewGrade = ReviewQualityCheckState.Grade.C,
|
||||
needsAnalysis = false,
|
||||
analysisStatus = AnalysisStatus.UP_TO_DATE,
|
||||
adjustedRating = 3.4f,
|
||||
productUrl = "https://example.com",
|
||||
highlights = sortedMapOf(
|
||||
@ -54,7 +55,7 @@ class ProductAnalysisMapperTest {
|
||||
val actual = ProductAnalysisTestData.productAnalysis(
|
||||
productId = "id1",
|
||||
grade = "C",
|
||||
needsAnalysis = false,
|
||||
needsAnalysis = true,
|
||||
adjustedRating = 3.4,
|
||||
analysisURL = "https://example.com",
|
||||
highlights = Highlight(
|
||||
@ -69,7 +70,7 @@ class ProductAnalysisMapperTest {
|
||||
val expected = ProductAnalysisTestData.analysisPresent(
|
||||
productId = "id1",
|
||||
reviewGrade = ReviewQualityCheckState.Grade.C,
|
||||
needsAnalysis = false,
|
||||
analysisStatus = AnalysisStatus.NEEDS_ANALYSIS,
|
||||
adjustedRating = 3.4f,
|
||||
productUrl = "https://example.com",
|
||||
highlights = sortedMapOf(
|
||||
@ -95,7 +96,7 @@ class ProductAnalysisMapperTest {
|
||||
val expected = ProductAnalysisTestData.analysisPresent(
|
||||
productId = "id1",
|
||||
reviewGrade = null,
|
||||
needsAnalysis = false,
|
||||
analysisStatus = AnalysisStatus.UP_TO_DATE,
|
||||
adjustedRating = 3.4f,
|
||||
productUrl = "https://example.com",
|
||||
)
|
||||
@ -128,7 +129,7 @@ class ProductAnalysisMapperTest {
|
||||
adjustedRating = 0.0,
|
||||
highlights = null,
|
||||
).toProductReviewState()
|
||||
val expected = ReviewQualityCheckState.OptedIn.ProductReviewState.NoAnalysisPresent
|
||||
val expected = ReviewQualityCheckState.OptedIn.ProductReviewState.NoAnalysisPresent()
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertThrows
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.OptedIn.ProductReviewState.AnalysisPresent
|
||||
import org.mozilla.fenix.shopping.ProductAnalysisTestData
|
||||
|
||||
class ReviewQualityCheckStateTest {
|
||||
|
||||
@ -73,12 +73,9 @@ class ReviewQualityCheckStateTest {
|
||||
@Test
|
||||
fun `WHEN AnalysisPresent is created with grade, rating and highlights as null THEN exception is thrown`() {
|
||||
assertThrows(IllegalArgumentException::class.java) {
|
||||
AnalysisPresent(
|
||||
productId = "",
|
||||
ProductAnalysisTestData.analysisPresent(
|
||||
reviewGrade = null,
|
||||
needsAnalysis = false,
|
||||
adjustedRating = null,
|
||||
productUrl = "",
|
||||
highlights = null,
|
||||
)
|
||||
}
|
||||
@ -87,34 +84,25 @@ class ReviewQualityCheckStateTest {
|
||||
@Test
|
||||
fun `WHEN AnalysisPresent is created with at least one of grade, rating and highlights as not null THEN no exception is thrown`() {
|
||||
val ratingPresent = kotlin.runCatching {
|
||||
AnalysisPresent(
|
||||
productId = "1",
|
||||
ProductAnalysisTestData.analysisPresent(
|
||||
reviewGrade = null,
|
||||
needsAnalysis = false,
|
||||
adjustedRating = 1.2f,
|
||||
productUrl = "",
|
||||
highlights = null,
|
||||
)
|
||||
}
|
||||
|
||||
val gradePresent = kotlin.runCatching {
|
||||
AnalysisPresent(
|
||||
productId = "2",
|
||||
ProductAnalysisTestData.analysisPresent(
|
||||
reviewGrade = ReviewQualityCheckState.Grade.A,
|
||||
needsAnalysis = false,
|
||||
adjustedRating = null,
|
||||
productUrl = "",
|
||||
highlights = null,
|
||||
)
|
||||
}
|
||||
|
||||
val highlightsPresent = kotlin.runCatching {
|
||||
AnalysisPresent(
|
||||
productId = "2",
|
||||
ProductAnalysisTestData.analysisPresent(
|
||||
reviewGrade = null,
|
||||
needsAnalysis = false,
|
||||
adjustedRating = null,
|
||||
productUrl = "",
|
||||
highlights = sortedMapOf(
|
||||
ReviewQualityCheckState.HighlightType.QUALITY to listOf(""),
|
||||
),
|
||||
@ -155,12 +143,7 @@ class ReviewQualityCheckStateTest {
|
||||
"Unbeatable deals",
|
||||
),
|
||||
)
|
||||
val analysis = AnalysisPresent(
|
||||
productId = "1",
|
||||
reviewGrade = ReviewQualityCheckState.Grade.A,
|
||||
needsAnalysis = false,
|
||||
adjustedRating = 4.2f,
|
||||
productUrl = "",
|
||||
val analysis = ProductAnalysisTestData.analysisPresent(
|
||||
highlights = highlights,
|
||||
)
|
||||
|
||||
@ -173,12 +156,7 @@ class ReviewQualityCheckStateTest {
|
||||
val highlights = sortedMapOf(
|
||||
ReviewQualityCheckState.HighlightType.PRICE to listOf("Affordable prices"),
|
||||
)
|
||||
val analysis = AnalysisPresent(
|
||||
productId = "1",
|
||||
reviewGrade = ReviewQualityCheckState.Grade.A,
|
||||
needsAnalysis = false,
|
||||
adjustedRating = 4.2f,
|
||||
productUrl = "",
|
||||
val analysis = ProductAnalysisTestData.analysisPresent(
|
||||
highlights = highlights,
|
||||
)
|
||||
|
||||
@ -194,12 +172,7 @@ class ReviewQualityCheckStateTest {
|
||||
"Free shipping options",
|
||||
),
|
||||
)
|
||||
val analysis = AnalysisPresent(
|
||||
productId = "1",
|
||||
reviewGrade = ReviewQualityCheckState.Grade.A,
|
||||
needsAnalysis = false,
|
||||
adjustedRating = 4.2f,
|
||||
productUrl = "",
|
||||
val analysis = ProductAnalysisTestData.analysisPresent(
|
||||
highlights = highlights,
|
||||
)
|
||||
|
||||
@ -216,12 +189,7 @@ class ReviewQualityCheckStateTest {
|
||||
"Express delivery",
|
||||
),
|
||||
)
|
||||
val analysis = AnalysisPresent(
|
||||
productId = "1",
|
||||
reviewGrade = ReviewQualityCheckState.Grade.A,
|
||||
needsAnalysis = false,
|
||||
adjustedRating = 4.2f,
|
||||
productUrl = "",
|
||||
val analysis = ProductAnalysisTestData.analysisPresent(
|
||||
highlights = highlights,
|
||||
)
|
||||
|
||||
@ -246,12 +214,7 @@ class ReviewQualityCheckStateTest {
|
||||
"Unbeatable deals",
|
||||
),
|
||||
)
|
||||
val analysis = AnalysisPresent(
|
||||
productId = "1",
|
||||
reviewGrade = ReviewQualityCheckState.Grade.A,
|
||||
needsAnalysis = false,
|
||||
adjustedRating = 4.2f,
|
||||
productUrl = "",
|
||||
val analysis = ProductAnalysisTestData.analysisPresent(
|
||||
highlights = highlights,
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user