package jnpf.dmsService; import jnpf.base.UserInfo; import jnpf.dmsEntity.fenfa.DmsWenjianDayinFasongEntity; import jnpf.dmsEntity.fenfa.DmsWenjianDayinQuerenEntity; import jnpf.dmsEntity.fenfa.DmsWenjianDayinRenwuEntity; import jnpf.dmsEntity.fenfa.form.DmsWenjianDayinQuerenForm; import jnpf.dmsMapper.DmsWenjianDayinQuerenMapper; import jnpf.dmsMapper.DmsWenjianFenfaMapper; import jnpf.dmsPermission.DmsCurrentIdentity; import jnpf.exception.DataException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import java.util.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; class DmsWenjianDayinQuerenServiceTest { final DmsWenjianDayinHaomaService numbers = mock(DmsWenjianDayinHaomaService.class); private final DmsCurrentIdentity identity = mock(DmsCurrentIdentity.class); private final DmsWenjianFenfaMapper tasks = mock(DmsWenjianFenfaMapper.class); private final DmsWenjianDayinQuerenMapper receipts = mock(DmsWenjianDayinQuerenMapper.class); private final DmsWenjianDayinTaizhangService ledger = mock(DmsWenjianDayinTaizhangService.class); private final DmsWenjianFenfaService distribution = mock(DmsWenjianFenfaService.class); private final DmsWenjianDayinQuerenService service = new DmsWenjianDayinQuerenService(identity, tasks, receipts, ledger, distribution, numbers); private final DmsWenjianDayinQuerenForm form = new DmsWenjianDayinQuerenForm(); private DmsWenjianDayinFasongEntity attempt; @BeforeEach void setup() throws Exception { UserInfo user = new UserInfo(); user.setUserId("user"); when(identity.requireUser()).thenReturn(user); when(identity.tenantId(user)).thenReturn("tenant"); form.setRequestId(UUID.randomUUID().toString()); form.setTaskId("task"); form.setFileVersionId("version"); form.setCopies(3); form.setClientResult("SUBMITTED"); DmsWenjianDayinRenwuEntity task = new DmsWenjianDayinRenwuEntity(); task.setDayinFenshu(3); when(tasks.selectPrintTaskForUpdate("tenant", "task")).thenReturn(task); when(ledger.list(any(), isNull(), eq("f_id"), eq("task"))).thenReturn(List.of(Map.of("f_id", "task"))); DmsWenjianDayinQuerenEntity version = new DmsWenjianDayinQuerenEntity(); version.setFileVersionId("version"); when(receipts.selectTaskVersion("tenant", "task")).thenReturn(version); when(distribution.printReserved(eq("task"), eq(3), anyList())).thenReturn(Collections.emptyList()); when(receipts.insertConfirmation(any())).thenReturn(1); attempt = new DmsWenjianDayinFasongEntity(); attempt.setId(form.getRequestId()); attempt.setTenantId("tenant"); attempt.setTaskId("task"); attempt.setFileVersionId("version"); attempt.setUserId("user"); attempt.setCopies(3); attempt.setState("OPEN"); attempt.setNumbersJson("[]"); attempt.setBatchesJson("[{\"id\":\"batch\",\"state\":\"SUBMITTED\"}]"); when(receipts.selectAttempt("tenant", form.getRequestId())).thenReturn(attempt); when(receipts.updateAttempt(any())).thenReturn(1); } @Test void missingOrUnknownAttemptCannotCreateRecords() { attempt.setNumbersJson("[]"); attempt.setBatchesJson("[{\"id\":\"batch\",\"state\":\"SENDING\"}]"); assertThrows(DataException.class, () -> service.confirm(form)); when(receipts.selectAttempt("tenant", form.getRequestId())).thenReturn(null); assertThrows(DataException.class, () -> service.confirm(form)); verifyNoInteractions(distribution); } @Test void onlySuccessfulClientResultMayWrite() { for (String result : Arrays.asList(null, "FAILED", "UNKNOWN", "SENDING")) { form.setClientResult(result); assertThrows(DataException.class, () -> service.confirm(form)); } verifyNoInteractions(distribution, tasks, receipts); } @Test void responseLossCanBeRetriedWithoutSecondPrint() throws Exception { service.confirm(form); ArgumentCaptor captor = ArgumentCaptor.forClass(DmsWenjianDayinQuerenEntity.class); verify(receipts).insertConfirmation(captor.capture()); when(receipts.selectConfirmation("tenant", form.getRequestId())).thenReturn(captor.getValue()); assertEquals(Collections.emptyList(), service.confirm(form)); verify(distribution, times(1)).printReserved(eq("task"), eq(3), anyList()); verify(receipts, times(1)).insertConfirmation(any()); verify(ledger, times(1)).list(any(), isNull(), eq("f_id"), eq("task")); } @Test void conflictingIdCannotReuseReceipt() throws Exception { service.confirm(form); ArgumentCaptor captor = ArgumentCaptor.forClass(DmsWenjianDayinQuerenEntity.class); verify(receipts).insertConfirmation(captor.capture()); when(receipts.selectConfirmation("tenant", form.getRequestId())).thenReturn(captor.getValue()); form.setCopies(2); assertThrows(DataException.class, () -> service.confirm(form)); verify(distribution, times(1)).printReserved(eq("task"), eq(3), anyList()); } @Test void partialConfirmationAcceptsRemainingAndRejectsExcess() throws Exception { when(tasks.countConsumedPrints("tenant", "task")).thenReturn(1); form.setCopies(3); assertThrows(DataException.class, () -> service.confirm(form)); form.setCopies(2); attempt.setCopies(2); service.confirm(form); verify(distribution).printReserved(eq("task"), eq(2), anyList()); } @Test void versionCopiesAndPermissionMustMatch() { form.setFileVersionId("wrong"); assertThrows(DataException.class, () -> service.confirm(form)); form.setFileVersionId("version"); form.setCopies(4); assertThrows(DataException.class, () -> service.confirm(form)); form.setCopies(3); when(ledger.list(any(), isNull(), eq("f_id"), eq("task"))).thenReturn(Collections.emptyList()); assertThrows(DataException.class, () -> service.confirm(form)); verifyNoInteractions(distribution); verify(receipts, never()).insertConfirmation(any()); } @Test void receiptFailurePropagatesForTransactionRollback() { when(receipts.insertConfirmation(any())).thenReturn(0); assertThrows(DataException.class, () -> service.confirm(form)); } }