yeg
2026-09-05 727e33642794a63505f52a8dfae269d9f9ffda29
ruoyi-admin/src/test/java/com/battery/business/service/impl/TestDataReceptionServiceImplTest.java
@@ -40,7 +40,7 @@
import com.battery.business.mapper.TTestMapper;
import com.battery.business.service.ITTestService;
/** Ticket08 通过接收入口验证三类持久化事实。 */
/** 通过接收入口验证三类持久化事实、实时预警和数据归属边界。 */
@ExtendWith(OutputCaptureExtension.class)
class TestDataReceptionServiceImplTest
{
@@ -48,6 +48,62 @@
    private static final Clock CLOCK = Clock.fixed(CAPTURED_AT, ZoneOffset.UTC);
    @Test
    void detectsRealtimeTemperatureExceededBetweenPersistenceSlots()
    {
        Fixture fixture = fixture();
        var threshold = new com.battery.business.domain.TTestWarningThreshold();
        threshold.setThresholdId(11L); threshold.setMetricCode("TEMPERATURE");
        threshold.setMinValue(new BigDecimal("8")); threshold.setMaxValue(new BigDecimal("33"));
        threshold.setUnit("℃"); threshold.setSeverity("WARNING");
        fixture.tests.selectTestById(1L).setThresholds(List.of(threshold));
        Clock clock = mock(Clock.class);
        when(clock.instant()).thenReturn(CAPTURED_AT);
        var service = new TestDataReceptionServiceImpl(fixture.mapper, fixture.tests, fixture.simulator, clock);
        when(fixture.simulator.latestCollector("collector-9")).thenReturn(collectorSnapshot(true,
                List.of(collector("S-01", 10L, "temperature", "25.1", "℃"))));
        when(fixture.mapper.insertRealtimeRecord(any())).thenReturn(1);
        service.captureReceivedData();
        when(clock.instant()).thenReturn(CAPTURED_AT.plusSeconds(5));
        when(fixture.simulator.latestCollector("collector-9")).thenReturn(collectorSnapshot(true,
                List.of(collector("S-01", 11L, "temperature", "38", "℃"))));
        service.captureReceivedData();
        verify(fixture.mapper).upsertWarningException(eq(1L), eq(11L), eq("COLLECTOR"), any(),
                eq("temperature"), eq(new BigDecimal("38")), eq("℃"), any(), eq("WARNING"), any(Date.class));
        verify(fixture.mapper, times(1)).insertRealtimeRecord(any());
    }
    @Test
    void primaryOvertemperatureIsNotOverwrittenByNormalSecondaryTemperature()
    {
        Fixture fixture = fixture();
        var threshold = new com.battery.business.domain.TTestWarningThreshold();
        threshold.setThresholdId(11L); threshold.setMetricCode("TEMPERATURE");
        threshold.setMinValue(new BigDecimal("8")); threshold.setMaxValue(new BigDecimal("33"));
        threshold.setUnit("℃"); threshold.setSeverity("WARNING");
        var test = fixture.tests.selectTestById(1L);
        test.setThresholds(List.of(threshold));
        test.getBatteries().get(0).setCollectorChannels(List.of(
                mapping("PRIMARY_TEMPERATURE", "S-01"), mapping("SECONDARY_TEMPERATURE_2", "S-03"),
                mapping("SECONDARY_TEMPERATURE_3", "S-05")));
        when(fixture.simulator.latestCollector("collector-9")).thenReturn(collectorSnapshot(true, List.of(
                collector("S-01", 10L, "temperature", "38", "℃"),
                collector("S-03", 10L, "temperature", "25.3", "℃"),
                collector("S-05", 10L, "temperature", "25.5", "℃"))));
        when(fixture.mapper.insertRealtimeRecord(any())).thenReturn(1);
        fixture.service().captureReceivedData();
        verify(fixture.mapper).upsertWarningException(eq(1L), eq(11L), eq("COLLECTOR"), any(),
                eq("temperature"), eq(new BigDecimal("38")), eq("℃"), any(), eq("WARNING"), any(Date.class));
        var row = ArgumentCaptor.forClass(TTestRealtimeRecord.class);
        verify(fixture.mapper).insertRealtimeRecord(row.capture());
        assertEquals(new BigDecimal("38"), row.getValue().getTemperature());
        assertTrue(row.getValue().getExtensionMeasurementsJson().contains("SECONDARY_TEMPERATURE_3"));
    }
    @Test
    void recordsOfflineSourcesInBackgroundEvenWithoutSuccessfulSamples() {
        Fixture fixture = fixture();
        when(fixture.mapper.selectOfflineTestSources(1L)).thenReturn(List.of(