Add unit tests for MessageSearchHelper

Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
This commit is contained in:
Álvaro Brey 2022-05-24 14:31:12 +02:00
parent 1d632f3c96
commit b10ea2f41f
No known key found for this signature in database
GPG Key ID: 2585783189A62105
3 changed files with 194 additions and 7 deletions

View File

@ -41,6 +41,7 @@ class MessageSearchHelper(
private var previousResults: List<SearchMessageEntry> = emptyList()
fun startMessageSearch(search: String): Observable<MessageSearchResults> {
resetCachedData()
return doSearch(search)
}
@ -56,7 +57,6 @@ class MessageSearchHelper(
}
private fun doSearch(search: String, cursor: Int = 0): Observable<MessageSearchResults> {
resetResultsIfNeeded(search)
disposeIfPossible()
return unifiedSearchRepository.searchMessages(user, search, cursor)
.map { results ->
@ -76,12 +76,6 @@ class MessageSearchHelper(
.doOnComplete(this::disposeIfPossible)
}
private fun resetResultsIfNeeded(search: String) {
if (search != previousSearch) {
resetCachedData()
}
}
private fun resetCachedData() {
previousSearch = null
previousCursor = 0

View File

@ -0,0 +1,146 @@
/*
* Nextcloud Talk application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.controllers.util
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.domain.SearchMessageEntry
import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepository
import com.nextcloud.talk.test.fakes.FakeUnifiedSearchRepository
import io.reactivex.Observable
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.MockitoAnnotations
class MessageSearchHelperTest {
@Mock
lateinit var userEntity: UserEntity
val repository = FakeUnifiedSearchRepository()
@Suppress("LongParameterList")
private fun createMessageEntry(
searchTerm: String = "foo",
thumbnailURL: String = "foo",
title: String = "foo",
messageExcerpt: String = "foo",
conversationToken: String = "foo",
messageId: String? = "foo"
) = SearchMessageEntry(searchTerm, thumbnailURL, title, messageExcerpt, conversationToken, messageId)
@Before
fun setUp() {
MockitoAnnotations.openMocks(this)
}
@Test
fun emptySearch() {
repository.response = UnifiedSearchRepository.UnifiedSearchResults(0, false, emptyList())
val sut = MessageSearchHelper(userEntity, repository)
val testObserver = sut.startMessageSearch("foo").test()
testObserver.assertComplete()
testObserver.assertValueCount(1)
val expected = MessageSearchHelper.MessageSearchResults(emptyList(), false)
testObserver.assertValue(expected)
}
@Test
fun nonEmptySearch_withMoreResults() {
val entries = (1..5).map { createMessageEntry() }
repository.response = UnifiedSearchRepository.UnifiedSearchResults(5, true, entries)
val sut = MessageSearchHelper(userEntity, repository)
val observable = sut.startMessageSearch("foo")
val expected = MessageSearchHelper.MessageSearchResults(entries, true)
testCall(observable, expected)
}
@Test
fun nonEmptySearch_withNoMoreResults() {
val entries = (1..2).map { createMessageEntry() }
repository.response = UnifiedSearchRepository.UnifiedSearchResults(2, false, entries)
val sut = MessageSearchHelper(userEntity, repository)
val observable = sut.startMessageSearch("foo")
val expected = MessageSearchHelper.MessageSearchResults(entries, false)
testCall(observable, expected)
}
@Test
fun nonEmptySearch_consecutiveSearches_sameResult() {
val entries = (1..2).map { createMessageEntry() }
repository.response = UnifiedSearchRepository.UnifiedSearchResults(2, false, entries)
val sut = MessageSearchHelper(userEntity, repository)
repeat(5) {
val observable = sut.startMessageSearch("foo")
val expected = MessageSearchHelper.MessageSearchResults(entries, false)
testCall(observable, expected)
}
}
@Test
fun loadMore_noPreviousResults() {
val sut = MessageSearchHelper(userEntity, repository)
Assert.assertEquals(null, sut.loadMore())
}
@Test
fun loadMore_previousResults_sameSearch() {
val sut = MessageSearchHelper(userEntity, repository)
val firstPageEntries = (1..5).map { createMessageEntry() }
repository.response = UnifiedSearchRepository.UnifiedSearchResults(5, true, firstPageEntries)
val firstPageObservable = sut.startMessageSearch("foo")
Assert.assertEquals(0, repository.lastRequestedCursor)
val firstPageExpected = MessageSearchHelper.MessageSearchResults(firstPageEntries, true)
testCall(firstPageObservable, firstPageExpected)
val secondPageEntries = (1..5).map { createMessageEntry(title = "bar") }
repository.response = UnifiedSearchRepository.UnifiedSearchResults(10, false, secondPageEntries)
val secondPageObservable = sut.loadMore()
Assert.assertEquals(5, repository.lastRequestedCursor)
Assert.assertNotNull(secondPageObservable)
val secondPageExpected = MessageSearchHelper.MessageSearchResults(firstPageEntries + secondPageEntries, false)
testCall(secondPageObservable!!, secondPageExpected)
}
private fun testCall(
searchCall: Observable<MessageSearchHelper.MessageSearchResults>,
expectedResult: MessageSearchHelper.MessageSearchResults
) {
val testObserver = searchCall.test()
testObserver.assertComplete()
testObserver.assertValueCount(1)
testObserver.assertValue(expectedResult)
testObserver.dispose()
}
}

View File

@ -0,0 +1,47 @@
/*
* Nextcloud Talk application
*
* @author Álvaro Brey
* Copyright (C) 2022 Álvaro Brey
* Copyright (C) 2022 Nextcloud GmbH
*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.test.fakes
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.domain.SearchMessageEntry
import com.nextcloud.talk.repositories.unifiedsearch.UnifiedSearchRepository
import io.reactivex.Observable
class FakeUnifiedSearchRepository : UnifiedSearchRepository {
lateinit var response: UnifiedSearchRepository.UnifiedSearchResults<SearchMessageEntry>
var lastRequestedCursor = -1
override fun searchMessages(
userEntity: UserEntity,
searchTerm: String,
cursor: Int,
limit: Int
): Observable<UnifiedSearchRepository.UnifiedSearchResults<SearchMessageEntry>> {
lastRequestedCursor = cursor
return Observable.just(response)
}
override fun searchInRoom(text: String, roomId: String): Observable<List<SearchMessageEntry>> {
TODO("Not yet implemented")
}
}