mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 18:56:44 -04:00
Updated test cases to accommodate the new search functionality.
* Due to linking errors with libkiwix/libzim functions, direct usage in testing was not possible. To address this, helper classes were created, similar to those in `java-libkiwix`, for testing the search functionality.
This commit is contained in:
parent
f03830c62f
commit
90e7e8d7f7
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2023 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.search.viewmodel
|
||||
|
||||
import org.kiwix.libzim.Entry
|
||||
|
||||
internal class EntryWrapper : Entry() {
|
||||
override fun getTitle(): String = super.getTitle()
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2023 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.search.viewmodel
|
||||
|
||||
import org.kiwix.libzim.SearchIterator
|
||||
|
||||
// Create this as a helper class, as we can not directly use libkiwix/libzim functions in testing
|
||||
internal class SearchIteratorWrapper : SearchIterator() {
|
||||
override fun remove() {}
|
||||
|
||||
override fun hasNext(): Boolean = super.hasNext()
|
||||
override fun next(): EntryWrapper = super.next() as EntryWrapper
|
||||
}
|
@ -18,25 +18,43 @@
|
||||
|
||||
package org.kiwix.kiwixmobile.core.search.viewmodel
|
||||
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem.RecentSearchListItem
|
||||
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem.ZimSearchResultListItem
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.SearchOrigin.FromWebView
|
||||
|
||||
internal class SearchStateTest {
|
||||
|
||||
@Test
|
||||
internal fun `visibleResults use searchResults when searchTerm is not empty`() {
|
||||
val results = listOf(ZimSearchResultListItem(""))
|
||||
val searchTerm = "notEmpty"
|
||||
val searchWrapper: SearchWrapper = mockk()
|
||||
val searchIteratorWrapper: SearchIteratorWrapper = mockk()
|
||||
val entryWrapper: EntryWrapper = mockk()
|
||||
val estimatedMatches = 1
|
||||
every { searchWrapper.estimatedMatches } returns estimatedMatches.toLong()
|
||||
// Settings list to hasNext() to ensure it returns true only for the first call.
|
||||
// Otherwise, if we do not set this, the method will always return true when checking if the iterator has a next value,
|
||||
// causing our test case to get stuck in an infinite loop due to this explicit setting.
|
||||
every { searchIteratorWrapper.hasNext() } returnsMany listOf(true, false)
|
||||
every { searchIteratorWrapper.next() } returns entryWrapper
|
||||
every { entryWrapper.title } returns searchTerm
|
||||
every {
|
||||
searchWrapper.getResults(
|
||||
0,
|
||||
estimatedMatches
|
||||
)
|
||||
} returns searchIteratorWrapper
|
||||
assertThat(
|
||||
SearchState(
|
||||
"notEmpty",
|
||||
SearchResultsWithTerm("", results),
|
||||
searchTerm,
|
||||
SearchResultsWithTerm("", searchWrapper),
|
||||
emptyList(),
|
||||
FromWebView
|
||||
).getVisibleResults(0)
|
||||
).isEqualTo(results)
|
||||
).isEqualTo(listOf(RecentSearchListItem(searchTerm)))
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -45,7 +63,7 @@ internal class SearchStateTest {
|
||||
assertThat(
|
||||
SearchState(
|
||||
"",
|
||||
SearchResultsWithTerm("", emptyList()),
|
||||
SearchResultsWithTerm("", null),
|
||||
results,
|
||||
FromWebView
|
||||
).getVisibleResults(0)
|
||||
@ -57,11 +75,11 @@ internal class SearchStateTest {
|
||||
assertThat(
|
||||
SearchState(
|
||||
"",
|
||||
SearchResultsWithTerm("notEqual", emptyList()),
|
||||
SearchResultsWithTerm("notEqual", null),
|
||||
emptyList(),
|
||||
FromWebView
|
||||
).isLoading
|
||||
).isTrue()
|
||||
).isTrue
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -70,10 +88,10 @@ internal class SearchStateTest {
|
||||
assertThat(
|
||||
SearchState(
|
||||
searchTerm,
|
||||
SearchResultsWithTerm(searchTerm, emptyList()),
|
||||
SearchResultsWithTerm(searchTerm, null),
|
||||
emptyList(),
|
||||
FromWebView
|
||||
).isLoading
|
||||
).isFalse()
|
||||
).isFalse
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ import org.kiwix.kiwixmobile.core.search.viewmodel.effects.SearchInPreviousScree
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.effects.ShowDeleteSearchDialog
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.effects.ShowToast
|
||||
import org.kiwix.kiwixmobile.core.search.viewmodel.effects.StartSpeechInput
|
||||
import org.kiwix.libzim.Search
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
internal class SearchViewModelTest {
|
||||
@ -101,7 +102,7 @@ internal class SearchViewModelTest {
|
||||
every { zimReaderContainer.copyReader() } returns zimFileReader
|
||||
coEvery {
|
||||
searchResultGenerator.generateSearchResults("", zimFileReader)
|
||||
} returns emptyList()
|
||||
} returns null
|
||||
every { zimReaderContainer.id } returns "id"
|
||||
every { recentSearchDao.recentSearches("id") } returns recentsFromDb.consumeAsFlow()
|
||||
viewModel = SearchViewModel(recentSearchDao, zimReaderContainer, searchResultGenerator)
|
||||
@ -112,7 +113,7 @@ internal class SearchViewModelTest {
|
||||
@Test
|
||||
fun `initial state is Initialising`() = runBlockingTest {
|
||||
viewModel.state.test(this).assertValue(
|
||||
SearchState("", SearchResultsWithTerm("", emptyList()), emptyList(), FromWebView)
|
||||
SearchState("", SearchResultsWithTerm("", null), emptyList(), FromWebView)
|
||||
).finish()
|
||||
}
|
||||
|
||||
@ -121,11 +122,12 @@ internal class SearchViewModelTest {
|
||||
val item = ZimSearchResultListItem("")
|
||||
val searchTerm = "searchTerm"
|
||||
val searchOrigin = FromWebView
|
||||
val search: Search = mockk()
|
||||
viewModel.state.test(this)
|
||||
.also {
|
||||
emissionOf(
|
||||
searchTerm = searchTerm,
|
||||
searchResults = listOf(item),
|
||||
search = search,
|
||||
databaseResults = listOf(RecentSearchListItem("")),
|
||||
searchOrigin = searchOrigin
|
||||
)
|
||||
@ -133,7 +135,7 @@ internal class SearchViewModelTest {
|
||||
.assertValue(
|
||||
SearchState(
|
||||
searchTerm,
|
||||
SearchResultsWithTerm(searchTerm, listOf(item)),
|
||||
SearchResultsWithTerm(searchTerm, search),
|
||||
listOf(RecentSearchListItem("")),
|
||||
searchOrigin
|
||||
)
|
||||
@ -241,14 +243,14 @@ internal class SearchViewModelTest {
|
||||
|
||||
private fun TestScope.emissionOf(
|
||||
searchTerm: String,
|
||||
searchResults: List<ZimSearchResultListItem>,
|
||||
search: Search,
|
||||
databaseResults: List<RecentSearchListItem>,
|
||||
searchOrigin: SearchOrigin
|
||||
) {
|
||||
|
||||
coEvery {
|
||||
searchResultGenerator.generateSearchResults(searchTerm, zimFileReader)
|
||||
} returns searchResults
|
||||
} returns search
|
||||
viewModel.actions.trySend(Filter(searchTerm)).isSuccess
|
||||
recentsFromDb.trySend(databaseResults).isSuccess
|
||||
viewModel.actions.trySend(ScreenWasStartedFrom(searchOrigin)).isSuccess
|
||||
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2023 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.kiwix.kiwixmobile.core.search.viewmodel
|
||||
|
||||
import org.kiwix.libzim.Search
|
||||
|
||||
// Create this as a helper class, as we can not directly use libkiwix/libzim functions in testing
|
||||
internal class SearchWrapper : Search() {
|
||||
override fun getEstimatedMatches(): Long = super.getEstimatedMatches()
|
||||
|
||||
override fun getResults(start: Int, maxResults: Int): SearchIteratorWrapper =
|
||||
super.getResults(start, maxResults) as SearchIteratorWrapper
|
||||
}
|
@ -25,8 +25,6 @@ import kotlinx.coroutines.runBlocking
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.kiwix.kiwixmobile.core.reader.ZimFileReader
|
||||
import org.kiwix.kiwixmobile.core.search.adapter.SearchListItem.ZimSearchResultListItem
|
||||
import org.kiwix.libzim.Search
|
||||
|
||||
internal class ZimSearchResultGeneratorTest {
|
||||
|
||||
@ -39,21 +37,18 @@ internal class ZimSearchResultGeneratorTest {
|
||||
internal fun `empty search term returns empty list`() {
|
||||
runBlocking {
|
||||
assertThat(zimSearchResultGenerator.generateSearchResults("", zimFileReader))
|
||||
.isEqualTo(emptyList<ZimSearchResultListItem>())
|
||||
.isEqualTo(null)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
internal fun `suggestion results are distinct`() {
|
||||
val validTitle = "title"
|
||||
val searchTerm = " "
|
||||
val item = ZimSearchResultListItem(validTitle)
|
||||
val search: Search = mockk()
|
||||
every { zimFileReader.searchSuggestions(searchTerm) } returns search
|
||||
every { zimFileReader.getSearchResultList(search) } returns listOf(item)
|
||||
val searchWrapper: SearchWrapper = mockk()
|
||||
every { zimFileReader.searchSuggestions(searchTerm) } returns searchWrapper
|
||||
runBlocking {
|
||||
assertThat(zimSearchResultGenerator.generateSearchResults(searchTerm, zimFileReader))
|
||||
.isEqualTo(listOf(ZimSearchResultListItem(validTitle)))
|
||||
.isEqualTo(searchWrapper)
|
||||
verify {
|
||||
zimFileReader.searchSuggestions(searchTerm)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user