feat(接口测试): 增加场景报告接口

This commit is contained in:
wxg0103 2024-01-19 20:48:09 +08:00 committed by Craftsman
parent 74aee959c6
commit 46d1d3f43f
25 changed files with 1211 additions and 668 deletions

View File

@ -1,94 +0,0 @@
package io.metersphere.api.domain;
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 ApiScenarioReportStructure implements Serializable {
@Schema(description = "请求资源 id", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{api_scenario_report_structure.report_id.not_blank}", groups = {Created.class})
@Size(min = 1, max = 50, message = "{api_scenario_report_structure.report_id.length_range}", groups = {Created.class, Updated.class})
private String reportId;
@Schema(description = "资源步骤结构树")
private byte[] resourceTree;
private static final long serialVersionUID = 1L;
public enum Column {
reportId("report_id", "reportId", "VARCHAR", false),
resourceTree("resource_tree", "resourceTree", "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

@ -1,270 +0,0 @@
package io.metersphere.api.domain;
import java.util.ArrayList;
import java.util.List;
public class ApiScenarioReportStructureExample {
protected String orderByClause;
protected boolean distinct;
protected List<Criteria> oredCriteria;
public ApiScenarioReportStructureExample() {
oredCriteria = new ArrayList<Criteria>();
}
public void setOrderByClause(String orderByClause) {
this.orderByClause = orderByClause;
}
public String getOrderByClause() {
return orderByClause;
}
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public boolean isDistinct() {
return distinct;
}
public List<Criteria> getOredCriteria() {
return oredCriteria;
}
public void or(Criteria criteria) {
oredCriteria.add(criteria);
}
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
public Criteria createCriteria() {
Criteria criteria = createCriteriaInternal();
if (oredCriteria.size() == 0) {
oredCriteria.add(criteria);
}
return criteria;
}
protected Criteria createCriteriaInternal() {
Criteria criteria = new Criteria();
return criteria;
}
public void clear() {
oredCriteria.clear();
orderByClause = null;
distinct = false;
}
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
super();
criteria = new ArrayList<Criterion>();
}
public boolean isValid() {
return criteria.size() > 0;
}
public List<Criterion> getAllCriteria() {
return criteria;
}
public List<Criterion> getCriteria() {
return criteria;
}
protected void addCriterion(String condition) {
if (condition == null) {
throw new RuntimeException("Value for condition cannot be null");
}
criteria.add(new Criterion(condition));
}
protected void addCriterion(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value));
}
protected void addCriterion(String condition, Object value1, Object value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value1, value2));
}
public Criteria andReportIdIsNull() {
addCriterion("report_id is null");
return (Criteria) this;
}
public Criteria andReportIdIsNotNull() {
addCriterion("report_id is not null");
return (Criteria) this;
}
public Criteria andReportIdEqualTo(String value) {
addCriterion("report_id =", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdNotEqualTo(String value) {
addCriterion("report_id <>", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdGreaterThan(String value) {
addCriterion("report_id >", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdGreaterThanOrEqualTo(String value) {
addCriterion("report_id >=", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdLessThan(String value) {
addCriterion("report_id <", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdLessThanOrEqualTo(String value) {
addCriterion("report_id <=", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdLike(String value) {
addCriterion("report_id like", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdNotLike(String value) {
addCriterion("report_id not like", value, "reportId");
return (Criteria) this;
}
public Criteria andReportIdIn(List<String> values) {
addCriterion("report_id in", values, "reportId");
return (Criteria) this;
}
public Criteria andReportIdNotIn(List<String> values) {
addCriterion("report_id not in", values, "reportId");
return (Criteria) this;
}
public Criteria andReportIdBetween(String value1, String value2) {
addCriterion("report_id between", value1, value2, "reportId");
return (Criteria) this;
}
public Criteria andReportIdNotBetween(String value1, String value2) {
addCriterion("report_id not between", value1, value2, "reportId");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {
protected Criteria() {
super();
}
}
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.typeHandler = typeHandler;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value) {
this(condition, value, null);
}
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.typeHandler = typeHandler;
this.betweenValue = true;
}
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
}
}

View File

@ -1,38 +0,0 @@
package io.metersphere.api.mapper;
import io.metersphere.api.domain.ApiScenarioReportStructure;
import io.metersphere.api.domain.ApiScenarioReportStructureExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface ApiScenarioReportStructureMapper {
long countByExample(ApiScenarioReportStructureExample example);
int deleteByExample(ApiScenarioReportStructureExample example);
int deleteByPrimaryKey(String reportId);
int insert(ApiScenarioReportStructure record);
int insertSelective(ApiScenarioReportStructure record);
List<ApiScenarioReportStructure> selectByExampleWithBLOBs(ApiScenarioReportStructureExample example);
List<ApiScenarioReportStructure> selectByExample(ApiScenarioReportStructureExample example);
ApiScenarioReportStructure selectByPrimaryKey(String reportId);
int updateByExampleSelective(@Param("record") ApiScenarioReportStructure record, @Param("example") ApiScenarioReportStructureExample example);
int updateByExampleWithBLOBs(@Param("record") ApiScenarioReportStructure record, @Param("example") ApiScenarioReportStructureExample example);
int updateByExample(@Param("record") ApiScenarioReportStructure record, @Param("example") ApiScenarioReportStructureExample example);
int updateByPrimaryKeySelective(ApiScenarioReportStructure record);
int updateByPrimaryKeyWithBLOBs(ApiScenarioReportStructure record);
int batchInsert(@Param("list") List<ApiScenarioReportStructure> list);
int batchInsertSelective(@Param("list") List<ApiScenarioReportStructure> list, @Param("selective") ApiScenarioReportStructure.Column ... selective);
}

View File

@ -1,222 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.api.mapper.ApiScenarioReportStructureMapper">
<resultMap id="BaseResultMap" type="io.metersphere.api.domain.ApiScenarioReportStructure">
<id column="report_id" jdbcType="VARCHAR" property="reportId" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.api.domain.ApiScenarioReportStructure">
<result column="resource_tree" jdbcType="LONGVARBINARY" property="resourceTree" />
</resultMap>
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause">
<where>
<foreach collection="example.oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List">
report_id
</sql>
<sql id="Blob_Column_List">
resource_tree
</sql>
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.api.domain.ApiScenarioReportStructureExample" resultMap="ResultMapWithBLOBs">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from api_scenario_report_structure
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByExample" parameterType="io.metersphere.api.domain.ApiScenarioReportStructureExample" resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from api_scenario_report_structure
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="ResultMapWithBLOBs">
select
<include refid="Base_Column_List" />
,
<include refid="Blob_Column_List" />
from api_scenario_report_structure
where report_id = #{reportId,jdbcType=VARCHAR}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
delete from api_scenario_report_structure
where report_id = #{reportId,jdbcType=VARCHAR}
</delete>
<delete id="deleteByExample" parameterType="io.metersphere.api.domain.ApiScenarioReportStructureExample">
delete from api_scenario_report_structure
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="io.metersphere.api.domain.ApiScenarioReportStructure">
insert into api_scenario_report_structure (report_id, resource_tree)
values (#{reportId,jdbcType=VARCHAR}, #{resourceTree,jdbcType=LONGVARBINARY})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.api.domain.ApiScenarioReportStructure">
insert into api_scenario_report_structure
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="reportId != null">
report_id,
</if>
<if test="resourceTree != null">
resource_tree,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="reportId != null">
#{reportId,jdbcType=VARCHAR},
</if>
<if test="resourceTree != null">
#{resourceTree,jdbcType=LONGVARBINARY},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="io.metersphere.api.domain.ApiScenarioReportStructureExample" resultType="java.lang.Long">
select count(*) from api_scenario_report_structure
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByExampleSelective" parameterType="map">
update api_scenario_report_structure
<set>
<if test="record.reportId != null">
report_id = #{record.reportId,jdbcType=VARCHAR},
</if>
<if test="record.resourceTree != null">
resource_tree = #{record.resourceTree,jdbcType=LONGVARBINARY},
</if>
</set>
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExampleWithBLOBs" parameterType="map">
update api_scenario_report_structure
set report_id = #{record.reportId,jdbcType=VARCHAR},
resource_tree = #{record.resourceTree,jdbcType=LONGVARBINARY}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map">
update api_scenario_report_structure
set report_id = #{record.reportId,jdbcType=VARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.api.domain.ApiScenarioReportStructure">
update api_scenario_report_structure
<set>
<if test="resourceTree != null">
resource_tree = #{resourceTree,jdbcType=LONGVARBINARY},
</if>
</set>
where report_id = #{reportId,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.api.domain.ApiScenarioReportStructure">
update api_scenario_report_structure
set resource_tree = #{resourceTree,jdbcType=LONGVARBINARY}
where report_id = #{reportId,jdbcType=VARCHAR}
</update>
<insert id="batchInsert" parameterType="map">
insert into api_scenario_report_structure
(report_id, resource_tree)
values
<foreach collection="list" item="item" separator=",">
(#{item.reportId,jdbcType=VARCHAR}, #{item.resourceTree,jdbcType=LONGVARBINARY})
</foreach>
</insert>
<insert id="batchInsertSelective" parameterType="map">
insert into api_scenario_report_structure (
<foreach collection="selective" item="column" separator=",">
${column.escapedColumnName}
</foreach>
)
values
<foreach collection="list" item="item" separator=",">
(
<foreach collection="selective" item="column" separator=",">
<if test="'report_id'.toString() == column.value">
#{item.reportId,jdbcType=VARCHAR}
</if>
<if test="'resource_tree'.toString() == column.value">
#{item.resourceTree,jdbcType=LONGVARBINARY}
</if>
</foreach>
)
</foreach>
</insert>
</mapper>

View File

@ -32,7 +32,6 @@ api_scenario.update_user.not_blank=更新人不能为空
api_scenario.priority.length_range=场景级别/P0/P1等长度必须在1-10之间 api_scenario.priority.length_range=场景级别/P0/P1等长度必须在1-10之间
api_scenario.priority.not_blank=场景级别/P0/P1等不能为空 api_scenario.priority.not_blank=场景级别/P0/P1等不能为空
api_scenario.step_total.not_blank=步骤总数不能为空 api_scenario.step_total.not_blank=步骤总数不能为空
api_scenario.pass_rate.not_blank=通过率不能为空
api_scenario.status.length_range=场景状态/未规划/已完成 等长度必须在1-20之间 api_scenario.status.length_range=场景状态/未规划/已完成 等长度必须在1-20之间
api_scenario.status.not_blank=场景状态/未规划/已完成 等不能为空 api_scenario.status.not_blank=场景状态/未规划/已完成 等不能为空
api_scenario.principal.length_range=责任人/用户ID长度必须在1-50之间 api_scenario.principal.length_range=责任人/用户ID长度必须在1-50之间
@ -43,6 +42,8 @@ api_scenario.environment_group.length_range=是否为环境组长度必须在1-1
api_scenario.environment_group.not_blank=是否为环境组不能为空 api_scenario.environment_group.not_blank=是否为环境组不能为空
api_scenario.project_id.length_range=项目ID长度必须在1-50之间 api_scenario.project_id.length_range=项目ID长度必须在1-50之间
api_scenario.project_id.not_blank=项目ID不能为空 api_scenario.project_id.not_blank=项目ID不能为空
api_scenario.request_pass_rate.not_blank=通过率不能为空
api_scenario.request_pass_rate.length_range=通过率长度必须在1-20之间
#module: ApiScenarioStep #module: ApiScenarioStep
api_scenario_step.id.not_blank=ID不能为空 api_scenario_step.id.not_blank=ID不能为空
api_scenario_step.id.length_range=步骤ID长度必须在1-50之间 api_scenario_step.id.length_range=步骤ID长度必须在1-50之间
@ -54,8 +55,14 @@ api_test_case_follow.case_id.length_range=用例ID长度必须在1-50之间
api_test_case_follow.case_id.not_blank=用例ID不能为空 api_test_case_follow.case_id.not_blank=用例ID不能为空
api_test_case_follow.follow_id.length_range=关注人/用户ID长度必须在1-50之间 api_test_case_follow.follow_id.length_range=关注人/用户ID长度必须在1-50之间
api_test_case_follow.follow_id.not_blank=关注人/用户ID不能为空 api_test_case_follow.follow_id.not_blank=关注人/用户ID不能为空
#moduleApiReportBlob #moduleApiReportStep
api_report_blob.api_report_id.not_blank=接口报告ID不能为空 api_report_step.step_id.not_blank=步骤ID不能为空
api_report_step.step_id.length_range=步骤ID长度必须在1-50之间
api_report_step.report_id.not_blank=报告ID不能为空
api_report_step.report_id.length_range=报告ID长度必须在1-50之间
api_report_step.sort.not_blank=步骤排序不能为空
api_report_step.step_type.not_blank=步骤类型不能为空
#moduleApiFakeErrorConfig #moduleApiFakeErrorConfig
api_fake_error_config.id.not_blank=误报pk不能为空 api_fake_error_config.id.not_blank=误报pk不能为空
api_fake_error_config.create_user.length_range=创建人长度必须在1-50之间 api_fake_error_config.create_user.length_range=创建人长度必须在1-50之间
@ -92,12 +99,26 @@ api_scenario_report.project_id.length_range=项目ID长度必须在1-50之间
api_scenario_report.project_id.not_blank=项目ID不能为空 api_scenario_report.project_id.not_blank=项目ID不能为空
api_scenario_report.scenario_id.length_range=场景ID长度必须在1-50之间 api_scenario_report.scenario_id.length_range=场景ID长度必须在1-50之间
api_scenario_report.scenario_id.not_blank=场景ID不能为空 api_scenario_report.scenario_id.not_blank=场景ID不能为空
#moduleApiScenarioEnv api_scenario_report.test_plan_id.not_blank=测试计划ID不能为空
api_scenario_environment.id.not_blank=场景环境pk不能为空 api_scenario_report.test_plan_id.length_range=测试计划ID长度必须在1-50之间
api_scenario_environment.api_scenario_id.length_range=场景ID长度必须在1-50之间 api_scenario_report.start_time.not_blank=开始时间不能为空
api_scenario_environment.api_scenario_id.not_blank=场景ID不能为空 api_scenario_report.request_duration.not_blank=请求时长不能为空
api_scenario_environment.project_id.length_range=项目ID长度必须在1-50之间 api_scenario_report.error_count.not_blank=失败数量不能为空
api_scenario_environment.project_id.not_blank=项目ID不能为空 api_scenario_report.fake_error_count.not_blank=误报数量不能为空
api_scenario_report.pending_count.not_blank=未执行数量不能为空
api_scenario_report.success_count.not_blank=成功数量不能为空
api_scenario_report.assertion_count.not_blank=断言数量不能为空
api_scenario_report.assertion_success_count.not_blank=断言成功数量不能为空
api_scenario_report.request_error_rate.not_blank=请求错误率不能为空
api_scenario_report.request_error_rate.length_range=请求错误率长度必须在1-20之间
api_scenario_report.request_pending_rate.not_blank=请求未执行率不能为空
api_scenario_report.request_pending_rate.length_range=请求未执行率长度必须在1-20之间
api_scenario_report.request_fake_error_rate.not_blank=请求误报率不能为空
api_scenario_report.request_fake_error_rate.length_range=请求误报率长度必须在1-20之间
api_scenario_report.request_pass_rate.not_blank=请求通过率不能为空
api_scenario_report.request_pass_rate.length_range=请求通过率长度必须在1-20之间
api_scenario_report.assertion_pass_rate.not_blank=断言通过率不能为空
api_scenario_report.assertion_pass_rate.length_range=断言通过率长度必须在1-20之间
#moduleApiDefinition #moduleApiDefinition
api_definition.id.not_blank=接口pk不能为空 api_definition.id.not_blank=接口pk不能为空
api_definition.id.length_range=接口pk长度必须在1-50之间 api_definition.id.length_range=接口pk长度必须在1-50之间
@ -198,19 +219,29 @@ api_definition_mock.project_id.length_range=项目ID长度必须在1-50之间
api_definition_mock.project_id.not_blank=项目ID不能为空 api_definition_mock.project_id.not_blank=项目ID不能为空
api_definition_mock.api_definition_id.length_range=接口ID长度必须在1-50之间 api_definition_mock.api_definition_id.length_range=接口ID长度必须在1-50之间
api_definition_mock.api_definition_id.not_blank=接口ID不能为空 api_definition_mock.api_definition_id.not_blank=接口ID不能为空
#moduleApiScenarioReportStructure #moduleApiScenarioReportStep
api_scenario_report_structure.report_id.not_blank=请求资源 id不能为空 api_scenario_report_step.step_id.not_blank=步骤ID不能为空
api_scenario_report_step.step_id.length_range=步骤ID长度必须在1-50之间
api_scenario_report_step.report_id.not_blank=报告ID不能为空
api_scenario_report_step.report_id.length_range=报告ID长度必须在1-50之间
api_scenario_report_step.sort.not_blank=步骤排序不能为空
api_scenario_report_step.step_type.not_blank=步骤类型不能为空
api_scenario_report_step.parent_id.not_blank=父级ID不能为空
api_scenario_report_step.parent_id.length_range=父级ID长度必须在1-50之间
#moduleApiReport #moduleApiReport
api_report.id.not_blank=接口结果报告pk不能为空 api_report.id.not_blank=接口结果报告pk不能为空
api_report.name.length_range=接口报告名称长度必须在1-200之间 api_report.name.length_range=接口报告名称长度必须在1-200之间
api_report.name.not_blank=接口报告名称不能为空 api_report.name.not_blank=接口报告名称不能为空
api_report.resource_id.length_range=资源ID/api_definition_id/api_test_case_id长度必须在1-50之间 api_report.resource_id.length_range=资源ID/api_definition_id/api_test_case_id长度必须在1-50之间
api_report.resource_id.not_blank=资源ID/api_definition_id/api_test_case_id不能为空 api_report.resource_id.not_blank=资源ID/api_definition_id/api_test_case_id不能为空
api_report.test_plan_id.not_blank=测试计划ID不能为空
api_report.create_user.length_range=创建人ID长度必须在1-50之间 api_report.create_user.length_range=创建人ID长度必须在1-50之间
api_report.create_user.not_blank=创建人ID不能为空 api_report.create_user.not_blank=创建人ID不能为空
api_report.update_user.length_range=修改人长度必须在1-50之间 api_report.update_user.length_range=修改人长度必须在1-50之间
api_report.update_user.not_blank=修改人不能为空 api_report.update_user.not_blank=修改人不能为空
api_report.deleted.length_range=删除状态长度必须在1-1之间 api_report.deleted.length_range=删除状态长度必须在1-1之间
api_report.start_time.not_blank=开始时间不能为空
api_report.request_duration.not_blank=请求时长不能为空
api_report.deleted.not_blank=删除状态不能为空 api_report.deleted.not_blank=删除状态不能为空
api_report.status.length_range=结果状态长度必须在1-50之间 api_report.status.length_range=结果状态长度必须在1-50之间
api_report.status.not_blank=结果状态不能为空 api_report.status.not_blank=结果状态不能为空
@ -226,6 +257,33 @@ api_report.integrated_report_id.length_range=集成报告id/api_scenario_report_
api_report.integrated_report_id.not_blank=集成报告id/api_scenario_report_id不能为空 api_report.integrated_report_id.not_blank=集成报告id/api_scenario_report_id不能为空
api_report.integrated.length_range=是否为集成报告默认否长度必须在1-1之间 api_report.integrated.length_range=是否为集成报告默认否长度必须在1-1之间
api_report.integrated.not_blank=是否为集成报告,默认否不能为空 api_report.integrated.not_blank=是否为集成报告,默认否不能为空
api_report.error_count.not_blank=失败数量不能为空
api_report.fake_error_count.not_blank=误报数量不能为空
api_report.pending_count.not_blank=未执行数量不能为空
api_report.success_count.not_blank=成功数量不能为空
api_report.assertion_count.not_blank=断言数量不能为空
api_report.assertion_success_count.not_blank=断言成功数量不能为空
api_report.request_error_rate.not_blank=请求错误率不能为空
api_report.request_error_rate.length_range=请求错误率长度必须在1-20之间
api_report.request_pending_rate.not_blank=请求未执行率不能为空
api_report.request_pending_rate.length_range=请求未执行率长度必须在1-20之间
api_report.request_fake_error_rate.not_blank=请求误报率不能为空
api_report.request_fake_error_rate.length_range=请求误报率长度必须在1-20之间
api_report.request_pass_rate.not_blank=请求通过率不能为空
api_report.request_pass_rate.length_range=请求通过率长度必须在1-20之间
api_report.assertion_pass_rate.not_blank=断言通过率不能为空
api_report.assertion_pass_rate.length_range=断言通过率长度必须在1-20之间
#module: ApiReportDetail
api_report_detail.id.not_blank=ID不能为空
api_report_detail.id.length_range=详情ID长度必须在1-50之间
api_report_detail.report_id.not_blank=报告ID不能为空
api_report_detail.report_id.length_range=报告ID长度必须在1-50之间
api_report_detail.step_id.not_blank=步骤ID不能为空
api_report_detail.step_id.length_range=步骤ID长度必须在1-50之间
api_report_detail.status.not_blank=状态不能为空
api_report_detail.status.length_range=状态长度必须在1-20之间
api_report_detail.request_time.not_blank=请求时间不能为空
api_report_detail.response_size.not_blank=响应大小不能为空
#moduleApiDefinitionModule #moduleApiDefinitionModule
api_definition_module.id.not_blank=接口模块pk不能为空 api_definition_module.id.not_blank=接口模块pk不能为空
api_definition_module.update_user.length_range=修改人长度必须在1-50之间 api_definition_module.update_user.length_range=修改人长度必须在1-50之间
@ -270,6 +328,8 @@ api_scenario_report_detail.report_id.length_range=报告ID长度必须在1-50之
api_scenario_report_detail.report_id.not_blank=报告ID不能为空 api_scenario_report_detail.report_id.not_blank=报告ID不能为空
api_scenario_report_detail.resource_id.length_range=场景中各个步骤请求唯一标识长度必须在1-50之间 api_scenario_report_detail.resource_id.length_range=场景中各个步骤请求唯一标识长度必须在1-50之间
api_scenario_report_detail.resource_id.not_blank=场景中各个步骤请求唯一标识不能为空 api_scenario_report_detail.resource_id.not_blank=场景中各个步骤请求唯一标识不能为空
api_scenario_report_detail.request_time.not_blank=请求时间不能为空
api_scenario_report_detail.response_size.not_blank=响应大小不能为空
#moduleApiDefinitionBlob #moduleApiDefinitionBlob
api_definition_blob.api_definition_id.not_blank=接口ID/ 一对一关系不能为空 api_definition_blob.api_definition_id.not_blank=接口ID/ 一对一关系不能为空
#module: ApiDebug #module: ApiDebug

View File

@ -43,6 +43,8 @@ api_scenario.environment_group.length_range=Whether it is an environment group l
api_scenario.environment_group.not_blank=Whether it is an environment group cannot be empty api_scenario.environment_group.not_blank=Whether it is an environment group cannot be empty
api_scenario.project_id.length_range=Item fk length must be between 1-50 api_scenario.project_id.length_range=Item fk length must be between 1-50
api_scenario.project_id.not_blank=Item fk cannot be empty api_scenario.project_id.not_blank=Item fk cannot be empty
api_scenario.request_pass_rate.not_blank=Pass rate cannot be empty
api_scenario.request_pass_rate.length_range=Pass rate length must be between 1-20
#module: ApiScenarioStep #module: ApiScenarioStep
api_scenario_step.id.not_blank=ID cannot be empty api_scenario_step.id.not_blank=ID cannot be empty
api_scenario_step.id.length_range=Step ID length must be between 1-50 api_scenario_step.id.length_range=Step ID length must be between 1-50
@ -92,6 +94,26 @@ api_scenario_report.project_id.length_range=Item fk length must be between 1-50
api_scenario_report.project_id.not_blank=Item fk cannot be empty api_scenario_report.project_id.not_blank=Item fk cannot be empty
api_scenario_report.scenario_id.length_range=Scene fk length must be between 1-50 api_scenario_report.scenario_id.length_range=Scene fk length must be between 1-50
api_scenario_report.scenario_id.not_blank=Scene fk cannot be empty api_scenario_report.scenario_id.not_blank=Scene fk cannot be empty
api_scenario_report.test_plan_id.not_blank=Test plan ID cannot be empty
api_scenario_report.test_plan_id.length_range=Test plan ID length must be between 1-50
api_scenario_report.start_time.not_blank=Start time cannot be empty
api_scenario_report.request_duration.not_blank=Request duration cannot be empty
api_scenario_report.error_count.not_blank=Error count cannot be empty
api_scenario_report.fake_error_count.not_blank=Fake error count cannot be empty
api_scenario_report.pending_count.not_blank=Pending count cannot be empty
api_scenario_report.success_count.not_blank=Success count cannot be empty
api_scenario_report.assertion_count.not_blank=Assertion count cannot be empty
api_scenario_report.assertion_success_count.not_blank=Assertion success count cannot be empty
api_scenario_report.request_error_rate.not_blank=Request error rate cannot be empty
api_scenario_report.request_error_rate.length_range=Request error rate length must be between 1-20
api_scenario_report.request_pending_rate.not_blank=Request pending rate cannot be empty
api_scenario_report.request_pending_rate.length_range=Request pending rate length must be between 1-20
api_scenario_report.request_fake_error_rate.not_blank=Request false positive rate cannot be empty
api_scenario_report.request_fake_error_rate.length_range=Request false positive rate length must be between 1-20
api_scenario_report.request_pass_rate.not_blank=Request pass rate cannot be empty
api_scenario_report.request_pass_rate.length_range=Request pass rate length must be between 1-20
api_scenario_report.assertion_pass_rate.not_blank=Assertion pass rate cannot be empty
api_scenario_report.assertion_pass_rate.length_range=Assertion pass rate length must be between 1-20
#moduleApiScenarioEnv #moduleApiScenarioEnv
api_scenario_environment.id.not_blank=The scene environment pk cannot be empty api_scenario_environment.id.not_blank=The scene environment pk cannot be empty
api_scenario_environment.api_scenario_id.length_range=Scene fk length must be between 1-50 api_scenario_environment.api_scenario_id.length_range=Scene fk length must be between 1-50
@ -198,8 +220,15 @@ api_definition_mock.project_id.length_range=Item fk length must be between 1-50
api_definition_mock.project_id.not_blank=Item fk cannot be empty api_definition_mock.project_id.not_blank=Item fk cannot be empty
api_definition_mock.api_definition_id.length_range=Interface fk length must be between 1-50 api_definition_mock.api_definition_id.length_range=Interface fk length must be between 1-50
api_definition_mock.api_definition_id.not_blank=Interface fk cannot be empty api_definition_mock.api_definition_id.not_blank=Interface fk cannot be empty
#moduleApiScenarioReportStructure #moduleApiScenarioReportStep
api_scenario_report_structure.report_id.not_blank=Request resource id cannot be empty api_scenario_report_step.step_id.not_blank=Step ID cannot be empty
api_scenario_report_step.step_id.length_range=Step ID length must be between 1-50
api_scenario_report_step.report_id.not_blank=Report ID cannot be empty
api_scenario_report_step.report_id.length_range=Report ID length must be between 1-50
api_scenario_report_step.sort.not_blank=Sort cannot be empty
api_scenario_report_step.step_type.not_blank=Step type cannot be empty
api_scenario_report_step.parent_id.not_blank=Parent ID cannot be empty
api_scenario_report_step.parent_id.length_range=Parent ID length must be between 1-50
#moduleApiReport #moduleApiReport
api_report.id.not_blank=Interface result report pk cannot be empty api_report.id.not_blank=Interface result report pk cannot be empty
api_report.name.length_range=The interface report name length must be between 1-200 api_report.name.length_range=The interface report name length must be between 1-200
@ -207,9 +236,12 @@ api_report.name.not_blank=Interface report name cannot be empty
api_report.resource_id.length_range=Resource fk/api_definition_id/api_test_case_id length must be between 1-50 api_report.resource_id.length_range=Resource fk/api_definition_id/api_test_case_id length must be between 1-50
api_report.resource_id.not_blank=Resource fk/api_definition_id/api_test_case_id cannot be empty api_report.resource_id.not_blank=Resource fk/api_definition_id/api_test_case_id cannot be empty
api_report.create_user.length_range=Creator fk length must be between 1-50 api_report.create_user.length_range=Creator fk length must be between 1-50
api_report.test_plan_id.not_blank=Test plan fk cannot be empty
api_report.create_user.not_blank=Creator fk cannot be empty api_report.create_user.not_blank=Creator fk cannot be empty
api_report.update_user.length_range=Modifier length must be between 1-50 api_report.update_user.length_range=Modifier length must be between 1-50
api_report.update_user.not_blank=Modifier cannot be empty api_report.update_user.not_blank=Modifier cannot be empty
api_report.start_time.not_blank=Start time cannot be empty
api_report.request_duration.not_blank=Request duration cannot be empty
api_report.deleted.length_range=Delete status length must be between 1-1 api_report.deleted.length_range=Delete status length must be between 1-1
api_report.deleted.not_blank=Delete status cannot be empty api_report.deleted.not_blank=Delete status cannot be empty
api_report.status.length_range=Result status length must be between 1-50 api_report.status.length_range=Result status length must be between 1-50
@ -226,6 +258,40 @@ api_report.integrated_report_id.length_range=Integration report id/api_scenario_
api_report.integrated_report_id.not_blank=Integration report id/api_scenario_report_id cannot be empty api_report.integrated_report_id.not_blank=Integration report id/api_scenario_report_id cannot be empty
api_report.integrated.length_range=Whether it is an integrated report, the default is no, the length must be between 1-1 api_report.integrated.length_range=Whether it is an integrated report, the default is no, the length must be between 1-1
api_report.integrated.not_blank=Whether it is an integrated report, the default is no, it cannot be empty api_report.integrated.not_blank=Whether it is an integrated report, the default is no, it cannot be empty
api_report.error_count.not_blank=Error count cannot be empty
api_report.fake_error_count.not_blank=Fake error count cannot be empty
api_report.pending_count.not_blank=Pending count cannot be empty
api_report.success_count.not_blank=Success count cannot be empty
api_report.assertion_count.not_blank=Assertion count cannot be empty
api_report.assertion_success_count.not_blank=Assertion success count cannot be empty
api_report.request_error_rate.not_blank=Request error rate cannot be empty
api_report.request_error_rate.length_range=Request error rate length must be between 1-20
api_report.request_pending_rate.not_blank=Request pending rate cannot be empty
api_report.request_pending_rate.length_range=Request pending rate length must be between 1-20
api_report.request_fake_error_rate.not_blank=Request false positive rate cannot be empty
api_report.request_fake_error_rate.length_range=Request false positive rate length must be between 1-20
api_report.request_pass_rate.not_blank=Request pass rate cannot be empty
api_report.request_pass_rate.length_range=Request pass rate length must be between 1-20
api_report.assertion_pass_rate.not_blank=Assertion pass rate cannot be empty
api_report.assertion_pass_rate.length_range=Assertion pass rate length must be between 1-20
#module: ApiReportDetail
api_report_detail.id.not_blank=ID cannot be empty
api_report_detail.id.length_range=ID length must be between 1-50
api_report_detail.report_id.not_blank=Report fk cannot be empty
api_report_detail.report_id.length_range=Report fk length must be between 1-50
api_report_detail.step_id.not_blank=Step fk cannot be empty
api_report_detail.step_id.length_range=Step fk length must be between 1-50
api_report_detail.status.not_blank=Status cannot be empty
api_report_detail.status.length_range=Status length must be between 1-20
api_report_detail.request_time.not_blank=Request time cannot be empty
api_report_detail.response_size.not_blank=Response size cannot be empty
#moduleApiReportStep
api_report_step.step_id.not_blank=Step pk cannot be empty
api_report_step.step_id.length_range=Step pk length must be between 1-50
api_report_step.report_id.not_blank=Report fk cannot be empty
api_report_step.report_id.length_range=Report fk length must be between 1-50
api_report_step.sort.not_blank=Sort cannot be empty
api_report_step.step_type.not_blank=Step type cannot be empty
#moduleApiDefinitionModule #moduleApiDefinitionModule
api_definition_module.id.not_blank=Interface module pk cannot be empty api_definition_module.id.not_blank=Interface module pk cannot be empty
api_definition_module.update_user.length_range=Modifier length must be between 1-50 api_definition_module.update_user.length_range=Modifier length must be between 1-50
@ -270,6 +336,8 @@ api_scenario_report_detail.report_id.length_range=Report fk length must be betwe
api_scenario_report_detail.report_id.not_blank=report fk cannot be empty api_scenario_report_detail.report_id.not_blank=report fk cannot be empty
api_scenario_report_detail.resource_id.length_range=Each step in the scenario requests a unique identifier length must be between 1-50 api_scenario_report_detail.resource_id.length_range=Each step in the scenario requests a unique identifier length must be between 1-50
api_scenario_report_detail.resource_id.not_blank=The unique identifier requested by each step in the scenario cannot be empty api_scenario_report_detail.resource_id.not_blank=The unique identifier requested by each step in the scenario cannot be empty
api_scenario_report_detail.request_time.not_blank=Request time cannot be empty
api_scenario_report_detail.response_size.not_blank=Response size cannot be empty
#moduleApiDefinitionBlob #moduleApiDefinitionBlob
api_definition_blob.api_definition_id.not_blank=The interface fk/one-to-one relationship cannot be empty api_definition_blob.api_definition_id.not_blank=The interface fk/one-to-one relationship cannot be empty
#module: ApiDebug #module: ApiDebug

View File

@ -43,6 +43,8 @@ api_scenario.environment_group.length_range=是否为环境组长度必须在1-1
api_scenario.environment_group.not_blank=是否为环境组不能为空 api_scenario.environment_group.not_blank=是否为环境组不能为空
api_scenario.project_id.length_range=项目ID长度必须在1-50之间 api_scenario.project_id.length_range=项目ID长度必须在1-50之间
api_scenario.project_id.not_blank=项目ID不能为空 api_scenario.project_id.not_blank=项目ID不能为空
api_scenario.request_pass_rate.not_blank=通过率不能为空
api_scenario.request_pass_rate.length_range=通过率长度必须在1-20之间
#module: ApiScenarioStep #module: ApiScenarioStep
api_scenario_step.id.not_blank=ID不能为空 api_scenario_step.id.not_blank=ID不能为空
api_scenario_step.id.length_range=步骤ID长度必须在1-50之间 api_scenario_step.id.length_range=步骤ID长度必须在1-50之间
@ -198,14 +200,22 @@ api_definition_mock.project_id.length_range=项目ID长度必须在1-50之间
api_definition_mock.project_id.not_blank=项目ID不能为空 api_definition_mock.project_id.not_blank=项目ID不能为空
api_definition_mock.api_definition_id.length_range=接口ID长度必须在1-50之间 api_definition_mock.api_definition_id.length_range=接口ID长度必须在1-50之间
api_definition_mock.api_definition_id.not_blank=接口ID不能为空 api_definition_mock.api_definition_id.not_blank=接口ID不能为空
#moduleApiScenarioReportStructure #moduleApiScenarioReportStep
api_scenario_report_structure.report_id.not_blank=请求资源 id不能为空 api_scenario_report_step.step_id.not_blank=步骤ID不能为空
api_scenario_report_step.step_id.length_range=步骤ID长度必须在1-50之间
api_scenario_report_step.report_id.not_blank=报告ID不能为空
api_scenario_report_step.report_id.length_range=报告ID长度必须在1-50之间
api_scenario_report_step.sort.not_blank=步骤排序不能为空
api_scenario_report_step.step_type.not_blank=步骤类型不能为空
api_scenario_report_step.parent_id.not_blank=父级ID不能为空
api_scenario_report_step.parent_id.length_range=父级ID长度必须在1-50之间
#moduleApiReport #moduleApiReport
api_report.id.not_blank=接口结果报告pk不能为空 api_report.id.not_blank=接口结果报告pk不能为空
api_report.name.length_range=接口报告名称长度必须在1-200之间 api_report.name.length_range=接口报告名称长度必须在1-200之间
api_report.name.not_blank=接口报告名称不能为空 api_report.name.not_blank=接口报告名称不能为空
api_report.resource_id.length_range=资源ID/api_definition_id/api_test_case_id长度必须在1-50之间 api_report.resource_id.length_range=资源ID/api_definition_id/api_test_case_id长度必须在1-50之间
api_report.resource_id.not_blank=资源ID/api_definition_id/api_test_case_id不能为空 api_report.resource_id.not_blank=资源ID/api_definition_id/api_test_case_id不能为空
api_report.test_plan_id.not_blank=测试计划ID不能为空
api_report.create_user.length_range=创建人ID长度必须在1-50之间 api_report.create_user.length_range=创建人ID长度必须在1-50之间
api_report.create_user.not_blank=创建人ID不能为空 api_report.create_user.not_blank=创建人ID不能为空
api_report.update_user.length_range=修改人长度必须在1-50之间 api_report.update_user.length_range=修改人长度必须在1-50之间
@ -214,6 +224,8 @@ api_report.deleted.length_range=删除状态长度必须在1-1之间
api_report.deleted.not_blank=删除状态不能为空 api_report.deleted.not_blank=删除状态不能为空
api_report.status.length_range=结果状态长度必须在1-50之间 api_report.status.length_range=结果状态长度必须在1-50之间
api_report.status.not_blank=结果状态不能为空 api_report.status.not_blank=结果状态不能为空
api_report.start_time.not_blank=开始时间不能为空
api_report.request_duration.not_blank=请求时长不能为空
api_report.run_mode.length_range=执行模块/API/CASE/API_PLAN长度必须在1-20之间 api_report.run_mode.length_range=执行模块/API/CASE/API_PLAN长度必须在1-20之间
api_report.run_mode.not_blank=执行模块/API/CASE/API_PLAN不能为空 api_report.run_mode.not_blank=执行模块/API/CASE/API_PLAN不能为空
api_report.pool_id.length_range=资源池长度必须在1-50之间 api_report.pool_id.length_range=资源池长度必须在1-50之间
@ -226,6 +238,29 @@ api_report.integrated_report_id.length_range=集成报告id/api_scenario_report_
api_report.integrated_report_id.not_blank=集成报告id/api_scenario_report_id不能为空 api_report.integrated_report_id.not_blank=集成报告id/api_scenario_report_id不能为空
api_report.integrated.length_range=是否为集成报告默认否长度必须在1-1之间 api_report.integrated.length_range=是否为集成报告默认否长度必须在1-1之间
api_report.integrated.not_blank=是否为集成报告,默认否不能为空 api_report.integrated.not_blank=是否为集成报告,默认否不能为空
api_report.error_count.not_blank=失败数量不能为空
api_report.fake_error_count.not_blank=误报数量不能为空
api_report.pending_count.not_blank=未执行数量不能为空
api_report.success_count.not_blank=成功数量不能为空
api_report.assertion_count.not_blank=断言数量不能为空
api_report.assertion_success_count.not_blank=断言成功数量不能为空
api_report.request_error_rate.not_blank=请求错误率不能为空
api_report.request_error_rate.length_range=请求错误率长度必须在1-20之间
api_report.request_pending_rate.not_blank=请求未执行率不能为空
api_report.request_pending_rate.length_range=请求未执行率长度必须在1-20之间
api_report.request_fake_error_rate.not_blank=请求误报率不能为空
api_report.request_fake_error_rate.length_range=请求误报率长度必须在1-20之间
api_report.request_pass_rate.not_blank=请求通过率不能为空
api_report.request_pass_rate.length_range=请求通过率长度必须在1-20之间
api_report.assertion_pass_rate.not_blank=断言通过率不能为空
api_report.assertion_pass_rate.length_range=断言通过率长度必须在1-20之间
#moduleApiReportStep
api_report_step.step_id.not_blank=步骤ID不能为空
api_report_step.step_id.length_range=步骤ID长度必须在1-50之间
api_report_step.report_id.not_blank=报告ID不能为空
api_report_step.report_id.length_range=报告ID长度必须在1-50之间
api_report_step.sort.not_blank=步骤排序不能为空
api_report_step.step_type.not_blank=步骤类型不能为空
#moduleApiDefinitionModule #moduleApiDefinitionModule
api_definition_module.id.not_blank=接口模块pk不能为空 api_definition_module.id.not_blank=接口模块pk不能为空
api_definition_module.update_user.length_range=修改人长度必须在1-50之间 api_definition_module.update_user.length_range=修改人长度必须在1-50之间
@ -270,6 +305,8 @@ api_scenario_report_detail.report_id.length_range=报告ID长度必须在1-50之
api_scenario_report_detail.report_id.not_blank=报告ID不能为空 api_scenario_report_detail.report_id.not_blank=报告ID不能为空
api_scenario_report_detail.resource_id.length_range=场景中各个步骤请求唯一标识长度必须在1-50之间 api_scenario_report_detail.resource_id.length_range=场景中各个步骤请求唯一标识长度必须在1-50之间
api_scenario_report_detail.resource_id.not_blank=场景中各个步骤请求唯一标识不能为空 api_scenario_report_detail.resource_id.not_blank=场景中各个步骤请求唯一标识不能为空
api_scenario_report_detail.request_time.not_blank=请求时间不能为空
api_scenario_report_detail.response_size.not_blank=响应大小不能为空
#moduleApiDefinitionBlob #moduleApiDefinitionBlob
api_definition_blob.api_definition_id.not_blank=接口ID/ 一对一关系不能为空 api_definition_blob.api_definition_id.not_blank=接口ID/ 一对一关系不能为空
#module: ApiDebug #module: ApiDebug

View File

@ -43,6 +43,8 @@ api_scenario.environment_group.length_range=是否為環境組長度必須在1-1
api_scenario.environment_group.not_blank=是否為環境組不能為空 api_scenario.environment_group.not_blank=是否為環境組不能為空
api_scenario.project_id.length_range=項目ID長度必須在1-50之間 api_scenario.project_id.length_range=項目ID長度必須在1-50之間
api_scenario.project_id.not_blank=項目ID不能為空 api_scenario.project_id.not_blank=項目ID不能為空
api_scenario.request_pass_rate.not_blank=通過率不能為空
api_scenario.request_pass_rate.length_range=通過率長度必須在1-20之間
#module: ApiScenarioStep #module: ApiScenarioStep
api_scenario_step.id.not_blank=步骤ID不能為空 api_scenario_step.id.not_blank=步骤ID不能為空
api_scenario_step.id.length_range=步骤ID長度必須在1-50之間 api_scenario_step.id.length_range=步骤ID長度必須在1-50之間
@ -198,8 +200,15 @@ api_definition_mock.project_id.length_range=項目ID長度必須在1-50之間
api_definition_mock.project_id.not_blank=項目ID不能為空 api_definition_mock.project_id.not_blank=項目ID不能為空
api_definition_mock.api_definition_id.length_range=接口ID長度必須在1-50之間 api_definition_mock.api_definition_id.length_range=接口ID長度必須在1-50之間
api_definition_mock.api_definition_id.not_blank=接口ID不能為空 api_definition_mock.api_definition_id.not_blank=接口ID不能為空
#moduleApiScenarioReportStructure #moduleApiScenarioReportStep
api_scenario_report_structure.report_id.not_blank=請求資源 id不能為空 api_scenario_report_step.step_id.not_blank=步骤ID不能為空
api_scenario_report_step.step_id.length_range=步骤ID长度必须在1-50之间
api_scenario_report_step.report_id.not_blank=报告ID不能為空
api_scenario_report_step.report_id.length_range=报告ID长度必须在1-50之间
api_scenario_report_step.sort.not_blank=步骤排序不能為空
api_scenario_report_step.step_type.not_blank=步骤类型不能為空
api_scenario_report_step.parent_id.not_blank=父级ID不能為空
api_scenario_report_step.parent_id.length_range=父级ID长度必须在1-50之间
#moduleApiReport #moduleApiReport
api_report.id.not_blank=接口結果報告pk不能為空 api_report.id.not_blank=接口結果報告pk不能為空
api_report.name.length_range=接口報告名稱長度必須在1-200之間 api_report.name.length_range=接口報告名稱長度必須在1-200之間
@ -207,10 +216,13 @@ api_report.name.not_blank=接口報告名稱不能為空
api_report.resource_id.length_range=資源ID/api_definition_id/api_test_case_id長度必須在1-50之間 api_report.resource_id.length_range=資源ID/api_definition_id/api_test_case_id長度必須在1-50之間
api_report.resource_id.not_blank=資源ID/api_definition_id/api_test_case_id不能為空 api_report.resource_id.not_blank=資源ID/api_definition_id/api_test_case_id不能為空
api_report.create_user.length_range=創建人ID長度必須在1-50之間 api_report.create_user.length_range=創建人ID長度必須在1-50之間
api_report.test_plan_id.not_blank=測試計劃ID不能為空
api_report.create_user.not_blank=創建人ID不能為空 api_report.create_user.not_blank=創建人ID不能為空
api_report.update_user.length_range=修改人長度必須在1-50之間 api_report.update_user.length_range=修改人長度必須在1-50之間
api_report.update_user.not_blank=修改人不能為空 api_report.update_user.not_blank=修改人不能為空
api_report.start_time.not_blank=開始時間不能為空
api_report.deleted.length_range=刪除狀態長度必須在1-1之間 api_report.deleted.length_range=刪除狀態長度必須在1-1之間
api_report.request_duration.not_blank=請求時長不能為空
api_report.deleted.not_blank=刪除狀態不能為空 api_report.deleted.not_blank=刪除狀態不能為空
api_report.status.length_range=結果狀態長度必須在1-50之間 api_report.status.length_range=結果狀態長度必須在1-50之間
api_report.status.not_blank=結果狀態不能為空 api_report.status.not_blank=結果狀態不能為空
@ -226,6 +238,29 @@ api_report.integrated_report_id.length_range=集成報告id/api_scenario_report_
api_report.integrated_report_id.not_blank=集成報告id/api_scenario_report_id不能為空 api_report.integrated_report_id.not_blank=集成報告id/api_scenario_report_id不能為空
api_report.integrated.length_range=是否為集成報告默認否長度必須在1-1之間 api_report.integrated.length_range=是否為集成報告默認否長度必須在1-1之間
api_report.integrated.not_blank=是否為集成報告,默認否不能為空 api_report.integrated.not_blank=是否為集成報告,默認否不能為空
api_report.error_count.not_blank=錯誤數不能為空
api_report.fake_error_count.not_blank=誤報數不能為空
api_report.pending_count.not_blank=未执行數不能為空
api_report.success_count.not_blank=成功數不能為空
api_report.assertion_count.not_blank=斷言數不能為空
api_report.assertion_success_count.not_blank=斷言成功數不能為空
api_report.request_error_rate.not_blank=請求錯誤率不能為空
api_report.request_error_rate.length_range=請求錯誤率長度必須在1-20之間
api_report.request_pending_rate.not_blank=請求未执行率不能為空
api_report.request_pending_rate.length_range=請求未执行率長度必須在1-20之間
api_report.request_fake_error_rate.not_blank=請求误报率不能为空
api_report.request_fake_error_rate.length_range=請求误报率长度必须在1-20之间
api_report.request_pass_rate.not_blank=請求通过率不能为空
api_report.request_pass_rate.length_range=請求通过率长度必须在1-20之间
api_report.assertion_pass_rate.not_blank=断言通过率不能为空
api_report.assertion_pass_rate.length_range=断言通过率长度必须在1-20之间
#moduleApiReportStep
api_report_step.step_id.not_blank=步骤ID不能為空
api_report_step.step_id.length_range=步骤ID長度必須在1-50之間
api_report_step.report_id.not_blank=報告ID不能為空
api_report_step.report_id.length_range=報告ID長度必須在1-50之間
api_report_step.sort.not_blank=步驟排序不能為空
api_report_step.step_type.not_blank=步驟類型不能為空
#moduleApiDefinitionModule #moduleApiDefinitionModule
api_definition_module.id.not_blank=接口模塊pk不能為空 api_definition_module.id.not_blank=接口模塊pk不能為空
api_definition_module.update_user.length_range=修改人長度必須在1-50之間 api_definition_module.update_user.length_range=修改人長度必須在1-50之間
@ -270,6 +305,8 @@ api_scenario_report_detail.report_id.length_range=報告ID長度必須在1-50之
api_scenario_report_detail.report_id.not_blank=報告ID不能為空 api_scenario_report_detail.report_id.not_blank=報告ID不能為空
api_scenario_report_detail.resource_id.length_range=場景中各個步驟請求唯一標識長度必須在1-50之間 api_scenario_report_detail.resource_id.length_range=場景中各個步驟請求唯一標識長度必須在1-50之間
api_scenario_report_detail.resource_id.not_blank=場景中各個步驟請求唯一標識不能為空 api_scenario_report_detail.resource_id.not_blank=場景中各個步驟請求唯一標識不能為空
api_scenario_report_detail.request_time.not_blank=請求時間不能為空
api_scenario_report_detail.response_size.not_blank=請求大小不能為空
#moduleApiDefinitionBlob #moduleApiDefinitionBlob
api_definition_blob.api_definition_id.not_blank=接口ID/ 一對一關繫不能為空 api_definition_blob.api_definition_id.not_blank=接口ID/ 一對一關繫不能為空
#module: ApiDebug #module: ApiDebug

View File

@ -79,7 +79,7 @@ public class ApiReportController {
@GetMapping("/get/{shareId}/{reportId}") @GetMapping("/get/{shareId}/{reportId}")
@Operation(summary = "接口测试-接口报告-分享报告获取") @Operation(summary = "接口测试-接口报告-分享报告获取")
public ApiReport get(@PathVariable String shareId, @PathVariable String reportId) { public ApiReportDTO get(@PathVariable String shareId, @PathVariable String reportId) {
ShareInfo shareInfo = apiReportShareService.checkResource(shareId); ShareInfo shareInfo = apiReportShareService.checkResource(shareId);
apiReportShareService.validateExpired(shareInfo); apiReportShareService.validateExpired(shareInfo);
return apiReportService.get(reportId); return apiReportService.get(reportId);

View File

@ -0,0 +1,106 @@
package io.metersphere.api.controller.scenario;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.api.domain.ApiScenarioReport;
import io.metersphere.api.dto.definition.ApiReportBatchRequest;
import io.metersphere.api.dto.definition.ApiReportPageRequest;
import io.metersphere.api.dto.scenario.ApiScenarioReportDTO;
import io.metersphere.api.dto.scenario.ApiScenarioReportDetailDTO;
import io.metersphere.api.service.ApiReportShareService;
import io.metersphere.api.service.scenario.ApiScenarioReportService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.domain.ShareInfo;
import io.metersphere.system.security.CheckOwner;
import io.metersphere.system.utils.PageUtils;
import io.metersphere.system.utils.Pager;
import io.metersphere.system.utils.SessionUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
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.*;
import java.util.List;
@RestController
@RequestMapping(value = "/api/report/scenario")
@Tag(name = "接口测试-接口报告-场景")
public class ApiScenarioReportController {
@Resource
private ApiScenarioReportService apiScenarioReportService;
@Resource
private ApiReportShareService apiReportShareService;
@PostMapping("/page")
@Operation(summary = "接口测试-接口报告-场景()")
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
@RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_READ)
public Pager<List<ApiScenarioReport>> 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, apiScenarioReportService.getPage(request));
}
@GetMapping("/rename/{id}/{name}")
@Operation(summary = "接口测试-接口报告-场景报告重命名")
@CheckOwner(resourceId = "#id", resourceType = "api_scenario_report")
@RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_UPDATE)
public void rename(@PathVariable String id, @PathVariable String name) {
apiScenarioReportService.rename(id, name, SessionUtils.getUserId());
}
@GetMapping("/delete/{id}")
@Operation(summary = "接口测试-接口报告-场景报告删除")
@CheckOwner(resourceId = "#id", resourceType = "api_scenario_report")
@RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_DELETE)
public void delete(@PathVariable String id) {
apiScenarioReportService.delete(id, SessionUtils.getUserId());
}
@PostMapping("/batch/delete")
@Operation(summary = "接口测试-接口报告-场景报告批量删除")
@CheckOwner(resourceId = "#request.getSelectIds()", resourceType = "api_scenario_report")
@RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_DELETE)
public void batchDelete(@RequestBody ApiReportBatchRequest request) {
apiScenarioReportService.batchDelete(request, SessionUtils.getUserId());
}
@GetMapping("/get/{id}")
@Operation(summary = "接口测试-接口报告-报告获取")
@CheckOwner(resourceId = "#id", resourceType = "api_scenario_report")
@RequiresPermissions(value = {PermissionConstants.PROJECT_API_REPORT_READ, PermissionConstants.PROJECT_API_SCENARIO_UPDATE}, logical = Logical.OR)
public ApiScenarioReportDTO get(@PathVariable String id) {
return apiScenarioReportService.get(id);
}
@GetMapping("/get/{shareId}/{reportId}")
@Operation(summary = "接口测试-接口报告-分享报告获取")
public ApiScenarioReportDTO get(@PathVariable String shareId, @PathVariable String reportId) {
ShareInfo shareInfo = apiReportShareService.checkResource(shareId);
apiReportShareService.validateExpired(shareInfo);
return apiScenarioReportService.get(reportId);
}
@GetMapping("/get/detail/{reportId}/{stepId}")
@Operation(summary = "接口测试-接口报告-报告详情获取")
@CheckOwner(resourceId = "#reportId", resourceType = "api_scenario_report")
@RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_READ)
public List<ApiScenarioReportDetailDTO> getDetail(@PathVariable String stepId,
@PathVariable String reportId) {
return apiScenarioReportService.getDetail(stepId, reportId);
}
@GetMapping("/get/detail/{shareId}/{reportId}/{stepId}")
public List<ApiScenarioReportDetailDTO> selectReportContent(@PathVariable String shareId,
@PathVariable String reportId,
@PathVariable String stepId) {
ShareInfo shareInfo = apiReportShareService.checkResource(shareId);
apiReportShareService.validateExpired(shareInfo);
return apiScenarioReportService.getDetail(stepId, reportId);
}
}

View File

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

View File

@ -0,0 +1,43 @@
package io.metersphere.api.dto.definition;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class ApiReportStepDTO {
@Schema(description = "步骤id")
private String stepId;
@Schema(description = "报告id")
private String reportId;
@Schema(description = "步骤名称")
private String name;
@Schema(description = "序号")
private Long sort;
@Schema(description = "步骤类型/API/CASE等")
private String stepType;
@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;
}

View File

@ -0,0 +1,15 @@
package io.metersphere.api.dto.scenario;
import io.metersphere.api.domain.ApiScenarioReport;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class ApiScenarioReportDTO extends ApiScenarioReport {
@Schema(description = "子节点")
private List<ApiScenarioReportStepDTO> children;
@Schema(description = "步骤总数")
private Integer stepTotal;
}

View File

@ -0,0 +1,44 @@
package io.metersphere.api.dto.scenario;
import io.metersphere.sdk.dto.api.result.RequestResult;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class ApiScenarioReportDetailDTO {
@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,52 @@
package io.metersphere.api.dto.scenario;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class ApiScenarioReportStepDTO {
@Schema(description = "步骤id")
private String stepId;
@Schema(description = "报告id")
private String reportId;
@Schema(description = "步骤名称")
private String name;
@Schema(description = "序号")
private Long sort;
@Schema(description = "步骤类型/API/CASE等")
private String stepType;
@Schema(description = "父级id")
private String parentId;
@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 List<ApiScenarioReportStepDTO> children;
}

View File

@ -3,6 +3,7 @@ package io.metersphere.api.mapper;
import io.metersphere.api.domain.ApiReport; import io.metersphere.api.domain.ApiReport;
import io.metersphere.api.dto.definition.ApiReportBatchRequest; import io.metersphere.api.dto.definition.ApiReportBatchRequest;
import io.metersphere.api.dto.definition.ApiReportPageRequest; import io.metersphere.api.dto.definition.ApiReportPageRequest;
import io.metersphere.api.dto.definition.ApiReportStepDTO;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
@ -13,4 +14,6 @@ public interface ExtApiReportMapper {
List<String> getIds(@Param("request") ApiReportBatchRequest request); List<String> getIds(@Param("request") ApiReportBatchRequest request);
List<ApiReport> selectApiReportByIds(@Param("ids") List<String> ids, @Param("deleted") boolean deleted); List<ApiReport> selectApiReportByIds(@Param("ids") List<String> ids, @Param("deleted") boolean deleted);
List<ApiReportStepDTO> selectStepsByReportId(String id);
} }

View File

@ -55,6 +55,23 @@
#{id} #{id}
</foreach> </foreach>
</select> </select>
<select id="selectStepsByReportId" resultType="io.metersphere.api.dto.definition.ApiReportStepDTO">
select api_report_step.step_id,
api_report_step.report_id,
api_report_step.`name`,
api_report_step.sort,
api_report_step.step_type,
api_report_detail.status,
api_report_detail.fake_code,
api_report_detail.request_name,
api_report_detail.request_time,
api_report_detail.code,
api_report_detail.response_size,
api_report_detail.script_identifier
from api_report_step left join api_report_detail on api_report_step.step_id = api_report_detail.step_id
and api_report_detail.report_id = api_report_step.report_id
where api_report_step.report_id = #{reportId}
</select>
<sql id="filters"> <sql id="filters">

View File

@ -0,0 +1,19 @@
package io.metersphere.api.mapper;
import io.metersphere.api.domain.ApiScenarioReport;
import io.metersphere.api.dto.definition.ApiReportBatchRequest;
import io.metersphere.api.dto.definition.ApiReportPageRequest;
import io.metersphere.api.dto.scenario.ApiScenarioReportStepDTO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ExtApiScenarioReportMapper {
List<ApiScenarioReport> list(@Param("request") ApiReportPageRequest request);
List<String> getIds(@Param("request") ApiReportBatchRequest request);
List<ApiScenarioReport> selectApiReportByIds(@Param("ids") List<String> ids, @Param("deleted") boolean deleted);
List<ApiScenarioReportStepDTO> selectStepByReportId(@Param("reportId") String reportId);
}

View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.api.mapper.ExtApiScenarioReportMapper">
<select id="list" resultType="io.metersphere.api.domain.ApiScenarioReport">
select
api_scenario_report.id,
api_scenario_report.name,
api_scenario_report.integrated,
api_scenario_report.status,
api_scenario_report.start_time,
api_scenario_report.update_time,
api_scenario_report.create_user,
api_scenario_report.update_user,
api_scenario_report.trigger_mode
from api_scenario_report where api_scenario_report.deleted = false
and api_scenario_report.test_plan_id = 'NONE'
<if test="request.keyword != null and request.keyword != ''">
and (
api_scenario_report.name like concat('%', #{request.keyword},'%')
)
</if>
<if test="request.projectId != null and request.projectId != ''">
and api_scenario_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_scenario_report.id
from api_scenario_report where api_scenario_report.deleted = false
and api_scenario_report.test_plan_id = 'NONE'
<if test="request.condition.keyword != null">
and (
api_scenario_report.name like concat('%', #{request.condition.keyword},'%')
)
</if>
<if test="request.projectId != null and request.projectId != ''">
and api_scenario_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.ApiScenarioReport">
select
api_scenario_report.id,
api_scenario_report.name
from api_scenario_report where api_scenario_report.deleted = #{deleted}
and api_scenario_report.test_plan_id = 'NONE'
and api_scenario_report.id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<select id="selectStepByReportId" resultType="io.metersphere.api.dto.scenario.ApiScenarioReportStepDTO">
select api_scenario_report_step.step_id,
api_scenario_report_step.report_id,
api_scenario_report_step.`name`,
api_scenario_report_step.sort,
api_scenario_report_step.step_type,
api_scenario_report_step.parent_id,
api_scenario_report_detail.status,
api_scenario_report_detail.fake_code,
api_scenario_report_detail.request_name,
api_scenario_report_detail.request_time,
api_scenario_report_detail.code,
api_scenario_report_detail.response_size,
api_scenario_report_detail.script_identifier
from api_scenario_report_step
left join api_scenario_report_detail
on api_scenario_report_step.step_id = api_scenario_report_detail.step_id
and api_scenario_report_detail.report_id = api_scenario_report_step.report_id
where api_scenario_report_step.report_id = #{reportId}
</select>
<sql id="filters">
<if test="${filter} != null and ${filter}.size() > 0">
<foreach collection="${filter}.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key=='integrated'">
and api_scenario_report.integrated in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
<when test="key=='status'">
and api_scenario_report.status in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
<when test="key=='triggerMode'">
and api_scenario_report.trigger_mode in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
</choose>
</if>
</foreach>
</if>
</sql>
</mapper>

View File

@ -2,6 +2,7 @@ package io.metersphere.api.service;
import io.metersphere.api.constants.ShareInfoType; import io.metersphere.api.constants.ShareInfoType;
import io.metersphere.api.domain.ApiReport; import io.metersphere.api.domain.ApiReport;
import io.metersphere.api.domain.ApiScenarioReport;
import io.metersphere.api.dto.share.ShareInfoDTO; import io.metersphere.api.dto.share.ShareInfoDTO;
import io.metersphere.api.mapper.ApiReportMapper; import io.metersphere.api.mapper.ApiReportMapper;
import io.metersphere.api.mapper.ApiScenarioReportMapper; import io.metersphere.api.mapper.ApiScenarioReportMapper;
@ -49,12 +50,12 @@ public class ApiReportShareService {
ApiReport apiReport = apiReportMapper.selectByPrimaryKey(new String(shareInfo.getCustomData())); ApiReport apiReport = apiReportMapper.selectByPrimaryKey(new String(shareInfo.getCustomData()));
if (apiReport != null && BooleanUtils.isFalse(apiReport.getDeleted())) { if (apiReport != null && BooleanUtils.isFalse(apiReport.getDeleted())) {
projectId = apiReport.getProjectId(); projectId = apiReport.getProjectId();
} /*else { } else {
ApiScenarioReport result = apiScenarioReportMapper.selectByPrimaryKey(new String(shareInfo.getCustomData())); ApiScenarioReport result = apiScenarioReportMapper.selectByPrimaryKey(new String(shareInfo.getCustomData()));
if (result != null && BooleanUtils.isFalse(result.getDeleted())) { if (result != null && BooleanUtils.isFalse(result.getDeleted())) {
projectId = result.getProjectId(); projectId = result.getProjectId();
} }
}*/ }
} }
if (StringUtils.isBlank(projectId)) { if (StringUtils.isBlank(projectId)) {
throw new MSException(Translator.get("api_case_report_not_exist")); throw new MSException(Translator.get("api_case_report_not_exist"));
@ -102,6 +103,7 @@ public class ApiReportShareService {
String lang = user.getLanguage() == null ? LocaleContextHolder.getLocale().toString() : user.getLanguage(); String lang = user.getLanguage() == null ? LocaleContextHolder.getLocale().toString() : user.getLanguage();
request.setLang(lang); request.setLang(lang);
request.setCreateUser(user.getId()); request.setCreateUser(user.getId());
request.setShareType(ShareInfoType.API_SHARE_REPORT.name());
ShareInfo shareInfo = createShareInfo(request); ShareInfo shareInfo = createShareInfo(request);
return conversionShareInfoToDTO(shareInfo); return conversionShareInfoToDTO(shareInfo);
} }

View File

@ -1,10 +1,7 @@
package io.metersphere.api.service.definition; package io.metersphere.api.service.definition;
import io.metersphere.api.domain.*; import io.metersphere.api.domain.*;
import io.metersphere.api.dto.definition.ApiReportBatchRequest; import io.metersphere.api.dto.definition.*;
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.ApiReportDetailMapper;
import io.metersphere.api.mapper.ApiReportMapper; import io.metersphere.api.mapper.ApiReportMapper;
import io.metersphere.api.mapper.ApiReportStepMapper; import io.metersphere.api.mapper.ApiReportStepMapper;
@ -158,13 +155,11 @@ public class ApiReportService {
ApiReport apiReport = checkResource(id); ApiReport apiReport = checkResource(id);
BeanUtils.copyBean(apiReportDTO, apiReport); BeanUtils.copyBean(apiReportDTO, apiReport);
//需要查询出所有的步骤 //需要查询出所有的步骤
ApiReportStepExample apiReportStep = new ApiReportStepExample(); List<ApiReportStepDTO> apiReportSteps = extApiReportMapper.selectStepsByReportId(id);
apiReportStep.createCriteria().andReportIdEqualTo(id);
List<ApiReportStep> apiReportSteps = apiReportStepMapper.selectByExample(apiReportStep);
if (CollectionUtils.isEmpty(apiReportSteps)) { if (CollectionUtils.isEmpty(apiReportSteps)) {
throw new MSException(Translator.get("api_case_report_not_exist")); throw new MSException(Translator.get("api_case_report_not_exist"));
} }
apiReportSteps.sort(Comparator.comparingLong(ApiReportStep::getSort)); apiReportSteps.sort(Comparator.comparingLong(ApiReportStepDTO::getSort));
apiReportDTO.setChildren(apiReportSteps); apiReportDTO.setChildren(apiReportSteps);
return apiReportDTO; return apiReportDTO;
} }

View File

@ -0,0 +1,87 @@
package io.metersphere.api.service.scenario;
import io.metersphere.api.domain.ApiScenarioReport;
import io.metersphere.api.mapper.ExtApiScenarioReportMapper;
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.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class ApiScenarioReportLogService {
@Resource
private ProjectMapper projectMapper;
@Resource
private OperationLogService operationLogService;
@Resource
private ExtApiScenarioReportMapper extApiScenarioReportMapper;
public void deleteLog(ApiScenarioReport scenarioReport) {
Project project = projectMapper.selectByPrimaryKey(scenarioReport.getProjectId());
LogDTO dto = new LogDTO(
scenarioReport.getProjectId(),
project.getOrganizationId(),
scenarioReport.getId(),
scenarioReport.getUpdateUser(),
OperationLogType.DELETE.name(),
OperationLogModule.API_REPORT,
scenarioReport.getName());
dto.setPath("/api/report/scenario/delete/" + scenarioReport.getId());
dto.setMethod(HttpMethodConstants.GET.name());
dto.setOriginalValue(JSON.toJSONBytes(scenarioReport));
operationLogService.add(dto);
}
public void updateLog(ApiScenarioReport scenarioReport) {
Project project = projectMapper.selectByPrimaryKey(scenarioReport.getProjectId());
LogDTO dto = new LogDTO(
scenarioReport.getProjectId(),
project.getOrganizationId(),
scenarioReport.getId(),
scenarioReport.getUpdateUser(),
OperationLogType.UPDATE.name(),
OperationLogModule.API_REPORT,
scenarioReport.getName());
dto.setPath("/api/report/scenario/rename/" + scenarioReport.getId() + "/" + scenarioReport.getName());
dto.setMethod(HttpMethodConstants.GET.name());
dto.setOriginalValue(JSON.toJSONBytes(scenarioReport));
operationLogService.add(dto);
}
@Async
public void batchDeleteLog(List<String> ids, String userId, String projectId) {
Project project = projectMapper.selectByPrimaryKey(projectId);
List<ApiScenarioReport> apiReports = extApiScenarioReportMapper.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/scenario/batch/delete");
dto.setMethod(HttpMethodConstants.POST.name());
dto.setOriginalValue(JSON.toJSONBytes(apiReport));
logs.add(dto);
});
operationLogService.batchAdd(logs);
}
}

View File

@ -1,10 +1,22 @@
package io.metersphere.api.service.scenario; package io.metersphere.api.service.scenario;
import io.metersphere.api.domain.ApiScenarioReport; import io.metersphere.api.domain.*;
import io.metersphere.api.domain.ApiScenarioReportStep; import io.metersphere.api.dto.definition.ApiReportBatchRequest;
import io.metersphere.api.dto.definition.ApiReportPageRequest;
import io.metersphere.api.dto.scenario.ApiScenarioReportDTO;
import io.metersphere.api.dto.scenario.ApiScenarioReportDetailDTO;
import io.metersphere.api.dto.scenario.ApiScenarioReportStepDTO;
import io.metersphere.api.mapper.ApiScenarioReportDetailMapper;
import io.metersphere.api.mapper.ApiScenarioReportMapper; import io.metersphere.api.mapper.ApiScenarioReportMapper;
import io.metersphere.api.mapper.ApiScenarioReportStepMapper; import io.metersphere.api.mapper.ApiScenarioReportStepMapper;
import io.metersphere.api.mapper.ExtApiScenarioReportMapper;
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.sdk.util.SubListUtils;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.service.UserLoginService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.ExecutorType;
@ -15,7 +27,9 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.List; import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service @Service
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -24,6 +38,17 @@ public class ApiScenarioReportService {
@Resource @Resource
private SqlSessionFactory sqlSessionFactory; private SqlSessionFactory sqlSessionFactory;
@Resource
private ExtApiScenarioReportMapper extApiScenarioReportMapper;
@Resource
private UserLoginService userLoginService;
@Resource
private ApiScenarioReportMapper apiScenarioReportMapper;
@Resource
private ApiScenarioReportLogService apiScenarioReportLogService;
@Resource
private ApiScenarioReportDetailMapper apiScenarioReportDetailMapper;
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public void insertApiScenarioReport(List<ApiScenarioReport> reports) { public void insertApiScenarioReport(List<ApiScenarioReport> reports) {
if (CollectionUtils.isNotEmpty(reports)) { if (CollectionUtils.isNotEmpty(reports)) {
@ -54,5 +79,129 @@ public class ApiScenarioReportService {
} }
} }
public List<ApiScenarioReport> getPage(ApiReportPageRequest request) {
List<ApiScenarioReport> list = extApiScenarioReportMapper.list(request);
//取所有的userid
Set<String> userSet = list.stream()
.flatMap(scenarioReport -> Stream.of(scenarioReport.getUpdateUser(), scenarioReport.getDeleteUser(), scenarioReport.getCreateUser()))
.collect(Collectors.toSet());
Map<String, String> userMap = userLoginService.getUserNameMap(new ArrayList<>(userSet));
list.forEach(scenarioReport -> {
scenarioReport.setCreateUser(userMap.get(scenarioReport.getCreateUser()));
scenarioReport.setUpdateUser(userMap.get(scenarioReport.getUpdateUser()));
scenarioReport.setDeleteUser(userMap.get(scenarioReport.getDeleteUser()));
});
return list;
}
public void rename(String id, String name, String userId) {
ApiScenarioReport apiScenarioReport = checkResource(id);
apiScenarioReport.setName(name);
apiScenarioReport.setUpdateTime(System.currentTimeMillis());
apiScenarioReport.setUpdateUser(userId);
apiScenarioReportMapper.updateByPrimaryKeySelective(apiScenarioReport);
apiScenarioReportLogService.updateLog(apiScenarioReport);
}
public void delete(String id, String userId) {
ApiScenarioReport scenarioReport = checkResource(id);
scenarioReport.setDeleted(true);
scenarioReport.setDeleteTime(System.currentTimeMillis());
scenarioReport.setDeleteUser(userId);
apiScenarioReportMapper.updateByPrimaryKeySelective(scenarioReport);
apiScenarioReportLogService.deleteLog(scenarioReport);
}
private ApiScenarioReport checkResource(String id) {
ApiScenarioReport scenarioReport = apiScenarioReportMapper.selectByPrimaryKey(id);
if (scenarioReport == null) {
throw new RuntimeException(Translator.get("api_scenario_report_not_exist"));
}
return scenarioReport;
}
public void batchDelete(ApiReportBatchRequest request, String userId) {
List<String> ids = doSelectIds(request);
if (CollectionUtils.isEmpty(ids)) {
return;
}
SubListUtils.dealForSubList(ids, 2000, subList -> {
ApiScenarioReportExample example = new ApiScenarioReportExample();
example.createCriteria().andIdIn(subList);
ApiScenarioReport scenarioReport = new ApiScenarioReport();
scenarioReport.setDeleted(true);
scenarioReport.setDeleteTime(System.currentTimeMillis());
scenarioReport.setDeleteUser(userId);
apiScenarioReportMapper.updateByExampleSelective(scenarioReport, example);
//TODO 记录日志
apiScenarioReportLogService.batchDeleteLog(subList, userId, request.getProjectId());
});
}
public List<String> doSelectIds(ApiReportBatchRequest request) {
if (request.isSelectAll()) {
List<String> ids = extApiScenarioReportMapper.getIds(request);
if (CollectionUtils.isNotEmpty(request.getExcludeIds())) {
ids.removeAll(request.getExcludeIds());
}
return ids;
} else {
request.getSelectIds().removeAll(request.getExcludeIds());
return request.getSelectIds();
}
}
public ApiScenarioReportDTO get(String id) {
ApiScenarioReportDTO scenarioReportDTO = new ApiScenarioReportDTO();
ApiScenarioReport scenarioReport = checkResource(id);
BeanUtils.copyBean(scenarioReportDTO, scenarioReport);
//需要查询出所有的步骤
List<ApiScenarioReportStepDTO> scenarioReportSteps = extApiScenarioReportMapper.selectStepByReportId(id);
if (CollectionUtils.isEmpty(scenarioReportSteps)) {
throw new MSException(Translator.get("api_scenario_report_not_exist"));
}
//将scenarioReportSteps按照parentId进行分组 值为list 然后根据sort进行排序
Map<String, List<ApiScenarioReportStepDTO>> scenarioReportStepMap = scenarioReportSteps.stream().collect(Collectors.groupingBy(ApiScenarioReportStepDTO::getParentId));
List<ApiScenarioReportStepDTO> steps = scenarioReportStepMap.get(scenarioReport.getScenarioId());
steps.sort(Comparator.comparingLong(ApiScenarioReportStepDTO::getSort));
getStepTree(steps, scenarioReportStepMap);
scenarioReportDTO.setStepTotal(steps.size());
scenarioReportDTO.setChildren(steps);
return scenarioReportDTO;
}
private static void getStepTree(List<ApiScenarioReportStepDTO> steps, Map<String, List<ApiScenarioReportStepDTO>> scenarioReportStepMap) {
steps.forEach(step -> {
List<ApiScenarioReportStepDTO> children = scenarioReportStepMap.get(step.getStepId());
if (CollectionUtils.isNotEmpty(children)) {
children.sort(Comparator.comparingLong(ApiScenarioReportStepDTO::getSort));
step.setChildren(children);
getStepTree(children, scenarioReportStepMap);
}
});
}
public List<ApiScenarioReportDetailDTO> getDetail(String stepId, String reportId) {
List<ApiScenarioReportDetail> apiReportDetails = checkResourceStep(stepId, reportId);
List<ApiScenarioReportDetailDTO> results = new ArrayList<>();
apiReportDetails.forEach(apiReportDetail -> {
ApiScenarioReportDetailDTO apiReportDetailDTO = new ApiScenarioReportDetailDTO();
BeanUtils.copyBean(apiReportDetailDTO, apiReportDetail);
apiReportDetailDTO.setContent(ApiDataUtils.parseObject(new String(apiReportDetail.getContent()), RequestResult.class));
results.add(apiReportDetailDTO);
});
return results;
}
private List<ApiScenarioReportDetail> checkResourceStep(String stepId, String reportId) {
ApiScenarioReportDetailExample detailExample = new ApiScenarioReportDetailExample();
detailExample.createCriteria().andStepIdEqualTo(stepId).andReportIdEqualTo(reportId);
List<ApiScenarioReportDetail> apiReportDetails = apiScenarioReportDetailMapper.selectByExampleWithBLOBs(detailExample);
if (CollectionUtils.isEmpty(apiReportDetails)) {
throw new MSException(Translator.get("api_case_report_not_exist"));
}
return apiReportDetails;
}
} }

View File

@ -279,7 +279,7 @@ public class ApiReportControllerTests extends BaseTest {
} }
@Test @Test
@Order(6) @Order(7)
public void testGetDetail() throws Exception { public void testGetDetail() throws Exception {
// @@请求成功 // @@请求成功
List<ApiReportDetail> reports = new ArrayList<>(); List<ApiReportDetail> reports = new ArrayList<>();
@ -315,7 +315,7 @@ public class ApiReportControllerTests extends BaseTest {
//分享报告 //分享报告
@Test @Test
@Order(7) @Order(8)
public void generateUrl() throws Exception { public void generateUrl() throws Exception {
ShareInfo shareInfo = new ShareInfo(); ShareInfo shareInfo = new ShareInfo();
shareInfo.setCustomData("test-report-id".getBytes()); shareInfo.setCustomData("test-report-id".getBytes());

View File

@ -1,21 +1,47 @@
package io.metersphere.api.controller; package io.metersphere.api.controller;
import io.metersphere.api.domain.ApiScenarioReport; import io.metersphere.api.constants.ShareInfoType;
import io.metersphere.api.domain.ApiScenarioReportExample; import io.metersphere.api.domain.*;
import io.metersphere.api.domain.ApiScenarioReportStep; import io.metersphere.api.dto.definition.ApiReportBatchRequest;
import io.metersphere.api.domain.ApiScenarioReportStepExample; import io.metersphere.api.dto.definition.ApiReportPageRequest;
import io.metersphere.api.dto.scenario.ApiScenarioDTO;
import io.metersphere.api.dto.scenario.ApiScenarioReportDTO;
import io.metersphere.api.dto.scenario.ApiScenarioReportDetailDTO;
import io.metersphere.api.dto.share.ShareInfoDTO;
import io.metersphere.api.mapper.ApiScenarioReportDetailMapper;
import io.metersphere.api.mapper.ApiScenarioReportMapper; import io.metersphere.api.mapper.ApiScenarioReportMapper;
import io.metersphere.api.mapper.ApiScenarioReportStepMapper; import io.metersphere.api.mapper.ApiScenarioReportStepMapper;
import io.metersphere.api.service.scenario.ApiScenarioReportService; import io.metersphere.api.service.scenario.ApiScenarioReportService;
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.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
import io.metersphere.system.utils.Pager;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc @AutoConfigureMockMvc
@ -27,6 +53,19 @@ public class ApiScenarioReportControllerTests extends BaseTest {
private ApiScenarioReportMapper apiScenarioReportMapper; private ApiScenarioReportMapper apiScenarioReportMapper;
@Resource @Resource
private ApiScenarioReportStepMapper apiScenarioReportStepMapper; private ApiScenarioReportStepMapper apiScenarioReportStepMapper;
@Resource
private ApiScenarioReportDetailMapper apiScenarioReportDetailMapper;
@Resource
private ShareInfoMapper shareInfoMapper;
@Resource
private ProjectApplicationMapper projectApplicationMapper;
private static final String BASIC = "/api/report/scenario";
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 @Test
@Order(1) @Order(1)
@ -34,13 +73,18 @@ public class ApiScenarioReportControllerTests extends BaseTest {
List<ApiScenarioReport> reports = new ArrayList<>(); List<ApiScenarioReport> reports = new ArrayList<>();
for (int i = 0; i < 2515; i++) { for (int i = 0; i < 2515; i++) {
ApiScenarioReport scenarioReport = new ApiScenarioReport(); ApiScenarioReport scenarioReport = new ApiScenarioReport();
scenarioReport.setId("api-report-id" + i); scenarioReport.setId("scenario-report-id" + i);
scenarioReport.setProjectId(DEFAULT_PROJECT_ID); scenarioReport.setProjectId(DEFAULT_PROJECT_ID);
scenarioReport.setName("api-report-name" + i); scenarioReport.setName("scenario-report-name" + i);
scenarioReport.setStartTime(System.currentTimeMillis()); scenarioReport.setStartTime(System.currentTimeMillis());
scenarioReport.setScenarioId("api-scenario-id" + i); scenarioReport.setScenarioId("scenario-scenario-id" + i);
scenarioReport.setCreateUser("admin"); scenarioReport.setCreateUser("admin");
scenarioReport.setUpdateUser("admin"); scenarioReport.setUpdateUser("admin");
if (i % 50 == 0) {
scenarioReport.setStatus(ApiReportStatus.SUCCESS.name());
} else if (i % 39 == 0) {
scenarioReport.setStatus(ApiReportStatus.ERROR.name());
}
scenarioReport.setUpdateTime(System.currentTimeMillis()); scenarioReport.setUpdateTime(System.currentTimeMillis());
scenarioReport.setPoolId("api-pool-id" + i); scenarioReport.setPoolId("api-pool-id" + i);
scenarioReport.setEnvironmentId("api-environment-id" + i); scenarioReport.setEnvironmentId("api-environment-id" + i);
@ -56,8 +100,8 @@ public class ApiScenarioReportControllerTests extends BaseTest {
List<ApiScenarioReportStep> steps = new ArrayList<>(); List<ApiScenarioReportStep> steps = new ArrayList<>();
for (int i = 0; i < 1515; i++) { for (int i = 0; i < 1515; i++) {
ApiScenarioReportStep apiScenarioReportStep = new ApiScenarioReportStep(); ApiScenarioReportStep apiScenarioReportStep = new ApiScenarioReportStep();
apiScenarioReportStep.setStepId("api-report-step-id" + i); apiScenarioReportStep.setStepId("scenario-report-step-id" + i);
apiScenarioReportStep.setReportId("api-report-id" + i); apiScenarioReportStep.setReportId("scenario-report-id" + i);
apiScenarioReportStep.setSort(0L); apiScenarioReportStep.setSort(0L);
apiScenarioReportStep.setStepType("case"); apiScenarioReportStep.setStepType("case");
steps.add(apiScenarioReportStep); steps.add(apiScenarioReportStep);
@ -67,4 +111,291 @@ public class ApiScenarioReportControllerTests extends BaseTest {
Assertions.assertEquals(steps1.size(), 1515); Assertions.assertEquals(steps1.size(), 1515);
} }
private MvcResult responsePost(String url, Object param) throws Exception {
return mockMvc.perform(MockMvcRequestBuilders.post(url)
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.content(JSON.toJSONString(param))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
}
public static <T> T parseObjectFromMvcResult(MvcResult mvcResult, Class<T> parseClass) {
try {
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
//返回请求正常
Assertions.assertNotNull(resultHolder);
return JSON.parseObject(JSON.toJSONString(resultHolder.getData()), parseClass);
} catch (Exception ignore) {
}
return null;
}
@Test
@Order(2)
public void testGetPage() throws Exception {
ApiReportPageRequest request = new ApiReportPageRequest();
request.setCurrent(1);
request.setPageSize(10);
request.setProjectId(DEFAULT_PROJECT_ID);
MvcResult mvcResult = responsePost(PAGE, request);
Pager<?> returnPager = parseObjectFromMvcResult(mvcResult, Pager.class);
//返回值不为空
Assertions.assertNotNull(returnPager);
//返回值的页码和当前页码相同
Assertions.assertEquals(returnPager.getCurrent(), request.getCurrent());
;
//返回的数据量不超过规定要返回的数据量相同
Assertions.assertTrue(((List<ApiScenarioDTO>) returnPager.getList()).size() <= request.getPageSize());
//过滤
request.setFilter(new HashMap<>() {{
put("status", List.of(ApiReportStatus.SUCCESS.name(), ApiReportStatus.ERROR.name()));
}});
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(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 = "scenario-report-new-name";
requestGetWithOk(RENAME + "scenario-report-id0" + "/" + newName);
ApiScenarioReport apiReport = apiScenarioReportMapper.selectByPrimaryKey("scenario-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 + "scenario-report-id0" + "/" + newName);
}
@Test
@Order(4)
public void testDeleted() throws Exception {
// @@请求成功
requestGetWithOk(DELETE + "scenario-report-id0");
ApiScenarioReport apiReport = apiScenarioReportMapper.selectByPrimaryKey("scenario-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 + "scenario-report-id1");
}
@Test
@Order(5)
public void testBatch() throws Exception {
// @@请求成功
ApiReportBatchRequest request = new ApiReportBatchRequest();
request.setProjectId(DEFAULT_PROJECT_ID);
request.setSelectIds(List.of("scenario-report-id3"));
request.setExcludeIds(List.of("scenario-report-id3"));
responsePost(BATCH_DELETE, request);
request.setSelectIds(List.of("scenario-report-id4"));
responsePost(BATCH_DELETE, request);
ApiScenarioReport apiReport = apiScenarioReportMapper.selectByPrimaryKey("scenario-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<ApiScenarioReport> reports = new ArrayList<>();
ApiScenarioReport scenarioReport = new ApiScenarioReport();
scenarioReport.setId("test-scenario-report-id");
scenarioReport.setProjectId(DEFAULT_PROJECT_ID);
scenarioReport.setName("test-scenario-report-name");
scenarioReport.setStartTime(System.currentTimeMillis());
scenarioReport.setScenarioId("test-scenario-scenario-id");
scenarioReport.setCreateUser("admin");
scenarioReport.setUpdateUser("admin");
scenarioReport.setUpdateTime(System.currentTimeMillis());
scenarioReport.setPoolId("api-pool-id");
scenarioReport.setEnvironmentId("api-environment-id");
scenarioReport.setRunMode("api-run-mode");
scenarioReport.setTriggerMode("api-trigger-mode");
scenarioReport.setVersionId("api-version-id");
reports.add(scenarioReport);
apiScenarioReportService.insertApiScenarioReport(reports);
List<ApiScenarioReportStep> steps = new ArrayList<>();
for (int i = 0; i < 20; i++) {
ApiScenarioReportStep apiScenarioReportStep = new ApiScenarioReportStep();
apiScenarioReportStep.setStepId("test-scenario-report-step-id" + i);
apiScenarioReportStep.setReportId("test-scenario-report-id");
apiScenarioReportStep.setSort((long) i);
apiScenarioReportStep.setStepType("case");
if (i % 2 == 0) {
apiScenarioReportStep.setParentId("test-scenario-scenario-id");
} else if (i % 3 == 0) {
apiScenarioReportStep.setParentId("test-scenario-report-step-id" + (i - 1));
} else {
apiScenarioReportStep.setParentId("test-scenario-report-step-id" + (i - 2));
}
steps.add(apiScenarioReportStep);
}
apiScenarioReportService.insertApiScenarioReportStep(steps);
MvcResult mvcResult = this.requestGetWithOk(GET + "test-scenario-report-id")
.andReturn();
ApiScenarioReportDTO apiReportDTO = ApiDataUtils.parseObject(JSON.toJSONString(parseResponse(mvcResult).get("data")), ApiScenarioReportDTO.class);
Assertions.assertNotNull(apiReportDTO);
Assertions.assertEquals(apiReportDTO.getId(), "test-scenario-report-id");
mockMvc.perform(getRequestBuilder(GET + "test"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
mockMvc.perform(getRequestBuilder(GET + "scenario-report-id10"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
// @@校验权限
requestGetPermissionTest(PermissionConstants.PROJECT_API_REPORT_READ, GET + "scenario-report-id0");
}
@Test
@Order(7)
public void testGetDetail() throws Exception {
// @@请求成功
List<ApiScenarioReportDetail> reports = new ArrayList<>();
for (int i = 0; i < 2; i++) {
ApiScenarioReportDetail apiReportDetail = new ApiScenarioReportDetail();
apiReportDetail.setId("test-report-detail-id" + i);
apiReportDetail.setReportId("test-scenario-report-id");
apiReportDetail.setStepId("test-scenario-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);
}
apiScenarioReportDetailMapper.batchInsert(reports);
MvcResult mvcResult = this.requestGetWithOk(DETAIL + "test-scenario-report-id" + "/" + "test-scenario-report-step-id1")
.andReturn();
List<ApiScenarioReportDTO> data = ApiDataUtils.parseArray(JSON.toJSONString(parseResponse(mvcResult).get("data")), ApiScenarioReportDTO.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(8)
public void generateUrl() throws Exception {
ShareInfo shareInfo = new ShareInfo();
shareInfo.setCustomData("test-scenario-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-scenario-report-id")
.andReturn();
ApiScenarioReportDTO apiReportDTO = ApiDataUtils.parseObject(JSON.toJSONString(parseResponse(mvcResult1).get("data")), ApiScenarioReportDTO.class);
Assertions.assertNotNull(apiReportDTO);
Assertions.assertEquals(apiReportDTO.getId(), "test-scenario-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-scenario-report-id" + "/" + "test-scenario-report-step-id1")
.andReturn();
List<ApiScenarioReportDetailDTO> data = ApiDataUtils.parseArray(JSON.toJSONString(parseResponse(mvcResult).get("data")), ApiScenarioReportDetailDTO.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-scenario-report-id"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
//TODO 过期的校验 未完成 需要补充
//项目当前设置了分享时间 并且没有过期
shareInfo = new ShareInfo();
shareInfo.setCustomData("test-scenario-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-scenario-report-id")
.andReturn();
apiReportDTO = ApiDataUtils.parseObject(JSON.toJSONString(parseResponse(mvcResult1).get("data")), ApiScenarioReportDTO.class);
Assertions.assertNotNull(apiReportDTO);
Assertions.assertEquals(apiReportDTO.getId(), "test-scenario-report-id");
//项目当前设置了分享时间 并且过期
shareInfo1 = shareInfoMapper.selectByPrimaryKey(shareId);
shareInfo1.setUpdateTime(1702950953000L);
shareInfoMapper.updateByPrimaryKey(shareInfo1);
mockMvc.perform(getRequestBuilder(GET + shareId + "/" + "test-scenario-report-id"))
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(status().is5xxServerError());
}
} }