feat(接口测试): 场景保存接口实现
This commit is contained in:
parent
280723aee0
commit
b5a5f6d899
|
@ -31,7 +31,7 @@ public class ApiScenarioStep implements Serializable {
|
||||||
private Boolean enable;
|
private Boolean enable;
|
||||||
|
|
||||||
@Schema(description = "资源id")
|
@Schema(description = "资源id")
|
||||||
private Long resourceId;
|
private String resourceId;
|
||||||
|
|
||||||
@Schema(description = "资源编号")
|
@Schema(description = "资源编号")
|
||||||
private String resourceNum;
|
private String resourceNum;
|
||||||
|
@ -49,7 +49,7 @@ public class ApiScenarioStep implements Serializable {
|
||||||
private String versionId;
|
private String versionId;
|
||||||
|
|
||||||
@Schema(description = "引用/复制/自定义")
|
@Schema(description = "引用/复制/自定义")
|
||||||
private String source;
|
private String refType;
|
||||||
|
|
||||||
@Schema(description = "循环等组件基础数据")
|
@Schema(description = "循环等组件基础数据")
|
||||||
private String config;
|
private String config;
|
||||||
|
@ -62,13 +62,13 @@ public class ApiScenarioStep implements Serializable {
|
||||||
name("name", "name", "VARCHAR", true),
|
name("name", "name", "VARCHAR", true),
|
||||||
sort("sort", "sort", "BIGINT", false),
|
sort("sort", "sort", "BIGINT", false),
|
||||||
enable("enable", "enable", "BIT", true),
|
enable("enable", "enable", "BIT", true),
|
||||||
resourceId("resource_id", "resourceId", "BIGINT", false),
|
resourceId("resource_id", "resourceId", "VARCHAR", false),
|
||||||
resourceNum("resource_num", "resourceNum", "VARCHAR", false),
|
resourceNum("resource_num", "resourceNum", "VARCHAR", false),
|
||||||
stepType("step_type", "stepType", "VARCHAR", false),
|
stepType("step_type", "stepType", "VARCHAR", false),
|
||||||
projectId("project_id", "projectId", "VARCHAR", false),
|
projectId("project_id", "projectId", "VARCHAR", false),
|
||||||
parentId("parent_id", "parentId", "VARCHAR", false),
|
parentId("parent_id", "parentId", "VARCHAR", false),
|
||||||
versionId("version_id", "versionId", "VARCHAR", false),
|
versionId("version_id", "versionId", "VARCHAR", false),
|
||||||
source("source", "source", "VARCHAR", true),
|
refType("ref_type", "refType", "VARCHAR", false),
|
||||||
config("config", "config", "VARCHAR", false);
|
config("config", "config", "VARCHAR", false);
|
||||||
|
|
||||||
private static final String BEGINNING_DELIMITER = "`";
|
private static final String BEGINNING_DELIMITER = "`";
|
||||||
|
|
|
@ -15,6 +15,11 @@ public class ApiScenarioStepBlob implements Serializable {
|
||||||
@Size(min = 1, max = 50, message = "{api_scenario_step_blob.id.length_range}", groups = {Created.class, Updated.class})
|
@Size(min = 1, max = 50, message = "{api_scenario_step_blob.id.length_range}", groups = {Created.class, Updated.class})
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "场景id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_scenario_step_blob.scenario_id.not_blank}", groups = {Created.class})
|
||||||
|
@Size(min = 1, max = 50, message = "{api_scenario_step_blob.scenario_id.length_range}", groups = {Created.class, Updated.class})
|
||||||
|
private String scenarioId;
|
||||||
|
|
||||||
@Schema(description = "场景步骤内容")
|
@Schema(description = "场景步骤内容")
|
||||||
private byte[] content;
|
private byte[] content;
|
||||||
|
|
||||||
|
@ -22,6 +27,7 @@ public class ApiScenarioStepBlob implements Serializable {
|
||||||
|
|
||||||
public enum Column {
|
public enum Column {
|
||||||
id("id", "id", "VARCHAR", false),
|
id("id", "id", "VARCHAR", false),
|
||||||
|
scenarioId("scenario_id", "scenarioId", "VARCHAR", false),
|
||||||
content("content", "content", "LONGVARBINARY", false);
|
content("content", "content", "LONGVARBINARY", false);
|
||||||
|
|
||||||
private static final String BEGINNING_DELIMITER = "`";
|
private static final String BEGINNING_DELIMITER = "`";
|
||||||
|
|
|
@ -173,6 +173,76 @@ public class ApiScenarioStepBlobExample {
|
||||||
addCriterion("id not between", value1, value2, "id");
|
addCriterion("id not between", value1, value2, "id");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdIsNull() {
|
||||||
|
addCriterion("scenario_id is null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdIsNotNull() {
|
||||||
|
addCriterion("scenario_id is not null");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdEqualTo(String value) {
|
||||||
|
addCriterion("scenario_id =", value, "scenarioId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdNotEqualTo(String value) {
|
||||||
|
addCriterion("scenario_id <>", value, "scenarioId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdGreaterThan(String value) {
|
||||||
|
addCriterion("scenario_id >", value, "scenarioId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdGreaterThanOrEqualTo(String value) {
|
||||||
|
addCriterion("scenario_id >=", value, "scenarioId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdLessThan(String value) {
|
||||||
|
addCriterion("scenario_id <", value, "scenarioId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdLessThanOrEqualTo(String value) {
|
||||||
|
addCriterion("scenario_id <=", value, "scenarioId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdLike(String value) {
|
||||||
|
addCriterion("scenario_id like", value, "scenarioId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdNotLike(String value) {
|
||||||
|
addCriterion("scenario_id not like", value, "scenarioId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdIn(List<String> values) {
|
||||||
|
addCriterion("scenario_id in", values, "scenarioId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdNotIn(List<String> values) {
|
||||||
|
addCriterion("scenario_id not in", values, "scenarioId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdBetween(String value1, String value2) {
|
||||||
|
addCriterion("scenario_id between", value1, value2, "scenarioId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andScenarioIdNotBetween(String value1, String value2) {
|
||||||
|
addCriterion("scenario_id not between", value1, value2, "scenarioId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Criteria extends GeneratedCriteria {
|
public static class Criteria extends GeneratedCriteria {
|
||||||
|
|
|
@ -444,52 +444,62 @@ public class ApiScenarioStepExample {
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andResourceIdEqualTo(Long value) {
|
public Criteria andResourceIdEqualTo(String value) {
|
||||||
addCriterion("resource_id =", value, "resourceId");
|
addCriterion("resource_id =", value, "resourceId");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andResourceIdNotEqualTo(Long value) {
|
public Criteria andResourceIdNotEqualTo(String value) {
|
||||||
addCriterion("resource_id <>", value, "resourceId");
|
addCriterion("resource_id <>", value, "resourceId");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andResourceIdGreaterThan(Long value) {
|
public Criteria andResourceIdGreaterThan(String value) {
|
||||||
addCriterion("resource_id >", value, "resourceId");
|
addCriterion("resource_id >", value, "resourceId");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andResourceIdGreaterThanOrEqualTo(Long value) {
|
public Criteria andResourceIdGreaterThanOrEqualTo(String value) {
|
||||||
addCriterion("resource_id >=", value, "resourceId");
|
addCriterion("resource_id >=", value, "resourceId");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andResourceIdLessThan(Long value) {
|
public Criteria andResourceIdLessThan(String value) {
|
||||||
addCriterion("resource_id <", value, "resourceId");
|
addCriterion("resource_id <", value, "resourceId");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andResourceIdLessThanOrEqualTo(Long value) {
|
public Criteria andResourceIdLessThanOrEqualTo(String value) {
|
||||||
addCriterion("resource_id <=", value, "resourceId");
|
addCriterion("resource_id <=", value, "resourceId");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andResourceIdIn(List<Long> values) {
|
public Criteria andResourceIdLike(String value) {
|
||||||
|
addCriterion("resource_id like", value, "resourceId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andResourceIdNotLike(String value) {
|
||||||
|
addCriterion("resource_id not like", value, "resourceId");
|
||||||
|
return (Criteria) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Criteria andResourceIdIn(List<String> values) {
|
||||||
addCriterion("resource_id in", values, "resourceId");
|
addCriterion("resource_id in", values, "resourceId");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andResourceIdNotIn(List<Long> values) {
|
public Criteria andResourceIdNotIn(List<String> values) {
|
||||||
addCriterion("resource_id not in", values, "resourceId");
|
addCriterion("resource_id not in", values, "resourceId");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andResourceIdBetween(Long value1, Long value2) {
|
public Criteria andResourceIdBetween(String value1, String value2) {
|
||||||
addCriterion("resource_id between", value1, value2, "resourceId");
|
addCriterion("resource_id between", value1, value2, "resourceId");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andResourceIdNotBetween(Long value1, Long value2) {
|
public Criteria andResourceIdNotBetween(String value1, String value2) {
|
||||||
addCriterion("resource_id not between", value1, value2, "resourceId");
|
addCriterion("resource_id not between", value1, value2, "resourceId");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
@ -844,73 +854,73 @@ public class ApiScenarioStepExample {
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceIsNull() {
|
public Criteria andRefTypeIsNull() {
|
||||||
addCriterion("`source` is null");
|
addCriterion("ref_type is null");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceIsNotNull() {
|
public Criteria andRefTypeIsNotNull() {
|
||||||
addCriterion("`source` is not null");
|
addCriterion("ref_type is not null");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceEqualTo(String value) {
|
public Criteria andRefTypeEqualTo(String value) {
|
||||||
addCriterion("`source` =", value, "source");
|
addCriterion("ref_type =", value, "refType");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceNotEqualTo(String value) {
|
public Criteria andRefTypeNotEqualTo(String value) {
|
||||||
addCriterion("`source` <>", value, "source");
|
addCriterion("ref_type <>", value, "refType");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceGreaterThan(String value) {
|
public Criteria andRefTypeGreaterThan(String value) {
|
||||||
addCriterion("`source` >", value, "source");
|
addCriterion("ref_type >", value, "refType");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceGreaterThanOrEqualTo(String value) {
|
public Criteria andRefTypeGreaterThanOrEqualTo(String value) {
|
||||||
addCriterion("`source` >=", value, "source");
|
addCriterion("ref_type >=", value, "refType");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceLessThan(String value) {
|
public Criteria andRefTypeLessThan(String value) {
|
||||||
addCriterion("`source` <", value, "source");
|
addCriterion("ref_type <", value, "refType");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceLessThanOrEqualTo(String value) {
|
public Criteria andRefTypeLessThanOrEqualTo(String value) {
|
||||||
addCriterion("`source` <=", value, "source");
|
addCriterion("ref_type <=", value, "refType");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceLike(String value) {
|
public Criteria andRefTypeLike(String value) {
|
||||||
addCriterion("`source` like", value, "source");
|
addCriterion("ref_type like", value, "refType");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceNotLike(String value) {
|
public Criteria andRefTypeNotLike(String value) {
|
||||||
addCriterion("`source` not like", value, "source");
|
addCriterion("ref_type not like", value, "refType");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceIn(List<String> values) {
|
public Criteria andRefTypeIn(List<String> values) {
|
||||||
addCriterion("`source` in", values, "source");
|
addCriterion("ref_type in", values, "refType");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceNotIn(List<String> values) {
|
public Criteria andRefTypeNotIn(List<String> values) {
|
||||||
addCriterion("`source` not in", values, "source");
|
addCriterion("ref_type not in", values, "refType");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceBetween(String value1, String value2) {
|
public Criteria andRefTypeBetween(String value1, String value2) {
|
||||||
addCriterion("`source` between", value1, value2, "source");
|
addCriterion("ref_type between", value1, value2, "refType");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Criteria andSourceNotBetween(String value1, String value2) {
|
public Criteria andRefTypeNotBetween(String value1, String value2) {
|
||||||
addCriterion("`source` not between", value1, value2, "source");
|
addCriterion("ref_type not between", value1, value2, "refType");
|
||||||
return (Criteria) this;
|
return (Criteria) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@ public interface ApiScenarioStepBlobMapper {
|
||||||
|
|
||||||
int updateByPrimaryKeyWithBLOBs(ApiScenarioStepBlob record);
|
int updateByPrimaryKeyWithBLOBs(ApiScenarioStepBlob record);
|
||||||
|
|
||||||
|
int updateByPrimaryKey(ApiScenarioStepBlob record);
|
||||||
|
|
||||||
int batchInsert(@Param("list") List<ApiScenarioStepBlob> list);
|
int batchInsert(@Param("list") List<ApiScenarioStepBlob> list);
|
||||||
|
|
||||||
int batchInsertSelective(@Param("list") List<ApiScenarioStepBlob> list, @Param("selective") ApiScenarioStepBlob.Column ... selective);
|
int batchInsertSelective(@Param("list") List<ApiScenarioStepBlob> list, @Param("selective") ApiScenarioStepBlob.Column ... selective);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
<mapper namespace="io.metersphere.api.mapper.ApiScenarioStepBlobMapper">
|
<mapper namespace="io.metersphere.api.mapper.ApiScenarioStepBlobMapper">
|
||||||
<resultMap id="BaseResultMap" type="io.metersphere.api.domain.ApiScenarioStepBlob">
|
<resultMap id="BaseResultMap" type="io.metersphere.api.domain.ApiScenarioStepBlob">
|
||||||
<id column="id" jdbcType="VARCHAR" property="id" />
|
<id column="id" jdbcType="VARCHAR" property="id" />
|
||||||
|
<result column="scenario_id" jdbcType="VARCHAR" property="scenarioId" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.api.domain.ApiScenarioStepBlob">
|
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.api.domain.ApiScenarioStepBlob">
|
||||||
<result column="content" jdbcType="LONGVARBINARY" property="content" />
|
<result column="content" jdbcType="LONGVARBINARY" property="content" />
|
||||||
|
@ -66,7 +67,7 @@
|
||||||
</where>
|
</where>
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id
|
id, scenario_id
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Blob_Column_List">
|
<sql id="Blob_Column_List">
|
||||||
content
|
content
|
||||||
|
@ -120,8 +121,10 @@
|
||||||
</if>
|
</if>
|
||||||
</delete>
|
</delete>
|
||||||
<insert id="insert" parameterType="io.metersphere.api.domain.ApiScenarioStepBlob">
|
<insert id="insert" parameterType="io.metersphere.api.domain.ApiScenarioStepBlob">
|
||||||
insert into api_scenario_step_blob (id, content)
|
insert into api_scenario_step_blob (id, scenario_id, content
|
||||||
values (#{id,jdbcType=VARCHAR}, #{content,jdbcType=LONGVARBINARY})
|
)
|
||||||
|
values (#{id,jdbcType=VARCHAR}, #{scenarioId,jdbcType=VARCHAR}, #{content,jdbcType=LONGVARBINARY}
|
||||||
|
)
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="insertSelective" parameterType="io.metersphere.api.domain.ApiScenarioStepBlob">
|
<insert id="insertSelective" parameterType="io.metersphere.api.domain.ApiScenarioStepBlob">
|
||||||
insert into api_scenario_step_blob
|
insert into api_scenario_step_blob
|
||||||
|
@ -129,6 +132,9 @@
|
||||||
<if test="id != null">
|
<if test="id != null">
|
||||||
id,
|
id,
|
||||||
</if>
|
</if>
|
||||||
|
<if test="scenarioId != null">
|
||||||
|
scenario_id,
|
||||||
|
</if>
|
||||||
<if test="content != null">
|
<if test="content != null">
|
||||||
content,
|
content,
|
||||||
</if>
|
</if>
|
||||||
|
@ -137,6 +143,9 @@
|
||||||
<if test="id != null">
|
<if test="id != null">
|
||||||
#{id,jdbcType=VARCHAR},
|
#{id,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="scenarioId != null">
|
||||||
|
#{scenarioId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="content != null">
|
<if test="content != null">
|
||||||
#{content,jdbcType=LONGVARBINARY},
|
#{content,jdbcType=LONGVARBINARY},
|
||||||
</if>
|
</if>
|
||||||
|
@ -154,6 +163,9 @@
|
||||||
<if test="record.id != null">
|
<if test="record.id != null">
|
||||||
id = #{record.id,jdbcType=VARCHAR},
|
id = #{record.id,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="record.scenarioId != null">
|
||||||
|
scenario_id = #{record.scenarioId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="record.content != null">
|
<if test="record.content != null">
|
||||||
content = #{record.content,jdbcType=LONGVARBINARY},
|
content = #{record.content,jdbcType=LONGVARBINARY},
|
||||||
</if>
|
</if>
|
||||||
|
@ -165,6 +177,7 @@
|
||||||
<update id="updateByExampleWithBLOBs" parameterType="map">
|
<update id="updateByExampleWithBLOBs" parameterType="map">
|
||||||
update api_scenario_step_blob
|
update api_scenario_step_blob
|
||||||
set id = #{record.id,jdbcType=VARCHAR},
|
set id = #{record.id,jdbcType=VARCHAR},
|
||||||
|
scenario_id = #{record.scenarioId,jdbcType=VARCHAR},
|
||||||
content = #{record.content,jdbcType=LONGVARBINARY}
|
content = #{record.content,jdbcType=LONGVARBINARY}
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
@ -172,7 +185,8 @@
|
||||||
</update>
|
</update>
|
||||||
<update id="updateByExample" parameterType="map">
|
<update id="updateByExample" parameterType="map">
|
||||||
update api_scenario_step_blob
|
update api_scenario_step_blob
|
||||||
set id = #{record.id,jdbcType=VARCHAR}
|
set id = #{record.id,jdbcType=VARCHAR},
|
||||||
|
scenario_id = #{record.scenarioId,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>
|
||||||
|
@ -180,6 +194,9 @@
|
||||||
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.api.domain.ApiScenarioStepBlob">
|
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.api.domain.ApiScenarioStepBlob">
|
||||||
update api_scenario_step_blob
|
update api_scenario_step_blob
|
||||||
<set>
|
<set>
|
||||||
|
<if test="scenarioId != null">
|
||||||
|
scenario_id = #{scenarioId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="content != null">
|
<if test="content != null">
|
||||||
content = #{content,jdbcType=LONGVARBINARY},
|
content = #{content,jdbcType=LONGVARBINARY},
|
||||||
</if>
|
</if>
|
||||||
|
@ -188,15 +205,22 @@
|
||||||
</update>
|
</update>
|
||||||
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.api.domain.ApiScenarioStepBlob">
|
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.api.domain.ApiScenarioStepBlob">
|
||||||
update api_scenario_step_blob
|
update api_scenario_step_blob
|
||||||
set content = #{content,jdbcType=LONGVARBINARY}
|
set scenario_id = #{scenarioId,jdbcType=VARCHAR},
|
||||||
|
content = #{content,jdbcType=LONGVARBINARY}
|
||||||
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
|
</update>
|
||||||
|
<update id="updateByPrimaryKey" parameterType="io.metersphere.api.domain.ApiScenarioStepBlob">
|
||||||
|
update api_scenario_step_blob
|
||||||
|
set scenario_id = #{scenarioId,jdbcType=VARCHAR}
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
</update>
|
</update>
|
||||||
<insert id="batchInsert" parameterType="map">
|
<insert id="batchInsert" parameterType="map">
|
||||||
insert into api_scenario_step_blob
|
insert into api_scenario_step_blob
|
||||||
(id, content)
|
(id, scenario_id, content)
|
||||||
values
|
values
|
||||||
<foreach collection="list" item="item" separator=",">
|
<foreach collection="list" item="item" separator=",">
|
||||||
(#{item.id,jdbcType=VARCHAR}, #{item.content,jdbcType=LONGVARBINARY})
|
(#{item.id,jdbcType=VARCHAR}, #{item.scenarioId,jdbcType=VARCHAR}, #{item.content,jdbcType=LONGVARBINARY}
|
||||||
|
)
|
||||||
</foreach>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="batchInsertSelective" parameterType="map">
|
<insert id="batchInsertSelective" parameterType="map">
|
||||||
|
@ -212,6 +236,9 @@
|
||||||
<if test="'id'.toString() == column.value">
|
<if test="'id'.toString() == column.value">
|
||||||
#{item.id,jdbcType=VARCHAR}
|
#{item.id,jdbcType=VARCHAR}
|
||||||
</if>
|
</if>
|
||||||
|
<if test="'scenario_id'.toString() == column.value">
|
||||||
|
#{item.scenarioId,jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
<if test="'content'.toString() == column.value">
|
<if test="'content'.toString() == column.value">
|
||||||
#{item.content,jdbcType=LONGVARBINARY}
|
#{item.content,jdbcType=LONGVARBINARY}
|
||||||
</if>
|
</if>
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||||
<result column="sort" jdbcType="BIGINT" property="sort" />
|
<result column="sort" jdbcType="BIGINT" property="sort" />
|
||||||
<result column="enable" jdbcType="BIT" property="enable" />
|
<result column="enable" jdbcType="BIT" property="enable" />
|
||||||
<result column="resource_id" jdbcType="BIGINT" property="resourceId" />
|
<result column="resource_id" jdbcType="VARCHAR" property="resourceId" />
|
||||||
<result column="resource_num" jdbcType="VARCHAR" property="resourceNum" />
|
<result column="resource_num" jdbcType="VARCHAR" property="resourceNum" />
|
||||||
<result column="step_type" jdbcType="VARCHAR" property="stepType" />
|
<result column="step_type" jdbcType="VARCHAR" property="stepType" />
|
||||||
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
|
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
|
||||||
<result column="parent_id" jdbcType="VARCHAR" property="parentId" />
|
<result column="parent_id" jdbcType="VARCHAR" property="parentId" />
|
||||||
<result column="version_id" jdbcType="VARCHAR" property="versionId" />
|
<result column="version_id" jdbcType="VARCHAR" property="versionId" />
|
||||||
<result column="source" jdbcType="VARCHAR" property="source" />
|
<result column="ref_type" jdbcType="VARCHAR" property="refType" />
|
||||||
<result column="config" jdbcType="VARCHAR" property="config" />
|
<result column="config" jdbcType="VARCHAR" property="config" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
<sql id="Example_Where_Clause">
|
<sql id="Example_Where_Clause">
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
</sql>
|
</sql>
|
||||||
<sql id="Base_Column_List">
|
<sql id="Base_Column_List">
|
||||||
id, scenario_id, `name`, sort, `enable`, resource_id, resource_num, step_type, project_id,
|
id, scenario_id, `name`, sort, `enable`, resource_id, resource_num, step_type, project_id,
|
||||||
parent_id, version_id, `source`, config
|
parent_id, version_id, ref_type, config
|
||||||
</sql>
|
</sql>
|
||||||
<select id="selectByExample" parameterType="io.metersphere.api.domain.ApiScenarioStepExample" resultMap="BaseResultMap">
|
<select id="selectByExample" parameterType="io.metersphere.api.domain.ApiScenarioStepExample" resultMap="BaseResultMap">
|
||||||
select
|
select
|
||||||
|
@ -112,12 +112,12 @@
|
||||||
insert into api_scenario_step (id, scenario_id, `name`,
|
insert into api_scenario_step (id, scenario_id, `name`,
|
||||||
sort, `enable`, resource_id,
|
sort, `enable`, resource_id,
|
||||||
resource_num, step_type, project_id,
|
resource_num, step_type, project_id,
|
||||||
parent_id, version_id, `source`,
|
parent_id, version_id, ref_type,
|
||||||
config)
|
config)
|
||||||
values (#{id,jdbcType=VARCHAR}, #{scenarioId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
|
values (#{id,jdbcType=VARCHAR}, #{scenarioId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
|
||||||
#{sort,jdbcType=BIGINT}, #{enable,jdbcType=BIT}, #{resourceId,jdbcType=BIGINT},
|
#{sort,jdbcType=BIGINT}, #{enable,jdbcType=BIT}, #{resourceId,jdbcType=VARCHAR},
|
||||||
#{resourceNum,jdbcType=VARCHAR}, #{stepType,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR},
|
#{resourceNum,jdbcType=VARCHAR}, #{stepType,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR},
|
||||||
#{parentId,jdbcType=VARCHAR}, #{versionId,jdbcType=VARCHAR}, #{source,jdbcType=VARCHAR},
|
#{parentId,jdbcType=VARCHAR}, #{versionId,jdbcType=VARCHAR}, #{refType,jdbcType=VARCHAR},
|
||||||
#{config,jdbcType=VARCHAR})
|
#{config,jdbcType=VARCHAR})
|
||||||
</insert>
|
</insert>
|
||||||
<insert id="insertSelective" parameterType="io.metersphere.api.domain.ApiScenarioStep">
|
<insert id="insertSelective" parameterType="io.metersphere.api.domain.ApiScenarioStep">
|
||||||
|
@ -156,8 +156,8 @@
|
||||||
<if test="versionId != null">
|
<if test="versionId != null">
|
||||||
version_id,
|
version_id,
|
||||||
</if>
|
</if>
|
||||||
<if test="source != null">
|
<if test="refType != null">
|
||||||
`source`,
|
ref_type,
|
||||||
</if>
|
</if>
|
||||||
<if test="config != null">
|
<if test="config != null">
|
||||||
config,
|
config,
|
||||||
|
@ -180,7 +180,7 @@
|
||||||
#{enable,jdbcType=BIT},
|
#{enable,jdbcType=BIT},
|
||||||
</if>
|
</if>
|
||||||
<if test="resourceId != null">
|
<if test="resourceId != null">
|
||||||
#{resourceId,jdbcType=BIGINT},
|
#{resourceId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="resourceNum != null">
|
<if test="resourceNum != null">
|
||||||
#{resourceNum,jdbcType=VARCHAR},
|
#{resourceNum,jdbcType=VARCHAR},
|
||||||
|
@ -197,8 +197,8 @@
|
||||||
<if test="versionId != null">
|
<if test="versionId != null">
|
||||||
#{versionId,jdbcType=VARCHAR},
|
#{versionId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="source != null">
|
<if test="refType != null">
|
||||||
#{source,jdbcType=VARCHAR},
|
#{refType,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="config != null">
|
<if test="config != null">
|
||||||
#{config,jdbcType=VARCHAR},
|
#{config,jdbcType=VARCHAR},
|
||||||
|
@ -230,7 +230,7 @@
|
||||||
`enable` = #{record.enable,jdbcType=BIT},
|
`enable` = #{record.enable,jdbcType=BIT},
|
||||||
</if>
|
</if>
|
||||||
<if test="record.resourceId != null">
|
<if test="record.resourceId != null">
|
||||||
resource_id = #{record.resourceId,jdbcType=BIGINT},
|
resource_id = #{record.resourceId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="record.resourceNum != null">
|
<if test="record.resourceNum != null">
|
||||||
resource_num = #{record.resourceNum,jdbcType=VARCHAR},
|
resource_num = #{record.resourceNum,jdbcType=VARCHAR},
|
||||||
|
@ -247,8 +247,8 @@
|
||||||
<if test="record.versionId != null">
|
<if test="record.versionId != null">
|
||||||
version_id = #{record.versionId,jdbcType=VARCHAR},
|
version_id = #{record.versionId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="record.source != null">
|
<if test="record.refType != null">
|
||||||
`source` = #{record.source,jdbcType=VARCHAR},
|
ref_type = #{record.refType,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="record.config != null">
|
<if test="record.config != null">
|
||||||
config = #{record.config,jdbcType=VARCHAR},
|
config = #{record.config,jdbcType=VARCHAR},
|
||||||
|
@ -265,13 +265,13 @@
|
||||||
`name` = #{record.name,jdbcType=VARCHAR},
|
`name` = #{record.name,jdbcType=VARCHAR},
|
||||||
sort = #{record.sort,jdbcType=BIGINT},
|
sort = #{record.sort,jdbcType=BIGINT},
|
||||||
`enable` = #{record.enable,jdbcType=BIT},
|
`enable` = #{record.enable,jdbcType=BIT},
|
||||||
resource_id = #{record.resourceId,jdbcType=BIGINT},
|
resource_id = #{record.resourceId,jdbcType=VARCHAR},
|
||||||
resource_num = #{record.resourceNum,jdbcType=VARCHAR},
|
resource_num = #{record.resourceNum,jdbcType=VARCHAR},
|
||||||
step_type = #{record.stepType,jdbcType=VARCHAR},
|
step_type = #{record.stepType,jdbcType=VARCHAR},
|
||||||
project_id = #{record.projectId,jdbcType=VARCHAR},
|
project_id = #{record.projectId,jdbcType=VARCHAR},
|
||||||
parent_id = #{record.parentId,jdbcType=VARCHAR},
|
parent_id = #{record.parentId,jdbcType=VARCHAR},
|
||||||
version_id = #{record.versionId,jdbcType=VARCHAR},
|
version_id = #{record.versionId,jdbcType=VARCHAR},
|
||||||
`source` = #{record.source,jdbcType=VARCHAR},
|
ref_type = #{record.refType,jdbcType=VARCHAR},
|
||||||
config = #{record.config,jdbcType=VARCHAR}
|
config = #{record.config,jdbcType=VARCHAR}
|
||||||
<if test="_parameter != null">
|
<if test="_parameter != null">
|
||||||
<include refid="Update_By_Example_Where_Clause" />
|
<include refid="Update_By_Example_Where_Clause" />
|
||||||
|
@ -293,7 +293,7 @@
|
||||||
`enable` = #{enable,jdbcType=BIT},
|
`enable` = #{enable,jdbcType=BIT},
|
||||||
</if>
|
</if>
|
||||||
<if test="resourceId != null">
|
<if test="resourceId != null">
|
||||||
resource_id = #{resourceId,jdbcType=BIGINT},
|
resource_id = #{resourceId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="resourceNum != null">
|
<if test="resourceNum != null">
|
||||||
resource_num = #{resourceNum,jdbcType=VARCHAR},
|
resource_num = #{resourceNum,jdbcType=VARCHAR},
|
||||||
|
@ -310,8 +310,8 @@
|
||||||
<if test="versionId != null">
|
<if test="versionId != null">
|
||||||
version_id = #{versionId,jdbcType=VARCHAR},
|
version_id = #{versionId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="source != null">
|
<if test="refType != null">
|
||||||
`source` = #{source,jdbcType=VARCHAR},
|
ref_type = #{refType,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
<if test="config != null">
|
<if test="config != null">
|
||||||
config = #{config,jdbcType=VARCHAR},
|
config = #{config,jdbcType=VARCHAR},
|
||||||
|
@ -325,26 +325,26 @@
|
||||||
`name` = #{name,jdbcType=VARCHAR},
|
`name` = #{name,jdbcType=VARCHAR},
|
||||||
sort = #{sort,jdbcType=BIGINT},
|
sort = #{sort,jdbcType=BIGINT},
|
||||||
`enable` = #{enable,jdbcType=BIT},
|
`enable` = #{enable,jdbcType=BIT},
|
||||||
resource_id = #{resourceId,jdbcType=BIGINT},
|
resource_id = #{resourceId,jdbcType=VARCHAR},
|
||||||
resource_num = #{resourceNum,jdbcType=VARCHAR},
|
resource_num = #{resourceNum,jdbcType=VARCHAR},
|
||||||
step_type = #{stepType,jdbcType=VARCHAR},
|
step_type = #{stepType,jdbcType=VARCHAR},
|
||||||
project_id = #{projectId,jdbcType=VARCHAR},
|
project_id = #{projectId,jdbcType=VARCHAR},
|
||||||
parent_id = #{parentId,jdbcType=VARCHAR},
|
parent_id = #{parentId,jdbcType=VARCHAR},
|
||||||
version_id = #{versionId,jdbcType=VARCHAR},
|
version_id = #{versionId,jdbcType=VARCHAR},
|
||||||
`source` = #{source,jdbcType=VARCHAR},
|
ref_type = #{refType,jdbcType=VARCHAR},
|
||||||
config = #{config,jdbcType=VARCHAR}
|
config = #{config,jdbcType=VARCHAR}
|
||||||
where id = #{id,jdbcType=VARCHAR}
|
where id = #{id,jdbcType=VARCHAR}
|
||||||
</update>
|
</update>
|
||||||
<insert id="batchInsert" parameterType="map">
|
<insert id="batchInsert" parameterType="map">
|
||||||
insert into api_scenario_step
|
insert into api_scenario_step
|
||||||
(id, scenario_id, `name`, sort, `enable`, resource_id, resource_num, step_type, project_id,
|
(id, scenario_id, `name`, sort, `enable`, resource_id, resource_num, step_type, project_id,
|
||||||
parent_id, version_id, `source`, config)
|
parent_id, version_id, ref_type, config)
|
||||||
values
|
values
|
||||||
<foreach collection="list" item="item" separator=",">
|
<foreach collection="list" item="item" separator=",">
|
||||||
(#{item.id,jdbcType=VARCHAR}, #{item.scenarioId,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR},
|
(#{item.id,jdbcType=VARCHAR}, #{item.scenarioId,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR},
|
||||||
#{item.sort,jdbcType=BIGINT}, #{item.enable,jdbcType=BIT}, #{item.resourceId,jdbcType=BIGINT},
|
#{item.sort,jdbcType=BIGINT}, #{item.enable,jdbcType=BIT}, #{item.resourceId,jdbcType=VARCHAR},
|
||||||
#{item.resourceNum,jdbcType=VARCHAR}, #{item.stepType,jdbcType=VARCHAR}, #{item.projectId,jdbcType=VARCHAR},
|
#{item.resourceNum,jdbcType=VARCHAR}, #{item.stepType,jdbcType=VARCHAR}, #{item.projectId,jdbcType=VARCHAR},
|
||||||
#{item.parentId,jdbcType=VARCHAR}, #{item.versionId,jdbcType=VARCHAR}, #{item.source,jdbcType=VARCHAR},
|
#{item.parentId,jdbcType=VARCHAR}, #{item.versionId,jdbcType=VARCHAR}, #{item.refType,jdbcType=VARCHAR},
|
||||||
#{item.config,jdbcType=VARCHAR})
|
#{item.config,jdbcType=VARCHAR})
|
||||||
</foreach>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
|
@ -374,7 +374,7 @@
|
||||||
#{item.enable,jdbcType=BIT}
|
#{item.enable,jdbcType=BIT}
|
||||||
</if>
|
</if>
|
||||||
<if test="'resource_id'.toString() == column.value">
|
<if test="'resource_id'.toString() == column.value">
|
||||||
#{item.resourceId,jdbcType=BIGINT}
|
#{item.resourceId,jdbcType=VARCHAR}
|
||||||
</if>
|
</if>
|
||||||
<if test="'resource_num'.toString() == column.value">
|
<if test="'resource_num'.toString() == column.value">
|
||||||
#{item.resourceNum,jdbcType=VARCHAR}
|
#{item.resourceNum,jdbcType=VARCHAR}
|
||||||
|
@ -391,8 +391,8 @@
|
||||||
<if test="'version_id'.toString() == column.value">
|
<if test="'version_id'.toString() == column.value">
|
||||||
#{item.versionId,jdbcType=VARCHAR}
|
#{item.versionId,jdbcType=VARCHAR}
|
||||||
</if>
|
</if>
|
||||||
<if test="'source'.toString() == column.value">
|
<if test="'ref_type'.toString() == column.value">
|
||||||
#{item.source,jdbcType=VARCHAR}
|
#{item.refType,jdbcType=VARCHAR}
|
||||||
</if>
|
</if>
|
||||||
<if test="'config'.toString() == column.value">
|
<if test="'config'.toString() == column.value">
|
||||||
#{item.config,jdbcType=VARCHAR}
|
#{item.config,jdbcType=VARCHAR}
|
||||||
|
|
|
@ -275,13 +275,13 @@ CREATE TABLE IF NOT EXISTS api_scenario_step(
|
||||||
`name` VARCHAR(255) COMMENT '步骤名称' ,
|
`name` VARCHAR(255) COMMENT '步骤名称' ,
|
||||||
`sort` BIGINT NOT NULL COMMENT '序号' ,
|
`sort` BIGINT NOT NULL COMMENT '序号' ,
|
||||||
`enable` BIT(1) NOT NULL DEFAULT 1 COMMENT '启用/禁用' ,
|
`enable` BIT(1) NOT NULL DEFAULT 1 COMMENT '启用/禁用' ,
|
||||||
`resource_id` BIGINT COMMENT '资源id' ,
|
`resource_id` VARCHAR(50) COMMENT '资源id' ,
|
||||||
`resource_num` VARCHAR(50) COMMENT '资源编号' ,
|
`resource_num` VARCHAR(50) COMMENT '资源编号' ,
|
||||||
`step_type` VARCHAR(50) COMMENT '步骤类型/API/CASE等' ,
|
`step_type` VARCHAR(50) COMMENT '步骤类型/API/CASE等' ,
|
||||||
`project_id` VARCHAR(50) COMMENT '项目fk' ,
|
`project_id` VARCHAR(50) COMMENT '项目fk' ,
|
||||||
`parent_id` VARCHAR(50) DEFAULT 'NONE' COMMENT '父级fk' ,
|
`parent_id` VARCHAR(50) DEFAULT 'NONE' COMMENT '父级fk' ,
|
||||||
`version_id` VARCHAR(50) COMMENT '版本号' ,
|
`version_id` VARCHAR(50) COMMENT '版本号' ,
|
||||||
`source` VARCHAR(10) COMMENT '引用/复制/自定义' ,
|
`ref_type` VARCHAR(10) COMMENT '引用/复制/自定义' ,
|
||||||
`config` VARCHAR(500) COMMENT '循环等组件基础数据' ,
|
`config` VARCHAR(500) COMMENT '循环等组件基础数据' ,
|
||||||
PRIMARY KEY (id)
|
PRIMARY KEY (id)
|
||||||
) ENGINE = InnoDB
|
) ENGINE = InnoDB
|
||||||
|
@ -296,12 +296,15 @@ CREATE INDEX idx_resource_num ON api_scenario_step(resource_num);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS api_scenario_step_blob(
|
CREATE TABLE IF NOT EXISTS api_scenario_step_blob(
|
||||||
`id` VARCHAR(50) NOT NULL COMMENT '场景步骤id' ,
|
`id` VARCHAR(50) NOT NULL COMMENT '场景步骤id' ,
|
||||||
|
`scenario_id` VARCHAR(50) NOT NULL COMMENT '场景id' ,
|
||||||
`content` LONGBLOB COMMENT '场景步骤内容' ,
|
`content` LONGBLOB COMMENT '场景步骤内容' ,
|
||||||
PRIMARY KEY (id)
|
PRIMARY KEY (id)
|
||||||
) ENGINE = InnoDB
|
) ENGINE = InnoDB
|
||||||
DEFAULT CHARSET = utf8mb4
|
DEFAULT CHARSET = utf8mb4
|
||||||
COLLATE = utf8mb4_general_ci COMMENT = '场景步骤内容';
|
COLLATE = utf8mb4_general_ci COMMENT = '场景步骤内容';
|
||||||
|
|
||||||
|
CREATE INDEX idx_scenario_id ON api_scenario_step_blob(scenario_id);
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS api_scenario_follower(
|
CREATE TABLE IF NOT EXISTS api_scenario_follower(
|
||||||
`api_scenario_id` VARCHAR(50) NOT NULL COMMENT '场景fk' ,
|
`api_scenario_id` VARCHAR(50) NOT NULL COMMENT '场景fk' ,
|
||||||
|
|
|
@ -54,6 +54,7 @@ public class DefaultRepositoryDir {
|
||||||
* project/{projectId}/api-debug/{apiDebugId}
|
* project/{projectId}/api-debug/{apiDebugId}
|
||||||
*/
|
*/
|
||||||
private static final String PROJECT_API_DEBUG_DIR = PROJECT_DIR + "/api-debug/%s";
|
private static final String PROJECT_API_DEBUG_DIR = PROJECT_DIR + "/api-debug/%s";
|
||||||
|
private static final String PROJECT_API_SCENARIO_DIR = PROJECT_DIR + "/api-scenario/%s";
|
||||||
private static final String PROJECT_BUG_DIR = PROJECT_DIR + "/bug/%s";
|
private static final String PROJECT_BUG_DIR = PROJECT_DIR + "/bug/%s";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,4 +113,8 @@ public class DefaultRepositoryDir {
|
||||||
public static String getSystemTempDir() {
|
public static String getSystemTempDir() {
|
||||||
return SYSTEM_TEMP_DIR;
|
return SYSTEM_TEMP_DIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getApiScenarioDir(String projectId, String apiScenarioId) {
|
||||||
|
return String.format(PROJECT_API_SCENARIO_DIR, projectId, apiScenarioId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ public class FileAssociationSourceUtil {
|
||||||
public static final String SOURCE_TYPE_BUG = "BUG";
|
public static final String SOURCE_TYPE_BUG = "BUG";
|
||||||
public static final String SOURCE_TYPE_FUNCTIONAL_CASE = "FUNCTIONAL_CASE";
|
public static final String SOURCE_TYPE_FUNCTIONAL_CASE = "FUNCTIONAL_CASE";
|
||||||
public static final String SOURCE_TYPE_API_DEBUG = "API_DEBUG";
|
public static final String SOURCE_TYPE_API_DEBUG = "API_DEBUG";
|
||||||
|
public static final String SOURCE_TYPE_API_SCENARIO= "API_SCENARIO";
|
||||||
public static final String SOURCE_TYPE_API_TEST_CASE = "API_TEST_CASE";
|
public static final String SOURCE_TYPE_API_TEST_CASE = "API_TEST_CASE";
|
||||||
public static final String SOURCE_TYPE_API_DEFINITION = "API_DEFINITION";
|
public static final String SOURCE_TYPE_API_DEFINITION = "API_DEFINITION";
|
||||||
public static final String SOURCE_TYPE_API_DEFINITION_MOCK = "API_DEFINITION_MOCK";
|
public static final String SOURCE_TYPE_API_DEFINITION_MOCK = "API_DEFINITION_MOCK";
|
||||||
|
@ -23,6 +24,7 @@ public class FileAssociationSourceUtil {
|
||||||
QUERY_SQL.put(SOURCE_TYPE_BUG, "SELECT id AS sourceId,title AS sourceName FROM bug");
|
QUERY_SQL.put(SOURCE_TYPE_BUG, "SELECT id AS sourceId,title AS sourceName FROM bug");
|
||||||
QUERY_SQL.put(SOURCE_TYPE_FUNCTIONAL_CASE, "SELECT id AS sourceId,name AS sourceName FROM functional_case");
|
QUERY_SQL.put(SOURCE_TYPE_FUNCTIONAL_CASE, "SELECT id AS sourceId,name AS sourceName FROM functional_case");
|
||||||
QUERY_SQL.put(SOURCE_TYPE_API_DEBUG, "SELECT id AS sourceId,name AS sourceName FROM api_debug");
|
QUERY_SQL.put(SOURCE_TYPE_API_DEBUG, "SELECT id AS sourceId,name AS sourceName FROM api_debug");
|
||||||
|
QUERY_SQL.put(SOURCE_TYPE_API_SCENARIO, "SELECT id AS sourceId,name AS sourceName FROM api_scenario");
|
||||||
QUERY_SQL.put(SOURCE_TYPE_API_TEST_CASE, "SELECT id AS sourceId,name AS sourceName FROM api_test_case");
|
QUERY_SQL.put(SOURCE_TYPE_API_TEST_CASE, "SELECT id AS sourceId,name AS sourceName FROM api_test_case");
|
||||||
QUERY_SQL.put(SOURCE_TYPE_API_DEFINITION, "SELECT id AS sourceId,name AS sourceName FROM api_definition");
|
QUERY_SQL.put(SOURCE_TYPE_API_DEFINITION, "SELECT id AS sourceId,name AS sourceName FROM api_definition");
|
||||||
QUERY_SQL.put(SOURCE_TYPE_API_DEFINITION_MOCK, "SELECT id AS sourceId,name AS sourceName FROM api_definition_mock");
|
QUERY_SQL.put(SOURCE_TYPE_API_DEFINITION_MOCK, "SELECT id AS sourceId,name AS sourceName FROM api_definition_mock");
|
||||||
|
|
|
@ -21,6 +21,7 @@ api_definition_template.create_user.not_blank=创建人不能为空
|
||||||
api_definition_template.project_id.length_range=项目ID长度必须在1-50之间
|
api_definition_template.project_id.length_range=项目ID长度必须在1-50之间
|
||||||
api_definition_template.project_id.not_blank=项目ID不能为空
|
api_definition_template.project_id.not_blank=项目ID不能为空
|
||||||
#module:ApiScenario
|
#module:ApiScenario
|
||||||
|
permission.system_api_scenario.name=场景
|
||||||
api_scenario.id.not_blank=不能为空
|
api_scenario.id.not_blank=不能为空
|
||||||
api_scenario.name.length_range=场景名称长度必须在1-200之间
|
api_scenario.name.length_range=场景名称长度必须在1-200之间
|
||||||
api_scenario.name.not_blank=场景名称不能为空
|
api_scenario.name.not_blank=场景名称不能为空
|
||||||
|
@ -314,5 +315,6 @@ api_definition_mock_exist=接口 MOCK 已存在
|
||||||
execute_resource_pool_not_config_error=请在【项目管理-应用管理-接口测试】中选择资源池
|
execute_resource_pool_not_config_error=请在【项目管理-应用管理-接口测试】中选择资源池
|
||||||
resource_pool_execute_error=资源池调用失败
|
resource_pool_execute_error=资源池调用失败
|
||||||
api_swagger_url_error=Swagger url无法连通
|
api_swagger_url_error=Swagger url无法连通
|
||||||
|
api_scenario_exist=场景已存在
|
||||||
schedule_not_exist=定时任务不存在
|
schedule_not_exist=定时任务不存在
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ api_definition_template.create_user.not_blank=Creator cannot be empty
|
||||||
api_definition_template.project_id.length_range=Item fk length must be between 1-50
|
api_definition_template.project_id.length_range=Item fk length must be between 1-50
|
||||||
api_definition_template.project_id.not_blank=Item fk cannot be empty
|
api_definition_template.project_id.not_blank=Item fk cannot be empty
|
||||||
#module:ApiScenario
|
#module:ApiScenario
|
||||||
|
permission.system_api_scenario.name=Scenario
|
||||||
api_scenario.id.not_blank=Can not be empty
|
api_scenario.id.not_blank=Can not be empty
|
||||||
api_scenario.name.length_range=The scene name length must be between 1-200
|
api_scenario.name.length_range=The scene name length must be between 1-200
|
||||||
api_scenario.name.not_blank=Scene name cannot be empty
|
api_scenario.name.not_blank=Scene name cannot be empty
|
||||||
|
@ -48,6 +49,7 @@ api_scenario_step.id.length_range=Step ID length must be between 1-50
|
||||||
api_scenario_step.scenario_id.not_blank=Scene ID cannot be empty
|
api_scenario_step.scenario_id.not_blank=Scene ID cannot be empty
|
||||||
api_scenario_step.scenario_id.length_range=Scene ID length must be between 1-50
|
api_scenario_step.scenario_id.length_range=Scene ID length must be between 1-50
|
||||||
api_scenario_step.sort.not_blank=SORT cannot be empty
|
api_scenario_step.sort.not_blank=SORT cannot be empty
|
||||||
|
|
||||||
#module:ApiTestCaseFollow
|
#module:ApiTestCaseFollow
|
||||||
api_test_case_follow.case_id.length_range=Use case fk length must be between 1-50
|
api_test_case_follow.case_id.length_range=Use case fk length must be between 1-50
|
||||||
api_test_case_follow.case_id.not_blank=Use case fk cannot be empty
|
api_test_case_follow.case_id.not_blank=Use case fk cannot be empty
|
||||||
|
@ -318,4 +320,5 @@ api_definition_mock_exist=The API MOCK already exists
|
||||||
execute_resource_pool_not_config_error=Select a resource pool in 【Project Management - Application Management - Interface Testing】
|
execute_resource_pool_not_config_error=Select a resource pool in 【Project Management - Application Management - Interface Testing】
|
||||||
resource_pool_execute_error=The resource pool call failed
|
resource_pool_execute_error=The resource pool call failed
|
||||||
api_swagger_url_error=Swagger url unable to connect
|
api_swagger_url_error=Swagger url unable to connect
|
||||||
|
api_scenario_exist=The scenario already exists
|
||||||
schedule_not_exist=The scheduled task does not exist
|
schedule_not_exist=The scheduled task does not exist
|
|
@ -21,6 +21,7 @@ api_definition_template.create_user.not_blank=创建人不能为空
|
||||||
api_definition_template.project_id.length_range=项目ID长度必须在1-50之间
|
api_definition_template.project_id.length_range=项目ID长度必须在1-50之间
|
||||||
api_definition_template.project_id.not_blank=项目ID不能为空
|
api_definition_template.project_id.not_blank=项目ID不能为空
|
||||||
#module:ApiScenario
|
#module:ApiScenario
|
||||||
|
permission.system_api_scenario.name=场景
|
||||||
api_scenario.id.not_blank=不能为空
|
api_scenario.id.not_blank=不能为空
|
||||||
api_scenario.name.length_range=场景名称长度必须在1-200之间
|
api_scenario.name.length_range=场景名称长度必须在1-200之间
|
||||||
api_scenario.name.not_blank=场景名称不能为空
|
api_scenario.name.not_blank=场景名称不能为空
|
||||||
|
@ -318,4 +319,5 @@ api_definition_mock_exist=接口 MOCK 已存在
|
||||||
execute_resource_pool_not_config_error=请在【项目管理-应用管理-接口测试】中选择资源池
|
execute_resource_pool_not_config_error=请在【项目管理-应用管理-接口测试】中选择资源池
|
||||||
resource_pool_execute_error=资源池调用失败
|
resource_pool_execute_error=资源池调用失败
|
||||||
api_swagger_url_error=Swagger url无法连通
|
api_swagger_url_error=Swagger url无法连通
|
||||||
|
api_scenario_exist=场景已存在
|
||||||
schedule_not_exist=定时任务不存在
|
schedule_not_exist=定时任务不存在
|
||||||
|
|
|
@ -21,6 +21,7 @@ api_definition_template.create_user.not_blank=創建人不能為空
|
||||||
api_definition_template.project_id.length_range=項目ID長度必須在1-50之間
|
api_definition_template.project_id.length_range=項目ID長度必須在1-50之間
|
||||||
api_definition_template.project_id.not_blank=項目ID不能為空
|
api_definition_template.project_id.not_blank=項目ID不能為空
|
||||||
#module:ApiScenario
|
#module:ApiScenario
|
||||||
|
permission.system_api_scenario.name=场景
|
||||||
api_scenario.id.not_blank=不能為空
|
api_scenario.id.not_blank=不能為空
|
||||||
api_scenario.name.length_range=場景名稱長度必須在1-200之間
|
api_scenario.name.length_range=場景名稱長度必須在1-200之間
|
||||||
api_scenario.name.not_blank=場景名稱不能為空
|
api_scenario.name.not_blank=場景名稱不能為空
|
||||||
|
@ -318,4 +319,5 @@ api_definition_mock_exist=接口 MOCK 已存在
|
||||||
execute_resource_pool_not_config_error=請在【項目管理-應用管理-接口測試】中選擇資源池
|
execute_resource_pool_not_config_error=請在【項目管理-應用管理-接口測試】中選擇資源池
|
||||||
resource_pool_execute_error=資源池調用失敗
|
resource_pool_execute_error=資源池調用失敗
|
||||||
api_swagger_url_error=Swagger url無法調解
|
api_swagger_url_error=Swagger url無法調解
|
||||||
|
api_scenario_exist=場景已存在
|
||||||
schedule_not_exist=定時任務不存在
|
schedule_not_exist=定時任務不存在
|
|
@ -0,0 +1,20 @@
|
||||||
|
package io.metersphere.api.constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-11 17:31
|
||||||
|
*/
|
||||||
|
public enum ApiScenarioStatus {
|
||||||
|
/**
|
||||||
|
* 进行中
|
||||||
|
*/
|
||||||
|
UNDERWAY,
|
||||||
|
/**
|
||||||
|
* 已完成
|
||||||
|
*/
|
||||||
|
COMPLETED,
|
||||||
|
/**
|
||||||
|
* 已废弃
|
||||||
|
*/
|
||||||
|
DEPRECATED
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package io.metersphere.api.constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-10 11:24
|
||||||
|
*/
|
||||||
|
public enum ApiScenarioStepRefType {
|
||||||
|
/**
|
||||||
|
* 在场景中直接创建的步骤
|
||||||
|
* 例如 自定义请求,逻辑控制器
|
||||||
|
*/
|
||||||
|
DIRECT,
|
||||||
|
/**
|
||||||
|
* 引用
|
||||||
|
*/
|
||||||
|
REF,
|
||||||
|
/**
|
||||||
|
* 步骤引用
|
||||||
|
*/
|
||||||
|
STEP_REF,
|
||||||
|
/**
|
||||||
|
* 复制
|
||||||
|
*/
|
||||||
|
COPY
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package io.metersphere.api.constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 步骤的类型
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-10 11:24
|
||||||
|
*/
|
||||||
|
public enum ApiScenarioStepType {
|
||||||
|
/**
|
||||||
|
* 接口定义
|
||||||
|
*/
|
||||||
|
API,
|
||||||
|
/**
|
||||||
|
* 接口用例
|
||||||
|
*/
|
||||||
|
API_CASE,
|
||||||
|
/**
|
||||||
|
* 场景
|
||||||
|
*/
|
||||||
|
API_SCENARIO
|
||||||
|
// todo 逻辑控制器等
|
||||||
|
}
|
|
@ -13,7 +13,8 @@ public enum ApiResultCode implements IResultCode {
|
||||||
API_DEFINITION_MODULE_NOT_EXIST(10404, "resource_not_exist"),
|
API_DEFINITION_MODULE_NOT_EXIST(10404, "resource_not_exist"),
|
||||||
RESOURCE_POOL_EXECUTE_ERROR(104005, "resource_pool_execute_error"),
|
RESOURCE_POOL_EXECUTE_ERROR(104005, "resource_pool_execute_error"),
|
||||||
EXECUTE_RESOURCE_POOL_NOT_CONFIG(104006, "execute_resource_pool_not_config_error"),
|
EXECUTE_RESOURCE_POOL_NOT_CONFIG(104006, "execute_resource_pool_not_config_error"),
|
||||||
API_DEFINITION_MOCK_EXIST(104007, "api_definition_mock_exist");
|
API_DEFINITION_MOCK_EXIST(104007, "api_definition_mock_exist"),
|
||||||
|
API_SCENARIO_EXIST(104008, "api_scenario_exist");
|
||||||
|
|
||||||
|
|
||||||
private final int code;
|
private final int code;
|
||||||
|
|
|
@ -2,11 +2,13 @@ package io.metersphere.api.controller.scenario;
|
||||||
|
|
||||||
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.scenario.ApiScenarioBatchEditRequest;
|
import io.metersphere.api.domain.ApiScenario;
|
||||||
import io.metersphere.api.dto.scenario.ApiScenarioDTO;
|
import io.metersphere.api.dto.scenario.*;
|
||||||
import io.metersphere.api.dto.scenario.ApiScenarioPageRequest;
|
import io.metersphere.api.service.scenario.ApiScenarioLogService;
|
||||||
import io.metersphere.api.service.scenario.ApiScenarioService;
|
import io.metersphere.api.service.scenario.ApiScenarioService;
|
||||||
import io.metersphere.sdk.constants.PermissionConstants;
|
import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
|
import io.metersphere.system.log.annotation.Log;
|
||||||
|
import io.metersphere.system.log.constants.OperationLogType;
|
||||||
import io.metersphere.system.security.CheckOwner;
|
import io.metersphere.system.security.CheckOwner;
|
||||||
import io.metersphere.system.utils.PageUtils;
|
import io.metersphere.system.utils.PageUtils;
|
||||||
import io.metersphere.system.utils.Pager;
|
import io.metersphere.system.utils.Pager;
|
||||||
|
@ -15,9 +17,11 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.shiro.authz.annotation.Logical;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -65,4 +69,42 @@ public class ApiScenarioController {
|
||||||
apiScenarioService.follow(id, SessionUtils.getUserId());
|
apiScenarioService.follow(id, SessionUtils.getUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/add")
|
||||||
|
@Operation(summary = "创建场景")
|
||||||
|
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_ADD)
|
||||||
|
@Log(type = OperationLogType.ADD, expression = "#msClass.addLog(#request)", msClass = ApiScenarioLogService.class)
|
||||||
|
public ApiScenario add(@Validated @RequestBody ApiScenarioAddRequest request) {
|
||||||
|
return apiScenarioService.add(request, SessionUtils.getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/upload/temp/file")
|
||||||
|
@Operation(summary = "上传场景所需的文件资源,并返回文件ID")
|
||||||
|
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_API_SCENARIO_ADD, PermissionConstants.PROJECT_API_SCENARIO_UPDATE})
|
||||||
|
public String uploadTempFile(@RequestParam("file") MultipartFile file) {
|
||||||
|
return apiScenarioService.uploadTempFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/update")
|
||||||
|
@Operation(summary = "更新场景")
|
||||||
|
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_UPDATE)
|
||||||
|
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#request)", msClass = ApiScenarioLogService.class)
|
||||||
|
public ApiScenario update(@Validated @RequestBody ApiScenarioUpdateRequest request) {
|
||||||
|
return apiScenarioService.update(request, SessionUtils.getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/delete/{id}")
|
||||||
|
@Operation(summary = "删除场景")
|
||||||
|
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_DELETE)
|
||||||
|
@Log(type = OperationLogType.DELETE, expression = "#msClass.deleteLog(#id)", msClass = ApiScenarioLogService.class)
|
||||||
|
public void delete(@PathVariable String id) {
|
||||||
|
apiScenarioService.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/delete-to-gc/{id}")
|
||||||
|
@Operation(summary = "删除场景到回收站")
|
||||||
|
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_DELETE)
|
||||||
|
@Log(type = OperationLogType.DELETE, expression = "#msClass.deleteLog(#id)", msClass = ApiScenarioLogService.class)
|
||||||
|
public void deleteToGc(@PathVariable String id) {
|
||||||
|
apiScenarioService.deleteToGc(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package io.metersphere.api.dto.request.http.body;
|
package io.metersphere.api.dto;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class BodyFile {
|
public class ApiFile {
|
||||||
/**
|
/**
|
||||||
* 记录文件的ID,防止重名
|
* 记录文件的ID,防止重名
|
||||||
* 生成脚本时,通过 fileId + value(文件名) 获取文件路径
|
* 生成脚本时,通过 fileId + value(文件名) 获取文件路径
|
|
@ -1,5 +1,6 @@
|
||||||
package io.metersphere.api.dto.request.http.body;
|
package io.metersphere.api.dto.request.http.body;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.ApiFile;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,6 +9,6 @@ import lombok.Data;
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class BinaryBody {
|
public class BinaryBody {
|
||||||
private BodyFile bodyFile;
|
private ApiFile bodyFile;
|
||||||
private String description;
|
private String description;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package io.metersphere.api.dto.request.http.body;
|
package io.metersphere.api.dto.request.http.body;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.ApiFile;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
@ -12,7 +13,7 @@ import java.util.List;
|
||||||
@Data
|
@Data
|
||||||
public class FormDataKV extends WWWFormKV {
|
public class FormDataKV extends WWWFormKV {
|
||||||
|
|
||||||
private List<BodyFile> files;
|
private List<ApiFile> files;
|
||||||
|
|
||||||
public boolean isFile() {
|
public boolean isFile() {
|
||||||
return StringUtils.equalsIgnoreCase(getParamType(), WWWFormParamType.FILE.name());
|
return StringUtils.equalsIgnoreCase(getParamType(), WWWFormParamType.FILE.name());
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
package io.metersphere.api.dto.scenario;
|
||||||
|
|
||||||
|
import io.metersphere.api.constants.ApiScenarioStatus;
|
||||||
|
import io.metersphere.system.valid.EnumValue;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-10 11:24
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ApiScenarioAddRequest {
|
||||||
|
@Schema(description = "场景名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_scenario.name.not_blank}")
|
||||||
|
@Size(min = 1, max = 255, message = "{api_scenario.name.length_range}")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "场景级别/P0/P1等", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_scenario.priority.not_blank}")
|
||||||
|
@Size(min = 1, max = 10, message = "{api_scenario.priority.length_range}")
|
||||||
|
private String priority;
|
||||||
|
|
||||||
|
@Schema(description = "场景状态/未规划/已完成 等", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_scenario.status.not_blank}")
|
||||||
|
@Size(min = 1, max = 20, message = "{api_scenario.status.length_range}")
|
||||||
|
@EnumValue(enumClass = ApiScenarioStatus.class)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "项目fk", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_scenario.project_id.not_blank}")
|
||||||
|
@Size(min = 1, max = 50, message = "{api_scenario.project_id.length_range}")
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
|
@Schema(description = "场景模块fk")
|
||||||
|
@NotBlank(message = "{api_debug.module_id.not_blank}")
|
||||||
|
private String moduleId;
|
||||||
|
|
||||||
|
@Schema(description = "描述信息")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "标签")
|
||||||
|
private List<String> tags;
|
||||||
|
|
||||||
|
@Schema(description = "是否为环境组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Boolean grouped;
|
||||||
|
|
||||||
|
@Schema(description = "环境或者环境组ID")
|
||||||
|
private String environmentId;
|
||||||
|
|
||||||
|
@Schema(description = "场景的通用配置")
|
||||||
|
private ScenarioConfig scenarioConfig;
|
||||||
|
|
||||||
|
@Schema(description = "步骤集合")
|
||||||
|
private List<ApiScenarioStepRequest> steps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 步骤详情
|
||||||
|
* key 为步骤ID
|
||||||
|
* 值 为详情
|
||||||
|
*/
|
||||||
|
@Schema(description = "步骤详情")
|
||||||
|
private Map<String, Object> stepDetails;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新上传的文件ID
|
||||||
|
* 创建时先按ID创建目录,再把文件放入目录
|
||||||
|
*/
|
||||||
|
@Schema(description = "新上传的文件ID")
|
||||||
|
private List<String> uploadFileIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新关联的文件ID
|
||||||
|
*/
|
||||||
|
@Schema(description = "关联文件ID")
|
||||||
|
private List<String> linkFileIds;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package io.metersphere.api.dto.scenario;
|
||||||
|
|
||||||
|
import io.metersphere.api.domain.ApiScenario;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ApiScenarioSimpleDTO extends ApiScenario {
|
||||||
|
|
||||||
|
@Schema(description = "更新人名称")
|
||||||
|
private String updateUserName;
|
||||||
|
@Schema(description = "创建人名称")
|
||||||
|
private String createUserName;
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package io.metersphere.api.dto.scenario;
|
||||||
|
|
||||||
|
import io.metersphere.api.constants.ApiScenarioStepType;
|
||||||
|
import io.metersphere.system.valid.EnumValue;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-10 11:24
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ApiScenarioStepRequest {
|
||||||
|
@Schema(description = "步骤id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_scenario_step.id.not_blank}")
|
||||||
|
@Size(max = 50, message = "{api_scenario_step.id.length_range}")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "步骤名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "启用/禁用")
|
||||||
|
private Boolean enable = true;
|
||||||
|
|
||||||
|
@Schema(description = "资源id")
|
||||||
|
private String resourceId;
|
||||||
|
|
||||||
|
@Schema(description = "资源编号")
|
||||||
|
private String resourceNum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ApiScenarioStepType
|
||||||
|
*/
|
||||||
|
@Schema(description = "步骤类型/API/CASE等")
|
||||||
|
@NotBlank
|
||||||
|
@EnumValue(enumClass = ApiScenarioStepType.class)
|
||||||
|
private String stepType;
|
||||||
|
|
||||||
|
@Schema(description = "项目fk")
|
||||||
|
private String projectId;
|
||||||
|
|
||||||
|
@Schema(description = "版本号")
|
||||||
|
private String versionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 引用模式:默认完全引用
|
||||||
|
* - 完全引用:步骤状态不可调整
|
||||||
|
* - 步骤引用:步骤状态可调整
|
||||||
|
*/
|
||||||
|
@Schema(description = "引用/复制/自定义")
|
||||||
|
private String refType;
|
||||||
|
|
||||||
|
@Schema(description = "循环等组件基础数据")
|
||||||
|
private Map<Object, Object> config;
|
||||||
|
|
||||||
|
@Schema(description = "子步骤")
|
||||||
|
private List<ApiScenarioStepRequest> children;
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
package io.metersphere.api.dto.scenario;
|
||||||
|
|
||||||
|
import io.metersphere.api.constants.ApiScenarioStatus;
|
||||||
|
import io.metersphere.system.valid.EnumValue;
|
||||||
|
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.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-10 11:24
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ApiScenarioUpdateRequest {
|
||||||
|
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{api_scenario.id.not_blank}", groups = {Updated.class})
|
||||||
|
@Size(max = 50, message = "{api_scenario.id.length_range}", groups = {Created.class, Updated.class})
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Schema(description = "场景名称", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@Size(max = 255, message = "{api_scenario.name.length_range}")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "场景级别/P0/P1等", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@Size(max = 10, message = "{api_scenario.priority.length_range}")
|
||||||
|
private String priority;
|
||||||
|
|
||||||
|
@Schema(description = "场景状态/未规划/已完成 等", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@Size(max = 20, message = "{api_scenario.status.length_range}")
|
||||||
|
@EnumValue(enumClass = ApiScenarioStatus.class)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@Schema(description = "场景模块fk")
|
||||||
|
private String moduleId;
|
||||||
|
|
||||||
|
@Schema(description = "描述信息")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Schema(description = "标签")
|
||||||
|
private List<String> tags;
|
||||||
|
|
||||||
|
@Schema(description = "是否为环境组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Boolean grouped;
|
||||||
|
|
||||||
|
@Schema(description = "环境或者环境组ID")
|
||||||
|
private String environmentId;
|
||||||
|
|
||||||
|
@Schema(description = "场景的通用配置")
|
||||||
|
private ScenarioConfig scenarioConfig;
|
||||||
|
|
||||||
|
@Schema(description = "步骤集合")
|
||||||
|
private List<ApiScenarioStepRequest> steps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 步骤详情
|
||||||
|
* key 为步骤ID
|
||||||
|
* 值 为详情
|
||||||
|
*/
|
||||||
|
@Schema(description = "步骤详情")
|
||||||
|
private Map<String, Object> stepDetails;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新上传的文件ID
|
||||||
|
* 创建时先按ID创建目录,再把文件放入目录
|
||||||
|
*/
|
||||||
|
@Schema(description = "新上传的文件ID")
|
||||||
|
private List<String> uploadFileIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新关联的文件ID
|
||||||
|
*/
|
||||||
|
@Schema(description = "关联文件ID")
|
||||||
|
private List<String> linkFileIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除本地上传的文件ID
|
||||||
|
*/
|
||||||
|
private List<String> deleteFileIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除关联的文件ID
|
||||||
|
*/
|
||||||
|
private List<String> unLinkRefIds;
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package io.metersphere.api.dto.scenario;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.ApiFile;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-12 10:11
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CsvVariable {
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* @see CsvVariableScope
|
||||||
|
*/
|
||||||
|
private String scope;
|
||||||
|
/**
|
||||||
|
* 文件信息
|
||||||
|
*/
|
||||||
|
private ApiFile file;
|
||||||
|
/**
|
||||||
|
* 分隔符
|
||||||
|
*/
|
||||||
|
private String delimiter;
|
||||||
|
/**
|
||||||
|
* 是否允许带引号
|
||||||
|
*/
|
||||||
|
private Boolean allowQuotationMarks = false;
|
||||||
|
/**
|
||||||
|
* 是否忽略首行
|
||||||
|
*/
|
||||||
|
private Boolean ignoreFirstLine = false;
|
||||||
|
/**
|
||||||
|
* 是否随机
|
||||||
|
*/
|
||||||
|
private Boolean random = false;
|
||||||
|
/**
|
||||||
|
* 遇到文件结束符再次循环
|
||||||
|
*/
|
||||||
|
private Boolean endFileLoopsAgain = true;
|
||||||
|
/**
|
||||||
|
* 遇到文件结束符停止线程
|
||||||
|
*/
|
||||||
|
private Boolean endFileStopThread = false;
|
||||||
|
/**
|
||||||
|
* 文件编码
|
||||||
|
* @see CsvEncodingType
|
||||||
|
*/
|
||||||
|
private String encoding;
|
||||||
|
|
||||||
|
|
||||||
|
public enum CsvEncodingType {
|
||||||
|
UTF8("UTF-8"), UFT16("UTF-16"), ISO885915("ISO-8859-15"), US_ASCII("US-ASCII");
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
CsvEncodingType(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CsvVariableScope {
|
||||||
|
/**
|
||||||
|
* 场景级:执行场景前加载CSV,当前场景任意步骤均可从CSV中读取到数据
|
||||||
|
*/
|
||||||
|
SCENARIO,
|
||||||
|
/**
|
||||||
|
* 步骤级:需在测试步骤的“更多操作”中指定使用添加该CSV,执行该步骤时加载CSV,作用域为步骤内的请求
|
||||||
|
*/
|
||||||
|
STEP
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package io.metersphere.api.dto.scenario;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.request.assertion.MsAssertionConfig;
|
||||||
|
import io.metersphere.api.dto.request.processors.MsProcessorConfig;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-12 09:47
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ScenarioConfig {
|
||||||
|
/**
|
||||||
|
* 场景变量
|
||||||
|
*/
|
||||||
|
private ScenarioVariable variable;
|
||||||
|
/**
|
||||||
|
* 前置处理器配置
|
||||||
|
*/
|
||||||
|
private MsProcessorConfig preProcessorConfig;
|
||||||
|
/**
|
||||||
|
* 后置处理器配置
|
||||||
|
*/
|
||||||
|
private MsProcessorConfig postProcessorConfig;
|
||||||
|
/**
|
||||||
|
* 断言配置
|
||||||
|
*/
|
||||||
|
private MsAssertionConfig assertionConfig;
|
||||||
|
/**
|
||||||
|
* 其他配置
|
||||||
|
*/
|
||||||
|
private ScenarioOtherConfig otherConfig;
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package io.metersphere.api.dto.scenario;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-12 09:47
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ScenarioOtherConfig {
|
||||||
|
/**
|
||||||
|
* 使用全局cookie
|
||||||
|
*/
|
||||||
|
private Boolean enableGlobalCookie = true;
|
||||||
|
/**
|
||||||
|
* 是否共享cookie
|
||||||
|
*/
|
||||||
|
private Boolean enableCookieShare;
|
||||||
|
/**
|
||||||
|
* 场景步骤等待时间
|
||||||
|
* 每一个步骤执行后都会等待相应的时间
|
||||||
|
*/
|
||||||
|
private Integer stepWaitTime;
|
||||||
|
/**
|
||||||
|
* 失败策略
|
||||||
|
* @see FailureStrategy
|
||||||
|
*/
|
||||||
|
private String failureStrategy;
|
||||||
|
|
||||||
|
public enum FailureStrategy {
|
||||||
|
/**
|
||||||
|
* 继续执行
|
||||||
|
*/
|
||||||
|
CONTINUE,
|
||||||
|
/**
|
||||||
|
* 停止执行
|
||||||
|
*/
|
||||||
|
STOP
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package io.metersphere.api.dto.scenario;
|
||||||
|
|
||||||
|
import io.metersphere.project.dto.environment.variables.CommonVariables;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-12 09:49
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ScenarioVariable {
|
||||||
|
/**
|
||||||
|
* 普通变量
|
||||||
|
*/
|
||||||
|
private List<CommonVariables> commonVariables;
|
||||||
|
/**
|
||||||
|
* csv变量
|
||||||
|
*/
|
||||||
|
private List<CsvVariable> csvVariables;
|
||||||
|
}
|
|
@ -30,4 +30,5 @@ public interface ExtApiScenarioMapper {
|
||||||
|
|
||||||
List<ApiScenario> getTestCaseByProvider(@Param("request") AssociateOtherCaseRequest request, @Param("deleted") boolean deleted);
|
List<ApiScenario> getTestCaseByProvider(@Param("request") AssociateOtherCaseRequest request, @Param("deleted") boolean deleted);
|
||||||
|
|
||||||
|
Long getLastPos(@Param("projectId") String projectId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,5 +362,12 @@
|
||||||
</if>
|
</if>
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
|
<select id="getLastPos" resultType="java.lang.Long">
|
||||||
|
SELECT pos
|
||||||
|
FROM api_scenario
|
||||||
|
WHERE project_id = #{projectId}
|
||||||
|
ORDER BY pos DESC
|
||||||
|
LIMIT 1;
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package io.metersphere.api.mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-16 19:57
|
||||||
|
*/
|
||||||
|
public interface ExtApiScenarioStepBlobMapper {
|
||||||
|
List<String> getStepIdsByScenarioId(String scenarioId);
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?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.api.mapper.ExtApiScenarioStepBlobMapper">
|
||||||
|
|
||||||
|
<select id="getStepIdsByScenarioId" resultType="java.lang.String">
|
||||||
|
SELECT id FROM api_scenario_step_blob WHERE scenario_id = #{scenarioId}
|
||||||
|
</select>
|
||||||
|
</mapper>
|
|
@ -0,0 +1,11 @@
|
||||||
|
package io.metersphere.api.mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-16 19:57
|
||||||
|
*/
|
||||||
|
public interface ExtApiScenarioStepMapper {
|
||||||
|
List<String> getStepIdsByScenarioId(String scenarioId);
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?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.api.mapper.ExtApiScenarioStepMapper">
|
||||||
|
|
||||||
|
<select id="getStepIdsByScenarioId" resultType="java.lang.String">
|
||||||
|
SELECT id FROM api_scenario_step WHERE scenario_id = #{scenarioId}
|
||||||
|
</select>
|
||||||
|
</mapper>
|
|
@ -1,7 +1,7 @@
|
||||||
package io.metersphere.api.parser.jmeter.body;
|
package io.metersphere.api.parser.jmeter.body;
|
||||||
|
|
||||||
import io.metersphere.api.dto.request.http.body.BinaryBody;
|
import io.metersphere.api.dto.request.http.body.BinaryBody;
|
||||||
import io.metersphere.api.dto.request.http.body.BodyFile;
|
import io.metersphere.api.dto.ApiFile;
|
||||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||||
import org.apache.jmeter.protocol.http.util.HTTPFileArg;
|
import org.apache.jmeter.protocol.http.util.HTTPFileArg;
|
||||||
|
@ -14,7 +14,7 @@ import org.apache.jmeter.protocol.http.util.HTTPFileArg;
|
||||||
public class MsBinaryBodyConverter extends MsBodyConverter<BinaryBody> {
|
public class MsBinaryBodyConverter extends MsBodyConverter<BinaryBody> {
|
||||||
@Override
|
@Override
|
||||||
public void parse(HTTPSamplerProxy sampler, BinaryBody body, ParameterConfig config) {
|
public void parse(HTTPSamplerProxy sampler, BinaryBody body, ParameterConfig config) {
|
||||||
BodyFile bodyFile = body.getBodyFile();
|
ApiFile bodyFile = body.getBodyFile();
|
||||||
HTTPFileArg httpFileArg = getHttpFileArg(bodyFile);
|
HTTPFileArg httpFileArg = getHttpFileArg(bodyFile);
|
||||||
sampler.setHTTPFiles(new HTTPFileArg[]{httpFileArg});
|
sampler.setHTTPFiles(new HTTPFileArg[]{httpFileArg});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package io.metersphere.api.parser.jmeter.body;
|
package io.metersphere.api.parser.jmeter.body;
|
||||||
|
|
||||||
|
|
||||||
import io.metersphere.api.dto.request.http.body.BodyFile;
|
import io.metersphere.api.dto.ApiFile;
|
||||||
import io.metersphere.api.dto.request.http.body.WWWFormKV;
|
import io.metersphere.api.dto.request.http.body.WWWFormKV;
|
||||||
import io.metersphere.jmeter.mock.Mock;
|
import io.metersphere.jmeter.mock.Mock;
|
||||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||||
|
@ -63,7 +63,7 @@ public abstract class MsBodyConverter<T> {
|
||||||
* @param file
|
* @param file
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected HTTPFileArg getHttpFileArg(BodyFile file) {
|
protected HTTPFileArg getHttpFileArg(ApiFile file) {
|
||||||
String fileId = file.getFileId();
|
String fileId = file.getFileId();
|
||||||
String fileName = file.getFileName();
|
String fileName = file.getFileName();
|
||||||
// 在对应目录下创建文件ID目录,将文件放入
|
// 在对应目录下创建文件ID目录,将文件放入
|
||||||
|
|
|
@ -80,7 +80,6 @@ public class ApiDebugService {
|
||||||
apiDebug.setPos(getNextOrder(request.getProjectId()));
|
apiDebug.setPos(getNextOrder(request.getProjectId()));
|
||||||
|
|
||||||
apiDebugMapper.insert(apiDebug);
|
apiDebugMapper.insert(apiDebug);
|
||||||
// todo 校验 moduleId
|
|
||||||
ApiDebugBlob apiDebugBlob = new ApiDebugBlob();
|
ApiDebugBlob apiDebugBlob = new ApiDebugBlob();
|
||||||
apiDebugBlob.setId(apiDebug.getId());
|
apiDebugBlob.setId(apiDebug.getId());
|
||||||
apiDebugBlob.setRequest(request.getRequest().getBytes());
|
apiDebugBlob.setRequest(request.getRequest().getBytes());
|
||||||
|
@ -120,7 +119,6 @@ public class ApiDebugService {
|
||||||
apiDebug.setUpdateUser(updateUser);
|
apiDebug.setUpdateUser(updateUser);
|
||||||
apiDebug.setUpdateTime(System.currentTimeMillis());
|
apiDebug.setUpdateTime(System.currentTimeMillis());
|
||||||
apiDebugMapper.updateByPrimaryKeySelective(apiDebug);
|
apiDebugMapper.updateByPrimaryKeySelective(apiDebug);
|
||||||
// todo 校验 moduleId
|
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(request.getRequest())) {
|
if (StringUtils.isNotBlank(request.getRequest())) {
|
||||||
ApiDebugBlob apiDebugBlob = new ApiDebugBlob();
|
ApiDebugBlob apiDebugBlob = new ApiDebugBlob();
|
||||||
|
|
|
@ -2,6 +2,8 @@ package io.metersphere.api.service.scenario;
|
||||||
|
|
||||||
import io.metersphere.api.domain.ApiScenario;
|
import io.metersphere.api.domain.ApiScenario;
|
||||||
import io.metersphere.api.domain.ApiScenarioExample;
|
import io.metersphere.api.domain.ApiScenarioExample;
|
||||||
|
import io.metersphere.api.dto.scenario.ApiScenarioAddRequest;
|
||||||
|
import io.metersphere.api.dto.scenario.ApiScenarioUpdateRequest;
|
||||||
import io.metersphere.api.mapper.ApiScenarioMapper;
|
import io.metersphere.api.mapper.ApiScenarioMapper;
|
||||||
import io.metersphere.project.domain.Project;
|
import io.metersphere.project.domain.Project;
|
||||||
import io.metersphere.project.mapper.ProjectMapper;
|
import io.metersphere.project.mapper.ProjectMapper;
|
||||||
|
@ -97,4 +99,49 @@ public class ApiScenarioLogService {
|
||||||
dto.setOriginalValue(JSON.toJSONBytes(apiTestCase));
|
dto.setOriginalValue(JSON.toJSONBytes(apiTestCase));
|
||||||
operationLogService.add(dto);
|
operationLogService.add(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LogDTO addLog(ApiScenarioAddRequest request) {
|
||||||
|
// todo 记录完整的场景信息
|
||||||
|
LogDTO dto = new LogDTO(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
OperationLogType.ADD.name(),
|
||||||
|
OperationLogModule.API_SCENARIO,
|
||||||
|
request.getName());
|
||||||
|
dto.setHistory(true);
|
||||||
|
dto.setOriginalValue(JSON.toJSONBytes(request));
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LogDTO updateLog(ApiScenarioUpdateRequest request) {
|
||||||
|
ApiScenario apiScenario = apiScenarioMapper.selectByPrimaryKey(request.getId());
|
||||||
|
// todo 记录完整的场景信息
|
||||||
|
LogDTO dto = new LogDTO(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
apiScenario.getId(),
|
||||||
|
null,
|
||||||
|
OperationLogType.UPDATE.name(),
|
||||||
|
OperationLogModule.API_SCENARIO,
|
||||||
|
apiScenario.getName());
|
||||||
|
dto.setHistory(true);
|
||||||
|
dto.setOriginalValue(JSON.toJSONBytes(request));
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LogDTO deleteLog(String id) {
|
||||||
|
ApiScenario apiScenario = apiScenarioMapper.selectByPrimaryKey(id);
|
||||||
|
LogDTO dto = new LogDTO(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
apiScenario.getId(),
|
||||||
|
null,
|
||||||
|
OperationLogType.DELETE.name(),
|
||||||
|
OperationLogModule.API_SCENARIO,
|
||||||
|
apiScenario.getName());
|
||||||
|
dto.setOriginalValue(JSON.toJSONBytes(apiScenario));
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
package io.metersphere.api.service.scenario;
|
package io.metersphere.api.service.scenario;
|
||||||
|
|
||||||
import com.alibaba.excel.util.BooleanUtils;
|
import io.metersphere.api.constants.ApiResourceType;
|
||||||
|
import io.metersphere.api.constants.ApiScenarioStepRefType;
|
||||||
|
import io.metersphere.api.constants.ApiScenarioStepType;
|
||||||
import io.metersphere.api.domain.*;
|
import io.metersphere.api.domain.*;
|
||||||
import io.metersphere.api.dto.scenario.ApiScenarioBatchEditRequest;
|
import io.metersphere.api.dto.debug.ApiFileResourceUpdateRequest;
|
||||||
import io.metersphere.api.dto.scenario.ApiScenarioDTO;
|
import io.metersphere.api.dto.scenario.*;
|
||||||
import io.metersphere.api.dto.scenario.ApiScenarioPageRequest;
|
import io.metersphere.api.mapper.*;
|
||||||
import io.metersphere.api.mapper.ApiScenarioFollowerMapper;
|
import io.metersphere.api.service.ApiFileResourceService;
|
||||||
import io.metersphere.api.mapper.ApiScenarioMapper;
|
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
|
||||||
import io.metersphere.api.mapper.ApiScenarioModuleMapper;
|
import io.metersphere.project.service.ProjectService;
|
||||||
import io.metersphere.api.mapper.ExtApiScenarioMapper;
|
import io.metersphere.sdk.constants.ApplicationNumScope;
|
||||||
|
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
||||||
import io.metersphere.sdk.domain.Environment;
|
import io.metersphere.sdk.domain.Environment;
|
||||||
import io.metersphere.sdk.domain.EnvironmentExample;
|
import io.metersphere.sdk.domain.EnvironmentExample;
|
||||||
import io.metersphere.sdk.domain.EnvironmentGroup;
|
import io.metersphere.sdk.domain.EnvironmentGroup;
|
||||||
|
@ -16,12 +19,17 @@ import io.metersphere.sdk.domain.EnvironmentGroupExample;
|
||||||
import io.metersphere.sdk.exception.MSException;
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import io.metersphere.sdk.mapper.EnvironmentGroupMapper;
|
import io.metersphere.sdk.mapper.EnvironmentGroupMapper;
|
||||||
import io.metersphere.sdk.mapper.EnvironmentMapper;
|
import io.metersphere.sdk.mapper.EnvironmentMapper;
|
||||||
import io.metersphere.sdk.util.SubListUtils;
|
import io.metersphere.sdk.util.*;
|
||||||
import io.metersphere.sdk.util.Translator;
|
import io.metersphere.system.log.constants.OperationLogModule;
|
||||||
import io.metersphere.system.service.UserLoginService;
|
import io.metersphere.system.service.UserLoginService;
|
||||||
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
|
import io.metersphere.system.uid.NumGenerator;
|
||||||
|
import io.metersphere.system.utils.ServiceUtils;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.collections.MapUtils;
|
import org.apache.commons.collections.MapUtils;
|
||||||
|
import org.apache.commons.collections4.ListUtils;
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.ibatis.session.ExecutorType;
|
import org.apache.ibatis.session.ExecutorType;
|
||||||
import org.apache.ibatis.session.SqlSession;
|
import org.apache.ibatis.session.SqlSession;
|
||||||
|
@ -29,21 +37,17 @@ import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
import org.mybatis.spring.SqlSessionUtils;
|
import org.mybatis.spring.SqlSessionUtils;
|
||||||
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.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static io.metersphere.api.controller.result.ApiResultCode.API_SCENARIO_EXIST;
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public class ApiScenarioService {
|
public class ApiScenarioService {
|
||||||
|
|
||||||
public static final Long ORDER_STEP = 5000L;
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ApiScenarioMapper apiScenarioMapper;
|
private ApiScenarioMapper apiScenarioMapper;
|
||||||
|
|
||||||
|
@ -64,6 +68,22 @@ public class ApiScenarioService {
|
||||||
private ApiScenarioFollowerMapper apiScenarioFollowerMapper;
|
private ApiScenarioFollowerMapper apiScenarioFollowerMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private SqlSessionFactory sqlSessionFactory;
|
private SqlSessionFactory sqlSessionFactory;
|
||||||
|
@Resource
|
||||||
|
private ProjectService projectService;
|
||||||
|
@Resource
|
||||||
|
private ExtBaseProjectVersionMapper extBaseProjectVersionMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiFileResourceService apiFileResourceService;
|
||||||
|
@Resource
|
||||||
|
private ApiScenarioStepMapper apiScenarioStepMapper;
|
||||||
|
@Resource
|
||||||
|
private ExtApiScenarioStepMapper extApiScenarioStepMapper;
|
||||||
|
@Resource
|
||||||
|
private ExtApiScenarioStepBlobMapper extApiScenarioStepBlobMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiScenarioStepBlobMapper apiScenarioStepBlobMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiScenarioBlobMapper apiScenarioBlobMapper;
|
||||||
public static final String PRIORITY = "Priority";
|
public static final String PRIORITY = "Priority";
|
||||||
public static final String STATUS = "Status";
|
public static final String STATUS = "Status";
|
||||||
public static final String TAGS = "Tags";
|
public static final String TAGS = "Tags";
|
||||||
|
@ -236,7 +256,7 @@ public class ApiScenarioService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void follow(String id, String userId) {
|
public void follow(String id, String userId) {
|
||||||
checkApiScenario(id);
|
checkResourceExist(id);
|
||||||
ApiScenarioFollowerExample example = new ApiScenarioFollowerExample();
|
ApiScenarioFollowerExample example = new ApiScenarioFollowerExample();
|
||||||
example.createCriteria().andApiScenarioIdEqualTo(id).andUserIdEqualTo(userId);
|
example.createCriteria().andApiScenarioIdEqualTo(id).andUserIdEqualTo(userId);
|
||||||
if (apiScenarioFollowerMapper.countByExample(example) > 0) {
|
if (apiScenarioFollowerMapper.countByExample(example) > 0) {
|
||||||
|
@ -251,11 +271,342 @@ public class ApiScenarioService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApiScenario checkApiScenario(String id) {
|
public ApiScenario add(ApiScenarioAddRequest request, String creator) {
|
||||||
ApiScenario apiScenario = apiScenarioMapper.selectByPrimaryKey(id);
|
checkAddExist(request);
|
||||||
if (apiScenario == null) {
|
ApiScenario scenario = getAddApiScenario(request, creator);
|
||||||
throw new MSException(Translator.get("api_scenario_is_not_exist"));
|
apiScenarioMapper.insert(scenario);
|
||||||
|
|
||||||
|
// 更新场景配置
|
||||||
|
ApiScenarioBlob apiScenarioBlob = new ApiScenarioBlob();
|
||||||
|
apiScenarioBlob.setId(scenario.getId());
|
||||||
|
apiScenarioBlob.setConfig(JSON.toJSONString(request.getScenarioConfig()).getBytes());
|
||||||
|
apiScenarioBlobMapper.insert(apiScenarioBlob);
|
||||||
|
|
||||||
|
// 插入步骤
|
||||||
|
if (CollectionUtils.isNotEmpty(request.getSteps())) {
|
||||||
|
List<ApiScenarioStepBlob> apiScenarioStepsDetails = new ArrayList<>();
|
||||||
|
List<ApiScenarioStep> apiScenarioSteps = getUpdateApiScenarioSteps(null, request.getSteps(), apiScenarioStepsDetails);
|
||||||
|
apiScenarioStepsDetails.addAll(getUpdateStepDetails(apiScenarioSteps, request.getStepDetails()));
|
||||||
|
apiScenarioSteps.forEach(step -> step.setScenarioId(scenario.getId()));
|
||||||
|
apiScenarioStepsDetails.forEach(step -> step.setScenarioId(scenario.getId()));
|
||||||
|
if (CollectionUtils.isNotEmpty(apiScenarioSteps)) {
|
||||||
|
apiScenarioStepMapper.batchInsert(apiScenarioSteps);
|
||||||
}
|
}
|
||||||
return apiScenario;
|
if (CollectionUtils.isNotEmpty(apiScenarioStepsDetails)) {
|
||||||
|
apiScenarioStepBlobMapper.batchInsert(apiScenarioStepsDetails);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理文件
|
||||||
|
ApiFileResourceUpdateRequest resourceUpdateRequest = getApiFileResourceUpdateRequest(scenario.getId(), scenario.getProjectId(), creator);
|
||||||
|
resourceUpdateRequest.setUploadFileIds(request.getUploadFileIds());
|
||||||
|
resourceUpdateRequest.setLinkFileIds(request.getLinkFileIds());
|
||||||
|
apiFileResourceService.addFileResource(resourceUpdateRequest);
|
||||||
|
return scenario;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApiScenario getAddApiScenario(ApiScenarioAddRequest request, String creator) {
|
||||||
|
ApiScenario scenario = new ApiScenario();
|
||||||
|
BeanUtils.copyBean(scenario, request);
|
||||||
|
scenario.setId(IDGenerator.nextStr());
|
||||||
|
scenario.setNum(getNextNum(request.getProjectId()));
|
||||||
|
scenario.setPos(getNextOrder(request.getProjectId()));
|
||||||
|
scenario.setLatest(true);
|
||||||
|
scenario.setCreateUser(creator);
|
||||||
|
scenario.setUpdateUser(creator);
|
||||||
|
scenario.setCreateTime(System.currentTimeMillis());
|
||||||
|
scenario.setUpdateTime(System.currentTimeMillis());
|
||||||
|
scenario.setVersionId(extBaseProjectVersionMapper.getDefaultVersion(request.getProjectId()));
|
||||||
|
scenario.setRefId(scenario.getId());
|
||||||
|
scenario.setLastReportStatus(StringUtils.EMPTY);
|
||||||
|
scenario.setDeleted(false);
|
||||||
|
scenario.setRequestPassRate("0");
|
||||||
|
scenario.setStepTotal(CollectionUtils.isEmpty(request.getSteps()) ? 0 : request.getSteps().size());
|
||||||
|
return scenario;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiScenario update(ApiScenarioUpdateRequest request, String updater) {
|
||||||
|
checkResourceExist(request.getId());
|
||||||
|
checkUpdateExist(request);
|
||||||
|
// 更新基础信息
|
||||||
|
ApiScenario scenario = BeanUtils.copyBean(new ApiScenario(), request);
|
||||||
|
scenario.setUpdateUser(updater);
|
||||||
|
scenario.setUpdateTime(System.currentTimeMillis());
|
||||||
|
apiScenarioMapper.updateByPrimaryKeySelective(scenario);
|
||||||
|
|
||||||
|
if (request.getScenarioConfig() != null) {
|
||||||
|
// 更新场景配置
|
||||||
|
ApiScenarioBlob apiScenarioBlob = new ApiScenarioBlob();
|
||||||
|
apiScenarioBlob.setId(scenario.getId());
|
||||||
|
apiScenarioBlob.setConfig(JSON.toJSONString(request.getScenarioConfig()).getBytes());
|
||||||
|
apiScenarioBlobMapper.updateByPrimaryKeyWithBLOBs(apiScenarioBlob);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新场景步骤
|
||||||
|
updateApiScenarioStep(request, scenario);
|
||||||
|
|
||||||
|
ApiScenario originScenario = apiScenarioMapper.selectByPrimaryKey(request.getId());
|
||||||
|
// 处理文件
|
||||||
|
ApiFileResourceUpdateRequest resourceUpdateRequest = getApiFileResourceUpdateRequest(scenario.getId(), originScenario.getProjectId(), updater);
|
||||||
|
resourceUpdateRequest.setUploadFileIds(request.getUploadFileIds());
|
||||||
|
resourceUpdateRequest.setLinkFileIds(request.getLinkFileIds());
|
||||||
|
resourceUpdateRequest.setUnLinkRefIds(request.getUnLinkRefIds());
|
||||||
|
resourceUpdateRequest.setDeleteFileIds(request.getDeleteFileIds());
|
||||||
|
apiFileResourceService.updateFileResource(resourceUpdateRequest);
|
||||||
|
|
||||||
|
return scenario;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新场景步骤
|
||||||
|
* @param request
|
||||||
|
* @param scenario
|
||||||
|
*/
|
||||||
|
private void updateApiScenarioStep(ApiScenarioUpdateRequest request, ApiScenario scenario) {
|
||||||
|
// steps 不为 null 则修改
|
||||||
|
if (request.getSteps() != null) {
|
||||||
|
if (CollectionUtils.isEmpty(request.getSteps())) {
|
||||||
|
// 如果是空数组,则删除所有步骤
|
||||||
|
deleteStepByScenarioId(scenario.getId());
|
||||||
|
deleteStepDetailByScenarioId(scenario.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ApiScenarioStepBlob> apiScenarioStepsDetails = new ArrayList<>();
|
||||||
|
List<ApiScenarioStep> apiScenarioSteps = getUpdateApiScenarioSteps(null, request.getSteps(), apiScenarioStepsDetails);
|
||||||
|
apiScenarioStepsDetails.addAll(getUpdateStepDetails(apiScenarioSteps, request.getStepDetails()));
|
||||||
|
apiScenarioSteps.forEach(step -> step.setScenarioId(scenario.getId()));
|
||||||
|
apiScenarioStepsDetails.forEach(step -> step.setScenarioId(scenario.getId()));
|
||||||
|
|
||||||
|
List<String> stepIds = apiScenarioSteps.stream().map(ApiScenarioStep::getId).collect(Collectors.toList());
|
||||||
|
List<String> originStepIds = extApiScenarioStepMapper.getStepIdsByScenarioId(scenario.getId());
|
||||||
|
List<String> deleteStepIds = ListUtils.subtract(originStepIds, stepIds);
|
||||||
|
|
||||||
|
// 步骤表-全部先删除再插入
|
||||||
|
deleteStepByScenarioId(scenario.getId());
|
||||||
|
apiScenarioStepMapper.batchInsert(apiScenarioSteps);
|
||||||
|
|
||||||
|
// 详情表-删除已经删除的步骤详情
|
||||||
|
SubListUtils.dealForSubList(deleteStepIds, 100, subIds -> {
|
||||||
|
ApiScenarioStepBlobExample stepBlobExample = new ApiScenarioStepBlobExample();
|
||||||
|
stepBlobExample.createCriteria().andIdIn(subIds);
|
||||||
|
apiScenarioStepBlobMapper.deleteByExample(stepBlobExample);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 查询原有的步骤详情
|
||||||
|
Set<String> originStepDetailIds = extApiScenarioStepBlobMapper.getStepIdsByScenarioId(scenario.getId())
|
||||||
|
.stream().collect(Collectors.toSet());
|
||||||
|
|
||||||
|
// 添加新增的步骤详情
|
||||||
|
List<ApiScenarioStepBlob> addApiScenarioStepsDetails = apiScenarioStepsDetails.stream()
|
||||||
|
.filter(step -> !originStepDetailIds.contains(step.getId()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (CollectionUtils.isNotEmpty(addApiScenarioStepsDetails)) {
|
||||||
|
apiScenarioStepBlobMapper.batchInsert(addApiScenarioStepsDetails);
|
||||||
|
}
|
||||||
|
// 更新原有的步骤详情
|
||||||
|
apiScenarioStepsDetails.stream()
|
||||||
|
.filter(step -> originStepDetailIds.contains(step.getId()))
|
||||||
|
.forEach(apiScenarioStepBlobMapper::updateByPrimaryKeySelective);
|
||||||
|
} else if (MapUtils.isNotEmpty(request.getStepDetails())) {
|
||||||
|
// steps 为 null,stepDetails 不为 null,则只更新详情
|
||||||
|
// 查询原有的步骤详情
|
||||||
|
Set<String> originStepDetailIds = extApiScenarioStepBlobMapper.getStepIdsByScenarioId(scenario.getId())
|
||||||
|
.stream().collect(Collectors.toSet());
|
||||||
|
// 更新原有的步骤详情
|
||||||
|
request.getStepDetails().forEach((stepId, stepDetail) -> {
|
||||||
|
if (originStepDetailIds.contains(stepId)) {
|
||||||
|
ApiScenarioStepBlob apiScenarioStepBlob = new ApiScenarioStepBlob();
|
||||||
|
apiScenarioStepBlob.setId(stepId);
|
||||||
|
apiScenarioStepBlob.setContent(JSON.toJSONString(stepDetail).getBytes());
|
||||||
|
apiScenarioStepBlobMapper.updateByPrimaryKeySelective(apiScenarioStepBlob);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteStepDetailByScenarioId(String scenarioId) {
|
||||||
|
ApiScenarioStepBlobExample blobExample = new ApiScenarioStepBlobExample();
|
||||||
|
blobExample.createCriteria().andScenarioIdEqualTo(scenarioId);
|
||||||
|
apiScenarioStepBlobMapper.deleteByExample(blobExample);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteStepByScenarioId(String scenarioId) {
|
||||||
|
ApiScenarioStepExample example = new ApiScenarioStepExample();
|
||||||
|
example.createCriteria().andScenarioIdEqualTo(scenarioId);
|
||||||
|
apiScenarioStepMapper.deleteByExample(example);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取待更新的 ApiScenarioStepBlob 列表
|
||||||
|
* @param apiScenarioSteps
|
||||||
|
* @param stepDetails
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private List<ApiScenarioStepBlob> getUpdateStepDetails(List<ApiScenarioStep> apiScenarioSteps, Map<String, Object> stepDetails) {
|
||||||
|
if (MapUtils.isEmpty(stepDetails)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, ApiScenarioStep> scenarioStepMap = apiScenarioSteps.stream()
|
||||||
|
.collect(Collectors.toMap(ApiScenarioStep::getId, Function.identity()));
|
||||||
|
|
||||||
|
List<ApiScenarioStepBlob> apiScenarioStepsDetails = new ArrayList<>();
|
||||||
|
stepDetails.forEach((stepId, stepDetail) -> {
|
||||||
|
ApiScenarioStep step = scenarioStepMap.get(stepId);
|
||||||
|
if (step == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean isRef = StringUtils.equalsAny(step.getRefType(), ApiScenarioStepRefType.REF.name(), ApiScenarioStepRefType.STEP_REF.name());
|
||||||
|
if (!isRef || StringUtils.equals(step.getRefType(), ApiScenarioStepType.API.name())) {
|
||||||
|
// 非引用的步骤,如果有编辑内容,保存到blob表
|
||||||
|
// 如果引用的是接口定义,也保存详情,因为应用接口定义允许修改参数值
|
||||||
|
ApiScenarioStepBlob apiScenarioStepBlob = new ApiScenarioStepBlob();
|
||||||
|
apiScenarioStepBlob.setId(stepId);
|
||||||
|
apiScenarioStepBlob.setContent(JSON.toJSONString(stepDetail).getBytes());
|
||||||
|
apiScenarioStepsDetails.add(apiScenarioStepBlob);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return apiScenarioStepsDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析步骤树结构
|
||||||
|
* 获取待更新的 ApiScenarioStep 列表
|
||||||
|
* @param parent
|
||||||
|
* @param steps
|
||||||
|
* @param apiScenarioStepsDetails
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private List<ApiScenarioStep> getUpdateApiScenarioSteps(ApiScenarioStepRequest parent,
|
||||||
|
List<ApiScenarioStepRequest> steps,
|
||||||
|
List<ApiScenarioStepBlob> apiScenarioStepsDetails) {
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(steps)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
List<ApiScenarioStep> apiScenarioSteps = new ArrayList<>();
|
||||||
|
long sort = 1;
|
||||||
|
for (ApiScenarioStepRequest step : steps) {
|
||||||
|
ApiScenarioStep apiScenarioStep = new ApiScenarioStep();
|
||||||
|
BeanUtils.copyBean(apiScenarioStep, step);
|
||||||
|
apiScenarioStep.setSort(sort++);
|
||||||
|
if (parent != null) {
|
||||||
|
apiScenarioStep.setParentId(parent.getId());
|
||||||
|
}
|
||||||
|
if (step.getConfig() != null) {
|
||||||
|
apiScenarioStep.setConfig(JSON.toJSONString(step.getConfig()));
|
||||||
|
}
|
||||||
|
apiScenarioSteps.add(apiScenarioStep);
|
||||||
|
|
||||||
|
if (StringUtils.equals(step.getRefType(), ApiScenarioStepRefType.STEP_REF.name())) {
|
||||||
|
// 如果是步骤引用,blob表保存启用的子步骤ID
|
||||||
|
Set<String> enableStepSet = getEnableStepSet(step.getChildren());
|
||||||
|
ApiScenarioStepBlob apiScenarioStepBlob = new ApiScenarioStepBlob();
|
||||||
|
apiScenarioStepBlob.setId(apiScenarioStep.getId());
|
||||||
|
apiScenarioStepBlob.setContent(JSON.toJSONString(enableStepSet).getBytes());
|
||||||
|
apiScenarioStepsDetails.add(apiScenarioStepBlob);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.equalsAny(step.getRefType(), ApiScenarioStepRefType.REF.name(), ApiScenarioStepRefType.STEP_REF.name())) {
|
||||||
|
// 引用的步骤不解析子步骤
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 解析子步骤
|
||||||
|
apiScenarioSteps.addAll(getUpdateApiScenarioSteps(step, step.getChildren(), apiScenarioStepsDetails));
|
||||||
|
}
|
||||||
|
return apiScenarioSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取步骤及子步骤中 enable 的步骤ID
|
||||||
|
*
|
||||||
|
* @param steps
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Set<String> getEnableStepSet(List<ApiScenarioStepRequest> steps) {
|
||||||
|
Set<String> enableSteps = new HashSet<>();
|
||||||
|
if (CollectionUtils.isEmpty(steps)) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
for (ApiScenarioStepRequest step : steps) {
|
||||||
|
if (BooleanUtils.isTrue(step.getEnable())) {
|
||||||
|
enableSteps.add(step.getId());
|
||||||
|
}
|
||||||
|
// 获取子步骤中 enable = true 的步骤
|
||||||
|
enableSteps.addAll(getEnableStepSet(step.getChildren()));
|
||||||
|
}
|
||||||
|
return enableSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ApiFileResourceUpdateRequest getApiFileResourceUpdateRequest(String sourceId, String projectId, String operator) {
|
||||||
|
String apiScenarioDir = DefaultRepositoryDir.getApiScenarioDir(projectId, sourceId);
|
||||||
|
ApiFileResourceUpdateRequest resourceUpdateRequest = new ApiFileResourceUpdateRequest();
|
||||||
|
resourceUpdateRequest.setProjectId(projectId);
|
||||||
|
resourceUpdateRequest.setFolder(apiScenarioDir);
|
||||||
|
resourceUpdateRequest.setResourceId(sourceId);
|
||||||
|
resourceUpdateRequest.setApiResourceType(ApiResourceType.API_SCENARIO);
|
||||||
|
resourceUpdateRequest.setOperator(operator);
|
||||||
|
resourceUpdateRequest.setLogModule(OperationLogModule.API_SCENARIO);
|
||||||
|
resourceUpdateRequest.setFileAssociationSourceType(FileAssociationSourceUtil.SOURCE_TYPE_API_DEBUG);
|
||||||
|
return resourceUpdateRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getNextNum(String projectId) {
|
||||||
|
return NumGenerator.nextNum(projectId, ApplicationNumScope.API_SCENARIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getNextOrder(String projectId) {
|
||||||
|
return projectService.getNextOrder(extApiScenarioMapper::getLastPos, projectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(String id) {
|
||||||
|
checkResourceExist(id);
|
||||||
|
apiScenarioMapper.deleteByPrimaryKey(id);
|
||||||
|
apiScenarioBlobMapper.deleteByPrimaryKey(id);
|
||||||
|
deleteStepByScenarioId(id);
|
||||||
|
deleteStepDetailByScenarioId(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteToGc(String id) {
|
||||||
|
checkResourceExist(id);
|
||||||
|
ApiScenario apiScenario = new ApiScenario();
|
||||||
|
apiScenario.setId(id);
|
||||||
|
apiScenario.setDeleted(true);
|
||||||
|
apiScenarioMapper.updateByPrimaryKeySelective(apiScenario);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAddExist(ApiScenarioAddRequest apiScenario) {
|
||||||
|
ApiScenarioExample example = new ApiScenarioExample();
|
||||||
|
// 统一模块下名称不能重复
|
||||||
|
example.createCriteria()
|
||||||
|
.andNameEqualTo(apiScenario.getName())
|
||||||
|
.andModuleIdEqualTo(apiScenario.getModuleId());
|
||||||
|
if (apiScenarioMapper.countByExample(example) > 0) {
|
||||||
|
throw new MSException(API_SCENARIO_EXIST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkUpdateExist(ApiScenarioUpdateRequest request) {
|
||||||
|
if (StringUtils.isBlank(request.getName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 统一模块下名称不能重复
|
||||||
|
ApiScenarioExample example = new ApiScenarioExample();
|
||||||
|
example.createCriteria()
|
||||||
|
.andIdNotEqualTo(request.getId())
|
||||||
|
.andModuleIdEqualTo(request.getModuleId())
|
||||||
|
.andNameEqualTo(request.getName());
|
||||||
|
if (apiScenarioMapper.countByExample(example) > 0) {
|
||||||
|
throw new MSException(API_SCENARIO_EXIST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApiScenario checkResourceExist(String id) {
|
||||||
|
return ServiceUtils.checkResourceExist(apiScenarioMapper.selectByPrimaryKey(id), "permission.system_api_scenario.name");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String uploadTempFile(MultipartFile file) {
|
||||||
|
return apiFileResourceService.uploadTempFile(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,25 +1,36 @@
|
||||||
package io.metersphere.api.controller;
|
package io.metersphere.api.controller;
|
||||||
|
|
||||||
|
import io.metersphere.api.constants.ApiDefinitionStatus;
|
||||||
|
import io.metersphere.api.constants.ApiScenarioStatus;
|
||||||
|
import io.metersphere.api.constants.ApiScenarioStepRefType;
|
||||||
import io.metersphere.api.domain.*;
|
import io.metersphere.api.domain.*;
|
||||||
import io.metersphere.api.dto.scenario.ApiScenarioBatchEditRequest;
|
import io.metersphere.api.dto.definition.ApiDefinitionAddRequest;
|
||||||
import io.metersphere.api.dto.scenario.ApiScenarioDTO;
|
import io.metersphere.api.dto.definition.ApiTestCaseAddRequest;
|
||||||
import io.metersphere.api.dto.scenario.ApiScenarioPageRequest;
|
import io.metersphere.api.dto.request.assertion.MsAssertionConfig;
|
||||||
import io.metersphere.api.mapper.ApiScenarioFollowerMapper;
|
import io.metersphere.api.dto.request.assertion.MsScriptAssertion;
|
||||||
import io.metersphere.api.mapper.ApiScenarioMapper;
|
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||||
import io.metersphere.api.mapper.ApiScenarioModuleMapper;
|
import io.metersphere.api.dto.scenario.*;
|
||||||
import io.metersphere.api.mapper.ExtApiScenarioMapper;
|
import io.metersphere.api.mapper.*;
|
||||||
|
import io.metersphere.api.service.definition.ApiDefinitionService;
|
||||||
|
import io.metersphere.api.service.definition.ApiTestCaseService;
|
||||||
|
import io.metersphere.api.utils.ApiDataUtils;
|
||||||
|
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
|
||||||
import io.metersphere.sdk.constants.ApplicationNumScope;
|
import io.metersphere.sdk.constants.ApplicationNumScope;
|
||||||
|
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
||||||
import io.metersphere.sdk.constants.PermissionConstants;
|
import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
import io.metersphere.sdk.constants.SessionConstants;
|
|
||||||
import io.metersphere.sdk.domain.Environment;
|
import io.metersphere.sdk.domain.Environment;
|
||||||
import io.metersphere.sdk.domain.EnvironmentExample;
|
import io.metersphere.sdk.domain.EnvironmentExample;
|
||||||
import io.metersphere.sdk.domain.EnvironmentGroup;
|
import io.metersphere.sdk.domain.EnvironmentGroup;
|
||||||
|
import io.metersphere.sdk.file.FileCenter;
|
||||||
|
import io.metersphere.sdk.file.FileRequest;
|
||||||
import io.metersphere.sdk.mapper.EnvironmentGroupMapper;
|
import io.metersphere.sdk.mapper.EnvironmentGroupMapper;
|
||||||
import io.metersphere.sdk.mapper.EnvironmentMapper;
|
import io.metersphere.sdk.mapper.EnvironmentMapper;
|
||||||
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
import io.metersphere.system.base.BaseTest;
|
import io.metersphere.system.base.BaseTest;
|
||||||
import io.metersphere.system.controller.handler.ResultHolder;
|
import io.metersphere.system.controller.handler.ResultHolder;
|
||||||
import io.metersphere.system.log.constants.OperationLogType;
|
import io.metersphere.system.log.constants.OperationLogType;
|
||||||
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
import io.metersphere.system.uid.NumGenerator;
|
import io.metersphere.system.uid.NumGenerator;
|
||||||
import io.metersphere.system.utils.Pager;
|
import io.metersphere.system.utils.Pager;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
@ -28,18 +39,15 @@ import org.junit.jupiter.api.*;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
import org.springframework.test.web.servlet.ResultMatcher;
|
import org.springframework.test.web.servlet.ResultMatcher;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
|
||||||
import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils;
|
import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.util.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
import static io.metersphere.api.controller.result.ApiResultCode.API_SCENARIO_EXIST;
|
||||||
|
import static io.metersphere.system.controller.handler.result.MsHttpResultCode.NOT_FOUND;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
@ -47,10 +55,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
public class ApiScenarioControllerTests extends BaseTest {
|
public class ApiScenarioControllerTests extends BaseTest {
|
||||||
private static final String BASE_PATH = "/api/scenario/";
|
private static final String BASE_PATH = "/api/scenario/";
|
||||||
private static final String PAGE = BASE_PATH + "page";
|
private static final String TRASH_PAGE = "trash/page";
|
||||||
private static final String TRASH_PAGE = BASE_PATH + "trash/page";
|
private static final String BATCH_EDIT = "batch/edit";
|
||||||
private static final String BATCH_EDIT = BASE_PATH + "batch/edit";
|
private static final String FOLLOW = "follow/";
|
||||||
private static final String FOLLOW = BASE_PATH + "follow/";
|
protected static final String UPLOAD_TEMP_FILE = "upload/temp/file";
|
||||||
|
protected static final String DELETE_TO_GC = "delete-to-gc/{0}";
|
||||||
|
|
||||||
private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError();
|
private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError();
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -65,27 +74,26 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
private ApiScenarioFollowerMapper apiScenarioFollowerMapper;
|
private ApiScenarioFollowerMapper apiScenarioFollowerMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private EnvironmentGroupMapper environmentGroupMapper;
|
private EnvironmentGroupMapper environmentGroupMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiScenarioStepMapper apiScenarioStepMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiScenarioStepBlobMapper apiScenarioStepBlobMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiScenarioBlobMapper apiScenarioBlobMapper;
|
||||||
|
@Resource
|
||||||
|
private ExtBaseProjectVersionMapper extBaseProjectVersionMapper;
|
||||||
|
@Resource
|
||||||
|
private ApiDefinitionService apiDefinitionService;
|
||||||
|
@Resource
|
||||||
|
private ApiTestCaseService apiTestCaseService;
|
||||||
|
private static ApiScenario addApiScenario;
|
||||||
|
private static ApiScenario anOtherAddApiScenario;
|
||||||
|
private static ApiDefinition apiDefinition;
|
||||||
|
private static ApiTestCase apiTestCase;
|
||||||
|
|
||||||
public static <T> T parseObjectFromMvcResult(MvcResult mvcResult, Class<T> parseClass) {
|
@Override
|
||||||
try {
|
protected String getBasePath() {
|
||||||
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
return BASE_PATH;
|
||||||
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
|
||||||
//返回请求正常
|
|
||||||
Assertions.assertNotNull(resultHolder);
|
|
||||||
return JSON.parseObject(JSON.toJSONString(resultHolder.getData()), parseClass);
|
|
||||||
} catch (Exception ignore) {
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MvcResult responsePost(String url, Object param) throws Exception {
|
|
||||||
return mockMvc.perform(MockMvcRequestBuilders.post(url)
|
|
||||||
.header(SessionConstants.HEADER_TOKEN, sessionId)
|
|
||||||
.header(SessionConstants.CSRF_TOKEN, csrfToken)
|
|
||||||
.content(JSON.toJSONString(param))
|
|
||||||
.contentType(MediaType.APPLICATION_JSON))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initApiScenario() {
|
public void initApiScenario() {
|
||||||
|
@ -177,6 +185,288 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1)
|
||||||
|
public void add() throws Exception {
|
||||||
|
initTestData();
|
||||||
|
|
||||||
|
// @@请求成功
|
||||||
|
ApiScenarioAddRequest request = new ApiScenarioAddRequest();
|
||||||
|
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
|
request.setDescription("desc");
|
||||||
|
request.setName("test name");
|
||||||
|
request.setModuleId("default");
|
||||||
|
request.setGrouped(false);
|
||||||
|
request.setEnvironmentId("environmentId");
|
||||||
|
request.setTags(List.of("tag1", "tag2"));
|
||||||
|
request.setPriority("P0");
|
||||||
|
request.setStatus(ApiScenarioStatus.COMPLETED.name());
|
||||||
|
List<ApiScenarioStepRequest> steps = getApiScenarioStepRequests();
|
||||||
|
Map<String, Object> steptDetailMap = new HashMap<>();
|
||||||
|
steptDetailMap.put(steps.get(1).getId(), getMsHttpElementParam());
|
||||||
|
steptDetailMap.put(steps.get(0).getId(), getMsHttpElementParam());
|
||||||
|
request.setSteps(steps);
|
||||||
|
request.setStepDetails(steptDetailMap);
|
||||||
|
request.setScenarioConfig(getScenarioConfig());
|
||||||
|
|
||||||
|
MvcResult mvcResult = this.requestPostWithOkAndReturn(DEFAULT_ADD, request);
|
||||||
|
ApiScenario resultData = getResultData(mvcResult, ApiScenario.class);
|
||||||
|
this.addApiScenario = apiScenarioMapper.selectByPrimaryKey(resultData.getId());
|
||||||
|
assertUpdateApiScenario(request, request.getScenarioConfig(), addApiScenario.getId());
|
||||||
|
assertUpdateSteps(steps, steptDetailMap);
|
||||||
|
|
||||||
|
request.setName("anOther name");
|
||||||
|
ApiScenarioStepRequest stepRequest = new ApiScenarioStepRequest();
|
||||||
|
stepRequest.setId(IDGenerator.nextStr());
|
||||||
|
stepRequest.setEnable(true);
|
||||||
|
stepRequest.setName(addApiScenario.getName());
|
||||||
|
stepRequest.setResourceId(addApiScenario.getId());
|
||||||
|
stepRequest.setRefType(ApiScenarioStepRefType.REF.name());
|
||||||
|
|
||||||
|
ApiScenarioStepRequest stepRequest2 = new ApiScenarioStepRequest();
|
||||||
|
stepRequest2.setId(IDGenerator.nextStr());
|
||||||
|
stepRequest2.setName(addApiScenario.getName());
|
||||||
|
stepRequest2.setResourceId(addApiScenario.getId());
|
||||||
|
stepRequest2.setRefType(ApiScenarioStepRefType.STEP_REF.name());
|
||||||
|
stepRequest2.setChildren(List.of(stepRequest));
|
||||||
|
steps = List.of(stepRequest, stepRequest2);
|
||||||
|
request.setSteps(steps);
|
||||||
|
mvcResult = this.requestPostWithOkAndReturn(DEFAULT_ADD, request);
|
||||||
|
this.anOtherAddApiScenario = apiScenarioMapper.selectByPrimaryKey(getResultData(mvcResult, ApiScenario.class).getId());
|
||||||
|
assertUpdateApiScenario(request, request.getScenarioConfig(), anOtherAddApiScenario.getId());
|
||||||
|
assertUpdateSteps(steps, steptDetailMap);
|
||||||
|
|
||||||
|
// @@重名校验异常
|
||||||
|
assertErrorCode(this.requestPost(DEFAULT_ADD, request), API_SCENARIO_EXIST);
|
||||||
|
// @@校验日志
|
||||||
|
checkLog(this.addApiScenario.getId(), OperationLogType.ADD);
|
||||||
|
// @@校验权限
|
||||||
|
requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_ADD, DEFAULT_ADD, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getMsHttpElementParam() {
|
||||||
|
return JSON.parseObject(ApiDataUtils.toJSONString(MsHTTPElementTest.getMsHttpElement()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验更新数据
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param scenarioConfig
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private ApiScenario assertUpdateApiScenario(Object request, ScenarioConfig scenarioConfig, String id) {
|
||||||
|
ApiScenario apiScenario = apiScenarioMapper.selectByPrimaryKey(id);
|
||||||
|
ApiScenarioBlob apiScenarioBlob = apiScenarioBlobMapper.selectByPrimaryKey(id);
|
||||||
|
ApiScenario copyApiScenario = BeanUtils.copyBean(new ApiScenario(), apiScenario);
|
||||||
|
copyApiScenario = BeanUtils.copyBean(copyApiScenario, request);
|
||||||
|
Assertions.assertEquals(apiScenario, copyApiScenario);
|
||||||
|
if (scenarioConfig != null) {
|
||||||
|
Assertions.assertEquals(scenarioConfig, JSON.parseObject(new String(apiScenarioBlob.getConfig()), ScenarioConfig.class));
|
||||||
|
}
|
||||||
|
return apiScenario;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertUpdateSteps(List<ApiScenarioStepRequest> steps, Map<String, Object> steptDetailMap) {
|
||||||
|
for (ApiScenarioStepRequest step : steps) {
|
||||||
|
ApiScenarioStep apiScenarioStep = apiScenarioStepMapper.selectByPrimaryKey(step.getId());
|
||||||
|
ApiScenarioStep copyApiScenarioStep = BeanUtils.copyBean(new ApiScenarioStep(), apiScenarioStep);
|
||||||
|
copyApiScenarioStep = BeanUtils.copyBean(copyApiScenarioStep, step);
|
||||||
|
Assertions.assertEquals(apiScenarioStep, copyApiScenarioStep);
|
||||||
|
ApiScenarioStepBlob apiScenarioStepBlob = apiScenarioStepBlobMapper.selectByPrimaryKey(step.getId());
|
||||||
|
if (apiScenarioStepBlob != null && steptDetailMap.get(step.getId()) != null) {
|
||||||
|
Assertions.assertEquals(steptDetailMap.get(step.getId()), JSON.parseObject(new String(apiScenarioStepBlob.getContent())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScenarioConfig getScenarioConfig() {
|
||||||
|
ScenarioConfig scenarioConfig = new ScenarioConfig();
|
||||||
|
MsAssertionConfig msAssertionConfig = new MsAssertionConfig();
|
||||||
|
MsScriptAssertion scriptAssertion = new MsScriptAssertion();
|
||||||
|
scriptAssertion.setScript("{}");
|
||||||
|
scriptAssertion.setName("script");
|
||||||
|
msAssertionConfig.setAssertions(List.of(scriptAssertion));
|
||||||
|
scenarioConfig.setAssertionConfig(msAssertionConfig);
|
||||||
|
ScenarioOtherConfig scenarioOtherConfig = new ScenarioOtherConfig();
|
||||||
|
scenarioOtherConfig.setStepWaitTime(1000);
|
||||||
|
scenarioOtherConfig.setFailureStrategy(ScenarioOtherConfig.FailureStrategy.CONTINUE.name());
|
||||||
|
scenarioOtherConfig.setEnableCookieShare(true);
|
||||||
|
scenarioConfig.setOtherConfig(scenarioOtherConfig);
|
||||||
|
return scenarioConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ApiScenarioStepRequest> getApiScenarioStepRequests() {
|
||||||
|
ApiScenarioStepRequest stepRequest = new ApiScenarioStepRequest();
|
||||||
|
stepRequest.setId(IDGenerator.nextStr());
|
||||||
|
stepRequest.setVersionId(extBaseProjectVersionMapper.getDefaultVersion(DEFAULT_PROJECT_ID));
|
||||||
|
stepRequest.setConfig(new HashMap<>());
|
||||||
|
stepRequest.setEnable(true);
|
||||||
|
stepRequest.setName(apiTestCase.getName());
|
||||||
|
stepRequest.setResourceId(apiTestCase.getId());
|
||||||
|
stepRequest.setRefType(ApiScenarioStepRefType.REF.name());
|
||||||
|
stepRequest.setConfig(new HashMap<>());
|
||||||
|
|
||||||
|
ApiScenarioStepRequest stepRequest2 = new ApiScenarioStepRequest();
|
||||||
|
stepRequest2.setId(IDGenerator.nextStr());
|
||||||
|
stepRequest2.setVersionId(extBaseProjectVersionMapper.getDefaultVersion(DEFAULT_PROJECT_ID));
|
||||||
|
stepRequest2.setConfig(new HashMap<>());
|
||||||
|
stepRequest2.setEnable(true);
|
||||||
|
stepRequest2.setResourceId(apiTestCase.getId());
|
||||||
|
stepRequest.setName(apiTestCase.getName() + "2");
|
||||||
|
stepRequest2.setRefType(ApiScenarioStepRefType.COPY.name());
|
||||||
|
|
||||||
|
ApiScenarioStepRequest stepRequest3 = new ApiScenarioStepRequest();
|
||||||
|
stepRequest3.setId(IDGenerator.nextStr());
|
||||||
|
stepRequest3.setVersionId(extBaseProjectVersionMapper.getDefaultVersion(DEFAULT_PROJECT_ID));
|
||||||
|
stepRequest3.setConfig(new HashMap<>());
|
||||||
|
stepRequest3.setEnable(true);
|
||||||
|
stepRequest3.setResourceId(apiDefinition.getId());
|
||||||
|
stepRequest.setName(apiDefinition.getName() + "3");
|
||||||
|
stepRequest3.setRefType(ApiScenarioStepRefType.REF.name());
|
||||||
|
|
||||||
|
return List.of(stepRequest, stepRequest2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initTestData() {
|
||||||
|
ApiDefinitionAddRequest apiDefinitionAddRequest = new ApiDefinitionAddRequest();
|
||||||
|
apiDefinitionAddRequest.setName("test scenario");
|
||||||
|
apiDefinitionAddRequest.setProtocol("HTTP");
|
||||||
|
apiDefinitionAddRequest.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
|
apiDefinitionAddRequest.setMethod("POST");
|
||||||
|
apiDefinitionAddRequest.setPath("/api/admin/posts");
|
||||||
|
apiDefinitionAddRequest.setStatus(ApiDefinitionStatus.PREPARE.getValue());
|
||||||
|
apiDefinitionAddRequest.setModuleId("default");
|
||||||
|
apiDefinitionAddRequest.setVersionId(extBaseProjectVersionMapper.getDefaultVersion(DEFAULT_PROJECT_ID));
|
||||||
|
apiDefinitionAddRequest.setDescription("描述内容");
|
||||||
|
apiDefinitionAddRequest.setName("test scenario");
|
||||||
|
MsHTTPElement msHttpElement = MsHTTPElementTest.getMsHttpElement();
|
||||||
|
apiDefinitionAddRequest.setRequest(ApiDataUtils.toJSONString(msHttpElement));
|
||||||
|
apiDefinitionAddRequest.setResponse("{}");
|
||||||
|
apiDefinition = apiDefinitionService.create(apiDefinitionAddRequest, "admin");
|
||||||
|
|
||||||
|
ApiTestCaseAddRequest apiTestCaseAddRequest = new ApiTestCaseAddRequest();
|
||||||
|
apiTestCaseAddRequest.setApiDefinitionId(apiDefinition.getId());
|
||||||
|
apiTestCaseAddRequest.setName("test");
|
||||||
|
apiTestCaseAddRequest.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
|
apiTestCaseAddRequest.setPriority("P0");
|
||||||
|
apiTestCaseAddRequest.setStatus("Underway");
|
||||||
|
apiTestCaseAddRequest.setTags(new LinkedHashSet<>(List.of("tag1", "tag2")));
|
||||||
|
apiTestCaseAddRequest.setRequest(ApiDataUtils.toJSONString(msHttpElement));
|
||||||
|
apiTestCase = apiTestCaseService.addCase(apiTestCaseAddRequest, "admin");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(2)
|
||||||
|
public void update() throws Exception {
|
||||||
|
// @@请求成功
|
||||||
|
ApiScenarioUpdateRequest request = new ApiScenarioUpdateRequest();
|
||||||
|
request.setId(addApiScenario.getId());
|
||||||
|
request.setDescription("desc update");
|
||||||
|
request.setName("test name update");
|
||||||
|
request.setModuleId("default");
|
||||||
|
request.setGrouped(false);
|
||||||
|
request.setEnvironmentId("environmentId update");
|
||||||
|
request.setTags(List.of("tag1 update", "tag2 update"));
|
||||||
|
request.setPriority("P0 update");
|
||||||
|
request.setStatus(ApiScenarioStatus.DEPRECATED.name());
|
||||||
|
List<ApiScenarioStepRequest> steps = getApiScenarioStepRequests();
|
||||||
|
|
||||||
|
// 验证修改基础信息
|
||||||
|
this.requestPostWithOk(DEFAULT_UPDATE, request);
|
||||||
|
assertUpdateApiScenario(request, request.getScenarioConfig(), addApiScenario.getId());
|
||||||
|
|
||||||
|
// 验证清除步骤
|
||||||
|
request.setSteps(List.of());
|
||||||
|
this.requestPostWithOk(DEFAULT_UPDATE, request);
|
||||||
|
assertUpdateApiScenario(request, request.getScenarioConfig(), addApiScenario.getId());
|
||||||
|
assertUpdateSteps(List.of(), new HashMap<>());
|
||||||
|
|
||||||
|
// 验证添加步骤
|
||||||
|
this.requestPostWithOk(DEFAULT_UPDATE, request);
|
||||||
|
Map<String, Object> steptDetailMap = new HashMap<>();
|
||||||
|
steptDetailMap.put(steps.get(0).getId(), getMsHttpElementParam());
|
||||||
|
steptDetailMap.put(steps.get(1).getId(), getMsHttpElementParam());
|
||||||
|
request.setSteps(steps);
|
||||||
|
request.setStepDetails(steptDetailMap);
|
||||||
|
request.setScenarioConfig(getScenarioConfig());
|
||||||
|
this.requestPostWithOk(DEFAULT_UPDATE, request);
|
||||||
|
assertUpdateSteps(steps, steptDetailMap);
|
||||||
|
|
||||||
|
// 验证修改步骤
|
||||||
|
steps.get(0).setName("test name update");
|
||||||
|
this.requestPostWithOk(DEFAULT_UPDATE, request);
|
||||||
|
assertUpdateSteps(steps, steptDetailMap);
|
||||||
|
|
||||||
|
// @@重名校验异常
|
||||||
|
request.setName(anOtherAddApiScenario.getName());
|
||||||
|
assertErrorCode(this.requestPost(DEFAULT_UPDATE, request), API_SCENARIO_EXIST);
|
||||||
|
// @@校验日志
|
||||||
|
checkLog(request.getId(), OperationLogType.UPDATE);
|
||||||
|
// @@校验权限
|
||||||
|
requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_UPDATE, DEFAULT_UPDATE, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(3)
|
||||||
|
public void deleteToGc() throws Exception {
|
||||||
|
// @@请求成功
|
||||||
|
this.requestGetWithOk(DELETE_TO_GC, addApiScenario.getId());
|
||||||
|
// todo 校验请求成功数据
|
||||||
|
// @@校验日志
|
||||||
|
checkLog(addApiScenario.getId(), OperationLogType.DELETE);
|
||||||
|
// @@校验权限
|
||||||
|
requestGetPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_DELETE, DELETE_TO_GC, addApiScenario.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(4)
|
||||||
|
public void delete() throws Exception {
|
||||||
|
// @@请求成功
|
||||||
|
this.requestGetWithOk(DEFAULT_DELETE, addApiScenario.getId());
|
||||||
|
// todo 校验请求成功数据
|
||||||
|
// @@校验日志
|
||||||
|
checkLog(addApiScenario.getId(), OperationLogType.DELETE);
|
||||||
|
// @@校验权限
|
||||||
|
requestGetPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_DELETE, DEFAULT_DELETE, addApiScenario.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(5)
|
||||||
|
public void uploadTempFile() throws Exception {
|
||||||
|
// @@请求成功
|
||||||
|
MockMultipartFile file = getMockMultipartFile();
|
||||||
|
String fileId = doUploadTempFile(file);
|
||||||
|
|
||||||
|
// 校验文件存在
|
||||||
|
FileRequest fileRequest = new FileRequest();
|
||||||
|
fileRequest.setFolder(DefaultRepositoryDir.getSystemTempDir() + "/" + fileId);
|
||||||
|
fileRequest.setFileName(file.getOriginalFilename());
|
||||||
|
Assertions.assertNotNull(FileCenter.getDefaultRepository().getFile(fileRequest));
|
||||||
|
|
||||||
|
requestUploadPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_ADD, UPLOAD_TEMP_FILE, file);
|
||||||
|
requestUploadPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_UPDATE, UPLOAD_TEMP_FILE, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String doUploadTempFile(MockMultipartFile file) throws Exception {
|
||||||
|
return JSON.parseObject(requestUploadFileWithOkAndReturn(UPLOAD_TEMP_FILE, file)
|
||||||
|
.getResponse()
|
||||||
|
.getContentAsString(), ResultHolder.class)
|
||||||
|
.getData().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MockMultipartFile getMockMultipartFile() {
|
||||||
|
MockMultipartFile file = new MockMultipartFile(
|
||||||
|
"file",
|
||||||
|
"file_upload.JPG",
|
||||||
|
MediaType.APPLICATION_OCTET_STREAM_VALUE,
|
||||||
|
"Hello, World!".getBytes()
|
||||||
|
);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(11)
|
@Order(11)
|
||||||
public void page() throws Exception {
|
public void page() throws Exception {
|
||||||
|
@ -186,8 +476,8 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
pageRequest.setProjectId(DEFAULT_PROJECT_ID);
|
pageRequest.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
pageRequest.setPageSize(10);
|
pageRequest.setPageSize(10);
|
||||||
pageRequest.setCurrent(1);
|
pageRequest.setCurrent(1);
|
||||||
MvcResult mvcResult = responsePost(PAGE, pageRequest);
|
MvcResult mvcResult = requestPostAndReturn(DEFAULT_PAGE, pageRequest);
|
||||||
Pager<?> returnPager = parseObjectFromMvcResult(mvcResult, Pager.class);
|
Pager<?> returnPager = getResultData(mvcResult, Pager.class);
|
||||||
//返回值不为空
|
//返回值不为空
|
||||||
Assertions.assertNotNull(returnPager);
|
Assertions.assertNotNull(returnPager);
|
||||||
//返回值的页码和当前页码相同
|
//返回值的页码和当前页码相同
|
||||||
|
@ -197,8 +487,8 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
|
|
||||||
//查询api-scenario-id1的数据
|
//查询api-scenario-id1的数据
|
||||||
pageRequest.setScenarioId("api-scenario-id1");
|
pageRequest.setScenarioId("api-scenario-id1");
|
||||||
mvcResult = responsePost(PAGE, pageRequest);
|
mvcResult = requestPostAndReturn(DEFAULT_PAGE, pageRequest);
|
||||||
returnPager = parseObjectFromMvcResult(mvcResult, Pager.class);
|
returnPager = getResultData(mvcResult, Pager.class);
|
||||||
//返回值不为空
|
//返回值不为空
|
||||||
Assertions.assertNotNull(returnPager);
|
Assertions.assertNotNull(returnPager);
|
||||||
//返回值的页码和当前页码相同
|
//返回值的页码和当前页码相同
|
||||||
|
@ -210,8 +500,8 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
//查询模块为moduleId1的数据
|
//查询模块为moduleId1的数据
|
||||||
pageRequest.setScenarioId(null);
|
pageRequest.setScenarioId(null);
|
||||||
pageRequest.setModuleIds(List.of("scenario-moduleId"));
|
pageRequest.setModuleIds(List.of("scenario-moduleId"));
|
||||||
mvcResult = responsePost(PAGE, pageRequest);
|
mvcResult = requestPostAndReturn(DEFAULT_PAGE, pageRequest);
|
||||||
returnPager = parseObjectFromMvcResult(mvcResult, Pager.class);
|
returnPager = getResultData(mvcResult, Pager.class);
|
||||||
//返回值不为空
|
//返回值不为空
|
||||||
Assertions.assertNotNull(returnPager);
|
Assertions.assertNotNull(returnPager);
|
||||||
//返回值的页码和当前页码相同
|
//返回值的页码和当前页码相同
|
||||||
|
@ -223,7 +513,7 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
pageRequest.setSort(new HashMap<>() {{
|
pageRequest.setSort(new HashMap<>() {{
|
||||||
put("createTime", "asc");
|
put("createTime", "asc");
|
||||||
}});
|
}});
|
||||||
responsePost(PAGE, pageRequest);
|
requestPostAndReturn(DEFAULT_PAGE, pageRequest);
|
||||||
|
|
||||||
pageRequest = new ApiScenarioPageRequest();
|
pageRequest = new ApiScenarioPageRequest();
|
||||||
pageRequest.setProjectId(DEFAULT_PROJECT_ID);
|
pageRequest.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
|
@ -233,8 +523,8 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
pageRequest.setFilter(new HashMap<>() {{
|
pageRequest.setFilter(new HashMap<>() {{
|
||||||
put("priority", List.of("P0"));
|
put("priority", List.of("P0"));
|
||||||
}});
|
}});
|
||||||
mvcResult = responsePost(PAGE, pageRequest);
|
mvcResult = requestPostAndReturn(DEFAULT_PAGE, pageRequest);
|
||||||
returnPager = parseObjectFromMvcResult(mvcResult, Pager.class);
|
returnPager = getResultData(mvcResult, Pager.class);
|
||||||
//返回值不为空
|
//返回值不为空
|
||||||
Assertions.assertNotNull(returnPager);
|
Assertions.assertNotNull(returnPager);
|
||||||
//返回值的页码和当前页码相同
|
//返回值的页码和当前页码相同
|
||||||
|
@ -243,7 +533,7 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
scenarioDTOS.forEach(scenario -> Assertions.assertEquals(scenario.getPriority(), "P0"));
|
scenarioDTOS.forEach(scenario -> Assertions.assertEquals(scenario.getPriority(), "P0"));
|
||||||
|
|
||||||
//校验权限
|
//校验权限
|
||||||
requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_READ, PAGE, pageRequest);
|
requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_READ, DEFAULT_PAGE, pageRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -257,7 +547,7 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
Assertions.assertTrue(CollectionUtils.isNotEmpty(followers));
|
Assertions.assertTrue(CollectionUtils.isNotEmpty(followers));
|
||||||
// @@校验日志
|
// @@校验日志
|
||||||
checkLog("api-scenario-id1", OperationLogType.UPDATE);
|
checkLog("api-scenario-id1", OperationLogType.UPDATE);
|
||||||
this.requestGet(FOLLOW + "111").andExpect(ERROR_REQUEST_MATCHER);
|
assertErrorCode(this.requestGet(FOLLOW + "111"), NOT_FOUND);
|
||||||
// @@校验权限
|
// @@校验权限
|
||||||
requestGetPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_UPDATE, FOLLOW + "api-scenario-id1");
|
requestGetPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_UPDATE, FOLLOW + "api-scenario-id1");
|
||||||
|
|
||||||
|
@ -269,11 +559,9 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
Assertions.assertTrue(CollectionUtils.isEmpty(followers));
|
Assertions.assertTrue(CollectionUtils.isEmpty(followers));
|
||||||
// @@校验日志
|
// @@校验日志
|
||||||
checkLog("api-scenario-id1", OperationLogType.UPDATE);
|
checkLog("api-scenario-id1", OperationLogType.UPDATE);
|
||||||
this.requestGet(FOLLOW + "111").andExpect(ERROR_REQUEST_MATCHER);
|
assertErrorCode(this.requestGet(FOLLOW + "111"), NOT_FOUND);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(13)
|
@Order(13)
|
||||||
public void batchEdit() throws Exception {
|
public void batchEdit() throws Exception {
|
||||||
|
@ -284,7 +572,7 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
request.setAppendTag(true);
|
request.setAppendTag(true);
|
||||||
request.setSelectAll(true);
|
request.setSelectAll(true);
|
||||||
request.setTags(new LinkedHashSet<>(List.of("tag1", "tag3", "tag4")));
|
request.setTags(new LinkedHashSet<>(List.of("tag1", "tag3", "tag4")));
|
||||||
responsePost(BATCH_EDIT, request);
|
requestPostAndReturn(BATCH_EDIT, request);
|
||||||
ApiScenarioExample example = new ApiScenarioExample();
|
ApiScenarioExample example = new ApiScenarioExample();
|
||||||
List<String> ids = extApiScenarioMapper.getIds(request, false);
|
List<String> ids = extApiScenarioMapper.getIds(request, false);
|
||||||
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andDeletedEqualTo(false).andIdIn(ids);
|
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andDeletedEqualTo(false).andIdIn(ids);
|
||||||
|
@ -296,7 +584,7 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
//覆盖标签
|
//覆盖标签
|
||||||
request.setTags(new LinkedHashSet<>(List.of("tag1")));
|
request.setTags(new LinkedHashSet<>(List.of("tag1")));
|
||||||
request.setAppendTag(false);
|
request.setAppendTag(false);
|
||||||
responsePost(BATCH_EDIT, request);
|
requestPostAndReturn(BATCH_EDIT, request);
|
||||||
apiScenarioMapper.selectByExample(example).forEach(scenario -> {
|
apiScenarioMapper.selectByExample(example).forEach(scenario -> {
|
||||||
Assertions.assertEquals(scenario.getTags(), List.of("tag1"));
|
Assertions.assertEquals(scenario.getTags(), List.of("tag1"));
|
||||||
});
|
});
|
||||||
|
@ -311,7 +599,7 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
List<String> apiIdList = apiScenarioList.stream().map(ApiScenario::getId).toList();
|
List<String> apiIdList = apiScenarioList.stream().map(ApiScenario::getId).toList();
|
||||||
request.setSelectIds(apiIdList);
|
request.setSelectIds(apiIdList);
|
||||||
request.setExcludeIds(apiIdList);
|
request.setExcludeIds(apiIdList);
|
||||||
responsePost(BATCH_EDIT, request);
|
requestPostAndReturn(BATCH_EDIT, request);
|
||||||
|
|
||||||
//优先级
|
//优先级
|
||||||
request.setTags(new LinkedHashSet<>());
|
request.setTags(new LinkedHashSet<>());
|
||||||
|
@ -320,7 +608,7 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
request.setModuleIds(List.of("scenario-moduleId"));
|
request.setModuleIds(List.of("scenario-moduleId"));
|
||||||
request.setPriority("P3");
|
request.setPriority("P3");
|
||||||
request.setExcludeIds(new ArrayList<>());
|
request.setExcludeIds(new ArrayList<>());
|
||||||
responsePost(BATCH_EDIT, request);
|
requestPostAndReturn(BATCH_EDIT, request);
|
||||||
//判断数据的优先级是不是P3
|
//判断数据的优先级是不是P3
|
||||||
example.clear();
|
example.clear();
|
||||||
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andDeletedEqualTo(false);
|
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andDeletedEqualTo(false);
|
||||||
|
@ -335,14 +623,14 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
request.setSelectAll(false);
|
request.setSelectAll(false);
|
||||||
request.setSelectIds(List.of("api-scenario-id1"));
|
request.setSelectIds(List.of("api-scenario-id1"));
|
||||||
request.setExcludeIds(List.of("api-scenario-id1"));
|
request.setExcludeIds(List.of("api-scenario-id1"));
|
||||||
responsePost(BATCH_EDIT, request);
|
requestPostAndReturn(BATCH_EDIT, request);
|
||||||
//状态
|
//状态
|
||||||
request.setPriority(null);
|
request.setPriority(null);
|
||||||
request.setType("Status");
|
request.setType("Status");
|
||||||
request.setStatus("Completed");
|
request.setStatus("Completed");
|
||||||
request.setSelectAll(true);
|
request.setSelectAll(true);
|
||||||
request.setExcludeIds(new ArrayList<>());
|
request.setExcludeIds(new ArrayList<>());
|
||||||
responsePost(BATCH_EDIT, request);
|
requestPostAndReturn(BATCH_EDIT, request);
|
||||||
//判断数据的状态是不是Completed
|
//判断数据的状态是不是Completed
|
||||||
apiScenarios = apiScenarioMapper.selectByExample(example);
|
apiScenarios = apiScenarioMapper.selectByExample(example);
|
||||||
apiScenarios.forEach(apiTestCase -> Assertions.assertEquals(apiTestCase.getStatus(), "Completed"));
|
apiScenarios.forEach(apiTestCase -> Assertions.assertEquals(apiTestCase.getStatus(), "Completed"));
|
||||||
|
@ -356,7 +644,7 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
environmentExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andMockEqualTo(true);
|
environmentExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andMockEqualTo(true);
|
||||||
List<Environment> environments = environmentMapper.selectByExample(environmentExample);
|
List<Environment> environments = environmentMapper.selectByExample(environmentExample);
|
||||||
request.setEnvId(environments.get(0).getId());
|
request.setEnvId(environments.get(0).getId());
|
||||||
responsePost(BATCH_EDIT, request);
|
requestPostAndReturn(BATCH_EDIT, request);
|
||||||
//判断数据的环境是不是environments.get(0).getId()
|
//判断数据的环境是不是environments.get(0).getId()
|
||||||
apiScenarios = apiScenarioMapper.selectByExample(example);
|
apiScenarios = apiScenarioMapper.selectByExample(example);
|
||||||
apiScenarios.forEach(apiTestCase -> Assertions.assertEquals(apiTestCase.getEnvironmentId(), environments.get(0).getId()));
|
apiScenarios.forEach(apiTestCase -> Assertions.assertEquals(apiTestCase.getEnvironmentId(), environments.get(0).getId()));
|
||||||
|
@ -370,7 +658,7 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
//环境组
|
//环境组
|
||||||
request.setGrouped(true);
|
request.setGrouped(true);
|
||||||
request.setGroupId("scenario-environment-group-id");
|
request.setGroupId("scenario-environment-group-id");
|
||||||
responsePost(BATCH_EDIT, request);
|
requestPostAndReturn(BATCH_EDIT, request);
|
||||||
apiScenarios = apiScenarioMapper.selectByExample(example);
|
apiScenarios = apiScenarioMapper.selectByExample(example);
|
||||||
apiScenarios.forEach(apiTestCase -> {
|
apiScenarios.forEach(apiTestCase -> {
|
||||||
Assertions.assertEquals(apiTestCase.getGrouped(), true);
|
Assertions.assertEquals(apiTestCase.getGrouped(), true);
|
||||||
|
@ -402,8 +690,8 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
pageRequest.setProjectId(DEFAULT_PROJECT_ID);
|
pageRequest.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
pageRequest.setPageSize(10);
|
pageRequest.setPageSize(10);
|
||||||
pageRequest.setCurrent(1);
|
pageRequest.setCurrent(1);
|
||||||
MvcResult mvcResult = responsePost(TRASH_PAGE, pageRequest);
|
MvcResult mvcResult = requestPostAndReturn(TRASH_PAGE, pageRequest);
|
||||||
Pager<?> returnPager = parseObjectFromMvcResult(mvcResult, Pager.class);
|
Pager<?> returnPager = getResultData(mvcResult, Pager.class);
|
||||||
//返回值不为空
|
//返回值不为空
|
||||||
Assertions.assertNotNull(returnPager);
|
Assertions.assertNotNull(returnPager);
|
||||||
//返回值的页码和当前页码相同
|
//返回值的页码和当前页码相同
|
||||||
|
@ -413,8 +701,8 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
|
|
||||||
//查询api-scenario-id1的数据
|
//查询api-scenario-id1的数据
|
||||||
pageRequest.setScenarioId("trash-api-scenario-id1");
|
pageRequest.setScenarioId("trash-api-scenario-id1");
|
||||||
mvcResult = responsePost(TRASH_PAGE, pageRequest);
|
mvcResult = requestPostAndReturn(TRASH_PAGE, pageRequest);
|
||||||
returnPager = parseObjectFromMvcResult(mvcResult, Pager.class);
|
returnPager = getResultData(mvcResult, Pager.class);
|
||||||
//返回值不为空
|
//返回值不为空
|
||||||
Assertions.assertNotNull(returnPager);
|
Assertions.assertNotNull(returnPager);
|
||||||
//返回值的页码和当前页码相同
|
//返回值的页码和当前页码相同
|
||||||
|
@ -426,8 +714,8 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
//查询模块为moduleId1的数据
|
//查询模块为moduleId1的数据
|
||||||
pageRequest.setScenarioId(null);
|
pageRequest.setScenarioId(null);
|
||||||
pageRequest.setModuleIds(List.of("scenario-moduleId-trash"));
|
pageRequest.setModuleIds(List.of("scenario-moduleId-trash"));
|
||||||
mvcResult = responsePost(TRASH_PAGE, pageRequest);
|
mvcResult = requestPostAndReturn(TRASH_PAGE, pageRequest);
|
||||||
returnPager = parseObjectFromMvcResult(mvcResult, Pager.class);
|
returnPager = getResultData(mvcResult, Pager.class);
|
||||||
//返回值不为空
|
//返回值不为空
|
||||||
Assertions.assertNotNull(returnPager);
|
Assertions.assertNotNull(returnPager);
|
||||||
//返回值的页码和当前页码相同
|
//返回值的页码和当前页码相同
|
||||||
|
@ -439,10 +727,8 @@ public class ApiScenarioControllerTests extends BaseTest {
|
||||||
pageRequest.setSort(new HashMap<>() {{
|
pageRequest.setSort(new HashMap<>() {{
|
||||||
put("createTime", "asc");
|
put("createTime", "asc");
|
||||||
}});
|
}});
|
||||||
responsePost(TRASH_PAGE, pageRequest);
|
requestPostAndReturn(TRASH_PAGE, pageRequest);
|
||||||
//校验权限
|
//校验权限
|
||||||
requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_READ, TRASH_PAGE, pageRequest);
|
requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_READ, TRASH_PAGE, pageRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package io.metersphere.api.controller;
|
package io.metersphere.api.controller;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.ApiFile;
|
||||||
import io.metersphere.api.dto.definition.HttpResponse;
|
import io.metersphere.api.dto.definition.HttpResponse;
|
||||||
import io.metersphere.api.dto.request.MsCommonElement;
|
import io.metersphere.api.dto.request.MsCommonElement;
|
||||||
import io.metersphere.api.dto.request.assertion.*;
|
import io.metersphere.api.dto.request.assertion.*;
|
||||||
|
@ -64,7 +65,7 @@ public class MsHTTPElementTest {
|
||||||
formDataKV.setValue("@email");
|
formDataKV.setValue("@email");
|
||||||
formDataKV.setKey("key");
|
formDataKV.setKey("key");
|
||||||
FormDataKV formDataFileKV = new FormDataKV();
|
FormDataKV formDataFileKV = new FormDataKV();
|
||||||
BodyFile bodyFile = new BodyFile();
|
ApiFile bodyFile = new ApiFile();
|
||||||
bodyFile.setFileId("aaa");
|
bodyFile.setFileId("aaa");
|
||||||
bodyFile.setFileName("aaa");
|
bodyFile.setFileName("aaa");
|
||||||
formDataFileKV.setFiles(List.of(bodyFile));
|
formDataFileKV.setFiles(List.of(bodyFile));
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@ -59,6 +60,8 @@ public class ProjectService {
|
||||||
@Resource
|
@Resource
|
||||||
private TestResourcePoolOrganizationMapper testResourcePoolOrganizationMapper;
|
private TestResourcePoolOrganizationMapper testResourcePoolOrganizationMapper;
|
||||||
|
|
||||||
|
public static final Long ORDER_STEP = 5000L;
|
||||||
|
|
||||||
|
|
||||||
public List<Project> getUserProject(String organizationId, String userId) {
|
public List<Project> getUserProject(String organizationId, String userId) {
|
||||||
if (organizationMapper.selectByPrimaryKey(organizationId) == null) {
|
if (organizationMapper.selectByPrimaryKey(organizationId) == null) {
|
||||||
|
@ -199,4 +202,9 @@ public class ProjectService {
|
||||||
projectVersionExample.createCriteria().andProjectIdEqualTo(projectId);
|
projectVersionExample.createCriteria().andProjectIdEqualTo(projectId);
|
||||||
return projectVersionMapper.selectByExample(projectVersionExample).get(0);
|
return projectVersionMapper.selectByExample(projectVersionExample).get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getNextOrder(Function<String, Long> getLastPosFunc, String projectId) {
|
||||||
|
Long pos = getLastPosFunc.apply(projectId);
|
||||||
|
return (pos == null ? 0 : pos) + ORDER_STEP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,4 +53,19 @@
|
||||||
JSON_CONTAINS(`value`, JSON_ARRAY(#{value}))
|
JSON_CONTAINS(`value`, JSON_ARRAY(#{value}))
|
||||||
</foreach>
|
</foreach>
|
||||||
</sql>
|
</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 fields.contains(key)" >
|
||||||
|
<where>
|
||||||
|
${table_name}.${key} in
|
||||||
|
<foreach collection="values" item="value" separator="," open="(" close=")">
|
||||||
|
#{value}
|
||||||
|
</foreach>
|
||||||
|
</where>
|
||||||
|
</if>
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
</sql>
|
||||||
</mapper>
|
</mapper>
|
|
@ -87,6 +87,7 @@ public abstract class BaseTest {
|
||||||
private MinioClient client;
|
private MinioClient client;
|
||||||
|
|
||||||
protected static final String DEFAULT_LIST = "list";
|
protected static final String DEFAULT_LIST = "list";
|
||||||
|
protected static final String DEFAULT_PAGE = "page";
|
||||||
protected static final String DEFAULT_GET = "get/{0}";
|
protected static final String DEFAULT_GET = "get/{0}";
|
||||||
protected static final String DEFAULT_ADD = "add";
|
protected static final String DEFAULT_ADD = "add";
|
||||||
protected static final String DEFAULT_UPDATE = "update";
|
protected static final String DEFAULT_UPDATE = "update";
|
||||||
|
|
Loading…
Reference in New Issue