mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-16 03:06:11 -04:00
refactor: Migrate all consumers from PodDevice to MonitoredDevice
Replace direct PodDevice/PodMonitor usage with MonitoredDevice/DeviceMonitor across ViewModels, UI screens, notifications, widgets, reactions, and service. All interface cast-based property access replaced with flat MonitoredDevice properties. Make L2capSocketFactory injectable.
This commit is contained in:
@@ -8,7 +8,8 @@ import eu.darken.capod.common.upgrade.UpgradeRepo
|
||||
import eu.darken.capod.main.core.GeneralSettings
|
||||
import eu.darken.capod.main.core.MonitorMode
|
||||
import eu.darken.capod.main.core.PermissionTool
|
||||
import eu.darken.capod.monitor.core.PodMonitor
|
||||
import eu.darken.capod.monitor.core.DeviceMonitor
|
||||
import eu.darken.capod.monitor.core.MonitoredDevice
|
||||
import eu.darken.capod.monitor.core.worker.MonitorControl
|
||||
import eu.darken.capod.pods.core.PodDevice
|
||||
import eu.darken.capod.profiles.core.AppleDeviceProfile
|
||||
@@ -44,7 +45,7 @@ class OverviewViewModelTest : BaseTest() {
|
||||
private val testDispatcher = UnconfinedTestDispatcher()
|
||||
|
||||
private lateinit var monitorControl: MonitorControl
|
||||
private lateinit var podMonitor: PodMonitor
|
||||
private lateinit var deviceMonitor: DeviceMonitor
|
||||
private lateinit var permissionTool: PermissionTool
|
||||
private lateinit var generalSettings: GeneralSettings
|
||||
private lateinit var debugSettings: DebugSettings
|
||||
@@ -53,7 +54,7 @@ class OverviewViewModelTest : BaseTest() {
|
||||
private lateinit var profilesRepo: DeviceProfilesRepo
|
||||
|
||||
private lateinit var missingPermissionsFlow: MutableStateFlow<Set<Permission>>
|
||||
private lateinit var devicesFlow: MutableStateFlow<List<PodDevice>>
|
||||
private lateinit var devicesFlow: MutableStateFlow<List<MonitoredDevice>>
|
||||
private lateinit var connectedDevicesFlow: MutableStateFlow<List<BluetoothDevice2>>
|
||||
private lateinit var isBluetoothEnabledFlow: MutableStateFlow<Boolean>
|
||||
private lateinit var profilesFlow: MutableStateFlow<List<DeviceProfile>>
|
||||
@@ -76,7 +77,7 @@ class OverviewViewModelTest : BaseTest() {
|
||||
|
||||
monitorControl = mockk(relaxed = true)
|
||||
|
||||
podMonitor = mockk<PodMonitor>().also {
|
||||
deviceMonitor = mockk<DeviceMonitor>().also {
|
||||
every { it.devices } returns devicesFlow
|
||||
}
|
||||
|
||||
@@ -117,7 +118,7 @@ class OverviewViewModelTest : BaseTest() {
|
||||
private fun createViewModel() = OverviewViewModel(
|
||||
dispatcherProvider = TestDispatcherProvider(testDispatcher),
|
||||
monitorControl = monitorControl,
|
||||
podMonitor = podMonitor,
|
||||
deviceMonitor = deviceMonitor,
|
||||
permissionTool = permissionTool,
|
||||
generalSettings = generalSettings,
|
||||
debugSettings = debugSettings,
|
||||
@@ -153,7 +154,7 @@ class OverviewViewModelTest : BaseTest() {
|
||||
|
||||
@Test
|
||||
fun `devices passed through when permissions granted`() = runTest(testDispatcher) {
|
||||
val device = mockk<PodDevice>(relaxed = true)
|
||||
val device = MonitoredDevice(ble = mockk(relaxed = true), aap = null)
|
||||
devicesFlow.value = listOf(device)
|
||||
|
||||
val vm = createViewModel()
|
||||
@@ -170,8 +171,14 @@ class OverviewViewModelTest : BaseTest() {
|
||||
val withoutProfile = object : PodDevice.Meta {
|
||||
override val profile: DeviceProfile? = null
|
||||
}
|
||||
val profiled = mockk<PodDevice>(relaxed = true) { every { meta } returns withProfile }
|
||||
val unmatched = mockk<PodDevice>(relaxed = true) { every { meta } returns withoutProfile }
|
||||
val profiled = MonitoredDevice(
|
||||
ble = mockk(relaxed = true) { every { meta } returns withProfile },
|
||||
aap = null,
|
||||
)
|
||||
val unmatched = MonitoredDevice(
|
||||
ble = mockk(relaxed = true) { every { meta } returns withoutProfile },
|
||||
aap = null,
|
||||
)
|
||||
|
||||
val state = OverviewViewModel.State(
|
||||
now = java.time.Instant.now(),
|
||||
@@ -195,8 +202,14 @@ class OverviewViewModelTest : BaseTest() {
|
||||
val withoutProfile = object : PodDevice.Meta {
|
||||
override val profile: DeviceProfile? = null
|
||||
}
|
||||
val profiled = mockk<PodDevice>(relaxed = true) { every { meta } returns withProfile }
|
||||
val unmatched = mockk<PodDevice>(relaxed = true) { every { meta } returns withoutProfile }
|
||||
val profiled = MonitoredDevice(
|
||||
ble = mockk(relaxed = true) { every { meta } returns withProfile },
|
||||
aap = null,
|
||||
)
|
||||
val unmatched = MonitoredDevice(
|
||||
ble = mockk(relaxed = true) { every { meta } returns withoutProfile },
|
||||
aap = null,
|
||||
)
|
||||
|
||||
val state = OverviewViewModel.State(
|
||||
now = java.time.Instant.now(),
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package eu.darken.capod.monitor.core
|
||||
|
||||
import eu.darken.capod.pods.core.HasCase
|
||||
import eu.darken.capod.pods.core.HasChargeDetectionDual
|
||||
import eu.darken.capod.pods.core.HasDualMicrophone
|
||||
import eu.darken.capod.pods.core.HasEarDetection
|
||||
import eu.darken.capod.pods.core.HasEarDetectionDual
|
||||
import eu.darken.capod.pods.core.PodDevice
|
||||
import eu.darken.capod.pods.core.apple.DualApplePods
|
||||
import eu.darken.capod.pods.core.apple.protocol.aap.AapConnectionState
|
||||
@@ -13,6 +18,7 @@ import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import org.junit.jupiter.api.Test
|
||||
import testhelpers.BaseTest
|
||||
import java.time.Instant
|
||||
|
||||
class MonitoredDeviceTest : BaseTest() {
|
||||
|
||||
@@ -88,4 +94,102 @@ class MonitoredDeviceTest : BaseTest() {
|
||||
val device = MonitoredDevice(ble = null, aap = null)
|
||||
device.model shouldBe PodDevice.Model.UNKNOWN
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `identity properties delegate to BLE`() {
|
||||
val id = PodDevice.Id()
|
||||
val meta = mockk<PodDevice.Meta>(relaxed = true)
|
||||
val device = MonitoredDevice(
|
||||
ble = mockk(relaxed = true) {
|
||||
every { identifier } returns id
|
||||
every { this@mockk.meta } returns meta
|
||||
},
|
||||
aap = null,
|
||||
)
|
||||
device.identifier shouldBe id
|
||||
device.meta shouldBe meta
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `identity properties null when BLE null`() {
|
||||
val device = MonitoredDevice(ble = null, aap = null)
|
||||
device.identifier.shouldBeNull()
|
||||
device.meta.shouldBeNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `signal timing properties delegate to BLE`() {
|
||||
val now = Instant.now()
|
||||
val earlier = now.minusSeconds(60)
|
||||
val device = MonitoredDevice(
|
||||
ble = mockk(relaxed = true) {
|
||||
every { seenLastAt } returns now
|
||||
every { seenFirstAt } returns earlier
|
||||
every { signalQuality } returns 0.75f
|
||||
every { rssi } returns -50
|
||||
},
|
||||
aap = null,
|
||||
)
|
||||
device.seenLastAt shouldBe now
|
||||
device.seenFirstAt shouldBe earlier
|
||||
device.signalQuality shouldBe 0.75f
|
||||
device.rssi shouldBe -50
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `signal timing defaults when BLE null`() {
|
||||
val device = MonitoredDevice(ble = null, aap = null)
|
||||
device.seenLastAt.shouldBeNull()
|
||||
device.seenFirstAt.shouldBeNull()
|
||||
device.signalQuality shouldBe 0f
|
||||
device.rssi shouldBe 0
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `charging properties delegate to BLE interfaces`() {
|
||||
val mock = mockk<DualApplePods>(relaxed = true) {
|
||||
every { model } returns PodDevice.Model.AIRPODS_PRO3
|
||||
every { (this@mockk as HasChargeDetectionDual).isLeftPodCharging } returns true
|
||||
every { (this@mockk as HasChargeDetectionDual).isRightPodCharging } returns false
|
||||
every { (this@mockk as HasCase).isCaseCharging } returns true
|
||||
}
|
||||
val device = MonitoredDevice(ble = mock, aap = null)
|
||||
device.isLeftPodCharging shouldBe true
|
||||
device.isRightPodCharging shouldBe false
|
||||
device.isCaseCharging shouldBe true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ear detection properties delegate to BLE interfaces`() {
|
||||
val mock = mockk<DualApplePods>(relaxed = true) {
|
||||
every { model } returns PodDevice.Model.AIRPODS_PRO3
|
||||
every { (this@mockk as HasEarDetectionDual).isLeftPodInEar } returns true
|
||||
every { (this@mockk as HasEarDetectionDual).isRightPodInEar } returns false
|
||||
every { (this@mockk as HasEarDetection).isBeingWorn } returns false
|
||||
every { (this@mockk as HasEarDetectionDual).isEitherPodInEar } returns true
|
||||
}
|
||||
val device = MonitoredDevice(ble = mock, aap = null)
|
||||
device.isLeftInEar shouldBe true
|
||||
device.isRightInEar shouldBe false
|
||||
device.isBeingWorn shouldBe false
|
||||
device.isEitherPodInEar shouldBe true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `icon and label properties delegate to BLE`() {
|
||||
val device = MonitoredDevice(
|
||||
ble = mockk(relaxed = true) {
|
||||
every { model } returns PodDevice.Model.AIRPODS_PRO3
|
||||
every { iconRes } returns 42
|
||||
},
|
||||
aap = null,
|
||||
)
|
||||
device.iconRes shouldBe 42
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `rawDataHex empty when BLE null`() {
|
||||
val device = MonitoredDevice(ble = null, aap = null)
|
||||
device.rawDataHex shouldBe emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class AutoConnectLogicTest : BaseTest() {
|
||||
fun setup() {
|
||||
autoConnect = AutoConnect(
|
||||
bluetoothManager = mockk(relaxed = true),
|
||||
podMonitor = mockk(relaxed = true),
|
||||
deviceMonitor = mockk(relaxed = true),
|
||||
generalSettings = mockk(relaxed = true),
|
||||
reactionSettings = mockk(relaxed = true),
|
||||
deviceProfilesRepo = mockk(relaxed = true),
|
||||
|
||||
@@ -16,7 +16,7 @@ class PlayPauseLogicTest : BaseTest() {
|
||||
fun setup() {
|
||||
// Create PlayPause instance with mocked dependencies (relaxed so we don't need to stub everything)
|
||||
playPause = PlayPause(
|
||||
podMonitor = mockk(relaxed = true),
|
||||
deviceMonitor = mockk(relaxed = true),
|
||||
bluetoothManager = mockk(relaxed = true),
|
||||
reactionSettings = mockk(relaxed = true),
|
||||
mediaControl = mockk(relaxed = true)
|
||||
|
||||
@@ -17,7 +17,7 @@ class PopUpReactionLogicTest : BaseTest() {
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
popUpReaction = PopUpReaction(
|
||||
podMonitor = mockk(relaxed = true),
|
||||
deviceMonitor = mockk(relaxed = true),
|
||||
reactionSettings = mockk(relaxed = true),
|
||||
bluetoothManager = mockk(relaxed = true),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user