mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
test(domain, node): Fill testing gaps for UseCases and migrate to commonTest
This commit is contained in:
parent
a69139cd91
commit
7b815130f4
3 changed files with 269 additions and 0 deletions
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2026 Meshtastic LLC
|
||||||
|
*
|
||||||
|
* 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. See
|
||||||
|
* 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 org.meshtastic.core.domain.usecase.settings
|
||||||
|
|
||||||
|
import dev.mokkery.answering.returns
|
||||||
|
import dev.mokkery.every
|
||||||
|
import dev.mokkery.matcher.any
|
||||||
|
import dev.mokkery.mock
|
||||||
|
import dev.mokkery.verify
|
||||||
|
import org.meshtastic.core.common.UiPreferences
|
||||||
|
import kotlin.test.BeforeTest
|
||||||
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
class SetLocaleUseCaseTest {
|
||||||
|
|
||||||
|
private val uiPreferences: UiPreferences = mock()
|
||||||
|
private lateinit var useCase: SetLocaleUseCase
|
||||||
|
|
||||||
|
@BeforeTest
|
||||||
|
fun setUp() {
|
||||||
|
useCase = SetLocaleUseCase(uiPreferences)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `invoke calls setLocale on uiPreferences`() {
|
||||||
|
every { uiPreferences.setLocale(any()) } returns Unit
|
||||||
|
useCase("en")
|
||||||
|
verify { uiPreferences.setLocale("en") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2026 Meshtastic LLC
|
||||||
|
*
|
||||||
|
* 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. See
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. See
|
||||||
|
* 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 org.meshtastic.core.domain.usecase.settings
|
||||||
|
|
||||||
|
import dev.mokkery.answering.returns
|
||||||
|
import dev.mokkery.every
|
||||||
|
import dev.mokkery.matcher.any
|
||||||
|
import dev.mokkery.mock
|
||||||
|
import dev.mokkery.verify
|
||||||
|
import org.meshtastic.core.repository.NotificationPrefs
|
||||||
|
import kotlin.test.BeforeTest
|
||||||
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
class SetNotificationSettingsUseCaseTest {
|
||||||
|
|
||||||
|
private val notificationPrefs: NotificationPrefs = mock()
|
||||||
|
private lateinit var useCase: SetNotificationSettingsUseCase
|
||||||
|
|
||||||
|
@BeforeTest
|
||||||
|
fun setUp() {
|
||||||
|
useCase = SetNotificationSettingsUseCase(notificationPrefs)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `setMessagesEnabled calls notificationPrefs`() {
|
||||||
|
every { notificationPrefs.setMessagesEnabled(any()) } returns Unit
|
||||||
|
useCase.setMessagesEnabled(true)
|
||||||
|
verify { notificationPrefs.setMessagesEnabled(true) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `setNodeEventsEnabled calls notificationPrefs`() {
|
||||||
|
every { notificationPrefs.setNodeEventsEnabled(any()) } returns Unit
|
||||||
|
useCase.setNodeEventsEnabled(false)
|
||||||
|
verify { notificationPrefs.setNodeEventsEnabled(false) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `setLowBatteryEnabled calls notificationPrefs`() {
|
||||||
|
every { notificationPrefs.setLowBatteryEnabled(any()) } returns Unit
|
||||||
|
useCase.setLowBatteryEnabled(true)
|
||||||
|
verify { notificationPrefs.setLowBatteryEnabled(true) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||||
|
*
|
||||||
|
* 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 org.meshtastic.feature.node.domain.usecase
|
||||||
|
|
||||||
|
import dev.mokkery.answering.returns
|
||||||
|
import dev.mokkery.every
|
||||||
|
import dev.mokkery.matcher.any
|
||||||
|
import dev.mokkery.mock
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.meshtastic.core.model.Node
|
||||||
|
import org.meshtastic.core.model.NodeSortOption
|
||||||
|
import org.meshtastic.core.repository.NodeRepository
|
||||||
|
import org.meshtastic.feature.node.list.NodeFilterState
|
||||||
|
import org.meshtastic.proto.Config
|
||||||
|
import org.meshtastic.proto.User
|
||||||
|
import kotlin.test.BeforeTest
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class GetFilteredNodesUseCaseTest {
|
||||||
|
|
||||||
|
private lateinit var nodeRepository: NodeRepository
|
||||||
|
private lateinit var useCase: GetFilteredNodesUseCase
|
||||||
|
|
||||||
|
@BeforeTest
|
||||||
|
fun setUp() {
|
||||||
|
nodeRepository = mock()
|
||||||
|
useCase = GetFilteredNodesUseCase(nodeRepository)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNode(
|
||||||
|
num: Int,
|
||||||
|
role: Config.DeviceConfig.Role = Config.DeviceConfig.Role.CLIENT,
|
||||||
|
ignored: Boolean = false,
|
||||||
|
name: String = "Node$num",
|
||||||
|
viaMqtt: Boolean = false,
|
||||||
|
): Node {
|
||||||
|
val user = User(id = "!$num", long_name = name, short_name = "N$num", role = role)
|
||||||
|
return Node(num = num, user = user, isIgnored = ignored, viaMqtt = viaMqtt)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `invoke applies repository filters and returns nodes`() = runTest {
|
||||||
|
// Arrange
|
||||||
|
val nodes = listOf(createNode(1), createNode(2))
|
||||||
|
val filter = NodeFilterState(filterText = "Node", includeUnknown = true)
|
||||||
|
|
||||||
|
every {
|
||||||
|
nodeRepository.getNodes(
|
||||||
|
sort = NodeSortOption.LAST_HEARD,
|
||||||
|
filter = "Node",
|
||||||
|
includeUnknown = true,
|
||||||
|
onlyOnline = false,
|
||||||
|
onlyDirect = false,
|
||||||
|
)
|
||||||
|
} returns flowOf(nodes)
|
||||||
|
|
||||||
|
// Act
|
||||||
|
val result = useCase(filter, NodeSortOption.LAST_HEARD).first()
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertEquals(2, result.size)
|
||||||
|
assertEquals(1, result[0].num)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `invoke filters out ignored nodes if showIgnored is false`() = runTest {
|
||||||
|
// Arrange
|
||||||
|
val normalNode = createNode(1, ignored = false)
|
||||||
|
val ignoredNode = createNode(2, ignored = true)
|
||||||
|
val filter = NodeFilterState(showIgnored = false)
|
||||||
|
|
||||||
|
every { nodeRepository.getNodes(any(), any(), any(), any(), any()) } returns
|
||||||
|
flowOf(listOf(normalNode, ignoredNode))
|
||||||
|
|
||||||
|
// Act
|
||||||
|
val result = useCase(filter, NodeSortOption.LAST_HEARD).first()
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertEquals(1, result.size)
|
||||||
|
assertEquals(1, result.first().num)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `invoke filters out infrastructure nodes if excludeInfrastructure is true`() = runTest {
|
||||||
|
// Arrange
|
||||||
|
val clientNode = createNode(1, role = Config.DeviceConfig.Role.CLIENT)
|
||||||
|
val routerNode = createNode(2, role = Config.DeviceConfig.Role.ROUTER)
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
val repeaterNode = createNode(3, role = Config.DeviceConfig.Role.REPEATER)
|
||||||
|
val clientBaseNode = createNode(4, role = Config.DeviceConfig.Role.CLIENT_BASE)
|
||||||
|
val filter = NodeFilterState(excludeInfrastructure = true)
|
||||||
|
|
||||||
|
every { nodeRepository.getNodes(any(), any(), any(), any(), any()) } returns
|
||||||
|
flowOf(listOf(clientNode, routerNode, repeaterNode, clientBaseNode))
|
||||||
|
|
||||||
|
// Act
|
||||||
|
val result = useCase(filter, NodeSortOption.LAST_HEARD).first()
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
// Should only keep the CLIENT node, others are infrastructure
|
||||||
|
assertEquals(1, result.size)
|
||||||
|
assertEquals(1, result.first().num)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `invoke filters out MQTT nodes if excludeMqtt is true`() = runTest {
|
||||||
|
// Arrange
|
||||||
|
val loraNode = createNode(1, viaMqtt = false)
|
||||||
|
val mqttNode = createNode(2, viaMqtt = true)
|
||||||
|
val filter = NodeFilterState(excludeMqtt = true)
|
||||||
|
|
||||||
|
every { nodeRepository.getNodes(any(), any(), any(), any(), any()) } returns flowOf(listOf(loraNode, mqttNode))
|
||||||
|
|
||||||
|
// Act
|
||||||
|
val result = useCase(filter, NodeSortOption.LAST_HEARD).first()
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertEquals(1, result.size)
|
||||||
|
assertEquals(1, result.first().num)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `invoke keeps MQTT nodes if excludeMqtt is false`() = runTest {
|
||||||
|
// Arrange
|
||||||
|
val loraNode = createNode(1, viaMqtt = false)
|
||||||
|
val mqttNode = createNode(2, viaMqtt = true)
|
||||||
|
val filter = NodeFilterState(excludeMqtt = false)
|
||||||
|
|
||||||
|
every { nodeRepository.getNodes(any(), any(), any(), any(), any()) } returns flowOf(listOf(loraNode, mqttNode))
|
||||||
|
|
||||||
|
// Act
|
||||||
|
val result = useCase(filter, NodeSortOption.LAST_HEARD).first()
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
assertEquals(2, result.size)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue