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/DmsPermissionGrantServiceTest.java |  138 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 138 insertions(+), 0 deletions(-)

diff --git a/jnpf-dms/jnpf-dms-biz/src/test/java/jnpf/dmsService/DmsPermissionGrantServiceTest.java b/jnpf-dms/jnpf-dms-biz/src/test/java/jnpf/dmsService/DmsPermissionGrantServiceTest.java
new file mode 100644
index 0000000..8594935
--- /dev/null
+++ b/jnpf-dms/jnpf-dms-biz/src/test/java/jnpf/dmsService/DmsPermissionGrantServiceTest.java
@@ -0,0 +1,138 @@
+package jnpf.dmsService;
+
+import jnpf.dmsEntity.permission.entity.DmsFilePermissionEntity;
+import jnpf.dmsIntegration.audit.DmsAuditAdapter;
+import jnpf.dmsMapper.DmsFilePermissionMapper;
+import jnpf.dmsMapper.DmsPermissionResourceMapper;
+import jnpf.dmsPermission.DmsCurrentIdentity;
+import jnpf.dmsPermission.DmsPermissionError;
+import jnpf.dmsPermission.DmsPermissionException;
+import jnpf.dmsPermission.DmsPermissionProperties;
+import jnpf.dmsPermission.DmsPrincipalValidator;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+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 DmsPermissionGrantServiceTest {
+    private static final String TENANT_ID = "tenant-1";
+    private static final String CREATOR_ID = "user-1";
+    private static final UUID FOLDER_ID = UUID.fromString("018f0000-0000-7000-8000-000000000402");
+    private static final UUID PERMISSION_ID = UUID.fromString("018f0000-0000-7000-8000-000000000403");
+    private static final String SOURCE_ID = "folder-creator-create:" + FOLDER_ID;
+    private static final String GRANT_REASON = "鐩綍鍒涘缓鑰呴粯璁� CREATE 鏉冮檺";
+
+    @Test
+    void grantsSelfCreatePermissionToFolderCreator() {
+        Fixture fixture = new Fixture();
+        when(fixture.permissionMapper.selectBySource(TENANT_ID, "SYSTEM", SOURCE_ID))
+                .thenReturn(Collections.emptyList());
+        when(fixture.permissionMapper.insertReturning(any(DmsFilePermissionEntity.class)))
+                .thenAnswer(invocation -> {
+                    DmsFilePermissionEntity entity = invocation.getArgument(0);
+                    entity.setId(PERMISSION_ID);
+                    return entity;
+                });
+
+        DmsFilePermissionEntity result = fixture.service.ensureFolderCreatorCreatePermission(
+                TENANT_ID, FOLDER_ID, CREATOR_ID);
+
+        assertEquals(PERMISSION_ID, result.getId());
+        verify(fixture.permissionMapper).lockSource(TENANT_ID, "SYSTEM", SOURCE_ID);
+        ArgumentCaptor<DmsFilePermissionEntity> captor = ArgumentCaptor.forClass(DmsFilePermissionEntity.class);
+        verify(fixture.permissionMapper).insertReturning(captor.capture());
+        DmsFilePermissionEntity permission = captor.getValue();
+        assertEquals(TENANT_ID, permission.getTenantId());
+        assertEquals("FOLDER", permission.getResourceType());
+        assertEquals(FOLDER_ID, permission.getResourceId());
+        assertEquals("SELF", permission.getResourceScope());
+        assertEquals("USER", permission.getPrincipalType());
+        assertEquals(CREATOR_ID, permission.getPrincipalId());
+        assertEquals(Boolean.FALSE, permission.getIncludeChildOrgs());
+        assertEquals("CREATE", permission.getActionCode());
+        assertEquals("SYSTEM", permission.getSourceType());
+        assertEquals(SOURCE_ID, permission.getSourceId());
+        assertNotNull(permission.getValidFrom());
+        assertEquals(GRANT_REASON, permission.getGrantReason());
+        assertEquals("USER", permission.getGrantedByType());
+        assertEquals(CREATOR_ID, permission.getGrantedById());
+        verify(fixture.currentIdentity, never()).requirePermissionAdministrator();
+        verify(fixture.principalValidator, never()).validate(any());
+        verify(fixture.auditAdapter).dataChange("CREATE", "鍒涘缓 DMS 鐩綍鍒涘缓鑰呴粯璁ゆ潈闄�",
+                "dms_file_permissions", PERMISSION_ID.toString(), GRANT_REASON, null);
+    }
+
+    @Test
+    void keepsRevokedPermissionRevokedOnIdempotentRetry() {
+        Fixture fixture = new Fixture();
+        DmsFilePermissionEntity existing = matchingPermission();
+        existing.setRevokedAt(new Date());
+        when(fixture.permissionMapper.selectBySource(TENANT_ID, "SYSTEM", SOURCE_ID))
+                .thenReturn(Collections.singletonList(existing));
+
+        DmsFilePermissionEntity result = fixture.service.ensureFolderCreatorCreatePermission(
+                TENANT_ID, FOLDER_ID, CREATOR_ID);
+
+        assertSame(existing, result);
+        verify(fixture.permissionMapper, never()).insertReturning(any(DmsFilePermissionEntity.class));
+        verify(fixture.auditAdapter, never()).dataChange(any(), any(), any(), any(), any(), any());
+    }
+
+    @Test
+    void rejectsMismatchedPermissionUsingSameSource() {
+        Fixture fixture = new Fixture();
+        DmsFilePermissionEntity existing = matchingPermission();
+        existing.setActionCode("READ");
+        when(fixture.permissionMapper.selectBySource(TENANT_ID, "SYSTEM", SOURCE_ID))
+                .thenReturn(Collections.singletonList(existing));
+
+        DmsPermissionException exception = assertThrows(DmsPermissionException.class,
+                () -> fixture.service.ensureFolderCreatorCreatePermission(TENANT_ID, FOLDER_ID, CREATOR_ID));
+
+        assertEquals(DmsPermissionError.SOURCE_CONFLICT, exception.getError());
+        verify(fixture.permissionMapper, never()).insertReturning(any(DmsFilePermissionEntity.class));
+    }
+
+    private static DmsFilePermissionEntity matchingPermission() {
+        DmsFilePermissionEntity permission = new DmsFilePermissionEntity();
+        permission.setId(PERMISSION_ID);
+        permission.setTenantId(TENANT_ID);
+        permission.setResourceType("FOLDER");
+        permission.setResourceId(FOLDER_ID);
+        permission.setResourceScope("SELF");
+        permission.setPrincipalType("USER");
+        permission.setPrincipalId(CREATOR_ID);
+        permission.setIncludeChildOrgs(false);
+        permission.setActionCode("CREATE");
+        permission.setSourceType("SYSTEM");
+        permission.setSourceId(SOURCE_ID);
+        permission.setValidFrom(new Date());
+        permission.setGrantReason(GRANT_REASON);
+        permission.setGrantedByType("USER");
+        permission.setGrantedById(CREATOR_ID);
+        return permission;
+    }
+
+    private static class Fixture {
+        private final DmsCurrentIdentity currentIdentity = mock(DmsCurrentIdentity.class);
+        private final DmsPermissionProperties properties = new DmsPermissionProperties();
+        private final DmsPrincipalValidator principalValidator = mock(DmsPrincipalValidator.class);
+        private final DmsPermissionResourceMapper resourceMapper = mock(DmsPermissionResourceMapper.class);
+        private final DmsFilePermissionMapper permissionMapper = mock(DmsFilePermissionMapper.class);
+        private final DmsAuditAdapter auditAdapter = mock(DmsAuditAdapter.class);
+        private final DmsPermissionGrantService service = new DmsPermissionGrantService(
+                currentIdentity, properties, principalValidator, resourceMapper, permissionMapper, auditAdapter);
+    }
+}

--
Gitblit v1.8.0