1package com.parseable.android
3import com.parseable.android.data.model.Alert
4import com.parseable.android.data.model.ApiResult
5import com.parseable.android.data.repository.ParseableRepository
6import com.parseable.android.ui.screens.alerts.AlertsViewModel
8import kotlinx.coroutines.Dispatchers
9import kotlinx.coroutines.ExperimentalCoroutinesApi
10import kotlinx.coroutines.test.*
12import org.junit.Assert.*
13import org.junit.Before
16@OptIn(ExperimentalCoroutinesApi::class)
17class AlertsViewModelTest {
19 private lateinit var repository: ParseableRepository
20 private lateinit var viewModel: AlertsViewModel
21 private val testDispatcher = UnconfinedTestDispatcher()
25 Dispatchers.setMain(testDispatcher)
26 repository = mockk(relaxed = true)
27 // The ViewModel loads once in init { refresh() }. Give that load a deterministic
28 // empty-success default so the initial state is clean; tests that exercise refresh
29 // override this stub and call refresh() again.
30 coEvery { repository.listAlerts() } returns ApiResult.Success(emptyList())
31 viewModel = AlertsViewModel(repository)
36 Dispatchers.resetMain()
40 fun `initial state has empty alerts and no loading`() {
41 val state = viewModel.state.value
42 assertTrue(state.alerts.isEmpty())
43 assertFalse(state.isLoading)
44 assertNull(state.error)
45 assertNull(state.alertToDelete)
49 fun `refresh loads alerts on success`() = runTest {
51 Alert(id = "1", title = "Alert 1", datasets = listOf("stream1"), state = "NotTriggered"),
52 Alert(id = "2", title = "Alert 2", datasets = listOf("stream2"), state = "Triggered"),
54 coEvery { repository.listAlerts() } returns ApiResult.Success(alerts)
58 val state = viewModel.state.value
59 assertEquals(alerts, state.alerts)
60 assertFalse(state.isLoading)
61 assertNull(state.error)
65 fun `refresh shows error on failure`() = runTest {
66 coEvery { repository.listAlerts() } returns ApiResult.Error("Server error", 500)
70 val state = viewModel.state.value
71 assertTrue(state.alerts.isEmpty())
72 assertFalse(state.isLoading)
73 assertNotNull(state.error)
77 fun `requestDelete sets alertToDelete`() {
78 val alert = Alert(id = "1", title = "Alert 1", datasets = listOf("stream1"))
80 viewModel.requestDelete(alert)
82 val state = viewModel.state.value
83 assertEquals(alert, state.alertToDelete)
87 fun `cancelDelete clears alertToDelete`() {
88 val alert = Alert(id = "1", title = "Alert 1", datasets = listOf("stream1"))
89 viewModel.requestDelete(alert)
90 assertEquals(alert, viewModel.state.value.alertToDelete)
92 viewModel.cancelDelete()
94 assertNull(viewModel.state.value.alertToDelete)
98 fun `deleteAlert on success refreshes list`() = runTest {
100 Alert(id = "2", title = "Alert 2", datasets = listOf("stream2")),
102 coEvery { repository.deleteAlert("1") } returns ApiResult.Success("deleted")
103 coEvery { repository.listAlerts() } returns ApiResult.Success(alerts)
105 viewModel.deleteAlert("1")
107 val state = viewModel.state.value
108 assertEquals(alerts, state.alerts)
109 assertFalse(state.isLoading)
110 assertNull(state.error)
111 assertNull(state.alertToDelete)
112 coVerify { repository.deleteAlert("1") }
113 coVerify { repository.listAlerts() }
117 fun `deleteAlert on error shows error message`() = runTest {
118 coEvery { repository.deleteAlert("1") } returns ApiResult.Error("Not found", 404)
120 viewModel.deleteAlert("1")
122 val state = viewModel.state.value
123 assertFalse(state.isLoading)
124 assertNotNull(state.error)
125 assertNull(state.alertToDelete)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list