From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master
---
jnpf-dms/jnpf-dms-biz/src/test/java/jnpf/dmsService/DmsFileRevisionServiceTest.java | 188 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 188 insertions(+), 0 deletions(-)
diff --git a/jnpf-dms/jnpf-dms-biz/src/test/java/jnpf/dmsService/DmsFileRevisionServiceTest.java b/jnpf-dms/jnpf-dms-biz/src/test/java/jnpf/dmsService/DmsFileRevisionServiceTest.java
new file mode 100644
index 0000000..54a3ee0
--- /dev/null
+++ b/jnpf-dms/jnpf-dms-biz/src/test/java/jnpf/dmsService/DmsFileRevisionServiceTest.java
@@ -0,0 +1,188 @@
+package jnpf.dmsService;
+
+import jnpf.base.UserInfo;
+import jnpf.dmsEntity.permission.entity.DmsDocumentEntity;
+import jnpf.dmsEntity.permission.entity.DmsFileVersionEntity;
+import jnpf.dmsEntity.permission.entity.DmsPermissionResourceEntity;
+import jnpf.dmsEntity.storage.entity.DmsFileObjectEntity;
+import jnpf.dmsEntity.storage.form.DmsFileRevisionRegisterForm;
+import jnpf.dmsEntity.storage.vo.DmsFileUploadVO;
+import jnpf.dmsIntegration.audit.DmsAuditAdapter;
+import jnpf.dmsMapper.DmsDocumentMapper;
+import jnpf.dmsMapper.DmsFileObjectMapper;
+import jnpf.dmsMapper.DmsFileVersionMapper;
+import jnpf.dmsMapper.DmsPermissionResourceMapper;
+import jnpf.dmsMapper.DmsVersionStateMapper;
+import jnpf.dmsPermission.DmsCurrentIdentity;
+import jnpf.dmsPermission.DmsPermissionException;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+
+import java.time.LocalDate;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class DmsFileRevisionServiceTest {
+
+ @Test
+ void createsNewVersionAndAtomicallySwitchesEffectiveState() {
+ Fixture fixture = new Fixture();
+ DmsFileRevisionRegisterForm form = fixture.form();
+ DmsFileUploadVO created = fixture.view(form);
+ when(fixture.fileObjectMapper.selectUploadBySource("tenant-1", "jnpf-file", "revision-1"))
+ .thenReturn(null, created);
+
+ DmsFileUploadVO result = fixture.service.register(form, "jnpf-file");
+
+ assertSame(created, result);
+ verify(fixture.fileObjectMapper).lockSource("tenant-1", "jnpf-file", "revision-1");
+ verify(fixture.decisionService).requireAllowed(any(), any(), any());
+ ArgumentCaptor<DmsFileVersionEntity> versionCaptor =
+ ArgumentCaptor.forClass(DmsFileVersionEntity.class);
+ verify(fixture.fileVersionMapper).insert(versionCaptor.capture());
+ assertEquals(2L, versionCaptor.getValue().getVersionNo());
+ assertEquals("D(01)", versionCaptor.getValue().getVersionLabel());
+ verify(fixture.resourceMapper).insert(any(DmsPermissionResourceEntity.class));
+ verify(fixture.fileObjectMapper).insert(any(DmsFileObjectEntity.class));
+ verify(fixture.versionStateMapper).supersedeCurrent("tenant-1", form.getDocumentId(),
+ form.getBaseFileVersionId(), "D(01)", "user-1");
+ verify(fixture.versionStateMapper).insertRevisionEffective("tenant-1", form.getDocumentId(),
+ form.getBaseFileVersionId(), form.getFileVersionId(), "revision-1",
+ "鏇存柊璐ㄩ噺鑱岃矗", "user-1");
+ }
+
+ @Test
+ void returnsExactIdempotentRetryWithoutWritingAgain() {
+ Fixture fixture = new Fixture();
+ DmsFileRevisionRegisterForm form = fixture.form();
+ DmsFileUploadVO existing = fixture.view(form);
+ when(fixture.fileObjectMapper.selectUploadBySource("tenant-1", "jnpf-file", "revision-1"))
+ .thenReturn(existing);
+
+ DmsFileUploadVO result = fixture.service.register(form, "jnpf-file");
+
+ assertSame(existing, result);
+ verify(fixture.documentMapper, never()).selectByTenantAndIdForUpdate(any(), any());
+ verify(fixture.fileVersionMapper, never()).insert(any(DmsFileVersionEntity.class));
+ verify(fixture.versionStateMapper, never()).supersedeCurrent(any(), any(), any(), any(), any());
+ }
+
+ @Test
+ void rejectsRetryWhenRevisionReasonChanges() {
+ Fixture fixture = new Fixture();
+ DmsFileRevisionRegisterForm form = fixture.form();
+ DmsFileUploadVO existing = fixture.view(form);
+ form.setRevisionReason("鍙︿竴涓師鍥�");
+ when(fixture.fileObjectMapper.selectUploadBySource("tenant-1", "jnpf-file", "revision-1"))
+ .thenReturn(existing);
+
+ assertThrows(DmsPermissionException.class,
+ () -> fixture.service.register(form, "jnpf-file"));
+
+ verify(fixture.fileVersionMapper, never()).insert(any(DmsFileVersionEntity.class));
+ }
+
+ @Test
+ void rejectsWhenSelectedVersionIsNoLongerCurrent() {
+ Fixture fixture = new Fixture();
+ DmsFileRevisionRegisterForm form = fixture.form();
+ DmsFileVersionEntity anotherCurrent = new DmsFileVersionEntity();
+ anotherCurrent.setId(UUID.fromString("018f0000-0000-7000-8000-000000000599"));
+ when(fixture.fileVersionMapper.selectCurrentEffective("tenant-1", form.getDocumentId()))
+ .thenReturn(anotherCurrent);
+
+ assertThrows(DmsPermissionException.class,
+ () -> fixture.service.register(form, "jnpf-file"));
+
+ verify(fixture.fileVersionMapper, never()).insert(any(DmsFileVersionEntity.class));
+ verify(fixture.versionStateMapper, never()).supersedeCurrent(any(), any(), any(), any(), any());
+ }
+
+ private static class Fixture {
+ private final DmsCurrentIdentity currentIdentity = mock(DmsCurrentIdentity.class);
+ private final DmsPermissionDecisionService decisionService = mock(DmsPermissionDecisionService.class);
+ private final DmsDocumentMapper documentMapper = mock(DmsDocumentMapper.class);
+ private final DmsFileVersionMapper fileVersionMapper = mock(DmsFileVersionMapper.class);
+ private final DmsPermissionResourceMapper resourceMapper = mock(DmsPermissionResourceMapper.class);
+ private final DmsFileObjectMapper fileObjectMapper = mock(DmsFileObjectMapper.class);
+ private final DmsVersionStateMapper versionStateMapper = mock(DmsVersionStateMapper.class);
+ private final DmsAuditAdapter auditAdapter = mock(DmsAuditAdapter.class);
+ private final DmsFileRevisionService service = new DmsFileRevisionService(currentIdentity,
+ decisionService, documentMapper, fileVersionMapper, resourceMapper, fileObjectMapper,
+ versionStateMapper, auditAdapter);
+ private final UUID documentId = UUID.fromString("018f0000-0000-7000-8000-000000000501");
+ private final UUID baseVersionId = UUID.fromString("018f0000-0000-7000-8000-000000000502");
+
+ private Fixture() {
+ UserInfo user = new UserInfo();
+ user.setUserId("user-1");
+ user.setTenantId("tenant-1");
+ when(currentIdentity.requireUser()).thenReturn(user);
+ when(currentIdentity.tenantId(user)).thenReturn("tenant-1");
+ DmsDocumentEntity document = new DmsDocumentEntity();
+ document.setId(documentId);
+ when(documentMapper.selectByTenantAndIdForUpdate("tenant-1", documentId))
+ .thenReturn(document);
+ DmsFileVersionEntity current = new DmsFileVersionEntity();
+ current.setId(baseVersionId);
+ when(fileVersionMapper.selectCurrentEffective("tenant-1", documentId)).thenReturn(current);
+ when(fileVersionMapper.selectNextVersionNo("tenant-1", documentId)).thenReturn(2L);
+ when(versionStateMapper.supersedeCurrent(any(), any(), any(), any(), any())).thenReturn(1);
+ }
+
+ private DmsFileRevisionRegisterForm form() {
+ DmsFileRevisionRegisterForm form = new DmsFileRevisionRegisterForm();
+ form.setDocumentId(documentId);
+ form.setBaseFileVersionId(baseVersionId);
+ form.setFileVersionId(UUID.fromString("018f0000-0000-7000-8000-000000000503"));
+ form.setFileObjectId(UUID.fromString("018f0000-0000-7000-8000-000000000504"));
+ form.setVersionLabel("D(01)");
+ form.setFileName("quality-manual-v2.docx");
+ form.setMimeType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
+ form.setSizeBytes(1024L);
+ form.setChecksumSha256("b".repeat(64));
+ form.setPreparedBy("author-1");
+ form.setPreparedOn(LocalDate.of(2026, 8, 22));
+ form.setRevisionReason("鏇存柊璐ㄩ噺鑱岃矗");
+ form.setStoragePlatform("seaweedfs-1");
+ form.setBucketName("jnpf-dms");
+ form.setBasePath("dms/");
+ form.setObjectPath("2026/08/22/document/");
+ form.setObjectName("version-v2.docx");
+ form.setSourceId("revision-1");
+ return form;
+ }
+
+ private DmsFileUploadVO view(DmsFileRevisionRegisterForm form) {
+ DmsFileUploadVO view = new DmsFileUploadVO();
+ view.setDocumentId(form.getDocumentId());
+ view.setBaseFileVersionId(form.getBaseFileVersionId());
+ view.setFileVersionId(form.getFileVersionId());
+ view.setFileObjectId(form.getFileObjectId());
+ view.setVersionNo(2L);
+ view.setVersionLabel(form.getVersionLabel());
+ view.setFileName(form.getFileName());
+ view.setMimeType(form.getMimeType());
+ view.setSizeBytes(form.getSizeBytes());
+ view.setChecksumSha256(form.getChecksumSha256());
+ view.setPreparedBy(form.getPreparedBy());
+ view.setPreparedOn(form.getPreparedOn());
+ view.setRevisionReason(form.getRevisionReason());
+ view.setStoragePlatform(form.getStoragePlatform());
+ view.setBucketName(form.getBucketName());
+ view.setBasePath(form.getBasePath());
+ view.setObjectPath(form.getObjectPath());
+ view.setObjectName(form.getObjectName());
+ view.setSourceId(form.getSourceId());
+ return view;
+ }
+ }
+}
--
Gitblit v1.8.0