Merge pull request #4382 from kiwix/Fixes#4381

Fixed: Online library was not retrieving after clicking “Allow downloading via mobile network” in the confirmation dialog.
This commit is contained in:
Kelson 2025-08-14 12:28:31 +02:00 committed by GitHub
commit 17b148fc4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 71 additions and 40 deletions

View File

@ -132,10 +132,12 @@ class BookmarksRobot : BaseRobot() {
fun assertBookmarkSaved(composeTestRule: ComposeContentTestRule) {
pauseForBetterTestPerformance()
composeTestRule.apply {
waitForIdle()
onNodeWithText("Test Zim").assertExists()
}
testFlakyView({
composeTestRule.apply {
waitForIdle()
onNodeWithText("Test Zim").assertExists()
}
})
}
fun assertBookmarkRemoved(composeTestRule: ComposeTestRule) {

View File

@ -18,11 +18,15 @@
package org.kiwix.kiwixmobile.page.bookmarks
import android.accessibilityservice.AccessibilityService
import android.content.Context
import android.content.Intent
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.core.content.edit
import androidx.core.net.toUri
import androidx.navigation.NavOptions
import androidx.preference.PreferenceManager
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.espresso.matcher.ViewMatchers.withContentDescription
import androidx.test.platform.app.InstrumentationRegistry
@ -128,8 +132,7 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
navOptions
)
}
waitForIdle()
waitUntilTimeout() // to load the ZIM file properly.
waitComposeToSettleViews() // to load the ZIM file properly.
}
bookmarks {
// delete any bookmark if already saved to properly perform this test case.
@ -139,40 +142,47 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
clickOnDeleteButton(composeTestRule)
assertNoBookMarkTextDisplayed(composeTestRule)
pressBack()
composeTestRule.apply {
waitForIdle()
waitUntilTimeout()
}
waitComposeToSettleViews()
// Test saving bookmark
clickOnSaveBookmarkImage(composeTestRule)
openBookmarkScreen(kiwixMainActivity as CoreMainActivity, composeTestRule)
assertBookmarkSaved(composeTestRule)
pressBack()
// Test removing bookmark
composeTestRule.apply {
waitForIdle()
waitUntilTimeout()
}
waitComposeToSettleViews()
clickOnSaveBookmarkImage(composeTestRule)
longClickOnSaveBookmarkImage(composeTestRule, TEST_PAUSE_MS_FOR_DOWNLOAD_TEST.toLong())
assertBookmarkRemoved(composeTestRule)
pressBack()
// Save the bookmark to test whether it remains saved after the application restarts or not.
composeTestRule.apply {
waitForIdle()
waitUntilTimeout()
}
waitComposeToSettleViews()
clickOnSaveBookmarkImage(composeTestRule)
waitComposeToSettleViews()
// Close the application.
InstrumentationRegistry.getInstrumentation().uiAutomation.performGlobalAction(
AccessibilityService.GLOBAL_ACTION_HOME
)
// wait a bit
waitComposeToSettleViews()
// reopen the application to test that book remains saved or not.
val context = ApplicationProvider.getApplicationContext<Context>()
val intent = context.packageManager.getLaunchIntentForPackage(context.packageName)
intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
context.startActivity(intent)
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
waitComposeToSettleViews()
topLevel {
clickBookmarksOnNavDrawer(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertBookmarkSaved(composeTestRule)
}
}
}
}
@Test
fun testBookmarkRemainsSavedOrNot() {
composeTestRule.waitForIdle()
topLevel {
clickBookmarksOnNavDrawer(kiwixMainActivity as CoreMainActivity, composeTestRule) {
assertBookmarkSaved(composeTestRule)
}
private fun waitComposeToSettleViews() {
composeTestRule.apply {
waitForIdle()
waitUntilTimeout()
}
}
@ -201,7 +211,7 @@ class LibkiwixBookmarkTest : BaseActivityTest() {
assertNoBookMarkTextDisplayed(composeTestRule)
pressBack()
}
composeTestRule.waitUntilTimeout()
waitComposeToSettleViews()
val coreReaderFragment = kiwixMainActivity.supportFragmentManager.fragments
.filterIsInstance<CoreReaderFragment>()
.firstOrNull()

View File

@ -155,7 +155,9 @@ class ZimManageViewModel @Inject constructor(
val category: String? = null,
val lang: String? = null,
val isLoadMoreItem: Boolean,
val page: Int
val page: Int,
// Bug Fix #4381
val version: Long = System.nanoTime()
)
data class OnlineLibraryResult(
@ -371,7 +373,20 @@ class ZimManageViewModel @Inject constructor(
category = newRequest.category ?: current.category,
lang = newRequest.lang ?: current.lang,
page = newRequest.page,
isLoadMoreItem = newRequest.isLoadMoreItem
isLoadMoreItem = newRequest.isLoadMoreItem,
version = if (isUnitTestCase) {
// In unit tests, we want predictable and testable values,
// so use the provided version instead of a dynamic timestamp.
newRequest.version
} else {
// Bug Fix #4381:
// Force StateFlow to emit even if all other fields are unchanged.
// Without this, identical requests may not trigger observers,
// causing the UI not to refresh.
// Using System.nanoTime() ensures a unique value each time,
// guaranteeing that collectors receive an update.
System.nanoTime()
}
)
}
}

View File

@ -302,18 +302,22 @@ class ZimManageViewModelTest {
}
@Test
fun `updateOnlineLibraryFilters updates onlineLibraryRequest`() = runTest {
val newRequest = ZimManageViewModel.OnlineLibraryRequest(
query = "test",
category = "cat",
lang = "en",
page = 2,
isLoadMoreItem = true
)
viewModel.onlineLibraryRequest.test {
skipItems(1)
viewModel.updateOnlineLibraryFilters(newRequest)
assertThat(awaitItem()).isEqualTo(newRequest)
fun `updateOnlineLibraryFilters updates onlineLibraryRequest`() = flakyTest {
runTest {
viewModel.setIsUnitTestCase()
val newRequest = ZimManageViewModel.OnlineLibraryRequest(
query = "test",
category = "cat",
lang = "en",
page = 2,
isLoadMoreItem = true,
version = 100L
)
viewModel.onlineLibraryRequest.test {
skipItems(1)
viewModel.updateOnlineLibraryFilters(newRequest)
assertThat(awaitItem()).isEqualTo(newRequest)
}
}
}