Commit cf0cfc7ed02e0fbc52b158a8860e9733e6c7384b

Authored by zichun
1 parent b96ba80c

feat(usr): UserCreateDTO + Bean Validation REQ-USR-001

backend/src/main/java/com/xly/test4/module/usr/dto/UserCreateDTO.java 0 → 100644
  1 +package com.xly.test4.module.usr.dto;
  2 +
  3 +import jakarta.validation.constraints.NotBlank;
  4 +import jakarta.validation.constraints.NotNull;
  5 +import jakarta.validation.constraints.Pattern;
  6 +import jakarta.validation.constraints.Size;
  7 +import lombok.Data;
  8 +
  9 +import java.util.List;
  10 +
  11 +@Data
  12 +public class UserCreateDTO {
  13 +
  14 + @NotBlank(message = "用户号不能为空")
  15 + @Size(max = 32, message = "用户号长度不能超过 32")
  16 + private String userCode;
  17 +
  18 + @NotBlank(message = "用户名不能为空")
  19 + @Size(max = 50, message = "用户名长度不能超过 50")
  20 + private String userName;
  21 +
  22 + private Integer employeeId;
  23 +
  24 + @NotBlank(message = "用户类型不能为空")
  25 + @Pattern(regexp = "NORMAL|ADMIN", message = "用户类型必须为 NORMAL 或 ADMIN")
  26 + private String userType;
  27 +
  28 + @NotBlank(message = "语言不能为空")
  29 + @Pattern(regexp = "zh-CN|en|zh-TW", message = "语言必须为 zh-CN / en / zh-TW")
  30 + private String language;
  31 +
  32 + @NotNull(message = "单据修改权限标志不能为空")
  33 + private Boolean canEditDoc;
  34 +
  35 + @Size(min = 1, max = 64, message = "密码长度需在 1-64 字符之间")
  36 + private String password;
  37 +
  38 + private List<Integer> permissionIds;
  39 +}
backend/src/test/java/com/xly/test4/module/usr/dto/UserCreateDTOValidationTest.java 0 → 100644
  1 +package com.xly.test4.module.usr.dto;
  2 +
  3 +import jakarta.validation.ConstraintViolation;
  4 +import jakarta.validation.Validation;
  5 +import jakarta.validation.Validator;
  6 +import jakarta.validation.ValidatorFactory;
  7 +import org.junit.jupiter.api.AfterAll;
  8 +import org.junit.jupiter.api.BeforeAll;
  9 +import org.junit.jupiter.api.Test;
  10 +
  11 +import java.util.List;
  12 +import java.util.Set;
  13 +
  14 +import static org.assertj.core.api.Assertions.assertThat;
  15 +
  16 +class UserCreateDTOValidationTest {
  17 +
  18 + private static ValidatorFactory factory;
  19 + private static Validator validator;
  20 +
  21 + @BeforeAll
  22 + static void setUp() {
  23 + factory = Validation.buildDefaultValidatorFactory();
  24 + validator = factory.getValidator();
  25 + }
  26 +
  27 + @AfterAll
  28 + static void tearDown() {
  29 + factory.close();
  30 + }
  31 +
  32 + private UserCreateDTO validDTO() {
  33 + UserCreateDTO dto = new UserCreateDTO();
  34 + dto.setUserCode("U-001");
  35 + dto.setUserName("alice");
  36 + dto.setEmployeeId(null);
  37 + dto.setUserType("NORMAL");
  38 + dto.setLanguage("zh-CN");
  39 + dto.setCanEditDoc(false);
  40 + dto.setPassword("Pass1234");
  41 + dto.setPermissionIds(List.of());
  42 + return dto;
  43 + }
  44 +
  45 + @Test
  46 + void allRequiredFieldsValid_zeroViolations() {
  47 + assertThat(validator.validate(validDTO())).isEmpty();
  48 + }
  49 +
  50 + @Test
  51 + void userNameBlank_violatesNotBlank() {
  52 + UserCreateDTO dto = validDTO();
  53 + dto.setUserName("");
  54 +
  55 + Set<ConstraintViolation<UserCreateDTO>> violations = validator.validate(dto);
  56 + assertThat(violations).extracting(v -> v.getPropertyPath().toString())
  57 + .contains("userName");
  58 + }
  59 +
  60 + @Test
  61 + void userTypeOutOfEnum_violatesPattern() {
  62 + UserCreateDTO dto = validDTO();
  63 + dto.setUserType("FOO");
  64 +
  65 + assertThat(validator.validate(dto))
  66 + .extracting(v -> v.getPropertyPath().toString())
  67 + .contains("userType");
  68 + }
  69 +
  70 + @Test
  71 + void languageOutOfEnum_violatesPattern() {
  72 + UserCreateDTO dto = validDTO();
  73 + dto.setLanguage("fr");
  74 +
  75 + assertThat(validator.validate(dto))
  76 + .extracting(v -> v.getPropertyPath().toString())
  77 + .contains("language");
  78 + }
  79 +
  80 + @Test
  81 + void userCodeOver32Chars_violatesSize() {
  82 + UserCreateDTO dto = validDTO();
  83 + dto.setUserCode("X".repeat(33));
  84 +
  85 + assertThat(validator.validate(dto))
  86 + .extracting(v -> v.getPropertyPath().toString())
  87 + .contains("userCode");
  88 + }
  89 +
  90 + @Test
  91 + void canEditDocNull_violatesNotNull() {
  92 + UserCreateDTO dto = validDTO();
  93 + dto.setCanEditDoc(null);
  94 +
  95 + assertThat(validator.validate(dto))
  96 + .extracting(v -> v.getPropertyPath().toString())
  97 + .contains("canEditDoc");
  98 + }
  99 +
  100 + @Test
  101 + void passwordOver64Chars_violatesSize() {
  102 + UserCreateDTO dto = validDTO();
  103 + dto.setPassword("p".repeat(65));
  104 +
  105 + assertThat(validator.validate(dto))
  106 + .extracting(v -> v.getPropertyPath().toString())
  107 + .contains("password");
  108 + }
  109 +
  110 + @Test
  111 + void passwordNull_isAllowed() {
  112 + UserCreateDTO dto = validDTO();
  113 + dto.setPassword(null);
  114 +
  115 + assertThat(validator.validate(dto)).isEmpty();
  116 + }
  117 +}