package jnpf.dmsService.impl;
|
|
import jnpf.base.UserInfo;
|
import jnpf.dmsEntity.DmsWenjianBanbenKongzhiEntity;
|
import jnpf.dmsEntity.DmsWenjianXinzengGuanliEntity;
|
import jnpf.dmsEntity.DmsWenjianXinzengShenheEntity;
|
import jnpf.dmsEntity.DmsWenjianXiudingShenheEntity;
|
import jnpf.dmsEntity.DmsWenjianXiudingShenqingEntity;
|
import jnpf.dmsEntity.wenjianbianhao.DmsFlowEventType;
|
import jnpf.dmsMapper.DmsWenjianBanbenKongzhiMapper;
|
import jnpf.dmsMapper.DmsWenjianXinzengGuanliMapper;
|
import jnpf.dmsMapper.DmsWenjianXinzengShenheMapper;
|
import jnpf.dmsMapper.DmsWenjianXiudingShenheMapper;
|
import jnpf.dmsMapper.DmsWenjianXiudingShenqingMapper;
|
import jnpf.dmsPermission.DmsCurrentIdentity;
|
import jnpf.exception.DataException;
|
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.mockito.ArgumentCaptor;
|
import org.mockito.InjectMocks;
|
import org.mockito.Mock;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
|
import java.util.Collections;
|
import java.util.Date;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.when;
|
|
@ExtendWith(MockitoExtension.class)
|
class DmsWenjianBanbenServiceImplTest {
|
|
private static final String TENANT_ID = "tenant-1";
|
private static final String FLOW_ID = "flow-1";
|
private static final String TASK_ID = "task-1";
|
|
@Mock private DmsCurrentIdentity identity;
|
@Mock private DmsWenjianBanbenKongzhiMapper controlMapper;
|
@Mock private DmsWenjianXinzengGuanliMapper newRequestMapper;
|
@Mock private DmsWenjianXinzengShenheMapper newAuditMapper;
|
@Mock private DmsWenjianXiudingShenqingMapper revisionRequestMapper;
|
@Mock private DmsWenjianXiudingShenheMapper revisionAuditMapper;
|
|
@InjectMocks
|
private DmsWenjianBanbenServiceImpl service;
|
|
@BeforeEach
|
void setUpIdentity() {
|
UserInfo user = new UserInfo();
|
user.setUserId("operator-1");
|
user.setTenantId(TENANT_ID);
|
when(identity.requireUser()).thenReturn(user);
|
when(identity.tenantId(user)).thenReturn(TENANT_ID);
|
}
|
|
@Test
|
void newAuditPassInitializesD00AndWritesAuditResult() {
|
DmsWenjianXinzengShenheEntity audit = newAudit(2);
|
DmsWenjianXinzengGuanliEntity request = newRequest();
|
when(newAuditMapper.selectByFlowForUpdate(TENANT_ID, FLOW_ID, TASK_ID))
|
.thenReturn(Collections.singletonList(audit));
|
when(newRequestMapper.selectByIdForUpdate(TENANT_ID, "new-request-1"))
|
.thenReturn(request);
|
when(controlMapper.selectByFileForUpdate(TENANT_ID, "new-request-1"))
|
.thenReturn(null);
|
when(controlMapper.insertControl(any())).thenReturn(1);
|
when(newAuditMapper.updateEffectiveVersion(audit)).thenReturn(1);
|
|
service.syncNewAuditFlow(FLOW_ID, TASK_ID, 2, DmsFlowEventType.END);
|
|
ArgumentCaptor<DmsWenjianBanbenKongzhiEntity> captor =
|
ArgumentCaptor.forClass(DmsWenjianBanbenKongzhiEntity.class);
|
verify(controlMapper).insertControl(captor.capture());
|
DmsWenjianBanbenKongzhiEntity control = captor.getValue();
|
assertEquals("new-request-1", control.getWenjianId());
|
assertEquals(0, control.getBanbenXuhao());
|
assertEquals(0L, control.getBiangengXuhao());
|
assertEquals("xinzeng", control.getZuihouShengxiaoLeixing());
|
assertEquals("D(00)", audit.getShengxiaoBanbenhao());
|
assertNotNull(audit.getBanbenShengxiaoShijian());
|
}
|
|
@Test
|
void upgradeRevisionAdvancesVersionAndChangeSequence() {
|
DmsWenjianXiudingShenheEntity audit = revisionAudit(2, "shengji");
|
DmsWenjianXiudingShenqingEntity request = revisionRequest(2, 4L);
|
DmsWenjianBanbenKongzhiEntity control = control(2, 4L);
|
when(revisionAuditMapper.selectByFlowForUpdate(TENANT_ID, FLOW_ID, TASK_ID))
|
.thenReturn(Collections.singletonList(audit));
|
when(revisionRequestMapper.selectByIdForUpdate(TENANT_ID, "revision-request-1"))
|
.thenReturn(request);
|
when(controlMapper.selectByFileForUpdate(TENANT_ID, "file-1")).thenReturn(control);
|
when(controlMapper.advance(any(), any(), any())).thenReturn(1);
|
when(revisionAuditMapper.updateEffectiveVersion(audit)).thenReturn(1);
|
|
service.syncRevisionAuditFlow(FLOW_ID, TASK_ID, 2, DmsFlowEventType.END);
|
|
assertEquals(3, control.getBanbenXuhao());
|
assertEquals(5L, control.getBiangengXuhao());
|
assertEquals("D(03)", audit.getShengxiaoBanbenhao());
|
assertEquals(5L, audit.getShengxiaoBiangengXuhao());
|
verify(controlMapper).advance(control, 2, 4L);
|
}
|
|
@Test
|
void unchangedRevisionKeepsVersionButAdvancesChangeSequence() {
|
DmsWenjianXiudingShenheEntity audit = revisionAudit(2, "wubianhua");
|
DmsWenjianXiudingShenqingEntity request = revisionRequest(2, 4L);
|
DmsWenjianBanbenKongzhiEntity control = control(2, 4L);
|
when(revisionAuditMapper.selectByFlowForUpdate(TENANT_ID, FLOW_ID, TASK_ID))
|
.thenReturn(Collections.singletonList(audit));
|
when(revisionRequestMapper.selectByIdForUpdate(TENANT_ID, "revision-request-1"))
|
.thenReturn(request);
|
when(controlMapper.selectByFileForUpdate(TENANT_ID, "file-1")).thenReturn(control);
|
when(controlMapper.advance(any(), any(), any())).thenReturn(1);
|
when(revisionAuditMapper.updateEffectiveVersion(audit)).thenReturn(1);
|
|
service.syncRevisionAuditFlow(FLOW_ID, TASK_ID, 2, DmsFlowEventType.END);
|
|
assertEquals(2, control.getBanbenXuhao());
|
assertEquals(5L, control.getBiangengXuhao());
|
assertEquals("D(02)", audit.getShengxiaoBanbenhao());
|
}
|
|
@Test
|
void staleRevisionSnapshotIsRejectedBeforeAnyUpdate() {
|
DmsWenjianXiudingShenheEntity audit = revisionAudit(2, "shengji");
|
DmsWenjianXiudingShenqingEntity request = revisionRequest(2, 3L);
|
DmsWenjianBanbenKongzhiEntity control = control(2, 4L);
|
when(revisionAuditMapper.selectByFlowForUpdate(TENANT_ID, FLOW_ID, TASK_ID))
|
.thenReturn(Collections.singletonList(audit));
|
when(revisionRequestMapper.selectByIdForUpdate(TENANT_ID, "revision-request-1"))
|
.thenReturn(request);
|
when(controlMapper.selectByFileForUpdate(TENANT_ID, "file-1")).thenReturn(control);
|
|
DataException exception = assertThrows(DataException.class,
|
() -> service.syncRevisionAuditFlow(
|
FLOW_ID, TASK_ID, 2, DmsFlowEventType.END));
|
|
assertEquals("来源文件已有其他修订生效,请重新发起修订申请", exception.getMessage());
|
verify(controlMapper, never()).advance(any(), any(), any());
|
verify(revisionAuditMapper, never()).updateEffectiveVersion(any());
|
}
|
|
@Test
|
void repeatedRevisionEndIsIdempotentAfterLaterVersionsExist() {
|
DmsWenjianXiudingShenheEntity audit = revisionAudit(2, "shengji");
|
audit.setShengxiaoBanbenXuhao(3);
|
audit.setShengxiaoBanbenhao("D(03)");
|
audit.setShengxiaoBiangengXuhao(5L);
|
audit.setBanbenShengxiaoShijian(new Date());
|
when(revisionAuditMapper.selectByFlowForUpdate(TENANT_ID, FLOW_ID, TASK_ID))
|
.thenReturn(Collections.singletonList(audit));
|
|
service.syncRevisionAuditFlow(FLOW_ID, TASK_ID, 2, DmsFlowEventType.END);
|
|
verify(revisionRequestMapper, never()).selectByIdForUpdate(any(), any());
|
verify(controlMapper, never()).advance(any(), any(), any());
|
}
|
|
private DmsWenjianXinzengShenheEntity newAudit(int state) {
|
DmsWenjianXinzengShenheEntity audit = new DmsWenjianXinzengShenheEntity();
|
audit.setId("new-audit-1");
|
audit.setTenantId(TENANT_ID);
|
audit.setFlowId(FLOW_ID);
|
audit.setFlowTaskId(TASK_ID);
|
audit.setFlowState(state);
|
audit.setShenqingdanId("new-request-1");
|
return audit;
|
}
|
|
private DmsWenjianXinzengGuanliEntity newRequest() {
|
DmsWenjianXinzengGuanliEntity request = new DmsWenjianXinzengGuanliEntity();
|
request.setId("new-request-1");
|
request.setTenantId(TENANT_ID);
|
request.setFlowState(2);
|
request.setXinxiuding("xinding");
|
request.setBanbenXuhao(0);
|
request.setBanbenhao("D(00)");
|
return request;
|
}
|
|
private DmsWenjianXiudingShenheEntity revisionAudit(int state, String type) {
|
DmsWenjianXiudingShenheEntity audit = new DmsWenjianXiudingShenheEntity();
|
audit.setId("revision-audit-1");
|
audit.setTenantId(TENANT_ID);
|
audit.setFlowId(FLOW_ID);
|
audit.setFlowTaskId(TASK_ID);
|
audit.setFlowState(state);
|
audit.setXiudingShenqingId("revision-request-1");
|
audit.setBiangengFangshi(type);
|
return audit;
|
}
|
|
private DmsWenjianXiudingShenqingEntity revisionRequest(int version, long change) {
|
DmsWenjianXiudingShenqingEntity request = new DmsWenjianXiudingShenqingEntity();
|
request.setId("revision-request-1");
|
request.setTenantId(TENANT_ID);
|
request.setFlowState(2);
|
request.setWenjianId("file-1");
|
request.setBanbenXuhao(version);
|
request.setBanbenhao(DmsWenjianBanbenServiceImpl.formatVersion(version));
|
request.setYuanBiangengXuhao(change);
|
return request;
|
}
|
|
private DmsWenjianBanbenKongzhiEntity control(int version, long change) {
|
DmsWenjianBanbenKongzhiEntity control = new DmsWenjianBanbenKongzhiEntity();
|
control.setId("control-1");
|
control.setTenantId(TENANT_ID);
|
control.setWenjianId("file-1");
|
control.setBanbenXuhao(version);
|
control.setBiangengXuhao(change);
|
control.setBizStatus("effective");
|
return control;
|
}
|
}
|