yeg
2026-09-05 27428b31edee97703b529559146cdd7eef87a7a9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package com.ruoyi.system.service.impl;
 
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.when;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import com.ruoyi.system.domain.TTest;
import com.ruoyi.system.domain.TTestDataOverride;
import com.ruoyi.system.mapper.TTestMapper;
import com.ruoyi.system.service.ITTestService;
 
/** Ticket01:三类查询直接返回数据库计算的当前有效数据,删除不抹除原始事实。 */
@ExtendWith(MockitoExtension.class)
class TestDataQueryServiceEffectiveDataTest
{
    @Mock
    private TTestMapper mapper;
    @Mock
    private ITTestService tests;
 
    @Test
    void appliesRealtimeEditAndFiltersDeletedRow()
    {
        when(tests.selectTestById(7L)).thenReturn(new TTest());
        Map<String, Object> edited = row("adapterId", 1L, "devtype", 22, "deviceId", 22L, "subdevid", 0, "channelId", 8L, "sequenceId", 3L,
                "voltage", 3.7d);
        Map<String, Object> deleted = row("adapterId", 1L, "devtype", 22, "deviceId", 22L, "subdevid", 0, "channelId", 8L, "sequenceId", 4L,
                "voltage", 3.8d);
        TTestDataOverride edit = override("1:22:22:0:8:3", "{\"voltage\":\"4.1000\"}", false);
        TTestDataOverride remove = override("1:22:22:0:8:4", null, true);
        when(mapper.selectPersistedRecords(7L)).thenReturn(List.of(edited, deleted));
        when(mapper.selectDataOverrides(7L, "REALTIME")).thenReturn(List.of(edit, remove));
 
        List<Map<String, Object>> result = new TestDataQueryServiceImpl(mapper, tests).records(7L);
 
        assertEquals(1, result.size());
        assertEquals("4.1000", result.get(0).get("voltage"));
        assertEquals(3L, result.get(0).get("sequenceId"));
    }
 
    @Test
    void usesStepAndCycleStableIdentities()
    {
        when(tests.selectTestById(8L)).thenReturn(new TTest());
        Map<String, Object> step = row("adapterId", 1L, "devtype", 22, "deviceId", 22L, "subdevid", 0, "channelId", 8L, "cycleNo", 2, "stepNo", 4,
                "capacity", 1d);
        Map<String, Object> cycle = row("adapterId", 1L, "devtype", 22, "deviceId", 22L, "subdevid", 0, "channelId", 8L, "cycleNo", 2,
                "efficiency", 90d);
        when(mapper.selectPersistedSteps(8L)).thenReturn(List.of(step));
        when(mapper.selectPersistedCycles(8L)).thenReturn(List.of(cycle));
        when(mapper.selectDataOverrides(8L, "STEP")).thenReturn(List.of(override("step:1:22:22:0:8:2:4",
                "{\"capacity\":\"2.0000\"}", false)));
        when(mapper.selectDataOverrides(8L, "CYCLE")).thenReturn(List.of(override("cycle:1:22:22:0:8:2",
                "{\"efficiency\":\"95.00\"}", false)));
        TestDataQueryServiceImpl service = new TestDataQueryServiceImpl(mapper, tests);
 
        assertEquals("2.0000", service.steps(8L).get(0).get("capacity"));
        assertEquals("95.00", service.cycles(8L).get(0).get("efficiency"));
        assertTrue(service.cycles(8L).get(0).containsKey("cycleNo"));
    }
 
    @Test
    void readsFinalPersistedTablesWhenAvailableAndReturnsEpochMillis()
    {
        when(tests.selectTestById(11L)).thenReturn(new TTest());
        Map<String, Object> row = row("recordNo", "RT-1", "deviceTime", java.util.Date.from(Instant.parse("2026-09-02T00:00:00Z")),
                "serverReceivedAt", java.util.Date.from(Instant.parse("2026-09-02T00:00:01Z")));
        when(mapper.selectPersistedFinalRealtimeRecords(11L)).thenReturn(List.of(row));
        when(mapper.selectDataOverrides(11L, "REALTIME")).thenReturn(List.of());
 
        Map<String, Object> actual = new TestDataQueryServiceImpl(mapper, tests).records(11L).get(0);
 
        assertEquals(Instant.parse("2026-09-02T00:00:00Z").toEpochMilli(), actual.get("deviceTime"));
        assertEquals(Instant.parse("2026-09-02T00:00:01Z").toEpochMilli(), actual.get("serverReceivedAt"));
    }
 
    @Test
    void assignsCollectorObservationToCabinetStepByDeviceTime()
    {
        when(tests.selectTestById(9L)).thenReturn(new TTest());
        Map<String, Object> cabinet = row("sourceType", "CABINET", "batteryNo", "B-01", "cycleNo", 1,
                "stepNo", 2, "stepName", "恒流充电", "deviceTime", Instant.parse("2026-09-02T00:00:00Z"),
                "adapterId", 1L, "devtype", 22, "deviceId", 22L, "subdevid", 0, "channelId", 8L, "sequenceId", 1L);
        Map<String, Object> collector = row("sourceType", "COLLECTOR", "batteryNo", "B-01", "metricCode", "temperature",
                "deviceTime", Instant.parse("2026-09-02T00:00:01Z"), "collectorId", 3L, "channelCode", "S-01", "sequenceId", 2L);
        when(mapper.selectPersistedRecords(9L)).thenReturn(List.of(cabinet));
        when(mapper.selectPersistedCollectorRecords(9L)).thenReturn(List.of(collector));
        when(mapper.selectDataOverrides(9L, "REALTIME")).thenReturn(List.of());
 
        List<Map<String, Object>> result = new TestDataQueryServiceImpl(mapper, tests).records(9L);
 
        assertEquals(2, result.size());
        Map<String, Object> assigned = result.stream().filter(item -> "COLLECTOR".equals(item.get("sourceType"))).findFirst().orElseThrow();
        assertEquals("1", assigned.get("cycleNo"));
        assertEquals("2", assigned.get("stepNo"));
        assertEquals("恒流充电", assigned.get("stepName"));
    }
 
    @Test
    void doesNotAssignCollectorObservationToDeletedCabinetStep()
    {
        when(tests.selectTestById(10L)).thenReturn(new TTest());
        Map<String, Object> cabinet = row("sourceType", "CABINET", "batteryNo", "B-01", "cycleNo", 1,
                "stepNo", 2, "stepName", "恒流充电", "deviceTime", Instant.parse("2026-09-02T00:00:00Z"),
                "adapterId", 1L, "devtype", 22, "deviceId", 22L, "subdevid", 0, "channelId", 8L, "sequenceId", 1L);
        Map<String, Object> collector = row("sourceType", "COLLECTOR", "batteryNo", "B-01", "metricCode", "temperature",
                "deviceTime", Instant.parse("2026-09-02T00:00:01Z"), "collectorId", 3L, "channelCode", "S-01", "sequenceId", 2L);
        when(mapper.selectPersistedRecords(10L)).thenReturn(List.of(cabinet));
        when(mapper.selectPersistedCollectorRecords(10L)).thenReturn(List.of(collector));
        when(mapper.selectDataOverrides(10L, "REALTIME")).thenReturn(List.of(
                override("1:22:22:0:8:1", null, true)));
 
        List<Map<String, Object>> result = new TestDataQueryServiceImpl(mapper, tests).records(10L);
 
        Map<String, Object> assigned = result.stream().filter(item -> "COLLECTOR".equals(item.get("sourceType"))).findFirst().orElseThrow();
        assertTrue(!assigned.containsKey("stepNo"));
        assertTrue(!assigned.containsKey("cycleNo"));
    }
 
    private static TTestDataOverride override(String identity, String values, boolean deleted)
    {
        TTestDataOverride result = new TTestDataOverride();
        result.setStableIdentity(identity);
        result.setFieldValues(values);
        result.setDeleted(deleted);
        return result;
    }
 
    private static Map<String, Object> row(Object... values)
    {
        Map<String, Object> result = new HashMap<>();
        for (int index = 0; index < values.length; index += 2) result.put(String.valueOf(values[index]), values[index + 1]);
        return result;
    }
}