mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-08 14:52:13 -04:00
Refactored the remaining test cases of ZimManageViewModel
to follow the new approach. Additionally, added new unit test cases to cover new functionalities such as pagination, fetching new content when changing language, searching, etc.
* Improved some unit test cases that sometimes failed on CI due to coroutine IO threading issues.
This commit is contained in:
parent
136052e0bb
commit
badddc8aab
@ -60,14 +60,6 @@ class OnlineLibraryManager @Inject constructor(
|
|||||||
it.printStackTrace()
|
it.printStackTrace()
|
||||||
}.getOrNull()
|
}.getOrNull()
|
||||||
|
|
||||||
suspend fun getOnlineBooksLanguage(): List<String> {
|
|
||||||
return runCatching {
|
|
||||||
library.booksLanguages.distinct()
|
|
||||||
}.onFailure {
|
|
||||||
it.printStackTrace()
|
|
||||||
}.getOrDefault(emptyList())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the URL for fetching the OPDS library entries with pagination and optional filters.
|
* Builds the URL for fetching the OPDS library entries with pagination and optional filters.
|
||||||
*
|
*
|
||||||
|
@ -163,6 +163,8 @@ class ZimManageViewModel @Inject constructor(
|
|||||||
val books: List<LibkiwixBook>
|
val books: List<LibkiwixBook>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Suppress("InjectDispatcher")
|
||||||
|
private var ioDispatcher: CoroutineDispatcher = Dispatchers.IO
|
||||||
private var isUnitTestCase: Boolean = false
|
private var isUnitTestCase: Boolean = false
|
||||||
val sideEffects: MutableSharedFlow<SideEffect<*>> = MutableSharedFlow()
|
val sideEffects: MutableSharedFlow<SideEffect<*>> = MutableSharedFlow()
|
||||||
private val _libraryItems = MutableStateFlow<List<LibraryListItem>>(emptyList())
|
private val _libraryItems = MutableStateFlow<List<LibraryListItem>>(emptyList())
|
||||||
@ -313,11 +315,11 @@ class ZimManageViewModel @Inject constructor(
|
|||||||
onCleared()
|
onCleared()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeCoroutineFlows(dispatcher: CoroutineDispatcher = Dispatchers.IO) {
|
private fun observeCoroutineFlows() {
|
||||||
val downloads = downloadDao.downloads()
|
val downloads = downloadDao.downloads()
|
||||||
val booksFromDao = books()
|
val booksFromDao = books()
|
||||||
coroutineJobs.apply {
|
coroutineJobs.apply {
|
||||||
add(scanBooksFromStorage(dispatcher))
|
add(scanBooksFromStorage())
|
||||||
add(updateBookItems())
|
add(updateBookItems())
|
||||||
add(fileSelectActions())
|
add(fileSelectActions())
|
||||||
add(updateLibraryItems(booksFromDao, downloads, networkLibrary))
|
add(updateLibraryItems(booksFromDao, downloads, networkLibrary))
|
||||||
@ -340,7 +342,7 @@ class ZimManageViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(FlowPreview::class)
|
@OptIn(FlowPreview::class)
|
||||||
private fun observeSearch(dispatcher: CoroutineDispatcher = Dispatchers.IO) =
|
private fun observeSearch() =
|
||||||
requestFiltering
|
requestFiltering
|
||||||
.onEach {
|
.onEach {
|
||||||
libraryListIsRefreshing.postValue(true)
|
libraryListIsRefreshing.postValue(true)
|
||||||
@ -349,17 +351,17 @@ class ZimManageViewModel @Inject constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
.debounce(500)
|
.debounce(500)
|
||||||
.flowOn(dispatcher)
|
.flowOn(ioDispatcher)
|
||||||
.launchIn(viewModelScope)
|
.launchIn(viewModelScope)
|
||||||
|
|
||||||
private fun observeLanguageChanges(dispatcher: CoroutineDispatcher = Dispatchers.IO) =
|
private fun observeLanguageChanges() =
|
||||||
sharedPreferenceUtil.onlineContentLanguage
|
sharedPreferenceUtil.onlineContentLanguage
|
||||||
.onEach {
|
.onEach {
|
||||||
updateOnlineLibraryFilters(
|
updateOnlineLibraryFilters(
|
||||||
OnlineLibraryRequest(lang = it, page = ZERO, isLoadMoreItem = false)
|
OnlineLibraryRequest(lang = it, page = ZERO, isLoadMoreItem = false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.flowOn(dispatcher)
|
.flowOn(ioDispatcher)
|
||||||
.launchIn(viewModelScope)
|
.launchIn(viewModelScope)
|
||||||
|
|
||||||
fun updateOnlineLibraryFilters(newRequest: OnlineLibraryRequest) {
|
fun updateOnlineLibraryFilters(newRequest: OnlineLibraryRequest) {
|
||||||
@ -381,11 +383,11 @@ class ZimManageViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
.launchIn(viewModelScope)
|
.launchIn(viewModelScope)
|
||||||
|
|
||||||
private fun scanBooksFromStorage(dispatcher: CoroutineDispatcher = Dispatchers.IO) =
|
private fun scanBooksFromStorage() =
|
||||||
checkFileSystemForBooksOnRequest(books())
|
checkFileSystemForBooksOnRequest(books())
|
||||||
.catch { it.printStackTrace() }
|
.catch { it.printStackTrace() }
|
||||||
.onEach { books -> libkiwixBookOnDisk.insert(books) }
|
.onEach { books -> libkiwixBookOnDisk.insert(books) }
|
||||||
.flowOn(dispatcher)
|
.flowOn(ioDispatcher)
|
||||||
.launchIn(viewModelScope)
|
.launchIn(viewModelScope)
|
||||||
|
|
||||||
private fun fileSelectActions() =
|
private fun fileSelectActions() =
|
||||||
@ -472,14 +474,11 @@ class ZimManageViewModel @Inject constructor(
|
|||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
private fun requestsAndConnectivityChangesToLibraryRequests(
|
private fun requestsAndConnectivityChangesToLibraryRequests(
|
||||||
library: MutableStateFlow<List<LibkiwixBook>>,
|
library: MutableStateFlow<List<LibkiwixBook>>
|
||||||
dispatcher: CoroutineDispatcher = Dispatchers.IO
|
|
||||||
) = requestDownloadLibrary.onEach { onlineLibraryRequest ->
|
) = requestDownloadLibrary.onEach { onlineLibraryRequest ->
|
||||||
// Cancel any previous ongoing job
|
|
||||||
onlineLibraryFetchingJob?.cancel()
|
onlineLibraryFetchingJob?.cancel()
|
||||||
|
|
||||||
// Launch new job
|
onlineLibraryFetchingJob = viewModelScope.launch(ioDispatcher) {
|
||||||
onlineLibraryFetchingJob = viewModelScope.launch(dispatcher) {
|
|
||||||
connectivityBroadcastReceiver.networkStates
|
connectivityBroadcastReceiver.networkStates
|
||||||
.filter { it == CONNECTED }
|
.filter { it == CONNECTED }
|
||||||
.take(1)
|
.take(1)
|
||||||
@ -499,15 +498,17 @@ class ZimManageViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.collect { result ->
|
.collect { result ->
|
||||||
library.value = if (result.onlineLibraryRequest.isLoadMoreItem) {
|
library.emit(
|
||||||
|
if (result.onlineLibraryRequest.isLoadMoreItem) {
|
||||||
library.value + result.books
|
library.value + result.books
|
||||||
} else {
|
} else {
|
||||||
result.books
|
result.books
|
||||||
}
|
}
|
||||||
|
)
|
||||||
resetDownloadState()
|
resetDownloadState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.flowOn(dispatcher)
|
}.flowOn(ioDispatcher)
|
||||||
.launchIn(viewModelScope)
|
.launchIn(viewModelScope)
|
||||||
|
|
||||||
private fun shouldProceedWithDownload(onlineLibraryRequest: OnlineLibraryRequest): Flow<KiwixService> {
|
private fun shouldProceedWithDownload(onlineLibraryRequest: OnlineLibraryRequest): Flow<KiwixService> {
|
||||||
@ -606,9 +607,8 @@ class ZimManageViewModel @Inject constructor(
|
|||||||
private fun updateLibraryItems(
|
private fun updateLibraryItems(
|
||||||
localBooksFromLibkiwix: Flow<List<Book>>,
|
localBooksFromLibkiwix: Flow<List<Book>>,
|
||||||
downloads: Flow<List<DownloadModel>>,
|
downloads: Flow<List<DownloadModel>>,
|
||||||
library: MutableStateFlow<List<LibkiwixBook>>,
|
library: MutableStateFlow<List<LibkiwixBook>>
|
||||||
dispatcher: CoroutineDispatcher = Dispatchers.IO
|
) = viewModelScope.launch(ioDispatcher) {
|
||||||
) = viewModelScope.launch(dispatcher) {
|
|
||||||
combine(
|
combine(
|
||||||
localBooksFromLibkiwix,
|
localBooksFromLibkiwix,
|
||||||
downloads,
|
downloads,
|
||||||
|
@ -50,6 +50,7 @@ import org.kiwix.kiwixmobile.language.viewmodel.Action.Select
|
|||||||
import org.kiwix.kiwixmobile.language.viewmodel.Action.UpdateLanguages
|
import org.kiwix.kiwixmobile.language.viewmodel.Action.UpdateLanguages
|
||||||
import org.kiwix.kiwixmobile.language.viewmodel.State.Content
|
import org.kiwix.kiwixmobile.language.viewmodel.State.Content
|
||||||
import org.kiwix.kiwixmobile.language.viewmodel.State.Loading
|
import org.kiwix.kiwixmobile.language.viewmodel.State.Loading
|
||||||
|
import org.kiwix.kiwixmobile.zimManager.TURBINE_TIMEOUT
|
||||||
import org.kiwix.kiwixmobile.zimManager.testFlow
|
import org.kiwix.kiwixmobile.zimManager.testFlow
|
||||||
import org.kiwix.sharedFunctions.InstantExecutorExtension
|
import org.kiwix.sharedFunctions.InstantExecutorExtension
|
||||||
import org.kiwix.sharedFunctions.language
|
import org.kiwix.sharedFunctions.language
|
||||||
@ -199,7 +200,8 @@ class LanguageViewModelTest {
|
|||||||
assert = {
|
assert = {
|
||||||
assertThat(awaitItem()).isEqualTo(Loading)
|
assertThat(awaitItem()).isEqualTo(Loading)
|
||||||
assertThat(awaitItem()).isEqualTo(Content(listOf()))
|
assertThat(awaitItem()).isEqualTo(Content(listOf()))
|
||||||
}
|
},
|
||||||
|
TURBINE_TIMEOUT
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ 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 okhttp3.HttpUrl
|
||||||
|
import okhttp3.Response
|
||||||
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
|
||||||
@ -56,13 +58,13 @@ import org.kiwix.kiwixmobile.core.dao.DownloadRoomDao
|
|||||||
import org.kiwix.kiwixmobile.core.dao.LibkiwixBookOnDisk
|
import org.kiwix.kiwixmobile.core.dao.LibkiwixBookOnDisk
|
||||||
import org.kiwix.kiwixmobile.core.data.DataSource
|
import org.kiwix.kiwixmobile.core.data.DataSource
|
||||||
import org.kiwix.kiwixmobile.core.data.remote.KiwixService
|
import org.kiwix.kiwixmobile.core.data.remote.KiwixService
|
||||||
|
import org.kiwix.kiwixmobile.core.downloader.downloadManager.ZERO
|
||||||
import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel
|
import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel
|
||||||
import org.kiwix.kiwixmobile.core.entity.LibkiwixBook
|
import org.kiwix.kiwixmobile.core.ui.components.ONE
|
||||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||||
import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower
|
import org.kiwix.kiwixmobile.core.utils.dialog.AlertDialogShower
|
||||||
import org.kiwix.kiwixmobile.core.utils.files.ScanningProgressListener
|
import org.kiwix.kiwixmobile.core.utils.files.ScanningProgressListener
|
||||||
import org.kiwix.kiwixmobile.core.zim_manager.ConnectivityBroadcastReceiver
|
import org.kiwix.kiwixmobile.core.zim_manager.ConnectivityBroadcastReceiver
|
||||||
import org.kiwix.kiwixmobile.core.zim_manager.Language
|
|
||||||
import org.kiwix.kiwixmobile.core.zim_manager.NetworkState
|
import org.kiwix.kiwixmobile.core.zim_manager.NetworkState
|
||||||
import org.kiwix.kiwixmobile.core.zim_manager.NetworkState.CONNECTED
|
import org.kiwix.kiwixmobile.core.zim_manager.NetworkState.CONNECTED
|
||||||
import org.kiwix.kiwixmobile.core.zim_manager.NetworkState.NOT_CONNECTED
|
import org.kiwix.kiwixmobile.core.zim_manager.NetworkState.NOT_CONNECTED
|
||||||
@ -87,9 +89,9 @@ import org.kiwix.kiwixmobile.zimManager.fileselectView.effects.StartMultiSelecti
|
|||||||
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem
|
import org.kiwix.kiwixmobile.zimManager.libraryView.adapter.LibraryListItem
|
||||||
import org.kiwix.libkiwix.Book
|
import org.kiwix.libkiwix.Book
|
||||||
import org.kiwix.sharedFunctions.InstantExecutorExtension
|
import org.kiwix.sharedFunctions.InstantExecutorExtension
|
||||||
|
import org.kiwix.sharedFunctions.MOCK_BASE_URL
|
||||||
import org.kiwix.sharedFunctions.bookOnDisk
|
import org.kiwix.sharedFunctions.bookOnDisk
|
||||||
import org.kiwix.sharedFunctions.downloadModel
|
import org.kiwix.sharedFunctions.downloadModel
|
||||||
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.Duration
|
||||||
@ -118,7 +120,6 @@ class ZimManageViewModelTest {
|
|||||||
private val downloads = MutableStateFlow<List<DownloadModel>>(emptyList())
|
private val downloads = MutableStateFlow<List<DownloadModel>>(emptyList())
|
||||||
private val booksOnFileSystem = MutableStateFlow<List<Book>>(emptyList())
|
private val booksOnFileSystem = MutableStateFlow<List<Book>>(emptyList())
|
||||||
private val books = MutableStateFlow<List<BookOnDisk>>(emptyList())
|
private val books = MutableStateFlow<List<BookOnDisk>>(emptyList())
|
||||||
private val languages = MutableStateFlow<List<Language>>(emptyList())
|
|
||||||
private val onlineContentLanguage = MutableStateFlow("")
|
private val onlineContentLanguage = MutableStateFlow("")
|
||||||
private val fileSystemStates =
|
private val fileSystemStates =
|
||||||
MutableStateFlow<FileSystemState>(FileSystemState.DetectingFileSystem)
|
MutableStateFlow<FileSystemState>(FileSystemState.DetectingFileSystem)
|
||||||
@ -159,16 +160,35 @@ class ZimManageViewModelTest {
|
|||||||
} returns networkCapabilities
|
} returns networkCapabilities
|
||||||
every { networkCapabilities.hasTransport(TRANSPORT_WIFI) } returns true
|
every { networkCapabilities.hasTransport(TRANSPORT_WIFI) } returns true
|
||||||
every { sharedPreferenceUtil.prefWifiOnly } returns true
|
every { sharedPreferenceUtil.prefWifiOnly } returns true
|
||||||
every { sharedPreferenceUtil.getCachedLanguageList() } returns languages.value
|
|
||||||
coEvery { onlineLibraryManager.getOnlineBooksLanguage() } returns listOf("eng")
|
|
||||||
every { sharedPreferenceUtil.onlineContentLanguage } returns onlineContentLanguage
|
every { sharedPreferenceUtil.onlineContentLanguage } returns onlineContentLanguage
|
||||||
|
every { sharedPreferenceUtil.selectedOnlineContentLanguage } returns ""
|
||||||
|
every { onlineLibraryManager.getStartOffset(any(), any()) } returns ONE
|
||||||
|
every {
|
||||||
|
onlineLibraryManager.buildLibraryUrl(
|
||||||
|
any(),
|
||||||
|
any(),
|
||||||
|
any(),
|
||||||
|
any(),
|
||||||
|
any(),
|
||||||
|
any()
|
||||||
|
)
|
||||||
|
} returns MOCK_BASE_URL
|
||||||
|
val response = mockk<retrofit2.Response<String>>()
|
||||||
|
val rawResponse = mockk<Response>()
|
||||||
|
every { response.raw() } returns rawResponse
|
||||||
|
val httpsUrl = mockk<HttpUrl>()
|
||||||
|
every { httpsUrl.host } returns ""
|
||||||
|
every { httpsUrl.scheme } returns ""
|
||||||
|
every { rawResponse.networkResponse?.request?.url } returns httpsUrl
|
||||||
|
coEvery { kiwixService.getLibraryPage(any()) } returns response
|
||||||
|
every { response.body() } returns ""
|
||||||
downloads.value = emptyList()
|
downloads.value = emptyList()
|
||||||
booksOnFileSystem.value = emptyList()
|
booksOnFileSystem.value = emptyList()
|
||||||
books.value = emptyList()
|
books.value = emptyList()
|
||||||
languages.value = emptyList()
|
|
||||||
fileSystemStates.value = FileSystemState.DetectingFileSystem
|
fileSystemStates.value = FileSystemState.DetectingFileSystem
|
||||||
booksOnDiskListItems.value = emptyList()
|
booksOnDiskListItems.value = emptyList()
|
||||||
networkStates.value = NOT_CONNECTED
|
networkStates.value = NOT_CONNECTED
|
||||||
|
onlineContentLanguage.value = ""
|
||||||
viewModel =
|
viewModel =
|
||||||
ZimManageViewModel(
|
ZimManageViewModel(
|
||||||
downloadRoomDao,
|
downloadRoomDao,
|
||||||
@ -258,136 +278,17 @@ class ZimManageViewModelTest {
|
|||||||
@Nested
|
@Nested
|
||||||
inner class Languages {
|
inner class Languages {
|
||||||
@Test
|
@Test
|
||||||
fun `network no result & empty language db activates the default locale`() = runTest {
|
fun `changing language updates the filter and do the network request`() = runTest {
|
||||||
val expectedLanguage =
|
|
||||||
Language(
|
|
||||||
active = true,
|
|
||||||
occurencesOfLanguage = 1,
|
|
||||||
language = "eng",
|
|
||||||
languageLocalized = "englocal",
|
|
||||||
languageCode = "ENG",
|
|
||||||
languageCodeISO2 = "en"
|
|
||||||
)
|
|
||||||
expectNetworkDbAndDefault(
|
|
||||||
listOf(),
|
|
||||||
listOf(),
|
|
||||||
expectedLanguage
|
|
||||||
)
|
|
||||||
advanceUntilIdle()
|
|
||||||
// verify { languageRoomDao.insert(listOf(expectedLanguage)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `network no result & a language db result triggers nothing`() = runTest {
|
|
||||||
expectNetworkDbAndDefault(
|
|
||||||
listOf(),
|
|
||||||
listOf(
|
|
||||||
Language(
|
|
||||||
active = true,
|
|
||||||
occurencesOfLanguage = 1,
|
|
||||||
language = "eng",
|
|
||||||
languageLocalized = "englocal",
|
|
||||||
languageCode = "ENG",
|
|
||||||
languageCodeISO2 = "en"
|
|
||||||
)
|
|
||||||
),
|
|
||||||
language(isActive = true, occurencesOfLanguage = 1)
|
|
||||||
)
|
|
||||||
// verify { languageRoomDao.insert(any()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `network result & empty language db triggers combined result of default + network`() =
|
|
||||||
runTest {
|
|
||||||
val defaultLanguage =
|
|
||||||
Language(
|
|
||||||
active = true,
|
|
||||||
occurencesOfLanguage = 1,
|
|
||||||
language = "English",
|
|
||||||
languageLocalized = "English",
|
|
||||||
languageCode = "eng",
|
|
||||||
languageCodeISO2 = "eng"
|
|
||||||
)
|
|
||||||
expectNetworkDbAndDefault(
|
|
||||||
listOf(
|
|
||||||
libkiwixBook(language = "eng"),
|
|
||||||
libkiwixBook(language = "eng"),
|
|
||||||
libkiwixBook(language = "fra")
|
|
||||||
),
|
|
||||||
listOf(),
|
|
||||||
defaultLanguage
|
|
||||||
)
|
|
||||||
verify {
|
|
||||||
// languageRoomDao.insert(
|
|
||||||
// listOf(
|
|
||||||
// defaultLanguage.copy(occurencesOfLanguage = 2),
|
|
||||||
// Language(
|
|
||||||
// active = false,
|
|
||||||
// occurencesOfLanguage = 1,
|
|
||||||
// language = "fra",
|
|
||||||
// languageLocalized = "",
|
|
||||||
// languageCode = "",
|
|
||||||
// languageCodeISO2 = ""
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `network result & language db results activates a combined network + db result`() =
|
|
||||||
runTest {
|
|
||||||
val dbLanguage =
|
|
||||||
Language(
|
|
||||||
active = true,
|
|
||||||
occurencesOfLanguage = 1,
|
|
||||||
language = "English",
|
|
||||||
languageLocalized = "English",
|
|
||||||
languageCode = "eng",
|
|
||||||
languageCodeISO2 = "eng"
|
|
||||||
)
|
|
||||||
expectNetworkDbAndDefault(
|
|
||||||
listOf(
|
|
||||||
libkiwixBook(language = "eng"),
|
|
||||||
libkiwixBook(language = "eng"),
|
|
||||||
libkiwixBook(language = "fra")
|
|
||||||
),
|
|
||||||
listOf(dbLanguage),
|
|
||||||
language(isActive = true, occurencesOfLanguage = 1)
|
|
||||||
)
|
|
||||||
advanceUntilIdle()
|
|
||||||
verify(timeout = MOCKK_TIMEOUT_FOR_VERIFICATION) {
|
|
||||||
// languageRoomDao.insert(
|
|
||||||
// listOf(
|
|
||||||
// dbLanguage.copy(occurencesOfLanguage = 2),
|
|
||||||
// Language(
|
|
||||||
// active = false,
|
|
||||||
// occurencesOfLanguage = 1,
|
|
||||||
// language = "fra",
|
|
||||||
// languageLocalized = "fra",
|
|
||||||
// languageCode = "fra",
|
|
||||||
// languageCodeISO2 = "fra"
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun TestScope.expectNetworkDbAndDefault(
|
|
||||||
networkBooks: List<LibkiwixBook>,
|
|
||||||
dbBooks: List<Language>,
|
|
||||||
defaultLanguage: Language
|
|
||||||
) {
|
|
||||||
every { application.getString(any()) } returns ""
|
every { application.getString(any()) } returns ""
|
||||||
every { application.getString(any(), any()) } returns ""
|
every { application.getString(any(), any()) } returns ""
|
||||||
// every { defaultLanguageProvider.provide() } returns defaultLanguage
|
viewModel.onlineLibraryRequest.test {
|
||||||
coEvery { onlineLibraryManager.getOnlineBooksLanguage() } returns networkBooks.map { it.language }
|
skipItems(1)
|
||||||
viewModel.networkLibrary.emit(networkBooks)
|
onlineContentLanguage.emit("eng")
|
||||||
advanceUntilIdle()
|
val onlineLibraryRequest = awaitItem()
|
||||||
languages.value = dbBooks
|
assertThat(onlineLibraryRequest.lang).isEqualTo("eng")
|
||||||
advanceUntilIdle()
|
assertThat(onlineLibraryRequest.page).isEqualTo(ZERO)
|
||||||
networkStates.value = CONNECTED
|
assertThat(onlineLibraryRequest.isLoadMoreItem).isEqualTo(false)
|
||||||
advanceUntilIdle()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,6 +300,32 @@ class ZimManageViewModelTest {
|
|||||||
.assertValue(NOT_CONNECTED)
|
.assertValue(NOT_CONNECTED)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `search triggers downloading online content`() = runTest {
|
||||||
|
viewModel.onlineLibraryRequest.test {
|
||||||
|
skipItems(1)
|
||||||
|
viewModel.requestFiltering.emit("test")
|
||||||
|
advanceUntilIdle()
|
||||||
|
assertThat(awaitItem().query).isEqualTo("test")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@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 book = BookTestWrapper("0")
|
val book = BookTestWrapper("0")
|
||||||
@ -406,54 +333,31 @@ class ZimManageViewModelTest {
|
|||||||
libkiwixBook(id = "0", url = "", language = Locale.ENGLISH.language, nativeBook = book)
|
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 = "")
|
viewModel.libraryItems.test {
|
||||||
testFlow(
|
|
||||||
flow = viewModel.libraryItems,
|
|
||||||
triggerAction = {
|
|
||||||
every { application.getString(any()) } returns ""
|
every { application.getString(any()) } returns ""
|
||||||
every { application.getString(any(), any()) } returns ""
|
every { application.getString(any(), any()) } returns ""
|
||||||
|
coEvery {
|
||||||
|
onlineLibraryManager.parseOPDSStreamAndGetBooks(any(), any())
|
||||||
|
} returns arrayListOf(bookWithActiveLanguage)
|
||||||
networkStates.value = CONNECTED
|
networkStates.value = CONNECTED
|
||||||
downloads.value = listOf(downloadModel(book = bookDownloading))
|
downloads.value = listOf(downloadModel(book = bookDownloading))
|
||||||
books.value = listOf(bookOnDisk(book = bookAlreadyOnDisk))
|
books.value = listOf(bookOnDisk(book = bookAlreadyOnDisk))
|
||||||
languages.value =
|
|
||||||
listOf(
|
|
||||||
language(isActive = true, occurencesOfLanguage = 1, languageCode = "activeLanguage"),
|
|
||||||
language(isActive = false, occurencesOfLanguage = 1, languageCode = "inactiveLanguage")
|
|
||||||
)
|
|
||||||
fileSystemStates.value = CanWrite4GbFile
|
fileSystemStates.value = CanWrite4GbFile
|
||||||
runBlocking {
|
|
||||||
viewModel.networkLibrary.emit(
|
|
||||||
listOf(
|
|
||||||
bookAlreadyOnDisk,
|
|
||||||
bookDownloading,
|
|
||||||
bookWithActiveLanguage,
|
|
||||||
bookWithInactiveLanguage
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
},
|
|
||||||
assert = {
|
|
||||||
while (true) {
|
|
||||||
val items = awaitItem()
|
val items = awaitItem()
|
||||||
val bookItems = items.filterIsInstance<LibraryListItem.BookItem>()
|
val bookItems = items.filterIsInstance<LibraryListItem.BookItem>()
|
||||||
if (bookItems.size >= 2 && bookItems[0].fileSystemState == CanWrite4GbFile) {
|
if (bookItems.size >= 2 && bookItems[0].fileSystemState == CanWrite4GbFile) {
|
||||||
// assertThat(items).isEqualTo(
|
assertThat(items).isEqualTo(
|
||||||
// listOf(
|
listOf(
|
||||||
// LibraryListItem.DividerItem(Long.MAX_VALUE, R.string.downloading),
|
LibraryListItem.DividerItem(Long.MAX_VALUE, "Downloading:"),
|
||||||
// LibraryListItem.LibraryDownloadItem(downloadModel(book = bookDownloading)),
|
LibraryListItem.LibraryDownloadItem(downloadModel(book = bookDownloading)),
|
||||||
// LibraryListItem.DividerItem(Long.MAX_VALUE - 1, R.string.your_languages),
|
LibraryListItem.DividerItem(Long.MAX_VALUE - 1, "All languages"),
|
||||||
// LibraryListItem.BookItem(bookWithActiveLanguage, CanWrite4GbFile),
|
LibraryListItem.BookItem(bookWithActiveLanguage, CanWrite4GbFile),
|
||||||
// LibraryListItem.DividerItem(Long.MIN_VALUE, R.string.other_languages),
|
|
||||||
// LibraryListItem.BookItem(bookWithInactiveLanguage, CanWrite4GbFile)
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
timeout = TURBINE_TIMEOUT
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -464,39 +368,60 @@ class ZimManageViewModelTest {
|
|||||||
url = "",
|
url = "",
|
||||||
size = "${Fat32Checker.FOUR_GIGABYTES_IN_KILOBYTES + 1}"
|
size = "${Fat32Checker.FOUR_GIGABYTES_IN_KILOBYTES + 1}"
|
||||||
)
|
)
|
||||||
every { application.getString(any()) } returns ""
|
every { application.getString(any()) } answers { "" }
|
||||||
every { application.getString(any(), any()) } returns ""
|
every { application.getString(any(), any()) } answers { "" }
|
||||||
testFlow(
|
every { application.getString(any(), *anyVararg()) } answers { "" }
|
||||||
viewModel.libraryItems,
|
|
||||||
triggerAction = {
|
// test libraryItems fetches for all language.
|
||||||
networkStates.tryEmit(CONNECTED)
|
viewModel.libraryItems.test {
|
||||||
downloads.tryEmit(listOf())
|
coEvery {
|
||||||
books.tryEmit(listOf())
|
onlineLibraryManager.parseOPDSStreamAndGetBooks(any(), any())
|
||||||
languages.tryEmit(
|
} returns arrayListOf(bookOver4Gb)
|
||||||
listOf(
|
networkStates.value = CONNECTED
|
||||||
language(isActive = true, occurencesOfLanguage = 1, languageCode = "activeLanguage")
|
downloads.value = listOf()
|
||||||
)
|
books.value = listOf()
|
||||||
)
|
onlineContentLanguage.value = ""
|
||||||
fileSystemStates.tryEmit(CannotWrite4GbFile)
|
fileSystemStates.emit(FileSystemState.DetectingFileSystem)
|
||||||
viewModel.networkLibrary.emit(listOf(bookOver4Gb))
|
fileSystemStates.emit(CannotWrite4GbFile)
|
||||||
},
|
advanceUntilIdle()
|
||||||
assert = {
|
|
||||||
while (true) {
|
|
||||||
val item = awaitItem()
|
val item = awaitItem()
|
||||||
val bookItem = item.filterIsInstance<LibraryListItem.BookItem>().firstOrNull()
|
val bookItem = item.filterIsInstance<LibraryListItem.BookItem>().firstOrNull()
|
||||||
if (bookItem?.fileSystemState == CannotWrite4GbFile) {
|
if (bookItem?.fileSystemState == CannotWrite4GbFile) {
|
||||||
assertThat(item).isEqualTo(
|
assertThat(item).isEqualTo(
|
||||||
listOf(
|
listOf(
|
||||||
// LibraryListItem.DividerItem(Long.MIN_VALUE, R.string.other_languages),
|
LibraryListItem.DividerItem(Long.MIN_VALUE, "All languages"),
|
||||||
LibraryListItem.BookItem(bookOver4Gb, CannotWrite4GbFile)
|
LibraryListItem.BookItem(bookOver4Gb, CannotWrite4GbFile)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
timeout = TURBINE_TIMEOUT
|
// test library items fetches for a particular language
|
||||||
|
viewModel.libraryItems.test {
|
||||||
|
coEvery {
|
||||||
|
onlineLibraryManager.parseOPDSStreamAndGetBooks(any(), any())
|
||||||
|
} returns arrayListOf(bookOver4Gb)
|
||||||
|
every { application.getString(any(), any()) } answers { "Selected language: English" }
|
||||||
|
networkStates.value = CONNECTED
|
||||||
|
downloads.value = listOf()
|
||||||
|
books.value = listOf()
|
||||||
|
onlineContentLanguage.value = "eng"
|
||||||
|
fileSystemStates.emit(FileSystemState.DetectingFileSystem)
|
||||||
|
fileSystemStates.emit(CannotWrite4GbFile)
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
|
val item = awaitItem()
|
||||||
|
val bookItem = item.filterIsInstance<LibraryListItem.BookItem>().firstOrNull()
|
||||||
|
if (bookItem?.fileSystemState == CannotWrite4GbFile) {
|
||||||
|
assertThat(item).isEqualTo(
|
||||||
|
listOf(
|
||||||
|
LibraryListItem.DividerItem(Long.MIN_VALUE, "Selected language: English"),
|
||||||
|
LibraryListItem.BookItem(bookOver4Gb, CannotWrite4GbFile)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@ -620,6 +545,7 @@ suspend fun <T> TestScope.testFlow(
|
|||||||
triggerAction()
|
triggerAction()
|
||||||
assert()
|
assert()
|
||||||
cancelAndIgnoreRemainingEvents()
|
cancelAndIgnoreRemainingEvents()
|
||||||
|
ensureAllEventsConsumed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
job.join()
|
job.join()
|
||||||
|
@ -58,6 +58,6 @@ interface KiwixService {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val OPDS_LIBRARY_ENDPOINT = "v2/entries"
|
const val OPDS_LIBRARY_ENDPOINT = "v2/entries"
|
||||||
const val ITEMS_PER_PAGE = 50
|
const val ITEMS_PER_PAGE = 25
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,6 +183,7 @@ suspend fun <T> TestScope.testFlow(
|
|||||||
triggerAction()
|
triggerAction()
|
||||||
assert()
|
assert()
|
||||||
cancelAndIgnoreRemainingEvents()
|
cancelAndIgnoreRemainingEvents()
|
||||||
|
ensureAllEventsConsumed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
job.join()
|
job.join()
|
||||||
|
@ -241,6 +241,7 @@ suspend fun <T> TestScope.testFlow(
|
|||||||
triggerAction()
|
triggerAction()
|
||||||
assert()
|
assert()
|
||||||
cancelAndIgnoreRemainingEvents()
|
cancelAndIgnoreRemainingEvents()
|
||||||
|
ensureAllEventsConsumed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
job.join()
|
job.join()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user