houzhongyi
2024-07-11 e7c1260db32209a078a962aaa0ad5492c35774fb
提交 | 用户 | 时间
e7c126 1 package com.iailab.module.system.service.permission;
H 2
3 import com.iailab.framework.common.enums.CommonStatusEnum;
4 import com.iailab.framework.test.core.ut.BaseDbUnitTest;
5 import com.iailab.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
6 import com.iailab.module.system.controller.admin.permission.vo.menu.MenuSaveVO;
7 import com.iailab.module.system.dal.dataobject.permission.MenuDO;
8 import com.iailab.module.system.dal.mysql.permission.MenuMapper;
9 import com.iailab.module.system.enums.permission.MenuTypeEnum;
10 import com.iailab.module.system.service.tenant.TenantService;
11 import org.junit.jupiter.api.Test;
12 import org.springframework.boot.test.mock.mockito.MockBean;
13 import org.springframework.context.annotation.Import;
14
15 import javax.annotation.Resource;
16 import java.util.Collection;
17 import java.util.Collections;
18 import java.util.List;
19 import java.util.Set;
20
21 import static com.iailab.framework.common.util.collection.SetUtils.asSet;
22 import static com.iailab.framework.common.util.object.ObjectUtils.cloneIgnoreId;
23 import static com.iailab.framework.test.core.util.AssertUtils.assertPojoEquals;
24 import static com.iailab.framework.test.core.util.AssertUtils.assertServiceException;
25 import static com.iailab.framework.test.core.util.RandomUtils.*;
26 import static com.iailab.module.system.dal.dataobject.permission.MenuDO.ID_ROOT;
27 import static com.iailab.module.system.enums.ErrorCodeConstants.*;
28 import static org.junit.jupiter.api.Assertions.assertEquals;
29 import static org.junit.jupiter.api.Assertions.assertNull;
30 import static org.mockito.ArgumentMatchers.argThat;
31 import static org.mockito.Mockito.doNothing;
32 import static org.mockito.Mockito.verify;
33
34 @Import(MenuServiceImpl.class)
35 public class MenuServiceImplTest extends BaseDbUnitTest {
36
37     @Resource
38     private MenuServiceImpl menuService;
39
40     @Resource
41     private MenuMapper menuMapper;
42
43     @MockBean
44     private PermissionService permissionService;
45     @MockBean
46     private TenantService tenantService;
47
48     @Test
49     public void testCreateMenu_success() {
50         // mock 数据(构造父菜单)
51         MenuDO menuDO = buildMenuDO(MenuTypeEnum.MENU,
52                 "parent", 0L);
53         menuMapper.insert(menuDO);
54         Long parentId = menuDO.getId();
55         // 准备参数
56         MenuSaveVO reqVO = randomPojo(MenuSaveVO.class, o -> {
57             o.setParentId(parentId);
58             o.setName("testSonName");
59             o.setType(MenuTypeEnum.MENU.getType());
60         }).setId(null); // 防止 id 被赋值
61         Long menuId = menuService.createMenu(reqVO);
62
63         // 校验记录的属性是否正确
64         MenuDO dbMenu = menuMapper.selectById(menuId);
65         assertPojoEquals(reqVO, dbMenu, "id");
66     }
67
68     @Test
69     public void testUpdateMenu_success() {
70         // mock 数据(构造父子菜单)
71         MenuDO sonMenuDO = createParentAndSonMenu();
72         Long sonId = sonMenuDO.getId();
73         // 准备参数
74         MenuSaveVO reqVO = randomPojo(MenuSaveVO.class, o -> {
75             o.setId(sonId);
76             o.setName("testSonName"); // 修改名字
77             o.setParentId(sonMenuDO.getParentId());
78             o.setType(MenuTypeEnum.MENU.getType());
79         });
80
81         // 调用
82         menuService.updateMenu(reqVO);
83         // 校验记录的属性是否正确
84         MenuDO dbMenu = menuMapper.selectById(sonId);
85         assertPojoEquals(reqVO, dbMenu);
86     }
87
88     @Test
89     public void testUpdateMenu_sonIdNotExist() {
90         // 准备参数
91         MenuSaveVO reqVO = randomPojo(MenuSaveVO.class);
92         // 调用,并断言异常
93         assertServiceException(() -> menuService.updateMenu(reqVO), MENU_NOT_EXISTS);
94     }
95
96     @Test
97     public void testDeleteMenu_success() {
98         // mock 数据
99         MenuDO menuDO = randomPojo(MenuDO.class);
100         menuMapper.insert(menuDO);
101         // 准备参数
102         Long id = menuDO.getId();
103
104         // 调用
105         menuService.deleteMenu(id);
106         // 断言
107         MenuDO dbMenuDO = menuMapper.selectById(id);
108         assertNull(dbMenuDO);
109         verify(permissionService).processMenuDeleted(id);
110     }
111
112     @Test
113     public void testDeleteMenu_menuNotExist() {
114         assertServiceException(() -> menuService.deleteMenu(randomLongId()),
115                 MENU_NOT_EXISTS);
116     }
117
118     @Test
119     public void testDeleteMenu_existChildren() {
120         // mock 数据(构造父子菜单)
121         MenuDO sonMenu = createParentAndSonMenu();
122         // 准备参数
123         Long parentId = sonMenu.getParentId();
124
125         // 调用并断言异常
126         assertServiceException(() -> menuService.deleteMenu(parentId), MENU_EXISTS_CHILDREN);
127     }
128
129     @Test
130     public void testGetMenuList_all() {
131         // mock 数据
132         MenuDO menu100 = randomPojo(MenuDO.class);
133         menuMapper.insert(menu100);
134         MenuDO menu101 = randomPojo(MenuDO.class);
135         menuMapper.insert(menu101);
136         // 准备参数
137
138         // 调用
139         List<MenuDO> list = menuService.getMenuList();
140         // 断言
141         assertEquals(2, list.size());
142         assertPojoEquals(menu100, list.get(0));
143         assertPojoEquals(menu101, list.get(1));
144     }
145
146     @Test
147     public void testGetMenuList() {
148         // mock 数据
149         MenuDO menuDO = randomPojo(MenuDO.class, o -> o.setName("iailab").setStatus(CommonStatusEnum.ENABLE.getStatus()));
150         menuMapper.insert(menuDO);
151         // 测试 status 不匹配
152         menuMapper.insert(cloneIgnoreId(menuDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
153         // 测试 name 不匹配
154         menuMapper.insert(cloneIgnoreId(menuDO, o -> o.setName("艿")));
155         // 准备参数
156         MenuListReqVO reqVO = new MenuListReqVO().setName("芋").setStatus(CommonStatusEnum.ENABLE.getStatus());
157
158         // 调用
159         List<MenuDO> result = menuService.getMenuList(reqVO);
160         // 断言
161         assertEquals(1, result.size());
162         assertPojoEquals(menuDO, result.get(0));
163     }
164
165     @Test
166     public void testGetMenuListByTenant() {
167         // mock 数据
168         MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus()));
169         menuMapper.insert(menu100);
170         MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus()));
171         menuMapper.insert(menu101);
172         MenuDO menu102 = randomPojo(MenuDO.class, o -> o.setId(102L).setStatus(CommonStatusEnum.ENABLE.getStatus()));
173         menuMapper.insert(menu102);
174         // mock 过滤菜单
175         Set<Long> menuIds = asSet(100L, 101L);
176         doNothing().when(tenantService).handleTenantMenu(argThat(handler -> {
177             handler.handle(menuIds);
178             return true;
179         }));
180         // 准备参数
181         MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus());
182
183         // 调用
184         List<MenuDO> result = menuService.getMenuListByTenant(reqVO);
185         // 断言
186         assertEquals(1, result.size());
187         assertPojoEquals(menu100, result.get(0));
188     }
189
190     @Test
191     public void testGetMenuIdListByPermissionFromCache() {
192         // mock 数据
193         MenuDO menu100 = randomPojo(MenuDO.class);
194         menuMapper.insert(menu100);
195         MenuDO menu101 = randomPojo(MenuDO.class);
196         menuMapper.insert(menu101);
197         // 准备参数
198         String permission = menu100.getPermission();
199
200         // 调用
201         List<Long> ids = menuService.getMenuIdListByPermissionFromCache(permission);
202         // 断言
203         assertEquals(1, ids.size());
204         assertEquals(menu100.getId(), ids.get(0));
205     }
206
207     @Test
208     public void testGetMenuList_ids() {
209         // mock 数据
210         MenuDO menu100 = randomPojo(MenuDO.class);
211         menuMapper.insert(menu100);
212         MenuDO menu101 = randomPojo(MenuDO.class);
213         menuMapper.insert(menu101);
214         // 准备参数
215         Collection<Long> ids = Collections.singleton(menu100.getId());
216
217         // 调用
218         List<MenuDO> list = menuService.getMenuList(ids);
219         // 断言
220         assertEquals(1, list.size());
221         assertPojoEquals(menu100, list.get(0));
222     }
223
224     @Test
225     public void testGetMenu() {
226         // mock 数据
227         MenuDO menu = randomPojo(MenuDO.class);
228         menuMapper.insert(menu);
229         // 准备参数
230         Long id = menu.getId();
231
232         // 调用
233         MenuDO dbMenu = menuService.getMenu(id);
234         // 断言
235         assertPojoEquals(menu, dbMenu);
236     }
237
238     @Test
239     public void testValidateParentMenu_success() {
240         // mock 数据
241         MenuDO menuDO = buildMenuDO(MenuTypeEnum.MENU, "parent", 0L);
242         menuMapper.insert(menuDO);
243         // 准备参数
244         Long parentId = menuDO.getId();
245
246         // 调用,无需断言
247         menuService.validateParentMenu(parentId, null);
248     }
249
250     @Test
251     public void testValidateParentMenu_canNotSetSelfToBeParent() {
252         // 调用,并断言异常
253         assertServiceException(() -> menuService.validateParentMenu(1L, 1L),
254                 MENU_PARENT_ERROR);
255     }
256
257     @Test
258     public void testValidateParentMenu_parentNotExist() {
259         // 调用,并断言异常
260         assertServiceException(() -> menuService.validateParentMenu(randomLongId(), null),
261                 MENU_PARENT_NOT_EXISTS);
262     }
263
264     @Test
265     public void testValidateParentMenu_parentTypeError() {
266         // mock 数据
267         MenuDO menuDO = buildMenuDO(MenuTypeEnum.BUTTON, "parent", 0L);
268         menuMapper.insert(menuDO);
269         // 准备参数
270         Long parentId = menuDO.getId();
271
272         // 调用,并断言异常
273         assertServiceException(() -> menuService.validateParentMenu(parentId, null),
274                 MENU_PARENT_NOT_DIR_OR_MENU);
275     }
276
277     @Test
278     public void testValidateMenu_success() {
279         // mock 父子菜单
280         MenuDO sonMenu = createParentAndSonMenu();
281         // 准备参数
282         Long parentId = sonMenu.getParentId();
283         Long otherSonMenuId = randomLongId();
284         String otherSonMenuName = randomString();
285
286         // 调用,无需断言
287         menuService.validateMenu(parentId, otherSonMenuName, otherSonMenuId);
288     }
289
290     @Test
291     public void testValidateMenu_sonMenuNameDuplicate() {
292         // mock 父子菜单
293         MenuDO sonMenu = createParentAndSonMenu();
294         // 准备参数
295         Long parentId = sonMenu.getParentId();
296         Long otherSonMenuId = randomLongId();
297         String otherSonMenuName = sonMenu.getName(); //相同名称
298
299         // 调用,并断言异常
300         assertServiceException(() -> menuService.validateMenu(parentId, otherSonMenuName, otherSonMenuId),
301                 MENU_NAME_DUPLICATE);
302     }
303
304     // ====================== 初始化方法 ======================
305
306     /**
307      * 插入父子菜单,返回子菜单
308      *
309      * @return 子菜单
310      */
311     private MenuDO createParentAndSonMenu() {
312         // 构造父子菜单
313         MenuDO parentMenuDO = buildMenuDO(MenuTypeEnum.MENU, "parent", ID_ROOT);
314         menuMapper.insert(parentMenuDO);
315         // 构建子菜单
316         MenuDO sonMenuDO = buildMenuDO(MenuTypeEnum.MENU, "testSonName",
317                 parentMenuDO.getParentId());
318         menuMapper.insert(sonMenuDO);
319         return sonMenuDO;
320     }
321
322     private MenuDO buildMenuDO(MenuTypeEnum type, String name, Long parentId) {
323         return buildMenuDO(type, name, parentId, randomCommonStatus());
324     }
325
326     private MenuDO buildMenuDO(MenuTypeEnum type, String name, Long parentId, Integer status) {
327         return randomPojo(MenuDO.class, o -> o.setId(null).setName(name).setParentId(parentId)
328                 .setType(type.getType()).setStatus(status));
329     }
330
331 }