feat(接口测试): 场景导入导出跨空间查询

--user=郭雨琦 场景导入导出跨空间查询
This commit is contained in:
guoyuqi 2022-03-07 14:08:46 +08:00 committed by fit2-zhao
parent 9137e5153a
commit 0e89db6369
21 changed files with 107 additions and 136 deletions

View File

@ -146,58 +146,23 @@ public class ApiScenarioImportUtil {
ApiTestCaseService testCaseService = CommonBeanFactory.getBean(ApiTestCaseService.class);
ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class);
ApiTestCaseWithBLOBs bloBs = testCaseService.get(object.getString("id"));
if (bloBs != null) {
boolean isSameWorkSpace = checkWorkSpace(bloBs.getProjectId(),projectId);
if(!isSameWorkSpace){
ApiDefinitionResult apiDefinition = apiDefinitionService.getById(bloBs.getApiDefinitionId());
String apiDefinitionId = checkDefinition(apiDefinitionService,apiDefinition, versionId,projectId,apiDefinitionMapper);
structureCaseData(bloBs,apiDefinitionId,versionId,projectId,apiTestCaseMapper);
object.put("projectId", projectId);
object.put("id", bloBs.getId());
}
}else{
if (bloBs == null) {
ApiDefinitionResult apiDefinition = getApiDefinitionResult(object,apiDefinitionService);
ApiTestCaseWithBLOBs testCase;
if(apiDefinition!=null){
testCase= getApiTestCase(object, testCaseService, apiDefinition);
if (testCase != null) {
boolean isSameWorkSpace = checkWorkSpace(testCase.getProjectId(),projectId);
if(!isSameWorkSpace){
String apiDefinitionId = checkDefinition(apiDefinitionService, apiDefinition, versionId,projectId,apiDefinitionMapper);
structureCaseData(testCase,apiDefinitionId,versionId,projectId,apiTestCaseMapper);
}
object.put("id", testCase.getId());
}else{
String apiDefinitionId = checkDefinition(apiDefinitionService, apiDefinition, versionId,projectId,apiDefinitionMapper);
testCase= structureCaseByJson(object, versionId, projectId, apiDefinitionId,apiTestCaseMapper);
structureCaseByJson(object, apiDefinition,apiTestCaseMapper);
}
}else{
ApiDefinitionResult apiDefinitionResult = structureApiDefinitionByJson(apiDefinitionService, object, versionId, projectId, apiDefinitionMapper);
testCase = structureCaseByJson(object, versionId, projectId, apiDefinitionResult.getId(),apiTestCaseMapper);
structureCaseByJson(object, apiDefinitionResult,apiTestCaseMapper);
}
object.put("projectId", projectId);
object.put("id", testCase.getId());
}
}
private static String checkDefinition(ApiDefinitionService apiDefinitionService, ApiDefinitionResult apiDefinition, String versionId, String projectId,ApiDefinitionMapper apiDefinitionMapper) {
boolean isSameWorkspace = checkWorkSpace(apiDefinition.getProjectId(),projectId);
if(!isSameWorkspace){
String requestStr = apiDefinition.getRequest();
JSONObject objectDefinition = JSONObject.parseObject(requestStr);
ApiDefinitionResult apiDefinitionResult1 = insertDefinitionByApiDefinition(apiDefinitionService,apiDefinition, objectDefinition, versionId, projectId,apiDefinitionMapper);
return apiDefinitionResult1.getId();
}else{
return apiDefinition.getId();
}
}
private static void structureCaseData(ApiTestCaseWithBLOBs testCase, String apiDefinitionId, String versionId, String projectId,ApiTestCaseMapper apiTestCaseMapper) {
String requestStr = testCase.getRequest();
JSONObject objectCase = JSONObject.parseObject(requestStr);
testCase.setApiDefinitionId(apiDefinitionId);
insertCaseByApiTestCase(testCase,objectCase,versionId,projectId,apiTestCaseMapper);
}
public static ApiDefinitionResult structureApiDefinitionByJson(ApiDefinitionService apiDefinitionService,JSONObject object, String versionId, String projectId,ApiDefinitionMapper apiDefinitionMapper) {
ApiDefinitionResult test = new ApiDefinitionResult();
apiDefinitionService.checkQuota();
@ -232,38 +197,21 @@ public class ApiScenarioImportUtil {
return test;
}
public static ApiDefinitionResult insertDefinitionByApiDefinition(ApiDefinitionService apiDefinitionService, ApiDefinitionResult apiDefinitionResult, JSONObject objectDefinition, String versionId, String projectId,ApiDefinitionMapper apiDefinitionMapper){
String id = UUID.randomUUID().toString();
apiDefinitionResult.setId(id);
apiDefinitionResult.setProjectId(projectId);
apiDefinitionResult.setVersionId(versionId);
apiDefinitionResult.setRefId(id);
apiDefinitionResult.setLatest(true);
objectDefinition.put("id", id);
objectDefinition.put("resourceId", id);
objectDefinition.put("projectId", projectId);
objectDefinition.put("useEnvironment","");
apiDefinitionService.initModulePathAndId(projectId, apiDefinitionResult);
apiDefinitionResult.setRequest(JSON.toJSONString(objectDefinition));
apiDefinitionResult.setOrder(apiDefinitionService.getImportNextOrder(projectId));
apiDefinitionMapper.insert(apiDefinitionResult);
return apiDefinitionResult;
}
public static ApiTestCaseWithBLOBs structureCaseByJson(JSONObject object, String versionId, String projectId, String apiDefinitionId,ApiTestCaseMapper apiTestCaseMapper) {
public static void structureCaseByJson(JSONObject object, ApiDefinitionResult apiDefinition, ApiTestCaseMapper apiTestCaseMapper) {
String projectId = apiDefinition.getProjectId();
ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class);
ApiTestCaseWithBLOBs apiTestCase = new ApiTestCaseWithBLOBs();
String id = UUID.randomUUID().toString();
apiTestCase.setId(id);
apiTestCase.setName(object.getString("name"));
apiTestCase.setCaseStatus(APITestStatus.Underway.name());
apiTestCase.setApiDefinitionId(apiDefinitionId);
apiTestCase.setApiDefinitionId(apiDefinition.getId());
apiTestCase.setCreateUserId(Objects.requireNonNull(SessionUtils.getUser()).getId());
apiTestCase.setUpdateUserId(Objects.requireNonNull(SessionUtils.getUser()).getId());
apiTestCase.setProjectId(projectId);
apiTestCase.setCreateTime(System.currentTimeMillis());
apiTestCase.setUpdateTime(System.currentTimeMillis());
apiTestCase.setVersionId(versionId);
apiTestCase.setVersionId(apiDefinition.getVersionId());
object.put("id", apiTestCase.getId());
object.put("resourceId", apiTestCase.getId());
object.put("projectId", projectId);
@ -271,22 +219,6 @@ public class ApiScenarioImportUtil {
apiTestCase.setRequest(object.toJSONString());
apiTestCase.setOrder(apiDefinitionService.getImportNextCaseOrder(projectId));
apiTestCaseMapper.insert(apiTestCase);
return apiTestCase;
}
public static void insertCaseByApiTestCase(ApiTestCaseWithBLOBs bloBs, JSONObject objectCase, String versionId, String projectId,ApiTestCaseMapper apiTestCaseMapper){
ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class);
String id = UUID.randomUUID().toString();
bloBs.setId(id);
bloBs.setProjectId(projectId);
bloBs.setVersionId(versionId);
objectCase.put("id", id);
objectCase.put("resourceId", id);
objectCase.put("projectId", projectId);
objectCase.put("useEnvironment","");
bloBs.setRequest(JSON.toJSONString(objectCase));
bloBs.setOrder(apiDefinitionService.getImportNextCaseOrder(projectId));
apiTestCaseMapper.insert(bloBs);
}
public static void formatHashTree(JSONArray hashTree) {

View File

@ -2002,7 +2002,7 @@ public class ApiAutomationService {
if (refType.equals("CASE")) {
ApiScenarioImportUtil.checkCase(object,versionId,projectId,apiTestCaseMapper,apiDefinitionMapper);
} else {
checkAutomation(object,projectId);
checkAutomation(object);
}
}else{
object.put("referenced", "Copy");
@ -2019,13 +2019,10 @@ public class ApiAutomationService {
}
}
public void checkAutomation(JSONObject object, String projectId) {
public void checkAutomation(JSONObject object) {
ApiScenarioWithBLOBs bloBs = getDto(object.getString("id"));
if (bloBs != null) {
boolean isSameWorkSpace = ApiScenarioImportUtil.checkWorkSpace(bloBs.getProjectId(),projectId);
if(!isSameWorkSpace){
object.put("referenced", "Copy");
}
if (bloBs == null) {
object.put("referenced", "Copy");
}
}

View File

@ -37,4 +37,6 @@ public interface ExtProjectMapper {
int getProjectPlanBugSize(@Param("projectId") String projectId);
void setDefaultMessageTask(@Param("projectId") String projectId);
List<ProjectDTO> queryListByIds(@Param("ids") List<String> ids);
}

View File

@ -139,7 +139,7 @@
SELECT MAX(system_id)
FROM project
</select>
<select id="queryNameByIds" resultType="io.metersphere.base.domain.Project">
<select id="queryNameByIds" resultType="java.util.Map">
SELECT id, name
FROM project
WHERE id IN
@ -246,6 +246,34 @@
and (issues.status != 'closed' or issues.status is null)
and test_case.status != 'Trash';
</select>
<select id="queryListByIds" resultType="io.metersphere.dto.ProjectDTO">
SELECT p.id,
p.workspace_id,
p.name,
p.description,
p.update_time,
p.issue_template_id,
p.case_template_id,
p.create_time,
w.id AS workspaceId,
w.name AS workspaceName,
p.tapd_id,
p.jira_key,
p.zentao_id,
p.azure_devops_id,
p.azure_filter_id,
user.name AS createUserName,
p.platform, p.third_part_template,
p.issue_config
FROM project p
JOIN workspace w ON p.workspace_id = w.id
LEFT JOIN user ON user.id = p.create_user
WHERE p.id IN
<foreach collection="ids" item="id" index="index"
open="(" close=")" separator=",">
#{id}
</foreach>
</select>
<insert id="setDefaultMessageTask">

View File

@ -138,6 +138,11 @@ public class ProjectController {
return checkPermissionService.getUserRelatedProjectIds();
}
@GetMapping("/getOwnerProjects")
public List<ProjectDTO> getOwnerProjects() {
return checkPermissionService.getOwnerProjects();
}
@GetMapping("/genTcpMockPort/{id}")
public String genTcpMockPort(@PathVariable String id){
return projectService.genTcpMockPort(id);

View File

@ -6,6 +6,7 @@ import io.metersphere.base.mapper.ext.*;
import io.metersphere.commons.constants.UserGroupType;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.dto.ProjectDTO;
import io.metersphere.dto.UserDTO;
import io.metersphere.i18n.Translator;
import org.apache.commons.collections4.CollectionUtils;
@ -14,6 +15,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@ -33,6 +35,9 @@ public class CheckPermissionService {
private ExtTestCaseReviewMapper extTestCaseReviewMapper;
@Resource
private UserService userService;
@Resource
private ExtProjectMapper extProjectMapper;
public void checkProjectOwner(String projectId) {
Set<String> projectIds = getUserRelatedProjectIds();
@ -123,4 +128,12 @@ public class CheckPermissionService {
MSException.throwException(Translator.get("check_owner_review"));
}
}
public List<ProjectDTO> getOwnerProjects() {
Set<String> userRelatedProjectIds = getUserRelatedProjectIds();
if (CollectionUtils.isEmpty(userRelatedProjectIds)) {
return new ArrayList<>(0);
}
List<String> projectIds = new ArrayList<>(userRelatedProjectIds);
return extProjectMapper.queryListByIds(projectIds);
}
}

View File

@ -106,7 +106,7 @@
<script>
import {getCurrentProjectID, getCurrentUser, getUUID, hasPermission} from "@/common/js/utils";
import {PROJECT_ID} from "@/common/js/constants";
import {PROJECT_ID, WORKSPACE_ID} from "@/common/js/constants";
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
const VersionSelect = requireComponent.keys().length > 0 ? requireComponent("./version/VersionSelect.vue") : {};
@ -166,6 +166,10 @@ export default {
};
},
created() {
let workspaceId = this.$route.params.workspaceId;
if (workspaceId) {
sessionStorage.setItem(WORKSPACE_ID, workspaceId);
}
let projectId = this.$route.params.projectId;
if (projectId) {
sessionStorage.setItem(PROJECT_ID, projectId);

View File

@ -1097,11 +1097,6 @@ export default {
if (!stepArray[i].projectId) {
// IDIDIDID
stepArray[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId;
} else {
const project = this.projectList.find(p => p.id === stepArray[i].projectId);
if (!project) {
stepArray[i].projectId = scenarioProjectId ? scenarioProjectId : this.projectId;
}
}
// debug
stepArray[i].parentIndex = fullPath ? fullPath + "_" + stepArray[i].index : stepArray[i].index;
@ -1669,7 +1664,7 @@ export default {
this.environmentType = val;
},
getWsProjects() {
this.$get("/project/listAll", res => {
this.$get("/project/getOwnerProjects", res => {
this.projectList = res.data;
})
},

View File

@ -149,7 +149,7 @@ export default {
this.$emit('close');
},
getWsProjects() {
this.$get("/project/listAll", res => {
this.$get("/project/getOwnerProjects", res => {
this.projectList = res.data;
})
},
@ -175,6 +175,7 @@ export default {
showPopover() {
this.projectIds.clear();
let url = "/api/automation/env";
this.$post(url, this.request, res => {
let data = res.data;
if (data) {

View File

@ -15,7 +15,7 @@
:title="displayTitle"
:if-from-variable-advance="ifFromVariableAdvance">
<template v-slot:afterTitle v-if="(request.refType==='API'|| request.refType==='CASE')&&isSameSpace">
<template v-slot:afterTitle v-if="(request.refType==='API'|| request.refType==='CASE')">
<span v-if="isShowNum" @click="clickResource(request)">{{ " ID: " + request.num + "" }}</span>
<span v-else>
<el-tooltip class="ms-num" effect="dark"
@ -231,8 +231,8 @@ export default {
envType: this.environmentType,
environmentMap: this.envMap,
isShowNum: false,
isSameSpace: true,
response: {},
dataWorkspaceId:'',
}
},
created() {
@ -251,11 +251,11 @@ export default {
if (this.request.num) {
this.isShowNum = true;
this.getWorkspaceId(this.request.projectId);
this.request.root = true;
if (this.request.id && this.request.referenced === 'REF') {
this.request.disabled = true;
}
this.getWorkspaceId(this.request.projectId);
} else {
this.isShowNum = false;
}
@ -485,7 +485,6 @@ export default {
}
if (response.data.num) {
this.request.num = response.data.num;
this.getWorkspaceId(response.data.projectId);
}
this.request.id = response.data.id;
this.request.disabled = true;
@ -510,7 +509,6 @@ export default {
if (response.data) {
if (response.data.num) {
this.request.num = response.data.num;
this.getWorkspaceId(response.data.projectId);
}
this.request.id = response.data.id;
this.request.versionName = response.data.versionName;
@ -522,7 +520,6 @@ export default {
if (response.data) {
if (response.data.num) {
this.request.num = response.data.num;
this.getWorkspaceId(response.data.projectId);
}
this.request.id = response.data.id;
this.request.versionName = response.data.versionName;
@ -704,7 +701,8 @@ export default {
dataType: "api",
dataSelectRange: 'edit:' + resource.id,
projectId: resource.projectId,
type: resource.protocol
type: resource.protocol,
workspaceId:this.dataWorkspaceId,
}
});
window.open(definitionData.href, '_blank');
@ -714,6 +712,7 @@ export default {
response.data.sourceId = resource.resourceId;
response.data.type = resource.type;
response.data.refType = resource.refType;
response.data.workspaceId = this.dataWorkspaceId;
this.clickCase(response.data)
} else {
this.$error("接口用例场景场景已经被删除");
@ -750,11 +749,7 @@ export default {
getWorkspaceId(projectId) {
this.$get("/project/get/" + projectId, response => {
if (response.data) {
if (response.data.workspaceId === getCurrentWorkspaceId()) {
this.isShowNum = true;
} else {
this.isSameSpace = false;
}
this.dataWorkspaceId = response.data.workspaceId
}
});
},

View File

@ -67,7 +67,7 @@ import MsTcpBasisParameters from "../../../definition/components/request/tcp/Tcp
import MsDubboBasisParameters from "../../../definition/components/request/dubbo/BasisParameters";
import MsApiRequestForm from "../../../definition/components/request/http/ApiHttpRequestForm";
import ApiBaseComponent from "../common/ApiBaseComponent";
import {getCurrentProjectID, getUUID, strMapToObj} from "@/common/js/utils";
import {getCurrentProjectID, getCurrentWorkspaceId, getUUID, strMapToObj} from "@/common/js/utils";
import {STEP} from "@/business/components/api/automation/scenario/Setting";
export default {
@ -112,11 +112,12 @@ export default {
},
},
created() {
if (!this.scenario.projectId) {
/*if (!this.scenario.projectId) {
this.scenario.projectId = getCurrentProjectID();
}
}*/
if (this.scenario.num) {
this.isShowNum = true;
this.getWorkspaceId(this.scenario.projectId);
} else {
this.isShowNum = false;
}
@ -139,9 +140,9 @@ export default {
return this.scenario.referenced !== undefined && this.scenario.referenced === 'Deleted' || this.scenario.referenced === 'REF';
},
projectId() {
/*projectId() {
return getCurrentProjectID();
},
},*/
},
methods: {
run() {
@ -256,9 +257,16 @@ export default {
clickResource(resource) {
let automationData = this.$router.resolve({
name: 'ApiAutomation',
params: {redirectID: getUUID(), dataType: "scenario", dataSelectRange: 'edit:' + resource.id, projectId: resource.projectId}
params: {redirectID: getUUID(), dataType: "scenario", dataSelectRange: 'edit:' + resource.id, projectId: resource.projectId,workspaceId:this.dataWorkspaceId }
});
window.open(automationData.href, '_blank');
},
getWorkspaceId(projectId) {
this.$get("/project/get/" + projectId, response => {
if (response.data) {
this.dataWorkspaceId = response.data.workspaceId;
}
});
}
}
}

View File

@ -18,7 +18,7 @@ export function getUrl(d) {
url += "/api/definition?resourceId=" + resourceId;
break;
case "CASE":
url += "/api/definition?caseId=" + d.id+"&projectId="+d.projectId;
url += "/api/definition?caseId=" + d.id+"&projectId="+d.projectId+"&workspaceId="+d.workspaceId;
break;
}
break;
@ -28,7 +28,7 @@ export function getUrl(d) {
url += "/api/definition?resourceId=" + resourceId;
break;
case "CASE":
url += "/api/definition?caseId=" + d.id+"&projectId="+d.projectId;
url += "/api/definition?caseId=" + d.id+"&projectId="+d.projectId+"&workspaceId="+d.workspaceId;
break;
}
break;
@ -38,7 +38,7 @@ export function getUrl(d) {
url += "/api/definition?resourceId=" + resourceId;
break;
case "CASE":
url += "/api/definition?caseId=" + d.id+"&projectId="+d.projectId;
url += "/api/definition?caseId=" + d.id+"&projectId="+d.projectId+"&workspaceId="+d.workspaceId;
break;
}
break;
@ -48,7 +48,7 @@ export function getUrl(d) {
url += "/api/definition?resourceId=" + resourceId;
break;
case "CASE":
url += "/api/definition?caseId=" + d.id+"&projectId="+d.projectId;
url += "/api/definition?caseId=" + d.id+"&projectId="+d.projectId+"&workspaceId="+d.workspaceId;
break;
}
break;
@ -58,7 +58,7 @@ export function getUrl(d) {
url += "/api/definition?resourceId=" + resourceId;
break;
case "CASE":
url += "/api/definition?caseId=" + d.id+"&projectId="+d.projectId;
url += "/api/definition?caseId=" + d.id+"&projectId="+d.projectId+"&workspaceId="+d.workspaceId;
break;
}
break;

View File

@ -274,6 +274,7 @@ export default {
params.ids.push(row.id);
});
params.condition = this.scenarioCondition;
this.$post('/api/automation/getApiScenarioProjectIdByConditions', params, res => {
let data = res.data;
data.forEach(scenario => {
@ -362,7 +363,7 @@ export default {
return this.$refs.envPopover.checkEnv();
},
getWsProjects() {
this.$get("/project/listAll", res => {
this.$get("/project/getOwnerProjects", res => {
this.projectList = res.data;
})
},

View File

@ -267,7 +267,7 @@ import MockConfig from "@/business/components/api/definition/components/mock/Moc
import ApiSchedule from "@/business/components/api/definition/components/import/ApiSchedule";
import MsEditCompleteContainer from "./components/EditCompleteContainer";
import MsEnvironmentSelect from "./components/case/MsEnvironmentSelect";
import {PROJECT_ID} from "@/common/js/constants";
import {PROJECT_ID, WORKSPACE_ID} from "@/common/js/constants";
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
@ -418,6 +418,9 @@ export default {
},
},
created() {
if (this.$route.query.workspaceId) {
sessionStorage.setItem(WORKSPACE_ID, this.$route.query.workspaceId);
}
let projectId = this.$route.params.projectId;
if (projectId) {
sessionStorage.setItem(PROJECT_ID, projectId);

View File

@ -155,7 +155,7 @@ export default {
this.runConfig.environmentGroupId = id;
},
getWsProjects() {
this.$get("/project/listAll", res => {
this.$get("/project/getOwnerProjects", res => {
this.projectList = res.data;
})
},

View File

@ -45,7 +45,7 @@ export default {
component: () => import('@/business/components/api/definition/ApiDefinition'),
},
{
path: "automation/:redirectID?/:dataType?/:dataSelectRange?/:projectId?",
path: "automation/:redirectID?/:dataType?/:dataSelectRange?/:projectId?/:workspaceId?",
name: "ApiAutomation",
component: () => import('@/business/components/api/automation/ApiAutomation'),
},

View File

@ -223,7 +223,7 @@ export default {
});
},
getWsProjects() {
this.$get("/project/listAll", res => {
this.$get("/project/getOwnerProjects", res => {
this.projectList = res.data;
})
},

View File

@ -152,7 +152,7 @@ export default {
this.runConfig.environmentGroupId = id;
},
getWsProjects() {
this.$get("/project/listAll", res => {
this.$get("/project/getOwnerProjects", res => {
this.projectList = res.data;
})
},

View File

@ -224,7 +224,7 @@
this.envGroupId = id;
},
getWsProjects() {
this.$get("/project/listAll", res => {
this.$get("/project/getOwnerProjectIds", res => {
this.projectList = res.data;
})
},

View File

@ -28,19 +28,6 @@
<slot></slot>
<!-- <template v-slot:footer>
<div v-if="$slots.footer">
<slot name="footer"></slot>
</div>
<div v-else>
<div style="margin-bottom: 15px" v-if="flag">
<el-checkbox v-model="checked">{{ $t('test_track.sync_add_api_load') }}</el-checkbox>
</div>
<ms-dialog-footer @cancel="close" v-loading="isSaving" @confirm="save"/>
</div>
</template>-->
</relevance-dialog>
</template>

View File

@ -160,7 +160,7 @@ export default {
this.projectEnvMap = projectEnvMap;
},
getWsProjects() {
this.$get("/project/listAll", res => {
this.$get("/project/getOwnerProjects", res => {
this.projectList = res.data;
})
},