feat(接口测试): 接口包含时脚本增加系统通知
--story=1012020 --user=王孝刚 接口脚本增加预警审核机制- v1,v2同步上 https://www.tapd.cn/55049933/s/1373989
This commit is contained in:
parent
9b7de47b07
commit
6a006845a4
|
@ -16,6 +16,7 @@ import io.metersphere.api.dto.scenario.DatabaseConfig;
|
|||
import io.metersphere.api.dto.scenario.KeyValue;
|
||||
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
|
||||
import io.metersphere.api.service.ApiTestEnvironmentService;
|
||||
import io.metersphere.api.service.MsHashTreeService;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
|
@ -59,6 +60,12 @@ public class ElementUtil {
|
|||
private static final String POST = "POST";
|
||||
private static final String ASSERTIONS = "ASSERTIONS";
|
||||
private static final String BODY_FILE_DIR = FileUtils.BODY_FILE_DIR;
|
||||
public final static List<String> scriptList = new ArrayList<String>() {{
|
||||
this.add("JSR223Processor");
|
||||
this.add("JSR223PreProcessor");
|
||||
this.add("JSR223PostProcessor");
|
||||
}};
|
||||
public static final String JSR = "jsr223";
|
||||
|
||||
public static Arguments addArguments(ParameterConfig config, String projectId, String name) {
|
||||
if (config.isEffective(projectId) && config.getConfig().get(projectId).getCommonConfig() != null
|
||||
|
@ -822,4 +829,58 @@ public class ElementUtil {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> scriptList(String request) {
|
||||
List<String> list = new ArrayList<>();
|
||||
if (StringUtils.isBlank(request)) {
|
||||
return list;
|
||||
}
|
||||
JSONObject element = JSONObject.parseObject(request);
|
||||
toList(element.getJSONArray(MsHashTreeService.HASH_TREE), scriptList, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void toList(JSONArray hashTree, List<String> scriptList, List<String> list) {
|
||||
for (int i = 0; i < hashTree.size(); i++) {
|
||||
JSONObject element = hashTree.getJSONObject(i);
|
||||
if (element == null) {
|
||||
continue;
|
||||
}
|
||||
if (scriptList.contains(element.getString(MsHashTreeService.TYPE))) {
|
||||
JSONObject elementTarget = JSONObject.parseObject(element.toString());
|
||||
if (elementTarget.containsKey(MsHashTreeService.HASH_TREE)) {
|
||||
elementTarget.remove(MsHashTreeService.HASH_TREE);
|
||||
}
|
||||
elementTarget.remove(MsHashTreeService.ACTIVE);
|
||||
elementTarget.remove(MsHashTreeService.INDEX);
|
||||
list.add(elementTarget.toString());
|
||||
}
|
||||
JSONArray jsrArray = element.getJSONArray(JSR);
|
||||
if (jsrArray != null) {
|
||||
for (int j = 0; j < jsrArray.size(); j++) {
|
||||
JSONObject jsr223 = jsrArray.getJSONObject(j);
|
||||
if (jsr223 != null) {
|
||||
list.add(jsr223.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (element.containsKey(MsHashTreeService.HASH_TREE)) {
|
||||
JSONArray elementJSONArray = element.getJSONArray(MsHashTreeService.HASH_TREE);
|
||||
toList(elementJSONArray, scriptList, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isSend(List<String> org, List<String> target) {
|
||||
if (org.size() != target.size() && target.size() > 0) {
|
||||
return true;
|
||||
}
|
||||
List<String> diff = org.stream()
|
||||
.filter(s -> !target.contains(s))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(diff)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,6 +156,8 @@ public class ApiAutomationService {
|
|||
|
||||
@Resource
|
||||
private JMeterService jMeterService;
|
||||
@Resource
|
||||
private ApiTestCaseService apiTestCaseService;
|
||||
private ThreadLocal<Long> currentScenarioOrder = new ThreadLocal<>();
|
||||
|
||||
public ApiScenarioDTO getDto(String id) {
|
||||
|
@ -286,6 +288,16 @@ public class ApiAutomationService {
|
|||
if (relationshipEdgeService != null) {
|
||||
relationshipEdgeService.initRelationshipEdge(null, scenario);
|
||||
}
|
||||
apiTestCaseService.checkAndSendReviewMessage(
|
||||
scenario.getId(),
|
||||
scenario.getName(),
|
||||
scenario.getProjectId(),
|
||||
"场景用例通知",
|
||||
NoticeConstants.TaskType.API_AUTOMATION_TASK,
|
||||
null,
|
||||
scenario.getScenarioDefinition(),
|
||||
scenario.getPrincipal()
|
||||
);
|
||||
uploadFiles(request, bodyFiles, scenarioFiles);
|
||||
|
||||
return scenario;
|
||||
|
@ -417,6 +429,16 @@ public class ApiAutomationService {
|
|||
if (relationshipEdgeService != null) {
|
||||
relationshipEdgeService.initRelationshipEdge(beforeScenario, scenario);
|
||||
}
|
||||
apiTestCaseService.checkAndSendReviewMessage(
|
||||
scenario.getId(),
|
||||
scenario.getName(),
|
||||
scenario.getProjectId(),
|
||||
"场景用例通知",
|
||||
NoticeConstants.TaskType.API_AUTOMATION_TASK,
|
||||
beforeScenario.getScenarioDefinition(),
|
||||
scenario.getScenarioDefinition(),
|
||||
scenario.getPrincipal()
|
||||
);
|
||||
checkAndSetLatestVersion(beforeScenario.getRefId());
|
||||
return scenario;
|
||||
}
|
||||
|
|
|
@ -18,10 +18,7 @@ import io.metersphere.api.dto.scenario.request.RequestType;
|
|||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.*;
|
||||
import io.metersphere.commons.constants.APITestStatus;
|
||||
import io.metersphere.commons.constants.CommonConstants;
|
||||
import io.metersphere.commons.constants.MsTestElementConstants;
|
||||
import io.metersphere.commons.constants.TestPlanStatus;
|
||||
import io.metersphere.commons.constants.*;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.controller.request.OrderRequest;
|
||||
|
@ -31,8 +28,11 @@ import io.metersphere.log.utils.ReflexObjectUtil;
|
|||
import io.metersphere.log.vo.DetailColumn;
|
||||
import io.metersphere.log.vo.OperatingLogDetails;
|
||||
import io.metersphere.log.vo.api.DefinitionReference;
|
||||
import io.metersphere.notice.service.NotificationService;
|
||||
import io.metersphere.plugin.core.MsTestElement;
|
||||
import io.metersphere.service.FileService;
|
||||
import io.metersphere.service.ProjectApplicationService;
|
||||
import io.metersphere.service.ProjectService;
|
||||
import io.metersphere.service.UserService;
|
||||
import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest;
|
||||
import io.metersphere.track.service.TestPlanApiCaseService;
|
||||
|
@ -48,6 +48,7 @@ import org.apache.ibatis.session.SqlSessionFactory;
|
|||
import org.aspectj.util.FileUtil;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
@ -113,6 +114,13 @@ public class ApiTestCaseService {
|
|||
private ObjectMapper mapper;
|
||||
@Resource
|
||||
private ExtApiDefinitionMapper extApiDefinitionMapper;
|
||||
@Resource
|
||||
private ProjectApplicationService projectApplicationService;
|
||||
@Resource
|
||||
private NotificationService notificationService;
|
||||
@Lazy
|
||||
@Resource
|
||||
private ProjectService projectService;
|
||||
|
||||
private static final String BODY_FILE_DIR = FileUtils.BODY_FILE_DIR;
|
||||
|
||||
|
@ -390,6 +398,7 @@ public class ApiTestCaseService {
|
|||
|
||||
final ApiTestCaseWithBLOBs test = apiTestCaseMapper.selectByPrimaryKey(request.getId());
|
||||
if (test != null) {
|
||||
String requestOrg = test.getRequest();
|
||||
test.setName(request.getName());
|
||||
test.setCaseStatus(request.getCaseStatus());
|
||||
if (StringUtils.isEmpty(request.getCaseStatus())) {
|
||||
|
@ -411,6 +420,15 @@ public class ApiTestCaseService {
|
|||
}
|
||||
apiTestCaseMapper.updateByPrimaryKeySelective(test);
|
||||
saveFollows(test.getId(), request.getFollows());
|
||||
this.checkAndSendReviewMessage(test.getId(),
|
||||
test.getName(),
|
||||
test.getProjectId(),
|
||||
"接口用例通知",
|
||||
NoticeConstants.TaskType.API_DEFINITION_TASK,
|
||||
requestOrg,
|
||||
test.getRequest(),
|
||||
test.getCreateUserId()
|
||||
);
|
||||
}
|
||||
return test;
|
||||
}
|
||||
|
@ -469,6 +487,15 @@ public class ApiTestCaseService {
|
|||
apiTestCaseMapper.insert(test);
|
||||
saveFollows(test.getId(), request.getFollows());
|
||||
}
|
||||
this.checkAndSendReviewMessage(test.getId(),
|
||||
test.getName(),
|
||||
test.getProjectId(),
|
||||
"接口用例通知",
|
||||
NoticeConstants.TaskType.API_DEFINITION_TASK,
|
||||
null,
|
||||
test.getRequest(),
|
||||
test.getCreateUserId()
|
||||
);
|
||||
return test;
|
||||
}
|
||||
|
||||
|
@ -1180,4 +1207,52 @@ public class ApiTestCaseService {
|
|||
return null;
|
||||
}
|
||||
|
||||
//检查并发送脚本审核的通知
|
||||
@Async
|
||||
public void checkAndSendReviewMessage(
|
||||
String id,
|
||||
String name,
|
||||
String projectId,
|
||||
String title,
|
||||
String resourceType,
|
||||
String requestOrg,
|
||||
String requestTarget,
|
||||
String sendUser) {
|
||||
|
||||
try {
|
||||
ProjectApplication scriptEnable = projectApplicationService
|
||||
.getProjectApplication(projectId, ProjectApplicationType.API_REVIEW_TEST_SCRIPT.name());
|
||||
|
||||
if (BooleanUtils.toBoolean(scriptEnable.getTypeValue())) {
|
||||
|
||||
List<String> org = ElementUtil.scriptList(requestOrg);
|
||||
List<String> target = ElementUtil.scriptList(requestTarget);
|
||||
boolean isSend = ElementUtil.isSend(org, target);
|
||||
if (isSend) {
|
||||
ProjectApplication reviewer = projectApplicationService
|
||||
.getProjectApplication(projectId, ProjectApplicationType.API_SCRIPT_REVIEWER.name());
|
||||
if (StringUtils.isNotEmpty(reviewer.getTypeValue())) {
|
||||
sendUser = reviewer.getTypeValue();
|
||||
}
|
||||
if (projectService.isProjectMember(projectId, sendUser)) {
|
||||
Notification notification = new Notification();
|
||||
notification.setTitle(title);
|
||||
notification.setOperator(reviewer.getTypeValue());
|
||||
notification.setOperation(NoticeConstants.Event.REVIEW);
|
||||
notification.setResourceId(id);
|
||||
notification.setResourceName(name);
|
||||
notification.setResourceType(resourceType);
|
||||
notification.setType(NotificationConstants.Type.SYSTEM_NOTICE.name());
|
||||
notification.setStatus(NotificationConstants.Status.UNREAD.name());
|
||||
notification.setCreateTime(System.currentTimeMillis());
|
||||
notification.setReceiver(sendUser);
|
||||
notificationService.sendAnnouncement(notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("发送通知失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,11 +7,12 @@ import io.metersphere.api.dto.ApiMockEnvUpdateDTO;
|
|||
import io.metersphere.api.dto.ApiTestEnvironmentDTO;
|
||||
import io.metersphere.api.dto.mockconfig.MockConfigStaticData;
|
||||
import io.metersphere.api.tcp.TCPPool;
|
||||
import io.metersphere.base.domain.ApiTestEnvironmentExample;
|
||||
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
||||
import io.metersphere.base.domain.Project;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiTestEnvironmentMapper;
|
||||
import io.metersphere.base.mapper.UserGroupMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiTestEnvironmentMapper;
|
||||
import io.metersphere.commons.constants.NoticeConstants;
|
||||
import io.metersphere.commons.constants.NotificationConstants;
|
||||
import io.metersphere.commons.constants.ProjectApplicationType;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
|
@ -23,16 +24,18 @@ import io.metersphere.log.utils.ReflexObjectUtil;
|
|||
import io.metersphere.log.vo.DetailColumn;
|
||||
import io.metersphere.log.vo.OperatingLogDetails;
|
||||
import io.metersphere.log.vo.system.SystemReference;
|
||||
import io.metersphere.service.EnvironmentGroupProjectService;
|
||||
import io.metersphere.service.ProjectApplicationService;
|
||||
import io.metersphere.service.ProjectService;
|
||||
import io.metersphere.service.SystemParameterService;
|
||||
import io.metersphere.notice.service.NotificationService;
|
||||
import io.metersphere.service.*;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.mybatis.spring.SqlSessionUtils;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
@ -40,6 +43,7 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
import javax.annotation.Resource;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
|
@ -55,6 +59,21 @@ public class ApiTestEnvironmentService {
|
|||
private ProjectApplicationService projectApplicationService;
|
||||
@Resource
|
||||
private SqlSessionFactory sqlSessionFactory;
|
||||
@Resource
|
||||
private NotificationService notificationService;
|
||||
@Lazy
|
||||
@Resource
|
||||
private ProjectService projectService;
|
||||
@Resource
|
||||
private UserGroupMapper userGroupMapper;
|
||||
|
||||
public static final String POST_STEP = "postStepProcessor";
|
||||
public static final String PRE_STEP = "preStepProcessor";
|
||||
public static final String POST = "postProcessor";
|
||||
public static final String PRE = "preProcessor";
|
||||
public static final String SCRIPT = "script";
|
||||
public static final String JSR = "jsr223";
|
||||
public static final String ASSERTIONS = "assertions";
|
||||
|
||||
public List<ApiTestEnvironmentWithBLOBs> list(String projectId) {
|
||||
ApiTestEnvironmentExample example = new ApiTestEnvironmentExample();
|
||||
|
@ -118,6 +137,14 @@ public class ApiTestEnvironmentService {
|
|||
request.setCreateTime(System.currentTimeMillis());
|
||||
request.setUpdateTime(System.currentTimeMillis());
|
||||
apiTestEnvironmentMapper.insert(request);
|
||||
checkAndSendReviewMessage(request.getId(),
|
||||
request.getName(),
|
||||
request.getProjectId(),
|
||||
NoticeConstants.TaskType.ENV_TASK,
|
||||
null,
|
||||
request.getConfig(),
|
||||
request.getCreateUser()
|
||||
);
|
||||
return request.getId();
|
||||
}
|
||||
|
||||
|
@ -140,7 +167,35 @@ public class ApiTestEnvironmentService {
|
|||
checkEnvironmentExist(apiTestEnvironment);
|
||||
FileUtils.createFiles(apiTestEnvironment.getUploadIds(), sslFiles, FileUtils.BODY_FILE_DIR + "/ssl");
|
||||
apiTestEnvironment.setUpdateTime(System.currentTimeMillis());
|
||||
ApiTestEnvironmentWithBLOBs envOrg = apiTestEnvironmentMapper.selectByPrimaryKey(apiTestEnvironment.getId());
|
||||
apiTestEnvironmentMapper.updateByPrimaryKeyWithBLOBs(apiTestEnvironment);
|
||||
|
||||
if (StringUtils.isBlank(apiTestEnvironment.getCreateUser())){
|
||||
UserGroupExample userGroupExample = new UserGroupExample();
|
||||
userGroupExample.createCriteria().andSourceIdEqualTo(apiTestEnvironment.getProjectId()).andGroupIdEqualTo("project_admin");
|
||||
List<UserGroup> userGroups = userGroupMapper.selectByExample(userGroupExample);
|
||||
if (CollectionUtils.isNotEmpty(userGroups)){
|
||||
userGroups.forEach(userGroup -> {
|
||||
checkAndSendReviewMessage(apiTestEnvironment.getId(),
|
||||
apiTestEnvironment.getName(),
|
||||
apiTestEnvironment.getProjectId(),
|
||||
NoticeConstants.TaskType.ENV_TASK,
|
||||
envOrg.getConfig(),
|
||||
apiTestEnvironment.getConfig(),
|
||||
userGroup.getUserId()
|
||||
);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
checkAndSendReviewMessage(apiTestEnvironment.getId(),
|
||||
apiTestEnvironment.getName(),
|
||||
apiTestEnvironment.getProjectId(),
|
||||
NoticeConstants.TaskType.ENV_TASK,
|
||||
envOrg.getConfig(),
|
||||
apiTestEnvironment.getConfig(),
|
||||
apiTestEnvironment.getCreateUser()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkEnvironmentExist(ApiTestEnvironmentWithBLOBs environment) {
|
||||
|
@ -606,4 +661,97 @@ public class ApiTestEnvironmentService {
|
|||
}
|
||||
return returnStr;
|
||||
}
|
||||
|
||||
@Async
|
||||
public void checkAndSendReviewMessage(
|
||||
String id,
|
||||
String name,
|
||||
String projectId,
|
||||
String resourceType,
|
||||
String requestOrg,
|
||||
String requestTarget,
|
||||
String sendUser) {
|
||||
try {
|
||||
ProjectApplication scriptEnable = projectApplicationService
|
||||
.getProjectApplication(projectId, ProjectApplicationType.API_REVIEW_TEST_SCRIPT.name());
|
||||
|
||||
if (BooleanUtils.toBoolean(scriptEnable.getTypeValue())) {
|
||||
List<String> org = scriptList(requestOrg);
|
||||
List<String> target = scriptList(requestTarget);
|
||||
boolean isSend = isSend(org, target);
|
||||
if (isSend) {
|
||||
|
||||
ProjectApplication reviewer = projectApplicationService
|
||||
.getProjectApplication(projectId, ProjectApplicationType.API_SCRIPT_REVIEWER.name());
|
||||
if (StringUtils.isNotBlank(reviewer.getTypeValue())) {
|
||||
sendUser = reviewer.getTypeValue();
|
||||
}
|
||||
if (projectService.isProjectMember(projectId, sendUser)) {
|
||||
Notification notification = new Notification();
|
||||
notification.setTitle("环境设置");
|
||||
notification.setOperator(reviewer.getTypeValue());
|
||||
notification.setOperation(NoticeConstants.Event.REVIEW);
|
||||
notification.setResourceId(id);
|
||||
notification.setResourceName(name);
|
||||
notification.setResourceType(resourceType);
|
||||
notification.setType(NotificationConstants.Type.SYSTEM_NOTICE.name());
|
||||
notification.setStatus(NotificationConstants.Status.UNREAD.name());
|
||||
notification.setCreateTime(System.currentTimeMillis());
|
||||
notification.setReceiver(sendUser);
|
||||
notificationService.sendAnnouncement(notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtil.error("发送通知失败", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static List<String> scriptList(String request) {
|
||||
List<String> list = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(request)){
|
||||
JSONObject configObj = JSONObject.parseObject(request);
|
||||
toList(list, configObj, POST_STEP, PRE_STEP);
|
||||
toList(list, configObj, PRE, POST);
|
||||
JSONObject object = configObj.getJSONObject(ASSERTIONS);
|
||||
if (ObjectUtils.isNotEmpty(object)) {
|
||||
JSONArray jsrArray = object.getJSONArray(JSR);
|
||||
if (jsrArray != null) {
|
||||
for (int j = 0; j < jsrArray.size(); j++) {
|
||||
JSONObject jsr223 = jsrArray.getJSONObject(j);
|
||||
if (jsr223 != null) {
|
||||
list.add(jsr223.getString(SCRIPT));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void toList(List<String> list, JSONObject configObj, String pre, String post) {
|
||||
JSONObject preProcessor = configObj.getJSONObject(pre);
|
||||
if (ObjectUtils.isNotEmpty(preProcessor) && StringUtils.isNotBlank(preProcessor.getString(SCRIPT))) {
|
||||
list.add(StringUtils.join(pre,preProcessor.getString(SCRIPT)));
|
||||
}
|
||||
JSONObject postProcessor = configObj.getJSONObject(post);
|
||||
if (ObjectUtils.isNotEmpty(postProcessor) && StringUtils.isNotBlank(postProcessor.getString(SCRIPT))) {
|
||||
list.add(StringUtils.join(post,postProcessor.getString(SCRIPT)));
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isSend(List<String> orgList, List<String> targetList) {
|
||||
if (orgList.size() != targetList.size() && targetList.size() > 0) {
|
||||
return true;
|
||||
}
|
||||
List<String> diff = orgList.stream()
|
||||
.filter(s -> !targetList.contains(s))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(diff)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ public class MsHashTreeService {
|
|||
private static final String FOLLOW_REDIRECTS = "followRedirects";
|
||||
private static final String AUTO_REDIRECTS = "autoRedirects";
|
||||
private static final String ALIAS = "alias";
|
||||
private static final String INDEX = "index";
|
||||
public static final String INDEX = "index";
|
||||
|
||||
public void setHashTree(JSONArray hashTree) {
|
||||
// 将引用转成复制
|
||||
|
|
|
@ -21,6 +21,7 @@ public interface NoticeConstants {
|
|||
String UI_DEFINITION_TASK = "UI_DEFINITION_TASK";
|
||||
String UI_HOME_TASK = "UI_HOME_TASK";
|
||||
String UI_REPORT_TASK = "UI_REPORT_TASK";
|
||||
String ENV_TASK = "ENV_TASK";
|
||||
}
|
||||
|
||||
interface Mode {
|
||||
|
|
|
@ -89,4 +89,13 @@ public enum ProjectApplicationType {
|
|||
* 性能测试脚本评审人
|
||||
*/
|
||||
PERFORMANCE_SCRIPT_REVIEWER,
|
||||
|
||||
/**
|
||||
* 接口测试是否评审脚本
|
||||
*/
|
||||
API_REVIEW_TEST_SCRIPT,
|
||||
/**
|
||||
* 接口测试脚本评审人
|
||||
*/
|
||||
API_SCRIPT_REVIEWER,
|
||||
}
|
||||
|
|
|
@ -38,4 +38,7 @@ public class ProjectConfig {
|
|||
//性能测试脚本审核人
|
||||
private String performanceScriptReviewer;
|
||||
|
||||
private String apiScriptReviewer;
|
||||
private Boolean apiReviewTestScript = false;
|
||||
|
||||
}
|
||||
|
|
|
@ -1191,7 +1191,7 @@ public class PerformanceTestService {
|
|||
if (StringUtils.isNotEmpty(loadTestScriptReviewerConfig.getTypeValue())) {
|
||||
sendUser = loadTestScriptReviewerConfig.getTypeValue();
|
||||
}
|
||||
if (projectService.isProjectMember(projectId, loadTestScriptReviewerConfig.getTypeValue())) {
|
||||
if (projectService.isProjectMember(projectId, sendUser)) {
|
||||
Notification notification = new Notification();
|
||||
notification.setTitle("性能测试通知");
|
||||
notification.setOperator(SessionUtils.getUserId());
|
||||
|
|
|
@ -218,7 +218,8 @@ public class ProjectApplicationService {
|
|||
String value = conf.getTypeValue();
|
||||
|
||||
//性能测试审核人,允许value值为空
|
||||
if (!StringUtils.equals(type, ProjectApplicationType.PERFORMANCE_SCRIPT_REVIEWER.name())
|
||||
if (!StringUtils.equals(type, ProjectApplicationType.API_SCRIPT_REVIEWER.name())
|
||||
&& !StringUtils.equals(type, ProjectApplicationType.PERFORMANCE_SCRIPT_REVIEWER.name())
|
||||
&& (StringUtils.isBlank(projectId) || StringUtils.isBlank(type) || StringUtils.isEmpty(value))) {
|
||||
LogUtil.error("create or update project config error. project id or conf type or value is blank.");
|
||||
return;
|
||||
|
|
|
@ -79,7 +79,9 @@
|
|||
"html-webpack-inline-source-plugin": "0.0.10",
|
||||
"less": "^3.9.0",
|
||||
"less-loader": "^7.3.0",
|
||||
"vue-template-compiler": "2.6.14"
|
||||
"vue-template-compiler": "2.6.14",
|
||||
"sass": "^1.43.4",
|
||||
"sass-loader": "^10.1.1"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
|
|
|
@ -256,6 +256,7 @@ export default {
|
|||
for (let i in arr) {
|
||||
arr[i].disabled = disabled;
|
||||
arr[i].projectId = this.calcProjectId(arr[i].projectId, id);
|
||||
arr[i].notAddStep = true;
|
||||
// 处理子请求环境
|
||||
let typeArray = ["JDBCPostProcessor", "JDBCSampler", "JDBCPreProcessor"]
|
||||
if (typeArray.indexOf(arr[i].type) !== -1) {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-button size="mini" @click="add" type="primary" v-if="tabType !== 'assertionsRule'">
|
||||
<el-button size="mini" @click="add" type="primary" v-if="tabType !== 'assertionsRule'" :disabled="request.notAddStep">
|
||||
{{ $t('api_test.request.assertions.add') }}
|
||||
</el-button>
|
||||
</p>
|
||||
|
|
|
@ -14,6 +14,15 @@ export function getResource(d) {
|
|||
|
||||
let resourceType = i18n.t('notice.resource.' + d.resourceType);
|
||||
if (!d.operation.startsWith('EXECUTE_')) {
|
||||
if (d.operation.startsWith('REVIEW') && d.resourceType === 'API_DEFINITION_TASK') {
|
||||
resourceType = i18n.t('notice.api_case');
|
||||
}
|
||||
if (d.operation.startsWith('REVIEW') && d.resourceType === 'API_AUTOMATION_TASK') {
|
||||
resourceType = i18n.t('notice.scenario_case');
|
||||
}
|
||||
if (d.operation.startsWith('REVIEW') && d.resourceType === 'ENV_TASK') {
|
||||
resourceType = i18n.t('notice.env_task');
|
||||
}
|
||||
return resourceType;
|
||||
}
|
||||
switch (d.resourceType) {
|
||||
|
@ -88,7 +97,9 @@ export function getUrl(d) {
|
|||
case "API_DEFINITION_TASK" :
|
||||
if (d.operation.startsWith('CASE_') || d.operation.startsWith('EXECUTE_')) {
|
||||
url += "/api/definition?caseId=" + d.resourceId;
|
||||
} else {
|
||||
} else if (d.operation.startsWith('REVIEW')) {
|
||||
url += "/api/definition?caseId=" + d.resourceId;
|
||||
}else {
|
||||
url += "/api/definition?resourceId=" + d.resourceId;
|
||||
}
|
||||
break;
|
||||
|
@ -113,6 +124,9 @@ export function getUrl(d) {
|
|||
case "TRACK_REPORT_TASK" :
|
||||
url += "/track/testPlan/reportList";
|
||||
break;
|
||||
case"ENV_TASK" :
|
||||
url += "/project/env?resourceId=" + d.resourceId;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -179,6 +179,20 @@ export default {
|
|||
created() {
|
||||
},
|
||||
|
||||
mounted() {
|
||||
//跳转环境编辑页面
|
||||
if (this.$route && this.$route.query && this.$route.query.resourceId) {
|
||||
let id = this.$route.query.resourceId;
|
||||
this.$get('/api/environment/get/' + id, response => {
|
||||
if (response.data) {
|
||||
this.editEnv(response.data);
|
||||
} else {
|
||||
this.$error(this.$t('environment.get_env_failed'));
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
activated() {
|
||||
this.list();
|
||||
},
|
||||
|
|
|
@ -36,13 +36,6 @@
|
|||
:unit-options="applyUnitOptions"
|
||||
@chooseChange="switchChange('TRACK_SHARE_REPORT_TIME', config.trackShareReportTime)"
|
||||
:title="$t('report.report_sharing_link')"/>
|
||||
<reviewer-config :name="$t('project.config.load_test_script_review')"
|
||||
:popTitle="$t('project.config.load_test_script_review_detail')"
|
||||
:reviewers="userInProject"
|
||||
:config.sync="config"
|
||||
@reviewerChange="switchChange('PERFORMANCE_SCRIPT_REVIEWER',config.performanceScriptReviewer)"
|
||||
@chooseChange="switchChange('PERFORMANCE_REVIEW_LOAD_TEST_SCRIPT',config.performanceReviewLoadTestScript)"
|
||||
/>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
|
||||
|
@ -107,6 +100,26 @@
|
|||
@change="runModeChange($event, ['RESOURCE_POOL_ID', config.resourcePoolId])"></el-switch>
|
||||
</template>
|
||||
</app-manage-item>
|
||||
<!-- 接口审核 -->
|
||||
<reviewer-config
|
||||
:name="$t('project.config.api_script_review')"
|
||||
:popTitle="$t('project.config.api_script_review_tips')"
|
||||
:reviewers="userInProject"
|
||||
:reviewer.sync="config.apiScriptReviewer"
|
||||
:reviewerSwitch.sync="config.apiReviewTestScript"
|
||||
@reviewerChange="
|
||||
switchChange(
|
||||
'API_SCRIPT_REVIEWER',
|
||||
config.apiScriptReviewer
|
||||
)
|
||||
"
|
||||
@chooseChange="
|
||||
switchChange(
|
||||
'API_REVIEW_TEST_SCRIPT',
|
||||
config.apiReviewTestScript
|
||||
)
|
||||
"
|
||||
/>
|
||||
|
||||
</el-row>
|
||||
</el-col>
|
||||
|
@ -196,7 +209,7 @@
|
|||
:reviewers="userInProject"
|
||||
:reviewer.sync="config.performanceScriptReviewer"
|
||||
:reviewerSwitch.sync="config.performanceReviewLoadTestScript"
|
||||
:placeholder="$t('commons.creator')"
|
||||
:placeholder="$t('commons.create_user')"
|
||||
@reviewerChange="
|
||||
switchChange(
|
||||
'PERFORMANCE_SCRIPT_REVIEWER',
|
||||
|
@ -291,6 +304,8 @@ export default {
|
|||
shareReport: true,
|
||||
performanceScriptReviewer: "",
|
||||
performanceReviewLoadTestScript: false,
|
||||
apiScriptReviewer: "",
|
||||
apiReviewTestScript: false,
|
||||
},
|
||||
isPool: false
|
||||
};
|
||||
|
@ -390,6 +405,8 @@ export default {
|
|||
if (!isExist) {
|
||||
this.$set(this.config, "performanceScriptReviewer", null);
|
||||
this.$set(this.config, "performanceReviewLoadTestScript", false);
|
||||
this.$set(this.config, "apiScriptReviewer", null);
|
||||
this.$set(this.config, "apiReviewTestScript", false);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
<el-col :span="codeSpan">
|
||||
<el-form-item>
|
||||
<template v-slot>
|
||||
<div style="position: relative;">
|
||||
<el-tabs v-model="activeName">
|
||||
<div style="position: relative;" :class="{'button-color': apiReviewTestScript}">
|
||||
<el-tabs v-model="activeName" >
|
||||
<el-tab-pane :label="$t('project.code_segment.segment')" name="code">
|
||||
<ms-code-edit
|
||||
v-if="isCodeEditAlive"
|
||||
|
@ -163,9 +163,17 @@ export default {
|
|||
response: {},
|
||||
request: {},
|
||||
debug: true,
|
||||
console: this.$t('project.code_segment.no_result')
|
||||
console: this.$t('project.code_segment.no_result'),
|
||||
apiReviewTestScript: false
|
||||
}
|
||||
},
|
||||
activated() {
|
||||
this.$get('/project_application/get/' + getCurrentProjectID() + '/API_REVIEW_TEST_SCRIPT', res => {
|
||||
if (res.data && res.data.typeValue) {
|
||||
this.apiReviewTestScript = res.data.typeValue === 'true';
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
open(data) {
|
||||
this.activeName = "code";
|
||||
|
@ -264,6 +272,10 @@ export default {
|
|||
})
|
||||
},
|
||||
handleTest() {
|
||||
if (this.apiReviewTestScript) {
|
||||
this.$warning(this.$t('project.config.script_warning'));
|
||||
return;
|
||||
}
|
||||
this.activeName = "result";
|
||||
this.console = this.$t('project.code_segment.no_result');
|
||||
this.reloadResult();
|
||||
|
@ -300,7 +312,7 @@ export default {
|
|||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang="scss" scoped>
|
||||
.template-title {
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
|
@ -343,4 +355,12 @@ export default {
|
|||
color:#935aa1;
|
||||
}
|
||||
|
||||
.button-color{
|
||||
.el-button--primary{
|
||||
color: #FFF !important;
|
||||
background-color: rgb(188, 156, 195) !important;
|
||||
border-color: rgb(188, 156, 195) !important;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -851,6 +851,10 @@ export default {
|
|||
contains_script_review: "has script step,review it please",
|
||||
load_test_script_review: "Performance test script review",
|
||||
load_test_script_review_detail: "Performance test script file upload must specify user review",
|
||||
api_script_review: "Interface script review",
|
||||
api_script_review_tips: "User review must be specified when interface use cases include script steps",
|
||||
reviewers: "Reviewers",
|
||||
script_warning:"The script has enabled the review mechanism and cannot test the script on the current page",
|
||||
}
|
||||
},
|
||||
member: {
|
||||
|
@ -1510,7 +1514,8 @@ export default {
|
|||
copy_warning: "Domain names whose enabling conditions are'none' do not support copying!",
|
||||
path_warning: "The path cannot be empty",
|
||||
project_warning: "project id cannot be empty",
|
||||
module_warning: "The path cannot be empty"
|
||||
module_warning: "The path cannot be empty",
|
||||
get_env_failed: "Jump environment deleted!",
|
||||
},
|
||||
scenario: {
|
||||
id: "Scenario ID",
|
||||
|
@ -2901,6 +2906,8 @@ export default {
|
|||
'EXECUTE_COMPLETED': ' Completed',
|
||||
},
|
||||
api_case: 'API Case',
|
||||
scenario_case: "Scenario Case",
|
||||
env_task: "Environment",
|
||||
},
|
||||
permission: {
|
||||
project_error_report_library: {
|
||||
|
|
|
@ -855,6 +855,9 @@ export default {
|
|||
load_test_script_review: "性能脚本审核",
|
||||
load_test_script_review_detail: "上传性能测试脚本文件须指定用户审核",
|
||||
contains_script_review: "包含脚本步骤,请审核",
|
||||
api_script_review: "接口脚本审核",
|
||||
api_script_review_tips: "接口用例包含脚本步骤时须指定用户审核",
|
||||
script_warning:"脚本已启用审核机制,无法在当前页面测试脚本",
|
||||
}
|
||||
},
|
||||
member: {
|
||||
|
@ -1514,7 +1517,8 @@ export default {
|
|||
copy_warning: "启用条件为 '无' 的域名不支持复制!",
|
||||
path_warning: "路径不能为空",
|
||||
project_warning: "项目不能为空",
|
||||
module_warning: "模块不能为空"
|
||||
module_warning: "模块不能为空",
|
||||
get_env_failed: "跳转环境被删除!",
|
||||
},
|
||||
scenario: {
|
||||
id: "场景ID",
|
||||
|
@ -2905,7 +2909,9 @@ export default {
|
|||
'EXECUTE_FAILED': '失败',
|
||||
'EXECUTE_COMPLETED': '完成',
|
||||
},
|
||||
api_case: '接口用例'
|
||||
api_case: '接口用例',
|
||||
scenario_case: "场景用例",
|
||||
env_task: "环境",
|
||||
},
|
||||
permission: {
|
||||
project_error_report_library: {
|
||||
|
|
|
@ -855,6 +855,10 @@ export default {
|
|||
contains_script_review: "包含脚本步骤,请审核",
|
||||
load_test_script_review: "性能腳本審核",
|
||||
load_test_script_review_detail: "上傳性能測試腳本文件須指定用戶審核",
|
||||
api_script_review: "接口腳本審核",
|
||||
api_script_review_tips: "接口用例包含腳本步驟時須指定用戶審核",
|
||||
reviewers: "審核人",
|
||||
script_warning:"腳本已啟用審核機制,無法在當前頁面測試腳本",
|
||||
}
|
||||
},
|
||||
member: {
|
||||
|
@ -1514,7 +1518,8 @@ export default {
|
|||
copy_warning: "啟用條件為 '無' 的域名不支持複製!",
|
||||
path_warning: "路徑不能為空",
|
||||
project_warning: "項目不能為空",
|
||||
module_warning: "模塊不能為空"
|
||||
module_warning: "模塊不能為空",
|
||||
get_env_failed: "跳轉環境被删除!",
|
||||
},
|
||||
scenario: {
|
||||
id: "場景ID",
|
||||
|
@ -2901,7 +2906,9 @@ export default {
|
|||
'EXECUTE_FAILED': '失敗',
|
||||
'EXECUTE_COMPLETED': '完成',
|
||||
},
|
||||
api_case: '接口用例'
|
||||
api_case: '接口用例',
|
||||
scenario_case: "場景用例",
|
||||
env_task: "環境",
|
||||
},
|
||||
permission: {
|
||||
project_error_report_library: {
|
||||
|
|
Loading…
Reference in New Issue