houzhongyi
2024-07-11 e7c1260db32209a078a962aaa0ad5492c35774fb
提交 | 用户 | 时间
e7c126 1 package com.iailab.module.system.service.tenant;
H 2
3 import com.iailab.framework.common.enums.CommonStatusEnum;
4 import com.iailab.framework.common.pojo.PageResult;
5 import com.iailab.framework.tenant.config.TenantProperties;
6 import com.iailab.framework.tenant.core.context.TenantContextHolder;
7 import com.iailab.framework.test.core.ut.BaseDbUnitTest;
8 import com.iailab.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
9 import com.iailab.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO;
10 import com.iailab.module.system.dal.dataobject.permission.MenuDO;
11 import com.iailab.module.system.dal.dataobject.permission.RoleDO;
12 import com.iailab.module.system.dal.dataobject.tenant.TenantDO;
13 import com.iailab.module.system.dal.dataobject.tenant.TenantPackageDO;
14 import com.iailab.module.system.dal.mysql.tenant.TenantMapper;
15 import com.iailab.module.system.enums.permission.RoleCodeEnum;
16 import com.iailab.module.system.enums.permission.RoleTypeEnum;
17 import com.iailab.module.system.service.permission.MenuService;
18 import com.iailab.module.system.service.permission.PermissionService;
19 import com.iailab.module.system.service.permission.RoleService;
20 import com.iailab.module.system.service.tenant.handler.TenantInfoHandler;
21 import com.iailab.module.system.service.tenant.handler.TenantMenuHandler;
22 import com.iailab.module.system.service.user.AdminUserService;
23 import org.junit.jupiter.api.BeforeEach;
24 import org.junit.jupiter.api.Test;
25 import org.springframework.boot.test.mock.mockito.MockBean;
26 import org.springframework.context.annotation.Import;
27
28 import javax.annotation.Resource;
29 import java.time.LocalDateTime;
30 import java.util.Arrays;
31 import java.util.Collections;
32 import java.util.List;
33
34 import static com.iailab.framework.common.util.collection.SetUtils.asSet;
35 import static com.iailab.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
36 import static com.iailab.framework.common.util.date.LocalDateTimeUtils.buildTime;
37 import static com.iailab.framework.common.util.object.ObjectUtils.cloneIgnoreId;
38 import static com.iailab.framework.test.core.util.AssertUtils.assertPojoEquals;
39 import static com.iailab.framework.test.core.util.AssertUtils.assertServiceException;
40 import static com.iailab.framework.test.core.util.RandomUtils.*;
41 import static com.iailab.module.system.dal.dataobject.tenant.TenantDO.PACKAGE_ID_SYSTEM;
42 import static com.iailab.module.system.enums.ErrorCodeConstants.*;
43 import static java.util.Arrays.asList;
44 import static java.util.Collections.singleton;
45 import static org.junit.jupiter.api.Assertions.*;
46 import static org.mockito.ArgumentMatchers.*;
47 import static org.mockito.Mockito.*;
48
49 /**
50  * {@link TenantServiceImpl} 的单元测试类
51  *
52  * @author iailab
53  */
54 @Import(TenantServiceImpl.class)
55 public class TenantServiceImplTest extends BaseDbUnitTest {
56
57     @Resource
58     private TenantServiceImpl tenantService;
59
60     @Resource
61     private TenantMapper tenantMapper;
62
63     @MockBean
64     private TenantProperties tenantProperties;
65     @MockBean
66     private TenantPackageService tenantPackageService;
67     @MockBean
68     private AdminUserService userService;
69     @MockBean
70     private RoleService roleService;
71     @MockBean
72     private MenuService menuService;
73     @MockBean
74     private PermissionService permissionService;
75
76     @BeforeEach
77     public void setUp() {
78         // 清理租户上下文
79         TenantContextHolder.clear();
80     }
81
82     @Test
83     public void testGetTenantIdList() {
84         // mock 数据
85         TenantDO tenant = randomPojo(TenantDO.class, o -> o.setId(1L));
86         tenantMapper.insert(tenant);
87
88         // 调用,并断言业务异常
89         List<Long> result = tenantService.getTenantIdList();
90         assertEquals(Collections.singletonList(1L), result);
91     }
92
93     @Test
94     public void testValidTenant_notExists() {
95         assertServiceException(() -> tenantService.validTenant(randomLongId()), TENANT_NOT_EXISTS);
96     }
97
98     @Test
99     public void testValidTenant_disable() {
100         // mock 数据
101         TenantDO tenant = randomPojo(TenantDO.class, o -> o.setId(1L).setStatus(CommonStatusEnum.DISABLE.getStatus()));
102         tenantMapper.insert(tenant);
103
104         // 调用,并断言业务异常
105         assertServiceException(() -> tenantService.validTenant(1L), TENANT_DISABLE, tenant.getName());
106     }
107
108     @Test
109     public void testValidTenant_expired() {
110         // mock 数据
111         TenantDO tenant = randomPojo(TenantDO.class, o -> o.setId(1L).setStatus(CommonStatusEnum.ENABLE.getStatus())
112                 .setExpireTime(buildTime(2020, 2, 2)));
113         tenantMapper.insert(tenant);
114
115         // 调用,并断言业务异常
116         assertServiceException(() -> tenantService.validTenant(1L), TENANT_EXPIRE, tenant.getName());
117     }
118
119     @Test
120     public void testValidTenant_success() {
121         // mock 数据
122         TenantDO tenant = randomPojo(TenantDO.class, o -> o.setId(1L).setStatus(CommonStatusEnum.ENABLE.getStatus())
123                 .setExpireTime(LocalDateTime.now().plusDays(1)));
124         tenantMapper.insert(tenant);
125
126         // 调用,并断言业务异常
127         tenantService.validTenant(1L);
128     }
129
130     @Test
131     public void testCreateTenant() {
132         // mock 套餐 100L
133         TenantPackageDO tenantPackage = randomPojo(TenantPackageDO.class, o -> o.setId(100L));
134         when(tenantPackageService.validTenantPackage(eq(100L))).thenReturn(tenantPackage);
135         // mock 角色 200L
136         when(roleService.createRole(argThat(role -> {
137             assertEquals(RoleCodeEnum.TENANT_ADMIN.getName(), role.getName());
138             assertEquals(RoleCodeEnum.TENANT_ADMIN.getCode(), role.getCode());
139             assertEquals(0, role.getSort());
140             assertEquals("系统自动生成", role.getRemark());
141             return true;
142         }), eq(RoleTypeEnum.SYSTEM.getType()))).thenReturn(200L);
143         // mock 用户 300L
144         when(userService.createUser(argThat(user -> {
145             assertEquals("yunai", user.getUsername());
146             assertEquals("yuanma", user.getPassword());
147             assertEquals("平台", user.getNickname());
148             assertEquals("15601691300", user.getMobile());
149             return true;
150         }))).thenReturn(300L);
151
152         // 准备参数
153         TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class, o -> {
154             o.setContactName("平台");
155             o.setContactMobile("15601691300");
156             o.setPackageId(100L);
157             o.setStatus(randomCommonStatus());
158             o.setWebsite("https://www.baidu.com");
159             o.setUsername("yunai");
160             o.setPassword("yuanma");
161         }).setId(null); // 设置为 null,方便后面校验
162
163         // 调用
164         Long tenantId = tenantService.createTenant(reqVO);
165         // 断言
166         assertNotNull(tenantId);
167         // 校验记录的属性是否正确
168         TenantDO tenant = tenantMapper.selectById(tenantId);
169         assertPojoEquals(reqVO, tenant, "id");
170         assertEquals(300L, tenant.getContactUserId());
171         // verify 分配权限
172         verify(permissionService).assignRoleMenu(eq(200L), same(tenantPackage.getMenuIds()));
173         // verify 分配角色
174         verify(permissionService).assignUserRole(eq(300L), eq(singleton(200L)));
175     }
176
177     @Test
178     public void testUpdateTenant_success() {
179         // mock 数据
180         TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setStatus(randomCommonStatus()));
181         tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
182         // 准备参数
183         TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class, o -> {
184             o.setId(dbTenant.getId()); // 设置更新的 ID
185             o.setStatus(randomCommonStatus());
186             o.setWebsite(randomString());
187         });
188
189         // mock 套餐
190         TenantPackageDO tenantPackage = randomPojo(TenantPackageDO.class,
191                 o -> o.setMenuIds(asSet(200L, 201L)));
192         when(tenantPackageService.validTenantPackage(eq(reqVO.getPackageId()))).thenReturn(tenantPackage);
193         // mock 所有角色
194         RoleDO role100 = randomPojo(RoleDO.class, o -> o.setId(100L).setCode(RoleCodeEnum.TENANT_ADMIN.getCode()));
195         role100.setTenantId(dbTenant.getId());
196         RoleDO role101 = randomPojo(RoleDO.class, o -> o.setId(101L));
197         role101.setTenantId(dbTenant.getId());
198         when(roleService.getRoleList()).thenReturn(asList(role100, role101));
199         // mock 每个角色的权限
200         when(permissionService.getRoleMenuListByRoleId(eq(101L))).thenReturn(asSet(201L, 202L));
201
202         // 调用
203         tenantService.updateTenant(reqVO);
204         // 校验是否更新正确
205         TenantDO tenant = tenantMapper.selectById(reqVO.getId()); // 获取最新的
206         assertPojoEquals(reqVO, tenant);
207         // verify 设置角色权限
208         verify(permissionService).assignRoleMenu(eq(100L), eq(asSet(200L, 201L)));
209         verify(permissionService).assignRoleMenu(eq(101L), eq(asSet(201L)));
210     }
211
212     @Test
213     public void testUpdateTenant_notExists() {
214         // 准备参数
215         TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class);
216
217         // 调用, 并断言异常
218         assertServiceException(() -> tenantService.updateTenant(reqVO), TENANT_NOT_EXISTS);
219     }
220
221     @Test
222     public void testUpdateTenant_system() {
223         // mock 数据
224         TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(PACKAGE_ID_SYSTEM));
225         tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
226         // 准备参数
227         TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class, o -> {
228             o.setId(dbTenant.getId()); // 设置更新的 ID
229         });
230
231         // 调用,校验业务异常
232         assertServiceException(() -> tenantService.updateTenant(reqVO), TENANT_CAN_NOT_UPDATE_SYSTEM);
233     }
234
235     @Test
236     public void testDeleteTenant_success() {
237         // mock 数据
238         TenantDO dbTenant = randomPojo(TenantDO.class,
239                 o -> o.setStatus(randomCommonStatus()));
240         tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
241         // 准备参数
242         Long id = dbTenant.getId();
243
244         // 调用
245         tenantService.deleteTenant(id);
246         // 校验数据不存在了
247         assertNull(tenantMapper.selectById(id));
248     }
249
250     @Test
251     public void testDeleteTenant_notExists() {
252         // 准备参数
253         Long id = randomLongId();
254
255         // 调用, 并断言异常
256         assertServiceException(() -> tenantService.deleteTenant(id), TENANT_NOT_EXISTS);
257     }
258
259     @Test
260     public void testDeleteTenant_system() {
261         // mock 数据
262         TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(PACKAGE_ID_SYSTEM));
263         tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
264         // 准备参数
265         Long id = dbTenant.getId();
266
267         // 调用, 并断言异常
268         assertServiceException(() -> tenantService.deleteTenant(id), TENANT_CAN_NOT_UPDATE_SYSTEM);
269     }
270
271     @Test
272     public void testGetTenant() {
273         // mock 数据
274         TenantDO dbTenant = randomPojo(TenantDO.class);
275         tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
276         // 准备参数
277         Long id = dbTenant.getId();
278
279         // 调用
280         TenantDO result = tenantService.getTenant(id);
281         // 校验存在
282         assertPojoEquals(result, dbTenant);
283     }
284
285     @Test
286     public void testGetTenantPage() {
287         // mock 数据
288         TenantDO dbTenant = randomPojo(TenantDO.class, o -> { // 等会查询到
289             o.setName("iailab");
290             o.setContactName("iailab");
291             o.setContactMobile("15601691300");
292             o.setStatus(CommonStatusEnum.ENABLE.getStatus());
293             o.setCreateTime(buildTime(2020, 12, 12));
294         });
295         tenantMapper.insert(dbTenant);
296         // 测试 name 不匹配
297         tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setName(randomString())));
298         // 测试 contactName 不匹配
299         tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setContactName(randomString())));
300         // 测试 contactMobile 不匹配
301         tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setContactMobile(randomString())));
302         // 测试 status 不匹配
303         tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
304         // 测试 createTime 不匹配
305         tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setCreateTime(buildTime(2021, 12, 12))));
306         // 准备参数
307         TenantPageReqVO reqVO = new TenantPageReqVO();
308         reqVO.setName("平台");
309         reqVO.setContactName("艿");
310         reqVO.setContactMobile("1560");
311         reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
312         reqVO.setCreateTime(buildBetweenTime(2020, 12, 1, 2020, 12, 24));
313
314         // 调用
315         PageResult<TenantDO> pageResult = tenantService.getTenantPage(reqVO);
316         // 断言
317         assertEquals(1, pageResult.getTotal());
318         assertEquals(1, pageResult.getList().size());
319         assertPojoEquals(dbTenant, pageResult.getList().get(0));
320     }
321
322     @Test
323     public void testGetTenantByName() {
324         // mock 数据
325         TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setName("平台"));
326         tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
327
328         // 调用
329         TenantDO result = tenantService.getTenantByName("平台");
330         // 校验存在
331         assertPojoEquals(result, dbTenant);
332     }
333
334     @Test
335     public void testGetTenantByWebsite() {
336         // mock 数据
337         TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setWebsite("https://www.baidu.com"));
338         tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
339
340         // 调用
341         TenantDO result = tenantService.getTenantByWebsite("https://www.baidu.com");
342         // 校验存在
343         assertPojoEquals(result, dbTenant);
344     }
345
346     @Test
347     public void testGetTenantListByPackageId() {
348         // mock 数据
349         TenantDO dbTenant1 = randomPojo(TenantDO.class, o -> o.setPackageId(1L));
350         tenantMapper.insert(dbTenant1);// @Sql: 先插入出一条存在的数据
351         TenantDO dbTenant2 = randomPojo(TenantDO.class, o -> o.setPackageId(2L));
352         tenantMapper.insert(dbTenant2);// @Sql: 先插入出一条存在的数据
353
354         // 调用
355         List<TenantDO> result = tenantService.getTenantListByPackageId(1L);
356         assertEquals(1, result.size());
357         assertPojoEquals(dbTenant1, result.get(0));
358     }
359
360     @Test
361     public void testGetTenantCountByPackageId() {
362         // mock 数据
363         TenantDO dbTenant1 = randomPojo(TenantDO.class, o -> o.setPackageId(1L));
364         tenantMapper.insert(dbTenant1);// @Sql: 先插入出一条存在的数据
365         TenantDO dbTenant2 = randomPojo(TenantDO.class, o -> o.setPackageId(2L));
366         tenantMapper.insert(dbTenant2);// @Sql: 先插入出一条存在的数据
367
368         // 调用
369         Long count = tenantService.getTenantCountByPackageId(1L);
370         assertEquals(1, count);
371     }
372
373     @Test
374     public void testHandleTenantInfo_disable() {
375         // 准备参数
376         TenantInfoHandler handler = mock(TenantInfoHandler.class);
377         // mock 禁用
378         when(tenantProperties.getEnable()).thenReturn(false);
379
380         // 调用
381         tenantService.handleTenantInfo(handler);
382         // 断言
383         verify(handler, never()).handle(any());
384     }
385
386     @Test
387     public void testHandleTenantInfo_success() {
388         // 准备参数
389         TenantInfoHandler handler = mock(TenantInfoHandler.class);
390         // mock 未禁用
391         when(tenantProperties.getEnable()).thenReturn(true);
392         // mock 租户
393         TenantDO dbTenant = randomPojo(TenantDO.class);
394         tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
395         TenantContextHolder.setTenantId(dbTenant.getId());
396
397         // 调用
398         tenantService.handleTenantInfo(handler);
399         // 断言
400         verify(handler).handle(argThat(argument -> {
401             assertPojoEquals(dbTenant, argument);
402             return true;
403         }));
404     }
405
406     @Test
407     public void testHandleTenantMenu_disable() {
408         // 准备参数
409         TenantMenuHandler handler = mock(TenantMenuHandler.class);
410         // mock 禁用
411         when(tenantProperties.getEnable()).thenReturn(false);
412
413         // 调用
414         tenantService.handleTenantMenu(handler);
415         // 断言
416         verify(handler, never()).handle(any());
417     }
418
419     @Test // 系统租户的情况
420     public void testHandleTenantMenu_system() {
421         // 准备参数
422         TenantMenuHandler handler = mock(TenantMenuHandler.class);
423         // mock 未禁用
424         when(tenantProperties.getEnable()).thenReturn(true);
425         // mock 租户
426         TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(PACKAGE_ID_SYSTEM));
427         tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
428         TenantContextHolder.setTenantId(dbTenant.getId());
429         // mock 菜单
430         when(menuService.getMenuList()).thenReturn(Arrays.asList(randomPojo(MenuDO.class, o -> o.setId(100L)),
431                 randomPojo(MenuDO.class, o -> o.setId(101L))));
432
433         // 调用
434         tenantService.handleTenantMenu(handler);
435         // 断言
436         verify(handler).handle(asSet(100L, 101L));
437     }
438
439     @Test // 普通租户的情况
440     public void testHandleTenantMenu_normal() {
441         // 准备参数
442         TenantMenuHandler handler = mock(TenantMenuHandler.class);
443         // mock 未禁用
444         when(tenantProperties.getEnable()).thenReturn(true);
445         // mock 租户
446         TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(200L));
447         tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
448         TenantContextHolder.setTenantId(dbTenant.getId());
449         // mock 菜单
450         when(tenantPackageService.getTenantPackage(eq(200L))).thenReturn(randomPojo(TenantPackageDO.class,
451                 o -> o.setMenuIds(asSet(100L, 101L))));
452
453         // 调用
454         tenantService.handleTenantMenu(handler);
455         // 断言
456         verify(handler).handle(asSet(100L, 101L));
457     }
458 }