From 1dbf0145d5ad65af652700eac59e6ebd7c201b48 Mon Sep 17 00:00:00 2001 From: ohall-m Date: Wed, 24 Jan 2024 13:02:23 -0500 Subject: [PATCH] Bug 1876332 - Refactoring out Translations Controller and Interactor This patch refactors out the translations controller and interactor to transition fully to a redux pattern. Leaving the translations use cases for reference browser usage. --- .../translations/TranslationsController.kt | 84 ----------------- .../TranslationsDialogFragment.kt | 19 +--- .../translations/TranslationsInteractor.kt | 54 ----------- .../TranslationsControllerTest.kt | 94 ------------------- .../TranslationsInteractorTest.kt | 78 --------------- 5 files changed, 1 insertion(+), 328 deletions(-) delete mode 100644 app/src/main/java/org/mozilla/fenix/translations/TranslationsController.kt delete mode 100644 app/src/main/java/org/mozilla/fenix/translations/TranslationsInteractor.kt delete mode 100644 app/src/test/java/org/mozilla/fenix/components/translations/TranslationsControllerTest.kt delete mode 100644 app/src/test/java/org/mozilla/fenix/components/translations/TranslationsInteractorTest.kt diff --git a/app/src/main/java/org/mozilla/fenix/translations/TranslationsController.kt b/app/src/main/java/org/mozilla/fenix/translations/TranslationsController.kt deleted file mode 100644 index f29014ae8d..0000000000 --- a/app/src/main/java/org/mozilla/fenix/translations/TranslationsController.kt +++ /dev/null @@ -1,84 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.fenix.translations - -import mozilla.components.browser.state.selector.findTab -import mozilla.components.browser.state.store.BrowserStore -import mozilla.components.concept.engine.translate.DetectedLanguages -import mozilla.components.concept.engine.translate.TranslationOptions -import mozilla.components.feature.session.SessionUseCases -import mozilla.components.support.base.log.logger.Logger - -/** - * Manages requests to complete operations with other components. - * - * @param translationUseCase The use case for performing a translation. - * @param browserStore The browser store to use for this controller. - * @param tabId The tab to perform operations or complete requests for. - */ -class TranslationsController( - private val translationUseCase: SessionUseCases.TranslateUseCase, - private val browserStore: BrowserStore, - private val tabId: String, - -) { - private val logger = Logger("TranslationsController") - - /** - * Retrieves detected information about the language on the browser page, the user's preferred - * language, and if the detected page language is supported. - * - * @return The [DetectedLanguages] object that contains page and user preference information. - */ - fun getDetectedLanguages(): DetectedLanguages? { - logger.info("Retrieving translations language support from the browser store.") - return browserStore.state.findTab(tabId)?.translationsState?.translationEngineState?.detectedLanguages - } - - /** - * Translates the page on the given [tabId]. Will fallback to default expectations if - * [fromLanguage] and [toLanguage] are not provided. - * - * @param tabId The ID of the tab to translate. - * @param fromLanguage The BCP-47 language code to translate from. If null, the default will - * be set to the page language. - * @param toLanguage The BCP-47 language code to translate to. If null, the default will - * be set to the user's preferred language. - * @param options Optional options to specify and additional criteria for the translation. - */ - fun translate( - tabId: String?, - fromLanguage: String?, - toLanguage: String?, - options: TranslationOptions?, - ) { - if (fromLanguage != null && toLanguage != null) { - logger.info("Requesting a translation.") - translationUseCase.invoke(tabId, fromLanguage, toLanguage, options) - return - } - - // Fallback to find defaults - var defaultFromLanguage = fromLanguage - var defaultToLanguage = toLanguage - val detectedLanguages = getDetectedLanguages() - - if (defaultFromLanguage == null) { - defaultFromLanguage = detectedLanguages?.documentLangTag - logger.info("Setting translating to use a default 'from' of $defaultFromLanguage.") - } - - if (defaultToLanguage == null) { - defaultToLanguage = detectedLanguages?.userPreferredLangTag - logger.info("Setting translating to use a default 'to' of $defaultToLanguage.") - } - - if (defaultFromLanguage != null && defaultToLanguage != null) { - logger.info("Requesting a translation based on defaults.") - translationUseCase.invoke(tabId, defaultFromLanguage, defaultToLanguage, options) - return - } - } -} 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 78c0cd73ab..442bd81124 100644 --- a/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/translations/TranslationsDialogFragment.kt @@ -26,7 +26,6 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R -import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.settings import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.theme.FirefoxTheme @@ -45,7 +44,6 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() { private var behavior: BottomSheetBehavior? = null private val args by navArgs() - private lateinit var interactor: TranslationsInteractor override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = super.onCreateDialog(savedInstanceState).apply { @@ -63,14 +61,6 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() { container: ViewGroup?, savedInstanceState: Bundle?, ): View = ComposeView(requireContext()).apply { - interactor = TranslationsInteractor( - translationsController = TranslationsController( - translationUseCase = requireComponents.useCases.sessionUseCases.translate, - browserStore = requireComponents.core.store, - tabId = args.sessionId, - ), - ) - setContent { FirefoxTheme { var translationsVisibility by remember { @@ -125,14 +115,7 @@ class TranslationsDialogFragment : BottomSheetDialogFragment() { from = BrowserDirection.FromTranslationsDialogFragment, ) }, - onTranslateButtonClick = { - interactor.onTranslate( - tabId = args.sessionId, - fromLanguage = null, - toLanguage = null, - null, - ) - }, + onTranslateButtonClick = {}, onNotNowButtonClick = { dismiss() }, ) } diff --git a/app/src/main/java/org/mozilla/fenix/translations/TranslationsInteractor.kt b/app/src/main/java/org/mozilla/fenix/translations/TranslationsInteractor.kt deleted file mode 100644 index cf98bd6163..0000000000 --- a/app/src/main/java/org/mozilla/fenix/translations/TranslationsInteractor.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.fenix.translations - -import mozilla.components.concept.engine.translate.DetectedLanguages -import mozilla.components.concept.engine.translate.TranslationOptions -import mozilla.components.support.base.log.logger.Logger - -/** - * Manages coordinating the functionality interactions for use in the views. - * - * @param translationsController The translations controller that requests data and - * interactions. - */ -class TranslationsInteractor( - private val translationsController: TranslationsController, -) { - private val logger = Logger("TranslationsInteractor") - - /** - * Retrieves the [DetectedLanguages] applicable to the page. - * - * @return The [DetectedLanguages] object that contains page and user preference information. - */ - fun detectedLanguages(): DetectedLanguages? { - logger.info("Requesting translations language support from the controller.") - return translationsController.getDetectedLanguages() - } - - /** - * Translates the page on the given [tabId]. - * If null is provided for [fromLanguage] or [toLanguage], the engine will attempt to - * find a sensible default. - * - * @param tabId The ID of the tab to translate. - * @param fromLanguage The BCP-47 language code to translate from. Usually will be the detected - * page language. If set as null, will revert to a default page language, if known. - * @param toLanguage The BCP-47 language code to translate to. Usually will be the user's - * preferred language. If set as null, will revert to a default of the user's preferred - * language, if known. - * @param options Optional options to specify and additional criteria for the translation. - */ - fun onTranslate( - tabId: String?, - fromLanguage: String?, - toLanguage: String?, - options: TranslationOptions?, - ) { - logger.info("Requesting a translation from the controller.") - translationsController.translate(tabId, fromLanguage, toLanguage, options) - } -} diff --git a/app/src/test/java/org/mozilla/fenix/components/translations/TranslationsControllerTest.kt b/app/src/test/java/org/mozilla/fenix/components/translations/TranslationsControllerTest.kt deleted file mode 100644 index a9b5800610..0000000000 --- a/app/src/test/java/org/mozilla/fenix/components/translations/TranslationsControllerTest.kt +++ /dev/null @@ -1,94 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.fenix.components.translations - -import mozilla.components.browser.state.selector.findTab -import mozilla.components.browser.state.state.BrowserState -import mozilla.components.browser.state.state.TabSessionState -import mozilla.components.browser.state.state.TranslationsState -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.TranslationEngineState -import mozilla.components.concept.engine.translate.TranslationOptions -import mozilla.components.feature.session.SessionUseCases -import mozilla.components.support.test.mock -import mozilla.components.support.test.whenever -import org.junit.Assert.assertNotNull -import org.junit.Assert.assertTrue -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mockito.spy -import org.mockito.Mockito.verify -import org.mozilla.fenix.helpers.FenixRobolectricTestRunner -import org.mozilla.fenix.translations.TranslationsController - -@RunWith(FenixRobolectricTestRunner::class) -class TranslationsControllerTest { - - val tab: TabSessionState = spy( - createTab( - url = "https://www.firefox.com", - title = "Firefox", - id = "1", - ), - ) - private val tabs = spy(listOf(tab)) - private val browserState = spy(BrowserState(tabs = tabs)) - private val browserStore = spy(BrowserStore(browserState)) - - private val translationsUseCase: SessionUseCases.TranslateUseCase = mock() - private val translationsController = spy(TranslationsController(translationUseCase = translationsUseCase, browserStore = browserStore, tabId = tab.id)) - - @Test - fun `Controller translate called the translate use case as expected`() { - val from = "en" - val to = "es" - val options = TranslationOptions(false) - translationsController.translate(tab.id, from, to, options) - verify(translationsUseCase).invoke(tab.id, from, to, options) - } - - @Test - fun `Controller translate called the translate use case as expected when languages were null`() { - val mockFrom = "es" - val mockTo = "en" - val mockDetectedLanguages = DetectedLanguages( - documentLangTag = mockFrom, - supportedDocumentLang = true, - userPreferredLangTag = mockTo, - ) - whenever(translationsController.getDetectedLanguages()).thenReturn(mockDetectedLanguages) - - val from = null - val to = null - val options = TranslationOptions(false) - translationsController.translate(tab.id, from, to, options) - - verify(translationsUseCase).invoke(tab.id, mockFrom, mockTo, options) - } - - @Test - fun `Controller detectedLanguages retrieved the languages as expected`() { - val mockFrom = "es" - val mockTo = "en" - val mockDetectedLanguages = DetectedLanguages( - documentLangTag = mockFrom, - supportedDocumentLang = true, - userPreferredLangTag = mockTo, - ) - val mockState = TranslationsState( - translationEngineState = TranslationEngineState(mockDetectedLanguages), - ) - - whenever(browserState.findTab(tab.id)?.translationsState).thenReturn(mockState) - - val test = translationsController.getDetectedLanguages() - - assertNotNull(test) - assertTrue(test?.documentLangTag == mockDetectedLanguages.documentLangTag) - assertTrue(test?.userPreferredLangTag == mockDetectedLanguages.userPreferredLangTag) - } -} diff --git a/app/src/test/java/org/mozilla/fenix/components/translations/TranslationsInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/components/translations/TranslationsInteractorTest.kt deleted file mode 100644 index e367aa0563..0000000000 --- a/app/src/test/java/org/mozilla/fenix/components/translations/TranslationsInteractorTest.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.fenix.components.translations - -import mozilla.components.browser.state.state.BrowserState -import mozilla.components.browser.state.state.TabSessionState -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.TranslationOptions -import mozilla.components.feature.session.SessionUseCases -import mozilla.components.support.test.mock -import mozilla.components.support.test.whenever -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mockito.never -import org.mockito.Mockito.spy -import org.mockito.Mockito.verify -import org.mozilla.fenix.helpers.FenixRobolectricTestRunner -import org.mozilla.fenix.translations.TranslationsController -import org.mozilla.fenix.translations.TranslationsInteractor - -@RunWith(FenixRobolectricTestRunner::class) -class TranslationsInteractorTest { - - val tab: TabSessionState = spy( - createTab( - url = "https://www.firefox.com", - title = "Firefox", - id = "1", - ), - ) - private val tabs = spy(listOf(tab)) - private val browserState = spy(BrowserState(tabs = tabs)) - private val browserStore = spy(BrowserStore(browserState)) - - private val translationsUseCase: SessionUseCases.TranslateUseCase = mock() - private val translationsController = spy(TranslationsController(translationUseCase = translationsUseCase, browserStore = browserStore, tabId = tab.id)) - private val interactor = TranslationsInteractor(translationsController) - - @Test - fun `Interactor onTranslate called the translate controller as expected`() { - val from = "en" - val to = "es" - val options = TranslationOptions(false) - interactor.onTranslate(tab.id, from, to, options) - verify(translationsController).translate(tab.id, from, to, options) - verify(translationsController, never()).getDetectedLanguages() - } - - @Test - fun `Interactor onTranslate called the translate controller as expected when languages are null`() { - val mockFrom = "es" - val mockTo = "en" - val mockDetectedLanguages = DetectedLanguages( - documentLangTag = mockFrom, - supportedDocumentLang = true, - userPreferredLangTag = mockTo, - ) - whenever(translationsController.getDetectedLanguages()).thenReturn(mockDetectedLanguages) - - val from = null - val to = null - val options = TranslationOptions(false) - interactor.onTranslate(tab.id, from, to, options) - verify(translationsController).translate(tab.id, from, to, options) - verify(translationsController).getDetectedLanguages() - verify(translationsUseCase).invoke(tab.id, mockFrom, mockTo, options) - } - - @Test - fun `Interactor detectedLanguages called the controller to pull detected languages`() { - interactor.detectedLanguages() - verify(translationsController).getDetectedLanguages() - } -}