package jnpf.fileStorage.dms;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import jnpf.base.ActionResult;
|
import jnpf.dms.DmsResourceApi;
|
import jnpf.dmsEntity.storage.approval.*;
|
import jnpf.dmsEntity.storage.form.*;
|
import jnpf.exception.DataException;
|
import org.junit.Test;
|
import org.mockito.ArgumentCaptor;
|
import org.springframework.web.multipart.MultipartFile;
|
import java.util.*;
|
import java.util.function.Function;
|
import static org.junit.Assert.*;
|
import static org.mockito.ArgumentMatchers.*;
|
import static org.mockito.Mockito.*;
|
|
public class DmsWorkflowFileCreateServiceTest {
|
DmsResourceApi api = mock(DmsResourceApi.class);
|
DmsFileStorageService storage = mock(DmsFileStorageService.class);
|
DmsCommonFileReader reader = mock(DmsCommonFileReader.class);
|
DmsApprovalPageMergeService approvalPages = mock(DmsApprovalPageMergeService.class);
|
DmsQianpiyeDocxWriter qianpiyeWriter = mock(DmsQianpiyeDocxWriter.class);
|
MultipartFile file = mock(MultipartFile.class);
|
MultipartFile approvalPage = mock(MultipartFile.class);
|
MultipartFile merged = mock(MultipartFile.class);
|
DmsWorkflowFileCreateService service = new DmsWorkflowFileCreateService(
|
api, storage, reader, approvalPages, qianpiyeWriter, new ObjectMapper());
|
DmsApprovedItem item(String key, String type) {
|
DmsApprovedItem i = new DmsApprovedItem(); i.setSourceKey(key); i.setChangeType(type); i.setDocumentName(key);
|
i.setFileJson("[{\"url\":\"/api/file/Image/annex/" + key + ".docx\"}]");
|
i.setDocumentId(UUID.randomUUID()); i.setFileVersionId(UUID.randomUUID()); return i;
|
}
|
DmsApprovedBatch batch(DmsApprovedItem... items) {
|
DmsApprovedBatch b = new DmsApprovedBatch(); b.setId(UUID.randomUUID()); b.setFlowId("flow"); b.setTaskId("task"); b.setAuditType("xinzeng_shenhe");
|
b.setSourceDigest("digest"); b.setItems(Arrays.asList(items)); b.setStatus("WAITING"); return b;
|
}
|
ActionResult<DmsApprovedBatch> success(DmsApprovedBatch batch) {
|
ActionResult<DmsApprovedBatch> r = new ActionResult<>(); r.setCode(200); r.setData(batch); return r;
|
}
|
@SuppressWarnings("unchecked") void storing() {
|
when(reader.withFile(any(), any(), any(), any())).thenAnswer(inv -> {
|
Function<MultipartFile, DmsFileUploadRegisterForm> operation = inv.getArgument(3); return operation.apply(file);
|
});
|
when(storage.storeWorkflowContent(any(), any(), eq(file))).thenAnswer(inv -> {
|
DmsFileUploadRegisterForm c = new DmsFileUploadRegisterForm(); c.setDocumentId(inv.getArgument(0));
|
c.setFileVersionId(inv.getArgument(1)); c.setFileObjectId(UUID.randomUUID()); return c;
|
});
|
}
|
@Test public void consumesDmsPushedSetAndCallsOnlyRegistrationAfterStoringAllChanges() {
|
DmsApprovedItem main = item("main", "REVISE"), record = item("record", "CREATE"), reuse = item("reuse", "REUSE");
|
DmsApprovedBatch b = batch(main, record, reuse); storing();
|
when(api.registerWorkflowUpload(eq("jnpf-file"), eq("sign"), any())).thenReturn(success(b));
|
assertSame(b, service.process(DmsApprovedRegistrationForm.from(b), "sign"));
|
ArgumentCaptor<DmsApprovedRegistrationCallback> callback = ArgumentCaptor.forClass(DmsApprovedRegistrationCallback.class);
|
org.mockito.InOrder order = inOrder(api, storage);
|
order.verify(storage).storeWorkflowContent(main.getDocumentId(), main.getFileVersionId(), file);
|
order.verify(storage).storeWorkflowContent(record.getDocumentId(), record.getFileVersionId(), file);
|
order.verify(api).registerWorkflowUpload(eq("jnpf-file"), eq("sign"), callback.capture());
|
assertEquals(b.getId(), callback.getValue().getBatchId());
|
assertEquals(2, callback.getValue().getFiles().size());
|
assertEquals("digest", callback.getValue().getSourceDigest());
|
verify(api, never()).prepareWorkflowFile(any(), any());
|
verify(api, never()).activateWorkflowFile(any(), any());
|
}
|
@Test public void secondStorageFailureNeverCallsRegistrationOrConfirmation() {
|
DmsApprovedBatch b = batch(item("main", "CREATE"), item("record", "CREATE")); storing();
|
when(storage.storeWorkflowContent(any(), any(), eq(file))).thenReturn(new DmsFileUploadRegisterForm()).thenThrow(new DataException("storage failed"));
|
assertThrows(DataException.class, () -> service.process(DmsApprovedRegistrationForm.from(b), null));
|
verifyNoInteractions(api);
|
}
|
@Test public void missingProgressIdentityCannotStartFileProcessing() {
|
DmsApprovedRegistrationForm command = DmsApprovedRegistrationForm.from(batch(item("main", "CREATE"))); command.setBatchId(null);
|
assertThrows(DataException.class, () -> service.process(command, null)); verifyNoInteractions(api, reader, storage);
|
}
|
@Test public void allReusedFilesStillConfirmTheBatchWithoutAnySourceRead() {
|
DmsApprovedBatch b = batch(item("main", "REUSE"));
|
when(api.registerWorkflowUpload(eq("jnpf-file"), isNull(), any())).thenReturn(success(b));
|
assertSame(b, service.process(DmsApprovedRegistrationForm.from(b), null)); verifyNoInteractions(reader, storage);
|
verify(api, never()).prepareWorkflowFile(any(), any());
|
}
|
@Test public void missingWrongOrIncompleteCallbackCannotReportSuccess() {
|
DmsApprovedBatch b = batch(item("main", "REUSE")); DmsApprovedRegistrationForm form = DmsApprovedRegistrationForm.from(b);
|
assertThrows(DataException.class, () -> service.process(form, null));
|
when(api.registerWorkflowUpload(eq("jnpf-file"), isNull(), any())).thenReturn(success(b));
|
b.setTaskId("other"); assertThrows(DataException.class, () -> service.process(form, null));
|
b.setTaskId("task"); b.setId(UUID.randomUUID()); assertThrows(DataException.class, () -> service.process(form, null));
|
}
|
@Test public void rejectsChoosingOnlyOneAttachmentFromMultipleFiles() {
|
assertThrows(DataException.class, () -> service.singleFileUrl("[{\"url\":\"a\"},{\"url\":\"b\"}]"));
|
assertEquals("a", service.singleFileUrl("[{\"url\":\"a\"}]"));
|
}
|
|
@Test public void prependsConfiguredApprovalPageBeforeStoringTheNewMainDocument() {
|
DmsApprovedItem main = item("main", "CREATE");
|
main.setApprovalPageFileJson("[{\"url\":\"/api/file/Image/annex/approval.pdf\"}]");
|
DmsApprovedBatch b = batch(main);
|
when(file.getOriginalFilename()).thenReturn("main.docx");
|
when(reader.withFile(any(), any(), any(), any())).thenAnswer(inv -> {
|
Function<MultipartFile, DmsFileUploadRegisterForm> operation = inv.getArgument(3);
|
return operation.apply(inv.<String>getArgument(0).contains("approval.pdf") ? approvalPage : file);
|
});
|
when(approvalPages.replaceOrPrepend(file, approvalPage)).thenReturn(merged);
|
when(storage.storeWorkflowContent(main.getDocumentId(), main.getFileVersionId(), merged))
|
.thenReturn(new DmsFileUploadRegisterForm());
|
when(api.registerWorkflowUpload(eq("jnpf-file"), isNull(), any())).thenReturn(success(b));
|
|
assertSame(b, service.process(DmsApprovedRegistrationForm.from(b), null));
|
|
verify(approvalPages).replaceOrPrepend(file, approvalPage);
|
verify(storage).storeWorkflowContent(main.getDocumentId(), main.getFileVersionId(), merged);
|
verify(storage, never()).storeWorkflowContent(main.getDocumentId(), main.getFileVersionId(), file);
|
}
|
|
@Test public void configuredApprovalPageDoesNotBlockImageRegistration() {
|
DmsApprovedItem main = item("PIC-SMP100-01000", "CREATE");
|
main.setApprovalPageFileJson("[{\"url\":\"/api/file/Image/annex/approval.docx\"}]");
|
DmsApprovedBatch b = batch(main);
|
when(file.getOriginalFilename()).thenReturn("图片测试PIC-SMP100-01000.png");
|
when(reader.withFile(any(), any(), any(), any())).thenAnswer(inv -> {
|
Function<MultipartFile, DmsFileUploadRegisterForm> operation = inv.getArgument(3);
|
return operation.apply(file);
|
});
|
when(storage.storeWorkflowContent(main.getDocumentId(), main.getFileVersionId(), file))
|
.thenReturn(new DmsFileUploadRegisterForm());
|
when(api.registerWorkflowUpload(eq("jnpf-file"), isNull(), any())).thenReturn(success(b));
|
|
assertSame(b, service.process(DmsApprovedRegistrationForm.from(b), null));
|
|
verify(reader, times(1)).withFile(any(), any(), any(), any());
|
verifyNoInteractions(approvalPages, qianpiyeWriter);
|
verify(storage).storeWorkflowContent(main.getDocumentId(), main.getFileVersionId(), file);
|
}
|
|
@Test public void originalDocxTagsAreRenderedWithoutAConfiguredApprovalPage() {
|
DmsApprovedItem main = item("main", "CREATE");
|
main.setApprovalValuesByTag(java.util.Map.of("dms.qianpiye.form.wenjian_bianhao", "DOC-001"));
|
main.setApprovalFlowVersionId("flow-version");
|
DmsApprovedBatch b = batch(main);
|
when(file.getOriginalFilename()).thenReturn("main.docx");
|
when(reader.withFile(any(), any(), any(), any())).thenAnswer(inv ->
|
inv.<Function<MultipartFile, DmsFileUploadRegisterForm>>getArgument(3).apply(file));
|
when(qianpiyeWriter.render(file, main.getApprovalValuesByTag(), "flow-version")).thenReturn(merged);
|
when(storage.storeWorkflowContent(main.getDocumentId(), main.getFileVersionId(), merged))
|
.thenReturn(new DmsFileUploadRegisterForm());
|
when(api.registerWorkflowUpload(eq("jnpf-file"), isNull(), any())).thenReturn(success(b));
|
|
assertSame(b, service.process(DmsApprovedRegistrationForm.from(b), null));
|
|
verify(qianpiyeWriter).render(file, main.getApprovalValuesByTag(), "flow-version");
|
verifyNoInteractions(approvalPages);
|
verify(storage).storeWorkflowContent(main.getDocumentId(), main.getFileVersionId(), merged);
|
verify(reader, times(1)).withFile(any(), any(), any(), any());
|
}
|
|
@Test public void configuredApprovalPageReadFailureNeverStoresTheOriginalOrCallsBackDms() {
|
DmsApprovedItem main = item("main", "CREATE");
|
main.setApprovalPageFileJson("[{\"url\":\"/api/file/Image/annex/missing.pdf\"}]");
|
DmsApprovedRegistrationForm form = DmsApprovedRegistrationForm.from(batch(main));
|
when(file.getOriginalFilename()).thenReturn("main.docx");
|
when(reader.withFile(any(), any(), any(), any())).thenAnswer(inv -> {
|
String url = inv.getArgument(0);
|
if (url.contains("missing.pdf")) throw new DataException("file-common文件不存在");
|
Function<MultipartFile, DmsFileUploadRegisterForm> operation = inv.getArgument(3);
|
return operation.apply(file);
|
});
|
|
assertThrows(DataException.class, () -> service.process(form, null));
|
|
verify(approvalPages, never()).replaceOrPrepend(any(), any());
|
verifyNoInteractions(storage, api);
|
}
|
|
@Test public void taggedRevisionReplacesTheExistingApprovalPage() {
|
DmsApprovedItem main = item("main", "REVISE");
|
main.setApprovalPageFileJson("[{\"url\":\"/api/file/Image/annex/approval.docx\"}]");
|
DmsApprovedBatch b = batch(main);
|
when(file.getOriginalFilename()).thenReturn("main.docx");
|
when(approvalPage.getOriginalFilename()).thenReturn("approval.docx");
|
when(reader.withFile(any(), any(), any(), any())).thenAnswer(inv -> {
|
Function<MultipartFile, DmsFileUploadRegisterForm> operation = inv.getArgument(3);
|
return operation.apply(inv.<String>getArgument(0).contains("approval.docx") ? approvalPage : file);
|
});
|
main.setApprovalValuesByTag(Collections.singletonMap(
|
"dms.qianpiye.flow.approve-1.approver", "张三"));
|
main.setApprovalFlowVersionId("flow-version");
|
when(qianpiyeWriter.render(approvalPage, main.getApprovalValuesByTag(),
|
main.getApprovalFlowVersionId())).thenReturn(merged);
|
when(approvalPages.withoutApprovalPages(file)).thenReturn(file);
|
when(qianpiyeWriter.render(file, main.getApprovalValuesByTag(),
|
main.getApprovalFlowVersionId())).thenReturn(file);
|
when(approvalPages.replaceOrPrepend(file, merged)).thenReturn(merged);
|
when(storage.storeWorkflowContent(main.getDocumentId(), main.getFileVersionId(), merged))
|
.thenReturn(new DmsFileUploadRegisterForm());
|
when(api.registerWorkflowUpload(eq("jnpf-file"), isNull(), any())).thenReturn(success(b));
|
|
assertSame(b, service.process(DmsApprovedRegistrationForm.from(b), null));
|
|
verify(qianpiyeWriter).render(approvalPage, main.getApprovalValuesByTag(),
|
main.getApprovalFlowVersionId());
|
verify(qianpiyeWriter).render(file, main.getApprovalValuesByTag(),
|
main.getApprovalFlowVersionId());
|
verify(approvalPages).replaceOrPrepend(file, merged);
|
verify(storage).storeWorkflowContent(main.getDocumentId(), main.getFileVersionId(), merged);
|
verify(reader, times(2)).withFile(any(), any(), any(), any());
|
}
|
}
|