feat(功能用例): 新增功能用例关联取消关联接口用例

This commit is contained in:
guoyuqi 2023-12-29 17:44:11 +08:00 committed by Craftsman
parent 6be702af86
commit eecdff9846
22 changed files with 715 additions and 65 deletions

View File

@ -30,6 +30,11 @@ public class FunctionalCaseTest implements Serializable {
@Size(min = 1, max = 64, message = "{functional_case_test.source_type.length_range}", groups = {Created.class, Updated.class})
private String sourceType;
@Schema(description = "用例所属项目", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{functional_case_test.project_id.not_blank}", groups = {Created.class})
@Size(min = 1, max = 50, message = "{functional_case_test.project_id.length_range}", groups = {Created.class, Updated.class})
private String projectId;
@Schema(description = "创建时间")
private Long createTime;
@ -49,6 +54,7 @@ public class FunctionalCaseTest implements Serializable {
caseId("case_id", "caseId", "VARCHAR", false),
sourceId("source_id", "sourceId", "VARCHAR", false),
sourceType("source_type", "sourceType", "VARCHAR", false),
projectId("project_id", "projectId", "VARCHAR", false),
createTime("create_time", "createTime", "BIGINT", false),
updateTime("update_time", "updateTime", "BIGINT", false),
createUser("create_user", "createUser", "VARCHAR", false),

View File

@ -384,6 +384,76 @@ public class FunctionalCaseTestExample {
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 Criteria andCreateTimeIsNull() {
addCriterion("create_time is null");
return (Criteria) this;

View File

@ -6,6 +6,7 @@
<result column="case_id" jdbcType="VARCHAR" property="caseId" />
<result column="source_id" jdbcType="VARCHAR" property="sourceId" />
<result column="source_type" jdbcType="VARCHAR" property="sourceType" />
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
<result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
<result column="create_user" jdbcType="VARCHAR" property="createUser" />
@ -70,7 +71,8 @@
</where>
</sql>
<sql id="Base_Column_List">
id, case_id, source_id, source_type, create_time, update_time, create_user, update_user
id, case_id, source_id, source_type, project_id, create_time, update_time, create_user,
update_user
</sql>
<select id="selectByExample" parameterType="io.metersphere.functional.domain.FunctionalCaseTestExample" resultMap="BaseResultMap">
select
@ -104,11 +106,13 @@
</delete>
<insert id="insert" parameterType="io.metersphere.functional.domain.FunctionalCaseTest">
insert into functional_case_test (id, case_id, source_id,
source_type, create_time, update_time,
create_user, update_user)
source_type, project_id, create_time,
update_time, create_user, update_user
)
values (#{id,jdbcType=VARCHAR}, #{caseId,jdbcType=VARCHAR}, #{sourceId,jdbcType=VARCHAR},
#{sourceType,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
#{createUser,jdbcType=VARCHAR}, #{updateUser,jdbcType=VARCHAR})
#{sourceType,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT},
#{updateTime,jdbcType=BIGINT}, #{createUser,jdbcType=VARCHAR}, #{updateUser,jdbcType=VARCHAR}
)
</insert>
<insert id="insertSelective" parameterType="io.metersphere.functional.domain.FunctionalCaseTest">
insert into functional_case_test
@ -125,6 +129,9 @@
<if test="sourceType != null">
source_type,
</if>
<if test="projectId != null">
project_id,
</if>
<if test="createTime != null">
create_time,
</if>
@ -151,6 +158,9 @@
<if test="sourceType != null">
#{sourceType,jdbcType=VARCHAR},
</if>
<if test="projectId != null">
#{projectId,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
#{createTime,jdbcType=BIGINT},
</if>
@ -186,6 +196,9 @@
<if test="record.sourceType != null">
source_type = #{record.sourceType,jdbcType=VARCHAR},
</if>
<if test="record.projectId != null">
project_id = #{record.projectId,jdbcType=VARCHAR},
</if>
<if test="record.createTime != null">
create_time = #{record.createTime,jdbcType=BIGINT},
</if>
@ -209,6 +222,7 @@
case_id = #{record.caseId,jdbcType=VARCHAR},
source_id = #{record.sourceId,jdbcType=VARCHAR},
source_type = #{record.sourceType,jdbcType=VARCHAR},
project_id = #{record.projectId,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT},
create_user = #{record.createUser,jdbcType=VARCHAR},
@ -229,6 +243,9 @@
<if test="sourceType != null">
source_type = #{sourceType,jdbcType=VARCHAR},
</if>
<if test="projectId != null">
project_id = #{projectId,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=BIGINT},
</if>
@ -249,6 +266,7 @@
set case_id = #{caseId,jdbcType=VARCHAR},
source_id = #{sourceId,jdbcType=VARCHAR},
source_type = #{sourceType,jdbcType=VARCHAR},
project_id = #{projectId,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT},
create_user = #{createUser,jdbcType=VARCHAR},
@ -257,13 +275,14 @@
</update>
<insert id="batchInsert" parameterType="map">
insert into functional_case_test
(id, case_id, source_id, source_type, create_time, update_time, create_user, update_user
)
(id, case_id, source_id, source_type, project_id, create_time, update_time, create_user,
update_user)
values
<foreach collection="list" item="item" separator=",">
(#{item.id,jdbcType=VARCHAR}, #{item.caseId,jdbcType=VARCHAR}, #{item.sourceId,jdbcType=VARCHAR},
#{item.sourceType,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT}, #{item.updateTime,jdbcType=BIGINT},
#{item.createUser,jdbcType=VARCHAR}, #{item.updateUser,jdbcType=VARCHAR})
#{item.sourceType,jdbcType=VARCHAR}, #{item.projectId,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT},
#{item.updateTime,jdbcType=BIGINT}, #{item.createUser,jdbcType=VARCHAR}, #{item.updateUser,jdbcType=VARCHAR}
)
</foreach>
</insert>
<insert id="batchInsertSelective" parameterType="map">
@ -288,6 +307,9 @@
<if test="'source_type'.toString() == column.value">
#{item.sourceType,jdbcType=VARCHAR}
</if>
<if test="'project_id'.toString() == column.value">
#{item.projectId,jdbcType=VARCHAR}
</if>
<if test="'create_time'.toString() == column.value">
#{item.createTime,jdbcType=BIGINT}
</if>

View File

@ -163,6 +163,7 @@ CREATE TABLE IF NOT EXISTS functional_case_test
`case_id` VARCHAR(50) NOT NULL COMMENT '功能用例ID',
`source_id` VARCHAR(50) NOT NULL COMMENT '其他类型用例ID',
`source_type` VARCHAR(64) NOT NULL COMMENT '用例类型:接口用例/场景用例/性能用例/UI用例',
`project_id` VARCHAR(50) NOT NULL COMMENT '用例所属项目' ,
`create_time` BIGINT NOT NULL COMMENT '创建时间',
`update_time` BIGINT NOT NULL COMMENT '更新时间',
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人',
@ -175,6 +176,8 @@ CREATE TABLE IF NOT EXISTS functional_case_test
CREATE INDEX idx_case_id ON functional_case_test (case_id);
CREATE INDEX idx_source_id ON functional_case_test (source_id);
CREATE INDEX idx_source_type ON functional_case_test(source_type);
CREATE INDEX idx_project_id ON functional_case_test(project_id);
CREATE TABLE IF NOT EXISTS functional_case_demand
(

View File

@ -1,13 +0,0 @@
package io.metersphere.dto;
import io.metersphere.api.domain.ApiTestCase;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class ApiTestCaseProviderDTO extends ApiTestCase {
@Schema(description = "版本名称")
private String versionName;
}

View File

@ -0,0 +1,47 @@
package io.metersphere.dto;
import io.metersphere.validation.groups.Created;
import io.metersphere.validation.groups.Updated;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
@Data
public class TestCaseProviderDTO {
@Schema(description = "用例pk", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{api_test_case.id.not_blank}", groups = {Updated.class})
@Size(min = 1, max = 50, message = "{api_test_case.id.length_range}", groups = {Created.class, Updated.class})
private String id;
@Schema(description = "用例名称", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{api_test_case.name.not_blank}", groups = {Created.class})
@Size(min = 1, max = 255, message = "{api_test_case.name.length_range}", groups = {Created.class, Updated.class})
private String name;
@Schema(description = "用例等级", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{api_test_case.priority.not_blank}", groups = {Created.class})
@Size(min = 1, max = 50, message = "{api_test_case.priority.length_range}", groups = {Created.class, Updated.class})
private String priority;
@Schema(description = "用例编号id")
private Long num;
@Schema(description = "标签")
private String tags;
@Schema(description = "自定义排序", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "{api_test_case.pos.not_blank}", groups = {Created.class})
private Long pos;
@Schema(description = "版本fk", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{api_test_case.version_id.not_blank}", groups = {Created.class})
@Size(min = 1, max = 50, message = "{api_test_case.version_id.length_range}", groups = {Created.class, Updated.class})
private String versionId;
@Schema(description = "版本名称")
private String versionName;
}

View File

@ -1,8 +1,9 @@
package io.metersphere.provider;
import io.metersphere.dto.ApiTestCaseProviderDTO;
import io.metersphere.dto.TestCaseProviderDTO;
import io.metersphere.request.ApiModuleProviderRequest;
import io.metersphere.request.ApiTestCasePageProviderRequest;
import io.metersphere.request.TestCasePageProviderRequest;
import io.metersphere.request.AssociateOtherCaseRequest;
import java.util.List;
import java.util.Map;
@ -17,10 +18,10 @@ public interface BaseAssociateApiProvider {
* @param sourceType 关联关系表表名
* @param sourceName 关联关系表主动关联方字段名称
* @param apiCaseColumnName 接口用例id 在关联关系表的字段名称
* @param apiTestCasePageProviderRequest 接口用例高级搜索条件
* @param testCasePageProviderRequest 接口用例高级搜索条件
* @return List<ApiTestCaseProviderDTO>
*/
List<ApiTestCaseProviderDTO> getApiTestCaseList(String sourceType, String sourceName, String apiCaseColumnName, ApiTestCasePageProviderRequest apiTestCasePageProviderRequest);
List<TestCaseProviderDTO> getApiTestCaseList(String sourceType, String sourceName, String apiCaseColumnName, TestCasePageProviderRequest testCasePageProviderRequest);
/**
* 根据接口用例的搜索条件获取符合条件的接口定义的模块统计数量
@ -31,5 +32,12 @@ public interface BaseAssociateApiProvider {
*/
Map<String, Long> moduleCount(String sourceType, String sourceName, String apiCaseColumnName, ApiModuleProviderRequest request, boolean deleted);
/**
* 根据页面筛选条件获取批量操作的用例ids
*
* @return 接口用例的ids
*/
List<String> getSelectIds(AssociateOtherCaseRequest request, Boolean deleted);
}

View File

@ -0,0 +1,58 @@
package io.metersphere.request;
import io.metersphere.sdk.constants.ModuleConstants;
import io.metersphere.validation.groups.Created;
import io.metersphere.validation.groups.Updated;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.util.List;
@Data
public class AssociateOtherCaseRequest {
@Schema(description = "不处理的ID")
List<String> excludeIds;
@Schema(description = "选择的ID", requiredMode = Schema.RequiredMode.REQUIRED)
@Valid
private List<
@NotBlank(message = "{id must not be blank}", groups = {Created.class, Updated.class})
String
> selectIds;
@Schema(description = "是否选择所有数据")
private boolean selectAll;
@Schema(description = "模块id")
private List<String> moduleIds;
@Schema(description = "版本id")
private String versionId;
@Schema(description = "版本来源")
private String refId;
@Schema(description = "要关联的用例选择的项目id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{associate_other_case_request.project_id.not_blank}")
private String projectId;
@Schema(description = "关联关系表里主ID eg:功能用例关联接口用例时为功能用例id")
@NotBlank(message = "{associate_other_case_request.case_id.not_blank}")
private String sourceId;
@Schema(description = "接口用例的接口协议", requiredMode = Schema.RequiredMode.REQUIRED)
private String protocol = ModuleConstants.NODE_PROTOCOL_HTTP;
@Schema(description = "关联用例的类型(API,SCENARIO,UI,PERFORMANCE)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{associate_other_case_request.type.not_blank}")
private String sourceType;
@Schema(description = "接口id")
private String apiDefinitionId;
@Schema(description = "查询条件")
private BaseProviderCondition condition = new BaseProviderCondition();
}

View File

@ -0,0 +1,22 @@
package io.metersphere.request;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class BaseProviderCondition {
@Schema(description = "关键字")
private String keyword;
@Schema(description = "匹配模式 所有/任一", allowableValues = {"AND", "OR"})
private String searchMode = "AND";
@Schema(description = "过滤字段")
private Map<String, List<String>> filter;
@Schema(description = "高级搜索")
private Map<String, Object> combine;
}

View File

@ -19,7 +19,7 @@ import java.util.Map;
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class ApiTestCasePageProviderRequest implements Serializable {
public class TestCasePageProviderRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@ -75,6 +75,10 @@ public class ApiTestCasePageProviderRequest implements Serializable {
@Schema(description = "版本来源")
private String refId;
@Schema(description = "关联用例的类型(API,SCENARIO,UI,PERFORMANCE)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{associate_other_case_request.type.not_blank}")
private String sourceType;
public String getSortString() {
if (sort == null || sort.isEmpty()) {

View File

@ -6,8 +6,9 @@ import io.metersphere.api.dto.definition.ApiTestCaseBatchRequest;
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
import io.metersphere.api.dto.definition.ApiTestCasePageRequest;
import io.metersphere.api.dto.definition.CasePassDTO;
import io.metersphere.dto.ApiTestCaseProviderDTO;
import io.metersphere.request.ApiTestCasePageProviderRequest;
import io.metersphere.dto.TestCaseProviderDTO;
import io.metersphere.request.TestCasePageProviderRequest;
import io.metersphere.request.AssociateOtherCaseRequest;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@ -44,6 +45,9 @@ public interface ExtApiTestCaseMapper {
List<String> getIdsByApiIds(@Param("ids") List<String> ids);
List<ApiTestCaseProviderDTO> listByProviderRequest(@Param("table") String resourceType, @Param("sourceName") String sourceName, @Param("apiCaseColumnName") String apiCaseColumnName,@Param("request") ApiTestCasePageProviderRequest request, @Param("deleted") boolean deleted);
List<TestCaseProviderDTO> listByProviderRequest(@Param("table") String resourceType, @Param("sourceName") String sourceName, @Param("apiCaseColumnName") String apiCaseColumnName, @Param("request") TestCasePageProviderRequest request, @Param("deleted") boolean deleted);
List<String> getIdsByProvider(@Param("request") AssociateOtherCaseRequest request, @Param("deleted") boolean deleted);
}

View File

@ -153,7 +153,7 @@
</foreach>
</select>
<select id="listByProviderRequest" resultType="io.metersphere.dto.ApiTestCaseProviderDTO">
<select id="listByProviderRequest" resultType="io.metersphere.dto.TestCaseProviderDTO">
SELECT
t1.id,
t1.project_id,
@ -173,6 +173,17 @@
<include refid="queryWhereCondition"/>
</select>
<select id="getIdsByProvider" resultType="java.lang.String">
SELECT
t1.id
FROM
api_test_case t1
LEFT JOIN api_report t3 ON t1.last_report_id = t3.id
INNER JOIN api_definition a ON t1.api_definition_id = a.id
WHERE t1.deleted =#{deleted}
<include refid="queryWhereConditionByBatch"/>
</select>
<sql id="queryWhereConditionByBatch">
<if test="request.protocol != null and request.protocol!=''">
and a.protocol = #{request.protocol}

View File

@ -3,14 +3,16 @@ package io.metersphere.api.provider;
import io.metersphere.api.mapper.ExtApiDefinitionModuleMapper;
import io.metersphere.api.mapper.ExtApiTestCaseMapper;
import io.metersphere.api.service.definition.ApiDefinitionModuleService;
import io.metersphere.dto.ApiTestCaseProviderDTO;
import io.metersphere.dto.TestCaseProviderDTO;
import io.metersphere.project.dto.ModuleCountDTO;
import io.metersphere.provider.BaseAssociateApiProvider;
import io.metersphere.request.ApiModuleProviderRequest;
import io.metersphere.request.ApiTestCasePageProviderRequest;
import io.metersphere.request.TestCasePageProviderRequest;
import io.metersphere.request.AssociateOtherCaseRequest;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.dto.sdk.BaseTreeNode;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import java.util.List;
@ -32,8 +34,8 @@ public class AssociateApiProvider implements BaseAssociateApiProvider {
private static final String UNPLANNED_API = "api_unplanned_request";
@Override
public List<ApiTestCaseProviderDTO> getApiTestCaseList(String sourceType, String sourceName, String apiCaseColumnName, ApiTestCasePageProviderRequest apiTestCasePageProviderRequest) {
return extApiTestCaseMapper.listByProviderRequest(sourceType, sourceName, apiCaseColumnName, apiTestCasePageProviderRequest, false);
public List<TestCaseProviderDTO> getApiTestCaseList(String sourceType, String sourceName, String apiCaseColumnName, TestCasePageProviderRequest testCasePageProviderRequest) {
return extApiTestCaseMapper.listByProviderRequest(sourceType, sourceName, apiCaseColumnName, testCasePageProviderRequest, false);
}
@Override
@ -47,6 +49,19 @@ public class AssociateApiProvider implements BaseAssociateApiProvider {
return moduleCountMap;
}
@Override
public List<String> getSelectIds(AssociateOtherCaseRequest request, Boolean deleted) {
if (request.isSelectAll()) {
List<String> ids = extApiTestCaseMapper.getIdsByProvider(request, deleted);
if (CollectionUtils.isNotEmpty(request.getExcludeIds())) {
ids.removeAll(request.getExcludeIds());
}
return ids;
} else {
return request.getSelectIds();
}
}
public long getAllCount(List<ModuleCountDTO> moduleCountDTOList) {
long count = 0;
for (ModuleCountDTO countDTO : moduleCountDTOList) {

View File

@ -1,16 +1,15 @@
package io.metersphere.api.controller;
import io.metersphere.api.provider.AssociateApiProvider;
import io.metersphere.dto.ApiTestCaseProviderDTO;
import io.metersphere.dto.TestCaseProviderDTO;
import io.metersphere.request.ApiModuleProviderRequest;
import io.metersphere.request.ApiTestCasePageProviderRequest;
import io.metersphere.request.TestCasePageProviderRequest;
import io.metersphere.request.AssociateOtherCaseRequest;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.apache.commons.collections4.CollectionUtils;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.jdbc.Sql;
@ -31,7 +30,8 @@ public class AssociateApiProviderTest extends BaseTest {
@Order(1)
@Sql(scripts = {"/dml/init_functional_case_test.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
public void getApiTestCaseListSuccess() throws Exception {
ApiTestCasePageProviderRequest request = new ApiTestCasePageProviderRequest();
TestCasePageProviderRequest request = new TestCasePageProviderRequest();
request.setSourceType("API");
request.setSourceId("gyq_associate_case_id_1");
request.setProjectId("project-associate-case-test");
request.setCurrent(1);
@ -39,7 +39,7 @@ public class AssociateApiProviderTest extends BaseTest {
request.setSort(new HashMap<>() {{
put("createTime", "desc");
}});
List<ApiTestCaseProviderDTO> apiTestCaseList = provider.getApiTestCaseList("functional_case_test", "case_id", "source_id", request);
List<TestCaseProviderDTO> apiTestCaseList = provider.getApiTestCaseList("functional_case_test", "case_id", "source_id", request);
String jsonString = JSON.toJSONString(apiTestCaseList);
System.out.println(jsonString);
}
@ -57,5 +57,23 @@ public class AssociateApiProviderTest extends BaseTest {
System.out.println(jsonString);
}
@Test
@Order(3)
public void getSelectIdsSuccess() throws Exception {
AssociateOtherCaseRequest request = new AssociateOtherCaseRequest();
request.setSourceType("API");
request.setSourceId("gyq_associate_case_id_1");
request.setSelectAll(true);
request.setProjectId("project-associate-case-test");
request.setExcludeIds(List.of("gyq_associate_api_case_id_2"));
List<String> selectIds = provider.getSelectIds(request, false);
Assertions.assertTrue(CollectionUtils.isNotEmpty(selectIds));
request.setSelectAll(false);
request.setProjectId("project-associate-case-test");
request.setSelectIds(List.of("gyq_associate_api_case_id_1"));
selectIds = provider.getSelectIds(request, false);
Assertions.assertTrue(CollectionUtils.isNotEmpty(selectIds));
}
}

View File

@ -0,0 +1,20 @@
package io.metersphere.functional.constants;
public class AssociateCaseType {
/**
* 接口用例
*/
public static final String API = "API";
/**
* 场景用例
*/
public static final String SCENARIO = "SCENARIO";
/**
* UI用例
*/
public static final String UI = "UI";
/**
* 性能用例
*/
public static final String PERFORMANCE = "PERFORMANCE";
}

View File

@ -2,14 +2,17 @@ package io.metersphere.functional.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.dto.ApiTestCaseProviderDTO;
import io.metersphere.dto.TestCaseProviderDTO;
import io.metersphere.functional.request.FunctionalTestCaseDisassociateRequest;
import io.metersphere.functional.service.FunctionalTestCaseService;
import io.metersphere.request.ApiModuleProviderRequest;
import io.metersphere.request.ApiTestCasePageProviderRequest;
import io.metersphere.request.TestCasePageProviderRequest;
import io.metersphere.request.AssociateOtherCaseRequest;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.system.security.CheckOwner;
import io.metersphere.system.utils.PageUtils;
import io.metersphere.system.utils.Pager;
import io.metersphere.system.utils.SessionUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
@ -37,20 +40,37 @@ public class FunctionalTestCaseController {
@Operation(summary = "用例管理-功能用例-关联其他用例-获取接口用例列表")
@RequiresPermissions(value = {PermissionConstants.FUNCTIONAL_CASE_READ_ADD, PermissionConstants.FUNCTIONAL_CASE_READ_UPDATE, PermissionConstants.FUNCTIONAL_CASE_READ_DELETE}, logical = Logical.OR)
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
public Pager<List<ApiTestCaseProviderDTO>> associateApiCaseList(@Validated @RequestBody ApiTestCasePageProviderRequest request) {
public Pager<List<TestCaseProviderDTO>> associateApiCaseList(@Validated @RequestBody TestCasePageProviderRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "create_time desc");
return PageUtils.setPageInfo(page, functionalTestCaseService.page(request));
}
@PostMapping("/associate/api/module/count")
@Operation(summary = "接口测试-接口管理-模块-统计模块数量")
@Operation(summary = "用例管理-功能用例-关联其他用例-统计接口用例模块数量")
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ)
@CheckOwner(resourceId = "#request.projectId", resourceType = "project")
public Map<String, Long> moduleCount(@Validated @RequestBody ApiModuleProviderRequest request) {
return functionalTestCaseService.moduleCount(request, false);
}
@PostMapping("/associate/case")
@Operation(summary = "用例管理-功能用例-关联其他用例-关联用例")
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ)
@CheckOwner(resourceId = "#request.sourceId", resourceType = "functional_case")
public void associateCase(@Validated @RequestBody AssociateOtherCaseRequest request) {
functionalTestCaseService.associateCase(request, false, SessionUtils.getUserId());
}
@PostMapping("/disassociate/case")
@Operation(summary = "用例管理-功能用例-关联其他用例-取消关联用例")
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ)
@CheckOwner(resourceId = "#request.projectId", resourceType = "project")
public void disassociateCase(@Validated @RequestBody FunctionalTestCaseDisassociateRequest request) {
functionalTestCaseService.disassociateCase(request);
}

View File

@ -0,0 +1,13 @@
package io.metersphere.functional.mapper;
import io.metersphere.functional.request.FunctionalTestCaseDisassociateRequest;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ExtFunctionalCaseTestMapper {
List<String> getIds(@Param("request") FunctionalTestCaseDisassociateRequest request);
}

View File

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.functional.mapper.ExtFunctionalCaseTestMapper">
<select id="getIds" resultType="java.lang.String">
SELECT
id
FROM
functional_case_test
where functional_case_test.case_id = #{request.caseId}
<choose>
<when test='request.condition.searchMode == "AND"'>
AND <include refid="queryWhereConditionByBaseQueryRequest"/>
</when>
<when test='request.condition.searchMode == "OR"'>
and (
<include refid="queryWhereConditionByBaseQueryRequest"/>
)
</when>
</choose>
1 = 1
</select>
<sql id="queryWhereConditionByBaseQueryRequest">
<if test="request.condition.keyword != null and request.sourceType == 'API'">
functional_case_test.source_id not in
(
select api_test_case.id from api_test_case where api_test_case.name like concat('%', #{request.keyword},'%')
)
<include refid="queryType">
<property name="searchMode" value="request.condition.searchMode"/>
</include>
</if>
<if test="request.condition.keyword != null and request.sourceType == 'SCENARIO'">
functional_case_test.source_id not in
(
select api_scenario.id from api_scenario where api_scenario.name like concat('%', #{request.keyword},'%')
)
<include refid="queryType">
<property name="searchMode" value="request.condition.searchMode"/>
</include>
</if>
<include refid="filters">
<property name="filter" value="request.condition.filter"/>
</include>
</sql>
<sql id="queryType">
<choose>
<when test='${searchMode} == "AND"'>
AND
</when>
<when test='${searchMode} == "OR"'>
OR
</when>
</choose>
</sql>
<sql id="filters">
<if test="${filter} != null and ${filter}.size() > 0">
<foreach collection="${filter}.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key=='project_id'">
functional_case_test.project_id in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
<include refid="queryType">
<property name="searchMode" value="request.searchMode"/>
</include>
</when>
<when test="key=='source_type'">
functional_case_test.source_type in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
<include refid="queryType">
<property name="searchMode" value="request.searchMode"/>
</include>
</when>
</choose>
</if>
</foreach>
</if>
</sql>
</mapper>

View File

@ -0,0 +1,20 @@
package io.metersphere.functional.request;
import io.metersphere.functional.dto.BaseFunctionalCaseBatchDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class FunctionalTestCaseDisassociateRequest extends BaseFunctionalCaseBatchDTO {
@Schema(description = "功能用例选择的项目id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{functional_test_case_disassociate_request.case_id.not_blank}")
private String caseId;
@Schema(description = "关联用例的类型(API,SCENARIO,UI,PERFORMANCE)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{functional_test_case_disassociate_request.type.not_blank}")
private String sourceType;
}

View File

@ -1,10 +1,24 @@
package io.metersphere.functional.service;
import io.metersphere.dto.ApiTestCaseProviderDTO;
import io.metersphere.dto.TestCaseProviderDTO;
import io.metersphere.functional.constants.AssociateCaseType;
import io.metersphere.functional.domain.FunctionalCaseTest;
import io.metersphere.functional.domain.FunctionalCaseTestExample;
import io.metersphere.functional.mapper.ExtFunctionalCaseTestMapper;
import io.metersphere.functional.mapper.FunctionalCaseTestMapper;
import io.metersphere.functional.request.FunctionalTestCaseDisassociateRequest;
import io.metersphere.provider.BaseAssociateApiProvider;
import io.metersphere.request.ApiModuleProviderRequest;
import io.metersphere.request.ApiTestCasePageProviderRequest;
import io.metersphere.request.TestCasePageProviderRequest;
import io.metersphere.request.AssociateOtherCaseRequest;
import io.metersphere.sdk.util.LogUtils;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionUtils;
import org.redisson.api.IdGenerator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -22,12 +36,22 @@ public class FunctionalTestCaseService {
@Resource
private BaseAssociateApiProvider provider;
@Resource
SqlSessionFactory sqlSessionFactory;
@Resource
private ExtFunctionalCaseTestMapper extFunctionalCaseTestMapper;
@Resource
private FunctionalCaseTestMapper functionalCaseTestMapper;
/**
* 获取功能用例未关联的接口用例列表
*
* @param request request
* @return List<ApiTestCaseProviderDTO>
*/
public List<ApiTestCaseProviderDTO> page(ApiTestCasePageProviderRequest request) {
public List<TestCaseProviderDTO> page(TestCasePageProviderRequest request) {
return provider.getApiTestCaseList("functional_case_test", "case_id", "source_id", request);
}
@ -42,4 +66,75 @@ public class FunctionalTestCaseService {
return provider.moduleCount("functional_case_test", "case_id", "source_id", request, deleted);
}
/**
* 关联其他用例
*
* @param request request
* @param deleted 接口定义是否删除
*/
public void associateCase(AssociateOtherCaseRequest request, boolean deleted, String userId) {
switch (request.getSourceType()) {
case AssociateCaseType.API -> associateApi(request, deleted, userId);
case AssociateCaseType.SCENARIO -> associateScenario(request, deleted, userId);
}
}
private void associateScenario(AssociateOtherCaseRequest request, boolean deleted, String userId) {
LogUtils.info("关联场景");
}
private void associateApi(AssociateOtherCaseRequest request, boolean deleted, String userId) {
List<String> selectIds = provider.getSelectIds(request, deleted);
if (CollectionUtils.isEmpty(selectIds)) {
return;
}
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
FunctionalCaseTestMapper caseTestMapper = sqlSession.getMapper(FunctionalCaseTestMapper.class);
for (String selectId : selectIds) {
FunctionalCaseTest functionalCaseTest = new FunctionalCaseTest();
functionalCaseTest.setCaseId(request.getSourceId());
functionalCaseTest.setProjectId(request.getProjectId());
functionalCaseTest.setSourceId(selectId);
functionalCaseTest.setSourceType(request.getSourceType());
functionalCaseTest.setId(IdGenerator.random().generateId());
functionalCaseTest.setCreateUser(userId);
functionalCaseTest.setCreateTime(System.currentTimeMillis());
functionalCaseTest.setUpdateUser(userId);
functionalCaseTest.setUpdateTime(System.currentTimeMillis());
caseTestMapper.insert(functionalCaseTest);
}
sqlSession.flushStatements();
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
}
/**
* 取消关联其他用例
*
* @param request request
*/
public void disassociateCase(FunctionalTestCaseDisassociateRequest request) {
List<String> functionalTestCaseIds = doSelectIds(request);
FunctionalCaseTestExample functionalCaseTestExample = new FunctionalCaseTestExample();
if (CollectionUtils.isNotEmpty(functionalTestCaseIds)) {
functionalCaseTestExample.createCriteria().andIdIn(functionalTestCaseIds);
functionalCaseTestMapper.deleteByExample(functionalCaseTestExample);
}
}
public List<String> doSelectIds(FunctionalTestCaseDisassociateRequest request) {
if (request.isSelectAll()) {
List<String> ids = extFunctionalCaseTestMapper.getIds(request);
if (org.apache.commons.collections.CollectionUtils.isNotEmpty(request.getExcludeIds())) {
ids.removeAll(request.getExcludeIds());
}
return ids;
} else {
return request.getSelectIds();
}
}
}

View File

@ -1,9 +1,14 @@
package io.metersphere.functional.controller;
import io.metersphere.dto.ApiTestCaseProviderDTO;
import io.metersphere.dto.TestCaseProviderDTO;
import io.metersphere.functional.constants.AssociateCaseType;
import io.metersphere.functional.domain.FunctionalCaseTest;
import io.metersphere.functional.mapper.FunctionalCaseTestMapper;
import io.metersphere.functional.request.FunctionalTestCaseDisassociateRequest;
import io.metersphere.provider.BaseAssociateApiProvider;
import io.metersphere.request.ApiModuleProviderRequest;
import io.metersphere.request.ApiTestCasePageProviderRequest;
import io.metersphere.request.AssociateOtherCaseRequest;
import io.metersphere.request.TestCasePageProviderRequest;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
@ -29,14 +34,24 @@ public class FunctionalTestCaseControllerTests extends BaseTest {
private static final String URL_CASE_PAGE_MODULE_COUNT = "/functional/case/test/associate/api/module/count";
private static final String URL_CASE_PAGE_ASSOCIATE = "/functional/case/test/associate/case";
private static final String URL_CASE_PAGE_DISASSOCIATE = "/functional/case/test/disassociate/case";
@Resource
BaseAssociateApiProvider provider;
@Resource
private FunctionalCaseTestMapper functionalCaseTestMapper;
@Test
@Order(1)
public void getPageSuccess() throws Exception {
ApiTestCasePageProviderRequest request = new ApiTestCasePageProviderRequest();
TestCasePageProviderRequest request = new TestCasePageProviderRequest();
request.setSourceType(AssociateCaseType.API);
request.setSourceId("gyq_associate_case_id_1");
request.setProjectId("project_gyq_associate_test");
request.setCurrent(1);
@ -44,17 +59,17 @@ public class FunctionalTestCaseControllerTests extends BaseTest {
request.setSort(new HashMap<>() {{
put("createTime", "desc");
}});
ApiTestCaseProviderDTO apiTestCaseProviderDTO = new ApiTestCaseProviderDTO();
apiTestCaseProviderDTO.setName("第一个");
List<ApiTestCaseProviderDTO> operations = new ArrayList<>();
operations.add(apiTestCaseProviderDTO);
TestCaseProviderDTO testCaseProviderDTO = new TestCaseProviderDTO();
testCaseProviderDTO.setName("第一个");
List<TestCaseProviderDTO> operations = new ArrayList<>();
operations.add(testCaseProviderDTO);
Mockito.when(provider.getApiTestCaseList("functional_case_test", "case_id", "source_id", request)).thenReturn(operations);
List<ApiTestCaseProviderDTO> apiTestCaseList = provider.getApiTestCaseList("functional_case_test", "case_id", "source_id", request);
List<TestCaseProviderDTO> apiTestCaseList = provider.getApiTestCaseList("functional_case_test", "case_id", "source_id", request);
MvcResult mvcResult = this.requestPostWithOkAndReturn(URL_CASE_PAGE, request);
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
List<ApiTestCaseProviderDTO> apiTestCaseProviderDTOS = JSON.parseArray(JSON.toJSONString(resultHolder.getData()), ApiTestCaseProviderDTO.class);
Assertions.assertNotNull(apiTestCaseProviderDTOS);
List<TestCaseProviderDTO> testCaseProviderDTOS = JSON.parseArray(JSON.toJSONString(resultHolder.getData()), TestCaseProviderDTO.class);
Assertions.assertNotNull(testCaseProviderDTOS);
System.out.println(JSON.toJSONString(apiTestCaseList));
}
@ -62,17 +77,18 @@ public class FunctionalTestCaseControllerTests extends BaseTest {
@Test
@Order(2)
public void getPageSuccessT() throws Exception {
ApiTestCasePageProviderRequest request = new ApiTestCasePageProviderRequest();
TestCasePageProviderRequest request = new TestCasePageProviderRequest();
request.setSourceType(AssociateCaseType.API);
request.setSourceId("gyq_associate_case_id_1");
request.setProjectId("project_gyq_associate_test");
request.setCurrent(1);
request.setPageSize(10);
List<ApiTestCaseProviderDTO> apiTestCaseList = provider.getApiTestCaseList("functional_case_test", "case_id", "source_id", request);
List<TestCaseProviderDTO> apiTestCaseList = provider.getApiTestCaseList("functional_case_test", "case_id", "source_id", request);
MvcResult mvcResult = this.requestPostWithOkAndReturn(URL_CASE_PAGE, request);
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
List<ApiTestCaseProviderDTO> apiTestCaseProviderDTOS = JSON.parseArray(JSON.toJSONString(resultHolder.getData()), ApiTestCaseProviderDTO.class);
Assertions.assertNotNull(apiTestCaseProviderDTOS);
List<TestCaseProviderDTO> testCaseProviderDTOS = JSON.parseArray(JSON.toJSONString(resultHolder.getData()), TestCaseProviderDTO.class);
Assertions.assertNotNull(testCaseProviderDTOS);
System.out.println(JSON.toJSONString(apiTestCaseList));
}
@ -90,5 +106,78 @@ public class FunctionalTestCaseControllerTests extends BaseTest {
Assertions.assertNotNull(resultHolder);
}
@Test
@Order(4)
public void associateCaseSuccess() throws Exception {
AssociateOtherCaseRequest request = new AssociateOtherCaseRequest();
request.setSourceType(AssociateCaseType.API);
request.setSourceId("gyq_associate_case_id_1");
request.setSelectAll(true);
request.setProjectId("project-associate-case-test");
request.setExcludeIds(List.of("gyq_associate_api_case_id_2"));
MvcResult mvcResult = this.requestPostWithOkAndReturn(URL_CASE_PAGE_ASSOCIATE, request);
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
Assertions.assertNotNull(resultHolder);
request.setSelectAll(false);
request.setProjectId("project-associate-case-test");
request.setSelectIds(List.of("gyq_associate_api_case_id_1"));
mvcResult = this.requestPostWithOkAndReturn(URL_CASE_PAGE_ASSOCIATE, request);
returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
resultHolder = JSON.parseObject(returnData, ResultHolder.class);
Assertions.assertNotNull(resultHolder);
}
@Test
@Order(5)
public void disassociateCaseSuccess() throws Exception {
addFunctionalCaseTest();
FunctionalTestCaseDisassociateRequest request = new FunctionalTestCaseDisassociateRequest();
request.setSourceType(AssociateCaseType.API);
request.setCaseId("gyq_associate_functional_case_id_1");
request.setSelectAll(true);
request.setExcludeIds(List.of("gyq_associate_api_case_id_2"));
MvcResult mvcResult = this.requestPostWithOkAndReturn(URL_CASE_PAGE_DISASSOCIATE, request);
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
Assertions.assertNotNull(resultHolder);
FunctionalCaseTest functionalCaseTest = functionalCaseTestMapper.selectByPrimaryKey("functionalCaseTestHasId");
Assertions.assertNull(functionalCaseTest);
request = new FunctionalTestCaseDisassociateRequest();
request.setSourceType(AssociateCaseType.API);
request.setCaseId("gyq_associate_case_id_1");
request.setSelectAll(true);
request.setSelectIds(List.of("gyq_associate_api_case_id_1"));
mvcResult = this.requestPostWithOkAndReturn(URL_CASE_PAGE_DISASSOCIATE, request);
returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
resultHolder = JSON.parseObject(returnData, ResultHolder.class);
Assertions.assertNotNull(resultHolder);
request = new FunctionalTestCaseDisassociateRequest();
request.setSourceType(AssociateCaseType.API);
request.setCaseId("gyq_associate_case_id_1");
request.setSelectAll(false);
request.setSelectIds(List.of("gyq_associate_api_case_id_1"));
mvcResult = this.requestPostWithOkAndReturn(URL_CASE_PAGE_DISASSOCIATE, request);
returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
resultHolder = JSON.parseObject(returnData, ResultHolder.class);
Assertions.assertNotNull(resultHolder);
}
private void addFunctionalCaseTest() {
FunctionalCaseTest functionalCaseTest = new FunctionalCaseTest();
functionalCaseTest.setId("functionalCaseTestHasId");
functionalCaseTest.setCaseId("gyq_associate_functional_case_id_1");
functionalCaseTest.setSourceId("gyq_api_case_id_1");
functionalCaseTest.setSourceType(AssociateCaseType.API);
functionalCaseTest.setProjectId("gyq-organization-associate-case-test");
functionalCaseTest.setCreateUser("admin");
functionalCaseTest.setCreateTime(System.currentTimeMillis());
functionalCaseTest.setUpdateUser("admin");
functionalCaseTest.setUpdateTime(System.currentTimeMillis());
functionalCaseTestMapper.insert(functionalCaseTest);
}
}

View File

@ -0,0 +1,33 @@
INSERT INTO organization(id, num, name, description, create_time, update_time, create_user, update_user, deleted,
delete_user, delete_time) VALUE
('gyq-organization-associate-case-test', null, 'gyq-organization-associate-case-test', 'gyq-organization-associate-case-test',
UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', 'admin', 0, null, null);
INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time)
VALUES ('gyq-project-associate-case-test', null, 'gyq-organization-associate-case-test', '用例评论项目', '系统默认创建的项目',
'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000);
INSERT INTO functional_case(id, num, module_id, project_id, template_id, name, review_status, tags, case_edit_type, pos, version_id, ref_id, last_execute_result, deleted, public_case, latest, create_user, update_user, delete_user, create_time, update_time, delete_time)
VALUES ('gyq_associate_functional_case_id_1', 100, 'TEST_MODULE_ID', 'gyq-project-associate-case-test', '100001', '测试', 'UN_REVIEWED', NULL, 'STEP', 0, 'v1.0.0', 'v1.0.0', 'UN_EXECUTED', b'0', b'0', b'1', 'admin', 'admin', '', 1698058347559, 1698058347559, NULL);
INSERT INTO functional_case_blob(id, steps, text_description, expected_result, prerequisite, description) VALUES ('gyq_associate_functional_case_id_1', 'STEP', '1111', '', '', 'TEST');
INSERT INTO api_test_case(id, name, priority, num, tags, status, last_report_status, last_report_id, pos, project_id, api_definition_id, version_id, environment_id, create_time, create_user, update_time, update_user, delete_time, delete_user, deleted)
VALUES ('gyq_api_case_id_1','gyq_api_case_id_1','P0',1001, null, 'Underway', null, null, 100, 'gyq-project-associate-case-test', 'gyq_api_definition_id_1', 'gyq_version_id', 'gyq_associate_env_id', 1698058347559, 'admin',1698058347559,'admin',null,null,false);
INSERT INTO api_test_case(id, name, priority, num, tags, status, last_report_status, last_report_id, pos, project_id, api_definition_id, version_id, environment_id, create_time, create_user, update_time, update_user, delete_time, delete_user, deleted)
VALUES ('gyq_api_case_id_2','测试查询模块用','P0',1002, null, 'Underway', null, null, 200, 'gyq-project-associate-case-test', 'gyq_api_definition_id_1', 'gyq_version_id', 'gyq_associate_env_id', 1698058347559, 'admin',1698058347559,'admin',null,null,false);
INSERT INTO api_definition(id, name, protocol, method, path, status, num, tags, pos, project_id, module_id, latest, version_id, ref_id, description, create_time, create_user, update_time, update_user, delete_user, delete_time, deleted)
VALUES ('gyq_associate_api_definition_id_1', 'gyq_associate_api_definition_id_1', 'HTTP', 'POST','api/test','test-api-status', 1000001, null, 1, 'gyq-project-associate-case-test' , 'gyq_associate_test_module', true, 'v1.10','gyq_associate_api_definition_id_1', null, UNIX_TIMESTAMP() * 1000,'admin', UNIX_TIMESTAMP() * 1000,'admin', null,null,false);
INSERT INTO api_definition_module(id, name,parent_id, project_id, pos, create_time, update_time, update_user, create_user)
VALUES ('gyq_associate_test_module', 'gyq_associate_test_module', 'NONE', 'gyq-project-associate-case-test', 100, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin','admin');
INSERT INTO project_version(id, project_id, name, description, status, latest, publish_time, start_time, end_time, create_time, create_user)
values ('gyq_version_id','gyq-project-associate-case-test','v1.0.0', null, 'open', 1, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin');