Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test: Symbol selection viewmodel #96

Merged
merged 2 commits into from
Dec 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import retrofit2.Response

/*
class AuthRepositoryTest {

private lateinit var authRepository: AuthRepository
Expand Down Expand Up @@ -407,4 +407,6 @@ class AuthRepositoryTest {

*/

}
}

*/
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.example.speechbuddy.viewmodel

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer
import com.example.speechbuddy.domain.models.Category
import com.example.speechbuddy.domain.models.Entry
import com.example.speechbuddy.domain.models.Symbol
import com.example.speechbuddy.repository.SymbolRepository
import com.example.speechbuddy.repository.WeightTableRepository
import com.example.speechbuddy.ui.models.DisplayMode
import com.example.speechbuddy.ui.models.SymbolItem
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.impl.annotations.MockK
import io.mockk.mockk
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
Expand All @@ -21,27 +25,31 @@ import kotlinx.coroutines.test.setMain
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Rule
import org.junit.Test

class SymbolSelectionViewModelTest {
@OptIn(DelicateCoroutinesApi::class)
private val mainThreadSurrogate = newSingleThreadContext("UI thread")

@MockK
private val mockSymbolRepository: SymbolRepository = mockk(relaxed = true)
private val mockWeightTableRepository: WeightTableRepository = mockk(relaxed = true)
private lateinit var viewModel: SymbolSelectionViewModel
private lateinit var mockSymbolRepository: SymbolRepository
private lateinit var mockWeightTableRepository: WeightTableRepository

private val symbol = Symbol(
id = 1, text = "test1", imageUrl = null, categoryId = 1, isFavorite = false, isMine = false
)
private val category = Category(1, "category")
private val query = "test"

@get:Rule
var instantExecutorRule = InstantTaskExecutorRule()

@OptIn(ExperimentalCoroutinesApi::class)
@Before
fun setUp() {
Dispatchers.setMain(mainThreadSurrogate)

mockSymbolRepository = mockk()
mockWeightTableRepository = mockk()
viewModel = SymbolSelectionViewModel(mockSymbolRepository, mockWeightTableRepository)
}

Expand All @@ -52,6 +60,107 @@ class SymbolSelectionViewModelTest {
mainThreadSurrogate.close()
}

class TestObserver<T> : Observer<T> {
val observedValues = mutableListOf<T?>()

override fun onChanged(value: T) {
observedValues.add(value)
}
}

@Test
fun `should enter display max when called`() {
viewModel.enterDisplayMax()
assertEquals(true, viewModel.uiState.value.isDisplayMax)
}

@Test
fun `should exit display max when called`() {
viewModel.exitDisplayMax()
assertEquals(false, viewModel.uiState.value.isDisplayMax)
}

@Test
fun `should select display mode when display mode is inputted`() {
val displayModeSymbol = DisplayMode.SYMBOL
val displayModeFavorite = DisplayMode.FAVORITE
val displayModeAll = DisplayMode.ALL
val displayModeCategory = DisplayMode.CATEGORY
val observer = TestObserver<List<Entry>>()
viewModel.entries.observeForever(observer)

coEvery { mockSymbolRepository.getEntries("") } returns flowOf(listOf(symbol))
coEvery { mockSymbolRepository.getSymbols("") } returns flowOf(listOf(symbol))
coEvery { mockSymbolRepository.getCategories("") } returns flowOf(listOf(category))
coEvery { mockSymbolRepository.getFavoriteSymbols("") } returns flowOf(listOf(symbol))

viewModel.selectDisplayMode(displayModeSymbol)
Thread.sleep(10) // viewModel.setQuery does not immediately produce result
assertEquals(displayModeSymbol, viewModel.uiState.value.displayMode)
assertEquals(symbol, observer.observedValues.last()?.get(0))

viewModel.selectDisplayMode(displayModeFavorite)
Thread.sleep(10) // viewModel.setQuery does not immediately produce result
assertEquals(displayModeFavorite, viewModel.uiState.value.displayMode)
assertEquals(symbol, observer.observedValues.last()?.get(0))

viewModel.selectDisplayMode(displayModeAll)
Thread.sleep(10) // viewModel.setQuery does not immediately produce result
assertEquals(displayModeAll, viewModel.uiState.value.displayMode)
assertEquals(symbol, observer.observedValues.last()?.get(0))

viewModel.selectDisplayMode(displayModeCategory)
Thread.sleep(10) // viewModel.setQuery does not immediately produce result
assertEquals(displayModeCategory, viewModel.uiState.value.displayMode)
assertEquals(category, observer.observedValues.last()?.get(0))
}


@Test
fun `should set query when query is inputted`() = runBlocking {
val observer = TestObserver<List<Entry>>()
viewModel.entries.observeForever(observer)

coEvery { mockSymbolRepository.getEntries(query) } returns flowOf(listOf(symbol))

viewModel.setQuery(query)
Thread.sleep(10) // viewModel.setQuery does not immediately produce result

assertEquals(symbol, observer.observedValues.last()?.get(0))
coVerify { mockSymbolRepository.getEntries(query) }
}


@Test
fun `clear single symbol when symbol item is inputted`() {
val symbolItem = SymbolItem(1, symbol)
coEvery { mockSymbolRepository.getEntries("") } returns flowOf(listOf(symbol))
coEvery { mockSymbolRepository.getSymbols("") } returns flowOf(listOf(symbol))
coEvery { mockSymbolRepository.getCategories("") } returns flowOf(listOf(category))
coEvery { mockSymbolRepository.getFavoriteSymbols("") } returns flowOf(listOf(symbol))
coEvery { mockWeightTableRepository.provideSuggestion(symbol) } returns flowOf(listOf(symbol))

viewModel.selectSymbol(symbol)
viewModel.clear(symbolItem)
assertEquals(symbol, viewModel.entries.value?.get(0))

viewModel.clear(symbolItem)
assertEquals(symbol, viewModel.entries.value?.get(0))
}

@Test
fun `should clear all selected symbols when called`() {
val selectedSymbols = listOf(SymbolItem(0, symbol))

coEvery { mockWeightTableRepository.update(selectedSymbols) } returns Unit

viewModel.selectSymbol(symbol)
viewModel.clearAll()

coVerify { mockWeightTableRepository.update(selectedSymbols) }
assertEquals(true, viewModel.selectedSymbols.isEmpty())
}

@Test
fun `should add symbol to selectedSymbols and provide suggestion when symbol is given`() =
runBlocking {
Expand Down Expand Up @@ -89,22 +198,14 @@ class SymbolSelectionViewModelTest {
}

@Test
fun `should set setQuery when input is made`() = runBlocking {
val input = "test"
viewModel.setQuery(input)
coVerify { mockSymbolRepository.getEntries(input) }
}


// @Test
// fun `should update weighttable and empty selected symbols when function is called`() =
// runBlocking {
// viewModel.selectSymbol(symbol)
// val temp = viewModel.selectedSymbols
// viewModel.clearAll()
// coVerify { mockWeightTableRepository.update(temp) }
// assertEquals(emptyList<SymbolItem>(), viewModel.selectedSymbols)
// }
fun `should update weighttable and empty selected symbols when function is called`() =
runBlocking {
viewModel.selectSymbol(symbol)
val temp = viewModel.selectedSymbols
viewModel.clearAll()
coVerify { mockWeightTableRepository.update(temp) }
assertEquals(emptyList<SymbolItem>(), viewModel.selectedSymbols)
}

@Test
fun `should update favorite when function is called`() = runBlocking {
Expand Down