package jnpf.dmsService; import jnpf.base.UserInfo; import jnpf.dmsEntity.fenfa.*; import jnpf.dmsEntity.fenfa.form.DmsWenjianGuidangForm; import jnpf.dmsEntity.fenfa.vo.DmsWenjianHuishouMingxiVO; import jnpf.dmsMapper.*; import jnpf.dmsPermission.DmsCurrentIdentity; import jnpf.exception.DataException; import org.junit.jupiter.api.*; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.*; import org.mockito.junit.jupiter.MockitoExtension; import java.util.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class DmsWenjianGuidangServiceTest { @Mock DmsCurrentIdentity identity; @Mock DmsWenjianChongdaGuard reprintGuard; @Mock DmsWenjianFenfaMapper fenfaMapper; @Mock DmsWenjianGuidangMapper mapper; @InjectMocks DmsWenjianGuidangService service; UserInfo user; @BeforeEach void setup() { user = new UserInfo(); user.setUserId("user"); user.setTenantId("tenant"); } void confirmIdentity() { when(identity.requireUser()).thenReturn(user); when(identity.tenantId(user)).thenReturn("tenant"); } DmsWenjianGuidangForm form(String... ids) { DmsWenjianGuidangForm f = new DmsWenjianGuidangForm(); f.setDayinJiluIds(Arrays.asList(ids)); f.setBizSign("signature"); return f; } DmsWenjianHuishouMingxiVO print(String id, String status) { DmsWenjianHuishouMingxiVO p=new DmsWenjianHuishouMingxiVO(); p.setDayinJiluId(id); p.setDayinLiushuihao("serial-"+id); p.setBizStatus(status); return p; } DmsWenjianGuidangDetail detail(String id, String box) { DmsWenjianGuidangDetail d=new DmsWenjianGuidangDetail(); d.setId("detail-"+id); d.setShenqingId("app"); d.setWenjianLiushuiId(id); d.setDanganheId(box); return d; } @Test void confirmUsesSortedTenantLocksAndDoesNotCreateRecycleRows() throws Exception { confirmIdentity(); when(fenfaMapper.selectRecyclePrintsForUpdate("tenant", Arrays.asList("a","b"))).thenReturn(Arrays.asList(print("a","daihuishou"),print("b","daihuishou"))); when(mapper.changeStatus(eq("tenant"),eq(Arrays.asList("a","b")),eq("daihuishou"),eq("daiguidang"),eq("user"),any())).thenReturn(2); assertEquals(2,service.confirm(form("b","a"))); verify(fenfaMapper,never()).insertRecycle(any()); verify(fenfaMapper,never()).insertRecycleDetail(any()); } @Test void confirmAcceptsCallbackBackedUnsignedCopyAndAuditsActualStatus() throws Exception { confirmIdentity(); DmsWenjianHuishouMingxiVO copy = print("a", "daifafang"); copy.setEarlyRecycleEligible(true); when(fenfaMapper.selectRecyclePrintsForUpdate("tenant", Arrays.asList("a"))).thenReturn(Arrays.asList(copy)); when(mapper.changeStatus(eq("tenant"), eq(Arrays.asList("a")), eq("daifafang"), eq("daiguidang"), eq("user"), any())).thenReturn(1); copy.setDayinRenwuId("task"); when(fenfaMapper.selectPrintTaskForUpdate("tenant", "task")).thenReturn(new DmsWenjianDayinRenwuEntity()); DmsWenjianGuidangForm f = form("a"); assertEquals(1, service.confirm(f)); assertEquals("daifafang", f.getBeforeStatuses().get("a")); assertNull(copy.getQianshouRen()); assertNull(copy.getQianshouShijian()); verify(reprintGuard).requireUnlocked("tenant", "a"); } @Test void confirmRejectsUnsignedCopyWithoutCallbackEvidence() { confirmIdentity(); when(fenfaMapper.selectRecyclePrintsForUpdate("tenant", Arrays.asList("a"))).thenReturn(Arrays.asList(print("a", "daifafang"))); assertThrows(DataException.class, () -> service.confirm(form("a"))); verifyNoInteractions(mapper); } @Test void confirmRejectsActiveReprintBeforeChangingStatus() throws Exception { confirmIdentity(); DmsWenjianHuishouMingxiVO copy = print("a", "daiqianshou"); copy.setEarlyRecycleEligible(true); when(fenfaMapper.selectRecyclePrintsForUpdate("tenant", Arrays.asList("a"))).thenReturn(Arrays.asList(copy)); doThrow(new DataException("reprinting")).when(reprintGuard).requireUnlocked("tenant", "a"); assertThrows(DataException.class, () -> service.confirm(form("a"))); verifyNoInteractions(mapper); } @Test void confirmRejectsMissingSignatureAndDuplicateIdsBeforeWrite() { DmsWenjianGuidangForm f=form("a"); f.setBizSign(" "); assertThrows(DataException.class,()->service.confirm(f)); assertThrows(DataException.class,()->service.confirm(form("a"," a "))); assertThrows(DataException.class,()->service.confirm(form())); verifyNoInteractions(mapper,fenfaMapper); } @Test void confirmCannotSwitchDestructionOrArchivedBranch() { confirmIdentity(); for(String status:Arrays.asList("daixiaohui","yixiaohui","daiguidang","yiguidang")) { when(fenfaMapper.selectRecyclePrintsForUpdate("tenant",Arrays.asList("a"))).thenReturn(Arrays.asList(print("a",status))); assertThrows(DataException.class,()->service.confirm(form("a"))); } verifyNoInteractions(mapper); } @Test void confirmRejectsMissingOrOtherTenantCopy() { confirmIdentity(); when(fenfaMapper.selectRecyclePrintsForUpdate("tenant",Arrays.asList("a"))).thenReturn(Collections.emptyList()); assertThrows(DataException.class,()->service.confirm(form("a"))); verifyNoInteractions(mapper); } @Test void failedCasDoesNotReportSuccessOrAuditSuccess() { confirmIdentity(); when(fenfaMapper.selectRecyclePrintsForUpdate("tenant",Arrays.asList("a"))).thenReturn(Arrays.asList(print("a","daihuishou"))); assertThrows(DataException.class,()->service.confirm(form("a"))); } @Test void prepareRejectsAnActiveApplicationAndDoesNotChangeStatus() { when(identity.tenantId()).thenReturn("tenant"); when(fenfaMapper.selectRecyclePrintsForUpdate("tenant",Arrays.asList("a"))).thenReturn(Arrays.asList(print("a","daiguidang"))); when(mapper.selectConflicts("tenant",Arrays.asList("a"),null)).thenReturn(Arrays.asList(detail("a","box"))); assertThrows(DataException.class,()->service.prepare(form("a"))); verify(mapper,never()).changeStatus(any(),any(),any(),any(),any(),any()); } @Test void prepareAllowsEditingSameApplication() throws Exception { when(identity.tenantId()).thenReturn("tenant"); when(fenfaMapper.selectRecyclePrintsForUpdate("tenant",Arrays.asList("a"))).thenReturn(Arrays.asList(print("a","daiguidang"))); DmsWenjianGuidangForm f=form("a");f.setShenqingId("app"); assertEquals(1,service.prepare(f).size()); verify(mapper).selectConflicts("tenant",Arrays.asList("a"),"app"); } }