package jnpf.dmsService;
|
|
import jnpf.dmsEntity.permission.entity.DmsFilePermissionEntity;
|
import jnpf.dmsEntity.permission.enums.DmsResourceType;
|
import jnpf.dmsEntity.permission.model.DmsResourcePath;
|
import jnpf.dmsEntity.permission.vo.DmsCursorPageVO;
|
import jnpf.dmsEntity.permission.vo.DmsPermissionGrantVO;
|
import jnpf.dmsMapper.DmsFilePermissionMapper;
|
import jnpf.dmsMapper.DmsPermissionGroupMapper;
|
import jnpf.dmsMapper.DmsPermissionUsageMapper;
|
import jnpf.dmsPermission.DmsCurrentIdentity;
|
import jnpf.dmsPermission.DmsCursorCodec;
|
import jnpf.dmsPermission.DmsPermissionMatcher;
|
import jnpf.dmsPermission.DmsPermissionProperties;
|
import jnpf.dmsPermission.DmsResourceResolver;
|
import jnpf.dmsPermission.DmsUserDisplayNameResolver;
|
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.provider.EnumSource;
|
import jnpf.dmsEntity.permission.enums.DmsPrincipalType;
|
import jnpf.permission.PositionApi;
|
import jnpf.permission.RoleApi;
|
import jnpf.permission.entity.PositionEntity;
|
import jnpf.permission.entity.RoleEntity;
|
import jnpf.permission.entity.PermissionGroupEntity;
|
import java.util.ArrayList;
|
import java.util.function.Function;
|
import jnpf.permission.OrganizeApi;
|
import jnpf.permission.entity.OrganizeEntity;
|
|
import java.util.Arrays;
|
import java.util.Collections;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.UUID;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.mockito.Mockito.verifyNoInteractions;
|
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.when;
|
|
class DmsPermissionAdminQueryServiceTest {
|
private static final String TENANT_ID = "tenant-1";
|
private static final String USER_ID = "user-1";
|
|
@Test
|
void enrichesGrantPageUserNames() {
|
Fixture fixture = new Fixture();
|
DmsFilePermissionEntity permission = permission(UUID.randomUUID());
|
when(fixture.permissionMapper.selectPage(TENANT_ID, null, null, null, null, null, 11))
|
.thenReturn(Collections.singletonList(permission));
|
when(fixture.grantService.toVO(permission)).thenReturn(toVO(permission));
|
when(fixture.userDisplayNameResolver.resolve(any()))
|
.thenReturn(Collections.singletonMap(USER_ID, "运营用户(yunying1)"));
|
|
DmsCursorPageVO<DmsPermissionGrantVO> result = fixture.service.grants(
|
null, null, null, null, 10);
|
|
assertEquals(1, result.getList().size());
|
assertEquals("运营用户(yunying1)", result.getList().get(0).getPrincipalName());
|
verify(fixture.userDisplayNameResolver).resolve(any());
|
verifyNoInteractions(fixture.organizeApi, fixture.positionApi, fixture.roleApi, fixture.permissionGroupMapper);
|
}
|
|
@Test
|
void enrichesGrantDetailUserName() {
|
Fixture fixture = new Fixture();
|
DmsFilePermissionEntity permission = permission(UUID.randomUUID());
|
when(fixture.permissionMapper.selectByTenantAndId(TENANT_ID, permission.getId()))
|
.thenReturn(permission);
|
when(fixture.grantService.toVO(permission)).thenReturn(toVO(permission));
|
when(fixture.userDisplayNameResolver.resolve(any()))
|
.thenReturn(Collections.singletonMap(USER_ID, "运营用户(yunying1)"));
|
|
DmsPermissionGrantVO result = fixture.service.grant(permission.getId());
|
|
assertEquals("运营用户(yunying1)", result.getPrincipalName());
|
verify(fixture.userDisplayNameResolver).resolve(any());
|
verifyNoInteractions(fixture.organizeApi, fixture.positionApi, fixture.roleApi, fixture.permissionGroupMapper);
|
}
|
|
@Test
|
void enrichesDirectAndInheritedUserGrantsWithOneResolverCall() {
|
Fixture fixture = new Fixture();
|
UUID selectedResourceId = UUID.randomUUID();
|
UUID ancestorResourceId = UUID.randomUUID();
|
DmsResourcePath path = new DmsResourcePath();
|
path.setActualResourceId(selectedResourceId);
|
path.setActualResourceType("FOLDER");
|
List<UUID> candidateIds = Arrays.asList(selectedResourceId, ancestorResourceId);
|
DmsFilePermissionEntity direct = permission(selectedResourceId);
|
DmsFilePermissionEntity inherited = permission(ancestorResourceId);
|
when(fixture.resourceResolver.resolve(TENANT_ID, DmsResourceType.FOLDER, selectedResourceId))
|
.thenReturn(path);
|
when(fixture.resourceResolver.candidateResourceIds(path)).thenReturn(candidateIds);
|
when(fixture.permissionMapper.selectForResourceIds(TENANT_ID, candidateIds, 1000))
|
.thenReturn(Arrays.asList(direct, inherited));
|
when(fixture.matcher.coversResource(any(), any())).thenReturn(true);
|
when(fixture.grantService.toVO(any())).thenAnswer(invocation -> toVO(invocation.getArgument(0)));
|
when(fixture.userDisplayNameResolver.resolve(any()))
|
.thenReturn(Collections.singletonMap(USER_ID, "运营用户(yunying1)"));
|
|
List<DmsPermissionGrantVO> result = fixture.service.resourceGrants(
|
DmsResourceType.FOLDER, selectedResourceId);
|
|
assertEquals(2, result.size());
|
assertFalse(result.get(0).isInherited());
|
assertTrue(result.get(1).isInherited());
|
assertEquals("运营用户(yunying1)", result.get(0).getPrincipalName());
|
assertEquals("运营用户(yunying1)", result.get(1).getPrincipalName());
|
verify(fixture.userDisplayNameResolver).resolve(any());
|
verifyNoInteractions(fixture.organizeApi, fixture.positionApi, fixture.roleApi, fixture.permissionGroupMapper);
|
}
|
|
@Test
|
void enrichesOrganizationPageAndDetail() {
|
Fixture fixture = new Fixture();
|
DmsFilePermissionEntity permission = organizationPermission(UUID.randomUUID());
|
when(fixture.permissionMapper.selectPage(TENANT_ID, null, null, null, null, null, 11))
|
.thenReturn(Collections.singletonList(permission));
|
when(fixture.permissionMapper.selectByTenantAndId(TENANT_ID, permission.getId())).thenReturn(permission);
|
when(fixture.grantService.toVO(permission)).thenAnswer(invocation -> toVO(permission));
|
when(fixture.organizeApi.getListByIds(Collections.singletonList("org-1")))
|
.thenReturn(Collections.singletonList(organization("org-1", "质量部")));
|
|
assertEquals("质量部", fixture.service.grants(null, null, null, null, 10)
|
.getList().get(0).getPrincipalName());
|
assertEquals("质量部", fixture.service.grant(permission.getId()).getPrincipalName());
|
}
|
|
@Test
|
void batchesDirectAndInheritedOrganizationsWithoutOverwritingUserWithSameId() {
|
Fixture fixture = new Fixture();
|
UUID selectedId = UUID.randomUUID();
|
UUID parentId = UUID.randomUUID();
|
DmsResourcePath path = new DmsResourcePath();
|
List<UUID> resourceIds = Arrays.asList(selectedId, parentId);
|
DmsFilePermissionEntity user = permission(selectedId);
|
user.setPrincipalId("org-1");
|
when(fixture.resourceResolver.resolve(TENANT_ID, DmsResourceType.FOLDER, selectedId)).thenReturn(path);
|
when(fixture.resourceResolver.candidateResourceIds(path)).thenReturn(resourceIds);
|
when(fixture.permissionMapper.selectForResourceIds(TENANT_ID, resourceIds, 1000))
|
.thenReturn(Arrays.asList(organizationPermission(selectedId), organizationPermission(parentId), user));
|
when(fixture.matcher.coversResource(any(), any())).thenReturn(true);
|
when(fixture.grantService.toVO(any())).thenAnswer(invocation -> toVO(invocation.getArgument(0)));
|
when(fixture.organizeApi.getListByIds(Collections.singletonList("org-1")))
|
.thenReturn(Collections.singletonList(organization("org-1", "质量部")));
|
when(fixture.userDisplayNameResolver.resolve(any())).thenReturn(Collections.singletonMap("org-1", "测试用户"));
|
|
List<DmsPermissionGrantVO> result = fixture.service.resourceGrants(DmsResourceType.FOLDER, selectedId);
|
assertEquals("质量部", result.get(0).getPrincipalName());
|
assertEquals("质量部", result.get(1).getPrincipalName());
|
assertFalse(result.get(0).isInherited());
|
assertTrue(result.get(1).isInherited());
|
assertEquals("测试用户", result.get(2).getPrincipalName());
|
verify(fixture.organizeApi).getListByIds(Collections.singletonList("org-1"));
|
}
|
|
@Test
|
void preservesOrganizationIdWhenLookupMissingOrUnavailable() {
|
Fixture fixture = new Fixture();
|
DmsFilePermissionEntity permission = organizationPermission(UUID.randomUUID());
|
when(fixture.permissionMapper.selectByTenantAndId(TENANT_ID, permission.getId())).thenReturn(permission);
|
when(fixture.grantService.toVO(permission)).thenAnswer(invocation -> toVO(permission));
|
when(fixture.organizeApi.getListByIds(Collections.singletonList("org-1")))
|
.thenReturn(Collections.emptyList())
|
.thenReturn(null)
|
.thenReturn(Arrays.asList(null, organization("org-1", " ")))
|
.thenThrow(new IllegalStateException("organization service unavailable"));
|
|
for (int i = 0; i < 4; i++) {
|
DmsPermissionGrantVO result = fixture.service.grant(permission.getId());
|
assertNull(result.getPrincipalName());
|
assertEquals("org-1", result.getPrincipalId());
|
}
|
}
|
|
@ParameterizedTest
|
@EnumSource(value = DmsPrincipalType.class, names = "USER", mode = EnumSource.Mode.EXCLUDE)
|
void enrichesEveryNonUserTypeInPageDetailAndInheritedList(DmsPrincipalType type) {
|
Fixture fixture = new Fixture();
|
UUID selectedId = UUID.randomUUID();
|
UUID parentId = UUID.randomUUID();
|
DmsFilePermissionEntity direct = principalPermission(type, selectedId);
|
DmsFilePermissionEntity inherited = principalPermission(type, parentId);
|
List<DmsFilePermissionEntity> rows = Arrays.asList(direct, inherited);
|
when(fixture.grantService.toVO(any())).thenAnswer(invocation -> toVO(invocation.getArgument(0)));
|
when(fixture.permissionMapper.selectPage(TENANT_ID, null, null, null, null, null, 11)).thenReturn(rows);
|
when(fixture.permissionMapper.selectByTenantAndId(TENANT_ID, direct.getId())).thenReturn(direct);
|
DmsResourcePath path = new DmsResourcePath();
|
when(fixture.resourceResolver.resolve(TENANT_ID, DmsResourceType.FOLDER, selectedId)).thenReturn(path);
|
when(fixture.resourceResolver.candidateResourceIds(path)).thenReturn(Arrays.asList(selectedId, parentId));
|
when(fixture.permissionMapper.selectForResourceIds(TENANT_ID, Arrays.asList(selectedId, parentId), 1000)).thenReturn(rows);
|
when(fixture.matcher.coversResource(any(), any())).thenReturn(true);
|
when(lookup(fixture, type).apply(Collections.singletonList("shared-id")))
|
.thenAnswer(invocation -> Collections.singletonList(namedPrincipal(type, " " + type.name() + "名称 ")));
|
|
assertEquals(type.name() + "名称", fixture.service.grants(null, null, null, null, 10).getList().get(0).getPrincipalName());
|
assertEquals(type.name() + "名称", fixture.service.grant(direct.getId()).getPrincipalName());
|
List<DmsPermissionGrantVO> result = fixture.service.resourceGrants(DmsResourceType.FOLDER, selectedId);
|
assertEquals(type.name() + "名称", result.get(0).getPrincipalName());
|
assertEquals(type.name() + "名称", result.get(1).getPrincipalName());
|
assertFalse(result.get(0).isInherited());
|
assertTrue(result.get(1).isInherited());
|
}
|
|
@ParameterizedTest
|
@EnumSource(value = DmsPrincipalType.class, names = "USER", mode = EnumSource.Mode.EXCLUDE)
|
void missingAndFailedLookupKeepIdsAndOtherTypesAvailable(DmsPrincipalType type) {
|
Fixture fixture = new Fixture();
|
List<DmsFilePermissionEntity> rows = new ArrayList<>();
|
for (DmsPrincipalType principalType : DmsPrincipalType.values()) {
|
rows.add(principalPermission(principalType, UUID.randomUUID()));
|
if (principalType != DmsPrincipalType.USER) {
|
when(lookup(fixture, principalType).apply(Collections.singletonList("shared-id")))
|
.thenAnswer(invocation -> Collections.singletonList(namedPrincipal(principalType, principalType.name())));
|
}
|
}
|
when(fixture.userDisplayNameResolver.resolve(any())).thenReturn(Collections.singletonMap("shared-id", "USER"));
|
when(fixture.grantService.toVO(any())).thenAnswer(invocation -> toVO(invocation.getArgument(0)));
|
when(fixture.permissionMapper.selectPage(TENANT_ID, null, null, null, null, null, 11)).thenReturn(rows);
|
when(lookup(fixture, type).apply(Collections.singletonList("shared-id")))
|
.thenAnswer(invocation -> Collections.emptyList())
|
.thenAnswer(invocation -> null)
|
.thenAnswer(invocation -> Arrays.asList(null, namedPrincipal(type, " ")))
|
.thenThrow(new IllegalStateException("principal lookup unavailable"));
|
for (int i = 0; i < 4; i++) {
|
List<DmsPermissionGrantVO> result = fixture.service.grants(null, null, null, null, 10).getList();
|
assertEquals(DmsPrincipalType.values().length, result.size());
|
for (DmsPermissionGrantVO grant : result) {
|
assertEquals("shared-id", grant.getPrincipalId());
|
if (type.name().equals(grant.getPrincipalType())) {
|
assertNull(grant.getPrincipalName());
|
} else {
|
assertEquals(grant.getPrincipalType(), grant.getPrincipalName());
|
}
|
}
|
}
|
}
|
|
@Test
|
void batchesAndIsolatesAllFiveTypesWithSameId() {
|
Fixture fixture = new Fixture();
|
List<DmsFilePermissionEntity> rows = new ArrayList<>();
|
for (DmsPrincipalType type : DmsPrincipalType.values()) {
|
rows.add(principalPermission(type, UUID.randomUUID()));
|
rows.add(principalPermission(type, UUID.randomUUID()));
|
if (type != DmsPrincipalType.USER) {
|
when(lookup(fixture, type).apply(Collections.singletonList("shared-id")))
|
.thenAnswer(invocation -> Collections.singletonList(namedPrincipal(type, type.name())));
|
}
|
}
|
when(fixture.userDisplayNameResolver.resolve(any())).thenReturn(Collections.singletonMap("shared-id", "USER"));
|
when(fixture.grantService.toVO(any())).thenAnswer(invocation -> toVO(invocation.getArgument(0)));
|
when(fixture.permissionMapper.selectPage(TENANT_ID, null, null, null, null, null, 11)).thenReturn(rows);
|
List<DmsPermissionGrantVO> result = fixture.service.grants(null, null, null, null, 10).getList();
|
assertEquals(10, result.size());
|
result.forEach(grant -> assertEquals(grant.getPrincipalType(), grant.getPrincipalName()));
|
verify(fixture.organizeApi).getListByIds(Collections.singletonList("shared-id"));
|
verify(fixture.positionApi).getListByIds(Collections.singletonList("shared-id"));
|
verify(fixture.roleApi).getListByIds(Collections.singletonList("shared-id"));
|
verify(fixture.permissionGroupMapper).selectDisplayByIds(Collections.singletonList("shared-id"));
|
}
|
|
private static DmsFilePermissionEntity principalPermission(DmsPrincipalType type, UUID resourceId) {
|
DmsFilePermissionEntity result = permission(resourceId);
|
result.setPrincipalType(type.name());
|
result.setPrincipalId("shared-id");
|
return result;
|
}
|
|
private static Function<List<String>, List<?>> lookup(Fixture fixture, DmsPrincipalType type) {
|
switch (type) {
|
case ORG: return fixture.organizeApi::getListByIds;
|
case POSITION: return fixture.positionApi::getListByIds;
|
case ROLE: return fixture.roleApi::getListByIds;
|
case GROUP: return fixture.permissionGroupMapper::selectDisplayByIds;
|
default: throw new IllegalArgumentException(type.name());
|
}
|
}
|
|
private static Object namedPrincipal(DmsPrincipalType type, String name) {
|
switch (type) {
|
case ORG: return organization("shared-id", name);
|
case POSITION:
|
PositionEntity position = new PositionEntity();
|
position.setId("shared-id");
|
position.setFullName(name);
|
return position;
|
case ROLE:
|
RoleEntity role = new RoleEntity();
|
role.setId("shared-id");
|
role.setFullName(name);
|
return role;
|
case GROUP:
|
PermissionGroupEntity group = new PermissionGroupEntity();
|
group.setId("shared-id");
|
group.setFullName(name);
|
group.setEnabledMark(0);
|
return group;
|
default: throw new IllegalArgumentException(type.name());
|
}
|
}
|
|
private static DmsFilePermissionEntity organizationPermission(UUID resourceId) {
|
DmsFilePermissionEntity result = permission(resourceId);
|
result.setPrincipalType("ORG");
|
result.setPrincipalId("org-1");
|
return result;
|
}
|
|
private static OrganizeEntity organization(String id, String name) {
|
OrganizeEntity result = new OrganizeEntity();
|
result.setId(id);
|
result.setFullName(name);
|
return result;
|
}
|
|
private static DmsFilePermissionEntity permission(UUID resourceId) {
|
DmsFilePermissionEntity result = new DmsFilePermissionEntity();
|
result.setId(UUID.randomUUID());
|
result.setResourceId(resourceId);
|
result.setPrincipalType("USER");
|
result.setPrincipalId(USER_ID);
|
result.setValidFrom(new Date(System.currentTimeMillis() - 60_000));
|
result.setUsedCount(0L);
|
result.setCreatedAt(new Date());
|
return result;
|
}
|
|
private static DmsPermissionGrantVO toVO(DmsFilePermissionEntity permission) {
|
DmsPermissionGrantVO result = new DmsPermissionGrantVO();
|
result.setId(permission.getId());
|
result.setResourceId(permission.getResourceId());
|
result.setPrincipalType(permission.getPrincipalType());
|
result.setPrincipalId(permission.getPrincipalId());
|
return result;
|
}
|
|
private static class Fixture {
|
private final DmsCurrentIdentity currentIdentity = mock(DmsCurrentIdentity.class);
|
private final DmsPermissionProperties properties = new DmsPermissionProperties();
|
private final DmsCursorCodec cursorCodec = new DmsCursorCodec();
|
private final DmsFilePermissionMapper permissionMapper = mock(DmsFilePermissionMapper.class);
|
private final DmsPermissionGroupMapper permissionGroupMapper = mock(DmsPermissionGroupMapper.class);
|
private final DmsPermissionUsageMapper usageMapper = mock(DmsPermissionUsageMapper.class);
|
private final DmsPermissionGrantService grantService = mock(DmsPermissionGrantService.class);
|
private final DmsResourceResolver resourceResolver = mock(DmsResourceResolver.class);
|
private final DmsPermissionMatcher matcher = mock(DmsPermissionMatcher.class);
|
private final DmsUserDisplayNameResolver userDisplayNameResolver = mock(DmsUserDisplayNameResolver.class);
|
private final OrganizeApi organizeApi = mock(OrganizeApi.class);
|
private final PositionApi positionApi = mock(PositionApi.class);
|
private final RoleApi roleApi = mock(RoleApi.class);
|
private final DmsPermissionAdminQueryService service = new DmsPermissionAdminQueryService(
|
currentIdentity, properties, cursorCodec, permissionMapper, permissionGroupMapper, usageMapper,
|
grantService, resourceResolver, matcher, userDisplayNameResolver, organizeApi, positionApi, roleApi);
|
|
private Fixture() {
|
when(currentIdentity.tenantId()).thenReturn(TENANT_ID);
|
}
|
}
|
}
|