Merge remote-tracking branch 'origin/v1.6' into v1.6
This commit is contained in:
commit
b190b77788
|
@ -1,9 +1,9 @@
|
||||||
---
|
---
|
||||||
name: Bug 提交
|
name: BUG 提交
|
||||||
about: 提交产品缺陷帮助我们更好的改进
|
about: 提交产品缺陷帮助我们更好的改进
|
||||||
title: "[BUG]"
|
title: "[BUG]"
|
||||||
labels: bug
|
labels: bug
|
||||||
assignees: ''
|
assignees: AgAngle
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
@ -3,9 +3,8 @@ name: 问题咨询
|
||||||
about: 提出针对本项目安装部署、使用及其他方面的相关问题
|
about: 提出针对本项目安装部署、使用及其他方面的相关问题
|
||||||
title: "[QUESTION]"
|
title: "[QUESTION]"
|
||||||
labels: question
|
labels: question
|
||||||
assignees: 'wangzhen-fit2cloud'
|
assignees: wangzhen-fit2cloud
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**请描述您的问题.**
|
**请描述您的问题.**
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
name: v1.6反馈
|
||||||
|
about: 提交关于 v1.6的缺陷与建议,赢取Lv同款鼠标垫!马克杯!文化衫!
|
||||||
|
title: "[v1.6]"
|
||||||
|
labels: v1.6
|
||||||
|
assignees: luty2018
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**问题/需求描述**
|
||||||
|
简要描述您碰到的问题或您面临的需求
|
||||||
|
|
||||||
|
**截图**
|
||||||
|
如果有截图,请附上截图.
|
|
@ -5,11 +5,6 @@ on:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- v1*
|
- v1*
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- v1*
|
|
||||||
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
|
@ -270,12 +270,12 @@
|
||||||
<version>1.0.51</version>
|
<version>1.0.51</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- swagger3 解析 -->
|
<!-- swagger3 解析 最新版本会有swagger-core版本冲突 -->
|
||||||
<!--<dependency>-->
|
<dependency>
|
||||||
<!--<groupId>io.swagger.parser.v3</groupId>-->
|
<groupId>io.swagger.parser.v3</groupId>
|
||||||
<!--<artifactId>swagger-parser</artifactId>-->
|
<artifactId>swagger-parser</artifactId>
|
||||||
<!--<version>2.0.24</version>-->
|
<version>2.0.18</version>
|
||||||
<!--</dependency>-->
|
</dependency>
|
||||||
|
|
||||||
<!-- 执行 js 代码依赖 -->
|
<!-- 执行 js 代码依赖 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -3,10 +3,7 @@ package io.metersphere.api.controller;
|
||||||
import com.github.pagehelper.Page;
|
import com.github.pagehelper.Page;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import io.metersphere.api.dto.ApiCaseBatchRequest;
|
import io.metersphere.api.dto.ApiCaseBatchRequest;
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
import io.metersphere.api.dto.definition.*;
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseResult;
|
|
||||||
import io.metersphere.api.dto.definition.SaveApiTestCaseRequest;
|
|
||||||
import io.metersphere.api.service.ApiTestCaseService;
|
import io.metersphere.api.service.ApiTestCaseService;
|
||||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||||
import io.metersphere.commons.constants.RoleConstants;
|
import io.metersphere.commons.constants.RoleConstants;
|
||||||
|
@ -81,11 +78,22 @@ public class ApiTestCaseController {
|
||||||
apiTestCaseService.editApiBath(request);
|
apiTestCaseService.editApiBath(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/batch/editByParam")
|
||||||
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
|
public void editApiBathByParam(@RequestBody ApiTestBatchRequest request) {
|
||||||
|
apiTestCaseService.editApiBathByParam(request);
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/deleteBatch")
|
@PostMapping("/deleteBatch")
|
||||||
public void deleteBatch(@RequestBody List<String> ids) {
|
public void deleteBatch(@RequestBody List<String> ids) {
|
||||||
apiTestCaseService.deleteBatch(ids);
|
apiTestCaseService.deleteBatch(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/deleteBatchByParam")
|
||||||
|
public void deleteBatchByParam(@RequestBody ApiTestBatchRequest request) {
|
||||||
|
apiTestCaseService.deleteBatchByParam(request);
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/relevance")
|
@PostMapping("/relevance")
|
||||||
public void testPlanRelevance(@RequestBody ApiCaseRelevanceRequest request) {
|
public void testPlanRelevance(@RequestBody ApiCaseRelevanceRequest request) {
|
||||||
apiTestCaseService.relevanceByCase(request);
|
apiTestCaseService.relevanceByCase(request);
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package io.metersphere.api.dto.definition;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||||
|
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||||
|
import io.metersphere.controller.request.OrderRequest;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ApiTestBatchRequest extends ApiTestCaseWithBLOBs {
|
||||||
|
private List<String> ids;
|
||||||
|
private List<OrderRequest> orders;
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* isSelectAllDate:选择的数据是否是全部数据(全部数据是不受分页影响的数据)
|
||||||
|
* filters: 数据状态
|
||||||
|
* name:如果是全部数据,那么表格如果历经查询,查询参数是什么
|
||||||
|
* moduleIds: 哪些模块的数据
|
||||||
|
* unSelectIds:是否在页面上有未勾选的数据,有的话他们的ID是哪些。
|
||||||
|
* filters/name/moduleIds/unSeelctIds 只在isSelectAllDate为true时需要。为了让程序能明确批量的范围。
|
||||||
|
*/
|
||||||
|
private boolean isSelectAllDate;
|
||||||
|
|
||||||
|
private Map<String, List<String>> filters;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private List<String> moduleIds;
|
||||||
|
|
||||||
|
private List<String> unSelectIds;
|
||||||
|
|
||||||
|
private String protocol;
|
||||||
|
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
public void cleanSelectParam() {
|
||||||
|
filters = new HashMap<>();
|
||||||
|
name = null;
|
||||||
|
moduleIds = new ArrayList<>();
|
||||||
|
protocol = null;
|
||||||
|
status = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -109,12 +109,6 @@ public class MsScenario extends MsTestElement {
|
||||||
arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=")
|
arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (config != null && config.getConfig() != null && config.getConfig().getCommonConfig() != null
|
|
||||||
&& CollectionUtils.isNotEmpty(config.getConfig().getHttpConfig().getHeaders())) {
|
|
||||||
config.getConfig().getHttpConfig().getHeaders().stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue ->
|
|
||||||
arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,16 +149,6 @@ public abstract class MsTestElement {
|
||||||
arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=")
|
arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (config != null && config.getConfig() != null && config.getConfig().getCommonConfig() != null
|
|
||||||
&& CollectionUtils.isNotEmpty(config.getConfig().getHttpConfig().getHeaders())) {
|
|
||||||
arguments.setEnabled(true);
|
|
||||||
arguments.setName(name + "Variables");
|
|
||||||
arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
|
|
||||||
arguments.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ArgumentsPanel"));
|
|
||||||
config.getConfig().getHttpConfig().getHeaders().stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue ->
|
|
||||||
arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,17 +181,25 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
||||||
}
|
}
|
||||||
// 请求体
|
// 请求体
|
||||||
if (!StringUtils.equals(this.getMethod(), "GET")) {
|
if (!StringUtils.equals(this.getMethod(), "GET")) {
|
||||||
|
if (this.body != null) {
|
||||||
List<KeyValue> bodyParams = this.body.getBodyParams(sampler, this.getId());
|
List<KeyValue> bodyParams = this.body.getBodyParams(sampler, this.getId());
|
||||||
if (this.body.getType().equals("Form Data")) {
|
if (StringUtils.isNotEmpty(this.body.getType()) && this.body.getType().equals("Form Data")) {
|
||||||
sampler.setDoMultipart(true);
|
sampler.setDoMultipart(true);
|
||||||
}
|
}
|
||||||
sampler.setArguments(httpArguments(bodyParams));
|
sampler.setArguments(httpArguments(bodyParams));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final HashTree httpSamplerTree = tree.add(sampler);
|
final HashTree httpSamplerTree = tree.add(sampler);
|
||||||
if (CollectionUtils.isNotEmpty(this.headers)) {
|
// 通用请求Headers
|
||||||
setHeader(httpSamplerTree);
|
if (config != null && config.getConfig() != null && config.getConfig().getHttpConfig() != null
|
||||||
|
&& CollectionUtils.isNotEmpty(config.getConfig().getHttpConfig().getHeaders())) {
|
||||||
|
setHeader(httpSamplerTree, config.getConfig().getHttpConfig().getHeaders());
|
||||||
}
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(this.headers)) {
|
||||||
|
setHeader(httpSamplerTree, this.headers);
|
||||||
|
}
|
||||||
|
|
||||||
//判断是否要开启DNS
|
//判断是否要开启DNS
|
||||||
if (config != null && config.getConfig() != null && config.getConfig().getCommonConfig() != null
|
if (config != null && config.getConfig() != null && config.getConfig().getCommonConfig() != null
|
||||||
&& config.getConfig().getCommonConfig().isEnableHost()) {
|
&& config.getConfig().getCommonConfig().isEnableHost()) {
|
||||||
|
@ -266,7 +274,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHeader(HashTree tree) {
|
public void setHeader(HashTree tree, List<KeyValue> headers) {
|
||||||
HeaderManager headerManager = new HeaderManager();
|
HeaderManager headerManager = new HeaderManager();
|
||||||
headerManager.setEnabled(true);
|
headerManager.setEnabled(true);
|
||||||
headerManager.setName(this.getName() + "Headers");
|
headerManager.setName(this.getName() + "Headers");
|
||||||
|
|
|
@ -32,12 +32,20 @@ public class KeyValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyValue(String name, String value, String description, String contentType) {
|
public KeyValue(String name, String value, String description, String contentType) {
|
||||||
|
this(name, value, description, contentType, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyValue(String name, String value, String description, String contentType, boolean required) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.contentType = contentType;
|
this.contentType = contentType;
|
||||||
this.enable = true;
|
this.enable = true;
|
||||||
this.required = true;
|
this.required = required;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyValue(String name, String value, String description, boolean required) {
|
||||||
|
this(name, value, description, "", required);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
|
|
|
@ -70,6 +70,30 @@ public abstract class ApiImportAbstractParser implements ApiImportParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getBodyType(String contentType) {
|
||||||
|
String bodyType = "";
|
||||||
|
switch (contentType) {
|
||||||
|
case "application/x-www-form-urlencoded":
|
||||||
|
bodyType = Body.WWW_FROM;
|
||||||
|
break;
|
||||||
|
case "multipart/form-data":
|
||||||
|
bodyType = Body.FORM_DATA;
|
||||||
|
break;
|
||||||
|
case "application/json":
|
||||||
|
bodyType = Body.JSON;
|
||||||
|
break;
|
||||||
|
case "application/xml":
|
||||||
|
bodyType = Body.XML;
|
||||||
|
break;
|
||||||
|
case "application/octet-stream":
|
||||||
|
bodyType = Body.BINARY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bodyType = Body.RAW;
|
||||||
|
}
|
||||||
|
return bodyType;
|
||||||
|
}
|
||||||
|
|
||||||
protected ApiDefinitionResult buildApiDefinition(String id, String name, String path, String method) {
|
protected ApiDefinitionResult buildApiDefinition(String id, String name, String path, String method) {
|
||||||
ApiDefinitionResult apiDefinition = new ApiDefinitionResult();
|
ApiDefinitionResult apiDefinition = new ApiDefinitionResult();
|
||||||
apiDefinition.setName(name);
|
apiDefinition.setName(name);
|
||||||
|
@ -118,10 +142,10 @@ public abstract class ApiImportAbstractParser implements ApiImportParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addCookie(List<KeyValue> headers, String key, String value) {
|
protected void addCookie(List<KeyValue> headers, String key, String value) {
|
||||||
addCookie(headers, key, value, "");
|
addCookie(headers, key, value, "", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addCookie(List<KeyValue> headers, String key, String value, String description) {
|
protected void addCookie(List<KeyValue> headers, String key, String value, String description, boolean required) {
|
||||||
boolean hasCookie = false;
|
boolean hasCookie = false;
|
||||||
for (KeyValue header : headers) {
|
for (KeyValue header : headers) {
|
||||||
if (StringUtils.equalsIgnoreCase("Cookie", header.getName())) {
|
if (StringUtils.equalsIgnoreCase("Cookie", header.getName())) {
|
||||||
|
@ -131,15 +155,15 @@ public abstract class ApiImportAbstractParser implements ApiImportParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hasCookie) {
|
if (!hasCookie) {
|
||||||
addHeader(headers, "Cookie", key + "=" + value + ";", description);
|
addHeader(headers, "Cookie", key + "=" + value + ";", description, "", required);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addHeader(List<KeyValue> headers, String key, String value) {
|
protected void addHeader(List<KeyValue> headers, String key, String value) {
|
||||||
addHeader(headers, key, value, "");
|
addHeader(headers, key, value, "", "", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addHeader(List<KeyValue> headers, String key, String value, String description) {
|
protected void addHeader(List<KeyValue> headers, String key, String value, String description, String contentType, boolean required) {
|
||||||
boolean hasContentType = false;
|
boolean hasContentType = false;
|
||||||
for (KeyValue header : headers) {
|
for (KeyValue header : headers) {
|
||||||
if (StringUtils.equalsIgnoreCase(header.getName(), key)) {
|
if (StringUtils.equalsIgnoreCase(header.getName(), key)) {
|
||||||
|
@ -147,20 +171,7 @@ public abstract class ApiImportAbstractParser implements ApiImportParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hasContentType) {
|
if (!hasContentType) {
|
||||||
headers.add(new KeyValue(key, value, description));
|
headers.add(new KeyValue(key, value, description, contentType, required));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// protected void addHeader(HttpRequest request, String key, String value) {
|
|
||||||
// List<KeyValue> headers = Optional.ofNullable(request.getHeaders()).orElse(new ArrayList<>());
|
|
||||||
// boolean hasContentType = false;
|
|
||||||
// for (KeyValue header : headers) {
|
|
||||||
// if (StringUtils.equalsIgnoreCase(header.getName(), key)) {
|
|
||||||
// hasContentType = true;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (!hasContentType) {
|
|
||||||
// headers.save(new KeyValue(key, value));
|
|
||||||
// }
|
|
||||||
// request.setHeaders(headers);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,9 @@ public class MsParser extends ApiImportAbstractParser {
|
||||||
List<ApiDefinitionResult> data = apiDefinitionImport.getData();
|
List<ApiDefinitionResult> data = apiDefinitionImport.getData();
|
||||||
data.forEach(apiDefinition -> {
|
data.forEach(apiDefinition -> {
|
||||||
String id = UUID.randomUUID().toString();
|
String id = UUID.randomUUID().toString();
|
||||||
// apiDefinition.setModuleId(null);
|
if (StringUtils.isBlank(apiDefinition.getModulePath())) {
|
||||||
|
apiDefinition.setModuleId(null);
|
||||||
|
}
|
||||||
parseModule(apiDefinition, importRequest.isSaved());
|
parseModule(apiDefinition, importRequest.isSaved());
|
||||||
apiDefinition.setId(id);
|
apiDefinition.setId(id);
|
||||||
apiDefinition.setProjectId(this.projectId);
|
apiDefinition.setProjectId(this.projectId);
|
||||||
|
|
|
@ -32,11 +32,19 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
||||||
@Override
|
@Override
|
||||||
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
|
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
|
||||||
Swagger swagger;
|
Swagger swagger;
|
||||||
|
String sourceStr = "";
|
||||||
if (StringUtils.isNotBlank(request.getSwaggerUrl())) {
|
if (StringUtils.isNotBlank(request.getSwaggerUrl())) {
|
||||||
swagger = new SwaggerParser().read(request.getSwaggerUrl());
|
swagger = new SwaggerParser().read(request.getSwaggerUrl());
|
||||||
} else {
|
} else {
|
||||||
swagger = new SwaggerParser().readWithInfo(getApiTestStr(source)).getSwagger();
|
sourceStr = getApiTestStr(source);
|
||||||
|
swagger = new SwaggerParser().readWithInfo(sourceStr).getSwagger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (swagger == null || swagger.getSwagger() == null) {
|
||||||
|
Swagger3Parser swagger3Parser = new Swagger3Parser();
|
||||||
|
return swagger3Parser.parse(sourceStr, request);
|
||||||
|
}
|
||||||
|
|
||||||
ApiDefinitionImport definitionImport = new ApiDefinitionImport();
|
ApiDefinitionImport definitionImport = new ApiDefinitionImport();
|
||||||
this.projectId = request.getProjectId();
|
this.projectId = request.getProjectId();
|
||||||
definitionImport.setData(parseRequests(swagger, request.isSaved()));
|
definitionImport.setData(parseRequests(swagger, request.isSaved()));
|
||||||
|
@ -144,27 +152,7 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
||||||
return Body.RAW;
|
return Body.RAW;
|
||||||
}
|
}
|
||||||
String contentType = operation.getConsumes().get(0);
|
String contentType = operation.getConsumes().get(0);
|
||||||
String bodyType = "";
|
return getBodyType(contentType);
|
||||||
switch (contentType) {
|
|
||||||
case "application/x-www-form-urlencoded":
|
|
||||||
bodyType = Body.WWW_FROM;
|
|
||||||
break;
|
|
||||||
case "multipart/form-data":
|
|
||||||
bodyType = Body.FORM_DATA;
|
|
||||||
break;
|
|
||||||
case "application/json":
|
|
||||||
bodyType = Body.JSON;
|
|
||||||
break;
|
|
||||||
case "application/xml":
|
|
||||||
bodyType = Body.XML;
|
|
||||||
break;
|
|
||||||
case "":
|
|
||||||
bodyType = Body.BINARY;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
bodyType = Body.RAW;
|
|
||||||
}
|
|
||||||
return bodyType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parsePathParameters(Parameter parameter, List<KeyValue> rests) {
|
private void parsePathParameters(Parameter parameter, List<KeyValue> rests) {
|
||||||
|
@ -178,12 +166,13 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
||||||
|
|
||||||
private void parseCookieParameters(Parameter parameter, List<KeyValue> headers) {
|
private void parseCookieParameters(Parameter parameter, List<KeyValue> headers) {
|
||||||
CookieParameter cookieParameter = (CookieParameter) parameter;
|
CookieParameter cookieParameter = (CookieParameter) parameter;
|
||||||
addCookie(headers, cookieParameter.getName(), "", getDefaultStringValue(cookieParameter.getDescription()));
|
addCookie(headers, cookieParameter.getName(), "", getDefaultStringValue(cookieParameter.getDescription()), parameter.getRequired());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseHeaderParameters(Parameter parameter, List<KeyValue> headers) {
|
private void parseHeaderParameters(Parameter parameter, List<KeyValue> headers) {
|
||||||
HeaderParameter headerParameter = (HeaderParameter) parameter;
|
HeaderParameter headerParameter = (HeaderParameter) parameter;
|
||||||
addHeader(headers, headerParameter.getName(), "", getDefaultStringValue(headerParameter.getDescription()));
|
addHeader(headers, headerParameter.getName(), "", getDefaultStringValue(headerParameter.getDescription()),
|
||||||
|
"", parameter.getRequired());
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpResponse parseResponse(Map<String, Response> responses) {
|
private HttpResponse parseResponse(Map<String, Response> responses) {
|
||||||
|
@ -311,7 +300,7 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
||||||
|
|
||||||
private void parseFormDataParameters(FormParameter parameter, Body body) {
|
private void parseFormDataParameters(FormParameter parameter, Body body) {
|
||||||
List<KeyValue> keyValues = Optional.ofNullable(body.getKvs()).orElse(new ArrayList<>());
|
List<KeyValue> keyValues = Optional.ofNullable(body.getKvs()).orElse(new ArrayList<>());
|
||||||
KeyValue kv = new KeyValue(parameter.getName(), "", getDefaultStringValue(parameter.getDescription()));
|
KeyValue kv = new KeyValue(parameter.getName(), "", getDefaultStringValue(parameter.getDescription()), parameter.getRequired());
|
||||||
if (StringUtils.equals(parameter.getType(), "file")) {
|
if (StringUtils.equals(parameter.getType(), "file")) {
|
||||||
kv.setType("file");
|
kv.setType("file");
|
||||||
}
|
}
|
||||||
|
@ -321,6 +310,6 @@ public class Swagger2Parser extends ApiImportAbstractParser {
|
||||||
|
|
||||||
private void parseQueryParameters(Parameter parameter, List<KeyValue> arguments) {
|
private void parseQueryParameters(Parameter parameter, List<KeyValue> arguments) {
|
||||||
QueryParameter queryParameter = (QueryParameter) parameter;
|
QueryParameter queryParameter = (QueryParameter) parameter;
|
||||||
arguments.add(new KeyValue(queryParameter.getName(), "", getDefaultStringValue(queryParameter.getDescription())));
|
arguments.add(new KeyValue(queryParameter.getName(), "", getDefaultStringValue(queryParameter.getDescription()), queryParameter.getRequired()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,374 @@
|
||||||
|
package io.metersphere.api.parse;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||||
|
import io.metersphere.api.dto.definition.ApiDefinitionResult;
|
||||||
|
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
||||||
|
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||||
|
import io.metersphere.api.dto.definition.response.HttpResponse;
|
||||||
|
import io.metersphere.api.dto.scenario.Body;
|
||||||
|
import io.metersphere.api.dto.scenario.KeyValue;
|
||||||
|
import io.metersphere.api.dto.scenario.request.RequestType;
|
||||||
|
import io.metersphere.api.service.ApiModuleService;
|
||||||
|
import io.metersphere.base.domain.ApiModule;
|
||||||
|
import io.metersphere.commons.exception.MSException;
|
||||||
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import io.metersphere.commons.utils.XMLUtils;
|
||||||
|
import io.swagger.parser.OpenAPIParser;
|
||||||
|
import io.swagger.v3.oas.models.*;
|
||||||
|
import io.swagger.v3.oas.models.headers.Header;
|
||||||
|
import io.swagger.v3.oas.models.media.*;
|
||||||
|
import io.swagger.v3.oas.models.parameters.*;
|
||||||
|
import io.swagger.v3.oas.models.responses.ApiResponse;
|
||||||
|
import io.swagger.v3.oas.models.responses.ApiResponses;
|
||||||
|
import io.swagger.v3.parser.core.models.SwaggerParseResult;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.collections.MapUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
public class Swagger3Parser extends ApiImportAbstractParser {
|
||||||
|
|
||||||
|
private Components components;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
|
||||||
|
String sourceStr = "";
|
||||||
|
if (StringUtils.isBlank(request.getSwaggerUrl())) {
|
||||||
|
sourceStr = getApiTestStr(source);
|
||||||
|
}
|
||||||
|
return parse(sourceStr, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiDefinitionImport parse(String sourceStr, ApiTestImportRequest request) {
|
||||||
|
SwaggerParseResult result;
|
||||||
|
if (StringUtils.isNotBlank(request.getSwaggerUrl())) {
|
||||||
|
result = new OpenAPIParser().readLocation(request.getSwaggerUrl(), null, null);
|
||||||
|
} else {
|
||||||
|
result = new OpenAPIParser().readContents(sourceStr, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == null) {
|
||||||
|
MSException.throwException("解析失败,请确认选择的是 swagger 格式!");
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenAPI openAPI = result.getOpenAPI();
|
||||||
|
|
||||||
|
if (result.getMessages() != null) {
|
||||||
|
result.getMessages().forEach(msg -> LogUtil.error(msg)); // validation errors and warnings
|
||||||
|
}
|
||||||
|
|
||||||
|
ApiDefinitionImport definitionImport = new ApiDefinitionImport();
|
||||||
|
this.projectId = request.getProjectId();
|
||||||
|
definitionImport.setData(parseRequests(openAPI, request.isSaved()));
|
||||||
|
return definitionImport;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ApiDefinitionResult> parseRequests(OpenAPI openAPI, boolean isSaved) {
|
||||||
|
Paths paths = openAPI.getPaths();
|
||||||
|
|
||||||
|
Set<String> pathNames = paths.keySet();
|
||||||
|
|
||||||
|
this.components = openAPI.getComponents();
|
||||||
|
|
||||||
|
List<ApiDefinitionResult> results = new ArrayList<>();
|
||||||
|
|
||||||
|
for (String pathName : pathNames) {
|
||||||
|
PathItem pathItem = paths.get(pathName);
|
||||||
|
|
||||||
|
Map<String, Operation> operationsMap = new HashMap<>();
|
||||||
|
operationsMap.put(HttpMethod.GET.name(), pathItem.getGet());
|
||||||
|
operationsMap.put(HttpMethod.POST.name(), pathItem.getPost());
|
||||||
|
operationsMap.put(HttpMethod.DELETE.name(), pathItem.getDelete());
|
||||||
|
operationsMap.put(HttpMethod.PUT.name(), pathItem.getPut());
|
||||||
|
operationsMap.put(HttpMethod.PATCH.name(), pathItem.getPatch());
|
||||||
|
operationsMap.put(HttpMethod.HEAD.name(), pathItem.getHead());
|
||||||
|
operationsMap.put(HttpMethod.OPTIONS.name(), pathItem.getOptions());
|
||||||
|
operationsMap.put(HttpMethod.TRACE.name(), pathItem.getTrace());
|
||||||
|
|
||||||
|
for (String method : operationsMap.keySet()) {
|
||||||
|
Operation operation = operationsMap.get(method);
|
||||||
|
if (operation != null) {
|
||||||
|
MsHTTPSamplerProxy request = buildRequest(operation, pathName, method);
|
||||||
|
ApiDefinitionResult apiDefinition = buildApiDefinition(request.getId(), operation, pathName, method);
|
||||||
|
parseParameters(operation, request);
|
||||||
|
parseRequestBody(operation.getRequestBody(), request.getBody());
|
||||||
|
apiDefinition.setRequest(JSON.toJSONString(request));
|
||||||
|
apiDefinition.setResponse(JSON.toJSONString(parseResponse(operation.getResponses())));
|
||||||
|
buildModule(apiDefinition, operation, isSaved);
|
||||||
|
results.add(apiDefinition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildModule(ApiDefinitionResult apiDefinition, Operation operation, boolean isSaved) {
|
||||||
|
List<String> tags = operation.getTags();
|
||||||
|
if (tags != null) {
|
||||||
|
tags.forEach(tag -> {
|
||||||
|
apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||||
|
ApiModule module = apiModuleService.getNewModule(tag, this.projectId, 1);
|
||||||
|
if (isSaved) {
|
||||||
|
createModule(module);
|
||||||
|
}
|
||||||
|
apiDefinition.setModuleId(module.getId());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApiDefinitionResult buildApiDefinition(String id, Operation operation, String path, String method) {
|
||||||
|
String name = "";
|
||||||
|
if (StringUtils.isNotBlank(operation.getSummary())) {
|
||||||
|
name = operation.getSummary();
|
||||||
|
} else {
|
||||||
|
name = operation.getOperationId();
|
||||||
|
}
|
||||||
|
return buildApiDefinition(id, name, path, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MsHTTPSamplerProxy buildRequest(Operation operation, String path, String method) {
|
||||||
|
String name = "";
|
||||||
|
if (StringUtils.isNotBlank(operation.getSummary())) {
|
||||||
|
name = operation.getSummary();
|
||||||
|
} else {
|
||||||
|
name = operation.getOperationId();
|
||||||
|
}
|
||||||
|
return buildRequest(name, path, method);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseParameters(Operation operation, MsHTTPSamplerProxy request) {
|
||||||
|
|
||||||
|
List<Parameter> parameters = operation.getParameters();
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(parameters)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo 路径变量 {xxx} 是否要转换
|
||||||
|
parameters.forEach(parameter -> {
|
||||||
|
if (parameter instanceof QueryParameter) {
|
||||||
|
parseQueryParameters(parameter, request.getArguments());
|
||||||
|
} else if (parameter instanceof PathParameter) {
|
||||||
|
parsePathParameters(parameter, request.getRest());
|
||||||
|
} else if (parameter instanceof HeaderParameter) {
|
||||||
|
parseHeaderParameters(parameter, request.getHeaders());
|
||||||
|
} else if (parameter instanceof CookieParameter) {
|
||||||
|
parseCookieParameters(parameter, request.getHeaders());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parsePathParameters(Parameter parameter, List<KeyValue> rests) {
|
||||||
|
PathParameter pathParameter = (PathParameter) parameter;
|
||||||
|
rests.add(new KeyValue(pathParameter.getName(), "", getDefaultStringValue(parameter.getDescription())));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDefaultStringValue(String val) {
|
||||||
|
return StringUtils.isBlank(val) ? "" : val;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseCookieParameters(Parameter parameter, List<KeyValue> headers) {
|
||||||
|
CookieParameter cookieParameter = (CookieParameter) parameter;
|
||||||
|
addCookie(headers, cookieParameter.getName(), "", getDefaultStringValue(cookieParameter.getDescription()), parameter.getRequired());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseHeaderParameters(Parameter parameter, List<KeyValue> headers) {
|
||||||
|
HeaderParameter headerParameter = (HeaderParameter) parameter;
|
||||||
|
addHeader(headers, headerParameter.getName(), "", getDefaultStringValue(headerParameter.getDescription()), "", parameter.getRequired());
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpResponse parseResponse(ApiResponses responses) {
|
||||||
|
HttpResponse msResponse = new HttpResponse();
|
||||||
|
msResponse.setBody(new Body());
|
||||||
|
msResponse.setHeaders(new ArrayList<>());
|
||||||
|
msResponse.setType(RequestType.HTTP);
|
||||||
|
// todo 状态码要调整?
|
||||||
|
msResponse.setStatusCode(new ArrayList<>());
|
||||||
|
if (responses != null) {
|
||||||
|
responses.forEach((responseCode, response) -> {
|
||||||
|
msResponse.getStatusCode().add(new KeyValue(responseCode, responseCode));
|
||||||
|
parseResponseHeader(response, msResponse.getHeaders());
|
||||||
|
parseResponseBody(response, msResponse.getBody());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return msResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseResponseHeader(ApiResponse response, List<KeyValue> msHeaders) {
|
||||||
|
Map<String, Header> headers = response.getHeaders();
|
||||||
|
if (headers != null) {
|
||||||
|
headers.forEach((k, v) -> {
|
||||||
|
msHeaders.add(new KeyValue(k, "", v.getDescription()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseResponseBody(ApiResponse response, Body body) {
|
||||||
|
body.setRaw(response.getDescription());
|
||||||
|
Content content = response.getContent();
|
||||||
|
if (content == null) {
|
||||||
|
body.setType(Body.RAW);
|
||||||
|
body.setRaw(response.getDescription());
|
||||||
|
} else {
|
||||||
|
parseBody(response.getContent(), body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseRequestBody(RequestBody requestBody, Body body) {
|
||||||
|
if (requestBody == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parseBody(requestBody.getContent(), body);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseBody(Content content, Body body) {
|
||||||
|
if (content == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 多个contentType ,优先取json
|
||||||
|
String contentType = "";
|
||||||
|
MediaType mediaType = content.get(contentType);
|
||||||
|
if (mediaType == null) {
|
||||||
|
Set<String> contentTypes = content.keySet();
|
||||||
|
contentType = contentTypes.iterator().next();
|
||||||
|
if (StringUtils.isBlank(contentType)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mediaType = content.get(contentType);
|
||||||
|
} else {
|
||||||
|
contentType = org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> refSet = new HashSet<>();
|
||||||
|
Map<String, Schema> infoMap = new HashMap();
|
||||||
|
Schema schema = mediaType.getSchema();
|
||||||
|
Object bodyData = parseSchema(schema, refSet, infoMap);
|
||||||
|
|
||||||
|
if (bodyData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.setType(getBodyType(contentType));
|
||||||
|
|
||||||
|
if (StringUtils.equals(contentType, org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
|
||||||
|
parseKvBody(schema, body, bodyData, infoMap);
|
||||||
|
} else if (StringUtils.equals(contentType, org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE)) {
|
||||||
|
body.setRaw(bodyData.toString());
|
||||||
|
} else if (StringUtils.equals(contentType, org.springframework.http.MediaType.APPLICATION_JSON_VALUE)) {
|
||||||
|
body.setRaw(bodyData.toString());
|
||||||
|
} else if (StringUtils.equals(contentType, org.springframework.http.MediaType.APPLICATION_XML_VALUE)) {
|
||||||
|
body.setRaw(parseXmlBody(schema, bodyData));
|
||||||
|
} else if (StringUtils.equals(contentType, org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE)) {
|
||||||
|
parseKvBody(schema, body, bodyData, infoMap);
|
||||||
|
} else {
|
||||||
|
body.setRaw(bodyData.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseKvBody(Schema schema, Body body, Object data, Map<String, Schema> infoMap) {
|
||||||
|
if (data instanceof JSONObject) {
|
||||||
|
((JSONObject) data).forEach((k, v) -> {
|
||||||
|
KeyValue kv = new KeyValue(k, v.toString());
|
||||||
|
Schema schemaInfo = infoMap.get(k);
|
||||||
|
if (schemaInfo != null) {
|
||||||
|
kv.setDescription(schemaInfo.getDescription());
|
||||||
|
// kv.setRequired(schemaInfo.getRequired());
|
||||||
|
if (schemaInfo instanceof BinarySchema) {
|
||||||
|
kv.setType("file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body.getKvs().add(kv);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
KeyValue kv = new KeyValue(schema.getName(), data.toString(), schema.getDescription());
|
||||||
|
Schema schemaInfo = infoMap.get(schema.getName());
|
||||||
|
if (schemaInfo != null) {
|
||||||
|
kv.setDescription(schemaInfo.getDescription());
|
||||||
|
if (schemaInfo instanceof BinarySchema) {
|
||||||
|
kv.setType("file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body.getKvs().add(kv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseXmlBody(Schema schema, Object data) {
|
||||||
|
if (data instanceof JSONObject) {
|
||||||
|
return XMLUtils.jsonToXmlStr((JSONObject) data);
|
||||||
|
} else {
|
||||||
|
JSONObject object = new JSONObject();
|
||||||
|
object.put(schema.getName(), getDefaultValueByPropertyType(schema));
|
||||||
|
return XMLUtils.jsonToXmlStr(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Schema getModelByRef(String ref) {
|
||||||
|
if (StringUtils.isBlank(ref)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (ref.split("/").length > 3) {
|
||||||
|
ref = ref.replace("#/components/schemas/", "");
|
||||||
|
}
|
||||||
|
return this.components.getSchemas().get(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object parseSchema(Schema schema, Set<String> refSet, Map<String, Schema> infoMap) {
|
||||||
|
infoMap.put(schema.getName(), schema);
|
||||||
|
if (StringUtils.isNotBlank(schema.get$ref())) {
|
||||||
|
if (refSet.contains(schema.get$ref())) {
|
||||||
|
return new JSONObject();
|
||||||
|
}
|
||||||
|
refSet.add(schema.get$ref());
|
||||||
|
Object propertiesResult = parseSchemaProperties(getModelByRef(schema.get$ref()), refSet, infoMap);
|
||||||
|
return propertiesResult == null ? getDefaultValueByPropertyType(schema) : propertiesResult;
|
||||||
|
} else if (schema instanceof ArraySchema) {
|
||||||
|
JSONArray jsonArray = new JSONArray();
|
||||||
|
Schema items = ((ArraySchema) schema).getItems();
|
||||||
|
parseSchema(items, refSet, infoMap);
|
||||||
|
jsonArray.add(parseSchema(items, refSet, infoMap));
|
||||||
|
return jsonArray;
|
||||||
|
} else if (schema instanceof BinarySchema) {
|
||||||
|
return getDefaultValueByPropertyType(schema);
|
||||||
|
} else {
|
||||||
|
Object propertiesResult = parseSchemaProperties(schema, refSet, infoMap);
|
||||||
|
return propertiesResult == null ? getDefaultValueByPropertyType(schema) : propertiesResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object parseSchemaProperties(Schema schema, Set<String> refSet, Map<String, Schema> infoMap) {
|
||||||
|
Map<String, Schema> properties = schema.getProperties();
|
||||||
|
if (MapUtils.isEmpty(properties)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
properties.forEach((key, value) -> {
|
||||||
|
jsonObject.put(key, parseSchema(value, refSet, infoMap));
|
||||||
|
});
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getDefaultValueByPropertyType(Schema value) {
|
||||||
|
Object example = value.getExample();
|
||||||
|
if (value instanceof IntegerSchema) {
|
||||||
|
return example == null ? 0 : example;
|
||||||
|
} else if (value instanceof NumberSchema) {
|
||||||
|
return example == null ? 0.0 : example;
|
||||||
|
} else {// todo 其他类型?
|
||||||
|
return getDefaultStringValue(value.getDescription());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseQueryParameters(Parameter parameter, List<KeyValue> arguments) {
|
||||||
|
QueryParameter queryParameter = (QueryParameter) parameter;
|
||||||
|
arguments.add(new KeyValue(queryParameter.getName(), "", getDefaultStringValue(queryParameter.getDescription()), parameter.getRequired()));
|
||||||
|
}
|
||||||
|
}
|
|
@ -385,6 +385,7 @@ public class ApiAutomationService {
|
||||||
selectRequest.setName(name);
|
selectRequest.setName(name);
|
||||||
selectRequest.setProjectId(projectId);
|
selectRequest.setProjectId(projectId);
|
||||||
selectRequest.setFilters(filters);
|
selectRequest.setFilters(filters);
|
||||||
|
selectRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||||
List<ApiScenarioDTO> list = extApiScenarioMapper.list(selectRequest);
|
List<ApiScenarioDTO> list = extApiScenarioMapper.list(selectRequest);
|
||||||
List<String> allIds = list.stream().map(ApiScenarioDTO::getId).collect(Collectors.toList());
|
List<String> allIds = list.stream().map(ApiScenarioDTO::getId).collect(Collectors.toList());
|
||||||
List<String> ids = allIds.stream().filter(id -> !unSelectIds.contains(id)).collect(Collectors.toList());
|
List<String> ids = allIds.stream().filter(id -> !unSelectIds.contains(id)).collect(Collectors.toList());
|
||||||
|
|
|
@ -485,6 +485,7 @@ public class ApiDefinitionService {
|
||||||
request.setName(name);
|
request.setName(name);
|
||||||
request.setModuleIds(moduleIds);
|
request.setModuleIds(moduleIds);
|
||||||
request.setProjectId(projectId);
|
request.setProjectId(projectId);
|
||||||
|
request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||||
List<ApiDefinitionResult> resList = extApiDefinitionMapper.list(request);
|
List<ApiDefinitionResult> resList = extApiDefinitionMapper.list(request);
|
||||||
List<String> ids = new ArrayList<>(0);
|
List<String> ids = new ArrayList<>(0);
|
||||||
if (!resList.isEmpty()) {
|
if (!resList.isEmpty()) {
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
package io.metersphere.api.service;
|
package io.metersphere.api.service;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
||||||
|
import io.metersphere.api.dto.automation.ApiScenarioRequest;
|
||||||
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
import io.metersphere.api.dto.definition.*;
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseResult;
|
|
||||||
import io.metersphere.api.dto.definition.SaveApiTestCaseRequest;
|
|
||||||
import io.metersphere.api.dto.ApiCaseBatchRequest;
|
import io.metersphere.api.dto.ApiCaseBatchRequest;
|
||||||
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
|
|
||||||
import io.metersphere.base.domain.*;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.mapper.ApiDefinitionMapper;
|
import io.metersphere.base.mapper.ApiDefinitionMapper;
|
||||||
import io.metersphere.base.mapper.ApiTestCaseMapper;
|
import io.metersphere.base.mapper.ApiTestCaseMapper;
|
||||||
|
@ -26,6 +25,7 @@ import org.apache.ibatis.session.ExecutorType;
|
||||||
import org.apache.ibatis.session.SqlSession;
|
import org.apache.ibatis.session.SqlSession;
|
||||||
import org.apache.ibatis.session.SqlSessionFactory;
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.aspectj.util.FileUtil;
|
import org.aspectj.util.FileUtil;
|
||||||
|
import org.python.antlr.ast.Str;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
@ -348,4 +348,41 @@ public class ApiTestCaseService {
|
||||||
List<ApiTestCaseWithBLOBs> list = extApiTestCaseMapper.getRequest(request);
|
List<ApiTestCaseWithBLOBs> list = extApiTestCaseMapper.getRequest(request);
|
||||||
return list.stream().collect(Collectors.toMap(ApiTestCaseWithBLOBs::getId, ApiTestCaseWithBLOBs::getRequest));
|
return list.stream().collect(Collectors.toMap(ApiTestCaseWithBLOBs::getId, ApiTestCaseWithBLOBs::getRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteBatchByParam(ApiTestBatchRequest request) {
|
||||||
|
List<String> ids = request.getIds();
|
||||||
|
if(request.isSelectAllDate()){
|
||||||
|
ids = this.getAllApiCaseIdsByFontedSelect(request.getFilters(),request.getModuleIds(),request.getName(),request.getProjectId(),request.getProtocol(),request.getUnSelectIds(),request.getStatus());
|
||||||
|
}
|
||||||
|
this.deleteBatch(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void editApiBathByParam(ApiTestBatchRequest request) {
|
||||||
|
List<String> ids = request.getIds();
|
||||||
|
if(request.isSelectAllDate()){
|
||||||
|
ids = this.getAllApiCaseIdsByFontedSelect(request.getFilters(),request.getModuleIds(),request.getName(),request.getProjectId(),request.getProtocol(),request.getUnSelectIds(),request.getStatus());
|
||||||
|
}
|
||||||
|
request.cleanSelectParam();
|
||||||
|
ApiTestCaseExample apiDefinitionExample = new ApiTestCaseExample();
|
||||||
|
apiDefinitionExample.createCriteria().andIdIn(ids);
|
||||||
|
ApiTestCaseWithBLOBs apiDefinitionWithBLOBs = new ApiTestCaseWithBLOBs();
|
||||||
|
BeanUtils.copyBean(apiDefinitionWithBLOBs, request);
|
||||||
|
apiDefinitionWithBLOBs.setUpdateTime(System.currentTimeMillis());
|
||||||
|
apiTestCaseMapper.updateByExampleSelective(apiDefinitionWithBLOBs, apiDefinitionExample);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> getAllApiCaseIdsByFontedSelect(Map<String, List<String>> filters,List<String>moduleIds, String name, String projectId, String protocol,List<String> unSelectIds,String status) {
|
||||||
|
ApiTestCaseRequest selectRequest = new ApiTestCaseRequest();
|
||||||
|
selectRequest.setFilters(filters);
|
||||||
|
selectRequest.setModuleIds(moduleIds);
|
||||||
|
selectRequest.setName(name);
|
||||||
|
selectRequest.setProjectId(projectId);
|
||||||
|
selectRequest.setProtocol(protocol);
|
||||||
|
selectRequest.setStatus(status);
|
||||||
|
selectRequest.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||||
|
List<ApiTestCaseResult> list = extApiTestCaseMapper.list(selectRequest);
|
||||||
|
List<String> allIds = list.stream().map(ApiTestCaseResult::getId).collect(Collectors.toList());
|
||||||
|
List<String> ids = allIds.stream().filter(id -> !unSelectIds.contains(id)).collect(Collectors.toList());
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
package io.metersphere.base.domain;
|
package io.metersphere.base.domain;
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class TestPlan implements Serializable {
|
public class TestPlan implements Serializable {
|
||||||
|
@ -40,6 +39,8 @@ public class TestPlan implements Serializable {
|
||||||
|
|
||||||
private String creator;
|
private String creator;
|
||||||
|
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
private String tags;
|
private String tags;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
|
@ -1233,6 +1233,76 @@ public class TestPlanExample {
|
||||||
addCriterion("creator not between", value1, value2, "creator");
|
addCriterion("creator not between", value1, value2, "creator");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdIsNull() {
|
||||||
|
addCriterion("project_id is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdIsNotNull() {
|
||||||
|
addCriterion("project_id is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdEqualTo(String value) {
|
||||||
|
addCriterion("project_id =", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdNotEqualTo(String value) {
|
||||||
|
addCriterion("project_id <>", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdGreaterThan(String value) {
|
||||||
|
addCriterion("project_id >", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("project_id >=", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdLessThan(String value) {
|
||||||
|
addCriterion("project_id <", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("project_id <=", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdLike(String value) {
|
||||||
|
addCriterion("project_id like", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdNotLike(String value) {
|
||||||
|
addCriterion("project_id not like", value, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdIn(List<String> values) {
|
||||||
|
addCriterion("project_id in", values, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdNotIn(List<String> values) {
|
||||||
|
addCriterion("project_id not in", values, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdBetween(String value1, String value2) {
|
||||||
|
addCriterion("project_id between", value1, value2, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andProjectIdNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("project_id not between", value1, value2, "projectId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Criteria extends GeneratedCriteria {
|
public static class Criteria extends GeneratedCriteria {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
<result column="planned_end_time" jdbcType="BIGINT" property="plannedEndTime" />
|
<result column="planned_end_time" jdbcType="BIGINT" property="plannedEndTime" />
|
||||||
<result column="actual_start_time" jdbcType="BIGINT" property="actualStartTime" />
|
<result column="actual_start_time" jdbcType="BIGINT" property="actualStartTime" />
|
||||||
<result column="creator" jdbcType="VARCHAR" property="creator" />
|
<result column="creator" jdbcType="VARCHAR" property="creator" />
|
||||||
|
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.TestPlan">
|
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.TestPlan">
|
||||||
<result column="tags" jdbcType="LONGVARCHAR" property="tags" />
|
<result column="tags" jdbcType="LONGVARCHAR" property="tags" />
|
||||||
|
@ -84,7 +85,7 @@
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, workspace_id, report_id, `name`, description, `status`, stage, principal, test_case_match_rule,
|
id, workspace_id, report_id, `name`, description, `status`, stage, principal, test_case_match_rule,
|
||||||
executor_match_rule, create_time, update_time, actual_end_time, planned_start_time,
|
executor_match_rule, create_time, update_time, actual_end_time, planned_start_time,
|
||||||
planned_end_time, actual_start_time, creator
|
planned_end_time, actual_start_time, creator, project_id
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Blob_Column_List">
|
<sql id="Blob_Column_List">
|
||||||
tags
|
tags
|
||||||
|
@ -143,15 +144,15 @@
|
||||||
stage, principal, test_case_match_rule,
|
stage, principal, test_case_match_rule,
|
||||||
executor_match_rule, create_time, update_time,
|
executor_match_rule, create_time, update_time,
|
||||||
actual_end_time, planned_start_time, planned_end_time,
|
actual_end_time, planned_start_time, planned_end_time,
|
||||||
actual_start_time, creator, tags
|
actual_start_time, creator, project_id,
|
||||||
)
|
tags)
|
||||||
values (#{id,jdbcType=VARCHAR}, #{workspaceId,jdbcType=VARCHAR}, #{reportId,jdbcType=VARCHAR},
|
values (#{id,jdbcType=VARCHAR}, #{workspaceId,jdbcType=VARCHAR}, #{reportId,jdbcType=VARCHAR},
|
||||||
#{name,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR},
|
#{name,jdbcType=VARCHAR}, #{description,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR},
|
||||||
#{stage,jdbcType=VARCHAR}, #{principal,jdbcType=VARCHAR}, #{testCaseMatchRule,jdbcType=VARCHAR},
|
#{stage,jdbcType=VARCHAR}, #{principal,jdbcType=VARCHAR}, #{testCaseMatchRule,jdbcType=VARCHAR},
|
||||||
#{executorMatchRule,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
#{executorMatchRule,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
||||||
#{actualEndTime,jdbcType=BIGINT}, #{plannedStartTime,jdbcType=BIGINT}, #{plannedEndTime,jdbcType=BIGINT},
|
#{actualEndTime,jdbcType=BIGINT}, #{plannedStartTime,jdbcType=BIGINT}, #{plannedEndTime,jdbcType=BIGINT},
|
||||||
#{actualStartTime,jdbcType=BIGINT}, #{creator,jdbcType=VARCHAR}, #{tags,jdbcType=LONGVARCHAR}
|
#{actualStartTime,jdbcType=BIGINT}, #{creator,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR},
|
||||||
)
|
#{tags,jdbcType=LONGVARCHAR})
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestPlan">
|
<insert id="insertSelective" parameterType="io.metersphere.base.domain.TestPlan">
|
||||||
insert into test_plan
|
insert into test_plan
|
||||||
|
@ -207,6 +208,9 @@
|
||||||
<if test="creator != null">
|
<if test="creator != null">
|
||||||
creator,
|
creator,
|
||||||
</if>
|
</if>
|
||||||
|
<if test="projectId != null">
|
||||||
|
project_id,
|
||||||
|
</if>
|
||||||
<if test="tags != null">
|
<if test="tags != null">
|
||||||
tags,
|
tags,
|
||||||
</if>
|
</if>
|
||||||
|
@ -263,6 +267,9 @@
|
||||||
<if test="creator != null">
|
<if test="creator != null">
|
||||||
#{creator,jdbcType=VARCHAR},
|
#{creator,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="projectId != null">
|
||||||
|
#{projectId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="tags != null">
|
<if test="tags != null">
|
||||||
#{tags,jdbcType=LONGVARCHAR},
|
#{tags,jdbcType=LONGVARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
@ -328,6 +335,9 @@
|
||||||
<if test="record.creator != null">
|
<if test="record.creator != null">
|
||||||
creator = #{record.creator,jdbcType=VARCHAR},
|
creator = #{record.creator,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="record.projectId != null">
|
||||||
|
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="record.tags != null">
|
<if test="record.tags != null">
|
||||||
tags = #{record.tags,jdbcType=LONGVARCHAR},
|
tags = #{record.tags,jdbcType=LONGVARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
@ -355,6 +365,7 @@
|
||||||
planned_end_time = #{record.plannedEndTime,jdbcType=BIGINT},
|
planned_end_time = #{record.plannedEndTime,jdbcType=BIGINT},
|
||||||
actual_start_time = #{record.actualStartTime,jdbcType=BIGINT},
|
actual_start_time = #{record.actualStartTime,jdbcType=BIGINT},
|
||||||
creator = #{record.creator,jdbcType=VARCHAR},
|
creator = #{record.creator,jdbcType=VARCHAR},
|
||||||
|
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||||
tags = #{record.tags,jdbcType=LONGVARCHAR}
|
tags = #{record.tags,jdbcType=LONGVARCHAR}
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
@ -378,7 +389,8 @@
|
||||||
planned_start_time = #{record.plannedStartTime,jdbcType=BIGINT},
|
planned_start_time = #{record.plannedStartTime,jdbcType=BIGINT},
|
||||||
planned_end_time = #{record.plannedEndTime,jdbcType=BIGINT},
|
planned_end_time = #{record.plannedEndTime,jdbcType=BIGINT},
|
||||||
actual_start_time = #{record.actualStartTime,jdbcType=BIGINT},
|
actual_start_time = #{record.actualStartTime,jdbcType=BIGINT},
|
||||||
creator = #{record.creator,jdbcType=VARCHAR}
|
creator = #{record.creator,jdbcType=VARCHAR},
|
||||||
|
project_id = #{record.projectId,jdbcType=VARCHAR}
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
</if>
|
</if>
|
||||||
|
@ -434,6 +446,9 @@
|
||||||
<if test="creator != null">
|
<if test="creator != null">
|
||||||
creator = #{creator,jdbcType=VARCHAR},
|
creator = #{creator,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="projectId != null">
|
||||||
|
project_id = #{projectId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="tags != null">
|
<if test="tags != null">
|
||||||
tags = #{tags,jdbcType=LONGVARCHAR},
|
tags = #{tags,jdbcType=LONGVARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
@ -458,6 +473,7 @@
|
||||||
planned_end_time = #{plannedEndTime,jdbcType=BIGINT},
|
planned_end_time = #{plannedEndTime,jdbcType=BIGINT},
|
||||||
actual_start_time = #{actualStartTime,jdbcType=BIGINT},
|
actual_start_time = #{actualStartTime,jdbcType=BIGINT},
|
||||||
creator = #{creator,jdbcType=VARCHAR},
|
creator = #{creator,jdbcType=VARCHAR},
|
||||||
|
project_id = #{projectId,jdbcType=VARCHAR},
|
||||||
tags = #{tags,jdbcType=LONGVARCHAR}
|
tags = #{tags,jdbcType=LONGVARCHAR}
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
</update>
|
</update>
|
||||||
|
@ -478,7 +494,8 @@
|
||||||
planned_start_time = #{plannedStartTime,jdbcType=BIGINT},
|
planned_start_time = #{plannedStartTime,jdbcType=BIGINT},
|
||||||
planned_end_time = #{plannedEndTime,jdbcType=BIGINT},
|
planned_end_time = #{plannedEndTime,jdbcType=BIGINT},
|
||||||
actual_start_time = #{actualStartTime,jdbcType=BIGINT},
|
actual_start_time = #{actualStartTime,jdbcType=BIGINT},
|
||||||
creator = #{creator,jdbcType=VARCHAR}
|
creator = #{creator,jdbcType=VARCHAR},
|
||||||
|
project_id = #{projectId,jdbcType=VARCHAR}
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
</update>
|
</update>
|
||||||
</mapper>
|
</mapper>
|
|
@ -98,9 +98,9 @@
|
||||||
|
|
||||||
<select id="list" resultType="io.metersphere.track.dto.TestPlanDTOWithMetric"
|
<select id="list" resultType="io.metersphere.track.dto.TestPlanDTOWithMetric"
|
||||||
parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
||||||
select DISTINCT test_plan.*, user.name as user_name from test_plan
|
select DISTINCT test_plan.*, user.name as user_name, project.name as projectName from test_plan
|
||||||
LEFT JOIN user ON user.id = test_plan.principal
|
LEFT JOIN user ON user.id = test_plan.principal
|
||||||
JOIN test_plan_project on test_plan.id = test_plan_project.test_plan_id JOIN project on project.id = test_plan_project.project_id
|
JOIN project on project.id = test_plan.project_id
|
||||||
<where>
|
<where>
|
||||||
<if test="request.combine != null">
|
<if test="request.combine != null">
|
||||||
<include refid="combine">
|
<include refid="combine">
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
AND test_plan.workspace_id = #{request.workspaceId}
|
AND test_plan.workspace_id = #{request.workspaceId}
|
||||||
</if>
|
</if>
|
||||||
<if test="request.projectId != null">
|
<if test="request.projectId != null">
|
||||||
AND test_plan_project.project_id = #{request.projectId}
|
AND test_plan.project_id = #{request.projectId}
|
||||||
</if>
|
</if>
|
||||||
<if test="request.id != null">
|
<if test="request.id != null">
|
||||||
AND test_plan.id = #{request.id}
|
AND test_plan.id = #{request.id}
|
||||||
|
@ -164,11 +164,10 @@
|
||||||
|
|
||||||
<select id="listRelate" resultType="io.metersphere.track.dto.TestPlanDTOWithMetric">
|
<select id="listRelate" resultType="io.metersphere.track.dto.TestPlanDTOWithMetric">
|
||||||
select distinct test_plan.* from test_plan
|
select distinct test_plan.* from test_plan
|
||||||
inner join test_plan_project on test_plan.id = test_plan_project.test_plan_id
|
|
||||||
<where>
|
<where>
|
||||||
test_plan.workspace_id = #{request.workspaceId}
|
test_plan.workspace_id = #{request.workspaceId}
|
||||||
<if test="request.projectId != null">
|
<if test="request.projectId != null">
|
||||||
and test_plan_project.project_id = #{request.projectId}
|
and test_plan.project_id = #{request.projectId}
|
||||||
</if>
|
</if>
|
||||||
and (test_plan.principal = #{request.principal}
|
and (test_plan.principal = #{request.principal}
|
||||||
<if test="request.planIds != null and request.planIds.size() > 0">
|
<if test="request.planIds != null and request.planIds.size() > 0">
|
||||||
|
@ -190,7 +189,8 @@
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="checkIsHave" resultType="int">
|
<select id="checkIsHave" resultType="int">
|
||||||
SELECT COUNT(1)
|
select sum(c) from (
|
||||||
|
SELECT COUNT(1) as c
|
||||||
FROM test_plan_project, project
|
FROM test_plan_project, project
|
||||||
WHERE project_id = project.id AND test_plan_id = #{planId}
|
WHERE project_id = project.id AND test_plan_id = #{planId}
|
||||||
<if test="workspaceIds != null and workspaceIds.size() > 0">
|
<if test="workspaceIds != null and workspaceIds.size() > 0">
|
||||||
|
@ -199,6 +199,15 @@
|
||||||
#{id}
|
#{id}
|
||||||
</foreach>
|
</foreach>
|
||||||
</if>
|
</if>
|
||||||
|
union
|
||||||
|
select count(1) as c from test_plan, project
|
||||||
|
WHERE project_id = project.id AND test_plan.id = #{planId}
|
||||||
|
<if test="workspaceIds != null and workspaceIds.size() > 0">
|
||||||
|
AND project.workspace_id IN
|
||||||
|
<foreach collection="workspaceIds" item="id" separator="," open="(" close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</if>) as temp
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectTestPlanByRelevancy" resultMap="BaseResultMap" parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
<select id="selectTestPlanByRelevancy" resultMap="BaseResultMap" parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
||||||
|
|
|
@ -272,13 +272,11 @@
|
||||||
select distinct plan_id from test_plan_test_case
|
select distinct plan_id from test_plan_test_case
|
||||||
inner join test_plan
|
inner join test_plan
|
||||||
on test_plan_test_case.plan_id = test_plan.id
|
on test_plan_test_case.plan_id = test_plan.id
|
||||||
inner join test_plan_project
|
|
||||||
on test_plan.id = test_plan_project.test_plan_id
|
|
||||||
<where>
|
<where>
|
||||||
test_plan_test_case.executor = #{userId}
|
test_plan_test_case.executor = #{userId}
|
||||||
and test_plan.workspace_id = #{workspaceId}
|
and test_plan.workspace_id = #{workspaceId}
|
||||||
<if test="projectId != null">
|
<if test="projectId != null">
|
||||||
and test_plan_project.project_id = #{projectId}
|
and test_plan.project_id = #{projectId}
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package io.metersphere.commons.utils;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONArray;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class XMLUtils {
|
||||||
|
|
||||||
|
private static void jsonToXmlStr(JSONObject jObj, StringBuffer buffer) {
|
||||||
|
Set<Map.Entry<String, Object>> se = jObj.entrySet();
|
||||||
|
for (Map.Entry<String, Object> en : se) {
|
||||||
|
if ("com.alibaba.fastjson.JSONObject".equals(en.getValue().getClass().getName())) {
|
||||||
|
buffer.append("<").append(en.getKey()).append(">");
|
||||||
|
JSONObject jo = jObj.getJSONObject(en.getKey());
|
||||||
|
jsonToXmlStr(jo, buffer);
|
||||||
|
buffer.append("</").append(en.getKey()).append(">");
|
||||||
|
} else if ("com.alibaba.fastjson.JSONArray".equals(en.getValue().getClass().getName())) {
|
||||||
|
JSONArray jarray = jObj.getJSONArray(en.getKey());
|
||||||
|
for (int i = 0; i < jarray.size(); i++) {
|
||||||
|
buffer.append("<").append(en.getKey()).append(">");
|
||||||
|
if (StringUtils.isNotBlank(jarray.getString(i))) {
|
||||||
|
JSONObject jsonobject = jarray.getJSONObject(i);
|
||||||
|
jsonToXmlStr(jsonobject, buffer);
|
||||||
|
buffer.append("</").append(en.getKey()).append(">");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("java.lang.String".equals(en.getValue().getClass().getName())) {
|
||||||
|
buffer.append("<").append(en.getKey()).append(">").append(en.getValue());
|
||||||
|
buffer.append("</").append(en.getKey()).append(">");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String jsonToXmlStr(JSONObject jObj) {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
buffer.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
|
||||||
|
try {
|
||||||
|
jsonToXmlStr(jObj, buffer);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import io.metersphere.base.domain.User;
|
||||||
import io.metersphere.commons.utils.SessionUtils;
|
import io.metersphere.commons.utils.SessionUtils;
|
||||||
import io.metersphere.controller.handler.annotation.NoResultHolder;
|
import io.metersphere.controller.handler.annotation.NoResultHolder;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
@ -35,6 +36,15 @@ public class TestController {
|
||||||
return jsonObject;
|
return jsonObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/wwwform", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
|
||||||
|
public Object testWwwForm(String id, User user, String name) {
|
||||||
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
jsonObject.put("id", id);
|
||||||
|
jsonObject.put("user", user.getName());
|
||||||
|
jsonObject.put("name", name);
|
||||||
|
return jsonObject;
|
||||||
|
}
|
||||||
|
|
||||||
@NoResultHolder
|
@NoResultHolder
|
||||||
@GetMapping(value = "/xml")
|
@GetMapping(value = "/xml")
|
||||||
public String getXmlString() {
|
public String getXmlString() {
|
||||||
|
|
|
@ -27,4 +27,6 @@ public class QueryTestPlanRequest extends TestPlan {
|
||||||
private Map<String, Object> combine;
|
private Map<String, Object> combine;
|
||||||
|
|
||||||
private String projectId;
|
private String projectId;
|
||||||
|
|
||||||
|
private String projectName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package io.metersphere.track.service;
|
package io.metersphere.track.service;
|
||||||
|
|
||||||
import io.metersphere.base.domain.Project;
|
import io.metersphere.base.domain.*;
|
||||||
import io.metersphere.base.domain.ProjectExample;
|
|
||||||
import io.metersphere.base.domain.TestPlanProject;
|
|
||||||
import io.metersphere.base.domain.TestPlanProjectExample;
|
|
||||||
import io.metersphere.base.mapper.ProjectMapper;
|
import io.metersphere.base.mapper.ProjectMapper;
|
||||||
|
import io.metersphere.base.mapper.TestPlanMapper;
|
||||||
import io.metersphere.base.mapper.TestPlanProjectMapper;
|
import io.metersphere.base.mapper.TestPlanProjectMapper;
|
||||||
import io.metersphere.track.request.testplancase.TestCaseRelevanceRequest;
|
import io.metersphere.track.request.testplancase.TestCaseRelevanceRequest;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -24,15 +22,22 @@ public class TestPlanProjectService {
|
||||||
TestPlanProjectMapper testPlanProjectMapper;
|
TestPlanProjectMapper testPlanProjectMapper;
|
||||||
@Resource
|
@Resource
|
||||||
ProjectMapper projectMapper;
|
ProjectMapper projectMapper;
|
||||||
|
@Resource
|
||||||
|
private TestPlanMapper testPlanMapper;
|
||||||
|
|
||||||
public List<String> getProjectIdsByPlanId(String planId) {
|
public List<String> getProjectIdsByPlanId(String planId) {
|
||||||
|
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(planId);
|
||||||
TestPlanProjectExample example = new TestPlanProjectExample();
|
TestPlanProjectExample example = new TestPlanProjectExample();
|
||||||
example.createCriteria().andTestPlanIdEqualTo(planId);
|
example.createCriteria().andTestPlanIdEqualTo(planId);
|
||||||
List<String> projectIds = testPlanProjectMapper.selectByExample(example)
|
List<String> projectIds = testPlanProjectMapper.selectByExample(example)
|
||||||
.stream()
|
.stream()
|
||||||
.map(TestPlanProject::getProjectId)
|
.map(TestPlanProject::getProjectId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
if (testPlan != null && StringUtils.isNotBlank(testPlan.getProjectId())) {
|
||||||
|
if (!projectIds.contains(testPlan.getProjectId())) {
|
||||||
|
projectIds.add(testPlan.getProjectId());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (projectIds.isEmpty()) {
|
if (projectIds.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,6 +111,7 @@ public class TestPlanService {
|
||||||
testPlan.setCreateTime(System.currentTimeMillis());
|
testPlan.setCreateTime(System.currentTimeMillis());
|
||||||
testPlan.setUpdateTime(System.currentTimeMillis());
|
testPlan.setUpdateTime(System.currentTimeMillis());
|
||||||
testPlan.setCreator(SessionUtils.getUser().getId());
|
testPlan.setCreator(SessionUtils.getUser().getId());
|
||||||
|
testPlan.setProjectId(SessionUtils.getCurrentProjectId());
|
||||||
testPlanMapper.insert(testPlan);
|
testPlanMapper.insert(testPlan);
|
||||||
|
|
||||||
List<String> userIds = new ArrayList<>();
|
List<String> userIds = new ArrayList<>();
|
||||||
|
@ -177,8 +178,16 @@ public class TestPlanService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void editTestPlanProject(TestPlanDTO testPlan) {
|
private void editTestPlanProject(TestPlanDTO testPlan) {
|
||||||
|
// 将要进行关联的项目ID
|
||||||
List<String> projectIds = testPlan.getProjectIds();
|
List<String> projectIds = testPlan.getProjectIds();
|
||||||
|
// 如果将要关联的项目ID中包含测试计划所属ID则进行剔除
|
||||||
if (!CollectionUtils.isEmpty(projectIds)) {
|
if (!CollectionUtils.isEmpty(projectIds)) {
|
||||||
|
if (projectIds.contains(testPlan.getProjectId())) {
|
||||||
|
projectIds.remove(testPlan.getProjectId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// todo 优化; TestPlanList intoPlan 方法会触发此更新
|
||||||
|
if (StringUtils.isNotBlank(testPlan.getProjectId())) {
|
||||||
TestPlanProjectExample testPlanProjectExample1 = new TestPlanProjectExample();
|
TestPlanProjectExample testPlanProjectExample1 = new TestPlanProjectExample();
|
||||||
testPlanProjectExample1.createCriteria().andTestPlanIdEqualTo(testPlan.getId());
|
testPlanProjectExample1.createCriteria().andTestPlanIdEqualTo(testPlan.getId());
|
||||||
List<TestPlanProject> testPlanProjects = testPlanProjectMapper.selectByExample(testPlanProjectExample1);
|
List<TestPlanProject> testPlanProjects = testPlanProjectMapper.selectByExample(testPlanProjectExample1);
|
||||||
|
@ -195,16 +204,25 @@ public class TestPlanService {
|
||||||
});
|
});
|
||||||
|
|
||||||
TestPlanProjectExample testPlanProjectExample = new TestPlanProjectExample();
|
TestPlanProjectExample testPlanProjectExample = new TestPlanProjectExample();
|
||||||
testPlanProjectExample.createCriteria().andTestPlanIdEqualTo(testPlan.getId()).andProjectIdNotIn(projectIds);
|
TestPlanProjectExample.Criteria criteria1 = testPlanProjectExample.createCriteria();
|
||||||
|
criteria1.andTestPlanIdEqualTo(testPlan.getId());
|
||||||
|
if (!CollectionUtils.isEmpty(projectIds)) {
|
||||||
|
criteria1.andProjectIdNotIn(projectIds);
|
||||||
|
}
|
||||||
testPlanProjectMapper.deleteByExample(testPlanProjectExample);
|
testPlanProjectMapper.deleteByExample(testPlanProjectExample);
|
||||||
|
|
||||||
// 关联的项目下的用例idList
|
// 关联的项目下的用例idList
|
||||||
|
List<String> caseIds = null;
|
||||||
|
// 测试计划所属项目下的用例不解除关联
|
||||||
|
projectIds.add(testPlan.getProjectId());
|
||||||
|
if (!CollectionUtils.isEmpty(projectIds)) {
|
||||||
TestCaseExample example = new TestCaseExample();
|
TestCaseExample example = new TestCaseExample();
|
||||||
example.createCriteria().andProjectIdIn(projectIds);
|
example.createCriteria().andProjectIdIn(projectIds);
|
||||||
List<TestCase> caseList = testCaseMapper.selectByExample(example);
|
List<TestCase> caseList = testCaseMapper.selectByExample(example);
|
||||||
List<String> caseIds = caseList.stream().map(TestCase::getId).collect(Collectors.toList());
|
caseIds = caseList.stream().map(TestCase::getId).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
// 取消关联所属项目下的用例和计划的关系
|
// 取消关联项目下的用例和计划的关系
|
||||||
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
|
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
|
||||||
TestPlanTestCaseExample.Criteria criteria = testPlanTestCaseExample.createCriteria().andPlanIdEqualTo(testPlan.getId());
|
TestPlanTestCaseExample.Criteria criteria = testPlanTestCaseExample.createCriteria().andPlanIdEqualTo(testPlan.getId());
|
||||||
if (!CollectionUtils.isEmpty(caseIds)) {
|
if (!CollectionUtils.isEmpty(caseIds)) {
|
||||||
|
@ -415,13 +433,13 @@ public class TestPlanService {
|
||||||
if (StringUtils.isBlank(currentWorkspaceId)) {
|
if (StringUtils.isBlank(currentWorkspaceId)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
TestPlanProjectExample testPlanProjectExample = new TestPlanProjectExample();
|
|
||||||
TestPlanProjectExample.Criteria criteria = testPlanProjectExample.createCriteria();
|
|
||||||
if (StringUtils.isNotBlank(SessionUtils.getCurrentProjectId())) {
|
if (StringUtils.isNotBlank(SessionUtils.getCurrentProjectId())) {
|
||||||
|
TestPlanExample testPlanExample = new TestPlanExample();
|
||||||
|
TestPlanExample.Criteria criteria = testPlanExample.createCriteria();
|
||||||
criteria.andProjectIdEqualTo(SessionUtils.getCurrentProjectId());
|
criteria.andProjectIdEqualTo(SessionUtils.getCurrentProjectId());
|
||||||
List<TestPlanProject> testPlanProjects = testPlanProjectMapper.selectByExample(testPlanProjectExample);
|
List<TestPlan> testPlans = testPlanMapper.selectByExample(testPlanExample);
|
||||||
if (!CollectionUtils.isEmpty(testPlanProjects)) {
|
if (!CollectionUtils.isEmpty(testPlans)) {
|
||||||
List<String> testPlanIds = testPlanProjects.stream().map(TestPlanProject::getTestPlanId).collect(Collectors.toList());
|
List<String> testPlanIds = testPlans.stream().map(TestPlan::getId).collect(Collectors.toList());
|
||||||
TestPlanExample testPlanTestCaseExample = new TestPlanExample();
|
TestPlanExample testPlanTestCaseExample = new TestPlanExample();
|
||||||
testPlanTestCaseExample.createCriteria().andWorkspaceIdEqualTo(currentWorkspaceId)
|
testPlanTestCaseExample.createCriteria().andWorkspaceIdEqualTo(currentWorkspaceId)
|
||||||
.andIdIn(testPlanIds)
|
.andIdIn(testPlanIds)
|
||||||
|
@ -434,18 +452,18 @@ public class TestPlanService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TestPlan> listTestAllPlan(String currentWorkspaceId) {
|
public List<TestPlan> listTestAllPlan(String currentWorkspaceId) {
|
||||||
TestPlanProjectExample testPlanProjectExample = new TestPlanProjectExample();
|
|
||||||
TestPlanProjectExample.Criteria criteria = testPlanProjectExample.createCriteria();
|
|
||||||
if (StringUtils.isNotBlank(SessionUtils.getCurrentProjectId())) {
|
if (StringUtils.isNotBlank(SessionUtils.getCurrentProjectId())) {
|
||||||
criteria.andProjectIdEqualTo(SessionUtils.getCurrentProjectId());
|
|
||||||
List<TestPlanProject> testPlanProjects = testPlanProjectMapper.selectByExample(testPlanProjectExample);
|
|
||||||
if (!CollectionUtils.isEmpty(testPlanProjects)) {
|
|
||||||
List<String> testPlanIds = testPlanProjects.stream().map(TestPlanProject::getTestPlanId).collect(Collectors.toList());
|
|
||||||
TestPlanExample testPlanExample = new TestPlanExample();
|
TestPlanExample testPlanExample = new TestPlanExample();
|
||||||
TestPlanExample.Criteria testPlanCriteria = testPlanExample.createCriteria();
|
TestPlanExample.Criteria criteria = testPlanExample.createCriteria();
|
||||||
|
criteria.andProjectIdEqualTo(SessionUtils.getCurrentProjectId());
|
||||||
|
List<TestPlan> testPlans = testPlanMapper.selectByExample(testPlanExample);
|
||||||
|
if (!CollectionUtils.isEmpty(testPlans)) {
|
||||||
|
List<String> testPlanIds = testPlans.stream().map(TestPlan::getId).collect(Collectors.toList());
|
||||||
|
TestPlanExample testPlanExample1 = new TestPlanExample();
|
||||||
|
TestPlanExample.Criteria testPlanCriteria = testPlanExample1.createCriteria();
|
||||||
testPlanCriteria.andWorkspaceIdEqualTo(currentWorkspaceId);
|
testPlanCriteria.andWorkspaceIdEqualTo(currentWorkspaceId);
|
||||||
testPlanCriteria.andIdIn(testPlanIds);
|
testPlanCriteria.andIdIn(testPlanIds);
|
||||||
return testPlanMapper.selectByExample(testPlanExample);
|
return testPlanMapper.selectByExample(testPlanExample1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 068127ce59ea8b016434ed52a9de4a7a4b13bdb4
|
Subproject commit f27d1609d77f7d6c988d37d709466e844d350e17
|
|
@ -0,0 +1,56 @@
|
||||||
|
alter table test_plan add project_id varchar(50) null comment '测试计划所属项目';
|
||||||
|
ALTER TABLE api_test_case MODIFY COLUMN name varchar(255) NOT NULL COMMENT 'Test name';
|
||||||
|
|
||||||
|
DROP PROCEDURE IF EXISTS test_cursor;
|
||||||
|
DELIMITER //
|
||||||
|
CREATE PROCEDURE test_cursor()
|
||||||
|
BEGIN
|
||||||
|
DECLARE planId VARCHAR(64);
|
||||||
|
DECLARE done INT DEFAULT 0;
|
||||||
|
DECLARE cursor1 CURSOR FOR (SELECT id
|
||||||
|
FROM test_plan
|
||||||
|
WHERE project_id IS NULL);
|
||||||
|
|
||||||
|
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
|
||||||
|
OPEN cursor1;
|
||||||
|
outer_loop:
|
||||||
|
LOOP
|
||||||
|
FETCH cursor1 INTO planId;
|
||||||
|
IF done
|
||||||
|
THEN
|
||||||
|
LEAVE outer_loop;
|
||||||
|
END IF;
|
||||||
|
select count(1) as s, project_id
|
||||||
|
into @num, @projectId
|
||||||
|
from test_plan_test_case
|
||||||
|
join test_case on case_id = test_case.id
|
||||||
|
where plan_id = planId
|
||||||
|
group by project_id
|
||||||
|
order by s desc
|
||||||
|
limit 1;
|
||||||
|
|
||||||
|
IF @projectId = ''
|
||||||
|
THEN
|
||||||
|
select test_plan_project.project_id
|
||||||
|
into @projectId
|
||||||
|
from test_plan
|
||||||
|
join test_plan_project on test_plan.id = test_plan_project.test_plan_id
|
||||||
|
where test_plan.id = planId
|
||||||
|
limit 1;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
UPDATE test_plan SET test_plan.project_id = @projectId WHERE test_plan.id = planId;
|
||||||
|
DELETE FROM test_plan_project
|
||||||
|
WHERE test_plan_project.project_id = @projectId
|
||||||
|
AND test_plan_project.test_plan_id = planId;
|
||||||
|
|
||||||
|
SET @projectId = '';
|
||||||
|
SET done = 0;
|
||||||
|
|
||||||
|
END LOOP;
|
||||||
|
CLOSE cursor1;
|
||||||
|
END //
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
CALL test_cursor();
|
||||||
|
DROP PROCEDURE IF EXISTS test_cursor;
|
|
@ -230,9 +230,7 @@
|
||||||
let path = "/test/plan/project";
|
let path = "/test/plan/project";
|
||||||
this.$post(path, {planId: this.tableData[i].id}, res => {
|
this.$post(path, {planId: this.tableData[i].id}, res => {
|
||||||
let arr = res.data;
|
let arr = res.data;
|
||||||
let projectName = arr.map(data => data.name).join("、");
|
|
||||||
let projectIds = arr.map(data => data.id);
|
let projectIds = arr.map(data => data.id);
|
||||||
this.$set(this.tableData[i], "projectName", projectName);
|
|
||||||
this.$set(this.tableData[i], "projectIds", projectIds);
|
this.$set(this.tableData[i], "projectIds", projectIds);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
|
|
||||||
<!-- 添加/编辑测试窗口-->
|
<!-- 添加/编辑测试窗口-->
|
||||||
<div v-else-if="item.type=== 'ADD'" class="ms-api-div">
|
<div v-else-if="item.type=== 'ADD'" class="ms-api-div">
|
||||||
<ms-api-config @runTest="runTest" @saveApi="saveApi" ref="apiConfig"
|
<ms-api-config @runTest="runTest" @saveApi="saveApi" @createRootModel="createRootModel" ref="apiConfig"
|
||||||
:current-api="item.api"
|
:current-api="item.api"
|
||||||
:currentProtocol="currentProtocol"
|
:currentProtocol="currentProtocol"
|
||||||
:moduleOptions="moduleOptions"/>
|
:moduleOptions="moduleOptions"/>
|
||||||
|
@ -215,6 +215,10 @@
|
||||||
this.apiTabs = tabs.filter(tab => tab.name !== targetName);
|
this.apiTabs = tabs.filter(tab => tab.name !== targetName);
|
||||||
this.refresh();
|
this.refresh();
|
||||||
},
|
},
|
||||||
|
//创建左侧树的根目录模块
|
||||||
|
createRootModel(){
|
||||||
|
this.$refs.nodeTree.createRootModel();
|
||||||
|
},
|
||||||
handleTabsEdit(targetName, action, api) {
|
handleTabsEdit(targetName, action, api) {
|
||||||
if (!getCurrentProjectID()) {
|
if (!getCurrentProjectID()) {
|
||||||
this.$warning(this.$t('commons.check_project_tip'));
|
this.$warning(this.$t('commons.check_project_tip'));
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
|
|
||||||
<div class="card-container">
|
<div class="card-container">
|
||||||
<!-- HTTP 请求参数 -->
|
<!-- HTTP 请求参数 -->
|
||||||
<ms-edit-complete-http-api @runTest="runTest" @saveApi="saveApi" :request="request" :response="response"
|
<ms-edit-complete-http-api @runTest="runTest" @saveApi="saveApi" @createRootModelInTree="createRootModelInTree" :request="request" :response="response"
|
||||||
:basisData="currentApi" :moduleOptions="moduleOptions" v-if="currentProtocol === 'HTTP'"/>
|
:basisData="currentApi" :moduleOptions="moduleOptions" v-if="currentProtocol === 'HTTP'"/>
|
||||||
<!-- TCP -->
|
<!-- TCP -->
|
||||||
<ms-edit-complete-tcp-api :request="request" @runTest="runTest" @saveApi="saveApi" :basisData="currentApi"
|
<ms-edit-complete-tcp-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi"
|
||||||
:moduleOptions="moduleOptions" v-if="currentProtocol === 'TCP'"/>
|
:moduleOptions="moduleOptions" v-if="currentProtocol === 'TCP'"/>
|
||||||
<!--DUBBO-->
|
<!--DUBBO-->
|
||||||
<ms-edit-complete-dubbo-api :request="request" @runTest="runTest" @saveApi="saveApi" :basisData="currentApi"
|
<ms-edit-complete-dubbo-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi"
|
||||||
:moduleOptions="moduleOptions" v-if="currentProtocol === 'DUBBO'"/>
|
:moduleOptions="moduleOptions" v-if="currentProtocol === 'DUBBO'"/>
|
||||||
<!--SQL-->
|
<!--SQL-->
|
||||||
<ms-edit-complete-sql-api :request="request" @runTest="runTest" @saveApi="saveApi" :basisData="currentApi"
|
<ms-edit-complete-sql-api :request="request" @runTest="runTest" @createRootModelInTree="createRootModelInTree" @saveApi="saveApi" :basisData="currentApi"
|
||||||
:moduleOptions="moduleOptions" v-if="currentProtocol === 'SQL'"/>
|
:moduleOptions="moduleOptions" v-if="currentProtocol === 'SQL'"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -75,6 +75,9 @@
|
||||||
this.$emit('runTest', data);
|
this.$emit('runTest', data);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
createRootModelInTree(){
|
||||||
|
this.$emit("createRootModel");
|
||||||
|
},
|
||||||
getMaintainerOptions() {
|
getMaintainerOptions() {
|
||||||
let workspaceId = localStorage.getItem(WORKSPACE_ID);
|
let workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||||
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
|
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
|
||||||
|
|
|
@ -11,7 +11,17 @@
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item :label="$t('test_track.module.module')" prop="moduleId">
|
<el-form-item :label="$t('test_track.module.module')" prop="moduleId">
|
||||||
<el-select class="ms-http-input" size="small" v-model="basicForm.moduleId" style="width: 100%" @change="reload">
|
<el-select class="ms-http-input" size="small" v-model="basicForm.moduleId" style="width: 100%" @change="reload">
|
||||||
|
<div v-if="moduleOptions.length>0">
|
||||||
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
|
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<el-option :key="0" :value="''">
|
||||||
|
<div style="margin-left: 40px">
|
||||||
|
<span style="font-size: 14px;color: #606266;font-weight: 48.93">{{$t('api_test.definition.select_comp.no_data')}},
|
||||||
|
</span><el-link type="primary" @click="createModules">{{$t('api_test.definition.select_comp.add_data')}}</el-link>
|
||||||
|
</div>
|
||||||
|
</el-option>
|
||||||
|
</div>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
@ -115,7 +125,10 @@
|
||||||
this.$emit('callback');
|
this.$emit('callback');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
|
createModules(){
|
||||||
|
this.$emit("createRootModelInTree");
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<br/>
|
<br/>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col>
|
<el-col>
|
||||||
<ms-basis-api :moduleOptions="moduleOptions" :basisData="basisData" ref="basicForm" @callback="callback"/>
|
<ms-basis-api @createRootModelInTree="createRootModelInTree" :moduleOptions="moduleOptions" :basisData="basisData" ref="basicForm" @callback="callback"/>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
@ -71,7 +71,10 @@
|
||||||
this.basisData.request = this.request;
|
this.basisData.request = this.request;
|
||||||
this.$emit('runTest', this.basisData);
|
this.$emit('runTest', this.basisData);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
createRootModelInTree(){
|
||||||
|
this.$emit("createRootModelInTree");
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {}
|
computed: {}
|
||||||
|
|
|
@ -36,7 +36,17 @@
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item :label="$t('test_track.module.module')" prop="moduleId">
|
<el-form-item :label="$t('test_track.module.module')" prop="moduleId">
|
||||||
<el-select class="ms-http-select" size="small" v-model="httpForm.moduleId">
|
<el-select class="ms-http-select" size="small" v-model="httpForm.moduleId">
|
||||||
|
<div v-if="moduleOptions.length>0">
|
||||||
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
|
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<el-option :key="0" :value="''">
|
||||||
|
<div style="margin-left: 40px">
|
||||||
|
<span style="font-size: 14px;color: #606266;font-weight: 48.93">{{$t('api_test.definition.select_comp.no_data')}},
|
||||||
|
</span><el-link type="primary" @click="createModules">{{$t('api_test.definition.select_comp.add_data')}}</el-link>
|
||||||
|
</div>
|
||||||
|
</el-option>
|
||||||
|
</div>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
@ -96,6 +106,7 @@
|
||||||
import {REQ_METHOD, API_STATUS} from "../../model/JsonData";
|
import {REQ_METHOD, API_STATUS} from "../../model/JsonData";
|
||||||
import MsJsr233Processor from "../processor/Jsr233Processor";
|
import MsJsr233Processor from "../processor/Jsr233Processor";
|
||||||
import {KeyValue} from "../../model/ApiTestModel";
|
import {KeyValue} from "../../model/ApiTestModel";
|
||||||
|
// import {append} from "./../../../../track/common/NodeTree";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsAddCompleteHttpApi",
|
name: "MsAddCompleteHttpApi",
|
||||||
|
@ -161,6 +172,9 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
createModules(){
|
||||||
|
this.$emit("createRootModelInTree");
|
||||||
|
},
|
||||||
getPath(id) {
|
getPath(id) {
|
||||||
if (id === null) {
|
if (id === null) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<br/>
|
<br/>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col>
|
<el-col>
|
||||||
<ms-basis-api :moduleOptions="moduleOptions" :basisData="basisData" ref="basicForm" @callback="callback"/>
|
<ms-basis-api @createRootModelInTree="createRootModelInTree" :moduleOptions="moduleOptions" :basisData="basisData" ref="basicForm" @callback="callback"/>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
@ -70,6 +70,9 @@
|
||||||
this.$emit('runTest', this.basisData);
|
this.$emit('runTest', this.basisData);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
createRootModelInTree(){
|
||||||
|
this.$emit("createRootModelInTree");
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<br/>
|
<br/>
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col>
|
<el-col>
|
||||||
<ms-basis-api :moduleOptions="moduleOptions" :basisData="basisData" ref="basicForm" @callback="callback"/>
|
<ms-basis-api @createRootModelInTree="createRootModelInTree" :moduleOptions="moduleOptions" :basisData="basisData" ref="basicForm" @callback="callback"/>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
@ -70,7 +70,10 @@
|
||||||
this.basisData.request = this.request;
|
this.basisData.request = this.request;
|
||||||
this.$emit('runTest', this.basisData);
|
this.$emit('runTest', this.basisData);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
createRootModelInTree(){
|
||||||
|
this.$emit("createRootModelInTree");
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
<el-input placeholder="搜索" @blur="search" @keyup.enter.native="search" class="search-input" size="small" v-model="condition.name"/>
|
<el-input placeholder="搜索" @blur="search" @keyup.enter.native="search" class="search-input" size="small" v-model="condition.name"/>
|
||||||
|
|
||||||
<el-table v-loading="result.loading"
|
<el-table v-loading="result.loading"
|
||||||
|
ref="caseTable"
|
||||||
border
|
border
|
||||||
:data="tableData" row-key="id" class="test-content adjust-table"
|
:data="tableData" row-key="id" class="test-content adjust-table"
|
||||||
@select-all="handleSelectAll"
|
@select-all="handleSelectAll"
|
||||||
|
@ -15,8 +16,21 @@
|
||||||
@select="handleSelect" :height="screenHeight">
|
@select="handleSelect" :height="screenHeight">
|
||||||
<el-table-column type="selection"/>
|
<el-table-column type="selection"/>
|
||||||
<el-table-column width="40" :resizable="false" align="center">
|
<el-table-column width="40" :resizable="false" align="center">
|
||||||
|
<el-dropdown slot="header" style="width: 14px">
|
||||||
|
<span class="el-dropdown-link" style="width: 14px">
|
||||||
|
<i class="el-icon-arrow-down el-icon--right" style="margin-left: 0px"></i>
|
||||||
|
</span>
|
||||||
|
<el-dropdown-menu slot="dropdown">
|
||||||
|
<el-dropdown-item @click.native.stop="isSelectDataAll(true)">
|
||||||
|
{{$t('api_test.batch_menus.select_all_data',[total])}}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item @click.native.stop="isSelectDataAll(false)">
|
||||||
|
{{$t('api_test.batch_menus.select_show_data',[tableData.length])}}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</el-dropdown>
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<show-more-btn :is-show="scope.row.showMore && !isReadOnly" :buttons="buttons" :size="selectRows.size"/>
|
<show-more-btn :is-show="scope.row.showMore && !isReadOnly" :buttons="buttons" :size="selectDataCounts"/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
@ -143,7 +157,10 @@
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
total: 0,
|
total: 0,
|
||||||
screenHeight: document.documentElement.clientHeight - 330,//屏幕高度
|
screenHeight: document.documentElement.clientHeight - 330,//屏幕高度
|
||||||
environmentId: undefined
|
environmentId: undefined,
|
||||||
|
selectAll: false,
|
||||||
|
unSelection:[],
|
||||||
|
selectDataCounts:0,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -216,7 +233,9 @@
|
||||||
this.condition.status = "Trash";
|
this.condition.status = "Trash";
|
||||||
this.condition.moduleIds = [];
|
this.condition.moduleIds = [];
|
||||||
}
|
}
|
||||||
|
this.selectAll = false;
|
||||||
|
this.unSelection = [];
|
||||||
|
this.selectDataCounts = 0;
|
||||||
this.condition.projectId = getCurrentProjectID();
|
this.condition.projectId = getCurrentProjectID();
|
||||||
|
|
||||||
if (this.currentProtocol != null) {
|
if (this.currentProtocol != null) {
|
||||||
|
@ -226,6 +245,7 @@
|
||||||
this.result = this.$post('/api/testcase/list/' + this.currentPage + "/" + this.pageSize, this.condition, response => {
|
this.result = this.$post('/api/testcase/list/' + this.currentPage + "/" + this.pageSize, this.condition, response => {
|
||||||
this.total = response.data.itemCount;
|
this.total = response.data.itemCount;
|
||||||
this.tableData = response.data.listObject;
|
this.tableData = response.data.listObject;
|
||||||
|
this.unSelection = response.data.listObject.map(s=>s.id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -237,6 +257,7 @@
|
||||||
// },
|
// },
|
||||||
handleSelect(selection, row) {
|
handleSelect(selection, row) {
|
||||||
_handleSelect(this, selection, row, this.selectRows);
|
_handleSelect(this, selection, row, this.selectRows);
|
||||||
|
this.selectRowsCount(this.selectRows)
|
||||||
},
|
},
|
||||||
showExecResult(row) {
|
showExecResult(row) {
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
|
@ -256,6 +277,7 @@
|
||||||
},
|
},
|
||||||
handleSelectAll(selection) {
|
handleSelectAll(selection) {
|
||||||
_handleSelectAll(this, selection, this.tableData, this.selectRows);
|
_handleSelectAll(this, selection, this.tableData, this.selectRows);
|
||||||
|
this.selectRowsCount(this.selectRows)
|
||||||
},
|
},
|
||||||
search() {
|
search() {
|
||||||
this.initTable();
|
this.initTable();
|
||||||
|
@ -294,7 +316,13 @@
|
||||||
confirmButtonText: this.$t('commons.confirm'),
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
callback: (action) => {
|
callback: (action) => {
|
||||||
if (action === 'confirm') {
|
if (action === 'confirm') {
|
||||||
this.$post('/api/testcase/deleteBatch/', Array.from(this.selectRows).map(row => row.id), () => {
|
let obj = {};
|
||||||
|
obj.projectId = getCurrentProjectID();
|
||||||
|
obj.selectAllDate = this.isSelectAllDate;
|
||||||
|
obj.unSelectIds = this.unSelection;
|
||||||
|
obj.ids = Array.from(this.selectRows).map(row => row.id);
|
||||||
|
obj = Object.assign(obj, this.condition);
|
||||||
|
this.$post('/api/testcase/deleteBatchByParam/', obj , () => {
|
||||||
this.selectRows.clear();
|
this.selectRows.clear();
|
||||||
this.initTable();
|
this.initTable();
|
||||||
this.$success(this.$t('commons.delete_success'));
|
this.$success(this.$t('commons.delete_success'));
|
||||||
|
@ -327,7 +355,12 @@
|
||||||
let param = {};
|
let param = {};
|
||||||
param[form.type] = form.value;
|
param[form.type] = form.value;
|
||||||
param.ids = ids;
|
param.ids = ids;
|
||||||
this.$post('/api/testcase/batch/edit', param, () => {
|
|
||||||
|
param.projectId = getCurrentProjectID();
|
||||||
|
param.selectAllDate = this.isSelectAllDate;
|
||||||
|
param.unSelectIds = this.unSelection;
|
||||||
|
param = Object.assign(param, this.condition);
|
||||||
|
this.$post('/api/testcase/batch/editByParam', param, () => {
|
||||||
this.$success(this.$t('commons.save_success'));
|
this.$success(this.$t('commons.save_success'));
|
||||||
this.initTable();
|
this.initTable();
|
||||||
});
|
});
|
||||||
|
@ -355,6 +388,31 @@
|
||||||
},
|
},
|
||||||
setEnvironment(data) {
|
setEnvironment(data) {
|
||||||
this.environmentId = data.id;
|
this.environmentId = data.id;
|
||||||
|
},
|
||||||
|
selectRowsCount(selection){
|
||||||
|
let selectedIDs = this.getIds(selection);
|
||||||
|
let allIDs = this.tableData.map(s=>s.id);
|
||||||
|
this.unSelection = allIDs.filter(function (val) {
|
||||||
|
return selectedIDs.indexOf(val) === -1
|
||||||
|
});
|
||||||
|
if(this.isSelectAllDate){
|
||||||
|
this.selectDataCounts =this.total - this.unSelection.length;
|
||||||
|
}else {
|
||||||
|
this.selectDataCounts =selection.size;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isSelectDataAll(dataType) {
|
||||||
|
this.isSelectAllDate = dataType;
|
||||||
|
this.selectRowsCount(this.selectRows)
|
||||||
|
//如果已经全选,不需要再操作了
|
||||||
|
if (this.selectRows.size != this.tableData.length) {
|
||||||
|
this.$refs.caseTable.toggleAllSelection(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getIds(rowSets){
|
||||||
|
let rowArray = Array.from(rowSets)
|
||||||
|
let ids = rowArray.map(s=>s.id);
|
||||||
|
return ids;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,6 +176,13 @@
|
||||||
this.$emit("nodeSelectEvent", node, nodeIds, pNodes);
|
this.$emit("nodeSelectEvent", node, nodeIds, pNodes);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
//创建根目录的模块---供父类使用
|
||||||
|
createRootModel(){
|
||||||
|
let dataArr = this.$refs.nodeTree.extendTreeNodes;
|
||||||
|
if(dataArr.length>0){
|
||||||
|
this.$refs.nodeTree.append({},dataArr[0]);
|
||||||
|
}
|
||||||
|
},
|
||||||
exportAPI() {
|
exportAPI() {
|
||||||
this.$emit('exportAPI');
|
this.$emit('exportAPI');
|
||||||
},
|
},
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
error() {
|
error() {
|
||||||
return this.response.responseCode >= 400;
|
return this.response && this.response.responseCode && this.response.responseCode >= 400;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="ms-div">
|
<div class="ms-div">
|
||||||
Body :
|
Body :
|
||||||
<pre>{{response.body}}</pre>
|
<pre>{{response.body ? response.body:""}}</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
|
@ -307,7 +307,7 @@ export default {
|
||||||
rules: {
|
rules: {
|
||||||
name: [
|
name: [
|
||||||
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
|
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
|
||||||
{max: 50, message: this.$t('test_track.length_less_than') + '50', trigger: 'blur'}
|
{max: 255, message: this.$t('test_track.length_less_than') + '255', trigger: 'blur'}
|
||||||
],
|
],
|
||||||
module: [{required: true, message: this.$t('test_track.case.input_module'), trigger: 'change'}],
|
module: [{required: true, message: this.$t('test_track.case.input_module'), trigger: 'change'}],
|
||||||
maintainer: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
maintainer: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||||
|
|
|
@ -58,11 +58,11 @@
|
||||||
<plan-stage-table-item :stage="scope.row.stage"/>
|
<plan-stage-table-item :stage="scope.row.stage"/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<!-- <el-table-column-->
|
||||||
prop="projectName"
|
<!-- prop="projectName"-->
|
||||||
:label="$t('test_track.plan.plan_project')"
|
<!-- :label="$t('test_track.plan.plan_project')"-->
|
||||||
show-overflow-tooltip>
|
<!-- show-overflow-tooltip>-->
|
||||||
</el-table-column>
|
<!-- </el-table-column>-->
|
||||||
|
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
|
@ -94,12 +94,12 @@
|
||||||
}
|
}
|
||||||
this.result = this.$post('/test/plan/list/all/relate', {}, response => {
|
this.result = this.$post('/test/plan/list/all/relate', {}, response => {
|
||||||
this.tableData = response.data;
|
this.tableData = response.data;
|
||||||
for (let i = 0; i < this.tableData.length; i++) {
|
// for (let i = 0; i < this.tableData.length; i++) {
|
||||||
let path = "/test/plan/project/name/" + this.tableData[i].id;
|
// let path = "/test/plan/project/name/" + this.tableData[i].id;
|
||||||
this.$get(path, res => {
|
// this.$get(path, res => {
|
||||||
this.$set(this.tableData[i], "projectName", res.data);
|
// this.$set(this.tableData[i], "projectName", res.data);
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
intoPlan(row, event, column) {
|
intoPlan(row, event, column) {
|
||||||
|
|
|
@ -21,10 +21,10 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="11" :offset="2">
|
<el-col :span="11" :offset="2">
|
||||||
<el-form-item :label="$t('test_track.plan.plan_project')" :label-width="formLabelWidth" prop="projectIds">
|
<el-form-item :label="$t('test_track.plan.related_project')" :label-width="formLabelWidth" prop="projectIds">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="form.projectIds"
|
v-model="form.projectIds"
|
||||||
:placeholder="$t('test_track.plan.input_plan_project')"
|
:placeholder="$t('test_track.plan.input_related_project')"
|
||||||
multiple
|
multiple
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
filterable>
|
filterable>
|
||||||
|
@ -134,7 +134,7 @@
|
||||||
|
|
||||||
import {WORKSPACE_ID} from '@/common/js/constants';
|
import {WORKSPACE_ID} from '@/common/js/constants';
|
||||||
import TestPlanStatusButton from "../common/TestPlanStatusButton";
|
import TestPlanStatusButton from "../common/TestPlanStatusButton";
|
||||||
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
import {getCurrentProjectID, listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||||
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
|
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -158,7 +158,7 @@ export default {
|
||||||
{required: true, message: this.$t('test_track.plan.input_plan_name'), trigger: 'blur'},
|
{required: true, message: this.$t('test_track.plan.input_plan_name'), trigger: 'blur'},
|
||||||
{max: 30, message: this.$t('test_track.length_less_than') + '30', trigger: 'blur'}
|
{max: 30, message: this.$t('test_track.length_less_than') + '30', trigger: 'blur'}
|
||||||
],
|
],
|
||||||
projectIds: [{required: true, message: this.$t('test_track.plan.input_plan_project'), trigger: 'change'}],
|
// projectIds: [{required: true, message: this.$t('test_track.plan.input_plan_project'), trigger: 'change'}],
|
||||||
principal: [{required: true, message: this.$t('test_track.plan.input_plan_principal'), trigger: 'change'}],
|
principal: [{required: true, message: this.$t('test_track.plan.input_plan_principal'), trigger: 'change'}],
|
||||||
stage: [{required: true, message: this.$t('test_track.plan.input_plan_stage'), trigger: 'change'}],
|
stage: [{required: true, message: this.$t('test_track.plan.input_plan_stage'), trigger: 'change'}],
|
||||||
description: [{max: 200, message: this.$t('test_track.length_less_than') + '200', trigger: 'blur'}]
|
description: [{max: 200, message: this.$t('test_track.length_less_than') + '200', trigger: 'blur'}]
|
||||||
|
@ -248,7 +248,7 @@ export default {
|
||||||
getProjects() {
|
getProjects() {
|
||||||
this.$get("/project/listAll", (response) => {
|
this.$get("/project/listAll", (response) => {
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
this.projects = response.data;
|
this.projects = response.data.filter(da => da.id !== getCurrentProjectID());
|
||||||
} else {
|
} else {
|
||||||
this.$warning()(response.message);
|
this.$warning()(response.message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,9 +228,7 @@ export default {
|
||||||
let path = "/test/plan/project";
|
let path = "/test/plan/project";
|
||||||
this.$post(path,{planId: this.tableData[i].id}, res => {
|
this.$post(path,{planId: this.tableData[i].id}, res => {
|
||||||
let arr = res.data;
|
let arr = res.data;
|
||||||
let projectName = arr.map(data => data.name).join("、");
|
let projectIds = arr.filter(d => d.id !== this.tableData[i].projectId).map(data => data.id);
|
||||||
let projectIds = arr.map(data => data.id);
|
|
||||||
this.$set(this.tableData[i], "projectName", projectName);
|
|
||||||
this.$set(this.tableData[i], "projectIds", projectIds);
|
this.$set(this.tableData[i], "projectIds", projectIds);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -505,6 +505,10 @@ export default {
|
||||||
api_case_status: "Ise case status",
|
api_case_status: "Ise case status",
|
||||||
api_case_passing_rate: "Use case pass rate",
|
api_case_passing_rate: "Use case pass rate",
|
||||||
create_tip: "Note: Detailed interface information can be filled out on the edit page",
|
create_tip: "Note: Detailed interface information can be filled out on the edit page",
|
||||||
|
select_comp:{
|
||||||
|
no_data:"No Data",
|
||||||
|
add_data:"Add Data"
|
||||||
|
},
|
||||||
request: {
|
request: {
|
||||||
grade_info: "Filter by rank",
|
grade_info: "Filter by rank",
|
||||||
run_env: "Operating environment",
|
run_env: "Operating environment",
|
||||||
|
@ -795,7 +799,7 @@ export default {
|
||||||
export_tip: "Export Tip",
|
export_tip: "Export Tip",
|
||||||
ms_tip: "Support for MeterSphere JSON format",
|
ms_tip: "Support for MeterSphere JSON format",
|
||||||
ms_export_tip: "Export jSON-formatted files via MeterSphere website or browser plug-ins",
|
ms_export_tip: "Export jSON-formatted files via MeterSphere website or browser plug-ins",
|
||||||
swagger_tip: "Only Swagger2.x json files are supported",
|
swagger_tip: "Swagger 2.0 and 3.0 json files are supported",
|
||||||
postman_tip: "Only Postman Collection V2.1 json files are supported",
|
postman_tip: "Only Postman Collection V2.1 json files are supported",
|
||||||
postman_export_tip: "Export the test collection by Postman",
|
postman_export_tip: "Export the test collection by Postman",
|
||||||
swagger_export_tip: "Export jSON-formatted files via Swagger website",
|
swagger_export_tip: "Export jSON-formatted files via Swagger website",
|
||||||
|
@ -1053,6 +1057,7 @@ export default {
|
||||||
edit_plan: "Edit test plan",
|
edit_plan: "Edit test plan",
|
||||||
plan_name: "Test plan name",
|
plan_name: "Test plan name",
|
||||||
plan_project: "Project",
|
plan_project: "Project",
|
||||||
|
related_project: "Related Project",
|
||||||
plan_stage: "Stage",
|
plan_stage: "Stage",
|
||||||
plan_status: "Status",
|
plan_status: "Status",
|
||||||
smoke_test: "Smoke test",
|
smoke_test: "Smoke test",
|
||||||
|
@ -1065,6 +1070,7 @@ export default {
|
||||||
input_plan_name: "Please input plan name",
|
input_plan_name: "Please input plan name",
|
||||||
input_plan_principal: "Please select principal",
|
input_plan_principal: "Please select principal",
|
||||||
input_plan_project: "Please select project",
|
input_plan_project: "Please select project",
|
||||||
|
input_related_project: "Please Related project",
|
||||||
input_plan_stage: "Please select stage",
|
input_plan_stage: "Please select stage",
|
||||||
plan_status_prepare: "Not started",
|
plan_status_prepare: "Not started",
|
||||||
plan_status_running: "Starting",
|
plan_status_running: "Starting",
|
||||||
|
|
|
@ -503,6 +503,10 @@ export default {
|
||||||
api_case_status: "用例状态",
|
api_case_status: "用例状态",
|
||||||
api_case_passing_rate: "用例通过率",
|
api_case_passing_rate: "用例通过率",
|
||||||
create_tip: "注: 详细的接口信息可以在编辑页面填写",
|
create_tip: "注: 详细的接口信息可以在编辑页面填写",
|
||||||
|
select_comp:{
|
||||||
|
no_data:"无数据",
|
||||||
|
add_data:"去添加"
|
||||||
|
},
|
||||||
request: {
|
request: {
|
||||||
grade_info: "按等级筛选",
|
grade_info: "按等级筛选",
|
||||||
run_env: "运行环境",
|
run_env: "运行环境",
|
||||||
|
@ -797,7 +801,7 @@ export default {
|
||||||
ms_tip: "支持 Metersphere json 格式",
|
ms_tip: "支持 Metersphere json 格式",
|
||||||
ms_export_tip: "通过 Metersphere 接口测试页面或者浏览器插件导出 json 格式文件",
|
ms_export_tip: "通过 Metersphere 接口测试页面或者浏览器插件导出 json 格式文件",
|
||||||
postman_tip: "只支持 Postman Collection v2.1 格式的 json 文件",
|
postman_tip: "只支持 Postman Collection v2.1 格式的 json 文件",
|
||||||
swagger_tip: "只支持 Swagger 2.x 版本的 json 文件",
|
swagger_tip: "支持 Swagger 2.0 与 3.0 版本的 json 文件",
|
||||||
post_export_tip: "通过 Postman 导出测试集合",
|
post_export_tip: "通过 Postman 导出测试集合",
|
||||||
swagger_export_tip: "通过 Swagger 页面导出",
|
swagger_export_tip: "通过 Swagger 页面导出",
|
||||||
suffixFormatErr: "文件格式不符合要求",
|
suffixFormatErr: "文件格式不符合要求",
|
||||||
|
@ -1054,6 +1058,7 @@ export default {
|
||||||
edit_plan: "编辑测试计划",
|
edit_plan: "编辑测试计划",
|
||||||
plan_name: "计划名称",
|
plan_name: "计划名称",
|
||||||
plan_project: "所属项目",
|
plan_project: "所属项目",
|
||||||
|
related_project: "关联项目",
|
||||||
plan_stage: "测试阶段",
|
plan_stage: "测试阶段",
|
||||||
plan_status: "当前状态",
|
plan_status: "当前状态",
|
||||||
smoke_test: "冒烟测试",
|
smoke_test: "冒烟测试",
|
||||||
|
@ -1066,6 +1071,7 @@ export default {
|
||||||
input_plan_name: "请输入测试计划名称",
|
input_plan_name: "请输入测试计划名称",
|
||||||
input_plan_principal: "请选择负责人",
|
input_plan_principal: "请选择负责人",
|
||||||
input_plan_project: "请选择所属项目",
|
input_plan_project: "请选择所属项目",
|
||||||
|
input_related_project: "请选择关联项目",
|
||||||
input_plan_stage: "请选择测试阶段",
|
input_plan_stage: "请选择测试阶段",
|
||||||
plan_status_prepare: "未开始",
|
plan_status_prepare: "未开始",
|
||||||
plan_status_running: "进行中",
|
plan_status_running: "进行中",
|
||||||
|
|
|
@ -503,6 +503,10 @@ export default {
|
||||||
api_case_status: "用例狀態",
|
api_case_status: "用例狀態",
|
||||||
api_case_passing_rate: "用例通過率",
|
api_case_passing_rate: "用例通過率",
|
||||||
create_tip: "註: 詳細的接口信息可以在編輯頁面填寫",
|
create_tip: "註: 詳細的接口信息可以在編輯頁面填寫",
|
||||||
|
select_comp:{
|
||||||
|
no_data:"無數據",
|
||||||
|
add_data:"去添加"
|
||||||
|
},
|
||||||
request: {
|
request: {
|
||||||
grade_info: "按等級筛选",
|
grade_info: "按等級筛选",
|
||||||
run_env: "運行環境",
|
run_env: "運行環境",
|
||||||
|
@ -796,7 +800,7 @@ export default {
|
||||||
ms_tip: "支持 Metersphere json 格式",
|
ms_tip: "支持 Metersphere json 格式",
|
||||||
ms_export_tip: "通過 Metersphere 接口測試頁面或者瀏覽器插件導出 json 格式文件",
|
ms_export_tip: "通過 Metersphere 接口測試頁面或者瀏覽器插件導出 json 格式文件",
|
||||||
postman_tip: "只支持 Postman Collection v2.1 格式的 json 文件",
|
postman_tip: "只支持 Postman Collection v2.1 格式的 json 文件",
|
||||||
swagger_tip: "只支持 Swagger 2.x 版本的 json 文件",
|
swagger_tip: "支持 Swagger 2.0 與 3.0版本的 json 文件",
|
||||||
post_export_tip: "通過 Postman 導出測試集合",
|
post_export_tip: "通過 Postman 導出測試集合",
|
||||||
swagger_export_tip: "通過 Swagger 頁面導出",
|
swagger_export_tip: "通過 Swagger 頁面導出",
|
||||||
suffixFormatErr: "文件格式不符合要求",
|
suffixFormatErr: "文件格式不符合要求",
|
||||||
|
@ -1053,6 +1057,7 @@ export default {
|
||||||
edit_plan: "編輯測試計劃",
|
edit_plan: "編輯測試計劃",
|
||||||
plan_name: "計劃名稱",
|
plan_name: "計劃名稱",
|
||||||
plan_project: "所屬項目",
|
plan_project: "所屬項目",
|
||||||
|
related_project: "關聯項目",
|
||||||
plan_stage: "測試階段",
|
plan_stage: "測試階段",
|
||||||
plan_status: "當前狀態",
|
plan_status: "當前狀態",
|
||||||
smoke_test: "冒煙測試",
|
smoke_test: "冒煙測試",
|
||||||
|
@ -1065,6 +1070,7 @@ export default {
|
||||||
input_plan_name: "請輸入測試計劃名稱",
|
input_plan_name: "請輸入測試計劃名稱",
|
||||||
input_plan_principal: "請選擇負責人",
|
input_plan_principal: "請選擇負責人",
|
||||||
input_plan_project: "請選擇所屬項目",
|
input_plan_project: "請選擇所屬項目",
|
||||||
|
input_related_project: "請選擇關聯項目",
|
||||||
input_plan_stage: "請選擇測試階段",
|
input_plan_stage: "請選擇測試階段",
|
||||||
plan_status_prepare: "未開始",
|
plan_status_prepare: "未開始",
|
||||||
plan_status_running: "進行中",
|
plan_status_running: "進行中",
|
||||||
|
|
Loading…
Reference in New Issue