feat(app): app_code/app_nature 编辑必填(C5,2026-09-28 拍板)——校验组 Create 扩 {Create,Update},存量 null 历史行不追溯;学校覆盖分支由前端回传原值满足校验(editAppForSchool 只读 name/desc/pcIcon 不受影响)
build / build-push (push) Failing after 49s

This commit is contained in:
chenxing
2026-09-28 17:07:44 +08:00
parent 7e222f19b8
commit 8f8a6b8cca
2 changed files with 89 additions and 6 deletions
@@ -36,18 +36,18 @@ public class ApplicationInfoRequest {
private Integer categoryId; private Integer categoryId;
/** /**
* 技术标识(= projman app.name,如 notice),全库唯一,新增必填。<br> * 技术标识(= projman app.name,如 notice),全库唯一,新增与编辑均必填。<br>
* 编辑不强制(部分提交场景不回传则保持原值);值域为引用键,改名须盘点引用。 * 编辑必填(2026-09-28 拍板):app_code 是应用身份锚点(消息 jump_app/服务目录键),不许置空;
* 存量 null 历史行不追溯,但编辑提交时必须补填。值域为引用键,改名须盘点引用。
*/ */
@NotBlank(groups = ValidationGroups.Create.class, message = "技术标识不能为空") @NotBlank(groups = {ValidationGroups.Create.class, ValidationGroups.Update.class}, message = "技术标识不能为空")
@Size(max = 32, message = "技术标识长度不能超过32") @Size(max = 32, message = "技术标识长度不能超过32")
private String appCode; private String appCode;
/** /**
* 应用性质:BASE=基石 / BUSINESS=业务,新增必填。<br> * 应用性质:BASE=基石 / BUSINESS=业务,新增与编辑均必填(2026-09-28 拍板,存量 null 行不追溯)。
* 编辑不强制(不回传则保持原值);学校模式覆盖线不涉及本字段。
*/ */
@NotBlank(groups = ValidationGroups.Create.class, message = "应用性质不能为空") @NotBlank(groups = {ValidationGroups.Create.class, ValidationGroups.Update.class}, message = "应用性质不能为空")
@Size(max = 16, message = "应用性质长度不能超过16") @Size(max = 16, message = "应用性质长度不能超过16")
private String appNature; private String appNature;
@@ -0,0 +1,83 @@
package com.yunhai.userbase.model.application;
import com.yunhai.userbase.common.validation.ValidationGroups;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* app_code / app_nature 编辑必填校验组单测(消息方案 C5,2026-09-28 拍板:新增/编辑均必填,
* 存量 null 历史行不追溯)。Create 组此前已必填;本测试冻结 Update 组同口径——
* 编辑提交置空 → 校验失败;带值 → 通过。学校模式覆盖线由前端分支原样回传原值满足校验
* (后端 editAppForSchool 只读 name/desc/pcIcon,其余字段忽略)。
*/
@DisplayName("ApplicationInfoRequest - app_code/app_nature 新增与编辑均必填")
class ApplicationInfoRequestValidationTest {
private static Validator validator;
@BeforeAll
static void setUp() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}
private ApplicationInfoRequest validRequest() {
ApplicationInfoRequest request = new ApplicationInfoRequest();
request.setId(100011);
request.setName("流程中心");
request.setCategoryId(2);
request.setAppCode("flow-center");
request.setAppNature("BUSINESS");
return request;
}
private static boolean hasViolation(Set<ConstraintViolation<ApplicationInfoRequest>> violations, String field) {
return violations.stream().anyMatch(v -> v.getPropertyPath().toString().equals(field));
}
@Test
void edit_空appCode_校验失败() {
ApplicationInfoRequest request = validRequest();
request.setAppCode(" ");
Set<ConstraintViolation<ApplicationInfoRequest>> violations =
validator.validate(request, ValidationGroups.Update.class);
assertTrue(hasViolation(violations, "appCode"), "编辑时技术标识置空必须被 Update 组拦截");
}
@Test
void edit_空appNature_校验失败() {
ApplicationInfoRequest request = validRequest();
request.setAppNature(null);
Set<ConstraintViolation<ApplicationInfoRequest>> violations =
validator.validate(request, ValidationGroups.Update.class);
assertTrue(hasViolation(violations, "appNature"), "编辑时应用性质置空必须被 Update 组拦截");
}
@Test
void edit_带appCodeAppNature_通过() {
Set<ConstraintViolation<ApplicationInfoRequest>> violations =
validator.validate(validRequest(), ValidationGroups.Update.class);
assertFalse(hasViolation(violations, "appCode"));
assertFalse(hasViolation(violations, "appNature"));
}
@Test
void create_空appCode_校验失败_口径不变() {
ApplicationInfoRequest request = validRequest();
request.setId(null);
request.setAppCode(null);
Set<ConstraintViolation<ApplicationInfoRequest>> violations =
validator.validate(request, ValidationGroups.Create.class);
assertTrue(hasViolation(violations, "appCode"), "新增必填为既有口径,防回归");
}
}