diff --git a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/promptslist/usecase/FetchBloggingPromptsListUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/promptslist/usecase/FetchBloggingPromptsListUseCase.kt index 5ad5195c362f..859a5b317852 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/promptslist/usecase/FetchBloggingPromptsListUseCase.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/bloggingprompts/promptslist/usecase/FetchBloggingPromptsListUseCase.kt @@ -3,6 +3,7 @@ package org.wordpress.android.ui.bloggingprompts.promptslist.usecase import org.wordpress.android.fluxc.model.bloggingprompts.BloggingPromptModel import org.wordpress.android.fluxc.store.bloggingprompts.BloggingPromptsStore import org.wordpress.android.ui.mysite.SelectedSiteRepository +import org.wordpress.android.util.PerAppLocaleManager import java.time.LocalDate import java.time.ZoneId import java.util.Date @@ -11,6 +12,7 @@ import javax.inject.Inject class FetchBloggingPromptsListUseCase @Inject constructor( private val bloggingPromptsStore: BloggingPromptsStore, private val selectedSiteRepository: SelectedSiteRepository, + private val perAppLocaleManager: PerAppLocaleManager, ) { suspend fun execute(): Result { return fetchBloggingPrompts() @@ -35,7 +37,12 @@ class FetchBloggingPromptsListUseCase @Inject constructor( .let { Date.from(it) } return selectedSiteRepository.getSelectedSite()?.let { site -> - bloggingPromptsStore.fetchPrompts(site, NUMBER_OF_PROMPTS, fromDate) + bloggingPromptsStore.fetchPrompts( + site, + NUMBER_OF_PROMPTS, + fromDate, + perAppLocaleManager.getCurrentLocaleLanguageCode() + ) .takeUnless { it.isError } ?.model } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt index da6e61de3fa1..6bf635515021 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt @@ -25,6 +25,7 @@ import org.wordpress.android.ui.mysite.SiteNavigationAction import org.wordpress.android.ui.pages.SnackbarMessageHolder import org.wordpress.android.ui.prefs.AppPrefsWrapper import org.wordpress.android.ui.utils.UiString +import org.wordpress.android.util.PerAppLocaleManager import org.wordpress.android.viewmodel.Event import java.time.LocalDate import java.time.ZoneId @@ -43,7 +44,8 @@ class BloggingPromptCardViewModelSlice @Inject constructor( private val bloggingPromptsCardTrackHelper: BloggingPromptsCardTrackHelper, private val bloggingPromptsPostTagProvider: BloggingPromptsPostTagProvider, private val bloggingPromptCardBuilder: BloggingPromptCardBuilder, - private val promptsStore: BloggingPromptsStore + private val promptsStore: BloggingPromptsStore, + private val perAppLocaleManager: PerAppLocaleManager ) { private val _onSnackbarMessage = MutableLiveData>() val onSnackbarMessage = _onSnackbarMessage as LiveData> @@ -91,7 +93,12 @@ class BloggingPromptCardViewModelSlice @Inject constructor( isSinglePromptRefresh: Boolean = false ) { val numOfPromptsToFetch = if (isSinglePromptRefresh) 1 else NUM_PROMPTS_TO_REQUEST - val result = promptsStore.fetchPrompts(selectedSite, numOfPromptsToFetch, Date()) + val result = promptsStore.fetchPrompts( + selectedSite, + numOfPromptsToFetch, + Date(), + perAppLocaleManager.getCurrentLocaleLanguageCode() + ) when { result.isError -> postLastState() else -> { diff --git a/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/promptslist/usecase/FetchBloggingPromptsListUseCaseTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/promptslist/usecase/FetchBloggingPromptsListUseCaseTest.kt index c9449aa100b8..981fb04d6a93 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/promptslist/usecase/FetchBloggingPromptsListUseCaseTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/bloggingprompts/promptslist/usecase/FetchBloggingPromptsListUseCaseTest.kt @@ -17,6 +17,7 @@ import org.wordpress.android.ui.bloggingprompts.promptslist.BloggingPromptsListF import org.wordpress.android.ui.bloggingprompts.promptslist.usecase.FetchBloggingPromptsListUseCase.Result.Failure import org.wordpress.android.ui.bloggingprompts.promptslist.usecase.FetchBloggingPromptsListUseCase.Result.Success import org.wordpress.android.ui.mysite.SelectedSiteRepository +import org.wordpress.android.util.PerAppLocaleManager import java.util.Date @ExperimentalCoroutinesApi @@ -26,13 +27,17 @@ class FetchBloggingPromptsListUseCaseTest : BaseUnitTest() { @Mock lateinit var bloggingPromptsStore: BloggingPromptsStore + + @Mock + lateinit var perAppLocaleManager: PerAppLocaleManager lateinit var useCase: FetchBloggingPromptsListUseCase @Before fun setUp() { useCase = FetchBloggingPromptsListUseCase( bloggingPromptsStore = bloggingPromptsStore, - selectedSiteRepository = selectedSiteRepository + selectedSiteRepository = selectedSiteRepository, + perAppLocaleManager = perAppLocaleManager ) } @@ -48,7 +53,8 @@ class FetchBloggingPromptsListUseCaseTest : BaseUnitTest() { @Test fun `given fetching prompts fails, when execute is called, then return failure`() = test { whenever(selectedSiteRepository.getSelectedSite()).thenReturn(SiteModel().apply { id = 1 }) - whenever(bloggingPromptsStore.fetchPrompts(any(), any(), any())) + whenever(perAppLocaleManager.getCurrentLocaleLanguageCode()).thenReturn("en") + whenever(bloggingPromptsStore.fetchPrompts(any(), any(), any(), any())) .thenReturn(BloggingPromptsResult(error = mock())) val result = useCase.execute() @@ -62,7 +68,8 @@ class FetchBloggingPromptsListUseCaseTest : BaseUnitTest() { var initialDate: Date = now var count: Int = 0 whenever(selectedSiteRepository.getSelectedSite()).thenReturn(SiteModel().apply { id = 1 }) - whenever(bloggingPromptsStore.fetchPrompts(any(), any(), any())) + whenever(perAppLocaleManager.getCurrentLocaleLanguageCode()).thenReturn("en") + whenever(bloggingPromptsStore.fetchPrompts(any(), any(), any(), any())) .doSuspendableAnswer { count = it.getArgument(1) initialDate = it.getArgument(2) @@ -97,7 +104,8 @@ class FetchBloggingPromptsListUseCaseTest : BaseUnitTest() { var initialDate: Date = now var count: Int = 0 whenever(selectedSiteRepository.getSelectedSite()).thenReturn(SiteModel().apply { id = 1 }) - whenever(bloggingPromptsStore.fetchPrompts(any(), any(), any())) + whenever(perAppLocaleManager.getCurrentLocaleLanguageCode()).thenReturn("en") + whenever(bloggingPromptsStore.fetchPrompts(any(), any(), any(), any())) .doSuspendableAnswer { count = it.getArgument(1) initialDate = it.getArgument(2) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSliceTest.kt index 4103820b3e7a..a7bcc5696712 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSliceTest.kt @@ -29,6 +29,7 @@ import org.wordpress.android.ui.mysite.SiteNavigationAction import org.wordpress.android.ui.pages.SnackbarMessageHolder import org.wordpress.android.ui.prefs.AppPrefsWrapper import org.wordpress.android.ui.utils.UiString +import org.wordpress.android.util.PerAppLocaleManager @Suppress("LargeClass") @ExperimentalCoroutinesApi @@ -58,6 +59,9 @@ class BloggingPromptCardViewModelSliceTest : BaseUnitTest() { @Mock lateinit var promptsStore: BloggingPromptsStore + @Mock + lateinit var perAppLocaleManager: PerAppLocaleManager + private lateinit var viewModelSlice: BloggingPromptCardViewModelSlice private lateinit var navigationActions: MutableList @@ -83,7 +87,8 @@ class BloggingPromptCardViewModelSliceTest : BaseUnitTest() { bloggingPromptsCardTrackHelper, bloggingPromptsPostTagProvider, bloggingPromptCardBuilder, - promptsStore + promptsStore, + perAppLocaleManager ) whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) diff --git a/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/BaseWPComRestClient.java b/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/BaseWPComRestClient.java index 8123c11f9137..75b148ea8c01 100644 --- a/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/BaseWPComRestClient.java +++ b/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/BaseWPComRestClient.java @@ -73,7 +73,7 @@ public Request add(WPComGsonRequest request) { return add(request, true); } - protected Request add(WPComGsonRequest request, boolean addLocaleParameter) { + public Request add(WPComGsonRequest request, boolean addLocaleParameter) { if (addLocaleParameter) { addLocaleToRequest(request); } diff --git a/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/WPComGsonRequestBuilder.kt b/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/WPComGsonRequestBuilder.kt index 13f06c9c5f18..cdd7ba7aa8ce 100644 --- a/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/WPComGsonRequestBuilder.kt +++ b/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/WPComGsonRequestBuilder.kt @@ -99,7 +99,8 @@ class WPComGsonRequestBuilder type: Type, enableCaching: Boolean = false, cacheTimeToLive: Int = BaseRequest.DEFAULT_CACHE_LIFETIME, - forced: Boolean = false + forced: Boolean = false, + addLocaleParameter: Boolean = true ) = suspendCancellableCoroutine> { cont -> val request = WPComGsonRequest.buildGetRequest(url, params, type, { cont.resume(Success(it)) @@ -113,7 +114,7 @@ class WPComGsonRequestBuilder if (forced) { request.setShouldForceUpdate() } - restClient.add(request) + restClient.add(request, addLocaleParameter) } /** diff --git a/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/bloggingprompts/BloggingPromptsRestClient.kt b/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/bloggingprompts/BloggingPromptsRestClient.kt index 1a9779905e76..612e69870575 100644 --- a/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/bloggingprompts/BloggingPromptsRestClient.kt +++ b/libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/bloggingprompts/BloggingPromptsRestClient.kt @@ -38,12 +38,17 @@ class BloggingPromptsRestClient @Inject constructor( site: SiteModel, perPage: Int, after: Date, + locale: String, ignoresYear: Boolean = true, ): BloggingPromptsPayload { val url = WPCOMV3.sites.site(site.siteId).blogging_prompts.url val params = mutableMapOf( "per_page" to perPage.toString(), - "after" to BloggingPromptsUtils.dateToString(after, ignoresYear) + "after" to BloggingPromptsUtils.dateToString(after, ignoresYear), + // Send the app's language slug (e.g. "tr") explicitly so prompt content is localized. + // The framework's default _locale is region-qualified (e.g. "tr_TR"), which the endpoint + // doesn't resolve, so we disable it below (addLocaleParameter = false) and set our own. + "_locale" to locale ) if (ignoresYear) { // when ignoring the year we force the response to be for the current year @@ -56,7 +61,8 @@ class BloggingPromptsRestClient @Inject constructor( this, url, params, - BloggingPromptsListResponseTypeToken.type + BloggingPromptsListResponseTypeToken.type, + addLocaleParameter = false ) return when (response) { is Success -> BloggingPromptsPayload(response.data) diff --git a/libs/fluxc/src/main/java/org/wordpress/android/fluxc/store/bloggingprompts/BloggingPromptsStore.kt b/libs/fluxc/src/main/java/org/wordpress/android/fluxc/store/bloggingprompts/BloggingPromptsStore.kt index fca34231413b..53a1f5a44aaa 100644 --- a/libs/fluxc/src/main/java/org/wordpress/android/fluxc/store/bloggingprompts/BloggingPromptsStore.kt +++ b/libs/fluxc/src/main/java/org/wordpress/android/fluxc/store/bloggingprompts/BloggingPromptsStore.kt @@ -29,10 +29,11 @@ class BloggingPromptsStore @Inject constructor( suspend fun fetchPrompts( site: SiteModel, number: Int, - from: Date + from: Date, + locale: String ): BloggingPromptsResult> { return coroutineEngine.withDefaultContext(AppLog.T.API, this, "fetchPrompts") { - val payload = restClient.fetchPrompts(site, number, from) + val payload = restClient.fetchPrompts(site, number, from, locale) storePrompts(site, payload) } } diff --git a/libs/fluxc/src/test/java/org/wordpress/android/fluxc/network/rest/wpcom/bloggingprompts/BloggingPromptsRestClientTest.kt b/libs/fluxc/src/test/java/org/wordpress/android/fluxc/network/rest/wpcom/bloggingprompts/BloggingPromptsRestClientTest.kt index b1bb8245fdc8..1862e5a1f7ec 100644 --- a/libs/fluxc/src/test/java/org/wordpress/android/fluxc/network/rest/wpcom/bloggingprompts/BloggingPromptsRestClientTest.kt +++ b/libs/fluxc/src/test/java/org/wordpress/android/fluxc/network/rest/wpcom/bloggingprompts/BloggingPromptsRestClientTest.kt @@ -103,6 +103,7 @@ class BloggingPromptsRestClientTest { private val siteId: Long = 1 private val numberOfPromptsToFetch: Int = 40 + private val locale: String = "en" @Before fun setUp() { @@ -123,7 +124,7 @@ class BloggingPromptsRestClientTest { val json = UnitTestUtils.getStringFromResourceFile(javaClass, PROMPTS_JSON) initFetchPrompts(data = getPromptsResponseFromJsonString(json)) - restClient.fetchPrompts(site, numberOfPromptsToFetch, Date()) + restClient.fetchPrompts(site, numberOfPromptsToFetch, Date(), locale) assertEquals( urlCaptor.firstValue, @@ -131,13 +132,23 @@ class BloggingPromptsRestClientTest { ) } + @Test + fun `when fetch prompts gets triggered, then the given locale is sent as the _locale param`() = test { + val json = UnitTestUtils.getStringFromResourceFile(javaClass, PROMPTS_JSON) + initFetchPrompts(data = getPromptsResponseFromJsonString(json)) + + restClient.fetchPrompts(site, numberOfPromptsToFetch, Date(), locale) + + assertEquals(locale, paramsCaptor.firstValue["_locale"]) + } + @Test fun `given success call, when fetch prompts gets triggered, then prompts response is returned`() = test { val json = UnitTestUtils.getStringFromResourceFile(javaClass, PROMPTS_JSON) initFetchPrompts(data = getPromptsResponseFromJsonString(json)) - val result = restClient.fetchPrompts(site, numberOfPromptsToFetch, Date()) + val result = restClient.fetchPrompts(site, numberOfPromptsToFetch, Date(), locale) assertSuccess(PROMPTS_RESPONSE, result) } @@ -147,7 +158,7 @@ class BloggingPromptsRestClientTest { test { initFetchPrompts(error = WPComGsonNetworkError(BaseNetworkError(GenericErrorType.UNKNOWN))) - val result = restClient.fetchPrompts(site, numberOfPromptsToFetch, Date()) + val result = restClient.fetchPrompts(site, numberOfPromptsToFetch, Date(), locale) assertError(GENERIC_ERROR, result) } @@ -157,7 +168,7 @@ class BloggingPromptsRestClientTest { test { initFetchPrompts(error = WPComGsonNetworkError(BaseNetworkError(GenericErrorType.TIMEOUT))) - val result = restClient.fetchPrompts(site, numberOfPromptsToFetch, Date()) + val result = restClient.fetchPrompts(site, numberOfPromptsToFetch, Date(), locale) assertError(TIMEOUT, result) } @@ -167,7 +178,7 @@ class BloggingPromptsRestClientTest { test { initFetchPrompts(error = WPComGsonNetworkError(BaseNetworkError(GenericErrorType.NETWORK_ERROR))) - val result = restClient.fetchPrompts(site, numberOfPromptsToFetch, Date()) + val result = restClient.fetchPrompts(site, numberOfPromptsToFetch, Date(), locale) assertError(API_ERROR, result) } @@ -177,7 +188,7 @@ class BloggingPromptsRestClientTest { test { initFetchPrompts(error = WPComGsonNetworkError(BaseNetworkError(GenericErrorType.INVALID_RESPONSE))) - val result = restClient.fetchPrompts(site, numberOfPromptsToFetch, Date()) + val result = restClient.fetchPrompts(site, numberOfPromptsToFetch, Date(), locale) assertError(INVALID_RESPONSE, result) } @@ -187,7 +198,7 @@ class BloggingPromptsRestClientTest { test { initFetchPrompts(error = WPComGsonNetworkError(BaseNetworkError(GenericErrorType.NOT_AUTHENTICATED))) - val result = restClient.fetchPrompts(site, numberOfPromptsToFetch, Date()) + val result = restClient.fetchPrompts(site, numberOfPromptsToFetch, Date(), locale) assertError(AUTHORIZATION_REQUIRED, result) } @@ -212,6 +223,7 @@ class BloggingPromptsRestClientTest { eq(BloggingPromptsListResponseTypeToken.type), eq(false), any(), + eq(false), eq(false) ) ).thenReturn(response) diff --git a/libs/fluxc/src/test/java/org/wordpress/android/fluxc/store/bloggingprompts/BloggingPromptsStoreTest.kt b/libs/fluxc/src/test/java/org/wordpress/android/fluxc/store/bloggingprompts/BloggingPromptsStoreTest.kt index f297dab6811f..7a8214b481cc 100644 --- a/libs/fluxc/src/test/java/org/wordpress/android/fluxc/store/bloggingprompts/BloggingPromptsStoreTest.kt +++ b/libs/fluxc/src/test/java/org/wordpress/android/fluxc/store/bloggingprompts/BloggingPromptsStoreTest.kt @@ -168,6 +168,7 @@ class BloggingPromptsStoreTest { private val numberOfPromptsToFetch = 40 private val requestedPromptDate = Date() + private val locale = "en" @Before fun setUp() { @@ -190,11 +191,12 @@ class BloggingPromptsStoreTest { restClient.fetchPrompts( siteModel, numberOfPromptsToFetch, - requestedPromptDate + requestedPromptDate, + locale ) ).thenReturn(payload) - promptsStore.fetchPrompts(siteModel, numberOfPromptsToFetch, requestedPromptDate) + promptsStore.fetchPrompts(siteModel, numberOfPromptsToFetch, requestedPromptDate, locale) verify(dao).insertForSite(siteModel.id, PROMPT_MODELS) } @@ -207,7 +209,8 @@ class BloggingPromptsStoreTest { restClient.fetchPrompts( siteModel, numberOfPromptsToFetch, - requestedPromptDate + requestedPromptDate, + locale ) ).thenReturn( payload @@ -216,7 +219,8 @@ class BloggingPromptsStoreTest { val result = promptsStore.fetchPrompts( siteModel, numberOfPromptsToFetch, - requestedPromptDate + requestedPromptDate, + locale ) assertThat(result.model).isEqualTo(PROMPT_MODELS) @@ -231,7 +235,8 @@ class BloggingPromptsStoreTest { restClient.fetchPrompts( siteModel, numberOfPromptsToFetch, - requestedPromptDate + requestedPromptDate, + locale ) ).thenReturn( payload @@ -246,7 +251,8 @@ class BloggingPromptsStoreTest { val result = promptsStore.fetchPrompts( siteModel, numberOfPromptsToFetch, - requestedPromptDate + requestedPromptDate, + locale ) assertThat(result.model).isNull() @@ -311,14 +317,16 @@ class BloggingPromptsStoreTest { restClient.fetchPrompts( siteModel, numberOfPromptsToFetch, - requestedPromptDate + requestedPromptDate, + locale ) ).thenReturn(payload) val result = promptsStore.fetchPrompts( siteModel, numberOfPromptsToFetch, - requestedPromptDate + requestedPromptDate, + locale ) assertThat(result.model).isNull()