/* * 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 . */ package com.geeksville.mesh.service import com.geeksville.mesh.repository.radio.RadioInterfaceService import io.mockk.every import io.mockk.mockk import io.mockk.verify import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test import org.meshtastic.core.data.repository.MeshLogRepository import org.meshtastic.core.data.repository.PacketRepository import org.meshtastic.core.service.ConnectionState import org.meshtastic.proto.MeshPacket import org.meshtastic.proto.QueueStatus import org.meshtastic.proto.ToRadio class PacketHandlerTest { private val packetRepository: PacketRepository = mockk(relaxed = true) private val serviceBroadcasts: MeshServiceBroadcasts = mockk(relaxed = true) private val radioInterfaceService: RadioInterfaceService = mockk(relaxed = true) private val meshLogRepository: MeshLogRepository = mockk(relaxed = true) private val connectionStateHolder: ConnectionStateHandler = mockk(relaxed = true) private val testDispatcher = StandardTestDispatcher() private val testScope = TestScope(testDispatcher) private lateinit var handler: PacketHandler @Before fun setUp() { handler = PacketHandler( dagger.Lazy { packetRepository }, serviceBroadcasts, radioInterfaceService, dagger.Lazy { meshLogRepository }, connectionStateHolder, ) handler.start(testScope) } @Test fun `sendToRadio with ToRadio sends immediately`() { val toRadio = ToRadio(packet = MeshPacket(id = 123)) handler.sendToRadio(toRadio) verify { radioInterfaceService.sendToRadio(any()) } } @Test fun `sendToRadio with MeshPacket queues and sends when connected`() = runTest(testDispatcher) { val packet = MeshPacket(id = 456) every { connectionStateHolder.connectionState } returns MutableStateFlow(ConnectionState.Connected) handler.sendToRadio(packet) testScheduler.runCurrent() verify { radioInterfaceService.sendToRadio(any()) } } @Test fun `handleQueueStatus completes deferred`() = runTest(testDispatcher) { val packet = MeshPacket(id = 789) every { connectionStateHolder.connectionState } returns MutableStateFlow(ConnectionState.Connected) handler.sendToRadio(packet) testScheduler.runCurrent() val status = QueueStatus( mesh_packet_id = 789, res = 0, // Success free = 1, ) handler.handleQueueStatus(status) testScheduler.runCurrent() } }