package com.yunhai.flowcenter.service; import com.yunhai.flowcenter.entity.FlwInstance; import com.yunhai.flowcenter.entity.FlwTask; import com.yunhai.flowcenter.repository.FlwTaskRepository; import com.yunhai.platform.apistd.BizException; import com.yunhai.platform.utils.model.BoaUser; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.test.util.ReflectionTestUtils; import java.util.Arrays; import java.util.Collections; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** * 用户面办件可见性守卫口径锁定(三种守卫必须同口径:svc-hall ApplyViewGuard / * Notice NoticeFlowGuard / 本类)。原先只认 type==1 超管,导致"能列办件、点详情 403"。 */ class FlowAccessGuardTest { private FlwTaskRepository taskRepository; private FlowAccessGuard guard; private FlwInstance instance; @BeforeEach void setUp() { taskRepository = mock(FlwTaskRepository.class); guard = new FlowAccessGuard(taskRepository); when(taskRepository.findByInstanceIdOrderByIdAsc(anyLong())) .thenReturn(Collections.emptyList()); instance = new FlwInstance(); ReflectionTestUtils.setField(instance, "id", 100L); instance.setSchId(990001L); instance.setSubmitterId(11); } private BoaUser user(int id, Integer type, Integer schId, Integer... roleIds) { BoaUser user = mock(BoaUser.class, org.mockito.Mockito.RETURNS_DEEP_STUBS); when(user.getId()).thenReturn(id); when(user.getType()).thenReturn(type); when(user.getRoleIds()).thenReturn(roleIds.length == 0 ? null : new java.util.ArrayList<>(Arrays.asList(roleIds))); when(user.getCurrentRole().getSchId()).thenReturn(schId); return user; } @Test void submitterCanViewOwnInstance() { assertDoesNotThrow(() -> guard.requireInstanceVisible(instance, user(11, 2, 990001, 9))); } @Test void assigneeCanViewInstance() { FlwTask task = new FlwTask(); task.setAssigneeId(22); when(taskRepository.findByInstanceIdOrderByIdAsc(100L)).thenReturn(Collections.singletonList(task)); assertDoesNotThrow(() -> guard.requireInstanceVisible(instance, user(22, 2, 990001, 9))); } @Test void sameSchoolAdminByTypeCanView() { assertDoesNotThrow(() -> guard.requireInstanceVisible(instance, user(33, 1, 990001))); } @Test void sameSchoolAdminByRoleIdCanView() { // 校级管理员 roleId∈{2,5,7}:FlowAdminGuard 放行其管理端,可见性守卫必须同口径 assertDoesNotThrow(() -> guard.requireInstanceVisible(instance, user(34, 2, 990001, 5))); } @Test void crossSchoolAdminIsDenied() { BizException e = assertThrows(BizException.class, () -> guard.requireInstanceVisible(instance, user(35, 1, 888888))); assertEquals("仅提交人/办理人/本校管理员可查看该办件", e.getMessage()); } @Test void ordinarySameSchoolUserIsDenied() { assertThrows(BizException.class, () -> guard.requireInstanceVisible(instance, user(36, 2, 990001, 9))); } @Test void userWithoutCurrentRoleIsDenied() { assertThrows(BizException.class, () -> guard.requireInstanceVisible(instance, user(37, 1, null))); } }