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.DmsFileUploadRegisterForm;
|
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 DmsFileUploadServiceTest {
|
|
@Test
|
void registersDocumentVersionResourcesAndObjectInOneServiceCall() {
|
Fixture fixture = new Fixture();
|
DmsFileUploadRegisterForm form = fixture.form();
|
DmsFileUploadVO created = fixture.view(form);
|
when(fixture.fileObjectMapper.selectUploadBySource("tenant-1", "jnpf-file", "source-1"))
|
.thenReturn(null, created);
|
|
DmsFileUploadVO result = fixture.service.register(form, "jnpf-file");
|
|
assertSame(created, result);
|
verify(fixture.decisionService).requireAllowed(any(), any(), any());
|
ArgumentCaptor<DmsDocumentEntity> documentCaptor = ArgumentCaptor.forClass(DmsDocumentEntity.class);
|
verify(fixture.documentMapper).insert(documentCaptor.capture());
|
assertEquals("MM-R02", documentCaptor.getValue().getDocumentNo());
|
assertEquals("QUALITY_MANUAL", documentCaptor.getValue().getDocumentType());
|
assertEquals("dept-quality", documentCaptor.getValue().getResponsibleDeptId());
|
|
ArgumentCaptor<DmsFileVersionEntity> versionCaptor = ArgumentCaptor.forClass(DmsFileVersionEntity.class);
|
verify(fixture.fileVersionMapper).insert(versionCaptor.capture());
|
assertEquals("D(00)", versionCaptor.getValue().getVersionLabel());
|
assertEquals("author-1", versionCaptor.getValue().getPreparedBy());
|
assertEquals(LocalDate.of(2026, 8, 21), versionCaptor.getValue().getPreparedOn());
|
verify(fixture.resourceMapper, org.mockito.Mockito.times(2)).insert(any(DmsPermissionResourceEntity.class));
|
verify(fixture.versionStateMapper).insertDirectEffective("tenant-1", form.getDocumentId(),
|
form.getFileVersionId(), "user-1");
|
verify(fixture.fileObjectMapper).insert(any(DmsFileObjectEntity.class));
|
}
|
|
@Test
|
void returnsExistingUploadWithoutDuplicateWrites() {
|
Fixture fixture = new Fixture();
|
DmsFileUploadRegisterForm form = fixture.form();
|
DmsFileUploadVO existing = fixture.view(form);
|
when(fixture.fileObjectMapper.selectUploadBySource("tenant-1", "jnpf-file", "source-1"))
|
.thenReturn(existing);
|
|
DmsFileUploadVO result = fixture.service.register(form, "jnpf-file");
|
|
assertSame(existing, result);
|
verify(fixture.documentMapper, never()).insert(any(DmsDocumentEntity.class));
|
verify(fixture.fileVersionMapper, never()).insert(any(DmsFileVersionEntity.class));
|
verify(fixture.versionStateMapper, never()).insertDirectEffective(any(), any(), any(), any());
|
verify(fixture.fileObjectMapper, never()).insert(any(DmsFileObjectEntity.class));
|
}
|
|
@Test
|
void rejectsIdempotentRetryWhenDocumentNumberChanges() {
|
Fixture fixture = new Fixture();
|
DmsFileUploadRegisterForm form = fixture.form();
|
DmsFileUploadVO existing = fixture.view(form);
|
form.setDocumentNo("MM-R03");
|
when(fixture.fileObjectMapper.selectUploadBySource("tenant-1", "jnpf-file", "source-1"))
|
.thenReturn(existing);
|
|
assertThrows(DmsPermissionException.class,
|
() -> fixture.service.register(form, "jnpf-file"));
|
|
verify(fixture.documentMapper, never()).insert(any(DmsDocumentEntity.class));
|
verify(fixture.fileVersionMapper, never()).insert(any(DmsFileVersionEntity.class));
|
verify(fixture.versionStateMapper, never()).insertDirectEffective(any(), any(), any(), any());
|
verify(fixture.fileObjectMapper, never()).insert(any(DmsFileObjectEntity.class));
|
}
|
|
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 DmsFileUploadService service = new DmsFileUploadService(currentIdentity, decisionService,
|
documentMapper, fileVersionMapper, resourceMapper, fileObjectMapper, versionStateMapper,
|
auditAdapter);
|
|
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");
|
}
|
|
private DmsFileUploadRegisterForm form() {
|
DmsFileUploadRegisterForm form = new DmsFileUploadRegisterForm();
|
form.setDocumentId(UUID.fromString("018f0000-0000-7000-8000-000000000301"));
|
form.setFileVersionId(UUID.fromString("018f0000-0000-7000-8000-000000000302"));
|
form.setFileObjectId(UUID.fromString("018f0000-0000-7000-8000-000000000303"));
|
form.setFolderId(UUID.fromString("018f0000-0000-7000-8000-000000000304"));
|
form.setDocumentNo("MM-R02");
|
form.setDocumentName("质量手册");
|
form.setDocumentType("QUALITY_MANUAL");
|
form.setResponsibleDeptId("dept-quality");
|
form.setVersionLabel("D(00)");
|
form.setFileName("report.txt");
|
form.setMimeType("text/plain");
|
form.setSizeBytes(12L);
|
form.setChecksumSha256("a".repeat(64));
|
form.setPreparedBy("author-1");
|
form.setPreparedOn(LocalDate.of(2026, 8, 21));
|
form.setStoragePlatform("seaweedfs-1");
|
form.setBucketName("jnpf-dms");
|
form.setBasePath("dms/");
|
form.setObjectPath("2026/08/17/document/");
|
form.setObjectName("version.txt");
|
form.setSourceId("source-1");
|
return form;
|
}
|
|
private DmsFileUploadVO view(DmsFileUploadRegisterForm form) {
|
DmsFileUploadVO view = new DmsFileUploadVO();
|
view.setDocumentId(form.getDocumentId());
|
view.setFileVersionId(form.getFileVersionId());
|
view.setFileObjectId(form.getFileObjectId());
|
view.setFolderId(form.getFolderId());
|
view.setDocumentNo(form.getDocumentNo());
|
view.setDocumentName(form.getDocumentName());
|
view.setDocumentType(form.getDocumentType());
|
view.setResponsibleDeptId(form.getResponsibleDeptId());
|
view.setVersionNo(1L);
|
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.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;
|
}
|
}
|
}
|