mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor: coroutine dispatchers and modernize testing infrastructure (#4901)
Some checks are pending
Dependency Submission / dependency-submission (push) Waiting to run
Main CI (Verify & Build) / validate-and-build (push) Waiting to run
Main Push Changelog / Generate main push changelog (push) Waiting to run
Some checks are pending
Dependency Submission / dependency-submission (push) Waiting to run
Main CI (Verify & Build) / validate-and-build (push) Waiting to run
Main Push Changelog / Generate main push changelog (push) Waiting to run
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
664ebf218e
commit
96060a0a4d
36 changed files with 621 additions and 182 deletions
|
|
@ -42,6 +42,7 @@ class AndroidScannerViewModel(
|
|||
radioInterfaceService: RadioInterfaceService,
|
||||
recentAddressesDataSource: RecentAddressesDataSource,
|
||||
getDiscoveredDevicesUseCase: GetDiscoveredDevicesUseCase,
|
||||
dispatchers: org.meshtastic.core.di.CoroutineDispatchers,
|
||||
private val bluetoothRepository: BluetoothRepository,
|
||||
private val usbRepository: UsbRepository,
|
||||
bleScanner: org.meshtastic.core.ble.BleScanner? = null,
|
||||
|
|
@ -51,6 +52,7 @@ class AndroidScannerViewModel(
|
|||
radioInterfaceService,
|
||||
recentAddressesDataSource,
|
||||
getDiscoveredDevicesUseCase,
|
||||
dispatchers,
|
||||
bleScanner,
|
||||
) {
|
||||
override fun requestBonding(entry: DeviceListEntry.Ble) {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import kotlinx.coroutines.flow.stateIn
|
|||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.annotation.KoinViewModel
|
||||
import org.meshtastic.core.common.util.ioDispatcher
|
||||
import org.meshtastic.core.datastore.RecentAddressesDataSource
|
||||
import org.meshtastic.core.datastore.model.RecentAddress
|
||||
import org.meshtastic.core.model.RadioController
|
||||
|
|
@ -52,6 +51,7 @@ open class ScannerViewModel(
|
|||
private val radioInterfaceService: RadioInterfaceService,
|
||||
private val recentAddressesDataSource: RecentAddressesDataSource,
|
||||
private val getDiscoveredDevicesUseCase: GetDiscoveredDevicesUseCase,
|
||||
private val dispatchers: org.meshtastic.core.di.CoroutineDispatchers,
|
||||
private val bleScanner: org.meshtastic.core.ble.BleScanner? = null,
|
||||
) : ViewModel() {
|
||||
private val _showMockInterface = MutableStateFlow(false)
|
||||
|
|
@ -84,7 +84,7 @@ open class ScannerViewModel(
|
|||
timeout = kotlin.time.Duration.INFINITE,
|
||||
serviceUuid = org.meshtastic.core.ble.MeshtasticBleConstants.SERVICE_UUID,
|
||||
)
|
||||
.flowOn(ioDispatcher)
|
||||
.flowOn(dispatchers.io)
|
||||
.collect { device ->
|
||||
if (!scannedBleDevices.value.containsKey(device.address)) {
|
||||
scannedBleDevices.update { current -> current + (device.address to device) }
|
||||
|
|
@ -123,7 +123,7 @@ open class ScannerViewModel(
|
|||
// Sort by name
|
||||
(bonded + unbondedScanned).sortedBy { it.name }
|
||||
}
|
||||
.flowOn(kotlinx.coroutines.Dispatchers.Default)
|
||||
.flowOn(dispatchers.default)
|
||||
.distinctUntilChanged()
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,12 @@ import dev.mokkery.every
|
|||
import dev.mokkery.matcher.any
|
||||
import dev.mokkery.mock
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.meshtastic.core.datastore.RecentAddressesDataSource
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.repository.RadioInterfaceService
|
||||
import org.meshtastic.core.repository.ServiceRepository
|
||||
import org.meshtastic.core.testing.FakeRadioController
|
||||
import org.meshtastic.core.testing.FakeServiceRepository
|
||||
import org.meshtastic.feature.connections.model.DiscoveredDevices
|
||||
import org.meshtastic.feature.connections.model.GetDiscoveredDevicesUseCase
|
||||
import kotlin.test.BeforeTest
|
||||
|
|
@ -35,17 +36,17 @@ import kotlin.test.Test
|
|||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
class ScannerViewModelTest {
|
||||
|
||||
private lateinit var viewModel: ScannerViewModel
|
||||
private val serviceRepository: ServiceRepository = mock(MockMode.autofill)
|
||||
private val radioController: RadioController = mock(MockMode.autofill)
|
||||
private val serviceRepository = FakeServiceRepository()
|
||||
private val radioController = FakeRadioController()
|
||||
private val radioInterfaceService: RadioInterfaceService = mock(MockMode.autofill)
|
||||
private val recentAddressesDataSource: RecentAddressesDataSource = mock(MockMode.autofill)
|
||||
private val getDiscoveredDevicesUseCase: GetDiscoveredDevicesUseCase = mock(MockMode.autofill)
|
||||
private val bleScanner: org.meshtastic.core.ble.BleScanner = mock(MockMode.autofill)
|
||||
|
||||
private val connectionProgressFlow = MutableStateFlow<String?>(null)
|
||||
private val discoveredDevicesFlow = MutableStateFlow(DiscoveredDevices())
|
||||
|
||||
@BeforeTest
|
||||
|
|
@ -54,11 +55,10 @@ class ScannerViewModelTest {
|
|||
every { radioInterfaceService.currentDeviceAddressFlow } returns MutableStateFlow(null)
|
||||
every { radioInterfaceService.supportedDeviceTypes } returns emptyList()
|
||||
|
||||
every { serviceRepository.connectionProgress } returns connectionProgressFlow
|
||||
every { getDiscoveredDevicesUseCase.invoke(any()) } returns discoveredDevicesFlow
|
||||
every { recentAddressesDataSource.recentAddresses } returns MutableStateFlow(emptyList())
|
||||
|
||||
connectionProgressFlow.value = null
|
||||
serviceRepository.setConnectionProgress("")
|
||||
discoveredDevicesFlow.value = DiscoveredDevices()
|
||||
|
||||
viewModel =
|
||||
|
|
@ -68,6 +68,12 @@ class ScannerViewModelTest {
|
|||
radioInterfaceService = radioInterfaceService,
|
||||
recentAddressesDataSource = recentAddressesDataSource,
|
||||
getDiscoveredDevicesUseCase = getDiscoveredDevicesUseCase,
|
||||
dispatchers =
|
||||
org.meshtastic.core.di.CoroutineDispatchers(
|
||||
io = UnconfinedTestDispatcher(),
|
||||
main = UnconfinedTestDispatcher(),
|
||||
default = UnconfinedTestDispatcher(),
|
||||
),
|
||||
bleScanner = bleScanner,
|
||||
)
|
||||
}
|
||||
|
|
@ -80,8 +86,8 @@ class ScannerViewModelTest {
|
|||
@Test
|
||||
fun `errorText reflects connectionProgress`() = runTest {
|
||||
viewModel.errorText.test {
|
||||
assertEquals(null, awaitItem())
|
||||
connectionProgressFlow.value = "Connecting..."
|
||||
assertEquals("", awaitItem())
|
||||
serviceRepository.setConnectionProgress("Connecting...")
|
||||
assertEquals("Connecting...", awaitItem())
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
|
|
@ -104,11 +110,9 @@ class ScannerViewModelTest {
|
|||
|
||||
@Test
|
||||
fun `changeDeviceAddress calls radioController`() {
|
||||
every { radioController.setDeviceAddress(any()) } returns Unit
|
||||
|
||||
viewModel.changeDeviceAddress("test_address")
|
||||
|
||||
dev.mokkery.verify { radioController.setDeviceAddress("test_address") }
|
||||
assertEquals("test_address", radioController.lastSetDeviceAddress)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ kotlin {
|
|||
implementation(projects.core.data)
|
||||
implementation(projects.core.database)
|
||||
implementation(projects.core.datastore)
|
||||
implementation(projects.core.di)
|
||||
implementation(projects.core.model)
|
||||
implementation(projects.core.navigation)
|
||||
implementation(projects.core.network)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import androidx.lifecycle.ViewModel
|
|||
import androidx.lifecycle.viewModelScope
|
||||
import co.touchlab.kermit.Logger
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
@ -42,6 +41,7 @@ import org.meshtastic.core.data.repository.FirmwareReleaseRepository
|
|||
import org.meshtastic.core.database.entity.FirmwareRelease
|
||||
import org.meshtastic.core.database.entity.FirmwareReleaseType
|
||||
import org.meshtastic.core.datastore.BootloaderWarningDataSource
|
||||
import org.meshtastic.core.di.CoroutineDispatchers
|
||||
import org.meshtastic.core.model.ConnectionState
|
||||
import org.meshtastic.core.model.DeviceHardware
|
||||
import org.meshtastic.core.model.MyNodeInfo
|
||||
|
|
@ -98,6 +98,7 @@ class FirmwareUpdateViewModel(
|
|||
private val firmwareUpdateManager: FirmwareUpdateManager,
|
||||
private val usbManager: FirmwareUsbManager,
|
||||
private val fileHandler: FirmwareFileHandler,
|
||||
private val dispatchers: CoroutineDispatchers,
|
||||
) : ViewModel() {
|
||||
|
||||
private val _state = MutableStateFlow<FirmwareUpdateState>(FirmwareUpdateState.Idle)
|
||||
|
|
@ -332,7 +333,7 @@ class FirmwareUpdateViewModel(
|
|||
}
|
||||
|
||||
private suspend fun observeDfuProgress() {
|
||||
firmwareUpdateManager.dfuProgressFlow().flowOn(Dispatchers.Main).collect { dfuState ->
|
||||
firmwareUpdateManager.dfuProgressFlow().flowOn(dispatchers.main).collect { dfuState ->
|
||||
when (dfuState) {
|
||||
is DfuInternalState.Progress -> handleDfuProgress(dfuState)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package org.meshtastic.feature.firmware
|
|||
*
|
||||
* Tests firmware update flow, state management, and error handling.
|
||||
*/
|
||||
@OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
|
||||
class FirmwareUpdateIntegrationTest {
|
||||
/*
|
||||
|
||||
|
|
@ -70,6 +71,11 @@ class FirmwareUpdateIntegrationTest {
|
|||
firmwareUpdateManager = firmwareUpdateManager,
|
||||
usbManager = usbManager,
|
||||
fileHandler = fileHandler,
|
||||
dispatchers = org.meshtastic.core.di.CoroutineDispatchers(
|
||||
io = kotlinx.coroutines.test.UnconfinedTestDispatcher(),
|
||||
main = kotlinx.coroutines.test.UnconfinedTestDispatcher(),
|
||||
default = kotlinx.coroutines.test.UnconfinedTestDispatcher(),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,13 +37,12 @@ import org.junit.Assert.assertTrue
|
|||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.meshtastic.core.model.ConnectionState
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.repository.MapPrefs
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.PacketRepository
|
||||
import org.meshtastic.core.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.repository.UiPrefs
|
||||
import org.meshtastic.core.testing.FakeNodeRepository
|
||||
import org.meshtastic.core.testing.FakeRadioController
|
||||
import org.meshtastic.feature.map.model.CustomTileProviderConfig
|
||||
import org.meshtastic.feature.map.prefs.map.GoogleMapsPrefs
|
||||
import org.meshtastic.feature.map.repository.CustomTileProviderRepository
|
||||
|
|
@ -56,10 +55,10 @@ class MapViewModelTest {
|
|||
private val application = mock<Application>(MockMode.autofill)
|
||||
private val mapPrefs = mock<MapPrefs>(MockMode.autofill)
|
||||
private val googleMapsPrefs = mock<GoogleMapsPrefs>(MockMode.autofill)
|
||||
private val nodeRepository = mock<NodeRepository>(MockMode.autofill)
|
||||
private val nodeRepository = FakeNodeRepository()
|
||||
private val packetRepository = mock<PacketRepository>(MockMode.autofill)
|
||||
private val radioConfigRepository = mock<RadioConfigRepository>(MockMode.autofill)
|
||||
private val radioController = mock<RadioController>(MockMode.autofill)
|
||||
private val radioController = FakeRadioController()
|
||||
private val customTileProviderRepository = mock<CustomTileProviderRepository>(MockMode.autofill)
|
||||
private val uiPrefs = mock<UiPrefs>(MockMode.autofill)
|
||||
private val savedStateHandle = SavedStateHandle(mapOf("waypointId" to null))
|
||||
|
|
@ -90,13 +89,7 @@ class MapViewModelTest {
|
|||
every { customTileProviderRepository.getCustomTileProviders() } returns flowOf(emptyList())
|
||||
every { radioConfigRepository.deviceProfileFlow } returns flowOf(mock(MockMode.autofill))
|
||||
every { uiPrefs.theme } returns MutableStateFlow(1)
|
||||
every { nodeRepository.myNodeInfo } returns MutableStateFlow(null)
|
||||
every { nodeRepository.ourNodeInfo } returns MutableStateFlow(null)
|
||||
every { nodeRepository.myId } returns MutableStateFlow(null)
|
||||
every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(emptyMap())
|
||||
every { nodeRepository.getNodes() } returns flowOf(emptyList())
|
||||
every { packetRepository.getWaypoints() } returns flowOf(emptyList())
|
||||
every { radioController.connectionState } returns MutableStateFlow(ConnectionState.Disconnected)
|
||||
|
||||
viewModel =
|
||||
MapViewModel(
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@ import kotlinx.coroutines.test.resetMain
|
|||
import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.coroutines.test.setMain
|
||||
import org.meshtastic.core.model.ConnectionState
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.PacketRepository
|
||||
import org.meshtastic.core.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.repository.ServiceRepository
|
||||
import org.meshtastic.core.testing.FakeNodeRepository
|
||||
import org.meshtastic.proto.ChannelSet
|
||||
import kotlin.test.AfterTest
|
||||
import kotlin.test.BeforeTest
|
||||
|
|
@ -45,7 +45,7 @@ class ContactsViewModelTest {
|
|||
|
||||
private val testDispatcher = UnconfinedTestDispatcher()
|
||||
private lateinit var viewModel: ContactsViewModel
|
||||
private val nodeRepository: NodeRepository = mock(MockMode.autofill)
|
||||
private val nodeRepository = FakeNodeRepository()
|
||||
private val packetRepository: PacketRepository = mock(MockMode.autofill)
|
||||
private val radioConfigRepository: RadioConfigRepository = mock(MockMode.autofill)
|
||||
private val serviceRepository: ServiceRepository = mock(MockMode.autofill)
|
||||
|
|
@ -54,11 +54,6 @@ class ContactsViewModelTest {
|
|||
fun setUp() {
|
||||
Dispatchers.setMain(testDispatcher)
|
||||
|
||||
every { nodeRepository.ourNodeInfo } returns MutableStateFlow(null)
|
||||
every { nodeRepository.myNodeInfo } returns MutableStateFlow(null)
|
||||
every { nodeRepository.myId } returns MutableStateFlow(null)
|
||||
every { nodeRepository.getNodes() } returns MutableStateFlow(emptyList())
|
||||
|
||||
every { serviceRepository.connectionState } returns MutableStateFlow(ConnectionState.Disconnected)
|
||||
every { packetRepository.getUnreadCountTotal() } returns MutableStateFlow(0)
|
||||
every { radioConfigRepository.channelSetFlow } returns MutableStateFlow(ChannelSet())
|
||||
|
|
|
|||
|
|
@ -129,8 +129,8 @@ class CompassViewModelTest {
|
|||
}
|
||||
|
||||
// Bearing from (0,0) to (1,1) is approx 45 degrees
|
||||
assertEquals(45f, state.bearing!!, 0.5f)
|
||||
assertEquals(0f, state.heading!!, 0.1f)
|
||||
assertEquals(45f, state.bearing, 0.5f)
|
||||
assertEquals(0f, state.heading, 0.1f)
|
||||
assertTrue(state.hasTargetPosition)
|
||||
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.ServiceRepository
|
||||
import org.meshtastic.core.testing.FakeNodeRepository
|
||||
import org.meshtastic.core.testing.FakeRadioController
|
||||
import org.meshtastic.core.ui.util.AlertManager
|
||||
import org.meshtastic.proto.User
|
||||
import kotlin.test.Test
|
||||
|
|
@ -34,9 +34,9 @@ import kotlin.test.Test
|
|||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class NodeManagementActionsTest {
|
||||
|
||||
private val nodeRepository = mock<NodeRepository>(MockMode.autofill)
|
||||
private val nodeRepository = FakeNodeRepository()
|
||||
private val serviceRepository = mock<ServiceRepository>(MockMode.autofill)
|
||||
private val radioController = mock<RadioController>(MockMode.autofill)
|
||||
private val radioController = FakeRadioController()
|
||||
private val alertManager = mock<AlertManager>(MockMode.autofill)
|
||||
private val testDispatcher = StandardTestDispatcher()
|
||||
private val testScope = TestScope(testDispatcher)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import co.touchlab.kermit.Logger
|
|||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
|
@ -220,12 +219,13 @@ class DebugViewModel(
|
|||
private val nodeRepository: NodeRepository,
|
||||
private val meshLogPrefs: MeshLogPrefs,
|
||||
private val alertManager: AlertManager,
|
||||
private val dispatchers: org.meshtastic.core.di.CoroutineDispatchers,
|
||||
) : ViewModel() {
|
||||
|
||||
val meshLog: StateFlow<ImmutableList<UiMeshLog>> =
|
||||
meshLogRepository
|
||||
.getAllLogs()
|
||||
.mapLatest { logs -> withContext(Dispatchers.Default) { toUiState(logs) } }
|
||||
.mapLatest { logs -> withContext(dispatchers.default) { toUiState(logs) } }
|
||||
.stateInWhileSubscribed(initialValue = persistentListOf())
|
||||
|
||||
private val _retentionDays = MutableStateFlow(meshLogPrefs.retentionDays.value)
|
||||
|
|
|
|||
|
|
@ -16,27 +16,44 @@
|
|||
*/
|
||||
package org.meshtastic.feature.settings.debugging
|
||||
|
||||
import dev.mokkery.MockMode
|
||||
import dev.mokkery.matcher.any
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.verify
|
||||
import io.kotest.matchers.shouldBe
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.resetMain
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.coroutines.test.setMain
|
||||
import org.meshtastic.core.di.CoroutineDispatchers
|
||||
import org.meshtastic.core.testing.FakeMeshLogPrefs
|
||||
import org.meshtastic.core.testing.FakeMeshLogRepository
|
||||
import org.meshtastic.core.testing.FakeNodeRepository
|
||||
import org.meshtastic.core.ui.util.AlertManager
|
||||
import kotlin.test.AfterTest
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class DebugViewModelTest {
|
||||
/*
|
||||
|
||||
private val meshLogRepository = FakeMeshLogRepository()
|
||||
private val nodeRepository = FakeNodeRepository()
|
||||
private val meshLogPrefs = FakeMeshLogPrefs()
|
||||
private val alertManager: AlertManager = mock(MockMode.autofill)
|
||||
|
||||
private val testDispatcher = UnconfinedTestDispatcher()
|
||||
|
||||
private val dispatchers = CoroutineDispatchers(testDispatcher, testDispatcher, testDispatcher)
|
||||
|
||||
private lateinit var viewModel: DebugViewModel
|
||||
|
||||
@Before
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
Dispatchers.setMain(testDispatcher)
|
||||
|
||||
every { meshLogRepository.getAllLogs() } returns flowOf(emptyList())
|
||||
every { nodeRepository.myNodeInfo } returns MutableStateFlow(null)
|
||||
every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(emptyMap())
|
||||
every { meshLogPrefs.retentionDays.value } returns 7
|
||||
every { meshLogPrefs.loggingEnabled.value } returns true
|
||||
meshLogPrefs.setRetentionDays(7)
|
||||
meshLogPrefs.setLoggingEnabled(true)
|
||||
|
||||
viewModel =
|
||||
DebugViewModel(
|
||||
|
|
@ -44,10 +61,11 @@ class DebugViewModelTest {
|
|||
nodeRepository = nodeRepository,
|
||||
meshLogPrefs = meshLogPrefs,
|
||||
alertManager = alertManager,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
|
||||
@After
|
||||
@AfterTest
|
||||
fun tearDown() {
|
||||
Dispatchers.resetMain()
|
||||
}
|
||||
|
|
@ -56,17 +74,18 @@ class DebugViewModelTest {
|
|||
fun `setRetentionDays updates prefs and deletes old logs`() = runTest {
|
||||
viewModel.setRetentionDays(14)
|
||||
|
||||
verify { meshLogPrefs.setRetentionDays(14) }
|
||||
verifySuspend { meshLogRepository.deleteLogsOlderThan(14) }
|
||||
meshLogPrefs.retentionDays.value shouldBe 14
|
||||
meshLogRepository.deleteLogsOlderThanCalledDays shouldBe 14
|
||||
viewModel.retentionDays.value shouldBe 14
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `setLoggingEnabled false deletes all logs`() = runTest {
|
||||
meshLogRepository.insert(org.meshtastic.core.model.MeshLog("123", "type", 1L, "raw"))
|
||||
viewModel.setLoggingEnabled(false)
|
||||
|
||||
verify { meshLogPrefs.setLoggingEnabled(false) }
|
||||
verifySuspend { meshLogRepository.deleteAll() }
|
||||
meshLogPrefs.loggingEnabled.value shouldBe false
|
||||
meshLogRepository.currentLogs shouldBe emptyList()
|
||||
viewModel.loggingEnabled.value shouldBe false
|
||||
}
|
||||
|
||||
|
|
@ -91,6 +110,4 @@ class DebugViewModelTest {
|
|||
viewModel.requestDeleteAllLogs()
|
||||
verify { alertManager.showAlert(titleRes = any(), messageRes = any(), onConfirm = any()) }
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,11 +53,11 @@ import org.meshtastic.core.repository.HomoglyphPrefs
|
|||
import org.meshtastic.core.repository.LocationRepository
|
||||
import org.meshtastic.core.repository.LocationService
|
||||
import org.meshtastic.core.repository.MapConsentPrefs
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.PacketRepository
|
||||
import org.meshtastic.core.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.repository.ServiceRepository
|
||||
import org.meshtastic.core.repository.UiPrefs
|
||||
import org.meshtastic.core.testing.FakeNodeRepository
|
||||
import org.meshtastic.feature.settings.navigation.ConfigRoute
|
||||
import org.meshtastic.proto.ChannelSet
|
||||
import org.meshtastic.proto.ChannelSettings
|
||||
|
|
@ -82,7 +82,7 @@ class RadioConfigViewModelTest {
|
|||
private val radioConfigRepository: RadioConfigRepository = mock(MockMode.autofill)
|
||||
private val packetRepository: PacketRepository = mock(MockMode.autofill)
|
||||
private val serviceRepository: ServiceRepository = mock(MockMode.autofill)
|
||||
private val nodeRepository: NodeRepository = mock(MockMode.autofill)
|
||||
private val nodeRepository = FakeNodeRepository()
|
||||
private val locationRepository: LocationRepository = mock(MockMode.autofill)
|
||||
private val mapConsentPrefs: MapConsentPrefs = mock(MockMode.autofill)
|
||||
private val analyticsPrefs: AnalyticsPrefs = mock(MockMode.autofill)
|
||||
|
|
@ -107,8 +107,6 @@ class RadioConfigViewModelTest {
|
|||
fun setUp() {
|
||||
Dispatchers.setMain(testDispatcher)
|
||||
|
||||
every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(emptyMap())
|
||||
every { nodeRepository.myNodeInfo } returns MutableStateFlow(null)
|
||||
every { radioConfigRepository.deviceProfileFlow } returns MutableStateFlow(DeviceProfile())
|
||||
every { radioConfigRepository.localConfigFlow } returns MutableStateFlow(LocalConfig())
|
||||
every { radioConfigRepository.channelSetFlow } returns MutableStateFlow(ChannelSet())
|
||||
|
|
@ -153,7 +151,7 @@ class RadioConfigViewModelTest {
|
|||
@Test
|
||||
fun `setConfig calls useCase`() = runTest {
|
||||
val node = Node(num = 123, user = User(id = "!123"))
|
||||
every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(mapOf(123 to node))
|
||||
nodeRepository.setNodes(listOf(node))
|
||||
viewModel = createViewModel()
|
||||
|
||||
val config = Config(device = Config.DeviceConfig(role = Config.DeviceConfig.Role.ROUTER))
|
||||
|
|
@ -191,7 +189,7 @@ class RadioConfigViewModelTest {
|
|||
@Test
|
||||
fun `processPacketResponse updates state on metadata result`() = runTest {
|
||||
val node = Node(num = 123, user = User(id = "!123"))
|
||||
every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(mapOf(123 to node))
|
||||
nodeRepository.setNodes(listOf(node))
|
||||
|
||||
val packet = MeshPacket()
|
||||
val metadata = DeviceMetadata(firmware_version = "3.0.0")
|
||||
|
|
@ -214,7 +212,7 @@ class RadioConfigViewModelTest {
|
|||
@Test
|
||||
fun `updateChannels calls useCase for each changed channel`() = runTest {
|
||||
val node = Node(num = 123, user = User(id = "!123"))
|
||||
every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(mapOf(123 to node))
|
||||
nodeRepository.setNodes(listOf(node))
|
||||
viewModel = createViewModel()
|
||||
|
||||
val old = listOf(ChannelSettings(name = "Old"))
|
||||
|
|
@ -231,7 +229,7 @@ class RadioConfigViewModelTest {
|
|||
@Test
|
||||
fun `setResponseStateLoading for REBOOT calls useCase after packet response`() = runTest {
|
||||
val node = Node(num = 123, user = User(id = "!123"))
|
||||
every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(mapOf(123 to node))
|
||||
nodeRepository.setNodes(listOf(node))
|
||||
|
||||
val packetFlow = MutableSharedFlow<MeshPacket>()
|
||||
every { serviceRepository.meshPacketFlow } returns packetFlow
|
||||
|
|
@ -252,7 +250,7 @@ class RadioConfigViewModelTest {
|
|||
@Test
|
||||
fun `setResponseStateLoading for FACTORY_RESET calls useCase after packet response`() = runTest {
|
||||
val node = Node(num = 123, user = User(id = "!123"))
|
||||
every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(mapOf(123 to node))
|
||||
nodeRepository.setNodes(listOf(node))
|
||||
|
||||
val packetFlow = MutableSharedFlow<MeshPacket>()
|
||||
every { serviceRepository.meshPacketFlow } returns packetFlow
|
||||
|
|
@ -283,7 +281,7 @@ class RadioConfigViewModelTest {
|
|||
@Test
|
||||
fun `setOwner calls useCase`() = runTest {
|
||||
val node = Node(num = 123, user = User(id = "!123"))
|
||||
every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(mapOf(123 to node))
|
||||
nodeRepository.setNodes(listOf(node))
|
||||
viewModel = createViewModel()
|
||||
|
||||
val user = User(long_name = "Test User")
|
||||
|
|
@ -297,7 +295,7 @@ class RadioConfigViewModelTest {
|
|||
@Test
|
||||
fun `setRingtone calls useCase`() = runTest {
|
||||
val node = Node(num = 123, user = User(id = "!123"))
|
||||
every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(mapOf(123 to node))
|
||||
nodeRepository.setNodes(listOf(node))
|
||||
viewModel = createViewModel()
|
||||
|
||||
everySuspend { radioConfigUseCase.setRingtone(any(), any()) } returns Unit
|
||||
|
|
@ -311,7 +309,7 @@ class RadioConfigViewModelTest {
|
|||
@Test
|
||||
fun `setCannedMessages calls useCase`() = runTest {
|
||||
val node = Node(num = 123, user = User(id = "!123"))
|
||||
every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(mapOf(123 to node))
|
||||
nodeRepository.setNodes(listOf(node))
|
||||
viewModel = createViewModel()
|
||||
|
||||
everySuspend { radioConfigUseCase.setCannedMessages(any(), any()) } returns Unit
|
||||
|
|
@ -341,7 +339,7 @@ class RadioConfigViewModelTest {
|
|||
@Test
|
||||
fun `registerRequestId timeout clears request and sets error`() = runTest {
|
||||
val node = Node(num = 123, user = User(id = "!123"))
|
||||
every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(mapOf(123 to node))
|
||||
nodeRepository.setNodes(listOf(node))
|
||||
viewModel = createViewModel()
|
||||
|
||||
everySuspend { radioConfigUseCase.getOwner(any()) } returns 42
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue