Commit 4a322ed72a8a74561f1ecfa92b56b35ec7acd2ff

Authored by 芋道源码
Committed by Gitee
2 parents 646b2022 10790958

!13 user模块单元测试

Merge pull request !13 from 化身孤岛的鲸/feat_test-user
@@ -46,7 +46,12 @@ @@ -46,7 +46,12 @@
46 <easyexcel.verion>2.2.7</easyexcel.verion> 46 <easyexcel.verion>2.2.7</easyexcel.verion>
47 <velocity.version>2.2</velocity.version> 47 <velocity.version>2.2</velocity.version>
48 <screw.version>1.0.5</screw.version> 48 <screw.version>1.0.5</screw.version>
  49 + <podam.version>7.2.6.RELEASE</podam.version>
  50 + <jedis-mock.version>0.1.16</jedis-mock.version>
49 <!-- 三方云服务相关 --> 51 <!-- 三方云服务相关 -->
  52 + <aliyun-java-sdk-core.version>4.5.18</aliyun-java-sdk-core.version>
  53 + <aliyun-java-sdk-dysmsapi.version>2.1.0</aliyun-java-sdk-dysmsapi.version>
  54 + <yunpian-java-sdk.version>1.2.7</yunpian-java-sdk.version>
50 </properties> 55 </properties>
51 56
52 <!-- 依赖声明 --> 57 <!-- 依赖声明 -->
@@ -213,14 +218,14 @@ @@ -213,14 +218,14 @@
213 <dependency> 218 <dependency>
214 <groupId>com.github.fppt</groupId> <!-- 单元测试,我们采用内嵌的 Redis 数据库 --> 219 <groupId>com.github.fppt</groupId> <!-- 单元测试,我们采用内嵌的 Redis 数据库 -->
215 <artifactId>jedis-mock</artifactId> 220 <artifactId>jedis-mock</artifactId>
216 - <version>0.1.16</version> 221 + <version>${jedis-mock.version}</version>
217 <scope>test</scope> 222 <scope>test</scope>
218 </dependency> 223 </dependency>
219 224
220 <dependency> 225 <dependency>
221 <groupId>uk.co.jemos.podam</groupId> <!-- 单元测试,随机生成 POJO 类 --> 226 <groupId>uk.co.jemos.podam</groupId> <!-- 单元测试,随机生成 POJO 类 -->
222 <artifactId>podam</artifactId> 227 <artifactId>podam</artifactId>
223 - <version>7.2.6.RELEASE</version> 228 + <version>${podam.version}</version>
224 <scope>test</scope> 229 <scope>test</scope>
225 </dependency> 230 </dependency>
226 231
@@ -278,18 +283,18 @@ @@ -278,18 +283,18 @@
278 <dependency> 283 <dependency>
279 <groupId>com.yunpian.sdk</groupId> 284 <groupId>com.yunpian.sdk</groupId>
280 <artifactId>yunpian-java-sdk</artifactId> 285 <artifactId>yunpian-java-sdk</artifactId>
281 - <version>1.2.7</version> 286 + <version>${yunpian-java-sdk.version}</version>
282 </dependency> 287 </dependency>
283 288
284 <dependency> 289 <dependency>
285 <groupId>com.aliyun</groupId> 290 <groupId>com.aliyun</groupId>
286 <artifactId>aliyun-java-sdk-core</artifactId> 291 <artifactId>aliyun-java-sdk-core</artifactId>
287 - <version>4.5.18</version> 292 + <version>${aliyun-java-sdk-core.version}</version>
288 </dependency> 293 </dependency>
289 <dependency> 294 <dependency>
290 <groupId>com.aliyun</groupId> 295 <groupId>com.aliyun</groupId>
291 <artifactId>aliyun-java-sdk-dysmsapi</artifactId> 296 <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
292 - <version>2.1.0</version> 297 + <version>${aliyun-java-sdk-dysmsapi.version}</version>
293 </dependency> 298 </dependency>
294 <!-- SMS SDK end --> 299 <!-- SMS SDK end -->
295 300
ruoyi-ui/src/views/system/user/index.vue
@@ -362,7 +362,7 @@ export default { @@ -362,7 +362,7 @@ export default {
362 created() { 362 created() {
363 this.getList(); 363 this.getList();
364 this.getTreeselect(); 364 this.getTreeselect();
365 - this.getConfigKey("sys.user.initPassword").then(response => { 365 + this.getConfigKey("sys.user.init-password").then(response => {
366 this.initPassword = response.msg; 366 this.initPassword = response.msg;
367 }); 367 });
368 }, 368 },
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/SysUserController.java
@@ -149,9 +149,9 @@ public class SysUserController { @@ -149,9 +149,9 @@ public class SysUserController {
149 // 手动创建导出 demo 149 // 手动创建导出 demo
150 List<SysUserImportExcelVO> list = Arrays.asList( 150 List<SysUserImportExcelVO> list = Arrays.asList(
151 SysUserImportExcelVO.builder().username("yudao").deptId(1L).email("yudao@iocoder.cn").mobile("15601691300") 151 SysUserImportExcelVO.builder().username("yudao").deptId(1L).email("yudao@iocoder.cn").mobile("15601691300")
152 - .nickname("芋道").status(CommonStatusEnum.ENABLE.getStatus()).sex(SysSexEnum.MALE.getSEX()).build(), 152 + .nickname("芋道").status(CommonStatusEnum.ENABLE.getStatus()).sex(SysSexEnum.MALE.getSex()).build(),
153 SysUserImportExcelVO.builder().username("yuanma").deptId(2L).email("yuanma@iocoder.cn").mobile("15601701300") 153 SysUserImportExcelVO.builder().username("yuanma").deptId(2L).email("yuanma@iocoder.cn").mobile("15601701300")
154 - .nickname("源码").status(CommonStatusEnum.DISABLE.getStatus()).sex(SysSexEnum.FEMALE.getSEX()).build() 154 + .nickname("源码").status(CommonStatusEnum.DISABLE.getStatus()).sex(SysSexEnum.FEMALE.getSex()).build()
155 ); 155 );
156 156
157 // 输出 157 // 输出
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/profile/SysUserProfileUpdateReqVO.java
@@ -3,9 +3,9 @@ package cn.iocoder.dashboard.modules.system.controller.user.vo.profile; @@ -3,9 +3,9 @@ package cn.iocoder.dashboard.modules.system.controller.user.vo.profile;
3 import io.swagger.annotations.ApiModel; 3 import io.swagger.annotations.ApiModel;
4 import io.swagger.annotations.ApiModelProperty; 4 import io.swagger.annotations.ApiModelProperty;
5 import lombok.Data; 5 import lombok.Data;
  6 +import org.hibernate.validator.constraints.Length;
6 7
7 import javax.validation.constraints.Email; 8 import javax.validation.constraints.Email;
8 -import javax.validation.constraints.Pattern;  
9 import javax.validation.constraints.Size; 9 import javax.validation.constraints.Size;
10 10
11 @ApiModel("用户个人信息更新 Request VO") 11 @ApiModel("用户个人信息更新 Request VO")
@@ -22,7 +22,7 @@ public class SysUserProfileUpdateReqVO { @@ -22,7 +22,7 @@ public class SysUserProfileUpdateReqVO {
22 private String email; 22 private String email;
23 23
24 @ApiModelProperty(value = "手机号码", example = "15601691300") 24 @ApiModelProperty(value = "手机号码", example = "15601691300")
25 - @Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误") 25 + @Length(min = 11, max = 11, message = "手机号长度必须 11 位")
26 private String mobile; 26 private String mobile;
27 27
28 @ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SysSexEnum 枚举类") 28 @ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SysSexEnum 枚举类")
src/main/java/cn/iocoder/dashboard/modules/system/controller/user/vo/user/SysUserBaseVO.java
@@ -2,10 +2,10 @@ package cn.iocoder.dashboard.modules.system.controller.user.vo.user; @@ -2,10 +2,10 @@ package cn.iocoder.dashboard.modules.system.controller.user.vo.user;
2 2
3 import io.swagger.annotations.ApiModelProperty; 3 import io.swagger.annotations.ApiModelProperty;
4 import lombok.Data; 4 import lombok.Data;
  5 +import org.hibernate.validator.constraints.Length;
5 6
6 import javax.validation.constraints.Email; 7 import javax.validation.constraints.Email;
7 import javax.validation.constraints.NotBlank; 8 import javax.validation.constraints.NotBlank;
8 -import javax.validation.constraints.Pattern;  
9 import javax.validation.constraints.Size; 9 import javax.validation.constraints.Size;
10 import java.util.Set; 10 import java.util.Set;
11 11
@@ -40,7 +40,7 @@ public class SysUserBaseVO { @@ -40,7 +40,7 @@ public class SysUserBaseVO {
40 private String email; 40 private String email;
41 41
42 @ApiModelProperty(value = "手机号码", example = "15601691300") 42 @ApiModelProperty(value = "手机号码", example = "15601691300")
43 - @Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误") 43 + @Length(min = 11, max = 11, message = "手机号长度必须 11 位")
44 private String mobile; 44 private String mobile;
45 45
46 @ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SysSexEnum 枚举类") 46 @ApiModelProperty(value = "用户性别", example = "1", notes = "参见 SysSexEnum 枚举类")
src/main/java/cn/iocoder/dashboard/modules/system/enums/common/SysSexEnum.java
@@ -3,6 +3,11 @@ package cn.iocoder.dashboard.modules.system.enums.common; @@ -3,6 +3,11 @@ package cn.iocoder.dashboard.modules.system.enums.common;
3 import lombok.AllArgsConstructor; 3 import lombok.AllArgsConstructor;
4 import lombok.Getter; 4 import lombok.Getter;
5 5
  6 +/**
  7 + * 性别的枚举值
  8 + *
  9 + * @author 芋道源码
  10 + */
6 @Getter 11 @Getter
7 @AllArgsConstructor 12 @AllArgsConstructor
8 public enum SysSexEnum { 13 public enum SysSexEnum {
@@ -10,6 +15,9 @@ public enum SysSexEnum { @@ -10,6 +15,9 @@ public enum SysSexEnum {
10 MALE(1), // 男 15 MALE(1), // 男
11 FEMALE(2); // 女 16 FEMALE(2); // 女
12 17
13 - private final Integer SEX; 18 + /**
  19 + * 性别
  20 + */
  21 + private final Integer sex;
14 22
15 } 23 }
src/main/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImpl.java
@@ -6,17 +6,11 @@ import cn.hutool.core.util.IdUtil; @@ -6,17 +6,11 @@ import cn.hutool.core.util.IdUtil;
6 import cn.hutool.core.util.StrUtil; 6 import cn.hutool.core.util.StrUtil;
7 import cn.iocoder.dashboard.common.enums.CommonStatusEnum; 7 import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
8 import cn.iocoder.dashboard.common.exception.ServiceException; 8 import cn.iocoder.dashboard.common.exception.ServiceException;
9 -import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil;  
10 import cn.iocoder.dashboard.common.pojo.PageResult; 9 import cn.iocoder.dashboard.common.pojo.PageResult;
11 import cn.iocoder.dashboard.modules.infra.service.file.InfFileService; 10 import cn.iocoder.dashboard.modules.infra.service.file.InfFileService;
12 import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO; 11 import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
13 import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO; 12 import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
14 -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserCreateReqVO;  
15 -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserExportReqVO;  
16 -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportExcelVO;  
17 -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserImportRespVO;  
18 -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserPageReqVO;  
19 -import cn.iocoder.dashboard.modules.system.controller.user.vo.user.SysUserUpdateReqVO; 13 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
20 import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert; 14 import cn.iocoder.dashboard.modules.system.convert.user.SysUserConvert;
21 import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO; 15 import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
22 import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO; 16 import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
@@ -26,21 +20,18 @@ import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService; @@ -26,21 +20,18 @@ import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
26 import cn.iocoder.dashboard.modules.system.service.dept.SysPostService; 20 import cn.iocoder.dashboard.modules.system.service.dept.SysPostService;
27 import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; 21 import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
28 import cn.iocoder.dashboard.util.collection.CollectionUtils; 22 import cn.iocoder.dashboard.util.collection.CollectionUtils;
  23 +import com.google.common.annotations.VisibleForTesting;
29 import lombok.extern.slf4j.Slf4j; 24 import lombok.extern.slf4j.Slf4j;
  25 +import org.springframework.beans.factory.annotation.Value;
30 import org.springframework.security.crypto.password.PasswordEncoder; 26 import org.springframework.security.crypto.password.PasswordEncoder;
31 import org.springframework.stereotype.Service; 27 import org.springframework.stereotype.Service;
32 import org.springframework.transaction.annotation.Transactional; 28 import org.springframework.transaction.annotation.Transactional;
33 29
34 import javax.annotation.Resource; 30 import javax.annotation.Resource;
35 import java.io.InputStream; 31 import java.io.InputStream;
36 -import java.util.ArrayList;  
37 -import java.util.Collection;  
38 -import java.util.Collections;  
39 -import java.util.LinkedHashMap;  
40 -import java.util.List;  
41 -import java.util.Map;  
42 -import java.util.Set; 32 +import java.util.*;
43 33
  34 +import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception;
44 import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; 35 import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
45 36
46 37
@@ -53,6 +44,9 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; @@ -53,6 +44,9 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
53 @Slf4j 44 @Slf4j
54 public class SysUserServiceImpl implements SysUserService { 45 public class SysUserServiceImpl implements SysUserService {
55 46
  47 + @Value("${sys.user.init-password:yudaoyuanma}")
  48 + private String userInitPassword;
  49 +
56 @Resource 50 @Resource
57 private SysUserMapper userMapper; 51 private SysUserMapper userMapper;
58 52
@@ -142,8 +136,6 @@ public class SysUserServiceImpl implements SysUserService { @@ -142,8 +136,6 @@ public class SysUserServiceImpl implements SysUserService {
142 updateObj.setId(id); 136 updateObj.setId(id);
143 updateObj.setStatus(status); 137 updateObj.setStatus(status);
144 userMapper.updateById(updateObj); 138 userMapper.updateById(updateObj);
145 - // 删除用户关联数据  
146 - permissionService.processUserDeleted(id);  
147 } 139 }
148 140
149 @Override 141 @Override
@@ -152,6 +144,8 @@ public class SysUserServiceImpl implements SysUserService { @@ -152,6 +144,8 @@ public class SysUserServiceImpl implements SysUserService {
152 this.checkUserExists(id); 144 this.checkUserExists(id);
153 // 删除用户 145 // 删除用户
154 userMapper.deleteById(id); 146 userMapper.deleteById(id);
  147 + // 删除用户关联数据
  148 + permissionService.processUserDeleted(id);
155 } 149 }
156 150
157 @Override 151 @Override
@@ -221,17 +215,19 @@ public class SysUserServiceImpl implements SysUserService { @@ -221,17 +215,19 @@ public class SysUserServiceImpl implements SysUserService {
221 this.checkPostEnable(postIds); 215 this.checkPostEnable(postIds);
222 } 216 }
223 217
224 - private void checkUserExists(Long id) { 218 + @VisibleForTesting
  219 + void checkUserExists(Long id) {
225 if (id == null) { 220 if (id == null) {
226 return; 221 return;
227 } 222 }
228 SysUserDO user = userMapper.selectById(id); 223 SysUserDO user = userMapper.selectById(id);
229 if (user == null) { 224 if (user == null) {
230 - throw ServiceExceptionUtil.exception(USER_NOT_EXISTS); 225 + throw exception(USER_NOT_EXISTS);
231 } 226 }
232 } 227 }
233 228
234 - private void checkUsernameUnique(Long id, String username) { 229 + @VisibleForTesting
  230 + void checkUsernameUnique(Long id, String username) {
235 if (StrUtil.isBlank(username)) { 231 if (StrUtil.isBlank(username)) {
236 return; 232 return;
237 } 233 }
@@ -241,14 +237,15 @@ public class SysUserServiceImpl implements SysUserService { @@ -241,14 +237,15 @@ public class SysUserServiceImpl implements SysUserService {
241 } 237 }
242 // 如果 id 为空,说明不用比较是否为相同 id 的用户 238 // 如果 id 为空,说明不用比较是否为相同 id 的用户
243 if (id == null) { 239 if (id == null) {
244 - throw ServiceExceptionUtil.exception(USER_USERNAME_EXISTS); 240 + throw exception(USER_USERNAME_EXISTS);
245 } 241 }
246 if (!user.getId().equals(id)) { 242 if (!user.getId().equals(id)) {
247 - throw ServiceExceptionUtil.exception(USER_USERNAME_EXISTS); 243 + throw exception(USER_USERNAME_EXISTS);
248 } 244 }
249 } 245 }
250 246
251 - private void checkEmailUnique(Long id, String email) { 247 + @VisibleForTesting
  248 + void checkEmailUnique(Long id, String email) {
252 if (StrUtil.isBlank(email)) { 249 if (StrUtil.isBlank(email)) {
253 return; 250 return;
254 } 251 }
@@ -258,14 +255,15 @@ public class SysUserServiceImpl implements SysUserService { @@ -258,14 +255,15 @@ public class SysUserServiceImpl implements SysUserService {
258 } 255 }
259 // 如果 id 为空,说明不用比较是否为相同 id 的用户 256 // 如果 id 为空,说明不用比较是否为相同 id 的用户
260 if (id == null) { 257 if (id == null) {
261 - throw ServiceExceptionUtil.exception(USER_EMAIL_EXISTS); 258 + throw exception(USER_EMAIL_EXISTS);
262 } 259 }
263 if (!user.getId().equals(id)) { 260 if (!user.getId().equals(id)) {
264 - throw ServiceExceptionUtil.exception(USER_EMAIL_EXISTS); 261 + throw exception(USER_EMAIL_EXISTS);
265 } 262 }
266 } 263 }
267 264
268 - private void checkMobileUnique(Long id, String mobile) { 265 + @VisibleForTesting
  266 + void checkMobileUnique(Long id, String mobile) {
269 if (StrUtil.isBlank(mobile)) { 267 if (StrUtil.isBlank(mobile)) {
270 return; 268 return;
271 } 269 }
@@ -275,42 +273,44 @@ public class SysUserServiceImpl implements SysUserService { @@ -275,42 +273,44 @@ public class SysUserServiceImpl implements SysUserService {
275 } 273 }
276 // 如果 id 为空,说明不用比较是否为相同 id 的用户 274 // 如果 id 为空,说明不用比较是否为相同 id 的用户
277 if (id == null) { 275 if (id == null) {
278 - throw ServiceExceptionUtil.exception(USER_MOBILE_EXISTS); 276 + throw exception(USER_MOBILE_EXISTS);
279 } 277 }
280 if (!user.getId().equals(id)) { 278 if (!user.getId().equals(id)) {
281 - throw ServiceExceptionUtil.exception(USER_MOBILE_EXISTS); 279 + throw exception(USER_MOBILE_EXISTS);
282 } 280 }
283 } 281 }
284 282
285 - private void checkDeptEnable(Long deptId) { 283 + @VisibleForTesting
  284 + void checkDeptEnable(Long deptId) {
286 if (deptId == null) { // 允许不选择 285 if (deptId == null) { // 允许不选择
287 return; 286 return;
288 } 287 }
289 SysDeptDO dept = deptService.getDept(deptId); 288 SysDeptDO dept = deptService.getDept(deptId);
290 if (dept == null) { 289 if (dept == null) {
291 - throw ServiceExceptionUtil.exception(DEPT_NOT_FOUND); 290 + throw exception(DEPT_NOT_FOUND);
292 } 291 }
293 if (!CommonStatusEnum.ENABLE.getStatus().equals(dept.getStatus())) { 292 if (!CommonStatusEnum.ENABLE.getStatus().equals(dept.getStatus())) {
294 - throw ServiceExceptionUtil.exception(DEPT_NOT_ENABLE); 293 + throw exception(DEPT_NOT_ENABLE);
295 } 294 }
296 } 295 }
297 296
298 - private void checkPostEnable(Set<Long> postIds) { 297 + @VisibleForTesting
  298 + void checkPostEnable(Set<Long> postIds) {
299 if (CollUtil.isEmpty(postIds)) { // 允许不选择 299 if (CollUtil.isEmpty(postIds)) { // 允许不选择
300 return; 300 return;
301 } 301 }
302 List<SysPostDO> posts = postService.getPosts(postIds, null); 302 List<SysPostDO> posts = postService.getPosts(postIds, null);
303 if (CollUtil.isEmpty(posts)) { 303 if (CollUtil.isEmpty(posts)) {
304 - throw ServiceExceptionUtil.exception(POST_NOT_FOUND); 304 + throw exception(POST_NOT_FOUND);
305 } 305 }
306 Map<Long, SysPostDO> postMap = CollectionUtils.convertMap(posts, SysPostDO::getId); 306 Map<Long, SysPostDO> postMap = CollectionUtils.convertMap(posts, SysPostDO::getId);
307 postIds.forEach(postId -> { 307 postIds.forEach(postId -> {
308 SysPostDO post = postMap.get(postId); 308 SysPostDO post = postMap.get(postId);
309 if (post == null) { 309 if (post == null) {
310 - throw ServiceExceptionUtil.exception(POST_NOT_FOUND); 310 + throw exception(POST_NOT_FOUND);
311 } 311 }
312 if (!CommonStatusEnum.ENABLE.getStatus().equals(post.getStatus())) { 312 if (!CommonStatusEnum.ENABLE.getStatus().equals(post.getStatus())) {
313 - throw ServiceExceptionUtil.exception(POST_NOT_ENABLE, post.getName()); 313 + throw exception(POST_NOT_ENABLE, post.getName());
314 } 314 }
315 }); 315 });
316 } 316 }
@@ -321,13 +321,14 @@ public class SysUserServiceImpl implements SysUserService { @@ -321,13 +321,14 @@ public class SysUserServiceImpl implements SysUserService {
321 * @param id 用户 id 321 * @param id 用户 id
322 * @param oldPassword 旧密码 322 * @param oldPassword 旧密码
323 */ 323 */
324 - private void checkOldPassword(Long id, String oldPassword) { 324 + @VisibleForTesting
  325 + void checkOldPassword(Long id, String oldPassword) {
325 SysUserDO user = userMapper.selectById(id); 326 SysUserDO user = userMapper.selectById(id);
326 if (user == null) { 327 if (user == null) {
327 - throw ServiceExceptionUtil.exception(USER_NOT_EXISTS); 328 + throw exception(USER_NOT_EXISTS);
328 } 329 }
329 if (!passwordEncoder.matches(oldPassword, user.getPassword())) { 330 if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
330 - throw ServiceExceptionUtil.exception(USER_PASSWORD_FAILED); 331 + throw exception(USER_PASSWORD_FAILED);
331 } 332 }
332 } 333 }
333 334
@@ -335,7 +336,7 @@ public class SysUserServiceImpl implements SysUserService { @@ -335,7 +336,7 @@ public class SysUserServiceImpl implements SysUserService {
335 @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入 336 @Transactional(rollbackFor = Exception.class) // 添加事务,异常则回滚所有导入
336 public SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport) { 337 public SysUserImportRespVO importUsers(List<SysUserImportExcelVO> importUsers, boolean isUpdateSupport) {
337 if (CollUtil.isEmpty(importUsers)) { 338 if (CollUtil.isEmpty(importUsers)) {
338 - throw ServiceExceptionUtil.exception(USER_IMPORT_LIST_IS_EMPTY); 339 + throw exception(USER_IMPORT_LIST_IS_EMPTY);
339 } 340 }
340 SysUserImportRespVO respVO = SysUserImportRespVO.builder().createUsernames(new ArrayList<>()) 341 SysUserImportRespVO respVO = SysUserImportRespVO.builder().createUsernames(new ArrayList<>())
341 .updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build(); 342 .updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
@@ -351,8 +352,8 @@ public class SysUserServiceImpl implements SysUserService { @@ -351,8 +352,8 @@ public class SysUserServiceImpl implements SysUserService {
351 // 判断如果不存在,在进行插入 352 // 判断如果不存在,在进行插入
352 SysUserDO existUser = userMapper.selectByUsername(importUser.getUsername()); 353 SysUserDO existUser = userMapper.selectByUsername(importUser.getUsername());
353 if (existUser == null) { 354 if (existUser == null) {
354 - // TODO 芋艿:初始密码  
355 - userMapper.insert(SysUserConvert.INSTANCE.convert(importUser)); 355 + userMapper.insert(SysUserConvert.INSTANCE.convert(importUser)
  356 + .setPassword(passwordEncoder.encode(userInitPassword))); // 设置默认密码
356 respVO.getCreateUsernames().add(importUser.getUsername()); 357 respVO.getCreateUsernames().add(importUser.getUsername());
357 return; 358 return;
358 } 359 }
src/test/java/cn/iocoder/dashboard/modules/system/service/auth/SysUserSessionServiceImplTest.java
1 package cn.iocoder.dashboard.modules.system.service.auth; 1 package cn.iocoder.dashboard.modules.system.service.auth;
2 2
3 import static cn.hutool.core.util.RandomUtil.randomEle; 3 import static cn.hutool.core.util.RandomUtil.randomEle;
4 -import static cn.iocoder.dashboard.modules.system.dal.redis.SysRedisKeyConstants.LOGIN_USER;  
5 import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals; 4 import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
6 import static cn.iocoder.dashboard.util.RandomUtils.randomDate; 5 import static cn.iocoder.dashboard.util.RandomUtils.randomDate;
7 import static cn.iocoder.dashboard.util.RandomUtils.randomLongId; 6 import static cn.iocoder.dashboard.util.RandomUtils.randomLongId;
@@ -25,7 +24,6 @@ import javax.annotation.Resource; @@ -25,7 +24,6 @@ import javax.annotation.Resource;
25 import org.junit.jupiter.api.Test; 24 import org.junit.jupiter.api.Test;
26 import org.springframework.boot.test.mock.mockito.MockBean; 25 import org.springframework.boot.test.mock.mockito.MockBean;
27 import org.springframework.context.annotation.Import; 26 import org.springframework.context.annotation.Import;
28 -import org.springframework.data.redis.core.StringRedisTemplate;  
29 27
30 import cn.hutool.core.date.DateUtil; 28 import cn.hutool.core.date.DateUtil;
31 import cn.iocoder.dashboard.BaseDbAndRedisUnitTest; 29 import cn.iocoder.dashboard.BaseDbAndRedisUnitTest;
@@ -33,10 +31,6 @@ import cn.iocoder.dashboard.common.enums.CommonStatusEnum; @@ -33,10 +31,6 @@ import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
33 import cn.iocoder.dashboard.common.pojo.PageResult; 31 import cn.iocoder.dashboard.common.pojo.PageResult;
34 import cn.iocoder.dashboard.framework.security.config.SecurityProperties; 32 import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
35 import cn.iocoder.dashboard.framework.security.core.LoginUser; 33 import cn.iocoder.dashboard.framework.security.core.LoginUser;
36 -import cn.iocoder.dashboard.modules.infra.controller.job.vo.job.InfJobPageReqVO;  
37 -import cn.iocoder.dashboard.modules.infra.dal.dataobject.job.InfJobDO;  
38 -import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum;  
39 -import cn.iocoder.dashboard.modules.infra.enums.job.InfJobStatusEnum;  
40 import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO; 34 import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO;
41 import cn.iocoder.dashboard.modules.system.dal.dataobject.auth.SysUserSessionDO; 35 import cn.iocoder.dashboard.modules.system.dal.dataobject.auth.SysUserSessionDO;
42 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; 36 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
@@ -50,7 +44,6 @@ import cn.iocoder.dashboard.modules.system.service.logger.impl.SysLoginLogServic @@ -50,7 +44,6 @@ import cn.iocoder.dashboard.modules.system.service.logger.impl.SysLoginLogServic
50 import cn.iocoder.dashboard.modules.system.service.user.SysUserServiceImpl; 44 import cn.iocoder.dashboard.modules.system.service.user.SysUserServiceImpl;
51 import cn.iocoder.dashboard.util.AssertUtils; 45 import cn.iocoder.dashboard.util.AssertUtils;
52 import cn.iocoder.dashboard.util.RandomUtils; 46 import cn.iocoder.dashboard.util.RandomUtils;
53 -import cn.iocoder.dashboard.util.json.JsonUtils;  
54 import cn.iocoder.dashboard.util.object.ObjectUtils; 47 import cn.iocoder.dashboard.util.object.ObjectUtils;
55 48
56 /** 49 /**
@@ -167,12 +160,12 @@ public class SysUserSessionServiceImplTest extends BaseDbAndRedisUnitTest { @@ -167,12 +160,12 @@ public class SysUserSessionServiceImplTest extends BaseDbAndRedisUnitTest {
167 String userIp = randomString(); 160 String userIp = randomString();
168 SysUserDO dbUser1 = randomPojo(SysUserDO.class, o -> { 161 SysUserDO dbUser1 = randomPojo(SysUserDO.class, o -> {
169 o.setUsername("testUsername1"); 162 o.setUsername("testUsername1");
170 - o.setSex(randomEle(SysSexEnum.values()).getSEX()); 163 + o.setSex(randomEle(SysSexEnum.values()).getSex());
171 o.setStatus(CommonStatusEnum.ENABLE.getStatus()); 164 o.setStatus(CommonStatusEnum.ENABLE.getStatus());
172 }); 165 });
173 SysUserDO dbUser2 = randomPojo(SysUserDO.class, o -> { 166 SysUserDO dbUser2 = randomPojo(SysUserDO.class, o -> {
174 o.setUsername("testUsername2"); 167 o.setUsername("testUsername2");
175 - o.setSex(randomEle(SysSexEnum.values()).getSEX()); 168 + o.setSex(randomEle(SysSexEnum.values()).getSex());
176 o.setStatus(CommonStatusEnum.ENABLE.getStatus()); 169 o.setStatus(CommonStatusEnum.ENABLE.getStatus());
177 }); 170 });
178 SysUserSessionDO dbSession = randomPojo(SysUserSessionDO.class, o -> { 171 SysUserSessionDO dbSession = randomPojo(SysUserSessionDO.class, o -> {
src/test/java/cn/iocoder/dashboard/modules/system/service/logger/SysOperateLogServiceImplTest.java
@@ -68,7 +68,7 @@ public class SysOperateLogServiceImplTest extends BaseDbUnitTest { @@ -68,7 +68,7 @@ public class SysOperateLogServiceImplTest extends BaseDbUnitTest {
68 // 先构造用户 68 // 先构造用户
69 SysUserDO user = RandomUtils.randomPojo(SysUserDO.class, o -> { 69 SysUserDO user = RandomUtils.randomPojo(SysUserDO.class, o -> {
70 o.setNickname("wangkai"); 70 o.setNickname("wangkai");
71 - o.setSex(SysSexEnum.MALE.getSEX()); 71 + o.setSex(SysSexEnum.MALE.getSex());
72 o.setStatus(CommonStatusEnum.ENABLE.getStatus()); 72 o.setStatus(CommonStatusEnum.ENABLE.getStatus());
73 }); 73 });
74 when(userService.getUsersByNickname("wangkai")).thenReturn(Collections.singletonList(user)); 74 when(userService.getUsersByNickname("wangkai")).thenReturn(Collections.singletonList(user));
@@ -119,7 +119,7 @@ public class SysOperateLogServiceImplTest extends BaseDbUnitTest { @@ -119,7 +119,7 @@ public class SysOperateLogServiceImplTest extends BaseDbUnitTest {
119 // 先构造用户 119 // 先构造用户
120 SysUserDO user = RandomUtils.randomPojo(SysUserDO.class, o -> { 120 SysUserDO user = RandomUtils.randomPojo(SysUserDO.class, o -> {
121 o.setNickname("wangkai"); 121 o.setNickname("wangkai");
122 - o.setSex(SysSexEnum.MALE.getSEX()); 122 + o.setSex(SysSexEnum.MALE.getSex());
123 o.setStatus(CommonStatusEnum.ENABLE.getStatus()); 123 o.setStatus(CommonStatusEnum.ENABLE.getStatus());
124 }); 124 });
125 when(userService.getUsersByNickname("wangkai")).thenReturn(Collections.singletonList(user)); 125 when(userService.getUsersByNickname("wangkai")).thenReturn(Collections.singletonList(user));
src/test/java/cn/iocoder/dashboard/modules/system/service/sms/SysSmsChannelServiceTest.java
@@ -56,7 +56,7 @@ public class SysSmsChannelServiceTest extends BaseDbUnitTest { @@ -56,7 +56,7 @@ public class SysSmsChannelServiceTest extends BaseDbUnitTest {
56 56
57 @Test 57 @Test
58 public void testInitLocalCache_success() { 58 public void testInitLocalCache_success() {
59 - // mock 数据s 59 + // mock 数据
60 SysSmsChannelDO smsChannelDO01 = randomSmsChannelDO(); 60 SysSmsChannelDO smsChannelDO01 = randomSmsChannelDO();
61 smsChannelMapper.insert(smsChannelDO01); 61 smsChannelMapper.insert(smsChannelDO01);
62 SysSmsChannelDO smsChannelDO02 = randomSmsChannelDO(); 62 SysSmsChannelDO smsChannelDO02 = randomSmsChannelDO();
src/test/java/cn/iocoder/dashboard/modules/system/service/user/SysUserServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.dashboard.modules.system.service.user;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.RandomUtil;
  5 +import cn.iocoder.dashboard.BaseDbUnitTest;
  6 +import cn.iocoder.dashboard.common.enums.CommonStatusEnum;
  7 +import cn.iocoder.dashboard.common.pojo.PageResult;
  8 +import cn.iocoder.dashboard.modules.infra.service.file.InfFileService;
  9 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
  10 +import cn.iocoder.dashboard.modules.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
  11 +import cn.iocoder.dashboard.modules.system.controller.user.vo.user.*;
  12 +import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysDeptDO;
  13 +import cn.iocoder.dashboard.modules.system.dal.dataobject.dept.SysPostDO;
  14 +import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
  15 +import cn.iocoder.dashboard.modules.system.dal.mysql.user.SysUserMapper;
  16 +import cn.iocoder.dashboard.modules.system.enums.common.SysSexEnum;
  17 +import cn.iocoder.dashboard.modules.system.service.dept.SysDeptService;
  18 +import cn.iocoder.dashboard.modules.system.service.dept.SysPostService;
  19 +import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService;
  20 +import cn.iocoder.dashboard.util.collection.ArrayUtils;
  21 +import cn.iocoder.dashboard.util.collection.CollectionUtils;
  22 +import cn.iocoder.dashboard.util.object.ObjectUtils;
  23 +import org.junit.jupiter.api.Test;
  24 +import org.mockito.stubbing.Answer;
  25 +import org.springframework.boot.test.mock.mockito.MockBean;
  26 +import org.springframework.context.annotation.Import;
  27 +import org.springframework.security.crypto.password.PasswordEncoder;
  28 +
  29 +import javax.annotation.Resource;
  30 +import java.io.ByteArrayInputStream;
  31 +import java.util.List;
  32 +import java.util.Set;
  33 +import java.util.function.Consumer;
  34 +
  35 +import static cn.hutool.core.util.RandomUtil.randomBytes;
  36 +import static cn.hutool.core.util.RandomUtil.randomEle;
  37 +import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*;
  38 +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
  39 +import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException;
  40 +import static cn.iocoder.dashboard.util.RandomUtils.*;
  41 +import static cn.iocoder.dashboard.util.date.DateUtils.buildTime;
  42 +import static org.assertj.core.util.Lists.newArrayList;
  43 +import static org.junit.jupiter.api.Assertions.assertEquals;
  44 +import static org.junit.jupiter.api.Assertions.assertNull;
  45 +import static org.mockito.ArgumentMatchers.*;
  46 +import static org.mockito.Mockito.*;
  47 +
  48 +/**
  49 + * {@link SysUserService} 的单元测试类
  50 + *
  51 + * @author zxl
  52 + */
  53 +@Import(SysUserServiceImpl.class)
  54 +public class SysUserServiceImplTest extends BaseDbUnitTest {
  55 +
  56 + @Resource
  57 + private SysUserServiceImpl userService;
  58 +
  59 + @Resource
  60 + private SysUserMapper userMapper;
  61 +
  62 + @MockBean
  63 + private SysDeptService deptService;
  64 + @MockBean
  65 + private SysPostService postService;
  66 + @MockBean
  67 + private SysPermissionService permissionService;
  68 + @MockBean
  69 + private PasswordEncoder passwordEncoder;
  70 + @MockBean
  71 + private InfFileService fileService;
  72 +
  73 + @Test
  74 + public void testCreatUser_success() {
  75 + // 准备参数
  76 + SysUserCreateReqVO reqVO = randomPojo(SysUserCreateReqVO.class, o -> {
  77 + o.setSex(RandomUtil.randomEle(SysSexEnum.values()).getSex());
  78 + o.setMobile(randomString());
  79 + });
  80 + // mock deptService 的方法
  81 + SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
  82 + o.setId(reqVO.getDeptId());
  83 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  84 + });
  85 + when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
  86 + // mock postService 的方法
  87 + List<SysPostDO> posts = CollectionUtils.convertList(reqVO.getPostIds(), postId ->
  88 + randomPojo(SysPostDO.class, o -> {
  89 + o.setId(postId);
  90 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  91 + }));
  92 + when(postService.getPosts(eq(reqVO.getPostIds()), isNull())).thenReturn(posts);
  93 + // mock passwordEncoder 的方法
  94 + when(passwordEncoder.encode(eq(reqVO.getPassword()))).thenReturn("yudaoyuanma");
  95 +
  96 + // 调用
  97 + Long userId = userService.createUser(reqVO);
  98 + // 断言
  99 + SysUserDO user = userMapper.selectById(userId);
  100 + assertPojoEquals(reqVO, user, "password");
  101 + assertEquals("yudaoyuanma", user.getPassword());
  102 + assertEquals(CommonStatusEnum.ENABLE.getStatus(), user.getStatus());
  103 + }
  104 +
  105 + @Test
  106 + public void testUpdateUser_success() {
  107 + // mock 数据
  108 + SysUserDO dbUser = randomSysUserDO();
  109 + userMapper.insert(dbUser);
  110 + // 准备参数
  111 + SysUserUpdateReqVO reqVO = randomPojo(SysUserUpdateReqVO.class, o -> {
  112 + o.setId(dbUser.getId());
  113 + o.setSex(RandomUtil.randomEle(SysSexEnum.values()).getSex());
  114 + o.setMobile(randomString());
  115 + });
  116 + // mock deptService 的方法
  117 + SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
  118 + o.setId(reqVO.getDeptId());
  119 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  120 + });
  121 + when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
  122 + // mock postService 的方法
  123 + List<SysPostDO> posts = CollectionUtils.convertList(reqVO.getPostIds(), postId ->
  124 + randomPojo(SysPostDO.class, o -> {
  125 + o.setId(postId);
  126 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  127 + }));
  128 + when(postService.getPosts(eq(reqVO.getPostIds()), isNull())).thenReturn(posts);
  129 +
  130 + // 调用
  131 + userService.updateUser(reqVO);
  132 + // 断言
  133 + SysUserDO user = userMapper.selectById(reqVO.getId());
  134 + assertPojoEquals(reqVO, user);
  135 + }
  136 +
  137 + @Test
  138 + public void testUpdateUserProfile_success() {
  139 + // mock 数据
  140 + SysUserDO dbUser = randomSysUserDO();
  141 + userMapper.insert(dbUser);
  142 + // 准备参数
  143 + Long userId = dbUser.getId();
  144 + SysUserProfileUpdateReqVO reqVO = randomPojo(SysUserProfileUpdateReqVO.class, o -> {
  145 + o.setMobile(randomString());
  146 + o.setSex(RandomUtil.randomEle(SysSexEnum.values()).getSex());
  147 + });
  148 +
  149 + // 调用
  150 + userService.updateUserProfile(userId, reqVO);
  151 + // 断言
  152 + SysUserDO user = userMapper.selectById(userId);
  153 + assertPojoEquals(reqVO, user);
  154 + }
  155 +
  156 + @Test
  157 + public void testUpdateUserPassword_success() {
  158 + // mock 数据
  159 + SysUserDO dbUser = randomSysUserDO(o -> o.setPassword("encode:yudao"));
  160 + userMapper.insert(dbUser);
  161 + // 准备参数
  162 + Long userId = dbUser.getId();
  163 + SysUserProfileUpdatePasswordReqVO reqVO = randomPojo(SysUserProfileUpdatePasswordReqVO.class, o -> {
  164 + o.setOldPassword("yudao");
  165 + o.setNewPassword("yuanma");
  166 + });
  167 + // mock 方法
  168 + when(passwordEncoder.encode(anyString())).then(
  169 + (Answer<String>) invocationOnMock -> "encode:" + invocationOnMock.getArgument(0));
  170 + when(passwordEncoder.matches(eq(reqVO.getOldPassword()), eq(dbUser.getPassword()))).thenReturn(true);
  171 +
  172 + // 调用
  173 + userService.updateUserPassword(userId, reqVO);
  174 + // 断言
  175 + SysUserDO user = userMapper.selectById(userId);
  176 + assertEquals("encode:yuanma", user.getPassword());
  177 + }
  178 +
  179 + @Test
  180 + public void testUpdateUserAvatar_success() {
  181 + // mock 数据
  182 + SysUserDO dbUser = randomSysUserDO();
  183 + userMapper.insert(dbUser);
  184 + // 准备参数
  185 + Long userId = dbUser.getId();
  186 + byte[] avatarFileBytes = randomBytes(10);
  187 + ByteArrayInputStream avatarFile = new ByteArrayInputStream(avatarFileBytes);
  188 + // mock 方法
  189 + String avatar = randomString();
  190 + when(fileService.createFile(anyString(), eq(avatarFileBytes))).thenReturn(avatar);
  191 +
  192 + // 调用
  193 + userService.updateUserAvatar(userId, avatarFile);
  194 + // 断言
  195 + SysUserDO user = userMapper.selectById(userId);
  196 + assertEquals(avatar, user.getAvatar());
  197 + }
  198 +
  199 + @Test
  200 + public void testUpdateUserPassword02_success() {
  201 + // mock 数据
  202 + SysUserDO dbUser = randomSysUserDO();
  203 + userMapper.insert(dbUser);
  204 + // 准备参数
  205 + Long userId = dbUser.getId();
  206 + String password = "yudao";
  207 + // mock 方法
  208 + when(passwordEncoder.encode(anyString())).then(
  209 + (Answer<String>) invocationOnMock -> "encode:" + invocationOnMock.getArgument(0));
  210 +
  211 + // 调用
  212 + userService.updateUserPassword(userId, password);
  213 + // 断言
  214 + SysUserDO user = userMapper.selectById(userId);
  215 + assertEquals("encode:" + password, user.getPassword());
  216 + }
  217 +
  218 + @Test
  219 + public void testUpdateUserStatus() {
  220 + // mock 数据
  221 + SysUserDO dbUser = randomSysUserDO();
  222 + userMapper.insert(dbUser);
  223 + // 准备参数
  224 + Long userId = dbUser.getId();
  225 + Integer status = randomCommonStatus();
  226 +
  227 + // 调用
  228 + userService.updateUserStatus(userId, status);
  229 + // 断言
  230 + SysUserDO user = userMapper.selectById(userId);
  231 + assertEquals(status, user.getStatus());
  232 + }
  233 +
  234 + @Test
  235 + public void testDeleteUser_success(){
  236 + // mock 数据
  237 + SysUserDO dbUser = randomSysUserDO();
  238 + userMapper.insert(dbUser);
  239 + // 准备参数
  240 + Long userId = dbUser.getId();
  241 +
  242 + // 调用数据
  243 + userService.deleteUser(userId);
  244 + // 校验结果
  245 + assertNull(userService.getUser(userId));
  246 + // 校验调用次数
  247 + verify(permissionService, times(1)).processUserDeleted(eq(userId));
  248 + }
  249 +
  250 + @Test
  251 + public void testGetUserPage() {
  252 + // mock 数据
  253 + SysUserDO dbUser = initGetUserPageData();
  254 + // 准备参数
  255 + SysUserPageReqVO reqVO = new SysUserPageReqVO();
  256 + reqVO.setUsername("yudao");
  257 + reqVO.setMobile("1560");
  258 + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  259 + reqVO.setBeginTime(buildTime(2020, 12, 1));
  260 + reqVO.setEndTime(buildTime(2020, 12, 24));
  261 + reqVO.setDeptId(1L); // 其中,1L 是 2L 的父部门
  262 + // mock 方法
  263 + List<SysDeptDO> deptList = newArrayList(randomPojo(SysDeptDO.class, o -> o.setId(2L)));
  264 + when(deptService.getDeptsByParentIdFromCache(eq(reqVO.getDeptId()), eq(true))).thenReturn(deptList);
  265 +
  266 + // 调用
  267 + PageResult<SysUserDO> pageResult = userService.getUserPage(reqVO);
  268 + // 断言
  269 + assertEquals(1, pageResult.getTotal());
  270 + assertEquals(1, pageResult.getList().size());
  271 + assertPojoEquals(dbUser, pageResult.getList().get(0));
  272 + }
  273 +
  274 + @Test
  275 + public void testGetUsers() {
  276 + // mock 数据
  277 + SysUserDO dbUser = initGetUserPageData();
  278 + // 准备参数
  279 + SysUserExportReqVO reqVO = new SysUserExportReqVO();
  280 + reqVO.setUsername("yudao");
  281 + reqVO.setMobile("1560");
  282 + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  283 + reqVO.setBeginTime(buildTime(2020, 12, 1));
  284 + reqVO.setEndTime(buildTime(2020, 12, 24));
  285 + reqVO.setDeptId(1L); // 其中,1L 是 2L 的父部门
  286 + // mock 方法
  287 + List<SysDeptDO> deptList = newArrayList(randomPojo(SysDeptDO.class, o -> o.setId(2L)));
  288 + when(deptService.getDeptsByParentIdFromCache(eq(reqVO.getDeptId()), eq(true))).thenReturn(deptList);
  289 +
  290 + // 调用
  291 + List<SysUserDO> list = userService.getUsers(reqVO);
  292 + // 断言
  293 + assertEquals(1, list.size());
  294 + assertPojoEquals(dbUser, list.get(0));
  295 + }
  296 +
  297 + /**
  298 + * 初始化 getUserPage 方法的测试数据
  299 + */
  300 + private SysUserDO initGetUserPageData() {
  301 + // mock 数据
  302 + SysUserDO dbUser = randomSysUserDO(o -> { // 等会查询到
  303 + o.setUsername("yudaoyuanma");
  304 + o.setMobile("15601691300");
  305 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  306 + o.setCreateTime(buildTime(2020, 12, 12));
  307 + o.setDeptId(2L);
  308 + });
  309 + userMapper.insert(dbUser);
  310 + // 测试 username 不匹配
  311 + userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setUsername("yuanma")));
  312 + // 测试 mobile 不匹配
  313 + userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setMobile("18818260888")));
  314 + // 测试 status 不匹配
  315 + userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
  316 + // 测试 createTime 不匹配
  317 + userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setCreateTime(buildTime(2020, 11, 11))));
  318 + // 测试 dept 不匹配
  319 + userMapper.insert(ObjectUtils.clone(dbUser, o -> o.setDeptId(0L)));
  320 + return dbUser;
  321 + }
  322 +
  323 + /**
  324 + * 情况一,校验不通过,导致插入失败
  325 + */
  326 + @Test
  327 + public void testImportUsers_01() {
  328 + // 准备参数
  329 + SysUserImportExcelVO importUser = randomPojo(SysUserImportExcelVO.class);
  330 + // mock 方法
  331 +
  332 + // 调用
  333 + SysUserImportRespVO respVO = userService.importUsers(newArrayList(importUser), true);
  334 + // 断言
  335 + assertEquals(0, respVO.getCreateUsernames().size());
  336 + assertEquals(0, respVO.getUpdateUsernames().size());
  337 + assertEquals(1, respVO.getFailureUsernames().size());
  338 + assertEquals(DEPT_NOT_FOUND.getMsg(), respVO.getFailureUsernames().get(importUser.getUsername()));
  339 + }
  340 +
  341 + /**
  342 + * 情况二,不存在,进行插入
  343 + */
  344 + @Test
  345 + public void testImportUsers_02() {
  346 + // 准备参数
  347 + SysUserImportExcelVO importUser = randomPojo(SysUserImportExcelVO.class, o -> {
  348 + o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
  349 + o.setSex(randomEle(SysSexEnum.values()).getSex()); // 保证 sex 的范围
  350 + });
  351 + // mock deptService 的方法
  352 + SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
  353 + o.setId(importUser.getDeptId());
  354 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  355 + });
  356 + when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
  357 + // mock passwordEncoder 的方法
  358 + when(passwordEncoder.encode(eq("yudaoyuanma"))).thenReturn("java");
  359 +
  360 + // 调用
  361 + SysUserImportRespVO respVO = userService.importUsers(newArrayList(importUser), true);
  362 + // 断言
  363 + assertEquals(1, respVO.getCreateUsernames().size());
  364 + SysUserDO user = userMapper.selectByUsername(respVO.getCreateUsernames().get(0));
  365 + assertPojoEquals(importUser, user);
  366 + assertEquals("java", user.getPassword());
  367 + assertEquals(0, respVO.getUpdateUsernames().size());
  368 + assertEquals(0, respVO.getFailureUsernames().size());
  369 + }
  370 +
  371 + /**
  372 + * 情况三,存在,但是不强制更新
  373 + */
  374 + @Test
  375 + public void testImportUsers_03() {
  376 + // mock 数据
  377 + SysUserDO dbUser = randomSysUserDO();
  378 + userMapper.insert(dbUser);
  379 + // 准备参数
  380 + SysUserImportExcelVO importUser = randomPojo(SysUserImportExcelVO.class, o -> {
  381 + o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
  382 + o.setSex(randomEle(SysSexEnum.values()).getSex()); // 保证 sex 的范围
  383 + o.setUsername(dbUser.getUsername());
  384 + });
  385 + // mock deptService 的方法
  386 + SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
  387 + o.setId(importUser.getDeptId());
  388 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  389 + });
  390 + when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
  391 +
  392 + // 调用
  393 + SysUserImportRespVO respVO = userService.importUsers(newArrayList(importUser), false);
  394 + // 断言
  395 + assertEquals(0, respVO.getCreateUsernames().size());
  396 + assertEquals(0, respVO.getUpdateUsernames().size());
  397 + assertEquals(1, respVO.getFailureUsernames().size());
  398 + assertEquals(USER_USERNAME_EXISTS.getMsg(), respVO.getFailureUsernames().get(importUser.getUsername()));
  399 + }
  400 +
  401 + /**
  402 + * 情况四,存在,强制更新
  403 + */
  404 + @Test
  405 + public void testImportUsers_04() {
  406 + // mock 数据
  407 + SysUserDO dbUser = randomSysUserDO();
  408 + userMapper.insert(dbUser);
  409 + // 准备参数
  410 + SysUserImportExcelVO importUser = randomPojo(SysUserImportExcelVO.class, o -> {
  411 + o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
  412 + o.setSex(randomEle(SysSexEnum.values()).getSex()); // 保证 sex 的范围
  413 + o.setUsername(dbUser.getUsername());
  414 + });
  415 + // mock deptService 的方法
  416 + SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
  417 + o.setId(importUser.getDeptId());
  418 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  419 + });
  420 + when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
  421 +
  422 + // 调用
  423 + SysUserImportRespVO respVO = userService.importUsers(newArrayList(importUser), true);
  424 + // 断言
  425 + assertEquals(0, respVO.getCreateUsernames().size());
  426 + assertEquals(1, respVO.getUpdateUsernames().size());
  427 + SysUserDO user = userMapper.selectByUsername(respVO.getUpdateUsernames().get(0));
  428 + assertPojoEquals(importUser, user);
  429 + assertEquals(0, respVO.getFailureUsernames().size());
  430 + }
  431 +
  432 + @Test
  433 + public void testCheckUserExists_notExists() {
  434 + assertServiceException(() -> userService.checkUserExists(randomLongId()), USER_NOT_EXISTS);
  435 + }
  436 +
  437 + @Test
  438 + public void testCheckUsernameUnique_usernameExistsForCreate() {
  439 + // 准备参数
  440 + String username = randomString();
  441 + // mock 数据
  442 + userMapper.insert(randomSysUserDO(o -> o.setUsername(username)));
  443 +
  444 + // 调用,校验异常
  445 + assertServiceException(() -> userService.checkUsernameUnique(null, username),
  446 + USER_USERNAME_EXISTS);
  447 + }
  448 +
  449 + @Test
  450 + public void testCheckUsernameUnique_usernameExistsForUpdate() {
  451 + // 准备参数
  452 + Long id = randomLongId();
  453 + String username = randomString();
  454 + // mock 数据
  455 + userMapper.insert(randomSysUserDO(o -> o.setUsername(username)));
  456 +
  457 + // 调用,校验异常
  458 + assertServiceException(() -> userService.checkUsernameUnique(id, username),
  459 + USER_USERNAME_EXISTS);
  460 + }
  461 +
  462 + @Test
  463 + public void testCheckEmailUnique_emailExistsForCreate() {
  464 + // 准备参数
  465 + String email = randomString();
  466 + // mock 数据
  467 + userMapper.insert(randomSysUserDO(o -> o.setEmail(email)));
  468 +
  469 + // 调用,校验异常
  470 + assertServiceException(() -> userService.checkEmailUnique(null, email),
  471 + USER_EMAIL_EXISTS);
  472 + }
  473 +
  474 + @Test
  475 + public void testCheckEmailUnique_emailExistsForUpdate() {
  476 + // 准备参数
  477 + Long id = randomLongId();
  478 + String email = randomString();
  479 + // mock 数据
  480 + userMapper.insert(randomSysUserDO(o -> o.setEmail(email)));
  481 +
  482 + // 调用,校验异常
  483 + assertServiceException(() -> userService.checkEmailUnique(id, email),
  484 + USER_EMAIL_EXISTS);
  485 + }
  486 +
  487 + @Test
  488 + public void testCheckMobileUnique_mobileExistsForCreate() {
  489 + // 准备参数
  490 + String mobile = randomString();
  491 + // mock 数据
  492 + userMapper.insert(randomSysUserDO(o -> o.setMobile(mobile)));
  493 +
  494 + // 调用,校验异常
  495 + assertServiceException(() -> userService.checkMobileUnique(null, mobile),
  496 + USER_MOBILE_EXISTS);
  497 + }
  498 +
  499 + @Test
  500 + public void testCheckMobileUnique_mobileExistsForUpdate() {
  501 + // 准备参数
  502 + Long id = randomLongId();
  503 + String mobile = randomString();
  504 + // mock 数据
  505 + userMapper.insert(randomSysUserDO(o -> o.setMobile(mobile)));
  506 +
  507 + // 调用,校验异常
  508 + assertServiceException(() -> userService.checkMobileUnique(id, mobile),
  509 + USER_MOBILE_EXISTS);
  510 + }
  511 +
  512 + @Test
  513 + public void testCheckDeptEnable_notFound() {
  514 + assertServiceException(() -> userService.checkDeptEnable(randomLongId()),
  515 + DEPT_NOT_FOUND);
  516 + }
  517 +
  518 + @Test
  519 + public void testCheckDeptEnable_notEnable() {
  520 + // 准备参数
  521 + Long deptId = randomLongId();
  522 + // mock deptService 的方法
  523 + SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
  524 + o.setId(deptId);
  525 + o.setStatus(CommonStatusEnum.DISABLE.getStatus());
  526 + });
  527 + when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
  528 +
  529 + // 调用,校验异常
  530 + assertServiceException(() -> userService.checkDeptEnable(deptId),
  531 + DEPT_NOT_ENABLE);
  532 + }
  533 +
  534 + @Test
  535 + public void testCheckPostEnable_notFound() {
  536 + assertServiceException(() -> userService.checkPostEnable(randomSet(Long.class)),
  537 + POST_NOT_FOUND);
  538 + }
  539 +
  540 + @Test
  541 + public void testCheckPostEnable_notEnable() {
  542 + // 准备参数
  543 + Set<Long> postIds = randomSet(Long.class);
  544 + // mock postService 的方法
  545 + List<SysPostDO> posts = CollectionUtils.convertList(postIds, postId ->
  546 + randomPojo(SysPostDO.class, o -> {
  547 + o.setId(postId);
  548 + o.setStatus(CommonStatusEnum.DISABLE.getStatus());
  549 + }));
  550 + when(postService.getPosts(eq(postIds), isNull())).thenReturn(posts);
  551 +
  552 + // 调用,校验异常
  553 + assertServiceException(() -> userService.checkPostEnable(postIds),
  554 + POST_NOT_ENABLE, CollUtil.getFirst(posts).getName());
  555 + }
  556 +
  557 + @Test
  558 + public void testCheckOldPassword_notExists() {
  559 + assertServiceException(() -> userService.checkOldPassword(randomLongId(), randomString()),
  560 + USER_NOT_EXISTS);
  561 + }
  562 +
  563 + @Test
  564 + public void testCheckOldPassword_passwordFailed() {
  565 + // mock 数据
  566 + SysUserDO user = randomSysUserDO();
  567 + userMapper.insert(user);
  568 + // 准备参数
  569 + Long id = user.getId();
  570 + String oldPassword = user.getPassword();
  571 +
  572 + // 调用,校验异常
  573 + assertServiceException(() -> userService.checkOldPassword(id, oldPassword),
  574 + USER_PASSWORD_FAILED);
  575 + // 校验调用
  576 + verify(passwordEncoder, times(1)).matches(eq(oldPassword), eq(user.getPassword()));
  577 + }
  578 +
  579 + // ========== 随机对象 ==========
  580 +
  581 + @SafeVarargs
  582 + private static SysUserDO randomSysUserDO(Consumer<SysUserDO>... consumers) {
  583 + Consumer<SysUserDO> consumer = (o) -> {
  584 + o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
  585 + o.setSex(randomEle(SysSexEnum.values()).getSex()); // 保证 sex 的范围
  586 + };
  587 + return randomPojo(SysUserDO.class, ArrayUtils.append(consumer, consumers));
  588 + }
  589 +
  590 +}