From 9656f1f95e307d35acbdaf8abc3ff81678eda0c8 Mon Sep 17 00:00:00 2001 From: iorgamgabriel Date: Tue, 27 Feb 2024 16:51:24 +0200 Subject: [PATCH] Bug 1862289 - Translations UI Integration Low Data Translate --- .../translations/TranslationsDialogBinding.kt | 26 ++++-- .../TranslationsDialogFragment.kt | 79 +++++++++++++++++-- .../TranslationsDialogMiddleware.kt | 10 +++ .../translations/TranslationsDialogStore.kt | 39 ++++++++- .../DownloadLanguageFileDialog.kt | 67 ++++++++++++---- .../LanguageDialogPreferenceFragment.kt | 9 ++- app/src/main/res/values/strings.xml | 6 ++ .../TranslationsDialogBindingTest.kt | 46 +++++++++++ .../TranslationsDialogMiddlewareTest.kt | 31 ++++++++ .../TranslationsDialogReducerTest.kt | 49 ++++++++++++ 10 files changed, 330 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt b/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt index e8f002b57..8b106096c 100644 --- a/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt +++ b/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogBinding.kt @@ -77,12 +77,14 @@ class TranslationsDialogBinding( // Session Translations State Behavior (Tab) val sessionTranslationsState = state.sessionState.translationsState + val fromSelected = sessionTranslationsState.translationEngineState?.initialFromLanguage( translateFromLanguages, ) - fromSelected?.let { + // Dispatch initialFrom Language only the first time when it is null. + if (fromSelected != null && translationsDialogStore.state.initialFrom == null) { translationsDialogStore.dispatch( TranslationsDialogAction.UpdateFromSelectedLanguage( fromSelected, @@ -94,7 +96,9 @@ class TranslationsDialogBinding( sessionTranslationsState.translationEngineState?.initialToLanguage( translateToLanguages, ) - toSelected?.let { + + // Dispatch initialTo Language only the first time when it is null. + if (toSelected != null && translationsDialogStore.state.initialTo == null) { translationsDialogStore.dispatch( TranslationsDialogAction.UpdateToSelectedLanguage( toSelected, @@ -130,6 +134,12 @@ class TranslationsDialogBinding( TranslationsDialogAction.UpdateTranslationError(sessionTranslationsState.translationError), ) } + + sessionTranslationsState.translationDownloadSize?.let { + translationsDialogStore.dispatch( + TranslationsDialogAction.UpdateDownloadTranslationDownloadSize(it), + ) + } } } @@ -153,11 +163,13 @@ class TranslationsDialogBinding( ), ) - translationsDialogStore.dispatch( - TranslationsDialogAction.UpdateTranslated( - true, - ), - ) + if (!translationsDialogStore.state.isTranslated) { + translationsDialogStore.dispatch( + TranslationsDialogAction.UpdateTranslated( + true, + ), + ) + } if (translationsDialogStore.state.dismissDialogState == DismissDialogState.WaitingToBeDismissed) { translationsDialogStore.dispatch( diff --git a/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt index c8c6034c1..1fdb42af7 100644 --- a/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt @@ -35,10 +35,14 @@ import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R +import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.settings import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.theme.FirefoxTheme +import org.mozilla.fenix.translations.preferences.downloadlanguages.DownloadLanguageFileDialog +import org.mozilla.fenix.translations.preferences.downloadlanguages.DownloadLanguageFileDialogType +import org.mozilla.fenix.translations.preferences.downloadlanguages.DownloadLanguagesFeature /** * The enum is to know what bottom sheet to open. @@ -56,8 +60,11 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() { private val args by navArgs() private val browserStore: BrowserStore by lazy { requireComponents.core.store } private val translationDialogBinding = ViewBoundFeatureWrapper() + private val downloadLanguagesFeature = + ViewBoundFeatureWrapper() private lateinit var translationsDialogStore: TranslationsDialogStore private var isTranslationInProgress: Boolean? = null + private var isDataSaverEnabledAndWifiDisabled = false override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = super.onCreateDialog(savedInstanceState).apply { @@ -192,9 +199,22 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() { view = view, ) translationsDialogStore.dispatch(TranslationsDialogAction.InitTranslationsDialog) + + downloadLanguagesFeature.set( + feature = DownloadLanguagesFeature( + context = requireContext(), + wifiConnectionMonitor = requireContext().components.wifiConnectionMonitor, + onDataSaverAndWifiChanged = { + isDataSaverEnabledAndWifiDisabled = it + }, + ), + owner = this, + view = view, + ) } @Composable + @Suppress("LongMethod") private fun TranslationsDialogContent(learnMoreUrl: String, onSettingClicked: () -> Unit) { val translationsDialogState = translationsDialogStore.observeAsComposableState { it }.value @@ -206,6 +226,10 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() { dismissDialog() } + var showDownloadLanguageFileDialog by remember { + mutableStateOf(false) + } + TranslationsDialog( translationsDialogState = translationsDialogState, learnMoreUrl = learnMoreUrl, @@ -216,7 +240,15 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() { if (state.error is TranslationError.CouldNotLoadLanguagesError) { translationsDialogStore.dispatch(TranslationsDialogAction.FetchSupportedLanguages) } else { - translationsDialogStore.dispatch(TranslationsDialogAction.TranslateAction) + if ( + isDataSaverEnabledAndWifiDisabled && + !requireContext().settings().ignoreTranslationsDataSaverWarning && + state.translationDownloadSize != null + ) { + showDownloadLanguageFileDialog = true + } else { + translationsDialogStore.dispatch(TranslationsDialogAction.TranslateAction) + } } }, onNegativeButtonClicked = { @@ -225,21 +257,58 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() { } dismiss() }, - onFromSelected = { + onFromSelected = { fromLanguage -> + state.initialTo?.let { + translationsDialogStore.dispatch( + TranslationsDialogAction.FetchDownloadFileSizeAction( + toLanguage = it, + fromLanguage = fromLanguage, + ), + ) + } + translationsDialogStore.dispatch( TranslationsDialogAction.UpdateFromSelectedLanguage( - it, + fromLanguage, ), ) }, - onToSelected = { + onToSelected = { toLanguage -> + state.initialFrom?.let { + translationsDialogStore.dispatch( + TranslationsDialogAction.FetchDownloadFileSizeAction( + toLanguage = toLanguage, + fromLanguage = it, + ), + ) + } + translationsDialogStore.dispatch( TranslationsDialogAction.UpdateToSelectedLanguage( - it, + toLanguage, ), ) }, ) + + var checkBoxEnabled by remember { mutableStateOf(false) } + if (showDownloadLanguageFileDialog) { + state.translationDownloadSize?.size?.let { fileSize -> + DownloadLanguageFileDialog( + downloadLanguageDialogType = DownloadLanguageFileDialogType.TranslationRequest, + fileSize = fileSize, + isCheckBoxEnabled = checkBoxEnabled, + onSavingModeStateChange = { checkBoxEnabled = it }, + onConfirmDownload = { + requireContext().settings().ignoreTranslationsDataSaverWarning = + checkBoxEnabled + showDownloadLanguageFileDialog = false + translationsDialogStore.dispatch(TranslationsDialogAction.TranslateAction) + }, + onCancel = { showDownloadLanguageFileDialog = false }, + ) + } + } } } diff --git a/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogMiddleware.kt b/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogMiddleware.kt index 39819732e..6671843b5 100644 --- a/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogMiddleware.kt +++ b/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogMiddleware.kt @@ -24,6 +24,16 @@ class TranslationsDialogMiddleware( action: TranslationsDialogAction, ) { when (action) { + is TranslationsDialogAction.FetchDownloadFileSizeAction -> { + browserStore.dispatch( + TranslationsAction.FetchTranslationDownloadSizeAction( + tabId = sessionId, + fromLanguage = action.fromLanguage, + toLanguage = action.toLanguage, + ), + ) + } + is TranslationsDialogAction.FetchSupportedLanguages -> { browserStore.dispatch( TranslationsAction.OperationRequestedAction( diff --git a/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogStore.kt b/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogStore.kt index f97d1e0e6..a02fb9027 100644 --- a/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogStore.kt +++ b/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogStore.kt @@ -6,6 +6,7 @@ package org.mozilla.fenix.translations import mozilla.components.browser.state.action.TranslationsAction import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.translate.Language +import mozilla.components.concept.engine.translate.TranslationDownloadSize import mozilla.components.concept.engine.translate.TranslationError import mozilla.components.lib.state.Action import mozilla.components.lib.state.Middleware @@ -33,6 +34,8 @@ class TranslationsDialogStore( * @property isTranslated The page is currently translated. * @property isTranslationInProgress The page is currently attempting a translation. * @property positiveButtonType Can be enabled,disabled or in progress. + * @property translationDownloadSize A data class to contain information + * related to the download size required for a given translation to/from pair. * @property error An error that can occur during the translation process. * @property dismissDialogState Whether the dialog bottom sheet should be dismissed. * @property initialFrom Initial "from" language, based on the translation state and page state. @@ -45,6 +48,7 @@ data class TranslationsDialogState( var isTranslated: Boolean = false, val isTranslationInProgress: Boolean = false, val positiveButtonType: PositiveButtonType? = null, + val translationDownloadSize: TranslationDownloadSize? = null, val error: TranslationError? = null, val dismissDialogState: DismissDialogState? = null, val initialFrom: Language? = null, @@ -139,6 +143,18 @@ sealed class TranslationsDialogAction : Action { * Updates the dialog title if the page was translated. */ data class UpdateTranslatedPageTitle(val title: String) : TranslationsDialogAction() + + /** + * Updates the translation download file size. + */ + data class UpdateDownloadTranslationDownloadSize(val translationDownloadSize: TranslationDownloadSize? = null) : + TranslationsDialogAction() + + /** + * Fetch the translation download file size. + */ + data class FetchDownloadFileSizeAction(val toLanguage: Language, val fromLanguage: Language) : + TranslationsDialogAction() } /** @@ -248,9 +264,7 @@ internal object TranslationsDialogReducer { is TranslationsDialogAction.UpdateTranslationError -> { state.copy( error = action.translationError, - positiveButtonType = if ( - action.translationError is TranslationError.LanguageNotSupportedError - ) { + positiveButtonType = if (action.translationError is TranslationError.LanguageNotSupportedError) { PositiveButtonType.Disabled } else { PositiveButtonType.Enabled @@ -269,13 +283,32 @@ internal object TranslationsDialogReducer { state.copy(translatedPageTitle = action.title) } + is TranslationsDialogAction.UpdateDownloadTranslationDownloadSize -> { + state.copy( + translationDownloadSize = if ( + action.translationDownloadSize?.fromLanguage == state.initialFrom && + action.translationDownloadSize?.toLanguage == state.initialTo && + isTranslationDownloadSizeValid(action.translationDownloadSize) + ) { + action.translationDownloadSize + } else { + null + }, + ) + } + is TranslationsDialogAction.TranslateAction, TranslationsDialogAction.FetchSupportedLanguages, TranslationsDialogAction.RestoreTranslation, + is TranslationsDialogAction.FetchDownloadFileSizeAction, -> { // handled by [TranslationsDialogMiddleware] state } } } + + private fun isTranslationDownloadSizeValid(translationDownloadSize: TranslationDownloadSize?) = + translationDownloadSize?.size != 0L && + translationDownloadSize?.error == null } diff --git a/app/src/main/java/org/mozilla/fenix/translations/preferences/downloadlanguages/DownloadLanguageFileDialog.kt b/app/src/main/java/org/mozilla/fenix/translations/preferences/downloadlanguages/DownloadLanguageFileDialog.kt index 45c847b57..3bdf9fb02 100644 --- a/app/src/main/java/org/mozilla/fenix/translations/preferences/downloadlanguages/DownloadLanguageFileDialog.kt +++ b/app/src/main/java/org/mozilla/fenix/translations/preferences/downloadlanguages/DownloadLanguageFileDialog.kt @@ -36,19 +36,19 @@ import org.mozilla.fenix.theme.FirefoxTheme /** * Download Languages File Dialog. - * + * @param downloadLanguageDialogType Whether the download language file item is + * of type all languages,single file translation request or default. * @param fileSize Language file size in bytes that should be displayed in the dialogue title. * @param isCheckBoxEnabled Whether saving mode checkbox is checked or unchecked. - * @param isAllLanguagesItemType Whether the download language file item is of type all languages. * @param onSavingModeStateChange Invoked when the user clicks on the checkbox of the saving mode state. * @param onConfirmDownload Invoked when the user click on the "Download" dialog button. * @param onCancel Invoked when the user clicks on the "Cancel" dialog button. */ @Composable fun DownloadLanguageFileDialog( + downloadLanguageDialogType: DownloadLanguageFileDialogType, fileSize: Long, isCheckBoxEnabled: Boolean, - isAllLanguagesItemType: Boolean, onSavingModeStateChange: (Boolean) -> Unit, onConfirmDownload: () -> Unit, onCancel: () -> Unit, @@ -62,18 +62,29 @@ fun DownloadLanguageFileDialog( ) .padding(16.dp), ) { + val title = + if (downloadLanguageDialogType is DownloadLanguageFileDialogType.TranslationRequest) { + stringResource( + R.string.translations_download_language_file_dialog_title, + fileSize.toMegabyteOrKilobyteString(), + ) + } else { + stringResource( + R.string.download_language_file_dialog_title, + fileSize.toMegabyteOrKilobyteString(), + ) + } Text( - text = stringResource( - R.string.download_language_file_dialog_title, - fileSize.toMegabyteOrKilobyteString(), - ), + text = title, modifier = Modifier .semantics { heading() }, color = FirefoxTheme.colors.textPrimary, style = FirefoxTheme.typography.headline7, ) - if (isAllLanguagesItemType) { + if (downloadLanguageDialogType is DownloadLanguageFileDialogType.AllLanguages || + downloadLanguageDialogType is DownloadLanguageFileDialogType.TranslationRequest + ) { Text( text = stringResource( R.string.download_language_file_dialog_message_all_languages, @@ -89,11 +100,14 @@ fun DownloadLanguageFileDialog( onSavingModeStateChange = onSavingModeStateChange, ) - val primaryButtonText: String = if (isAllLanguagesItemType) { - stringResource(id = R.string.download_language_file_dialog_positive_button_text_all_languages) - } else { - stringResource(id = R.string.download_language_file_dialog_positive_button_text) - } + val primaryButtonText: String = + if (downloadLanguageDialogType is DownloadLanguageFileDialogType.AllLanguages || + downloadLanguageDialogType is DownloadLanguageFileDialogType.TranslationRequest + ) { + stringResource(id = R.string.download_language_file_dialog_positive_button_text_all_languages) + } else { + stringResource(id = R.string.download_language_file_dialog_positive_button_text) + } PrimaryButton( text = primaryButtonText, @@ -163,9 +177,9 @@ private fun DownloadLanguageFileDialogCheckbox( private fun PrefDownloadLanguageFileDialogPreviewAllLanguages() { FirefoxTheme { DownloadLanguageFileDialog( + downloadLanguageDialogType = DownloadLanguageFileDialogType.AllLanguages, fileSize = 4000L, isCheckBoxEnabled = true, - isAllLanguagesItemType = true, onSavingModeStateChange = {}, onConfirmDownload = {}, onCancel = {}, @@ -173,14 +187,37 @@ private fun PrefDownloadLanguageFileDialogPreviewAllLanguages() { } } +/** + * Download Languages File Dialog Type. + */ +sealed class DownloadLanguageFileDialogType { + + /** + * All language files need to be downloaded. + */ + data object AllLanguages : DownloadLanguageFileDialogType() + + /** + * Only one language package needs to be downloaded. + */ + data object Default : DownloadLanguageFileDialogType() + + /** + * When the user presses the translate button, the site needs to be translated. + * To perform this translation, the device will need to download a language model to perform + * this specific translation, if not already downloaded. + */ + data object TranslationRequest : DownloadLanguageFileDialogType() +} + @Composable @LightDarkPreview private fun PrefDownloadLanguageFileDialogPreview() { FirefoxTheme { DownloadLanguageFileDialog( + downloadLanguageDialogType = DownloadLanguageFileDialogType.Default, fileSize = 4000L, isCheckBoxEnabled = false, - isAllLanguagesItemType = false, onSavingModeStateChange = {}, onConfirmDownload = {}, onCancel = {}, diff --git a/app/src/main/java/org/mozilla/fenix/translations/preferences/downloadlanguages/LanguageDialogPreferenceFragment.kt b/app/src/main/java/org/mozilla/fenix/translations/preferences/downloadlanguages/LanguageDialogPreferenceFragment.kt index d8ed724d8..cf3fde6a2 100644 --- a/app/src/main/java/org/mozilla/fenix/translations/preferences/downloadlanguages/LanguageDialogPreferenceFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/translations/preferences/downloadlanguages/LanguageDialogPreferenceFragment.kt @@ -74,10 +74,15 @@ class LanguageDialogPreferenceFragment : DialogFragment() { FirefoxTheme { var checkBoxEnabled by remember { mutableStateOf(false) } DownloadLanguageFileDialog( + downloadLanguageDialogType = if (args.downloadLanguageItemStatePreference.type == + DownloadLanguageItemTypePreference.AllLanguages + ) { + DownloadLanguageFileDialogType.AllLanguages + } else { + DownloadLanguageFileDialogType.Default + }, fileSize = args.itemFileSizePreference, isCheckBoxEnabled = checkBoxEnabled, - isAllLanguagesItemType = args.downloadLanguageItemStatePreference.type == - DownloadLanguageItemTypePreference.AllLanguages, onSavingModeStateChange = { checkBoxEnabled = it }, onConfirmDownload = { requireContext().settings().ignoreTranslationsDataSaverWarning = diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 822f5eae3..e3278f5fd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2377,6 +2377,12 @@ Learn more Translating… + + Download language in data saving mode (%1$s)? + diff --git a/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogBindingTest.kt b/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogBindingTest.kt index 06653a4a1..5a96482b0 100644 --- a/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogBindingTest.kt +++ b/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogBindingTest.kt @@ -11,6 +11,7 @@ import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.translate.DetectedLanguages import mozilla.components.concept.engine.translate.Language +import mozilla.components.concept.engine.translate.TranslationDownloadSize import mozilla.components.concept.engine.translate.TranslationEngineState import mozilla.components.concept.engine.translate.TranslationError import mozilla.components.concept.engine.translate.TranslationOperation @@ -303,4 +304,49 @@ class TranslationsDialogBindingTest { TranslationsDialogAction.UpdateTranslationError(fetchError), ) } + + @Test + fun `WHEN set translation download size action sent to the browserStore THEN update translation dialog store based on operation`() = + runTestOnMain { + translationsDialogStore = + spy(TranslationsDialogStore(TranslationsDialogState())) + browserStore = BrowserStore( + BrowserState( + tabs = listOf(tab), + selectedTabId = tabId, + ), + ) + + val binding = TranslationsDialogBinding( + browserStore = browserStore, + translationsDialogStore = translationsDialogStore, + sessionId = tabId, + getTranslatedPageTitle = { localizedFrom, localizedTo -> + testContext.getString( + R.string.translations_bottom_sheet_title_translation_completed, + localizedFrom, + localizedTo, + ) + }, + ) + binding.start() + + val toLanguage = Language("de", "German") + val fromLanguage = Language("es", "Spanish") + val translationDownloadSize = TranslationDownloadSize( + fromLanguage = fromLanguage, + toLanguage = toLanguage, + size = 1000L, + ) + browserStore.dispatch( + TranslationsAction.SetTranslationDownloadSizeAction( + tabId = tab.id, + translationSize = translationDownloadSize, + ), + ).joinBlocking() + + verify(translationsDialogStore).dispatch( + TranslationsDialogAction.UpdateDownloadTranslationDownloadSize(translationDownloadSize), + ) + } } diff --git a/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogMiddlewareTest.kt b/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogMiddlewareTest.kt index 178b4ec86..4f540b252 100644 --- a/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogMiddlewareTest.kt +++ b/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogMiddlewareTest.kt @@ -98,4 +98,35 @@ class TranslationsDialogMiddlewareTest { ) } } + + @Test + fun `GIVEN translationState WHEN FetchDownloadFileSizeAction from TranslationDialogStore is called THEN call FetchTranslationDownloadSizeAction from BrowserStore`() = + runTest { + val browserStore = mockk(relaxed = true) + val translationsDialogMiddleware = + TranslationsDialogMiddleware(browserStore = browserStore, sessionId = "tab1") + + val translationStore = TranslationsDialogStore( + initialState = TranslationsDialogState(), + middlewares = listOf(translationsDialogMiddleware), + ) + translationStore.dispatch( + TranslationsDialogAction.FetchDownloadFileSizeAction( + toLanguage = Language("en", "English"), + fromLanguage = Language("fr", "France"), + ), + ).joinBlocking() + + translationStore.waitUntilIdle() + + verify { + browserStore.dispatch( + TranslationsAction.FetchTranslationDownloadSizeAction( + tabId = "tab1", + fromLanguage = Language("fr", "France"), + toLanguage = Language("en", "English"), + ), + ) + } + } } diff --git a/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogReducerTest.kt b/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogReducerTest.kt index 0aa43d4d2..a70b33548 100644 --- a/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogReducerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/translations/TranslationsDialogReducerTest.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.translations import mozilla.components.concept.engine.translate.Language +import mozilla.components.concept.engine.translate.TranslationDownloadSize import mozilla.components.concept.engine.translate.TranslationError import mozilla.components.support.test.robolectric.testContext import org.junit.Assert.assertEquals @@ -226,4 +227,52 @@ class TranslationsDialogReducerTest { updatedState.translatedPageTitle, ) } + + @Test + fun `WHEN the reducer is called for UpdateDownloadTranslationDownloadSize THEN a new state with translationDownloadSize is returned`() { + val spanishLanguage = Language("es", "Spanish") + val englishLanguage = Language("en", "English") + val translationsDialogState = + TranslationsDialogState(initialTo = englishLanguage, initialFrom = spanishLanguage) + val translationDownloadSize = TranslationDownloadSize( + fromLanguage = spanishLanguage, + toLanguage = englishLanguage, + size = 1000L, + ) + val updatedState = TranslationsDialogReducer.reduce( + translationsDialogState, + TranslationsDialogAction.UpdateDownloadTranslationDownloadSize( + translationDownloadSize, + ), + ) + + assertEquals( + translationDownloadSize, + updatedState.translationDownloadSize, + ) + } + + @Test + fun `WHEN the reducer is called for UpdateDownloadTranslationDownloadSize with a invalid object THEN a new state with translationDownloadSize null is returned`() { + val spanishLanguage = Language("es", "Spanish") + val englishLanguage = Language("en", "English") + val translationsDialogState = + TranslationsDialogState(initialTo = englishLanguage, initialFrom = spanishLanguage) + val translationDownloadSize = TranslationDownloadSize( + fromLanguage = englishLanguage, + toLanguage = spanishLanguage, + size = 0L, + ) + val updatedState = TranslationsDialogReducer.reduce( + translationsDialogState, + TranslationsDialogAction.UpdateDownloadTranslationDownloadSize( + translationDownloadSize, + ), + ) + + assertEquals( + null, + updatedState.translationDownloadSize, + ) + } }