Fixed: ZimManageViewModelTest which was failing on CI.

This commit is contained in:
MohitMaliFtechiz 2025-06-12 14:53:37 +05:30
parent c2d35e17d4
commit e24d214553
2 changed files with 61 additions and 56 deletions

View File

@ -44,7 +44,6 @@ import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain import kotlinx.coroutines.test.setMain
import kotlinx.coroutines.withTimeout
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
@ -95,6 +94,9 @@ import org.kiwix.sharedFunctions.downloadModel
import org.kiwix.sharedFunctions.language import org.kiwix.sharedFunctions.language
import org.kiwix.sharedFunctions.libkiwixBook import org.kiwix.sharedFunctions.libkiwixBook
import java.util.Locale import java.util.Locale
import kotlin.time.Duration
import kotlin.time.DurationUnit
import kotlin.time.toDuration
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
@ExtendWith(InstantExecutorExtension::class) @ExtendWith(InstantExecutorExtension::class)
@ -252,7 +254,7 @@ class ZimManageViewModelTest {
) )
) )
advanceUntilIdle() advanceUntilIdle()
coVerify(timeout = 500) { coVerify(timeout = MOCKK_TIMEOUT_FOR_VERIFICATION) {
libkiwixBookOnDisk.insert(listOfNotNull(expectedBook.book.nativeBook)) libkiwixBookOnDisk.insert(listOfNotNull(expectedBook.book.nativeBook))
} }
} }
@ -359,7 +361,7 @@ class ZimManageViewModelTest {
language(isActive = true, occurencesOfLanguage = 1) language(isActive = true, occurencesOfLanguage = 1)
) )
advanceUntilIdle() advanceUntilIdle()
verify(timeout = 500) { verify(timeout = MOCKK_TIMEOUT_FOR_VERIFICATION) {
newLanguagesDao.insert( newLanguagesDao.insert(
listOf( listOf(
dbLanguage.copy(occurencesOfLanguage = 2), dbLanguage.copy(occurencesOfLanguage = 2),
@ -403,7 +405,9 @@ class ZimManageViewModelTest {
@Test @Test
fun `library update removes from sources and maps to list items`() = runTest { fun `library update removes from sources and maps to list items`() = runTest {
val bookAlreadyOnDisk = libkiwixBook(id = "0", url = "", language = Locale.ENGLISH.language) val book = BookTestWrapper("0")
val bookAlreadyOnDisk =
libkiwixBook(id = "0", url = "", language = Locale.ENGLISH.language, nativeBook = book)
val bookDownloading = libkiwixBook(id = "1", url = "") val bookDownloading = libkiwixBook(id = "1", url = "")
val bookWithActiveLanguage = libkiwixBook(id = "3", language = "activeLanguage", url = "") val bookWithActiveLanguage = libkiwixBook(id = "3", language = "activeLanguage", url = "")
val bookWithInactiveLanguage = libkiwixBook(id = "4", language = "inactiveLanguage", url = "") val bookWithInactiveLanguage = libkiwixBook(id = "4", language = "inactiveLanguage", url = "")
@ -412,20 +416,16 @@ class ZimManageViewModelTest {
triggerAction = { triggerAction = {
every { application.getString(any()) } returns "" every { application.getString(any()) } returns ""
every { application.getString(any(), any()) } returns "" every { application.getString(any(), any()) } returns ""
networkStates.tryEmit(CONNECTED) networkStates.value = CONNECTED
advanceUntilIdle() downloads.value = listOf(downloadModel(book = bookDownloading))
downloads.tryEmit(listOf(downloadModel(book = bookDownloading))) books.value = listOf(bookOnDisk(book = bookAlreadyOnDisk))
advanceUntilIdle() languages.value =
books.tryEmit(listOf(bookOnDisk(book = bookAlreadyOnDisk)))
advanceUntilIdle()
languages.tryEmit(
listOf( listOf(
language(isActive = true, occurencesOfLanguage = 1, languageCode = "activeLanguage"), language(isActive = true, occurencesOfLanguage = 1, languageCode = "activeLanguage"),
language(isActive = false, occurencesOfLanguage = 1, languageCode = "inactiveLanguage") language(isActive = false, occurencesOfLanguage = 1, languageCode = "inactiveLanguage")
) )
) fileSystemStates.value = CanWrite4GbFile
fileSystemStates.tryEmit(CanWrite4GbFile) runBlocking {
advanceUntilIdle()
viewModel.networkLibrary.emit( viewModel.networkLibrary.emit(
listOf( listOf(
bookAlreadyOnDisk, bookAlreadyOnDisk,
@ -434,10 +434,15 @@ class ZimManageViewModelTest {
bookWithInactiveLanguage bookWithInactiveLanguage
) )
) )
}
advanceUntilIdle()
}, },
assert = { assert = {
skipItems(1) while (true) {
assertThat(awaitItem()).isEqualTo( val items = awaitItem()
val bookItems = items.filterIsInstance<LibraryListItem.BookItem>()
if (bookItems.size >= 2 && bookItems[0].fileSystemState == CanWrite4GbFile) {
assertThat(items).isEqualTo(
listOf( listOf(
LibraryListItem.DividerItem(Long.MAX_VALUE, R.string.downloading), LibraryListItem.DividerItem(Long.MAX_VALUE, R.string.downloading),
LibraryListItem.LibraryDownloadItem(downloadModel(book = bookDownloading)), LibraryListItem.LibraryDownloadItem(downloadModel(book = bookDownloading)),
@ -447,7 +452,11 @@ class ZimManageViewModelTest {
LibraryListItem.BookItem(bookWithInactiveLanguage, CanWrite4GbFile) LibraryListItem.BookItem(bookWithInactiveLanguage, CanWrite4GbFile)
) )
) )
break
} }
}
},
timeout = TURBINE_TIMEOUT
) )
} }
@ -476,7 +485,6 @@ class ZimManageViewModelTest {
viewModel.networkLibrary.emit(listOf(bookOver4Gb)) viewModel.networkLibrary.emit(listOf(bookOver4Gb))
}, },
assert = { assert = {
withTimeout(5000) {
while (true) { while (true) {
val item = awaitItem() val item = awaitItem()
val bookItem = item.filterIsInstance<LibraryListItem.BookItem>().firstOrNull() val bookItem = item.filterIsInstance<LibraryListItem.BookItem>().firstOrNull()
@ -490,8 +498,8 @@ class ZimManageViewModelTest {
break break
} }
} }
} },
} timeout = TURBINE_TIMEOUT
) )
} }
@ -608,10 +616,11 @@ class ZimManageViewModelTest {
suspend fun <T> TestScope.testFlow( suspend fun <T> TestScope.testFlow(
flow: Flow<T>, flow: Flow<T>,
triggerAction: suspend () -> Unit, triggerAction: suspend () -> Unit,
assert: suspend TurbineTestContext<T>.() -> Unit assert: suspend TurbineTestContext<T>.() -> Unit,
timeout: Duration? = null
) { ) {
val job = launch { val job = launch {
flow.test { flow.test(timeout = timeout) {
triggerAction() triggerAction()
assert() assert()
cancelAndIgnoreRemainingEvents() cancelAndIgnoreRemainingEvents()
@ -625,3 +634,6 @@ class BookTestWrapper(private val id: String) : Book(0L) {
override fun equals(other: Any?): Boolean = other is BookTestWrapper && getId() == other.getId() override fun equals(other: Any?): Boolean = other is BookTestWrapper && getId() == other.getId()
override fun hashCode(): Int = getId().hashCode() override fun hashCode(): Int = getId().hashCode()
} }
val TURBINE_TIMEOUT = 5000.toDuration(DurationUnit.MILLISECONDS)
const val MOCKK_TIMEOUT_FOR_VERIFICATION = 1000L

View File

@ -142,14 +142,7 @@ data class LibkiwixBook(
get() = ZimReaderSource(File(path.orEmpty())) get() = ZimReaderSource(File(path.orEmpty()))
// Two books are equal if their ids match // Two books are equal if their ids match
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean = other is LibkiwixBook && other.id == id
if (other is LibkiwixBook) {
if (other.id == id) {
return true
}
}
return false
}
// Only use the book's id to generate a hash code // Only use the book's id to generate a hash code
override fun hashCode(): Int = id.hashCode() override fun hashCode(): Int = id.hashCode()