From e38aca8134570513435c003c25dc05f1ae51c9c9 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期四, 08 十月 2026 13:56:28 +0800
Subject: [PATCH] 实现 Ticket04:采集器辅助测量与登记入口,拆除开发模拟器

---
 ruoyi-admin/src/test/java/com/battery/business/service/impl/DeviceDiscoveryPersistenceServiceTest.java |   63 ++++++++++++++++++-------------
 1 files changed, 37 insertions(+), 26 deletions(-)

diff --git a/ruoyi-admin/src/test/java/com/battery/business/service/impl/DeviceDiscoveryPersistenceServiceTest.java b/ruoyi-admin/src/test/java/com/battery/business/service/impl/DeviceDiscoveryPersistenceServiceTest.java
index a68bc03..09e335e 100644
--- a/ruoyi-admin/src/test/java/com/battery/business/service/impl/DeviceDiscoveryPersistenceServiceTest.java
+++ b/ruoyi-admin/src/test/java/com/battery/business/service/impl/DeviceDiscoveryPersistenceServiceTest.java
@@ -19,34 +19,45 @@
 
 class DeviceDiscoveryPersistenceServiceTest
 {
+    /**
+     * 来源不可达时,既有候选保留来源身份但旧快照被撤下、在线转为离线,登记设备同步离线;
+     * 来源恢复后下一次成功发现重新带回实时事实。
+     */
     @Test
-    void failedDiscoveryInvalidatesSuccessfulSnapshotUntilSoftwareReturns() throws Exception
+    void failedDiscoveryInvalidatesSuccessfulSnapshotUntilSourceReturns()
     {
-        try (var simulator = new com.battery.device.simulator.BtsDevelopmentSimulator(0);
-             var registry = new DeviceAdapterRegistry(List.of(new com.battery.device.bts.BtsDeviceAdapterFactory())))
-        {
-            registry.synchronize(new com.battery.device.api.registry.AdapterInstanceConfig("dev-sim", "BTS",
-                    "127.0.0.1", simulator.port(), 5000, "Asia/Hong_Kong", true,
-                    com.battery.device.api.model.AdapterCapabilities.observeOnly()));
-            var store = new InMemoryDeviceDiscoveryCandidateStore();
-            var mapper = Mockito.mock(TDetectionCabinetMapper.class);
-            var persistence = new DeviceDiscoveryPersistenceService(store, mapper);
-            var scheduler = new com.battery.business.runtime.DevelopmentSimulatorDiscoveryScheduler(registry, persistence);
-            simulator.updateChannel(1, 1, true, com.battery.device.api.model.DeviceWorkStatus.WORKING);
-            scheduler.discover();
-            var before = store.snapshot(java.time.Instant.now()).cabinets().get(0);
-            org.junit.jupiter.api.Assertions.assertNotNull(before.channels().get(0).latestSnapshot());
-            simulator.setSoftwareAccessible(false);
-            scheduler.discover();
-            var failed = store.snapshot(java.time.Instant.now()).cabinets().get(0);
-            assertEquals(before.deviceCode(), failed.deviceCode());
-            org.junit.jupiter.api.Assertions.assertFalse(failed.online());
-            org.junit.jupiter.api.Assertions.assertNull(failed.channels().get(0).latestSnapshot());
-            verify(mapper).markRegisteredCabinetsOffline("dev-sim");
-            simulator.setSoftwareAccessible(true);
-            scheduler.discover();
-            org.junit.jupiter.api.Assertions.assertTrue(store.snapshot(java.time.Instant.now()).cabinets().get(0).online());
-        }
+        InMemoryDeviceDiscoveryCandidateStore store = new InMemoryDeviceDiscoveryCandidateStore();
+        TDetectionCabinetMapper cabinetMapper = Mockito.mock(TDetectionCabinetMapper.class);
+        DeviceAdapterRegistry registry = Mockito.mock(DeviceAdapterRegistry.class);
+        DeviceAdapter adapter = Mockito.mock(DeviceAdapter.class);
+        ChannelIdentity identity = new ChannelIdentity("neware76", 21, 36, 1, 2);
+        java.time.Instant observedAt = java.time.Instant.parse("2026-09-28T01:54:56Z");
+        com.battery.device.api.model.RealtimeSnapshot snapshot = new com.battery.device.api.model.RealtimeSnapshot(
+                identity, com.battery.device.api.model.DeviceWorkStatus.WORKING, 3, 7, "1", null,
+                new java.math.BigDecimal("1.2"), new java.math.BigDecimal("3.3"),
+                new java.math.BigDecimal("0.5"), new java.math.BigDecimal("1.1"), 60L, 30L, null, observedAt, java.util.Map.of());
+        when(adapter.discoverChannels()).thenReturn(List.of(new DetectedChannel(identity, "26.1.2.3", true)));
+        when(adapter.inquire(any())).thenReturn(java.util.Map.of(identity, snapshot));
+        when(registry.execute(eq("neware76"), any())).thenAnswer(invocation -> {
+            @SuppressWarnings("unchecked")
+            Function<DeviceAdapter, Object> operation = (Function<DeviceAdapter, Object>) invocation.getArgument(1);
+            return operation.apply(adapter);
+        });
+        DeviceDiscoveryPersistenceService service = new DeviceDiscoveryPersistenceService(store, cabinetMapper);
+        service.discoverForReception(registry, new DeviceDiscoveryPersistenceService.DiscoverySource(
+                "neware76", 8L, "新威 7.6 那台", 60000, true));
+
+        var before = store.snapshot(java.time.Instant.now()).cabinets().get(0);
+        org.junit.jupiter.api.Assertions.assertNotNull(before.channels().get(0).latestSnapshot());
+        org.junit.jupiter.api.Assertions.assertTrue(before.online());
+
+        service.markUnavailable("neware76");
+
+        var failed = store.snapshot(java.time.Instant.now()).cabinets().get(0);
+        assertEquals(before.deviceCode(), failed.deviceCode());
+        org.junit.jupiter.api.Assertions.assertFalse(failed.online());
+        org.junit.jupiter.api.Assertions.assertNull(failed.channels().get(0).latestSnapshot());
+        verify(cabinetMapper).markRegisteredCabinetsOffline("neware76");
     }
 
     @Test

--
Gitblit v1.7.1