fix(接口测试): 同步接口变更相关接口

--task=1015860 --user=陈建星 【接口测试】接口用例支持同步更新接口变更-后端-批量同步更新接口 https://www.tapd.cn/55049933/s/1558631
This commit is contained in:
AgAngle 2024-08-05 17:11:48 +08:00 committed by Craftsman
parent 85bd5949f8
commit a7c31c63ac
10 changed files with 225 additions and 34 deletions

View File

@ -95,6 +95,10 @@ public class ApiTestCase implements Serializable {
@NotNull(message = "{api_test_case.ignore_api_change.not_blank}", groups = {Created.class})
private Boolean ignoreApiChange;
@Schema(description = "忽略接口与用例参数不一致", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "{api_test_case.ignore_api_diff.not_blank}", groups = {Created.class})
private Boolean ignoreApiDiff;
private static final long serialVersionUID = 1L;
public enum Column {
@ -119,7 +123,8 @@ public class ApiTestCase implements Serializable {
deleteUser("delete_user", "deleteUser", "VARCHAR", false),
deleted("deleted", "deleted", "BIT", false),
apiChange("api_change", "apiChange", "BIT", false),
ignoreApiChange("ignore_api_change", "ignoreApiChange", "BIT", false);
ignoreApiChange("ignore_api_change", "ignoreApiChange", "BIT", false),
ignoreApiDiff("ignore_api_diff", "ignoreApiDiff", "BIT", false);
private static final String BEGINNING_DELIMITER = "`";

View File

@ -1597,6 +1597,66 @@ public class ApiTestCaseExample {
addCriterion("ignore_api_change not between", value1, value2, "ignoreApiChange");
return (Criteria) this;
}
public Criteria andIgnoreApiDiffIsNull() {
addCriterion("ignore_api_diff is null");
return (Criteria) this;
}
public Criteria andIgnoreApiDiffIsNotNull() {
addCriterion("ignore_api_diff is not null");
return (Criteria) this;
}
public Criteria andIgnoreApiDiffEqualTo(Boolean value) {
addCriterion("ignore_api_diff =", value, "ignoreApiDiff");
return (Criteria) this;
}
public Criteria andIgnoreApiDiffNotEqualTo(Boolean value) {
addCriterion("ignore_api_diff <>", value, "ignoreApiDiff");
return (Criteria) this;
}
public Criteria andIgnoreApiDiffGreaterThan(Boolean value) {
addCriterion("ignore_api_diff >", value, "ignoreApiDiff");
return (Criteria) this;
}
public Criteria andIgnoreApiDiffGreaterThanOrEqualTo(Boolean value) {
addCriterion("ignore_api_diff >=", value, "ignoreApiDiff");
return (Criteria) this;
}
public Criteria andIgnoreApiDiffLessThan(Boolean value) {
addCriterion("ignore_api_diff <", value, "ignoreApiDiff");
return (Criteria) this;
}
public Criteria andIgnoreApiDiffLessThanOrEqualTo(Boolean value) {
addCriterion("ignore_api_diff <=", value, "ignoreApiDiff");
return (Criteria) this;
}
public Criteria andIgnoreApiDiffIn(List<Boolean> values) {
addCriterion("ignore_api_diff in", values, "ignoreApiDiff");
return (Criteria) this;
}
public Criteria andIgnoreApiDiffNotIn(List<Boolean> values) {
addCriterion("ignore_api_diff not in", values, "ignoreApiDiff");
return (Criteria) this;
}
public Criteria andIgnoreApiDiffBetween(Boolean value1, Boolean value2) {
addCriterion("ignore_api_diff between", value1, value2, "ignoreApiDiff");
return (Criteria) this;
}
public Criteria andIgnoreApiDiffNotBetween(Boolean value1, Boolean value2) {
addCriterion("ignore_api_diff not between", value1, value2, "ignoreApiDiff");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -24,6 +24,7 @@
<result column="deleted" jdbcType="BIT" property="deleted" />
<result column="api_change" jdbcType="BIT" property="apiChange" />
<result column="ignore_api_change" jdbcType="BIT" property="ignoreApiChange" />
<result column="ignore_api_diff" jdbcType="BIT" property="ignoreApiDiff" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
@ -124,7 +125,8 @@
<sql id="Base_Column_List">
id, `name`, priority, num, tags, `status`, last_report_status, last_report_id, pos,
project_id, api_definition_id, version_id, environment_id, create_time, create_user,
update_time, update_user, delete_time, delete_user, deleted, api_change, ignore_api_change
update_time, update_user, delete_time, delete_user, deleted, api_change, ignore_api_change,
ignore_api_diff
</sql>
<select id="selectByExample" parameterType="io.metersphere.api.domain.ApiTestCaseExample" resultMap="BaseResultMap">
select
@ -164,7 +166,8 @@
version_id, environment_id, create_time,
create_user, update_time, update_user,
delete_time, delete_user, deleted,
api_change, ignore_api_change)
api_change, ignore_api_change, ignore_api_diff
)
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{priority,jdbcType=VARCHAR},
#{num,jdbcType=BIGINT}, #{tags,jdbcType=VARCHAR,typeHandler=io.metersphere.handler.ListTypeHandler},
#{status,jdbcType=VARCHAR}, #{lastReportStatus,jdbcType=VARCHAR}, #{lastReportId,jdbcType=VARCHAR},
@ -172,7 +175,8 @@
#{versionId,jdbcType=VARCHAR}, #{environmentId,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT},
#{createUser,jdbcType=VARCHAR}, #{updateTime,jdbcType=BIGINT}, #{updateUser,jdbcType=VARCHAR},
#{deleteTime,jdbcType=BIGINT}, #{deleteUser,jdbcType=VARCHAR}, #{deleted,jdbcType=BIT},
#{apiChange,jdbcType=BIT}, #{ignoreApiChange,jdbcType=BIT})
#{apiChange,jdbcType=BIT}, #{ignoreApiChange,jdbcType=BIT}, #{ignoreApiDiff,jdbcType=BIT}
)
</insert>
<insert id="insertSelective" parameterType="io.metersphere.api.domain.ApiTestCase">
insert into api_test_case
@ -243,6 +247,9 @@
<if test="ignoreApiChange != null">
ignore_api_change,
</if>
<if test="ignoreApiDiff != null">
ignore_api_diff,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
@ -311,6 +318,9 @@
<if test="ignoreApiChange != null">
#{ignoreApiChange,jdbcType=BIT},
</if>
<if test="ignoreApiDiff != null">
#{ignoreApiDiff,jdbcType=BIT},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.api.domain.ApiTestCaseExample" resultType="java.lang.Long">
@ -388,6 +398,9 @@
<if test="record.ignoreApiChange != null">
ignore_api_change = #{record.ignoreApiChange,jdbcType=BIT},
</if>
<if test="record.ignoreApiDiff != null">
ignore_api_diff = #{record.ignoreApiDiff,jdbcType=BIT},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -416,7 +429,8 @@
delete_user = #{record.deleteUser,jdbcType=VARCHAR},
deleted = #{record.deleted,jdbcType=BIT},
api_change = #{record.apiChange,jdbcType=BIT},
ignore_api_change = #{record.ignoreApiChange,jdbcType=BIT}
ignore_api_change = #{record.ignoreApiChange,jdbcType=BIT},
ignore_api_diff = #{record.ignoreApiDiff,jdbcType=BIT}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -487,6 +501,9 @@
<if test="ignoreApiChange != null">
ignore_api_change = #{ignoreApiChange,jdbcType=BIT},
</if>
<if test="ignoreApiDiff != null">
ignore_api_diff = #{ignoreApiDiff,jdbcType=BIT},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
@ -512,15 +529,16 @@
delete_user = #{deleteUser,jdbcType=VARCHAR},
deleted = #{deleted,jdbcType=BIT},
api_change = #{apiChange,jdbcType=BIT},
ignore_api_change = #{ignoreApiChange,jdbcType=BIT}
ignore_api_change = #{ignoreApiChange,jdbcType=BIT},
ignore_api_diff = #{ignoreApiDiff,jdbcType=BIT}
where id = #{id,jdbcType=VARCHAR}
</update>
<insert id="batchInsert" parameterType="map">
insert into api_test_case
(id, `name`, priority, num, tags, `status`, last_report_status, last_report_id, pos,
project_id, api_definition_id, version_id, environment_id, create_time, create_user,
update_time, update_user, delete_time, delete_user, deleted, api_change, ignore_api_change
)
update_time, update_user, delete_time, delete_user, deleted, api_change, ignore_api_change,
ignore_api_diff)
values
<foreach collection="list" item="item" separator=",">
(#{item.id,jdbcType=VARCHAR}, #{item.name,jdbcType=VARCHAR}, #{item.priority,jdbcType=VARCHAR},
@ -530,7 +548,8 @@
#{item.versionId,jdbcType=VARCHAR}, #{item.environmentId,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT},
#{item.createUser,jdbcType=VARCHAR}, #{item.updateTime,jdbcType=BIGINT}, #{item.updateUser,jdbcType=VARCHAR},
#{item.deleteTime,jdbcType=BIGINT}, #{item.deleteUser,jdbcType=VARCHAR}, #{item.deleted,jdbcType=BIT},
#{item.apiChange,jdbcType=BIT}, #{item.ignoreApiChange,jdbcType=BIT})
#{item.apiChange,jdbcType=BIT}, #{item.ignoreApiChange,jdbcType=BIT}, #{item.ignoreApiDiff,jdbcType=BIT}
)
</foreach>
</insert>
<insert id="batchInsertSelective" parameterType="map">
@ -609,6 +628,9 @@
<if test="'ignore_api_change'.toString() == column.value">
#{item.ignoreApiChange,jdbcType=BIT}
</if>
<if test="'ignore_api_diff'.toString() == column.value">
#{item.ignoreApiDiff,jdbcType=BIT}
</if>
</foreach>
)
</foreach>

View File

@ -3,7 +3,7 @@ SET SESSION innodb_lock_wait_timeout = 7200;
ALTER TABLE api_test_case ADD api_change BIT(1) DEFAULT 0 NOT NULL COMMENT '接口定义参数变更标识';
ALTER TABLE api_test_case ADD ignore_api_change BIT(1) DEFAULT 0 NOT NULL COMMENT '忽略接口定义参数变更';
ALTER TABLE api_test_case ADD ignore_api_diff BIT(1) DEFAULT 0 NOT NULL COMMENT '忽略接口与用例参数不一致';
-- set innodb lock wait timeout to default
SET SESSION innodb_lock_wait_timeout = DEFAULT;

View File

@ -198,6 +198,14 @@ public class ApiTestCaseController {
apiTestCaseRecoverService.batchRecover(request, SessionUtils.getUserId());
}
@PostMapping("/batch/api-change/sync")
@Operation(summary = "接口测试-接口管理-接口用例-批量编辑")
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_CASE_UPDATE)
@CheckOwner(resourceId = "#request.getSelectIds()", resourceType = "api_test_case")
public void batchSyncApiChange(@Validated @RequestBody ApiCaseBatchSyncRequest request) {
apiTestCaseService.batchSyncApiChange(request, SessionUtils.getUserId());
}
@PostMapping(value = "/trash/page")
@Operation(summary = "接口测试-接口管理-接口用例-回收站-分页查询")
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_CASE_READ)
@ -310,6 +318,14 @@ public class ApiTestCaseController {
apiTestCaseService.clearApiChange(id);
}
@GetMapping("/api-change/ignore/{id}")
@Operation(summary = "清除接口参数变更标识")
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_API_DEFINITION_CASE_ADD, PermissionConstants.PROJECT_API_DEFINITION_CASE_UPDATE})
@CheckOwner(resourceId = "#id", resourceType = "api_test_case")
public void ignoreApiChange(@PathVariable String id) {
apiTestCaseService.ignoreApiChange(id);
}
@GetMapping("/api/compare/{id}")
@Operation(summary = "与接口定义对比")
@RequiresPermissions(value = PermissionConstants.PROJECT_API_DEFINITION_CASE_READ)

View File

@ -0,0 +1,39 @@
package io.metersphere.api.dto.definition;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@Data
@EqualsAndHashCode(callSuper = false)
public class ApiCaseBatchSyncRequest extends ApiTestCaseBatchRequest implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "同步项")
private ApiCaseSyncItemRequest syncItems = new ApiCaseSyncItemRequest();
@Schema(description = "是否删除多余参数", defaultValue = "false")
private boolean deleteRedundantParam = false;
@Schema(description = "通知配置")
private ApiCaseSyncNotificationRequest notificationConfig = new ApiCaseSyncNotificationRequest();
public class ApiCaseSyncItemRequest {
@Schema(description = "请求头", defaultValue = "true")
private Boolean header = true;
@Schema(description = "请求体", defaultValue = "true")
private Boolean body = true;
@Schema(description = "Query参数", defaultValue = "true")
private Boolean query = true;
@Schema(description = "Rest参数", defaultValue = "true")
private Boolean rest = true;
}
public class ApiCaseSyncNotificationRequest {
@Schema(description = "是否通知接口创建人", defaultValue = "true")
private Boolean apiCreator = true;
@Schema(description = "是否通知引用该用例的场景创建人", defaultValue = "true")
private Boolean scenarioCreator = true;
}
}

View File

@ -30,7 +30,7 @@
</update>
<update id="setApiChangeByApiDefinitionId">
update api_test_case
set api_change = true
set api_change = true, ignore_api_diff = false
where api_definition_id = #{apiDefinitionId}
and api_change is false
and ignore_api_change is false

View File

@ -950,6 +950,7 @@ public class ApiTestCaseService extends MoveNodeService {
ApiTestCase apiTestCase = new ApiTestCase();
apiTestCase.setId(id);
apiTestCase.setApiChange(false);
apiTestCase.setIgnoreApiDiff(true);
apiTestCaseMapper.updateByPrimaryKeySelective(apiTestCase);
}
@ -978,4 +979,18 @@ public class ApiTestCaseService extends MoveNodeService {
private AbstractMsTestElement getTestElement(ApiTestCaseBlob apiTestCaseBlob) {
return ApiDataUtils.parseObject(new String(apiTestCaseBlob.getRequest()), AbstractMsTestElement.class);
}
public void ignoreApiChange(String id) {
checkResourceExist(id);
ApiTestCase apiTestCase = new ApiTestCase();
apiTestCase.setId(id);
apiTestCase.setApiChange(false);
apiTestCase.setIgnoreApiDiff(true);
apiTestCase.setIgnoreApiChange(true);
apiTestCaseMapper.updateByPrimaryKeySelective(apiTestCase);
}
public void batchSyncApiChange(ApiCaseBatchSyncRequest request, String userId) {
// todo
}
}

View File

@ -2853,6 +2853,7 @@ public class ApiScenarioControllerTests extends BaseTest {
apiTestCase.setLastReportStatus("未执行");
apiTestCase.setApiChange(false);
apiTestCase.setIgnoreApiChange(false);
apiTestCase.setIgnoreApiDiff(false);
apiTestCases.add(apiTestCase);
}
apiTestCaseMapper.batchInsert(apiTestCases);

View File

@ -111,6 +111,8 @@ public class ApiTestCaseControllerTests extends BaseTest {
private static final String RUN_POST = "run";
private static final String BATCH_RUN = "batch/run";
private static final String API_CHANGE_CLEAR = "api-change/clear/{0}";
private static final String API_CHANGE_IGNORE = "api-change/ignore/{0}";
private static final String API_CHANGE_SYNC = "batch/api-change/sync";
private static final String API_COMPARE = "api/compare/{0}";
private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError();
@ -234,6 +236,7 @@ public class ApiTestCaseControllerTests extends BaseTest {
apiTestCase.setLastReportStatus("SUCCESS");
apiTestCase.setApiChange(false);
apiTestCase.setIgnoreApiChange(false);
apiTestCase.setIgnoreApiDiff(false);
caseMapper.insert(apiTestCase);
ApiTestCaseBlob apiTestCaseBlob = new ApiTestCaseBlob();
apiTestCaseBlob.setId(apiTestCase.getId());
@ -437,6 +440,7 @@ public class ApiTestCaseControllerTests extends BaseTest {
apiTestCaseService.handleApiParamChange(apiTestCase.getApiDefinitionId(), changeRequest, originRequest);
// 校验变更通知
Assertions.assertEquals(apiTestCaseMapper.selectByPrimaryKey(apiTestCase.getId()).getApiChange(), true);
Assertions.assertEquals(apiTestCaseMapper.selectByPrimaryKey(apiTestCase.getId()).getIgnoreApiDiff(), false);
}
@Test
@ -460,12 +464,41 @@ public class ApiTestCaseControllerTests extends BaseTest {
apiTestCaseMapper.updateByPrimaryKeySelective(updateCase);
this.requestGetWithOk(API_CHANGE_CLEAR, apiTestCase.getId());
Assertions.assertFalse(apiTestCaseMapper.selectByPrimaryKey(apiTestCase.getId()).getApiChange());
Assertions.assertTrue(apiTestCaseMapper.selectByPrimaryKey(apiTestCase.getId()).getIgnoreApiDiff());
// @@校验权限
requestGetPermissionTest(PermissionConstants.PROJECT_API_DEFINITION_CASE_ADD, API_CHANGE_CLEAR, apiTestCase.getId());
requestGetPermissionTest(PermissionConstants.PROJECT_API_DEFINITION_CASE_UPDATE, API_CHANGE_CLEAR, apiTestCase.getId());
}
@Test
@Order(3)
public void ignoreApiChange() throws Exception {
ApiTestCase updateCase = new ApiTestCase();
updateCase.setApiChange(true);
updateCase.setId(apiTestCase.getId());
apiTestCaseMapper.updateByPrimaryKeySelective(updateCase);
this.requestGetWithOk(API_CHANGE_IGNORE, apiTestCase.getId());
Assertions.assertFalse(apiTestCaseMapper.selectByPrimaryKey(apiTestCase.getId()).getApiChange());
Assertions.assertTrue(apiTestCaseMapper.selectByPrimaryKey(apiTestCase.getId()).getIgnoreApiDiff());
Assertions.assertTrue(apiTestCaseMapper.selectByPrimaryKey(apiTestCase.getId()).getIgnoreApiChange());
// @@校验权限
requestGetPermissionTest(PermissionConstants.PROJECT_API_DEFINITION_CASE_ADD, API_CHANGE_IGNORE, apiTestCase.getId());
requestGetPermissionTest(PermissionConstants.PROJECT_API_DEFINITION_CASE_UPDATE, API_CHANGE_IGNORE, apiTestCase.getId());
}
@Test
@Order(4)
public void batchSyncApiChange() throws Exception {
ApiCaseBatchSyncRequest request = new ApiCaseBatchSyncRequest();
request.setProjectId(DEFAULT_PROJECT_ID);
this.requestPostWithOk(API_CHANGE_SYNC, request);
// @@校验权限
requestPostPermissionTest(PermissionConstants.PROJECT_API_DEFINITION_CASE_UPDATE, API_CHANGE_SYNC, request);
}
/**
* 测试关联的文件更新
*