fix(项目设置): 保存模板解析默认值报错
This commit is contained in:
parent
dc017c84c4
commit
7454357e58
|
@ -56,12 +56,7 @@ public enum CustomFieldType {
|
|||
/**
|
||||
* 多值输入框(标签输入框)
|
||||
*/
|
||||
MULTIPLE_INPUT(false),
|
||||
/**
|
||||
* 级联下拉框
|
||||
* 第三方平台可能会使用
|
||||
*/
|
||||
CASCADING_SELECT(false);
|
||||
MULTIPLE_INPUT(false);
|
||||
|
||||
private final Boolean hasOption;
|
||||
|
||||
|
|
|
@ -19,6 +19,6 @@ public class TemplateCustomFieldDTO {
|
|||
private String apiFieldId;
|
||||
|
||||
@Schema(title = "默认值")
|
||||
private String defaultValue;
|
||||
private Object defaultValue;
|
||||
|
||||
}
|
||||
|
|
|
@ -22,5 +22,5 @@ public class TemplateCustomFieldRequest {
|
|||
private String apiFieldId;
|
||||
|
||||
@Schema(title = "默认值")
|
||||
private String defaultValue;
|
||||
private Object defaultValue;
|
||||
}
|
||||
|
|
|
@ -406,6 +406,7 @@ user_role_relation_remove_admin_user_permission_error=无法将 admin 用户将
|
|||
internal_custom_field_permission_error=系统字段或模板无法删除!
|
||||
internal_template_permission_error=系统模板无法删除!
|
||||
default_template_permission_error=默认模板无法删除!
|
||||
field_validate_error={0}字段参数值不合法
|
||||
|
||||
#result message
|
||||
http_result_success=操作成功
|
||||
|
@ -444,7 +445,7 @@ plugin_permission_error=没有该插件的访问权限
|
|||
template_scene_illegal_error=使用场景不合法
|
||||
|
||||
# 内置的模板或字段
|
||||
custom_field.functional_priority=优先级
|
||||
custom_field.functional_priority=用例等级
|
||||
template.default=默认模板
|
||||
|
||||
parent.node.not_blank=父节点不能为空
|
||||
|
|
|
@ -409,6 +409,7 @@ user_role_relation_remove_admin_user_permission_error=Unable to delete the admin
|
|||
internal_custom_field_permission_error=System fields cannot be deleted!
|
||||
internal_template_permission_error=System template cannot be deleted!
|
||||
default_template_permission_error=Default templates cannot be deleted!
|
||||
field_validate_error=The field {0} value is invalid
|
||||
|
||||
#result message
|
||||
http_result_success=operate success
|
||||
|
@ -447,7 +448,7 @@ plugin_permission_error=No access to this plugin
|
|||
scheduled_tasks=Scheduled Tasks
|
||||
template_scene_illegal_error=Scene is illegal
|
||||
# 内置的模板或字段
|
||||
custom_field.functional_priority=Priority
|
||||
custom_field.functional_priority=Case Priority
|
||||
template.default=Default
|
||||
|
||||
set_default_template=Set the default template
|
||||
|
|
|
@ -406,6 +406,7 @@ user_role_relation_remove_admin_user_permission_error=无法将 admin 用户将
|
|||
internal_custom_field_permission_error=系统字段或模板无法删除!
|
||||
internal_template_permission_error=系统模板无法删除!
|
||||
default_template_permission_error=默认模板无法删除!
|
||||
field_validate_error={0}字段参数值不合法
|
||||
|
||||
#result message
|
||||
http_result_success=操作成功
|
||||
|
@ -445,7 +446,7 @@ plugin_permission_error=没有该插件的访问权限
|
|||
scheduled_tasks=定时任务
|
||||
template_scene_illegal_error=使用场景不合法
|
||||
# 内置的模板或字段
|
||||
custom_field.functional_priority=优先级
|
||||
custom_field.functional_priority=用例等级
|
||||
template.default=默认模板
|
||||
|
||||
set_default_template=设置默认模板
|
||||
|
|
|
@ -405,6 +405,7 @@ user_role_relation_remove_admin_user_permission_error=無法將 admin 用戶將
|
|||
internal_custom_field_permission_error=系統字段或模板無法刪除!
|
||||
internal_template_permission_error=系統模板無法刪除!
|
||||
default_template_permission_error=默认模板无法删除!
|
||||
field_validate_error={0}字段參數值不合法
|
||||
|
||||
#result message
|
||||
http_result_success=操作成功
|
||||
|
@ -444,7 +445,7 @@ scheduled_tasks=定時任務
|
|||
template_scene_illegal_error=使用場景不合法
|
||||
|
||||
# 内置的模板或字段
|
||||
custom_field.functional_priority=優先級
|
||||
custom_field.functional_priority=用例等級
|
||||
template.default=默認模板
|
||||
|
||||
set_default_template=設置默認模板
|
||||
|
|
|
@ -350,7 +350,7 @@ public class ProjectTemplateControllerTests extends BaseTest {
|
|||
Assertions.assertEquals(customFieldDTO.getApiFieldId(), templateCustomField.getApiFieldId());
|
||||
Assertions.assertEquals(customFieldDTO.getRequired(), templateCustomField.getRequired());
|
||||
Assertions.assertEquals(templateCustomField.getTemplateId(), template.getId());
|
||||
Assertions.assertEquals(customFieldDTO.getFieldName(), "优先级");
|
||||
Assertions.assertEquals(customFieldDTO.getFieldName(), "用例等级");
|
||||
}
|
||||
|
||||
// @@校验权限
|
||||
|
|
|
@ -26,7 +26,8 @@ public enum CommonResultCode implements IResultCode {
|
|||
TEMPLATE_EXIST(100013, "template.exist"),
|
||||
DEFAULT_TEMPLATE_PERMISSION(100014, "default_template_permission_error"),
|
||||
STATUS_ITEM_NOT_EXIST(100015, "status_item.not.exist"),
|
||||
STATUS_ITEM_EXIST(100016, "status_item.exist");
|
||||
STATUS_ITEM_EXIST(100016, "status_item.exist"),
|
||||
FIELD_VALIDATE_ERROR(100017, "field_validate_error");
|
||||
|
||||
|
||||
private int code;
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package io.metersphere.system.dto;
|
||||
|
||||
import io.metersphere.system.domain.CustomField;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class CustomFieldDao extends CustomField implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Boolean required;
|
||||
|
||||
private String defaultValue;
|
||||
|
||||
private Object value;
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package io.metersphere.system.resolver.field;
|
||||
|
||||
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.dto.CustomFieldDao;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.metersphere.system.controller.handler.result.CommonResultCode.FIELD_VALIDATE_ERROR;
|
||||
|
||||
public abstract class AbstractCustomFieldResolver {
|
||||
|
||||
/**
|
||||
* 校验参数是否合法
|
||||
*
|
||||
* @param customField
|
||||
* @param value
|
||||
*/
|
||||
abstract public void validate(CustomFieldDao customField, Object value);
|
||||
|
||||
protected void throwValidateException(String name) {
|
||||
throw new MSException(FIELD_VALIDATE_ERROR, Translator.get(FIELD_VALIDATE_ERROR.getMessage(), name));
|
||||
}
|
||||
|
||||
protected void validateRequired(CustomFieldDao customField, Object value) {
|
||||
if (!customField.getRequired()) {
|
||||
return;
|
||||
}
|
||||
if (value == null) {
|
||||
throwValidateException(customField.getName());
|
||||
} else if (value instanceof String && StringUtils.isBlank(value.toString())) {
|
||||
throwValidateException(customField.getName());
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateArrayRequired(CustomFieldDao customField, Object value) {
|
||||
if (!customField.getRequired()) {
|
||||
return;
|
||||
}
|
||||
if (value == null || (value instanceof List && CollectionUtils.isEmpty((List) value))) {
|
||||
throwValidateException(customField.getName());
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateArray(String name, Object value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
if (value instanceof List) {
|
||||
((List) value).forEach(v -> validateString(name, v));
|
||||
} else {
|
||||
throwValidateException(name);
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateString(String name, Object v) {
|
||||
if (!(v instanceof String)) {
|
||||
throwValidateException(name);
|
||||
}
|
||||
}
|
||||
|
||||
public Object parse2Value(String value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String parse2String(Object value) {
|
||||
return value == null ? null : value.toString();
|
||||
}
|
||||
|
||||
protected Object parse2Array(String value) {
|
||||
return value == null ? null : JSON.parseArray(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package io.metersphere.system.resolver.field;
|
||||
|
||||
|
||||
import io.metersphere.sdk.util.DateUtils;
|
||||
import io.metersphere.system.dto.CustomFieldDao;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class CustomFieldDateResolver extends AbstractCustomFieldResolver {
|
||||
|
||||
@Override
|
||||
public void validate(CustomFieldDao customField, Object value) {
|
||||
validateRequired(customField, value);
|
||||
validateString(customField.getName(), value);
|
||||
try {
|
||||
if (value != null && StringUtils.isNotBlank(value.toString())) {
|
||||
DateUtils.getDate(value.toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throwValidateException(customField.getName());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package io.metersphere.system.resolver.field;
|
||||
|
||||
|
||||
import io.metersphere.sdk.util.DateUtils;
|
||||
import io.metersphere.system.dto.CustomFieldDao;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class CustomFieldDateTimeResolver extends AbstractCustomFieldResolver {
|
||||
|
||||
@Override
|
||||
public void validate(CustomFieldDao customField, Object value) {
|
||||
validateRequired(customField, value);
|
||||
try {
|
||||
if (value != null && StringUtils.isNotBlank(value.toString())) {
|
||||
DateUtils.getTime(value.toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throwValidateException(customField.getName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package io.metersphere.system.resolver.field;
|
||||
|
||||
|
||||
import io.metersphere.system.dto.CustomFieldDao;
|
||||
|
||||
public class CustomFieldFloatResolver extends AbstractCustomFieldResolver {
|
||||
|
||||
@Override
|
||||
public void validate(CustomFieldDao customField, Object value) {
|
||||
validateRequired(customField, value);
|
||||
if (value != null && !(value instanceof Number)) {
|
||||
throwValidateException(customField.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parse2Value(String value) {
|
||||
return value == null ? null : Float.parseFloat(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package io.metersphere.system.resolver.field;
|
||||
|
||||
import io.metersphere.system.dto.CustomFieldDao;
|
||||
|
||||
public class CustomFieldIntegerResolver extends AbstractCustomFieldResolver {
|
||||
@Override
|
||||
public void validate(CustomFieldDao customField, Object value) {
|
||||
validateRequired(customField, value);
|
||||
if (value != null && !(value instanceof Integer)) {
|
||||
throwValidateException(customField.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parse2Value(String value) {
|
||||
return value == null ? null : Integer.parseInt(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package io.metersphere.system.resolver.field;
|
||||
|
||||
|
||||
import io.metersphere.system.dto.CustomFieldDao;
|
||||
|
||||
public class CustomFieldMemberResolver extends AbstractCustomFieldResolver {
|
||||
|
||||
@Override
|
||||
public void validate(CustomFieldDao customField, Object value) {
|
||||
validateRequired(customField, value);
|
||||
validateString(customField.getName(), value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package io.metersphere.system.resolver.field;
|
||||
|
||||
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.dto.CustomFieldDao;
|
||||
|
||||
public class CustomFieldMultipleMemberResolver extends CustomFieldMemberResolver {
|
||||
|
||||
@Override
|
||||
public void validate(CustomFieldDao customField, Object value) {
|
||||
validateArrayRequired(customField, value);
|
||||
validateArray(customField.getName(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parse2String(Object value) {
|
||||
return JSON.toJSONString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parse2Value(String value) {
|
||||
return parse2Array(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package io.metersphere.system.resolver.field;
|
||||
|
||||
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.domain.CustomFieldOption;
|
||||
import io.metersphere.system.dto.CustomFieldDao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CustomFieldMultipleSelectResolver extends CustomFieldSelectResolver {
|
||||
|
||||
@Override
|
||||
public void validate(CustomFieldDao customField, Object value) {
|
||||
validateArrayRequired(customField, value);
|
||||
validateArray(customField.getName(), value);
|
||||
List<CustomFieldOption> options = getOptions(customField.getId());
|
||||
Set<String> values = options.stream().map(CustomFieldOption::getValue).collect(Collectors.toSet());
|
||||
for (String item : (List<String>)value) {
|
||||
if (!values.contains(item)) {
|
||||
throwValidateException(customField.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parse2String(Object value) {
|
||||
return JSON.toJSONString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parse2Value(String value) {
|
||||
return parse2Array(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package io.metersphere.system.resolver.field;
|
||||
|
||||
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.dto.CustomFieldDao;
|
||||
|
||||
public class CustomFieldMultipleTextResolver extends AbstractCustomFieldResolver {
|
||||
|
||||
|
||||
@Override
|
||||
public void validate(CustomFieldDao customField, Object value) {
|
||||
validateArrayRequired(customField, value);
|
||||
validateArray(customField.getName(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parse2String(Object value) {
|
||||
return JSON.toJSONString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parse2Value(String value) {
|
||||
return parse2Array(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package io.metersphere.system.resolver.field;
|
||||
|
||||
import io.metersphere.sdk.constants.CustomFieldType;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class CustomFieldResolverFactory {
|
||||
|
||||
private static final HashMap<String, AbstractCustomFieldResolver> resolverMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
resolverMap.put(CustomFieldType.SELECT.name(), new CustomFieldSelectResolver());
|
||||
resolverMap.put(CustomFieldType.RADIO.name(), new CustomFieldSelectResolver());
|
||||
|
||||
resolverMap.put(CustomFieldType.MULTIPLE_SELECT.name(), new CustomFieldMultipleSelectResolver());
|
||||
resolverMap.put(CustomFieldType.CHECKBOX.name(), new CustomFieldMultipleSelectResolver());
|
||||
|
||||
resolverMap.put(CustomFieldType.INPUT.name(), new CustomFieldTextResolver());
|
||||
resolverMap.put(CustomFieldType.TEXTAREA.name(), new CustomFieldTextResolver());
|
||||
|
||||
resolverMap.put(CustomFieldType.MULTIPLE_INPUT.name(), new CustomFieldMultipleTextResolver());
|
||||
|
||||
resolverMap.put(CustomFieldType.DATE.name(), new CustomFieldDateResolver());
|
||||
resolverMap.put(CustomFieldType.DATETIME.name(), new CustomFieldDateTimeResolver());
|
||||
|
||||
resolverMap.put(CustomFieldType.MEMBER.name(), new CustomFieldMemberResolver());
|
||||
resolverMap.put(CustomFieldType.MULTIPLE_MEMBER.name(), new CustomFieldMultipleMemberResolver());
|
||||
|
||||
resolverMap.put(CustomFieldType.INT.name(), new CustomFieldIntegerResolver());
|
||||
resolverMap.put(CustomFieldType.FLOAT.name(), new CustomFieldFloatResolver());
|
||||
}
|
||||
|
||||
public static AbstractCustomFieldResolver getResolver(String type) {
|
||||
return resolverMap.get(type);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package io.metersphere.system.resolver.field;
|
||||
|
||||
|
||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import io.metersphere.system.domain.CustomFieldOption;
|
||||
import io.metersphere.system.dto.CustomFieldDao;
|
||||
import io.metersphere.system.service.BaseCustomFieldOptionService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CustomFieldSelectResolver extends AbstractCustomFieldResolver {
|
||||
|
||||
@Override
|
||||
public void validate(CustomFieldDao customField, Object value) {
|
||||
validateRequired(customField, value);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
validateString(customField.getName(), value);
|
||||
List<CustomFieldOption> options = getOptions(customField.getId());
|
||||
Set<String> values = options.stream().map(CustomFieldOption::getValue).collect(Collectors.toSet());
|
||||
if (!values.contains(value)) {
|
||||
throwValidateException(customField.getName());
|
||||
}
|
||||
}
|
||||
|
||||
protected List<CustomFieldOption> getOptions(String id) {
|
||||
BaseCustomFieldOptionService customFieldOptionService = CommonBeanFactory.getBean(BaseCustomFieldOptionService.class);
|
||||
return customFieldOptionService.getByFieldId(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package io.metersphere.system.resolver.field;
|
||||
|
||||
import io.metersphere.system.dto.CustomFieldDao;
|
||||
|
||||
public class CustomFieldTextResolver extends AbstractCustomFieldResolver {
|
||||
|
||||
@Override
|
||||
public void validate(CustomFieldDao customField, Object value) {
|
||||
validateRequired(customField, value);
|
||||
validateString(customField.getName(), value);
|
||||
}
|
||||
|
||||
}
|
|
@ -5,7 +5,10 @@ import io.metersphere.sdk.util.BeanUtils;
|
|||
import io.metersphere.system.domain.CustomField;
|
||||
import io.metersphere.system.domain.TemplateCustomField;
|
||||
import io.metersphere.system.domain.TemplateCustomFieldExample;
|
||||
import io.metersphere.system.dto.CustomFieldDao;
|
||||
import io.metersphere.system.mapper.TemplateCustomFieldMapper;
|
||||
import io.metersphere.system.resolver.field.AbstractCustomFieldResolver;
|
||||
import io.metersphere.system.resolver.field.CustomFieldResolverFactory;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -49,6 +52,17 @@ public class BaseTemplateCustomFieldService {
|
|||
if (CollectionUtils.isEmpty(customFieldRequests)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 过滤下不存在的字段
|
||||
List<String> ids = customFieldRequests.stream().map(TemplateCustomFieldRequest::getFieldId).toList();
|
||||
Set<String> fieldIdSet = baseCustomFieldService.getByIds(ids)
|
||||
.stream()
|
||||
.map(CustomField::getId)
|
||||
.collect(Collectors.toSet());
|
||||
customFieldRequests = customFieldRequests.stream()
|
||||
.filter(item -> fieldIdSet.contains(item.getFieldId()))
|
||||
.toList();
|
||||
|
||||
AtomicReference<Integer> pos = new AtomicReference<>(0);
|
||||
List<TemplateCustomField> templateCustomFields = customFieldRequests.stream().map(field -> {
|
||||
TemplateCustomField templateCustomField = new TemplateCustomField();
|
||||
|
@ -56,19 +70,24 @@ public class BaseTemplateCustomFieldService {
|
|||
BeanUtils.copyBean(templateCustomField, field);
|
||||
templateCustomField.setTemplateId(id);
|
||||
templateCustomField.setPos(pos.getAndSet(pos.get() + 1));
|
||||
templateCustomField.setDefaultValue(parseDefaultValue(field));
|
||||
return templateCustomField;
|
||||
}).toList();
|
||||
|
||||
// 过滤下不存在的字段
|
||||
List<String> ids = templateCustomFields.stream().map(TemplateCustomField::getFieldId).toList();
|
||||
Set<String> fieldIdSet = baseCustomFieldService.getByIds(ids).stream().map(CustomField::getId).collect(Collectors.toSet());
|
||||
templateCustomFields = templateCustomFields.stream().filter(item -> fieldIdSet.contains(item.getFieldId())).toList();
|
||||
|
||||
if (templateCustomFields.size() > 0) {
|
||||
templateCustomFieldMapper.batchInsert(templateCustomFields);
|
||||
}
|
||||
}
|
||||
|
||||
private String parseDefaultValue(TemplateCustomFieldRequest field) {
|
||||
CustomField customField = baseCustomFieldService.getWithCheck(field.getFieldId());
|
||||
AbstractCustomFieldResolver customFieldResolver = CustomFieldResolverFactory.getResolver(customField.getType());
|
||||
CustomFieldDao customFieldDao = BeanUtils.copyBean(new CustomFieldDao(), customField);
|
||||
customFieldDao.setRequired(false);
|
||||
customFieldResolver.validate(customFieldDao, field.getDefaultValue());
|
||||
return customFieldResolver.parse2String(field.getDefaultValue());
|
||||
}
|
||||
|
||||
public List<TemplateCustomField> getByTemplateId(String id) {
|
||||
TemplateCustomFieldExample example = new TemplateCustomFieldExample();
|
||||
example.createCriteria().andTemplateIdEqualTo(id);
|
||||
|
|
|
@ -7,6 +7,9 @@ import io.metersphere.sdk.dto.TemplateDTO;
|
|||
import io.metersphere.sdk.dto.request.TemplateCustomFieldRequest;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.system.resolver.field.AbstractCustomFieldResolver;
|
||||
import io.metersphere.system.resolver.field.CustomFieldResolverFactory;
|
||||
import io.metersphere.system.utils.ServiceUtils;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.domain.CustomField;
|
||||
|
@ -96,20 +99,30 @@ public class BaseTemplateService {
|
|||
|
||||
// 查找字段名称
|
||||
List<String> fieldIds = templateCustomFields.stream().map(TemplateCustomField::getFieldId).toList();
|
||||
Map<String, String> fieldNameMap = baseCustomFieldService.getByIds(fieldIds)
|
||||
List<CustomField> customFields = baseCustomFieldService.getByIds(fieldIds);
|
||||
Map<String, CustomField> fieldMap = customFields
|
||||
.stream()
|
||||
.collect(Collectors.toMap(CustomField::getId, i -> {
|
||||
if (i.getInternal()) {
|
||||
return baseCustomFieldService.translateInternalField(i.getName());
|
||||
.collect(Collectors.toMap(CustomField::getId, customField -> {
|
||||
if (customField.getInternal()) {
|
||||
customField.setName(baseCustomFieldService.translateInternalField(customField.getName()));
|
||||
}
|
||||
return i.getName();
|
||||
return customField;
|
||||
}));
|
||||
|
||||
// 封装字段信息
|
||||
List<TemplateCustomFieldDTO> fieldDTOS = templateCustomFields.stream().map(i -> {
|
||||
CustomField customField = fieldMap.get(i.getFieldId());
|
||||
TemplateCustomFieldDTO templateCustomFieldDTO = new TemplateCustomFieldDTO();
|
||||
BeanUtils.copyBean(templateCustomFieldDTO, i);
|
||||
templateCustomFieldDTO.setFieldName(fieldNameMap.get(i.getFieldId()));
|
||||
templateCustomFieldDTO.setFieldName(customField.getName());
|
||||
AbstractCustomFieldResolver customFieldResolver = CustomFieldResolverFactory.getResolver(customField.getType());
|
||||
Object defaultValue = null;
|
||||
try {
|
||||
defaultValue = customFieldResolver.parse2Value(i.getDefaultValue());
|
||||
} catch (Exception e) {
|
||||
LogUtils.error(e);
|
||||
}
|
||||
templateCustomFieldDTO.setDefaultValue(defaultValue);
|
||||
return templateCustomFieldDTO;
|
||||
}).toList();
|
||||
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
package io.metersphere.system.base;
|
||||
|
||||
import io.metersphere.sdk.constants.CustomFieldType;
|
||||
import io.metersphere.sdk.constants.InternalUser;
|
||||
import io.metersphere.sdk.constants.TemplateScene;
|
||||
import io.metersphere.sdk.dto.request.CustomFieldOptionRequest;
|
||||
import io.metersphere.sdk.exception.MSException;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.system.domain.CustomField;
|
||||
import io.metersphere.system.dto.CustomFieldDao;
|
||||
import io.metersphere.system.resolver.field.AbstractCustomFieldResolver;
|
||||
import io.metersphere.system.resolver.field.CustomFieldResolverFactory;
|
||||
import io.metersphere.system.service.OrganizationCustomFieldService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.metersphere.system.controller.handler.result.CommonResultCode.FIELD_VALIDATE_ERROR;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2023-10-20 11:32
|
||||
*/
|
||||
@Service
|
||||
public class BaseCustomFieldTestService {
|
||||
|
||||
|
||||
@Resource
|
||||
private OrganizationCustomFieldService organizationCustomFieldService;
|
||||
|
||||
private static Map<CustomFieldType, CustomField> customFields;
|
||||
|
||||
public static final String OPTION_VALUE = "OPTION_VALUE";
|
||||
|
||||
|
||||
public Map<CustomFieldType, CustomField> addOrgTestCustomFields() {
|
||||
if (customFields != null) {
|
||||
return customFields;
|
||||
}
|
||||
customFields = new HashMap<>();
|
||||
for (CustomFieldType customFieldType : CustomFieldType.values()) {
|
||||
CustomFieldOptionRequest customFieldOptionRequest = new CustomFieldOptionRequest();
|
||||
customFieldOptionRequest.setValue(OPTION_VALUE);
|
||||
customFieldOptionRequest.setText("test");
|
||||
List<CustomFieldOptionRequest> optionRequests = Arrays.asList(customFieldOptionRequest);
|
||||
CustomField customField = new CustomField();
|
||||
customField.setType(customFieldType.name());
|
||||
customField.setName(customFieldType.name());
|
||||
customField.setCreateUser(InternalUser.ADMIN.getValue());
|
||||
customField.setScene(TemplateScene.FUNCTIONAL.name());
|
||||
customField.setScopeId(BaseTest.DEFAULT_ORGANIZATION_ID);
|
||||
customField = organizationCustomFieldService.add(customField, optionRequests);
|
||||
customFields.put(customFieldType, customField);
|
||||
}
|
||||
return customFields;
|
||||
}
|
||||
|
||||
public Map<CustomFieldType, CustomField> getCustomFields() {
|
||||
return customFields;
|
||||
}
|
||||
|
||||
public void testResolverEmptyValidate() {
|
||||
Map<CustomFieldType, Object> emptyValueMap = new HashMap<>();
|
||||
Arrays.stream(CustomFieldType.values()).forEach(i -> emptyValueMap.put(i, StringUtils.EMPTY));
|
||||
emptyValueMap.put(CustomFieldType.MULTIPLE_SELECT, List.of());
|
||||
emptyValueMap.put(CustomFieldType.MULTIPLE_INPUT, List.of());
|
||||
emptyValueMap.put(CustomFieldType.CHECKBOX, List.of());
|
||||
emptyValueMap.put(CustomFieldType.MULTIPLE_MEMBER, List.of());
|
||||
emptyValueMap.put(CustomFieldType.INT, null);
|
||||
emptyValueMap.put(CustomFieldType.FLOAT, null);
|
||||
assertValidateError(emptyValueMap);
|
||||
}
|
||||
|
||||
public void testResolverErrorValidate() {
|
||||
Map<CustomFieldType, Object> errorValueMap = new HashMap<>();
|
||||
Arrays.stream(CustomFieldType.values()).forEach(i -> errorValueMap.put(i, 1));
|
||||
errorValueMap.put(CustomFieldType.MULTIPLE_SELECT, StringUtils.EMPTY);
|
||||
errorValueMap.put(CustomFieldType.MULTIPLE_INPUT, StringUtils.EMPTY);
|
||||
errorValueMap.put(CustomFieldType.CHECKBOX, StringUtils.EMPTY);
|
||||
errorValueMap.put(CustomFieldType.MULTIPLE_MEMBER, StringUtils.EMPTY);
|
||||
errorValueMap.put(CustomFieldType.INT, StringUtils.EMPTY);
|
||||
errorValueMap.put(CustomFieldType.FLOAT, StringUtils.EMPTY);
|
||||
assertValidateError(errorValueMap);
|
||||
|
||||
errorValueMap.clear();
|
||||
Arrays.stream(CustomFieldType.values()).forEach(i -> errorValueMap.put(i, 1));
|
||||
errorValueMap.put(CustomFieldType.DATE, "eeee");
|
||||
errorValueMap.put(CustomFieldType.DATETIME, "eeee");
|
||||
errorValueMap.put(CustomFieldType.DATETIME, "eeee");
|
||||
errorValueMap.put(CustomFieldType.MULTIPLE_SELECT, List.of(1));
|
||||
errorValueMap.put(CustomFieldType.MULTIPLE_INPUT, List.of(1));
|
||||
errorValueMap.put(CustomFieldType.CHECKBOX, List.of(1));
|
||||
errorValueMap.put(CustomFieldType.MULTIPLE_MEMBER, List.of(1));
|
||||
errorValueMap.put(CustomFieldType.INT, "dd");
|
||||
errorValueMap.put(CustomFieldType.FLOAT, "dd");
|
||||
assertValidateError(errorValueMap);
|
||||
}
|
||||
|
||||
public void testResolverParse() {
|
||||
Map<CustomFieldType, Object> objectValueMap = new HashMap<>();
|
||||
Arrays.stream(CustomFieldType.values()).forEach(i -> objectValueMap.put(i, "1"));
|
||||
objectValueMap.put(CustomFieldType.SELECT, OPTION_VALUE);
|
||||
objectValueMap.put(CustomFieldType.RADIO, OPTION_VALUE);
|
||||
objectValueMap.put(CustomFieldType.DATE, "2021-10-10");
|
||||
objectValueMap.put(CustomFieldType.DATETIME, "2021-10-10 10:10:10");
|
||||
objectValueMap.put(CustomFieldType.RADIO, OPTION_VALUE);
|
||||
objectValueMap.put(CustomFieldType.MULTIPLE_SELECT, List.of(OPTION_VALUE));
|
||||
objectValueMap.put(CustomFieldType.CHECKBOX, List.of(OPTION_VALUE));
|
||||
objectValueMap.put(CustomFieldType.MULTIPLE_INPUT, List.of(OPTION_VALUE));
|
||||
objectValueMap.put(CustomFieldType.MULTIPLE_MEMBER, List.of(OPTION_VALUE));
|
||||
objectValueMap.put(CustomFieldType.INT, 1);
|
||||
objectValueMap.put(CustomFieldType.FLOAT, 1.2f);
|
||||
|
||||
for (CustomFieldType customFieldType : CustomFieldType.values()) {
|
||||
// 校验 validate 调用成功
|
||||
invokeValidate(objectValueMap, customFieldType);
|
||||
|
||||
AbstractCustomFieldResolver customFieldResolver = CustomFieldResolverFactory.getResolver(customFieldType.name());
|
||||
CustomField customField = getCustomFields().get(customFieldType);
|
||||
CustomFieldDao customFieldDao = BeanUtils.copyBean(new CustomFieldDao(), customField);
|
||||
customFieldDao.setRequired(true);
|
||||
String valueStr = customFieldResolver.parse2String(objectValueMap.get(customFieldType));
|
||||
Object objectValue = customFieldResolver.parse2Value(valueStr);
|
||||
// 校验 parse2String 和 parse2Value 是否正确
|
||||
if (objectValue instanceof List) {
|
||||
Assertions.assertEquals(objectValue.toString(), objectValueMap.get(customFieldType).toString());
|
||||
} else {
|
||||
Assertions.assertEquals(objectValue, objectValueMap.get(customFieldType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void assertValidateError(Map<CustomFieldType, Object> errorValueMap) {
|
||||
for (CustomFieldType customFieldType : CustomFieldType.values()) {
|
||||
try {
|
||||
invokeValidate(errorValueMap, customFieldType);
|
||||
} catch (MSException e) {
|
||||
Assertions.assertEquals(e.getErrorCode(), FIELD_VALIDATE_ERROR);
|
||||
continue;
|
||||
}
|
||||
throw new MSException("自定义字段校验失败");
|
||||
}
|
||||
}
|
||||
|
||||
private void invokeValidate(Map<CustomFieldType, Object> valueMap, CustomFieldType customFieldType) {
|
||||
AbstractCustomFieldResolver customFieldResolver = CustomFieldResolverFactory.getResolver(customFieldType.name());
|
||||
CustomField customField = getCustomFields().get(customFieldType);
|
||||
CustomFieldDao customFieldDao = BeanUtils.copyBean(new CustomFieldDao(), customField);
|
||||
customFieldDao.setRequired(true);
|
||||
customFieldResolver.validate(customFieldDao, valueMap.get(customFieldType));
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ import io.metersphere.sdk.dto.TemplateDTO;
|
|||
import io.metersphere.sdk.dto.request.TemplateCustomFieldRequest;
|
||||
import io.metersphere.sdk.dto.request.TemplateUpdateRequest;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.system.base.BaseCustomFieldTestService;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.controller.param.TemplateUpdateRequestDefinition;
|
||||
import io.metersphere.system.domain.*;
|
||||
|
@ -37,7 +38,7 @@ import static io.metersphere.system.controller.result.SystemResultCode.ORGANIZAT
|
|||
* @author jianxing
|
||||
* @date : 2023-8-30
|
||||
*/
|
||||
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@AutoConfigureMockMvc
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
public class OrganizationTemplateControllerTests extends BaseTest {
|
||||
|
@ -62,6 +63,8 @@ public class OrganizationTemplateControllerTests extends BaseTest {
|
|||
private BaseOrganizationParameterService organizationParameterService;
|
||||
@Resource
|
||||
private OrganizationTemplateService organizationTemplateService;
|
||||
@Resource
|
||||
private BaseCustomFieldTestService baseCustomFieldTestService;
|
||||
|
||||
private static Template addTemplate;
|
||||
private static Template anotherTemplateField;
|
||||
|
@ -320,7 +323,7 @@ public class OrganizationTemplateControllerTests extends BaseTest {
|
|||
Assertions.assertEquals(customFieldDTO.getApiFieldId(), templateCustomField.getApiFieldId());
|
||||
Assertions.assertEquals(customFieldDTO.getRequired(), templateCustomField.getRequired());
|
||||
Assertions.assertEquals(templateCustomField.getTemplateId(), template.getId());
|
||||
Assertions.assertEquals(customFieldDTO.getFieldName(), "优先级");
|
||||
Assertions.assertEquals(customFieldDTO.getFieldName(), "用例等级");
|
||||
}
|
||||
|
||||
// @@校验权限
|
||||
|
@ -395,4 +398,16 @@ public class OrganizationTemplateControllerTests extends BaseTest {
|
|||
// @@校验权限
|
||||
requestGetPermissionTest(PermissionConstants.ORGANIZATION_TEMPLATE_READ, IS_ORGANIZATION_TEMPLATE_ENABLE, DEFAULT_ORGANIZATION_ID, TemplateScene.FUNCTIONAL.name());
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试自定义字段解析器
|
||||
*/
|
||||
@Test
|
||||
@Order(9)
|
||||
public void testCustomFiledResolver() {
|
||||
baseCustomFieldTestService.addOrgTestCustomFields();
|
||||
baseCustomFieldTestService.testResolverEmptyValidate();
|
||||
baseCustomFieldTestService.testResolverErrorValidate();
|
||||
baseCustomFieldTestService.testResolverParse();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue