package jnpf.dmsService;
|
|
import jnpf.dmsEntity.kanwu.DmsXiudingKanwuRow;
|
import jnpf.dmsMapper.DmsXiudingKanwuMapper;
|
import jnpf.dmsIntegration.audit.DmsBusinessChangeAudit;
|
import jnpf.exception.DataException;
|
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.provider.ValueSource;
|
import org.mockito.*;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
import java.util.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
import static org.mockito.Mockito.*;
|
|
@ExtendWith(MockitoExtension.class)
|
class DmsXiudingKanwuServiceTest {
|
@Mock DmsXiudingKanwuMapper mapper;
|
@Mock DmsBusinessChangeAudit audit;
|
@InjectMocks DmsXiudingKanwuService service;
|
DmsXiudingKanwuRow row(String id) {
|
DmsXiudingKanwuRow row = new DmsXiudingKanwuRow();
|
row.setKanwuZixiangId(id); row.setKanwuShenqingId("request");
|
row.setWenjianId("file"); row.setBanbenId("base"); row.setKanwuNeirong("content");
|
row.setChuliJielun("yixiugai_queren"); row.setChuliYuanyin("已核对并修订");
|
row.setChuliRenId("drafter"); row.setChuliShijian(new Date(1000));
|
return row;
|
}
|
void arrange(List<DmsXiudingKanwuRow> handled, List<DmsXiudingKanwuRow> approved) {
|
when(mapper.selectHandlingForUpdate("tenant", "audit")).thenReturn(handled);
|
when(mapper.selectApprovedForUpdate("tenant", "file", "base")).thenReturn(approved);
|
}
|
List<DmsXiudingKanwuRow> load() { return service.loadAndValidate("tenant", "audit", "file", "base"); }
|
@Test void acceptsEmptyScope() { arrange(List.of(), List.of()); assertTrue(load().isEmpty()); }
|
@Test void sortsWithoutMutatingMapperListAndNormalizesFiles() {
|
DmsXiudingKanwuRow handled = row("a"), source = row("a");
|
handled.setFujian("[{\"url\":\"x\",\"name\":\"n\"}]");
|
source.setFujian("[{\"name\":\"n\",\"url\":\"x\"}]");
|
DmsXiudingKanwuRow empty = row("b"); empty.setFujian("[]");
|
arrange(List.of(empty, handled), List.of(source, row("b")));
|
assertEquals(List.of("a", "b"), load().stream().map(DmsXiudingKanwuRow::getKanwuZixiangId).toList());
|
}
|
@ParameterizedTest @ValueSource(strings={"yixiugai_queren", "bucaina"})
|
void bothOutcomesRequireReasonAndAuditFields(String outcome) {
|
DmsXiudingKanwuRow handled = row("a"); handled.setChuliJielun(outcome);
|
arrange(List.of(handled), List.of(row("a"))); assertEquals(outcome, load().get(0).getChuliJielun());
|
handled.setChuliYuanyin(" "); assertThrows(DataException.class, this::load);
|
handled.setChuliYuanyin("reason"); handled.setChuliRenId(null); assertThrows(DataException.class, this::load);
|
handled.setChuliRenId("drafter"); handled.setChuliShijian(null); assertThrows(DataException.class, this::load);
|
}
|
@Test void rejectsMissingNewApprovedNote() { arrange(List.of(row("a")), List.of(row("a"), row("b"))); assertThrows(DataException.class, this::load); }
|
@Test void rejectsUnapprovedOrOutOfScopeNote() { arrange(List.of(row("other")), List.of(row("a"))); assertThrows(DataException.class, this::load); }
|
@Test void rejectsDuplicateHandling() { arrange(List.of(row("a"), row("a")), List.of(row("a"), row("b"))); assertThrows(DataException.class, this::load); }
|
@Test void rejectsChangedContentOrFiles() {
|
DmsXiudingKanwuRow handled = row("a"); arrange(List.of(handled), List.of(row("a")));
|
handled.setKanwuNeirong("changed"); assertThrows(DataException.class, this::load);
|
handled.setKanwuNeirong("content"); handled.setFujian("[{}]"); assertThrows(DataException.class, this::load);
|
handled.setFujian("{}"); assertThrows(DataException.class, this::load);
|
handled.setFujian("invalid"); assertThrows(DataException.class, this::load);
|
}
|
@Test void rejectsUnknownOutcome() { DmsXiudingKanwuRow handled=row("a");handled.setChuliJielun("yes");arrange(List.of(handled),List.of(row("a")));assertThrows(DataException.class,this::load); }
|
@Test void preservesFirstProcessingAuditAndOnlyClosesUnprocessedRows() {
|
DmsXiudingKanwuRow processed = row("a"); processed.setShifouYichuli("yes");
|
arrange(List.of(row("a"), row("b")), List.of(processed, row("b")));
|
List<DmsXiudingKanwuRow> verified = load();
|
when(mapper.markProcessed("tenant", verified.get(1))).thenReturn(1);
|
Date writtenAt = new Date(9000);
|
Map<String, Object> before = DmsBusinessChangeAudit.values("shifou_yichuli", null,
|
"chuliren", "previous", "chuli_shijian", null);
|
Map<String, Object> after = DmsBusinessChangeAudit.values("shifou_yichuli", "yes",
|
"chuliren", "drafter", "chuli_shijian", writtenAt);
|
when(mapper.selectProcessingState("tenant", "b")).thenReturn(before, after);
|
service.complete("tenant", "audit", verified);
|
verify(mapper, never()).markProcessed("tenant", verified.get(0));
|
verify(mapper).markProcessed("tenant", verified.get(1));
|
verify(mapper, never()).selectProcessingState("tenant", "a");
|
verify(audit).record(eq("tenant"), eq("DMS_REVISION_ERRATA_PROCESSED"),
|
eq("修订生效后回写勘误处理状态"), eq("dms_wenjian_kanwu_shenqing_zixiang"), eq("b"),
|
eq(before), eq(after), eq("已核对并修订"), argThat(context ->
|
"audit".equals(context.get("xiuding_shenhe_id"))
|
&& "request".equals(context.get("kanwu_shenqing_id"))
|
&& "yixiugai_queren".equals(context.get("chuli_jielun"))
|
&& new Date(1000).equals(context.get("chuli_shijian"))));
|
verifyNoMoreInteractions(audit);
|
}
|
@Test void emptyOrAlreadyProcessedRowsDoNotCreateAuditEvents() {
|
service.complete("tenant", "audit", List.of());
|
DmsXiudingKanwuRow processed = row("a");
|
processed.setAlreadyProcessed(true);
|
service.complete("tenant", "audit", List.of(processed));
|
verifyNoInteractions(mapper, audit);
|
}
|
@Test void updateFailurePropagatesToEffectiveTransaction() {
|
when(mapper.selectProcessingState("tenant", "a")).thenReturn(Map.of("id", "a"));
|
assertThrows(DataException.class, () -> service.complete("tenant", "audit", List.of(row("a"))));
|
verify(mapper).markProcessed(eq("tenant"), any());
|
verifyNoInteractions(audit);
|
}
|
@Test void missingSnapshotDoesNotFabricateAuditValues() {
|
when(mapper.selectProcessingState("tenant", "a")).thenReturn(null);
|
assertThrows(DataException.class, () -> service.complete("tenant", "audit", List.of(row("a"))));
|
verify(mapper, never()).markProcessed(anyString(), any());
|
verifyNoInteractions(audit);
|
}
|
}
|