feat(接口测试): 接口用例报告接口

This commit is contained in:
wxg0103 2024-01-18 21:02:15 +08:00 committed by Craftsman
parent a4bc242e6a
commit a3e0e5cbe2
45 changed files with 1178 additions and 174 deletions

View File

@ -2,9 +2,10 @@ package io.metersphere.api.mapper;
import io.metersphere.api.domain.ApiReportStep;
import io.metersphere.api.domain.ApiReportStepExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ApiReportStepMapper {
long countByExample(ApiReportStepExample example);
@ -30,5 +31,5 @@ public interface ApiReportStepMapper {
int batchInsert(@Param("list") List<ApiReportStep> list);
int batchInsertSelective(@Param("list") List<ApiReportStep> list, @Param("selective") ApiReportStep.Column ... selective);
int batchInsertSelective(@Param("list") List<ApiReportStep> list, @Param("selective") ApiReportStep.Column... selective);
}

View File

@ -4,32 +4,117 @@ import io.metersphere.validation.groups.*;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import lombok.Data;
@Data
public class ShareInfo implements Serializable {
@Schema(description = "分享ID", requiredMode = Schema.RequiredMode.REQUIRED)
@Schema(description = "分享ID", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{share_info.id.not_blank}", groups = {Updated.class})
@Size(min = 1, max = 50, message = "{share_info.id.length_range}", groups = {Created.class, Updated.class})
private String id;
@Schema(description = "创建时间")
@Schema(description = "创建时间")
private Long createTime;
@Schema(description = "创建人")
@Schema(description = "创建人")
private String createUser;
@Schema(description = "更新时间")
@Schema(description = "更新时间")
private Long updateTime;
@Schema(description = "分享类型single batch")
@Schema(description = "分享类型 资源的类型 Single, Batch, API_SHARE_REPORT, TEST_PLAN_SHARE_REPORT")
private String shareType;
@Schema(description = "语言")
@Schema(description = "语言")
private String lang;
@Schema(description = "分享扩展数据")
@Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{share_info.project_id.not_blank}", groups = {Created.class})
@Size(min = 1, max = 50, message = "{share_info.project_id.length_range}", groups = {Created.class, Updated.class})
private String projectId;
@Schema(description = "分享扩展数据 资源的id")
private byte[] customData;
private static final long serialVersionUID = 1L;
public enum Column {
id("id", "id", "VARCHAR", false),
createTime("create_time", "createTime", "BIGINT", false),
createUser("create_user", "createUser", "VARCHAR", false),
updateTime("update_time", "updateTime", "BIGINT", false),
shareType("share_type", "shareType", "VARCHAR", false),
lang("lang", "lang", "VARCHAR", false),
projectId("project_id", "projectId", "VARCHAR", false),
customData("custom_data", "customData", "LONGVARBINARY", false);
private static final String BEGINNING_DELIMITER = "`";
private static final String ENDING_DELIMITER = "`";
private final String column;
private final boolean isColumnNameDelimited;
private final String javaProperty;
private final String jdbcType;
public String value() {
return this.column;
}
public String getValue() {
return this.column;
}
public String getJavaProperty() {
return this.javaProperty;
}
public String getJdbcType() {
return this.jdbcType;
}
Column(String column, String javaProperty, String jdbcType, boolean isColumnNameDelimited) {
this.column = column;
this.javaProperty = javaProperty;
this.jdbcType = jdbcType;
this.isColumnNameDelimited = isColumnNameDelimited;
}
public String desc() {
return this.getEscapedColumnName() + " DESC";
}
public String asc() {
return this.getEscapedColumnName() + " ASC";
}
public static Column[] excludes(Column ... excludes) {
ArrayList<Column> columns = new ArrayList<>(Arrays.asList(Column.values()));
if (excludes != null && excludes.length > 0) {
columns.removeAll(new ArrayList<>(Arrays.asList(excludes)));
}
return columns.toArray(new Column[]{});
}
public static Column[] all() {
return Column.values();
}
public String getEscapedColumnName() {
if (this.isColumnNameDelimited) {
return new StringBuilder().append(BEGINNING_DELIMITER).append(this.column).append(ENDING_DELIMITER).toString();
} else {
return this.column;
}
}
public String getAliasedEscapedColumnName() {
return this.getEscapedColumnName();
}
}
}

View File

@ -503,6 +503,76 @@ public class ShareInfoExample {
addCriterion("lang not between", value1, value2, "lang");
return (Criteria) this;
}
public Criteria andProjectIdIsNull() {
addCriterion("project_id is null");
return (Criteria) this;
}
public Criteria andProjectIdIsNotNull() {
addCriterion("project_id is not null");
return (Criteria) this;
}
public Criteria andProjectIdEqualTo(String value) {
addCriterion("project_id =", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdNotEqualTo(String value) {
addCriterion("project_id <>", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdGreaterThan(String value) {
addCriterion("project_id >", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdGreaterThanOrEqualTo(String value) {
addCriterion("project_id >=", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdLessThan(String value) {
addCriterion("project_id <", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdLessThanOrEqualTo(String value) {
addCriterion("project_id <=", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdLike(String value) {
addCriterion("project_id like", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdNotLike(String value) {
addCriterion("project_id not like", value, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdIn(List<String> values) {
addCriterion("project_id in", values, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdNotIn(List<String> values) {
addCriterion("project_id not in", values, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdBetween(String value1, String value2) {
addCriterion("project_id between", value1, value2, "projectId");
return (Criteria) this;
}
public Criteria andProjectIdNotBetween(String value1, String value2) {
addCriterion("project_id not between", value1, value2, "projectId");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -33,4 +33,8 @@ public interface ShareInfoMapper {
int updateByPrimaryKeyWithBLOBs(ShareInfo record);
int updateByPrimaryKey(ShareInfo record);
int batchInsert(@Param("list") List<ShareInfo> list);
int batchInsertSelective(@Param("list") List<ShareInfo> list, @Param("selective") ShareInfo.Column ... selective);
}

View File

@ -8,6 +8,7 @@
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
<result column="share_type" jdbcType="VARCHAR" property="shareType" />
<result column="lang" jdbcType="VARCHAR" property="lang" />
<result column="project_id" jdbcType="VARCHAR" property="projectId" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.sdk.domain.ShareInfo">
<result column="custom_data" jdbcType="LONGVARBINARY" property="customData" />
@ -71,7 +72,7 @@
</where>
</sql>
<sql id="Base_Column_List">
id, create_time, create_user, update_time, share_type, lang
id, create_time, create_user, update_time, share_type, lang, project_id
</sql>
<sql id="Blob_Column_List">
custom_data
@ -127,10 +128,10 @@
<insert id="insert" parameterType="io.metersphere.sdk.domain.ShareInfo">
insert into share_info (id, create_time, create_user,
update_time, share_type, lang,
custom_data)
project_id, custom_data)
values (#{id,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{createUser,jdbcType=VARCHAR},
#{updateTime,jdbcType=BIGINT}, #{shareType,jdbcType=VARCHAR}, #{lang,jdbcType=VARCHAR},
#{customData,jdbcType=LONGVARBINARY})
#{projectId,jdbcType=VARCHAR}, #{customData,jdbcType=LONGVARBINARY})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.sdk.domain.ShareInfo">
insert into share_info
@ -153,6 +154,9 @@
<if test="lang != null">
lang,
</if>
<if test="projectId != null">
project_id,
</if>
<if test="customData != null">
custom_data,
</if>
@ -176,6 +180,9 @@
<if test="lang != null">
#{lang,jdbcType=VARCHAR},
</if>
<if test="projectId != null">
#{projectId,jdbcType=VARCHAR},
</if>
<if test="customData != null">
#{customData,jdbcType=LONGVARBINARY},
</if>
@ -208,6 +215,9 @@
<if test="record.lang != null">
lang = #{record.lang,jdbcType=VARCHAR},
</if>
<if test="record.projectId != null">
project_id = #{record.projectId,jdbcType=VARCHAR},
</if>
<if test="record.customData != null">
custom_data = #{record.customData,jdbcType=LONGVARBINARY},
</if>
@ -224,6 +234,7 @@
update_time = #{record.updateTime,jdbcType=BIGINT},
share_type = #{record.shareType,jdbcType=VARCHAR},
lang = #{record.lang,jdbcType=VARCHAR},
project_id = #{record.projectId,jdbcType=VARCHAR},
custom_data = #{record.customData,jdbcType=LONGVARBINARY}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -236,7 +247,8 @@
create_user = #{record.createUser,jdbcType=VARCHAR},
update_time = #{record.updateTime,jdbcType=BIGINT},
share_type = #{record.shareType,jdbcType=VARCHAR},
lang = #{record.lang,jdbcType=VARCHAR}
lang = #{record.lang,jdbcType=VARCHAR},
project_id = #{record.projectId,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -259,6 +271,9 @@
<if test="lang != null">
lang = #{lang,jdbcType=VARCHAR},
</if>
<if test="projectId != null">
project_id = #{projectId,jdbcType=VARCHAR},
</if>
<if test="customData != null">
custom_data = #{customData,jdbcType=LONGVARBINARY},
</if>
@ -272,6 +287,7 @@
update_time = #{updateTime,jdbcType=BIGINT},
share_type = #{shareType,jdbcType=VARCHAR},
lang = #{lang,jdbcType=VARCHAR},
project_id = #{projectId,jdbcType=VARCHAR},
custom_data = #{customData,jdbcType=LONGVARBINARY}
where id = #{id,jdbcType=VARCHAR}
</update>
@ -281,7 +297,57 @@
create_user = #{createUser,jdbcType=VARCHAR},
update_time = #{updateTime,jdbcType=BIGINT},
share_type = #{shareType,jdbcType=VARCHAR},
lang = #{lang,jdbcType=VARCHAR}
lang = #{lang,jdbcType=VARCHAR},
project_id = #{projectId,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
<insert id="batchInsert" parameterType="map">
insert into share_info
(id, create_time, create_user, update_time, share_type, lang, project_id, custom_data
)
values
<foreach collection="list" item="item" separator=",">
(#{item.id,jdbcType=VARCHAR}, #{item.createTime,jdbcType=BIGINT}, #{item.createUser,jdbcType=VARCHAR},
#{item.updateTime,jdbcType=BIGINT}, #{item.shareType,jdbcType=VARCHAR}, #{item.lang,jdbcType=VARCHAR},
#{item.projectId,jdbcType=VARCHAR}, #{item.customData,jdbcType=LONGVARBINARY})
</foreach>
</insert>
<insert id="batchInsertSelective" parameterType="map">
insert into share_info (
<foreach collection="selective" item="column" separator=",">
${column.escapedColumnName}
</foreach>
)
values
<foreach collection="list" item="item" separator=",">
(
<foreach collection="selective" item="column" separator=",">
<if test="'id'.toString() == column.value">
#{item.id,jdbcType=VARCHAR}
</if>
<if test="'create_time'.toString() == column.value">
#{item.createTime,jdbcType=BIGINT}
</if>
<if test="'create_user'.toString() == column.value">
#{item.createUser,jdbcType=VARCHAR}
</if>
<if test="'update_time'.toString() == column.value">
#{item.updateTime,jdbcType=BIGINT}
</if>
<if test="'share_type'.toString() == column.value">
#{item.shareType,jdbcType=VARCHAR}
</if>
<if test="'lang'.toString() == column.value">
#{item.lang,jdbcType=VARCHAR}
</if>
<if test="'project_id'.toString() == column.value">
#{item.projectId,jdbcType=VARCHAR}
</if>
<if test="'custom_data'.toString() == column.value">
#{item.customData,jdbcType=LONGVARBINARY}
</if>
</foreach>
)
</foreach>
</insert>
</mapper>

View File

@ -156,17 +156,21 @@ CREATE INDEX idx_type ON operation_history (`type`);
CREATE TABLE IF NOT EXISTS share_info
(
`id` VARCHAR(50) NOT NULL COMMENT '分享ID' ,
`create_time` BIGINT NOT NULL COMMENT '创建时间' ,
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人' ,
`update_time` BIGINT NOT NULL COMMENT '更新时间' ,
`share_type` VARCHAR(64) COMMENT '分享类型single batch' ,
`custom_data` LONGBLOB COMMENT '分享扩展数据' ,
`lang` VARCHAR(10) COMMENT '语言' ,
`id` VARCHAR(50) NOT NULL COMMENT '分享ID' ,
`create_time` BIGINT NOT NULL COMMENT '创建时间' ,
`create_user` VARCHAR(50) NOT NULL COMMENT '创建人' ,
`update_time` BIGINT NOT NULL COMMENT '更新时间' ,
`share_type` VARCHAR(64) COMMENT '分享类型 资源的类型 Single, Batch, API_SHARE_REPORT, TEST_PLAN_SHARE_REPORT' ,
`custom_data` LONGBLOB COMMENT '分享扩展数据 资源的id' ,
`lang` VARCHAR(10) COMMENT '语言' ,
`project_id` VARCHAR(50) NOT NULL COMMENT '项目id' ,
PRIMARY KEY (id)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci COMMENT = '分享';
CREATE INDEX idx_share_type ON share_info(share_type);
CREATE INDEX idx_project_id ON share_info(project_id);
-- set innodb lock wait timeout to default
SET SESSION innodb_lock_wait_timeout = DEFAULT;

View File

@ -41,10 +41,8 @@ INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_PERSONAL_API_KEY:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_PERSONAL:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'SYSTEM_PERSONAL:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'member', 'PROJECT_TEST_PLAN_MODULE:READ');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'member', 'PROJECT_TEST_PLAN:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'PROJECT_TEST_PLAN_MODULE:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'member', 'PROJECT_TEST_PLAN:READ');
-- 组织管理员权限
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'org_admin', 'ORGANIZATION_USER_ROLE:READ');
@ -177,6 +175,9 @@ INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_API_SCENARIO:READ+IMPORT');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_API_SCENARIO:READ+EXPORT');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_API_SCENARIO:READ+DEBUG');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_API_REPORT:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_API_REPORT:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_API_REPORT:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'FUNCTIONAL_CASE:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'FUNCTIONAL_CASE:READ+ADD');
@ -192,20 +193,13 @@ INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'CASE_REVIEW:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'CASE_REVIEW:READ+REVIEW');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'CASE_REVIEW:READ+RELEVANCE');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN_MODULE:READ+ADD');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN_MODULE:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN_MODULE:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+ADD');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+EXECUTE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN_MODULE:READ+ADD');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN_MODULE:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN_MODULE:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+ADD');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+EXECUTE');
-- 项目成员权限
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_BASE_INFO:READ');
@ -296,6 +290,9 @@ INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_API_SCENARIO:READ+IMPORT');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_API_SCENARIO:READ+EXPORT');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_API_SCENARIO:READ+DEBUG');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_API_REPORT:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_API_REPORT:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_API_REPORT:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'FUNCTIONAL_CASE:READ');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'FUNCTIONAL_CASE:READ+ADD');
@ -311,20 +308,13 @@ INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'CASE_REVIEW:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'CASE_REVIEW:READ+REVIEW');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'CASE_REVIEW:READ+RELEVANCE');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN_MODULE:READ+ADD');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN_MODULE:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN_MODULE:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ+ADD');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id)
VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ+EXECUTE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN_MODULE:READ+ADD');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN_MODULE:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN_MODULE:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ+ADD');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ+UPDATE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ+DELETE');
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_TEST_PLAN:READ+EXECUTE');
-- 初始化当前站点配置
INSERT into system_parameter values('base.url', 'http://127.0.0.1:8081', 'text');
-- 初始化prometheus站点配置

View File

@ -286,6 +286,13 @@ public class PermissionConstants {
/*------ end: API_MANAGEMENT ------*/
/*------ start: API_REPORT ------*/
public static final String PROJECT_API_REPORT_READ = "PROJECT_API_REPORT:READ";
public static final String PROJECT_API_REPORT_UPDATE = "PROJECT_API_REPORT:READ+UPDATE";
public static final String PROJECT_API_REPORT_DELETE = "PROJECT_API_REPORT:READ+DELETE";
/*------ end: API_REPORT ------*/
//个人中心
/*------ start: PERSONAL_CENTER ------*/
public static final String SYSTEM_PERSONAL_API_KEY_ADD = "SYSTEM_PERSONAL_API_KEY:READ+ADD";

View File

@ -1,4 +1,4 @@
package io.metersphere.workstation.utils;
package io.metersphere.sdk.util;
import org.apache.commons.lang3.StringUtils;

View File

@ -317,4 +317,6 @@ resource_pool_execute_error=资源池调用失败
api_swagger_url_error=Swagger url无法连通
api_scenario_exist=场景已存在
schedule_not_exist=定时任务不存在
api_case_report_not_exist=用例报告不存在
api_scenario_report_not_exist=场景报告不存在

View File

@ -49,7 +49,6 @@ 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.length_range=Scene ID length must be between 1-50
api_scenario_step.sort.not_blank=SORT cannot be empty
#moduleApiTestCaseFollow
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
@ -321,4 +320,6 @@ execute_resource_pool_not_config_error=Select a resource pool in 【Project Mana
resource_pool_execute_error=The resource pool call failed
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
api_case_report_not_exist=Api report does not exist
api_scenario_report_not_exist=Scenario report does not exist

View File

@ -321,3 +321,5 @@ resource_pool_execute_error=资源池调用失败
api_swagger_url_error=Swagger url无法连通
api_scenario_exist=场景已存在
schedule_not_exist=定时任务不存在
api_case_report_not_exist=用例报告不存在
api_scenario_report_not_exist=场景报告不存在

View File

@ -320,4 +320,6 @@ execute_resource_pool_not_config_error=請在【項目管理-應用管理-接口
resource_pool_execute_error=資源池調用失敗
api_swagger_url_error=Swagger url無法調解
api_scenario_exist=場景已存在
schedule_not_exist=定時任務不存在
schedule_not_exist=定時任務不存在
api_case_report_not_exist=用例報告不存在
api_scenario_report_not_exist=場景報告不存在

View File

@ -484,6 +484,7 @@ permission.api_mock.name=接口Mock
permission.api_definition.import=导入
permission.api_definition.export=导出
permission.api_definition.execute=执行
permission.api_report=接口报告
#接口管理
api_definition_not_exist=接口不存在

View File

@ -494,6 +494,7 @@ permission.api_mock.name=API Mock
permission.api_definition.import=Import
permission.api_definition.export=Export
permission.api_definition.execute=Execute
permission.api_report=Api Report
#接口管理
api_definition_not_exist=API definition is not exist

View File

@ -490,6 +490,7 @@ permission.api_mock.name=接口Mock
permission.api_definition.import=导入
permission.api_definition.export=导出
permission.api_definition.execute=执行
permission.api_report=接口报告
#接口管理
api_definition_not_exist=接口不存在

View File

@ -490,6 +490,7 @@ permission.api_mock.name=接口Mock
permission.api_definition.import=導入
permission.api_definition.export=導出
permission.api_definition.execute=執行
permission.api_report=接口報告
#接口管理
api_definition_not_exist=接口不存在

View File

@ -6,5 +6,5 @@ package io.metersphere.api.constants;
* @version: 1.0
*/
public enum ShareInfoType {
Single, Batch
SINGLE, BATCH, API_SHARE_REPORT, TEST_PLAN_SHARE_REPORT
}

View File

@ -0,0 +1,34 @@
package io.metersphere.api.controller;
import io.metersphere.api.dto.share.ShareInfoDTO;
import io.metersphere.api.service.ApiReportShareService;
import io.metersphere.sdk.domain.ShareInfo;
import io.metersphere.system.utils.SessionUtils;
import io.metersphere.validation.groups.Created;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Objects;
@RestController
@RequestMapping(value = "/api/report/share")
@Tag(name = "接口测试-接口报告-分享")
public class ApiReportShareController {
@Resource
private ApiReportShareService apiReportShareService;
@PostMapping("/gen")
public ShareInfoDTO generateShareInfo(@Validated(Created.class) @RequestBody ShareInfo request) {
return apiReportShareService.gen(request, Objects.requireNonNull(SessionUtils.getUser()));
}
@GetMapping("/get/{id}")
public ShareInfo get(@PathVariable String id) {
return apiReportShareService.get(id);
}
}

View File

@ -3,9 +3,14 @@ package io.metersphere.api.controller.definition;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.api.domain.ApiReport;
import io.metersphere.api.dto.definition.ApiReportBatchRequest;
import io.metersphere.api.dto.definition.ApiReportDTO;
import io.metersphere.api.dto.definition.ApiReportDetailDTO;
import io.metersphere.api.dto.definition.ApiReportPageRequest;
import io.metersphere.api.service.ApiReportShareService;
import io.metersphere.api.service.definition.ApiReportService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.system.dto.sdk.BasePageRequest;
import io.metersphere.sdk.domain.ShareInfo;
import io.metersphere.system.security.CheckOwner;
import io.metersphere.system.utils.PageUtils;
import io.metersphere.system.utils.Pager;
@ -14,12 +19,10 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@ -29,15 +32,75 @@ import java.util.List;
public class ApiReportController {
@Resource
private ApiReportService apiReportService;
@Resource
private ApiReportShareService apiReportShareService;
@PostMapping("/page")
@Operation(summary = "接口测试-接口报告-用例()")
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ)
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
public Pager<List<ApiReport>> getPage(@Validated @RequestBody BasePageRequest request) {
@RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_READ)
public Pager<List<ApiReport>> getPage(@Validated @RequestBody ApiReportPageRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "start_time desc");
return PageUtils.setPageInfo(page, apiReportService.getPage(request, SessionUtils.getCurrentProjectId()));
return PageUtils.setPageInfo(page, apiReportService.getPage(request));
}
@GetMapping("/rename/{id}/{name}")
@Operation(summary = "接口测试-接口报告-用例报告重命名")
@CheckOwner(resourceId = "#id", resourceType = "api_report")
@RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_UPDATE)
public void rename(@PathVariable String id, @PathVariable String name) {
apiReportService.rename(id, name, SessionUtils.getUserId());
}
@GetMapping("/delete/{id}")
@Operation(summary = "接口测试-接口报告-用例报告删除")
@CheckOwner(resourceId = "#id", resourceType = "api_report")
@RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_DELETE)
public void delete(@PathVariable String id) {
apiReportService.delete(id, SessionUtils.getUserId());
}
@PostMapping("/batch/delete")
@Operation(summary = "接口测试-接口报告-用例报告批量删除")
@CheckOwner(resourceId = "#request.getSelectIds()", resourceType = "api_report")
@RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_DELETE)
public void batchDelete(@RequestBody ApiReportBatchRequest request) {
apiReportService.batchDelete(request, SessionUtils.getUserId());
}
@GetMapping("/get/{id}")
@Operation(summary = "接口测试-接口报告-报告获取")
@CheckOwner(resourceId = "#id", resourceType = "api_report")
@RequiresPermissions(value = {PermissionConstants.PROJECT_API_REPORT_READ, PermissionConstants.PROJECT_API_DEFINITION_CASE_UPDATE}, logical = Logical.OR)
public ApiReportDTO get(@PathVariable String id) {
return apiReportService.get(id);
}
@GetMapping("/get/{shareId}/{reportId}")
@Operation(summary = "接口测试-接口报告-分享报告获取")
public ApiReport get(@PathVariable String shareId, @PathVariable String reportId) {
ShareInfo shareInfo = apiReportShareService.checkResource(shareId);
apiReportShareService.validateExpired(shareInfo);
return apiReportService.get(reportId);
}
@GetMapping("/get/detail/{reportId}/{stepId}")
@Operation(summary = "接口测试-接口报告-报告详情获取")
@CheckOwner(resourceId = "#reportId", resourceType = "api_report")
@RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_READ)
public List<ApiReportDetailDTO> getDetail(@PathVariable String stepId,
@PathVariable String reportId) {
return apiReportService.getDetail(stepId, reportId);
}
@GetMapping("/get/detail/{shareId}/{reportId}/{stepId}")
public List<ApiReportDetailDTO> selectReportContent(@PathVariable String shareId,
@PathVariable String reportId,
@PathVariable String stepId) {
ShareInfo shareInfo = apiReportShareService.checkResource(shareId);
apiReportShareService.validateExpired(shareInfo);
return apiReportService.getDetail(stepId, reportId);
}
}

View File

@ -0,0 +1,12 @@
package io.metersphere.api.dto.definition;
import io.metersphere.system.dto.table.TableBatchProcessDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class ApiReportBatchRequest extends TableBatchProcessDTO {
@Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED)
private String projectId;
}

View File

@ -0,0 +1,15 @@
package io.metersphere.api.dto.definition;
import io.metersphere.api.domain.ApiReport;
import io.metersphere.api.domain.ApiReportStep;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class ApiReportDTO extends ApiReport {
@Schema(description = "子节点")
private List<ApiReportStep> children;
}

View File

@ -0,0 +1,44 @@
package io.metersphere.api.dto.definition;
import io.metersphere.sdk.dto.api.result.RequestResult;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class ApiReportDetailDTO {
@Schema(description = "报告详情id")
private String id;
@Schema(description = "接口报告id")
private String reportId;
@Schema(description = "各个步骤请求唯一标识")
private String stepId;
@Schema(description = "结果状态")
private String status;
@Schema(description = "误报编号/误报状态独有")
private String fakeCode;
@Schema(description = "请求名称")
private String requestName;
@Schema(description = "请求耗时")
private Long requestTime;
@Schema(description = "请求响应码")
private String code;
@Schema(description = "响应内容大小")
private Long responseSize;
@Schema(description = "脚本标识")
private String scriptIdentifier;
@Schema(description = "结果内容详情")
private RequestResult content;
}

View File

@ -0,0 +1,12 @@
package io.metersphere.api.dto.definition;
import io.metersphere.system.dto.sdk.BasePageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class ApiReportPageRequest extends BasePageRequest {
@Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED)
private String projectId;
}

View File

@ -1,12 +1,16 @@
package io.metersphere.api.mapper;
import io.metersphere.api.domain.ApiReport;
import io.metersphere.system.dto.sdk.BasePageRequest;
import io.metersphere.api.dto.definition.ApiReportBatchRequest;
import io.metersphere.api.dto.definition.ApiReportPageRequest;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ExtApiReportMapper {
List<ApiReport> list(@Param("request") BasePageRequest request, @Param("projectId") String projectId);
List<ApiReport> list(@Param("request") ApiReportPageRequest request);
List<String> getIds(@Param("request") ApiReportBatchRequest request);
List<ApiReport> selectApiReportByIds(@Param("ids") List<String> ids, @Param("deleted") boolean deleted);
}

View File

@ -13,16 +13,48 @@
api_report.create_user,
api_report.update_user,
api_report.trigger_mode
from api_report where api_report.project_id = #{projectId}
from api_report where api_report.deleted = false
and api_report.test_plan_id = 'NONE'
<if test="request.keyword != null and request.keyword != ''">
and (
api_report.name like concat('%', #{request.keyword},'%')
)
</if>
<if test="request.projectId != null and request.projectId != ''">
and api_report.project_id = #{request.projectId}
</if>
<include refid="filters">
<property name="filter" value="request.filter"/>
</include>
</select>
<select id="getIds" resultType="java.lang.String">
select
api_report.id
from api_report where api_report.deleted = false
and api_report.test_plan_id = 'NONE'
<if test="request.condition.keyword != null">
and (
api_report.name like concat('%', #{request.condition.keyword},'%')
)
</if>
<if test="request.projectId != null and request.projectId != ''">
and api_report.project_id = #{request.projectId}
</if>
<include refid="filters">
<property name="filter" value="request.condition.filter"/>
</include>
</select>
<select id="selectApiReportByIds" resultType="io.metersphere.api.domain.ApiReport">
select
api_report.id,
api_report.name
from api_report where api_report.deleted = #{deleted}
and api_report.test_plan_id = 'NONE'
and api_report.id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<sql id="filters">
@ -38,6 +70,10 @@
and api_report.status in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
<when test="key=='triggerMode'">
and api_report.trigger_mode in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
</choose>
</if>
</foreach>

View File

@ -0,0 +1,120 @@
package io.metersphere.api.service;
import io.metersphere.api.constants.ShareInfoType;
import io.metersphere.api.domain.ApiReport;
import io.metersphere.api.dto.share.ShareInfoDTO;
import io.metersphere.api.mapper.ApiReportMapper;
import io.metersphere.api.mapper.ApiScenarioReportMapper;
import io.metersphere.project.domain.ProjectApplication;
import io.metersphere.project.domain.ProjectApplicationExample;
import io.metersphere.project.mapper.ProjectApplicationMapper;
import io.metersphere.sdk.domain.ShareInfo;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.mapper.ShareInfoMapper;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.dto.sdk.SessionUser;
import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import static io.metersphere.sdk.util.ShareUtil.getTimeMills;
@Service
@Transactional(rollbackFor = Exception.class)
public class ApiReportShareService {
@Resource
private ApiReportMapper apiReportMapper;
@Resource
private ShareInfoMapper shareInfoMapper;
@Resource
private ProjectApplicationMapper projectApplicationMapper;
@Resource
private ApiScenarioReportMapper apiScenarioReportMapper;
private static final Long DEFAULT = 1000L * 60 * 60 * 24 * 30;
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void validateExpired(ShareInfo shareInfo) {
String shareType = shareInfo.getShareType();
String projectId = "";
if (StringUtils.equals(shareType, ShareInfoType.API_SHARE_REPORT.name())) {
ApiReport apiReport = apiReportMapper.selectByPrimaryKey(new String(shareInfo.getCustomData()));
if (apiReport != null && BooleanUtils.isFalse(apiReport.getDeleted())) {
projectId = apiReport.getProjectId();
} /*else {
ApiScenarioReport result = apiScenarioReportMapper.selectByPrimaryKey(new String(shareInfo.getCustomData()));
if (result != null && BooleanUtils.isFalse(result.getDeleted())) {
projectId = result.getProjectId();
}
}*/
}
if (StringUtils.isBlank(projectId)) {
throw new MSException(Translator.get("api_case_report_not_exist"));
}
ProjectApplicationExample example = new ProjectApplicationExample();
example.createCriteria().andProjectIdEqualTo(projectId).andTypeEqualTo(shareType);
List<ProjectApplication> projectApplications = projectApplicationMapper.selectByExample(example);
if (CollectionUtils.isEmpty(projectApplications)) {
millisCheck(System.currentTimeMillis() - shareInfo.getUpdateTime(), DEFAULT, shareInfo.getId());
} else {
String expr = projectApplications.getFirst().getTypeValue();
long timeMills = getTimeMills(shareInfo.getUpdateTime(), expr);
millisCheck(System.currentTimeMillis(), timeMills, shareInfo.getId());
}
}
private void millisCheck(long compareMillis, long millis, String shareInfoId) {
if (compareMillis > millis) {
shareInfoMapper.deleteByPrimaryKey(shareInfoId);
throw new MSException(Translator.get("connection_expired"));
}
}
public ShareInfo createShareInfo(ShareInfo shareInfo) {
long createTime = System.currentTimeMillis();
shareInfo.setId(IDGenerator.nextStr());
shareInfo.setCreateTime(createTime);
shareInfo.setUpdateTime(createTime);
shareInfoMapper.insert(shareInfo);
return shareInfo;
}
public ShareInfoDTO conversionShareInfoToDTO(ShareInfo shareInfo) {
ShareInfoDTO returnDTO = new ShareInfoDTO();
if (null != shareInfo.getCustomData()) {
String url = "?shareId=" + shareInfo.getId();
returnDTO.setId(shareInfo.getId());
returnDTO.setShareUrl(url);
}
return returnDTO;
}
public ShareInfoDTO gen(ShareInfo request, SessionUser user) {
String lang = user.getLanguage() == null ? LocaleContextHolder.getLocale().toString() : user.getLanguage();
request.setLang(lang);
request.setCreateUser(user.getId());
ShareInfo shareInfo = createShareInfo(request);
return conversionShareInfoToDTO(shareInfo);
}
public ShareInfo checkResource(String id) {
ShareInfo shareInfo = shareInfoMapper.selectByPrimaryKey(id);
if (shareInfo == null) {
throw new RuntimeException(Translator.get("connection_expired"));
}
return shareInfo;
}
public ShareInfo get(String id) {
return checkResource(id);
}
}

View File

@ -19,7 +19,6 @@ import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* @author: LAN
@ -37,6 +36,8 @@ public class ApiShareService {
@Resource
ApiDefinitionService apiDefinitionService;
@Resource
ApiReportShareService apiReportShareService;
/**
* 生成 api 接口文档分享信息
@ -54,30 +55,30 @@ public class ApiShareService {
shareInfoRequest.setCreateUser(user.getId());
shareInfoRequest.setLang(lang);
shareInfoRequest.setCustomData(data.getBytes());
shareInfoRequest.setProjectId(request.getProjectId());
});
ShareInfo shareInfo = Optional.ofNullable(customData)
.map(data -> genShareInfo(shareInfoRequest))
.orElse(new ShareInfo());
return conversionShareInfoToDTO(shareInfo);
return apiReportShareService.conversionShareInfoToDTO(shareInfo);
}
private String genCustomData(ApiDefinitionDocRequest request, ShareInfo shareInfoRequest) {
String customData = null;
if (ApiDefinitionDocType.ALL.name().equals(request.getType()) || ApiDefinitionDocType.MODULE.name().equals(request.getType())) {
customData = JSON.toJSONString(request);
shareInfoRequest.setShareType(ShareInfoType.Batch.name());
shareInfoRequest.setShareType(ShareInfoType.BATCH.name());
} else if (ApiDefinitionDocType.API.name().equals(request.getType())) {
apiDefinitionService.checkApiDefinition(request.getApiId());
customData = JSON.toJSONString(request);
shareInfoRequest.setShareType(ShareInfoType.Single.name());
shareInfoRequest.setShareType(ShareInfoType.SINGLE.name());
}
return customData;
}
/**
* 生成分享连接
* 如果该数据有连接则返回已有的连接不做有效期判断, 反之创建链接
@ -87,27 +88,9 @@ public class ApiShareService {
*/
public ShareInfo genShareInfo(ShareInfo request) {
List<ShareInfo> shareInfos = extShareInfoMapper.selectByShareTypeAndShareApiIdWithBLOBs(request.getShareType(), request.getCustomData(), request.getLang());
return shareInfos.isEmpty() ? createShareInfo(request) : shareInfos.get(0);
return shareInfos.isEmpty() ? apiReportShareService.createShareInfo(request) : shareInfos.getFirst();
}
public ShareInfo createShareInfo(ShareInfo shareInfo) {
long createTime = System.currentTimeMillis();
shareInfo.setId(UUID.randomUUID().toString());
shareInfo.setCreateTime(createTime);
shareInfo.setUpdateTime(createTime);
shareInfoMapper.insert(shareInfo);
return shareInfo;
}
public ShareInfoDTO conversionShareInfoToDTO(ShareInfo shareInfo) {
ShareInfoDTO returnDTO = new ShareInfoDTO();
if (null != shareInfo.getCustomData()) {
String url = "?shareId=" + shareInfo.getId();
returnDTO.setId(shareInfo.getId());
returnDTO.setShareUrl(url);
}
return returnDTO;
}
public ApiDefinitionDocDTO shareDocView(String shareId) {
ShareInfo shareInfo = shareInfoMapper.selectByPrimaryKey(shareId);

View File

@ -0,0 +1,85 @@
package io.metersphere.api.service.definition;
import io.metersphere.api.domain.ApiReport;
import io.metersphere.api.mapper.ExtApiReportMapper;
import io.metersphere.project.domain.Project;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.log.constants.OperationLogModule;
import io.metersphere.system.log.constants.OperationLogType;
import io.metersphere.system.log.dto.LogDTO;
import io.metersphere.system.log.service.OperationLogService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class ApiReportLogService {
@Resource
private ProjectMapper projectMapper;
@Resource
private OperationLogService operationLogService;
@Resource
private ExtApiReportMapper extApiReportMapper;
public void deleteLog(ApiReport apiReport) {
Project project = projectMapper.selectByPrimaryKey(apiReport.getProjectId());
LogDTO dto = new LogDTO(
apiReport.getProjectId(),
project.getOrganizationId(),
apiReport.getId(),
apiReport.getUpdateUser(),
OperationLogType.DELETE.name(),
OperationLogModule.API_REPORT,
apiReport.getName());
dto.setPath("/api/report/case/delete/" + apiReport.getId());
dto.setMethod(HttpMethodConstants.GET.name());
dto.setOriginalValue(JSON.toJSONBytes(apiReport));
operationLogService.add(dto);
}
public void updateLog(ApiReport apiReport) {
Project project = projectMapper.selectByPrimaryKey(apiReport.getProjectId());
LogDTO dto = new LogDTO(
apiReport.getProjectId(),
project.getOrganizationId(),
apiReport.getId(),
apiReport.getUpdateUser(),
OperationLogType.UPDATE.name(),
OperationLogModule.API_REPORT,
apiReport.getName());
dto.setPath("/api/report/case/rename/" + apiReport.getId() + "/" + apiReport.getName());
dto.setMethod(HttpMethodConstants.GET.name());
dto.setOriginalValue(JSON.toJSONBytes(apiReport));
operationLogService.add(dto);
}
public void batchDeleteLog(List<String> ids, String userId, String projectId) {
Project project = projectMapper.selectByPrimaryKey(projectId);
List<ApiReport> apiReports = extApiReportMapper.selectApiReportByIds(ids, true);
List<LogDTO> logs = new ArrayList<>();
apiReports.forEach(apiReport -> {
LogDTO dto = new LogDTO(
projectId,
project.getOrganizationId(),
apiReport.getId(),
userId,
OperationLogType.DELETE.name(),
OperationLogModule.API_REPORT,
apiReport.getName());
dto.setPath("/api/report/case/batch/delete");
dto.setMethod(HttpMethodConstants.POST.name());
dto.setOriginalValue(JSON.toJSONBytes(apiReport));
logs.add(dto);
});
operationLogService.batchAdd(logs);
}
}

View File

@ -1,12 +1,20 @@
package io.metersphere.api.service.definition;
import io.metersphere.api.domain.ApiReport;
import io.metersphere.api.domain.ApiReportStep;
import io.metersphere.api.domain.*;
import io.metersphere.api.dto.definition.ApiReportBatchRequest;
import io.metersphere.api.dto.definition.ApiReportDTO;
import io.metersphere.api.dto.definition.ApiReportDetailDTO;
import io.metersphere.api.dto.definition.ApiReportPageRequest;
import io.metersphere.api.mapper.ApiReportDetailMapper;
import io.metersphere.api.mapper.ApiReportMapper;
import io.metersphere.api.mapper.ApiReportStepMapper;
import io.metersphere.api.mapper.ExtApiReportMapper;
import io.metersphere.api.utils.ApiDataUtils;
import io.metersphere.sdk.dto.api.result.RequestResult;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.SubListUtils;
import io.metersphere.system.dto.sdk.BasePageRequest;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.service.UserLoginService;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
@ -18,10 +26,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -38,6 +43,13 @@ public class ApiReportService {
private ExtApiReportMapper extApiReportMapper;
@Resource
private UserLoginService userLoginService;
@Resource
private ApiReportStepMapper apiReportStepMapper;
@Resource
private ApiReportDetailMapper apiReportDetailMapper;
@Resource
private ApiReportLogService apiReportLogService;
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public void insertApiReport(List<ApiReport> reports) {
@ -46,8 +58,6 @@ public class ApiReportService {
ApiReportMapper reportMapper = sqlSession.getMapper(ApiReportMapper.class);
SubListUtils.dealForSubList(reports, 1000, subList -> {
subList.forEach(reportMapper::insertSelective);
sqlSession.flushStatements();
sqlSession.clearCache();
});
sqlSession.flushStatements();
if (sqlSessionFactory != null) {
@ -63,8 +73,6 @@ public class ApiReportService {
ApiReportStepMapper stepMapper = sqlSession.getMapper(ApiReportStepMapper.class);
SubListUtils.dealForSubList(reportSteps, 1000, subList -> {
subList.forEach(stepMapper::insertSelective);
sqlSession.flushStatements();
sqlSession.clearCache();
});
sqlSession.flushStatements();
if (sqlSessionFactory != null) {
@ -73,8 +81,8 @@ public class ApiReportService {
}
}
public List<ApiReport> getPage(BasePageRequest request, String projectId) {
List<ApiReport> list = extApiReportMapper.list(request, projectId);
public List<ApiReport> getPage(ApiReportPageRequest request) {
List<ApiReport> list = extApiReportMapper.list(request);
//取所有的userid
Set<String> userSet = list.stream()
.flatMap(apiReport -> Stream.of(apiReport.getUpdateUser(), apiReport.getDeleteUser(), apiReport.getCreateUser()))
@ -87,4 +95,99 @@ public class ApiReportService {
});
return list;
}
public void rename(String id, String name, String userId) {
ApiReport apiReport = checkResource(id);
apiReport.setName(name);
apiReport.setUpdateTime(System.currentTimeMillis());
apiReport.setUpdateUser(userId);
apiReportMapper.updateByPrimaryKeySelective(apiReport);
apiReportLogService.updateLog(apiReport);
}
public void delete(String id, String userId) {
ApiReport apiReport = checkResource(id);
apiReport.setDeleted(true);
apiReport.setDeleteTime(System.currentTimeMillis());
apiReport.setDeleteUser(userId);
apiReportMapper.updateByPrimaryKeySelective(apiReport);
apiReportLogService.deleteLog(apiReport);
}
private ApiReport checkResource(String id) {
ApiReport apiReport = apiReportMapper.selectByPrimaryKey(id);
if (apiReport == null) {
throw new RuntimeException(Translator.get("api_case_report_not_exist"));
}
return apiReport;
}
public void batchDelete(ApiReportBatchRequest request, String userId) {
List<String> ids = doSelectIds(request);
if (CollectionUtils.isEmpty(ids)) {
return;
}
SubListUtils.dealForSubList(ids, 2000, subList -> {
ApiReportExample example = new ApiReportExample();
example.createCriteria().andIdIn(subList);
ApiReport apiReport = new ApiReport();
apiReport.setDeleted(true);
apiReport.setDeleteTime(System.currentTimeMillis());
apiReport.setDeleteUser(userId);
apiReportMapper.updateByExampleSelective(apiReport, example);
//TODO 记录日志
apiReportLogService.batchDeleteLog(subList, userId, request.getProjectId());
});
}
public List<String> doSelectIds(ApiReportBatchRequest request) {
if (request.isSelectAll()) {
List<String> ids = extApiReportMapper.getIds(request);
if (CollectionUtils.isNotEmpty(request.getExcludeIds())) {
ids.removeAll(request.getExcludeIds());
}
return ids;
} else {
request.getSelectIds().removeAll(request.getExcludeIds());
return request.getSelectIds();
}
}
public ApiReportDTO get(String id) {
ApiReportDTO apiReportDTO = new ApiReportDTO();
ApiReport apiReport = checkResource(id);
BeanUtils.copyBean(apiReportDTO, apiReport);
//需要查询出所有的步骤
ApiReportStepExample apiReportStep = new ApiReportStepExample();
apiReportStep.createCriteria().andReportIdEqualTo(id);
List<ApiReportStep> apiReportSteps = apiReportStepMapper.selectByExample(apiReportStep);
if (CollectionUtils.isEmpty(apiReportSteps)) {
throw new MSException(Translator.get("api_case_report_not_exist"));
}
apiReportSteps.sort(Comparator.comparingLong(ApiReportStep::getSort));
apiReportDTO.setChildren(apiReportSteps);
return apiReportDTO;
}
public List<ApiReportDetailDTO> getDetail(String stepId, String reportId) {
List<ApiReportDetail> apiReportDetails = checkResourceStep(stepId, reportId);
List<ApiReportDetailDTO> results = new ArrayList<>();
apiReportDetails.forEach(apiReportDetail -> {
ApiReportDetailDTO apiReportDetailDTO = new ApiReportDetailDTO();
BeanUtils.copyBean(apiReportDetailDTO, apiReportDetail);
apiReportDetailDTO.setContent(ApiDataUtils.parseObject(new String(apiReportDetail.getContent()), RequestResult.class));
results.add(apiReportDetailDTO);
});
return results;
}
private List<ApiReportDetail> checkResourceStep(String stepId, String reportId) {
ApiReportDetailExample apiReportDetailExample = new ApiReportDetailExample();
apiReportDetailExample.createCriteria().andStepIdEqualTo(stepId).andReportIdEqualTo(reportId);
List<ApiReportDetail> apiReportDetails = apiReportDetailMapper.selectByExampleWithBLOBs(apiReportDetailExample);
if (CollectionUtils.isEmpty(apiReportDetails)) {
throw new MSException(Translator.get("api_case_report_not_exist"));
}
return apiReportDetails;
}
}

View File

@ -31,8 +31,6 @@ public class ApiScenarioReportService {
ApiScenarioReportMapper reportMapper = sqlSession.getMapper(ApiScenarioReportMapper.class);
SubListUtils.dealForSubList(reports, 1000, subList -> {
subList.forEach(reportMapper::insertSelective);
sqlSession.flushStatements();
sqlSession.clearCache();
});
sqlSession.flushStatements();
if (sqlSessionFactory != null) {
@ -48,8 +46,6 @@ public class ApiScenarioReportService {
ApiScenarioReportStepMapper stepMapper = sqlSession.getMapper(ApiScenarioReportStepMapper.class);
SubListUtils.dealForSubList(reportSteps, 1000, subList -> {
subList.forEach(stepMapper::insertSelective);
sqlSession.flushStatements();
sqlSession.clearCache();
});
sqlSession.flushStatements();
if (sqlSessionFactory != null) {

View File

@ -129,6 +129,21 @@
"id": "PROJECT_API_SCENARIO:READ+DEBUG"
}
]
},
{
"id": "PROJECT_API_REPORT",
"name": "permission.api_report",
"permissions": [
{
"id": "PROJECT_API_REPORT:READ"
},
{
"id": "PROJECT_API_REPORT:READ+UPDATE"
},
{
"id": "PROJECT_API_REPORT:READ+DELETE"
}
]
}
]
}

View File

@ -59,12 +59,12 @@ public class ApiDefinitionScheduleControllerTests extends BaseTest {
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID);
List<ApiDefinitionSwagger> apiDefinitionSwaggers = apiDefinitionSwaggerMapper.selectByExample(example);
assert apiDefinitionSwaggers.size() == 1;
ID = apiDefinitionSwaggers.get(0).getId();
ID = apiDefinitionSwaggers.getFirst().getId();
ScheduleExample scheduleExample = new ScheduleExample();
scheduleExample.createCriteria().andResourceIdEqualTo(apiDefinitionSwaggers.get(0).getId());
scheduleExample.createCriteria().andResourceIdEqualTo(apiDefinitionSwaggers.getFirst().getId());
List<Schedule> schedules = scheduleMapper.selectByExample(scheduleExample);
assert schedules.size() == 1;
SCHEDULE_ID = schedules.get(0).getId();
SCHEDULE_ID = schedules.getFirst().getId();
request = new ApiScheduleRequest();
request.setName("定时任务2");

View File

@ -1,19 +1,29 @@
package io.metersphere.api.controller;
import io.metersphere.api.domain.ApiReport;
import io.metersphere.api.domain.ApiReportExample;
import io.metersphere.api.domain.ApiReportStep;
import io.metersphere.api.domain.ApiReportStepExample;
import io.metersphere.api.constants.ShareInfoType;
import io.metersphere.api.domain.*;
import io.metersphere.api.dto.definition.ApiReportBatchRequest;
import io.metersphere.api.dto.definition.ApiReportDTO;
import io.metersphere.api.dto.definition.ApiReportDetailDTO;
import io.metersphere.api.dto.definition.ApiReportPageRequest;
import io.metersphere.api.dto.scenario.ApiScenarioDTO;
import io.metersphere.api.dto.share.ShareInfoDTO;
import io.metersphere.api.mapper.ApiReportDetailMapper;
import io.metersphere.api.mapper.ApiReportMapper;
import io.metersphere.api.mapper.ApiReportStepMapper;
import io.metersphere.api.service.definition.ApiReportService;
import io.metersphere.api.utils.ApiDataUtils;
import io.metersphere.project.domain.ProjectApplication;
import io.metersphere.project.domain.ProjectApplicationExample;
import io.metersphere.project.mapper.ProjectApplicationMapper;
import io.metersphere.sdk.constants.ApiReportStatus;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.constants.SessionConstants;
import io.metersphere.sdk.domain.ShareInfo;
import io.metersphere.sdk.mapper.ShareInfoMapper;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
import io.metersphere.system.dto.sdk.BasePageRequest;
import io.metersphere.system.utils.Pager;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.*;
@ -21,6 +31,7 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.nio.charset.StandardCharsets;
@ -42,6 +53,21 @@ public class ApiReportControllerTests extends BaseTest {
private ApiReportMapper apiReportMapper;
@Resource
private ApiReportStepMapper apiReportStepMapper;
@Resource
private ApiReportDetailMapper apiReportDetailMapper;
@Resource
private ShareInfoMapper shareInfoMapper;
@Resource
private ProjectApplicationMapper projectApplicationMapper;
private static final String BASIC = "/api/report/case";
private static final String PAGE = BASIC + "/page";
private static final String RENAME = BASIC + "/rename/";
private static final String DELETE = BASIC + "/delete/";
private static final String GET = BASIC + "/get/";
private static final String BATCH_DELETE = BASIC + "/batch/delete";
private static final String DETAIL = BASIC + "/get/detail/";
@Test
@Order(1)
@ -77,7 +103,7 @@ public class ApiReportControllerTests extends BaseTest {
for (int i = 0; i < 1515; i++) {
ApiReportStep apiReportStep = new ApiReportStep();
apiReportStep.setStepId("api-report-step-id" + i);
apiReportStep.setReportId("api-report-id" + i);
apiReportStep.setReportId("api-report-id-success" + i);
apiReportStep.setSort(0L);
apiReportStep.setStepType("case");
steps.add(apiReportStep);
@ -91,7 +117,6 @@ public class ApiReportControllerTests extends BaseTest {
return mockMvc.perform(MockMvcRequestBuilders.post(url)
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.header(SessionConstants.CURRENT_PROJECT, DEFAULT_PROJECT_ID)
.content(JSON.toJSONString(param))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
@ -113,10 +138,11 @@ public class ApiReportControllerTests extends BaseTest {
@Test
@Order(2)
public void testGetPage() throws Exception {
BasePageRequest request = new BasePageRequest();
ApiReportPageRequest request = new ApiReportPageRequest();
request.setCurrent(1);
request.setPageSize(10);
MvcResult mvcResult = responsePost("/api/report/case/page", request);
request.setProjectId(DEFAULT_PROJECT_ID);
MvcResult mvcResult = responsePost(PAGE, request);
Pager<?> returnPager = parseObjectFromMvcResult(mvcResult, Pager.class);
//返回值不为空
Assertions.assertNotNull(returnPager);
@ -127,18 +153,245 @@ public class ApiReportControllerTests extends BaseTest {
Assertions.assertTrue(((List<ApiScenarioDTO>) returnPager.getList()).size() <= request.getPageSize());
//过滤
request.setFilter(new HashMap<>() {{
put("status", List.of("SUCCESS", "ERROR"));
put("status", List.of(ApiReportStatus.SUCCESS.name(), ApiReportStatus.ERROR.name()));
}});
mvcResult = responsePost("/api/report/case/page", request);
mvcResult = responsePost(PAGE, request);
returnPager = parseObjectFromMvcResult(mvcResult, Pager.class);
//返回值不为空
Assertions.assertNotNull(returnPager);
Assertions.assertTrue(((List<ApiReport>) returnPager.getList()).size() <= request.getPageSize());
List<ApiReport> list = JSON.parseArray(JSON.toJSONString(returnPager.getList()), ApiReport.class);
list.forEach(apiReport -> {
Assertions.assertTrue(apiReport.getStatus().equals("SUCCESS") || apiReport.getStatus().equals("ERROR"));
Assertions.assertTrue(apiReport.getStatus().equals(ApiReportStatus.SUCCESS.name()) || apiReport.getStatus().equals(ApiReportStatus.ERROR.name()));
});
//校验权限
requestPostPermissionTest(PermissionConstants.PROJECT_API_REPORT_READ, PAGE, request);
}
protected ResultActions requestGetWithOk(String url, Object... uriVariables) throws Exception {
return mockMvc.perform(getRequestBuilder(url, uriVariables))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
@Test
@Order(3)
public void testRename() throws Exception {
// @@请求成功
String newName = "api-report-new-name";
requestGetWithOk(RENAME + "api-report-id0" + "/" + newName);
ApiReport apiReport = apiReportMapper.selectByPrimaryKey("api-report-id0");
Assertions.assertNotNull(apiReport);
Assertions.assertEquals(apiReport.getName(), newName);
mockMvc.perform(getRequestBuilder(RENAME + "api-report" + "/" + newName))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
// @@校验权限
requestGetPermissionTest(PermissionConstants.PROJECT_API_REPORT_UPDATE, RENAME + "api-report-id0" + "/" + newName);
}
@Test
@Order(4)
public void testDeleted() throws Exception {
// @@请求成功
requestGetWithOk(DELETE + "api-report-id0");
ApiReport apiReport = apiReportMapper.selectByPrimaryKey("api-report-id0");
Assertions.assertNotNull(apiReport);
Assertions.assertTrue(apiReport.getDeleted());
mockMvc.perform(getRequestBuilder(RENAME + "api-report"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
// @@校验权限
requestGetPermissionTest(PermissionConstants.PROJECT_API_REPORT_DELETE, DELETE + "api-report-id1");
}
@Test
@Order(5)
public void testBatch() throws Exception {
// @@请求成功
ApiReportBatchRequest request = new ApiReportBatchRequest();
request.setProjectId(DEFAULT_PROJECT_ID);
request.setSelectIds(List.of("api-report-id3"));
request.setExcludeIds(List.of("api-report-id3"));
responsePost(BATCH_DELETE, request);
request.setSelectIds(List.of("api-report-id4"));
responsePost(BATCH_DELETE, request);
ApiReport apiReport = apiReportMapper.selectByPrimaryKey("api-report-id4");
Assertions.assertNotNull(apiReport);
Assertions.assertTrue(apiReport.getDeleted());
request.setSelectAll(true);
responsePost(BATCH_DELETE, request);
// @@校验权限
requestPostPermissionTest(PermissionConstants.PROJECT_API_REPORT_DELETE, BATCH_DELETE, request);
}
@Test
@Order(6)
public void testGet() throws Exception {
// @@请求成功
List<ApiReport> reports = new ArrayList<>();
ApiReport apiReport = new ApiReport();
apiReport.setId("test-report-id");
apiReport.setProjectId(DEFAULT_PROJECT_ID);
apiReport.setName("test-report-name");
apiReport.setStartTime(System.currentTimeMillis());
apiReport.setResourceId("test-resource-id");
apiReport.setCreateUser("admin");
apiReport.setUpdateUser("admin");
apiReport.setUpdateTime(System.currentTimeMillis());
apiReport.setPoolId("api-pool-id");
apiReport.setEnvironmentId("api-environment-id");
apiReport.setRunMode("api-run-mode");
apiReport.setStatus(ApiReportStatus.SUCCESS.name());
apiReport.setTriggerMode("api-trigger-mode");
apiReport.setVersionId("api-version-id");
reports.add(apiReport);
apiReportService.insertApiReport(reports);
List<ApiReportStep> steps = new ArrayList<>();
for (int i = 0; i < 5; i++) {
ApiReportStep apiReportStep = new ApiReportStep();
apiReportStep.setStepId("test-report-step-id" + i);
apiReportStep.setReportId("test-report-id");
apiReportStep.setSort((long) i);
apiReportStep.setStepType("case");
steps.add(apiReportStep);
}
apiReportService.insertApiReportStep(steps);
MvcResult mvcResult = this.requestGetWithOk(GET + "test-report-id")
.andReturn();
ApiReportDTO apiReportDTO = ApiDataUtils.parseObject(JSON.toJSONString(parseResponse(mvcResult).get("data")), ApiReportDTO.class);
Assertions.assertNotNull(apiReportDTO);
Assertions.assertEquals(apiReportDTO.getId(), "test-report-id");
mockMvc.perform(getRequestBuilder(GET + "test"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
mockMvc.perform(getRequestBuilder(GET + "api-report-id10"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
// @@校验权限
requestGetPermissionTest(PermissionConstants.PROJECT_API_REPORT_READ, GET + "api-report-id0");
}
@Test
@Order(6)
public void testGetDetail() throws Exception {
// @@请求成功
List<ApiReportDetail> reports = new ArrayList<>();
for (int i = 0; i < 2; i++) {
ApiReportDetail apiReportDetail = new ApiReportDetail();
apiReportDetail.setId("test-report-detail-id" + i);
apiReportDetail.setReportId("test-report-id");
apiReportDetail.setStepId("test-report-step-id1");
apiReportDetail.setStatus("success");
apiReportDetail.setResponseSize(0L);
apiReportDetail.setRequestTime((long) i);
apiReportDetail.setContent("{\"resourceId\":\"\",\"stepId\":null,\"threadName\":\"Thread Group\",\"name\":\"HTTP Request1\",\"url\":\"https://www.baidu.com/\",\"requestSize\":195,\"startTime\":1705570589125,\"endTime\":1705570589310,\"error\":1,\"headers\":\"Connection: keep-alive\\nContent-Length: 0\\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\\nHost: www.baidu.com\\nUser-Agent: Apache-HttpClient/4.5.14 (Java/21)\\n\",\"cookies\":\"\",\"body\":\"POST https://www.baidu.com/\\n\\nPOST data:\\n\\n\\n[no cookies]\\n\",\"status\":\"ERROR\",\"method\":\"POST\",\"assertionTotal\":1,\"passAssertionsTotal\":0,\"subRequestResults\":[],\"responseResult\":{\"responseCode\":\"200\",\"responseMessage\":\"OK\",\"responseTime\":185,\"latency\":180,\"responseSize\":2559,\"headers\":\"HTTP/1.1 200 OK\\nContent-Length: 2443\\nContent-Type: text/html\\nServer: bfe\\nDate: Thu, 18 Jan 2024 09:36:29 GMT\\n\",\"body\":\"<!DOCTYPE html>\\r\\n<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class=\\\"bg s_ipt_wr\\\"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus=autofocus></span><span class=\\\"bg s_btn_wr\\\"><input type=submit id=su value=百度一下 class=\\\"bg s_btn\\\" autofocus></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=https://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href=\\\"http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === \\\"\\\" ? \\\"?\\\" : \\\"&\\\")+ \\\"bdorz_come=1\\\")+ '\\\" name=\\\"tj_login\\\" class=\\\"lb\\\">登录</a>');\\r\\n </script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style=\\\"display: block;\\\">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>\\r\\n\",\"contentType\":\"text/html\",\"vars\":null,\"imageUrl\":null,\"socketInitTime\":14,\"dnsLookupTime\":0,\"tcpHandshakeTime\":0,\"sslHandshakeTime\":0,\"transferStartTime\":166,\"downloadTime\":5,\"bodySize\":2443,\"headerSize\":116,\"assertions\":[{\"name\":\"JSON Assertion\",\"content\":null,\"script\":null,\"message\":\"Expected to find an object with property ['test'] in path $ but found 'java.lang.String'. This is not a json object according to the JsonProvider: 'com.jayway.jsonpath.spi.json.JsonSmartJsonProvider'.\",\"pass\":false}]},\"isSuccessful\":false,\"fakeErrorMessage\":\"\",\"fakeErrorCode\":null}\n".getBytes());
reports.add(apiReportDetail);
}
apiReportDetailMapper.batchInsert(reports);
MvcResult mvcResult = this.requestGetWithOk(DETAIL + "test-report-id" + "/" + "test-report-step-id1")
.andReturn();
List<ApiReportDetailDTO> data = ApiDataUtils.parseArray(JSON.toJSONString(parseResponse(mvcResult).get("data")), ApiReportDetailDTO.class);
Assertions.assertNotNull(data);
mockMvc.perform(getRequestBuilder(DETAIL + "test"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
mockMvc.perform(getRequestBuilder(DETAIL + "api-report-id10"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
// @@校验权限
requestGetPermissionTest(PermissionConstants.PROJECT_API_REPORT_READ, GET + "api-report-id0");
}
//分享报告
@Test
@Order(7)
public void generateUrl() throws Exception {
ShareInfo shareInfo = new ShareInfo();
shareInfo.setCustomData("test-report-id".getBytes());
shareInfo.setProjectId(DEFAULT_PROJECT_ID);
shareInfo.setShareType(ShareInfoType.API_SHARE_REPORT.name());
MvcResult mvcResult = responsePost("/api/report/share/gen", shareInfo);
ShareInfoDTO shareInfoDTO = parseObjectFromMvcResult(mvcResult, ShareInfoDTO.class);
Assertions.assertNotNull(shareInfoDTO);
Assertions.assertNotNull(shareInfoDTO.getShareUrl());
Assertions.assertNotNull(shareInfoDTO.getId());
String shareId = shareInfoDTO.getId();
MvcResult mvcResult1 = this.requestGetWithOk(GET + shareId + "/" + "test-report-id")
.andReturn();
ApiReportDTO apiReportDTO = ApiDataUtils.parseObject(JSON.toJSONString(parseResponse(mvcResult1).get("data")), ApiReportDTO.class);
Assertions.assertNotNull(apiReportDTO);
Assertions.assertEquals(apiReportDTO.getId(), "test-report-id");
this.requestGetWithOk("/api/report/share/get/" + shareId)
.andReturn();
mockMvc.perform(getRequestBuilder("/api/report/share/get/" + "test"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
mvcResult = this.requestGetWithOk(DETAIL + shareId + "/" + "test-report-id" + "/" + "test-report-step-id1")
.andReturn();
List<ApiReportDetailDTO> data = ApiDataUtils.parseArray(JSON.toJSONString(parseResponse(mvcResult).get("data")), ApiReportDetailDTO.class);
Assertions.assertNotNull(data);
//过期时间时间戳 1702950953000 2023-12-19 09:55:53
ShareInfo shareInfo1 = shareInfoMapper.selectByPrimaryKey(shareId);
shareInfo1.setUpdateTime(1702950953000L);
shareInfoMapper.updateByPrimaryKey(shareInfo1);
mockMvc.perform(getRequestBuilder(GET + shareId + "/" + "test-report-id"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
//TODO 过期的校验 未完成 需要补充
//项目当前设置了分享时间 并且没有过期
shareInfo = new ShareInfo();
shareInfo.setCustomData("test-report-id".getBytes());
shareInfo.setProjectId(DEFAULT_PROJECT_ID);
shareInfo.setShareType(ShareInfoType.API_SHARE_REPORT.name());
mvcResult = responsePost("/api/report/share/gen", shareInfo);
shareInfoDTO = parseObjectFromMvcResult(mvcResult, ShareInfoDTO.class);
Assertions.assertNotNull(shareInfoDTO);
Assertions.assertNotNull(shareInfoDTO.getShareUrl());
Assertions.assertNotNull(shareInfoDTO.getId());
shareId = shareInfoDTO.getId();
ProjectApplicationExample projectApplicationExample = new ProjectApplicationExample();
projectApplicationExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andTypeEqualTo(ShareInfoType.API_SHARE_REPORT.name());
List<ProjectApplication> projectApplications = projectApplicationMapper.selectByExample(projectApplicationExample);
if (projectApplications.isEmpty()) {
ProjectApplication projectApplication = new ProjectApplication();
projectApplication.setProjectId(DEFAULT_PROJECT_ID);
projectApplication.setType(ShareInfoType.API_SHARE_REPORT.name());
projectApplication.setTypeValue("1D");
projectApplicationMapper.insert(projectApplication);
}
mvcResult1 = this.requestGetWithOk(GET + shareId + "/" + "test-report-id")
.andReturn();
apiReportDTO = ApiDataUtils.parseObject(JSON.toJSONString(parseResponse(mvcResult1).get("data")), ApiReportDTO.class);
Assertions.assertNotNull(apiReportDTO);
Assertions.assertEquals(apiReportDTO.getId(), "test-report-id");
//项目当前设置了分享时间 并且过期
shareInfo1 = shareInfoMapper.selectByPrimaryKey(shareId);
shareInfo1.setUpdateTime(1702950953000L);
shareInfoMapper.updateByPrimaryKey(shareInfo1);
mockMvc.perform(getRequestBuilder(GET + shareId + "/" + "test-report-id"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
}
}

View File

@ -35,7 +35,7 @@ import org.springframework.test.web.servlet.MvcResult;
import java.util.List;
@SpringBootTest(webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc
public class ApiShareControllerTests extends BaseTest {
@ -78,7 +78,7 @@ public class ApiShareControllerTests extends BaseTest {
ApiDataUtils.setResolver(MsHTTPElement.class);
ShareInfoDTO shareInfoDTO = ApiDataUtils.parseObject(JSON.toJSONString(parseResponse(mvcResult).get("data")), ShareInfoDTO.class);
// 校验数据是否正确
List<ShareInfo> shareInfos = extShareInfoMapper.selectByShareTypeAndShareApiIdWithBLOBs(ShareInfoType.Single.name(), JSON.toJSONString(request).getBytes(), "zh_CN");
List<ShareInfo> shareInfos = extShareInfoMapper.selectByShareTypeAndShareApiIdWithBLOBs(ShareInfoType.SINGLE.name(), JSON.toJSONString(request).getBytes(), "zh_CN");
Assertions.assertNotNull(shareInfos);
Assertions.assertEquals(1, shareInfos.size());
Assertions.assertEquals(shareInfoDTO.getId(), shareInfos.get(0).getId());
@ -96,7 +96,7 @@ public class ApiShareControllerTests extends BaseTest {
ApiDataUtils.setResolver(MsHTTPElement.class);
ShareInfoDTO shareInfoDTOModule = ApiDataUtils.parseObject(JSON.toJSONString(parseResponse(mvcResultModule).get("data")), ShareInfoDTO.class);
// 校验数据是否正确
List<ShareInfo> shareInfosModule = extShareInfoMapper.selectByShareTypeAndShareApiIdWithBLOBs(ShareInfoType.Batch.name(), JSON.toJSONString(request).getBytes(), "zh_CN");
List<ShareInfo> shareInfosModule = extShareInfoMapper.selectByShareTypeAndShareApiIdWithBLOBs(ShareInfoType.BATCH.name(), JSON.toJSONString(request).getBytes(), "zh_CN");
Assertions.assertNotNull(shareInfosModule);
Assertions.assertEquals(1, shareInfosModule.size());
Assertions.assertEquals(shareInfoDTOModule.getId(), shareInfosModule.get(0).getId());
@ -112,7 +112,7 @@ public class ApiShareControllerTests extends BaseTest {
ShareInfoDTO allShareInfoDTO = ApiDataUtils.parseObject(JSON.toJSONString(parseResponse(mvcResultAll).get("data")), ShareInfoDTO.class);
// 校验数据是否正确
List<ShareInfo> allShareInfos = extShareInfoMapper.selectByShareTypeAndShareApiIdWithBLOBs(ShareInfoType.Batch.name(), JSON.toJSONString(request).getBytes(), "zh_CN");
List<ShareInfo> allShareInfos = extShareInfoMapper.selectByShareTypeAndShareApiIdWithBLOBs(ShareInfoType.BATCH.name(), JSON.toJSONString(request).getBytes(), "zh_CN");
Assertions.assertNotNull(allShareInfos);
Assertions.assertEquals(1, allShareInfos.size());
Assertions.assertEquals(allShareInfoDTO.getId(), allShareInfos.get(0).getId());
@ -135,14 +135,14 @@ public class ApiShareControllerTests extends BaseTest {
ApiDefinitionDocDTO copyAllApiDefinitionDocDTO = new ApiDefinitionDocDTO();
List<ApiDefinitionDTO> allList = extApiDefinitionMapper.listDoc(apiDefinitionDocRequest);
if(null != allList){
if (null != allList) {
ApiDefinitionDTO info = allList.stream().findFirst().orElseThrow(() -> new MSException(ApiResultCode.API_DEFINITION_NOT_EXIST));
ApiDefinitionBlob allApiDefinitionBlob = apiDefinitionBlobMapper.selectByPrimaryKey(info.getId());
if(allApiDefinitionBlob != null){
if (allApiDefinitionBlob != null) {
info.setRequest(ApiDataUtils.parseObject(new String(allApiDefinitionBlob.getRequest()), AbstractMsTestElement.class));
info.setResponse(ApiDataUtils.parseArray(new String(allApiDefinitionBlob.getResponse()), HttpResponse.class));
}
if(StringUtils.isBlank(copyAllApiDefinitionDocDTO.getDocTitle())){
if (StringUtils.isBlank(copyAllApiDefinitionDocDTO.getDocTitle())) {
copyAllApiDefinitionDocDTO.setDocTitle(Translator.get(ALL_API));
}
copyAllApiDefinitionDocDTO.setType(ApiDefinitionDocType.ALL.name());

View File

@ -12,4 +12,8 @@ public class KeyValueEnableParam extends KeyValueParam {
* 描述
*/
private String description;
/**
* 是否必填
*/
private Boolean required = false;
}

View File

@ -16,13 +16,11 @@ public class DataSource implements Serializable {
@Schema(description = "数据源名称")
private String dataSource;
@Schema(description = "数据驱动")
@NotBlank(message = "{environment_datasource.driver.not_blank}")
private String driver;
@Schema(description = "数据驱动id")
@NotBlank(message = "{environment_datasource.driverId.not_blank}")
private String driverId;
@Schema(description = "数据库连接url")
@NotBlank(message = "{environment_datasource.dbUrl.not_blank}")
private String dbUrl;
@Schema(description = "用户名")
private String username;

View File

@ -175,7 +175,7 @@ public class EnvironmentService {
String baseUrl = baseSystemConfigDTO.getUrl();
if (StringUtils.isNotEmpty(baseUrl)) {
Project project = projectMapper.selectByPrimaryKey(environment.getProjectId());
environmentInfoDTO.getConfig().getHttpConfig().get(0).setUrl(StringUtils.join(baseUrl, MOCK_EVN_SOCKET, project.getNum()));
environmentInfoDTO.getConfig().getHttpConfig().getFirst().setUrl(StringUtils.join(baseUrl, MOCK_EVN_SOCKET, project.getNum()));
}
}
@ -194,7 +194,7 @@ public class EnvironmentService {
String fileName = null;
if (CollectionUtils.isNotEmpty(environmentList)) {
if (environmentList.size() == 1) {
fileName = StringUtils.join(project.getName(), "_", environmentList.get(0).getName(), ".json");
fileName = StringUtils.join(project.getName(), "_", environmentList.getFirst().getName(), ".json");
} else {
fileName = StringUtils.join(project.getName(), "_", Translator.get("env_info_all"));
}
@ -267,7 +267,7 @@ public class EnvironmentService {
environmentExample.createCriteria().andNameEqualTo(environment.getName()).andProjectIdEqualTo(environment.getProjectId()).andIdNotEqualTo(environment.getId());
List<Environment> environments = environmentMapper.selectByExample(environmentExample);
if (CollectionUtils.isNotEmpty(environments)) {
return environments.get(0);
return environments.getFirst();
}
return null;
}

View File

@ -614,7 +614,7 @@ public class FileMetadataService {
fileMetadataExample.createCriteria().andRefIdEqualTo(refId).andLatestEqualTo(true);
List<FileMetadata> fileMetadataList = fileMetadataMapper.selectByExample(fileMetadataExample);
if (CollectionUtils.isNotEmpty(fileMetadataList)) {
return fileMetadataList.get(0);
return fileMetadataList.getFirst();
} else {
throw new MSException(Translator.get("latest.file.not.exist"));
}

View File

@ -81,8 +81,8 @@ public class GlobalParamsService {
if (CollectionUtils.isNotEmpty(projectParameters)) {
GlobalParamsDTO globalParamsDTO = new GlobalParamsDTO();
globalParamsDTO.setProjectId(projectId);
globalParamsDTO.setId(projectParameters.get(0).getId());
globalParamsDTO.setGlobalParams(JSON.parseObject(new String(projectParameters.get(0).getParameters()), GlobalParams.class));
globalParamsDTO.setId(projectParameters.getFirst().getId());
globalParamsDTO.setGlobalParams(JSON.parseObject(new String(projectParameters.getFirst().getParameters()), GlobalParams.class));
return globalParamsDTO;
} else {
return null;
@ -116,8 +116,8 @@ public class GlobalParamsService {
if (CollectionUtils.isNotEmpty(projectParameters)) {
GlobalParamsDTO globalParamsDTO = new GlobalParamsDTO();
globalParamsDTO.setProjectId(projectId);
globalParamsDTO.setId(projectParameters.get(0).getId());
globalParamsDTO.setGlobalParams(JSON.parseObject(new String(projectParameters.get(0).getParameters()), GlobalParams.class));
globalParamsDTO.setId(projectParameters.getFirst().getId());
globalParamsDTO.setGlobalParams(JSON.parseObject(new String(projectParameters.getFirst().getParameters()), GlobalParams.class));
bytes = JSON.toJSONString(globalParamsDTO).getBytes();
} else {
throw new MSException(Translator.get("global_parameters_is_not_exist"));

View File

@ -167,8 +167,8 @@ public class ProjectService {
TestResourcePoolExample.Criteria criteria = example.createCriteria();
criteria.andIdIn(poolIds).andEnableEqualTo(true).andDeletedEqualTo(false);
List<TestResourcePool> testResourcePools = new ArrayList<>();
testResourcePools = switch (type) {
case ApplicationScope.API_TEST-> {
testResourcePools = switch (type) {
case ApplicationScope.API_TEST -> {
criteria.andApiTestEqualTo(true);
yield testResourcePoolMapper.selectByExample(example);
}
@ -183,7 +183,7 @@ public class ProjectService {
default -> new ArrayList<>();
};
return testResourcePools.stream().map(testResourcePool ->
new OptionDTO(testResourcePool.getId(), testResourcePool.getName())
new OptionDTO(testResourcePool.getId(), testResourcePool.getName())
).toList();
}
@ -200,7 +200,7 @@ public class ProjectService {
public ProjectVersion getLatestVersion(String projectId) {
ProjectVersionExample projectVersionExample = new ProjectVersionExample();
projectVersionExample.createCriteria().andProjectIdEqualTo(projectId);
return projectVersionMapper.selectByExample(projectVersionExample).get(0);
return projectVersionMapper.selectByExample(projectVersionExample).getFirst();
}
public Long getNextOrder(Function<String, Long> getLastPosFunc, String projectId) {

View File

@ -57,7 +57,6 @@ import org.springframework.util.MultiValueMap;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@ -786,7 +785,7 @@ public class EnvironmentControllerTests extends BaseTest {
EnvironmentExample example = new EnvironmentExample();
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andNameEqualTo("name");
List<Environment> environments = environmentMapper.selectByExample(example);
String id = environments.get(0).getId();
String id = environments.getFirst().getId();
MvcResult mvcResult = this.responseGet(get + id);
EnvironmentInfoDTO response = parseObjectFromMvcResult(mvcResult, EnvironmentInfoDTO.class);
Assertions.assertNotNull(response);
@ -817,7 +816,7 @@ public class EnvironmentControllerTests extends BaseTest {
EnvironmentExample environmentExample = new EnvironmentExample();
environmentExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andMockEqualTo(true);
List<Environment> environmentList = environmentMapper.selectByExample(environmentExample);
MOCKID = environmentList.get(0).getId();
MOCKID = environmentList.getFirst().getId();
this.responseGet(get + MOCKID);
}
@ -858,20 +857,13 @@ public class EnvironmentControllerTests extends BaseTest {
dataSource.setDbUrl(null);
dataSource.setPassword("Password123@mysql");
dataSource.setUsername("root");
dataSource.setDriverId(StringUtils.join("system", "&", "com.mysql.cj.jdbc.Driver"));
dataSource.setDriver("com.mysql.cj.jdbc.Driver");
this.requestPost(validate, dataSource, BAD_REQUEST_MATCHER);
//测试mysql DriverId为空
dataSource.setDbUrl("jdbc:mysql://");
dataSource.setDriverId(null);
this.requestPost(validate, dataSource, BAD_REQUEST_MATCHER);
//测试mysql Driver为空
dataSource.setDriverId(StringUtils.join("system", "&", "com.mysql.cj.jdbc.Driver"));
dataSource.setDriver(null);
this.requestPost(validate, dataSource, BAD_REQUEST_MATCHER);
// 测试500
dataSource.setDriver("com.mysql.cj.jdbc.Driver");
dataSource.setDbUrl("jdbc:mysql://");
dataSource.setDriverId(StringUtils.join("system", "&", "com.mysql.cj.jdbc.Driver"));
this.requestPost(validate, dataSource, ERROR_REQUEST_MATCHER);
}
@ -893,7 +885,7 @@ public class EnvironmentControllerTests extends BaseTest {
EnvironmentExample example = new EnvironmentExample();
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andNameEqualTo("name");
List<Environment> environments = environmentMapper.selectByExample(example);
String id = environments.get(0).getId();
String id = environments.getFirst().getId();
EnvironmentRequest request = new EnvironmentRequest();
request.setId(id);
request.setProjectId(DEFAULT_PROJECT_ID);
@ -912,7 +904,7 @@ public class EnvironmentControllerTests extends BaseTest {
example = new EnvironmentExample();
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andNameEqualTo("commonParams");
environments = environmentMapper.selectByExample(example);
request.setId(environments.get(0).getId());
request.setId(environments.getFirst().getId());
request.setName("commonParams");
FileInputStream inputStream = new FileInputStream(new File(
this.getClass().getClassLoader().getResource("file/e5d6b195f54c96a59b3c0a9c8888798f.p12")
@ -931,7 +923,7 @@ public class EnvironmentControllerTests extends BaseTest {
example = new EnvironmentExample();
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andNameEqualTo("校验权限");
environments = environmentMapper.selectByExample(example);
id = environments.get(0).getId();
id = environments.getFirst().getId();
request.setProjectId(DEFAULT_PROJECT_ID);
request.setName("校验更新权限");
request.setId(id);
@ -956,7 +948,7 @@ public class EnvironmentControllerTests extends BaseTest {
EnvironmentExample example = new EnvironmentExample();
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andNameEqualTo("name");
List<Environment> environments = environmentMapper.selectByExample(example);
String id = environments.get(0).getId();
String id = environments.getFirst().getId();
request = new EnvironmentRequest();
request.setId(id);
request.setProjectId(DEFAULT_PROJECT_ID);
@ -985,7 +977,7 @@ public class EnvironmentControllerTests extends BaseTest {
EnvironmentExample example = new EnvironmentExample();
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andMockEqualTo(true);
List<Environment> environments = environmentMapper.selectByExample(example);
posRequest.setMoveId(environments.get(0).getId());
posRequest.setMoveId(environments.getFirst().getId());
posRequest.setMoveMode("AFTER");
this.requestPostWithOkAndReturn(POS_URL, posRequest, DEFAULT_PROJECT_ID);
@ -1001,7 +993,7 @@ public class EnvironmentControllerTests extends BaseTest {
EnvironmentExample example = new EnvironmentExample();
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andNameEqualTo("name");
List<Environment> environments = environmentMapper.selectByExample(example);
String id = environments.get(0).getId();
String id = environments.getFirst().getId();
this.requestGet(delete + id);
//校验日志
checkLog(id, OperationLogType.DELETE);
@ -1017,7 +1009,7 @@ public class EnvironmentControllerTests extends BaseTest {
example = new EnvironmentExample();
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andNameEqualTo("uploadFile");
environments = environmentMapper.selectByExample(example);
id = environments.get(0).getId();
id = environments.getFirst().getId();
this.requestGet(delete + id);
//查询文件
FileRequest fileRequest = new FileRequest();
@ -1136,10 +1128,6 @@ public class EnvironmentControllerTests extends BaseTest {
request.setExcludeIds(List.of("environmentId1"));
MvcResult mvcResult1 = this.requestPostDownloadFile(exportEnv, null, request, DEFAULT_PROJECT_ID);
byte[] fileBytes1 = mvcResult1.getResponse().getContentAsByteArray();
File file = new File("test.json");
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(fileBytes1);
fileOutputStream.close();
Assertions.assertNotNull(fileBytes1);
request.setSelectIds(List.of("不存在blob"));
request.setSelectAll(false);

View File

@ -213,7 +213,7 @@ public class EnvironmentGroupControllerTests extends BaseTest {
}
EnvironmentGroupExample example = new EnvironmentGroupExample();
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andNameEqualTo("group");
GROUP_ID = environmentGroupMapper.selectByExample(example).get(0).getId();
GROUP_ID = environmentGroupMapper.selectByExample(example).getFirst().getId();
return GROUP_ID;
}
@ -229,7 +229,7 @@ public class EnvironmentGroupControllerTests extends BaseTest {
EnvironmentExample environmentExample = new EnvironmentExample();
environmentExample.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andNameEqualTo("httpConfig-group");
List<Environment> environments = environmentMapper.selectByExample(environmentExample);
environmentGroupProjectDTO.setEnvironmentId(environments.get(0).getId());
environmentGroupProjectDTO.setEnvironmentId(environments.getFirst().getId());
environmentGroupProjectDTO.setProjectId(DEFAULT_PROJECT_ID);
groupRequest.setEnvGroupProject(List.of(environmentGroupProjectDTO));
MvcResult mvcResult = this.responsePost(update, groupRequest);
@ -306,7 +306,7 @@ public class EnvironmentGroupControllerTests extends BaseTest {
EnvironmentGroupExample example = new EnvironmentGroupExample();
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID).andNameEqualTo("校验权限");
List<EnvironmentGroup> environments = environmentGroupMapper.selectByExample(example);
posRequest.setMoveId(environments.get(0).getId());
posRequest.setMoveId(environments.getFirst().getId());
posRequest.setMoveMode("AFTER");
this.requestPostWithOkAndReturn(POS_URL, posRequest);

View File

@ -368,7 +368,7 @@ public class GlobalParamsControllerTests extends BaseTest {
List<ProjectParameter> projectParametersList = projectParametersMapper.selectByExample(example);
GlobalParamsRequest request = new GlobalParamsRequest();
request.setProjectId("projectId1");
request.setId(projectParametersList.get(0).getId());
request.setId(projectParametersList.getFirst().getId());
GlobalParams globalParams = new GlobalParams();
globalParams.setHeaders(getHeaders(2));
globalParams.setCommonVariables(getEnvVariables(2));
@ -390,7 +390,7 @@ public class GlobalParamsControllerTests extends BaseTest {
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID);
projectParametersList = projectParametersMapper.selectByExample(example);
request.setProjectId(DEFAULT_PROJECT_ID);
request.setId(projectParametersList.get(0).getId());
request.setId(projectParametersList.getFirst().getId());
GlobalParams globalParams1 = new GlobalParams();
globalParams1.setHeaders(getHeaders(3));
globalParams1.setCommonVariables(getEnvVariables(4));
@ -575,7 +575,7 @@ public class GlobalParamsControllerTests extends BaseTest {
if (CollectionUtils.isEmpty(listObject)) {
continue;
}
if (listObject.get(0) instanceof File || listObject.get(0) instanceof MockMultipartFile) {
if (listObject.getFirst() instanceof File || listObject.getFirst() instanceof MockMultipartFile) {
// 参数是多个文件时,设置多个文件
for (Object subObject : ((List) o)) {
multipartFile = getMockMultipartFile(key, subObject);

View File

@ -22,6 +22,7 @@ public class OperationLogModule {
public static final String API_DEFINITION_MOCK = "API_DEFINITION_MOCK";
public static final String API_DEFINITION_CASE = "API_DEFINITION_CASE";
public static final String API_SCENARIO = "API_SCENARIO";
public static final String API_REPORT = "API_REPORT";
public static final String AUTH_TITLE = "AUTH_TITLE";
public static final String PROJECT_ENVIRONMENT_SETTING = "PROJECT_ENVIRONMENT_SETTING";
public static final String PROJECT_PROJECT_MANAGER = "PROJECT_PROJECT_MANAGER";