diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 7069e5cc13bb..8a7eb902d294 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -2,7 +2,7 @@ 18.5 ----- - +* [*] Fixed a crash in Page Template chooser [https://github.com/wordpress-mobile/WordPress-Android/pull/15415] 18.4 ----- diff --git a/WordPress/src/main/java/org/wordpress/android/util/SiteUtils.java b/WordPress/src/main/java/org/wordpress/android/util/SiteUtils.java index 0ccf3ff579be..4c0c1d16fce1 100644 --- a/WordPress/src/main/java/org/wordpress/android/util/SiteUtils.java +++ b/WordPress/src/main/java/org/wordpress/android/util/SiteUtils.java @@ -205,7 +205,7 @@ public static void disableBlockEditor(Dispatcher dispatcher, SiteModel siteModel dispatcher.dispatch(SiteActionBuilder.newUpdateSiteAction(siteModel)); } - public static boolean isBlockEditorDefaultForNewPost(SiteModel site) { + public static boolean isBlockEditorDefaultForNewPost(@Nullable SiteModel site) { if (site == null) { return true; } diff --git a/WordPress/src/main/java/org/wordpress/android/viewmodel/mlp/ModalLayoutPickerViewModel.kt b/WordPress/src/main/java/org/wordpress/android/viewmodel/mlp/ModalLayoutPickerViewModel.kt index 512705255362..6b0a09c48a0e 100644 --- a/WordPress/src/main/java/org/wordpress/android/viewmodel/mlp/ModalLayoutPickerViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/viewmodel/mlp/ModalLayoutPickerViewModel.kt @@ -61,15 +61,19 @@ class ModalLayoutPickerViewModel @Inject constructor( private val _onCreateNewPageRequested = SingleLiveEvent() val onCreateNewPageRequested: LiveData = _onCreateNewPageRequested - private val site: SiteModel by lazy { - requireNotNull(siteStore.getSiteByLocalId(selectedSiteRepository.getSelectedSiteLocalId())) + private val site: SiteModel? by lazy { + siteStore.getSiteByLocalId(selectedSiteRepository.getSelectedSiteLocalId(true)) } override val useCachedData: Boolean = true override val selectedLayout: LayoutModel? get() = (uiState.value as? Content)?.let { state -> - state.selectedLayoutSlug?.let { siteStore.getBlockLayout(site, it) }?.let { LayoutModel(it) } + state.selectedLayoutSlug?.let { slug -> + site?.let { site -> + siteStore.getBlockLayout(site, slug) + } + }?.let { LayoutModel(it) } } sealed class PageRequest(val template: String?) { @@ -90,7 +94,8 @@ class ModalLayoutPickerViewModel @Inject constructor( } override fun fetchLayouts(preferCache: Boolean) { - if (!networkUtils.isNetworkAvailable()) { + val selectedSite = site + if (!networkUtils.isNetworkAvailable() || selectedSite == null) { setErrorState() return } @@ -99,7 +104,7 @@ class ModalLayoutPickerViewModel @Inject constructor( } launch { val payload = FetchBlockLayoutsPayload( - site, + selectedSite, supportedBlocksProvider.fromAssets().supported, thumbDimensionProvider.previewWidth.toFloat(), thumbDimensionProvider.previewHeight.toFloat(), diff --git a/WordPress/src/test/java/org/wordpress/android/viewmodel/mlp/ModalLayoutPickerViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/viewmodel/mlp/ModalLayoutPickerViewModelTest.kt index dcf7b7770332..c5f7d23660ec 100644 --- a/WordPress/src/test/java/org/wordpress/android/viewmodel/mlp/ModalLayoutPickerViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/viewmodel/mlp/ModalLayoutPickerViewModelTest.kt @@ -103,15 +103,22 @@ class ModalLayoutPickerViewModelTest { } @ExperimentalCoroutinesApi - private fun mockFetchingSelectedSite(isError: Boolean = false, block: suspend CoroutineScope.() -> T) { + private fun mockFetchingSelectedSite( + isError: Boolean = false, + isSiteUnavailable: Boolean = false, + block: suspend CoroutineScope.() -> T + ) { coroutineScope.runBlockingTest { val site = SiteModel().apply { id = 1 mobileEditor = GB_EDITOR_NAME } - whenever(selectedSiteRepository.getSelectedSiteLocalId()).thenReturn(site.id) - whenever(siteStore.getSiteByLocalId(site.id)).thenReturn(site) - whenever(siteStore.getSiteByLocalId(site.id)).thenReturn(site) + whenever(selectedSiteRepository.getSelectedSiteLocalId(true)).thenReturn(site.id) + if (isSiteUnavailable) { + whenever(siteStore.getSiteByLocalId(site.id)).thenReturn(null) + } else { + whenever(siteStore.getSiteByLocalId(site.id)).thenReturn(site) + } whenever(siteStore.getBlockLayout(site, "about")).thenReturn(aboutLayout) whenever(supportedBlocksProvider.fromAssets()).thenReturn(SupportedBlocks()) whenever(thumbDimensionProvider.previewWidth).thenReturn(136) @@ -172,6 +179,14 @@ class ModalLayoutPickerViewModelTest { assertThat(viewModel.uiState.value is Error).isEqualTo(true) } + @ExperimentalCoroutinesApi + @Test + fun `when modal layout picker starts and the site is unavailable errors are handled`() = + mockFetchingSelectedSite(isSiteUnavailable = true) { + viewModel.createPageFlowTriggered() + assertThat(viewModel.uiState.value is Error).isEqualTo(true) + } + @ExperimentalCoroutinesApi @Test fun `modal layout picker is shown when triggered`() = mockFetchingSelectedSite {