mirror of
https://github.com/wismna/DoNext.git
synced 2025-12-06 00:02:40 -05:00
Add DueTodayViewModel Unit Tests
This commit is contained in:
BIN
donext.backup
Normal file
BIN
donext.backup
Normal file
Binary file not shown.
@@ -80,6 +80,9 @@ dependencies {
|
|||||||
implementation("androidx.navigation:navigation-compose:2.9.5")
|
implementation("androidx.navigation:navigation-compose:2.9.5")
|
||||||
implementation("androidx.hilt:hilt-navigation-compose:1.3.0")
|
implementation("androidx.hilt:hilt-navigation-compose:1.3.0")
|
||||||
implementation("sh.calvin.reorderable:reorderable:3.0.0")
|
implementation("sh.calvin.reorderable:reorderable:3.0.0")
|
||||||
|
testImplementation("junit:junit:4.13.2")
|
||||||
|
testImplementation("io.mockk:mockk:1.13.12")
|
||||||
|
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")
|
||||||
androidTestImplementation("androidx.test.ext:junit-ktx:1.3.0")
|
androidTestImplementation("androidx.test.ext:junit-ktx:1.3.0")
|
||||||
androidTestImplementation(platform("androidx.compose:compose-bom:2025.10.01"))
|
androidTestImplementation(platform("androidx.compose:compose-bom:2025.10.01"))
|
||||||
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
package com.wismna.geoffroy.donext.presentation.viewmodel
|
||||||
|
|
||||||
|
import com.wismna.geoffroy.donext.R
|
||||||
|
import com.wismna.geoffroy.donext.domain.model.Priority
|
||||||
|
import com.wismna.geoffroy.donext.domain.model.Task
|
||||||
|
import com.wismna.geoffroy.donext.domain.usecase.GetDueTodayTasksUseCase
|
||||||
|
import com.wismna.geoffroy.donext.domain.usecase.ToggleTaskDeletedUseCase
|
||||||
|
import com.wismna.geoffroy.donext.domain.usecase.ToggleTaskDoneUseCase
|
||||||
|
import com.wismna.geoffroy.donext.presentation.ui.events.UiEvent
|
||||||
|
import com.wismna.geoffroy.donext.presentation.ui.events.UiEventBus
|
||||||
|
import io.mockk.*
|
||||||
|
import junit.framework.TestCase.assertEquals
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
import kotlinx.coroutines.test.*
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
class DueTodayViewModelTest {
|
||||||
|
|
||||||
|
private lateinit var getDueTodayTasksUseCase: GetDueTodayTasksUseCase
|
||||||
|
private lateinit var toggleTaskDeletedUseCase: ToggleTaskDeletedUseCase
|
||||||
|
private lateinit var toggleTaskDoneUseCase: ToggleTaskDoneUseCase
|
||||||
|
private lateinit var uiEventBus: UiEventBus
|
||||||
|
private lateinit var viewModel: DueTodayViewModel
|
||||||
|
|
||||||
|
private val testDispatcher = StandardTestDispatcher()
|
||||||
|
private val tasksFlow = MutableSharedFlow<List<Task>>(replay = 1)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
Dispatchers.setMain(testDispatcher)
|
||||||
|
|
||||||
|
getDueTodayTasksUseCase = mockk()
|
||||||
|
toggleTaskDeletedUseCase = mockk(relaxed = true)
|
||||||
|
toggleTaskDoneUseCase = mockk(relaxed = true)
|
||||||
|
uiEventBus = mockk(relaxed = true)
|
||||||
|
|
||||||
|
coEvery { getDueTodayTasksUseCase.invoke() } returns tasksFlow
|
||||||
|
|
||||||
|
viewModel = DueTodayViewModel(
|
||||||
|
getDueTodayTasksUseCase,
|
||||||
|
toggleTaskDeletedUseCase,
|
||||||
|
toggleTaskDoneUseCase,
|
||||||
|
uiEventBus
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun tearDown() {
|
||||||
|
Dispatchers.resetMain()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `dueTodayTasks updates when flow emits`() = runTest {
|
||||||
|
val taskList = listOf(Task(taskListId = 0, id = 1, name = "Test Task", description = "", priority = Priority.NORMAL, isDone = false, isDeleted = false))
|
||||||
|
tasksFlow.emit(taskList)
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
|
assertEquals(taskList, viewModel.dueTodayTasks)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `onTaskClicked sends EditTask event`() = runTest {
|
||||||
|
val task = Task(taskListId = 0, id = 42, name = "Click me", description = "", priority = Priority.NORMAL, isDone = false, isDeleted = false)
|
||||||
|
|
||||||
|
viewModel.onTaskClicked(task)
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
|
coVerify { uiEventBus.send(UiEvent.EditTask(task)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `updateTaskDone toggles done and sends snackbar with undo`() = runTest {
|
||||||
|
val taskId = 5L
|
||||||
|
|
||||||
|
viewModel.updateTaskDone(taskId)
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
|
coVerify { toggleTaskDoneUseCase(taskId, true) }
|
||||||
|
coVerify {
|
||||||
|
uiEventBus.send(
|
||||||
|
match {
|
||||||
|
it is UiEvent.ShowUndoSnackbar &&
|
||||||
|
it.message == R.string.snackbar_message_task_done
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `deleteTask toggles deleted and sends snackbar with undo`() = runTest {
|
||||||
|
val taskId = 7L
|
||||||
|
|
||||||
|
viewModel.deleteTask(taskId)
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
|
coVerify { toggleTaskDeletedUseCase(taskId, true) }
|
||||||
|
coVerify {
|
||||||
|
uiEventBus.send(
|
||||||
|
match{
|
||||||
|
it is UiEvent.ShowUndoSnackbar &&
|
||||||
|
it.message == R.string.snackbar_message_task_recycle
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user