mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
feat/decoupling (#4685)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
40244f8337
commit
2c49db8041
254 changed files with 5132 additions and 2666 deletions
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* 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. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.meshtastic.core.domain
|
||||
|
||||
/**
|
||||
* Interface for enqueuing background work for transmitting messages. This allows the domain layer to trigger durable
|
||||
* transmission without depending on Android-specific WorkManager.
|
||||
*/
|
||||
interface MessageQueue {
|
||||
suspend fun enqueue(packetId: Int)
|
||||
}
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
* 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.core.domain.usecase
|
||||
|
||||
import co.touchlab.kermit.Logger
|
||||
import org.meshtastic.core.common.util.HomoglyphCharacterStringTransformer
|
||||
import org.meshtastic.core.common.util.nowMillis
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.data.repository.PacketRepository
|
||||
import org.meshtastic.core.database.entity.Packet
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.domain.MessageQueue
|
||||
import org.meshtastic.core.model.Capabilities
|
||||
import org.meshtastic.core.model.DataPacket
|
||||
import org.meshtastic.core.model.MessageStatus
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.prefs.homoglyph.HomoglyphPrefs
|
||||
import org.meshtastic.proto.Config
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
import kotlin.random.Random
|
||||
|
||||
/**
|
||||
* Use case for sending a message. This component handles message transformation, persistence, and enqueuing for durable
|
||||
* delivery.
|
||||
*/
|
||||
@Suppress("TooGenericExceptionCaught")
|
||||
class SendMessageUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val nodeRepository: NodeRepository,
|
||||
private val packetRepository: PacketRepository,
|
||||
private val radioController: RadioController,
|
||||
private val homoglyphEncodingPrefs: HomoglyphPrefs,
|
||||
private val messageQueue: MessageQueue,
|
||||
) {
|
||||
|
||||
@Suppress("NestedBlockDepth", "LongMethod", "CyclomaticComplexMethod")
|
||||
suspend operator fun invoke(
|
||||
text: String,
|
||||
contactKey: String = "0${DataPacket.ID_BROADCAST}",
|
||||
replyId: Int? = null,
|
||||
) {
|
||||
val channel = contactKey[0].digitToIntOrNull()
|
||||
val dest = if (channel != null) contactKey.substring(1) else contactKey
|
||||
|
||||
val ourNode = nodeRepository.ourNodeInfo.value
|
||||
val fromId = ourNode?.user?.id ?: DataPacket.ID_LOCAL
|
||||
|
||||
// logic for direct messages
|
||||
if (channel == null) {
|
||||
val destNode = nodeRepository.getNode(dest)
|
||||
val fwVersion = ourNode?.metadata?.firmware_version
|
||||
val isClientBase = ourNode?.user?.role == Config.DeviceConfig.Role.CLIENT_BASE
|
||||
val capabilities = Capabilities(fwVersion)
|
||||
|
||||
if (capabilities.canSendVerifiedContacts) {
|
||||
sendSharedContact(destNode)
|
||||
} else {
|
||||
if (!destNode.isFavorite && !isClientBase) {
|
||||
favoriteNode(destNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply homoglyph encoding
|
||||
val finalMessageText =
|
||||
if (homoglyphEncodingPrefs.homoglyphEncodingEnabled) {
|
||||
HomoglyphCharacterStringTransformer.optimizeUtf8StringWithHomoglyphs(text)
|
||||
} else {
|
||||
text
|
||||
}
|
||||
|
||||
val packetId = abs(Random.nextInt())
|
||||
|
||||
val packet =
|
||||
DataPacket(dest, channel ?: 0, finalMessageText, replyId).apply {
|
||||
from = fromId
|
||||
id = packetId
|
||||
status = MessageStatus.QUEUED
|
||||
}
|
||||
|
||||
val packetToSave =
|
||||
Packet(
|
||||
uuid = 0L,
|
||||
myNodeNum = ourNode?.num ?: 0,
|
||||
packetId = packetId,
|
||||
port_num = packet.dataType,
|
||||
contact_key = contactKey,
|
||||
received_time = nowMillis,
|
||||
read = true,
|
||||
data = packet,
|
||||
snr = packet.snr,
|
||||
rssi = packet.rssi,
|
||||
hopsAway = packet.hopsAway,
|
||||
filtered = false,
|
||||
)
|
||||
|
||||
try {
|
||||
// Write to the DB to immediately reflect the queued state on the UI
|
||||
packetRepository.insert(packetToSave)
|
||||
|
||||
// Enqueue for durable transmission via the platform-specific queue
|
||||
messageQueue.enqueue(packetId)
|
||||
} catch (ex: Exception) {
|
||||
Logger.e(ex) { "Failed to enqueue message packet" }
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun favoriteNode(node: Node) {
|
||||
try {
|
||||
radioController.favoriteNode(node.num)
|
||||
} catch (ex: Exception) {
|
||||
Logger.e(ex) { "Favorite node error" }
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun sendSharedContact(node: Node) {
|
||||
try {
|
||||
radioController.sendSharedContact(node.num)
|
||||
} catch (ex: Exception) {
|
||||
Logger.e(ex) { "Send shared contact error" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,11 +16,16 @@
|
|||
*/
|
||||
package org.meshtastic.core.domain.usecase.settings
|
||||
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
/** Use case for performing administrative actions on the radio. */
|
||||
/**
|
||||
* Use case for performing administrative and destructive actions on mesh nodes.
|
||||
*
|
||||
* This component provides methods for rebooting, shutting down, or resetting nodes within the mesh. It also handles
|
||||
* local database synchronization when these actions are performed on the locally connected device.
|
||||
*/
|
||||
open class AdminActionsUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
|
|
|
|||
|
|
@ -16,14 +16,14 @@
|
|||
*/
|
||||
package org.meshtastic.core.domain.usecase.settings
|
||||
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import javax.inject.Inject
|
||||
import kotlin.time.Duration.Companion.days
|
||||
|
||||
/** Use case for cleaning up nodes from the database. */
|
||||
class CleanNodeDatabaseUseCase
|
||||
open class CleanNodeDatabaseUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val nodeRepository: NodeRepository,
|
||||
|
|
@ -43,11 +43,9 @@ constructor(
|
|||
nodeRepository.getNodesOlderThan(olderThanTimestamp.toInt())
|
||||
}
|
||||
|
||||
return nodesToConsider
|
||||
.filterNot { node ->
|
||||
(node.hasPKC && node.lastHeard >= sevenDaysAgoSeconds) || node.isIgnored || node.isFavorite
|
||||
}
|
||||
.map { it.toModel() }
|
||||
return nodesToConsider.filterNot { node ->
|
||||
(node.hasPKC && node.lastHeard >= sevenDaysAgoSeconds) || node.isIgnored || node.isFavorite
|
||||
}
|
||||
}
|
||||
|
||||
/** Performs the cleanup of specified nodes. */
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ package org.meshtastic.core.domain.usecase.settings
|
|||
import android.icu.text.SimpleDateFormat
|
||||
import kotlinx.coroutines.flow.first
|
||||
import org.meshtastic.core.data.repository.MeshLogRepository
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.model.Position
|
||||
import org.meshtastic.core.model.util.positionToMeter
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.proto.PortNum
|
||||
import java.io.BufferedWriter
|
||||
import java.util.Locale
|
||||
|
|
@ -30,7 +30,7 @@ import kotlin.math.roundToInt
|
|||
import org.meshtastic.proto.Position as ProtoPosition
|
||||
|
||||
/** Use case for exporting persisted packet data to a CSV format. */
|
||||
class ExportDataUseCase
|
||||
open class ExportDataUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val nodeRepository: NodeRepository,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import java.io.OutputStream
|
|||
import javax.inject.Inject
|
||||
|
||||
/** Use case for exporting a device profile to an output stream. */
|
||||
class ExportProfileUseCase @Inject constructor() {
|
||||
open class ExportProfileUseCase @Inject constructor() {
|
||||
/**
|
||||
* Exports the provided [DeviceProfile] to the given [OutputStream].
|
||||
*
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import java.io.OutputStream
|
|||
import javax.inject.Inject
|
||||
|
||||
/** Use case for exporting security configuration to a JSON format. */
|
||||
class ExportSecurityConfigUseCase @Inject constructor() {
|
||||
open class ExportSecurityConfigUseCase @Inject constructor() {
|
||||
/**
|
||||
* Exports the provided [Config.SecurityConfig] as a JSON string to the given [OutputStream].
|
||||
*
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import java.io.InputStream
|
|||
import javax.inject.Inject
|
||||
|
||||
/** Use case for importing a device profile from an input stream. */
|
||||
class ImportProfileUseCase @Inject constructor() {
|
||||
open class ImportProfileUseCase @Inject constructor() {
|
||||
/**
|
||||
* Imports a [DeviceProfile] from the provided [InputStream].
|
||||
*
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import org.meshtastic.proto.User
|
|||
import javax.inject.Inject
|
||||
|
||||
/** Use case for installing a device profile onto a radio. */
|
||||
class InstallProfileUseCase @Inject constructor(private val radioController: RadioController) {
|
||||
open class InstallProfileUseCase @Inject constructor(private val radioController: RadioController) {
|
||||
/**
|
||||
* Installs the provided [DeviceProfile] onto the radio at [destNum].
|
||||
*
|
||||
|
|
|
|||
|
|
@ -20,19 +20,19 @@ import kotlinx.coroutines.flow.Flow
|
|||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import org.meshtastic.core.data.repository.DeviceHardwareRepository
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.ConnectionState
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.prefs.radio.RadioPrefs
|
||||
import org.meshtastic.core.prefs.radio.isBle
|
||||
import org.meshtastic.core.prefs.radio.isSerial
|
||||
import org.meshtastic.core.prefs.radio.isTcp
|
||||
import org.meshtastic.core.repository.DeviceHardwareRepository
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
/** Use case to determine if the currently connected device is capable of over-the-air (OTA) updates. */
|
||||
class IsOtaCapableUseCase
|
||||
open class IsOtaCapableUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val nodeRepository: NodeRepository,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import org.meshtastic.core.model.RadioController
|
|||
import javax.inject.Inject
|
||||
|
||||
/** Use case for controlling location sharing with the mesh. */
|
||||
class MeshLocationUseCase @Inject constructor(private val radioController: RadioController) {
|
||||
open class MeshLocationUseCase @Inject constructor(private val radioController: RadioController) {
|
||||
/** Starts providing the phone's location to the mesh. */
|
||||
fun startProvidingLocation() {
|
||||
radioController.startProvideLocation()
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
package org.meshtastic.core.domain.usecase.settings
|
||||
|
||||
import co.touchlab.kermit.Logger
|
||||
import org.meshtastic.core.database.model.getStringResFrom
|
||||
import org.meshtastic.core.model.getStringResFrom
|
||||
import org.meshtastic.core.resources.UiText
|
||||
import org.meshtastic.proto.AdminMessage
|
||||
import org.meshtastic.proto.Channel
|
||||
|
|
@ -54,7 +54,7 @@ sealed class RadioResponseResult {
|
|||
}
|
||||
|
||||
/** Use case for processing incoming [MeshPacket]s that are responses to admin requests. */
|
||||
class ProcessRadioResponseUseCase @Inject constructor() {
|
||||
open class ProcessRadioResponseUseCase @Inject constructor() {
|
||||
/**
|
||||
* Decodes and processes the provided [packet].
|
||||
*
|
||||
|
|
|
|||
|
|
@ -20,7 +20,11 @@ import org.meshtastic.core.datastore.UiPreferencesDataSource
|
|||
import javax.inject.Inject
|
||||
|
||||
/** Use case for setting whether the application intro has been completed. */
|
||||
class SetAppIntroCompletedUseCase @Inject constructor(private val uiPreferencesDataSource: UiPreferencesDataSource) {
|
||||
open class SetAppIntroCompletedUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val uiPreferencesDataSource: UiPreferencesDataSource,
|
||||
) {
|
||||
operator fun invoke(completed: Boolean) {
|
||||
uiPreferencesDataSource.setAppIntroCompleted(completed)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@
|
|||
package org.meshtastic.core.domain.usecase.settings
|
||||
|
||||
import org.meshtastic.core.database.DatabaseConstants
|
||||
import org.meshtastic.core.database.DatabaseManager
|
||||
import org.meshtastic.core.repository.DatabaseManager
|
||||
import javax.inject.Inject
|
||||
|
||||
/** Use case for setting the database cache limit. */
|
||||
class SetDatabaseCacheLimitUseCase @Inject constructor(private val databaseManager: DatabaseManager) {
|
||||
open class SetDatabaseCacheLimitUseCase @Inject constructor(private val databaseManager: DatabaseManager) {
|
||||
operator fun invoke(limit: Int) {
|
||||
val clamped = limit.coerceIn(DatabaseConstants.MIN_CACHE_LIMIT, DatabaseConstants.MAX_CACHE_LIMIT)
|
||||
databaseManager.setCacheLimit(clamped)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import org.meshtastic.core.prefs.meshlog.MeshLogPrefs
|
|||
import javax.inject.Inject
|
||||
|
||||
/** Use case for managing mesh log settings. */
|
||||
class SetMeshLogSettingsUseCase
|
||||
open class SetMeshLogSettingsUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val meshLogRepository: MeshLogRepository,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import org.meshtastic.core.prefs.ui.UiPrefs
|
|||
import javax.inject.Inject
|
||||
|
||||
/** Use case for setting whether to provide the node location to the mesh. */
|
||||
class SetProvideLocationUseCase @Inject constructor(private val uiPrefs: UiPrefs) {
|
||||
open class SetProvideLocationUseCase @Inject constructor(private val uiPrefs: UiPrefs) {
|
||||
operator fun invoke(myNodeNum: Int, provideLocation: Boolean) {
|
||||
uiPrefs.setShouldProvideNodeLocation(myNodeNum, provideLocation)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import org.meshtastic.core.datastore.UiPreferencesDataSource
|
|||
import javax.inject.Inject
|
||||
|
||||
/** Use case for setting the application theme. */
|
||||
class SetThemeUseCase @Inject constructor(private val uiPreferencesDataSource: UiPreferencesDataSource) {
|
||||
open class SetThemeUseCase @Inject constructor(private val uiPreferencesDataSource: UiPreferencesDataSource) {
|
||||
operator fun invoke(themeMode: Int) {
|
||||
uiPreferencesDataSource.setTheme(themeMode)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import org.meshtastic.core.prefs.analytics.AnalyticsPrefs
|
|||
import javax.inject.Inject
|
||||
|
||||
/** Use case for toggling the analytics preference. */
|
||||
class ToggleAnalyticsUseCase @Inject constructor(private val analyticsPrefs: AnalyticsPrefs) {
|
||||
open class ToggleAnalyticsUseCase @Inject constructor(private val analyticsPrefs: AnalyticsPrefs) {
|
||||
operator fun invoke() {
|
||||
analyticsPrefs.analyticsAllowed = !analyticsPrefs.analyticsAllowed
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import org.meshtastic.core.prefs.homoglyph.HomoglyphPrefs
|
|||
import javax.inject.Inject
|
||||
|
||||
/** Use case for toggling the homoglyph encoding preference. */
|
||||
class ToggleHomoglyphEncodingUseCase @Inject constructor(private val homoglyphEncodingPrefs: HomoglyphPrefs) {
|
||||
open class ToggleHomoglyphEncodingUseCase @Inject constructor(private val homoglyphEncodingPrefs: HomoglyphPrefs) {
|
||||
operator fun invoke() {
|
||||
homoglyphEncodingPrefs.homoglyphEncodingEnabled = !homoglyphEncodingPrefs.homoglyphEncodingEnabled
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ class FakeRadioController : RadioController {
|
|||
sentSharedContacts.add(nodeNum)
|
||||
}
|
||||
|
||||
override suspend fun setLocalConfig(config: org.meshtastic.proto.Config) {}
|
||||
|
||||
override suspend fun setLocalChannel(channel: org.meshtastic.proto.Channel) {}
|
||||
|
||||
override suspend fun setOwner(destNum: Int, user: org.meshtastic.proto.User, packetId: Int) {}
|
||||
|
||||
override suspend fun setConfig(destNum: Int, config: org.meshtastic.proto.Config, packetId: Int) {}
|
||||
|
|
@ -83,6 +87,10 @@ class FakeRadioController : RadioController {
|
|||
|
||||
override suspend fun reboot(destNum: Int, packetId: Int) {}
|
||||
|
||||
override suspend fun rebootToDfu(nodeNum: Int) {}
|
||||
|
||||
override suspend fun requestRebootOta(requestId: Int, destNum: Int, mode: Int, hash: ByteArray?) {}
|
||||
|
||||
override suspend fun shutdown(destNum: Int, packetId: Int) {}
|
||||
|
||||
override suspend fun factoryReset(destNum: Int, packetId: Int) {}
|
||||
|
|
@ -91,6 +99,16 @@ class FakeRadioController : RadioController {
|
|||
|
||||
override suspend fun removeByNodenum(packetId: Int, nodeNum: Int) {}
|
||||
|
||||
override suspend fun requestPosition(destNum: Int, currentPosition: org.meshtastic.core.model.Position) {}
|
||||
|
||||
override suspend fun requestUserInfo(destNum: Int) {}
|
||||
|
||||
override suspend fun requestTraceroute(requestId: Int, destNum: Int) {}
|
||||
|
||||
override suspend fun requestTelemetry(requestId: Int, destNum: Int, typeValue: Int) {}
|
||||
|
||||
override suspend fun requestNeighborInfo(requestId: Int, destNum: Int) {}
|
||||
|
||||
override suspend fun beginEditSettings(destNum: Int) {}
|
||||
|
||||
override suspend fun commitEditSettings(destNum: Int) {}
|
||||
|
|
@ -101,6 +119,8 @@ class FakeRadioController : RadioController {
|
|||
|
||||
override fun stopProvideLocation() {}
|
||||
|
||||
override fun setDeviceAddress(address: String) {}
|
||||
|
||||
// --- Helper methods for testing ---
|
||||
|
||||
fun setConnectionState(state: ConnectionState) {
|
||||
|
|
|
|||
|
|
@ -29,15 +29,15 @@ import org.junit.Assert.assertEquals
|
|||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.data.repository.PacketRepository
|
||||
import org.meshtastic.core.database.entity.Packet
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.domain.FakeRadioController
|
||||
import org.meshtastic.core.domain.MessageQueue
|
||||
import org.meshtastic.core.model.Capabilities
|
||||
import org.meshtastic.core.model.DataPacket
|
||||
import org.meshtastic.core.prefs.homoglyph.HomoglyphPrefs
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.repository.HomoglyphPrefs
|
||||
import org.meshtastic.core.repository.MessageQueue
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.core.repository.PacketRepository
|
||||
import org.meshtastic.core.repository.usecase.SendMessageUseCase
|
||||
import org.meshtastic.proto.Config
|
||||
import org.meshtastic.proto.DeviceMetadata
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ class SendMessageUseCaseTest {
|
|||
assertEquals(0, radioController.favoritedNodes.size)
|
||||
assertEquals(0, radioController.sentSharedContacts.size)
|
||||
|
||||
coVerify { packetRepository.insert(any<Packet>()) }
|
||||
coVerify { packetRepository.savePacket(any(), any(), any(), any()) }
|
||||
coVerify { messageQueue.enqueue(any()) }
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ class SendMessageUseCaseTest {
|
|||
assertEquals(1, radioController.favoritedNodes.size)
|
||||
assertEquals(12345, radioController.favoritedNodes[0])
|
||||
|
||||
coVerify { packetRepository.insert(any<Packet>()) }
|
||||
coVerify { packetRepository.savePacket(any(), any(), any(), any()) }
|
||||
coVerify { messageQueue.enqueue(any()) }
|
||||
}
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ class SendMessageUseCaseTest {
|
|||
assertEquals(1, radioController.sentSharedContacts.size)
|
||||
assertEquals(67890, radioController.sentSharedContacts[0])
|
||||
|
||||
coVerify { packetRepository.insert(any<Packet>()) }
|
||||
coVerify { packetRepository.savePacket(any(), any(), any(), any()) }
|
||||
coVerify { messageQueue.enqueue(any()) }
|
||||
}
|
||||
|
||||
|
|
@ -166,9 +166,9 @@ class SendMessageUseCaseTest {
|
|||
useCase(originalText, "0${DataPacket.ID_BROADCAST}", null)
|
||||
|
||||
// Assert
|
||||
val packetSlot = slot<Packet>()
|
||||
coVerify { packetRepository.insert(capture(packetSlot)) }
|
||||
assertTrue(packetSlot.captured.data?.text?.contains("Apple") == true)
|
||||
val packetSlot = slot<DataPacket>()
|
||||
coVerify { packetRepository.savePacket(any(), any(), capture(packetSlot), any()) }
|
||||
assertTrue(packetSlot.captured.text?.contains("Apple") == true)
|
||||
coVerify { messageQueue.enqueue(any()) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ import kotlinx.coroutines.test.runTest
|
|||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
|
||||
class AdminActionsUseCaseTest {
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ import kotlinx.coroutines.test.runTest
|
|||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.database.entity.NodeEntity
|
||||
import org.meshtastic.core.domain.FakeRadioController
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import kotlin.time.Duration.Companion.days
|
||||
|
||||
class CleanNodeDatabaseUseCaseTest {
|
||||
|
|
@ -47,9 +47,9 @@ class CleanNodeDatabaseUseCaseTest {
|
|||
val currentTime = 1000000L
|
||||
val olderThanTimestamp = currentTime - 30.days.inWholeSeconds
|
||||
|
||||
val oldNode = NodeEntity(num = 1, lastHeard = (olderThanTimestamp - 1).toInt())
|
||||
val newNode = NodeEntity(num = 2, lastHeard = (currentTime - 1).toInt())
|
||||
val ignoredNode = NodeEntity(num = 3, lastHeard = (olderThanTimestamp - 1).toInt(), isIgnored = true)
|
||||
val oldNode = Node(num = 1, lastHeard = (olderThanTimestamp - 1).toInt())
|
||||
val newNode = Node(num = 2, lastHeard = (currentTime - 1).toInt())
|
||||
val ignoredNode = Node(num = 3, lastHeard = (olderThanTimestamp - 1).toInt(), isIgnored = true)
|
||||
|
||||
coEvery { nodeRepository.getNodesOlderThan(any()) } returns listOf(oldNode, ignoredNode)
|
||||
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ import org.junit.Before
|
|||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.meshtastic.core.data.repository.MeshLogRepository
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.database.entity.MeshLog
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
import org.meshtastic.proto.Data
|
||||
import org.meshtastic.proto.FromRadio
|
||||
import org.meshtastic.proto.MeshPacket
|
||||
|
|
@ -63,7 +63,6 @@ class ExportDataUseCaseTest {
|
|||
val nodes = mapOf(senderNodeNum to senderNode)
|
||||
val stateFlow = MutableStateFlow(nodes)
|
||||
every { nodeRepository.nodeDBbyNum } returns stateFlow
|
||||
every { nodeRepository.getNodeEntityDBbyNumFlow() } returns flowOf(emptyMap())
|
||||
|
||||
val meshPacket =
|
||||
MeshPacket(
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ import org.junit.Assert.assertFalse
|
|||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.meshtastic.core.data.repository.DeviceHardwareRepository
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.ConnectionState
|
||||
import org.meshtastic.core.model.Node
|
||||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.prefs.radio.RadioPrefs
|
||||
import org.meshtastic.core.repository.DeviceHardwareRepository
|
||||
import org.meshtastic.core.repository.NodeRepository
|
||||
|
||||
class IsOtaCapableUseCaseTest {
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import io.mockk.verify
|
|||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.meshtastic.core.database.DatabaseConstants
|
||||
import org.meshtastic.core.database.DatabaseManager
|
||||
import org.meshtastic.core.repository.DatabaseManager
|
||||
|
||||
class SetDatabaseCacheLimitUseCaseTest {
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue