feat: add robot logic

This commit is contained in:
guoyuqi 2023-08-25 11:01:53 +08:00 committed by 刘瑞斌
parent 93661e24c8
commit 94cb4c133a
15 changed files with 710 additions and 41 deletions

View File

@ -91,6 +91,11 @@ functional_case_template_extend.id.not_blank=ID is required
functional_case_template_extend.step_model.length_range=Step Model length must be between {min} and {max}
functional_case_template_extend.step_model.not_blank=Step Model is required
project_is_null=Project does not exist
# robot
robot_is_null=The current robot does not exist
ding_type_is_null= DingTalk robot type is required
ding_app_key_is_null=DingTalk AppKey is required
ding_app_secret_is_null=DingTalk AppSecret is required
# permission
permission.project_user.name=User
permission.project_group.name=User group

View File

@ -91,6 +91,11 @@ functional_case_template_extend.id.not_blank=ID不能为空
functional_case_template_extend.step_model.length_range=步骤模型长度必须在{min}-{max}之间
functional_case_template_extend.step_model.not_blank=步骤模型不能为空
project_not_exist=项目不存在
# robot
robot_is_null=当前机器人不存在
ding_type_is_null=钉钉机器人的类型不能为空
ding_app_key_is_null=钉钉的AppKey不能为空
ding_app_secret_is_null=钉钉的AppSecret不能为空
# permission
permission.project_user.name=用户
permission.project_group.name=用户组

View File

@ -91,6 +91,11 @@ functional_case_template_extend.id.not_blank=ID不能為空
functional_case_template_extend.step_model.length_range=步驟模型長度必須在{min}-{max}之間
functional_case_template_extend.step_model.not_blank=步驟模型不能為空
project_is_null=項目不存在
# robot
robot_is_null=當前機器人不存在
ding_type_is_null=釘釘機器人的類型不能為空
ding_app_key_is_null = 釘釘的AppKey不能為空
ding_app_secret_is_null =釘釘的AppSecret不能為空
# permission
permission.project_user.name=用戶
permission.project_group.name=用戶組

View File

@ -18,7 +18,14 @@
<artifactId>metersphere-sdk</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>io.metersphere</groupId>
<artifactId>metersphere-sdk</artifactId>
<version>${revision}</version>
<classifier>tests</classifier>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,90 @@
package io.metersphere.project.controller;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.metersphere.project.domain.ProjectRobot;
import io.metersphere.project.dto.ProjectRobotDTO;
import io.metersphere.project.request.ProjectRobotRequest;
import io.metersphere.project.service.ProjectRobotService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.PageUtils;
import io.metersphere.sdk.util.Pager;
import io.metersphere.sdk.util.SessionUtils;
import io.metersphere.validation.groups.Created;
import io.metersphere.validation.groups.Updated;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Tag(name = "项目机器人管理")
@RestController
@RequestMapping("/project/robot/")
public class ProjectRobotController {
@Resource
private ProjectRobotService projectRobotService;
@PostMapping("/list/page")
@Operation(summary = "获取机器人列表")
@RequiresPermissions(PermissionConstants.PROJECT_MESSAGE_READ)
public Pager<List<ProjectRobot>> listResourcePools(@Validated @RequestBody ProjectRobotRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(), true);
return PageUtils.setPageInfo(page, projectRobotService.getList(request));
}
@PostMapping("add")
@Operation(summary = "新增机器人管理")
@RequiresPermissions(PermissionConstants.PROJECT_MESSAGE_READ_ADD)
public void add(@Validated({Created.class}) @RequestBody ProjectRobotDTO projectRobotDTO) {
ProjectRobot projectRobot = new ProjectRobot();
BeanUtils.copyBean(projectRobot, projectRobotDTO);
projectRobot.setCreateUser(SessionUtils.getUserId());
projectRobot.setCreateTime(System.currentTimeMillis());
projectRobot.setUpdateUser(SessionUtils.getUserId());
projectRobot.setUpdateTime(System.currentTimeMillis());
projectRobotService.add(projectRobot);
}
@PostMapping("update")
@Operation(summary = "更新机器人")
@RequiresPermissions(PermissionConstants.PROJECT_MESSAGE_READ_UPDATE)
public void update(@Validated({Updated.class}) @RequestBody ProjectRobotDTO projectRobotDTO) {
ProjectRobot projectRobot = new ProjectRobot();
BeanUtils.copyBean(projectRobot, projectRobotDTO);
projectRobot.setCreateUser(null);
projectRobot.setCreateTime(null);
projectRobot.setUpdateUser(SessionUtils.getUserId());
projectRobot.setUpdateTime(System.currentTimeMillis());
projectRobotService.update(projectRobot);
}
@GetMapping("get/{id}")
@Operation(summary = "获取机器人详情")
@RequiresPermissions(PermissionConstants.PROJECT_MESSAGE_READ)
public ProjectRobotDTO getDetail(@PathVariable(value = "id") String id) {
return projectRobotService.getDetail(id);
}
@GetMapping("delete/{id}")
@Operation(summary = "删除机器人")
@RequiresPermissions(PermissionConstants.PROJECT_MESSAGE_READ_DELETE)
public void delete(@PathVariable(value = "id") String id) {
projectRobotService.delete(id);
}
@GetMapping("enable/{id}")
@Operation(summary = "禁用机器人")
@RequiresPermissions(PermissionConstants.PROJECT_MESSAGE_READ_UPDATE)
public void enable(@PathVariable(value = "id") String id) {
projectRobotService.enable(id, SessionUtils.getUserId(), System.currentTimeMillis());
}
}

View File

@ -0,0 +1,38 @@
package io.metersphere.project.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class ProjectRobotDTO {
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED)
private String id;
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED)
private String name;
@Schema(description = "所属平台(飞书,钉钉,企业微信,自定义)", requiredMode = Schema.RequiredMode.REQUIRED)
private String platform;
@Schema(description = "webhook", requiredMode = Schema.RequiredMode.REQUIRED)
private String webhook;
@Schema(description = "钉钉自定义和内部")
private String type;
@Schema(description = "钉钉AppKey")
private String appKey;
@Schema(description = "钉钉AppSecret")
private String appSecret;
@Schema(description = "是否启用")
private Boolean enable;
@Schema(description = "描述")
private String description;
@Schema(description = "项目id", requiredMode = Schema.RequiredMode.REQUIRED)
private String projectId;
}

View File

@ -0,0 +1,5 @@
package io.metersphere.project.enums;
public enum ProjectRobotPlatform {
DING_TALK, LARK, WE_COM, CUSTOM
}

View File

@ -0,0 +1,5 @@
package io.metersphere.project.enums;
public enum ProjectRobotType {
CUSTOM, ENTERPRISE
}

View File

@ -0,0 +1,11 @@
package io.metersphere.project.request;
import io.metersphere.sdk.dto.BasePageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class ProjectRobotRequest extends BasePageRequest {
@Schema(description = "是否禁用")
private Boolean enable;
}

View File

@ -0,0 +1,110 @@
package io.metersphere.project.service;
import io.metersphere.project.domain.ProjectRobot;
import io.metersphere.project.domain.ProjectRobotExample;
import io.metersphere.project.dto.ProjectRobotDTO;
import io.metersphere.project.enums.ProjectRobotPlatform;
import io.metersphere.project.enums.ProjectRobotType;
import io.metersphere.project.mapper.ProjectRobotMapper;
import io.metersphere.project.request.ProjectRobotRequest;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.Translator;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.UUID;
@Service
@Transactional
public class ProjectRobotService {
@Resource
private ProjectRobotMapper robotMapper;
public void add(ProjectRobot projectRobot) {
projectRobot.setId(UUID.randomUUID().toString());
projectRobot.setEnable(true);
checkDingTalk(projectRobot);
robotMapper.insert(projectRobot);
}
private static void checkDingTalk(ProjectRobot projectRobot) {
if (StringUtils.equals(projectRobot.getPlatform(), ProjectRobotPlatform.DING_TALK.toString())) {
if (StringUtils.isBlank(projectRobot.getType())) {
throw new MSException(Translator.get("ding_type_is_null"));
}
if (StringUtils.equals(projectRobot.getType(), ProjectRobotType.ENTERPRISE.toString())) {
if (StringUtils.isBlank(projectRobot.getAppKey())) {
throw new MSException(Translator.get("ding_app_key_is_null"));
}
if (StringUtils.isBlank(projectRobot.getAppSecret())) {
throw new MSException(Translator.get("ding_app_secret_is_null"));
}
}
}
}
public void update(ProjectRobot projectRobot) {
checkRobotExist(projectRobot.getId());
checkDingTalk(projectRobot);
robotMapper.updateByPrimaryKeySelective(projectRobot);
}
private ProjectRobot checkRobotExist(String robotId) {
ProjectRobot projectRobotInDB = robotMapper.selectByPrimaryKey(robotId);
if (projectRobotInDB == null) {
throw new MSException(Translator.get("robot_is_null"));
}
return projectRobotInDB;
}
public void delete(String id) {
checkRobotExist(id);
robotMapper.deleteByPrimaryKey(id);
}
public void enable(String id, String updateUser, Long updateTime) {
ProjectRobot projectRobot = checkRobotExist(id);
if (projectRobot.getEnable()) {
projectRobot.setEnable(false);
} else {
projectRobot.setEnable(true);
}
projectRobot.setCreateUser(null);
projectRobot.setCreateTime(null);
projectRobot.setUpdateUser(updateUser);
projectRobot.setUpdateTime(updateTime);
robotMapper.updateByPrimaryKeySelective(projectRobot);
}
public List<ProjectRobot> getList(ProjectRobotRequest request) {
ProjectRobotExample projectExample = new ProjectRobotExample();
ProjectRobotExample.Criteria criteria = projectExample.createCriteria();
if (StringUtils.isNotBlank(request.getKeyword())) {
criteria.andNameLike(StringUtils.wrapIfMissing(request.getKeyword(), "%"));
}
if (request.getEnable() != null) {
criteria.andEnableEqualTo(request.getEnable());
}
projectExample.setOrderByClause("create_time desc");
return robotMapper.selectByExample(projectExample);
}
public ProjectRobotDTO getDetail(String robotId) {
ProjectRobot projectRobotInDB = checkRobotExist(robotId);
ProjectRobotDTO projectRobotDTO = new ProjectRobotDTO();
BeanUtils.copyBean(projectRobotDTO, projectRobotInDB);
return projectRobotDTO;
}
}

View File

@ -1,7 +1,7 @@
package io.metersphere.project.controller;
import com.jayway.jsonpath.JsonPath;
import io.metersphere.project.domain.ProjectApplication;
import io.metersphere.sdk.base.BaseTest;
import io.metersphere.sdk.constants.SessionConstants;
import io.metersphere.sdk.util.JSON;
import jakarta.annotation.Resource;
@ -22,28 +22,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@SpringBootTest
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc
public class ProjectApplicationControllerTests {
public class ProjectApplicationControllerTests extends BaseTest {
@Resource
private MockMvc mockMvc;
private static String sessionId;
private static String csrfToken;
@Test
@Order(0)
public void login() throws Exception {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login")
.content("{\"username\":\"admin\",\"password\":\"metersphere\"}")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
sessionId = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.sessionId");
csrfToken = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.csrfToken");
}
@Test
@Order(1)
public void testAddApp() throws Exception {
ProjectApplication projectApplication = new ProjectApplication();
projectApplication.setProjectId("1");
@ -60,7 +44,7 @@ public class ProjectApplicationControllerTests {
}
@Test
@Order(2)
@Order(1)
public void testUpdateApp() throws Exception {
ProjectApplication projectApplication = new ProjectApplication();
projectApplication.setProjectId("1");
@ -77,7 +61,7 @@ public class ProjectApplicationControllerTests {
}
@Test
@Order(3)
@Order(2)
public void testListApp() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/project/application/list/1")
.header(SessionConstants.HEADER_TOKEN, sessionId)

View File

@ -1,6 +1,7 @@
package io.metersphere.project.controller;
import com.jayway.jsonpath.JsonPath;
import io.metersphere.sdk.base.BaseTest;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
@ -20,28 +21,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@SpringBootTest
@AutoConfigureMockMvc
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class ProjectControllerTests {
public class ProjectControllerTests extends BaseTest {
@Resource
private MockMvc mockMvc;
private static String projectId;
private static String sessionId;
private static String csrfToken;
@Test
@Order(0)
public void login() throws Exception {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/login")
.content("{\"username\":\"admin\",\"password\":\"metersphere\"}")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn();
sessionId = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.sessionId");
csrfToken = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.data.csrfToken");
}
// 添加项目
// @Test
// @Order(1)

View File

@ -0,0 +1,389 @@
package io.metersphere.project.controller;
import io.metersphere.project.domain.ProjectRobot;
import io.metersphere.project.dto.ProjectRobotDTO;
import io.metersphere.project.enums.ProjectRobotPlatform;
import io.metersphere.project.enums.ProjectRobotType;
import io.metersphere.project.request.ProjectRobotRequest;
import io.metersphere.sdk.base.BaseTest;
import io.metersphere.sdk.constants.SessionConstants;
import io.metersphere.sdk.controller.handler.ResultHolder;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Pager;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
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.ResultMatcher;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
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
@AutoConfigureMockMvc
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class ProjectRobotControllerTests extends BaseTest {
public static final String ROBOT_ADD = "/project/robot/add";
public static final String ROBOT_UPDATE = "/project/robot/update";
public static final String ROBOT_DELETE = "/project/robot/delete";
public static final String ROBOT_ENABLE = "/project/robot/enable";
public static final String ROBOT_LIST = "/project/robot/list/page";
public static final String ROBOT_DETAIL = "/project/robot/get";
@Test
@Order(1)
void addRobotSuccessWeCom() throws Exception {
ProjectRobotDTO projectRobotDTO = new ProjectRobotDTO();
projectRobotDTO.setName("企业微信机器人");
projectRobotDTO.setPlatform(ProjectRobotPlatform.WE_COM.toString());
projectRobotDTO.setProjectId("test_project");
projectRobotDTO.setWebhook("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=2b67ccf4-e0da-4cd6-ae74-8d42657865f8");
getPostResult(projectRobotDTO, ROBOT_ADD, status().isOk());
listByKeyWord("企业微信机器人");
}
@Test
@Order(2)
void addRobotSuccessLark() throws Exception {
ProjectRobotDTO projectRobotDTO = new ProjectRobotDTO();
projectRobotDTO.setName("飞书机器人");
projectRobotDTO.setPlatform(ProjectRobotPlatform.LARK.toString());
projectRobotDTO.setProjectId("test_project");
projectRobotDTO.setWebhook("https://open.feishu.cn/open-apis/bot/v2/hook/a6024229-9d9d-41c2-8662-7bc3da1092cb");
getPostResult(projectRobotDTO, ROBOT_ADD, status().isOk());
listByKeyWord("飞书机器人");
}
@Test
@Order(3)
void addRobotSuccessDingCustom() throws Exception {
setDingCustom("钉钉自定义机器人");
listByKeyWord("钉钉自定义机器人");
}
private void setDingCustom(String name) throws Exception {
ProjectRobotDTO projectRobotDTO = new ProjectRobotDTO();
projectRobotDTO.setName(name);
projectRobotDTO.setPlatform(ProjectRobotPlatform.DING_TALK.toString());
projectRobotDTO.setProjectId("test_project");
projectRobotDTO.setType(ProjectRobotType.CUSTOM.toString());
projectRobotDTO.setWebhook("https://oapi.dingtalk.com/robot/send?access_token=fd963136a4d7eebaaa68de261223089148e62d7519fbaf426626fe3157725b8a");
getPostResult(projectRobotDTO, ROBOT_ADD, status().isOk());
}
@Test
@Order(4)
void addRobotSuccessDingEn() throws Exception {
setDingEn("钉钉企业应用机器人");
listByKeyWord("钉钉企业应用机器人");
}
private void setDingEn(String name) throws Exception {
ProjectRobotDTO projectRobotDTO = new ProjectRobotDTO();
projectRobotDTO.setName(name);
projectRobotDTO.setPlatform(ProjectRobotPlatform.DING_TALK.toString());
projectRobotDTO.setProjectId("test_project");
projectRobotDTO.setType(ProjectRobotType.ENTERPRISE.toString());
projectRobotDTO.setAppKey("dingxwd71o7kj4qoixo7");
projectRobotDTO.setAppSecret("szmOD9bjGgKtfYk09-Xx2rPdX-xkW4R8Iic0eig_k1D3k95nG4TLKRSpUKUD_f0G");
projectRobotDTO.setWebhook("https://oapi.dingtalk.com/robot/send?access_token=e971f376669334cd44c585d419f0fdfa1600f97f906109b377999d8a0986b11e");
getPostResult(projectRobotDTO, ROBOT_ADD, status().isOk());
}
@Test
@Order(5)
void addRobotFailDingCustomByType() throws Exception {
ProjectRobotDTO projectRobotDTO = new ProjectRobotDTO();
projectRobotDTO.setName("钉钉自定义机器人");
projectRobotDTO.setPlatform(ProjectRobotPlatform.DING_TALK.toString());
projectRobotDTO.setProjectId("test_project");
projectRobotDTO.setWebhook("https://oapi.dingtalk.com/robot/send?access_token=e971f376669334cd44c585d419f0fdfa1600f97f906109b377999d8a0986b11e");
getPostResult(projectRobotDTO, ROBOT_ADD, status().is5xxServerError());
}
@Test
@Order(6)
void addRobotFailDingCustomByKey() throws Exception {
ProjectRobotDTO projectRobotDTO = new ProjectRobotDTO();
projectRobotDTO.setName("钉钉自定义机器人");
projectRobotDTO.setPlatform(ProjectRobotPlatform.DING_TALK.toString());
projectRobotDTO.setProjectId("test_project");
projectRobotDTO.setType(ProjectRobotType.ENTERPRISE.toString());
projectRobotDTO.setWebhook("https://oapi.dingtalk.com/robot/send?access_token=e971f376669334cd44c585d419f0fdfa1600f97f906109b377999d8a0986b11e");
getPostResult(projectRobotDTO, ROBOT_ADD, status().is5xxServerError());
}
@Test
@Order(7)
void addRobotFailDingCustomBySecret() throws Exception {
ProjectRobotDTO projectRobotDTO = new ProjectRobotDTO();
projectRobotDTO.setName("钉钉自定义机器人");
projectRobotDTO.setPlatform(ProjectRobotPlatform.DING_TALK.toString());
projectRobotDTO.setProjectId("test_project");
projectRobotDTO.setType(ProjectRobotType.ENTERPRISE.toString());
projectRobotDTO.setAppKey("dingxwd71o7kj4qoixo7");
projectRobotDTO.setWebhook("https://oapi.dingtalk.com/robot/send?access_token=e971f376669334cd44c585d419f0fdfa1600f97f906109b377999d8a0986b11e");
getPostResult(projectRobotDTO, ROBOT_ADD, status().is5xxServerError());
}
@Test
@Order(8)
void updateRobotSuccessCusTom() throws Exception {
setCustomRobot("用于更新自定义机器人");
ProjectRobot projectRobot = getRobot("用于更新自定义机器人");
checkUpdate(projectRobot, "更新自定义机器人", status().isOk());
}
@Test
@Order(9)
void updateRobotSuccessDingCus() throws Exception {
setDingCustom("用于更新钉钉自定义机器人");
ProjectRobot projectRobot = getRobot("用于更新钉钉自定义机器人");
checkUpdate(projectRobot, "更新钉钉自定义机器人", status().isOk());
}
@Test
@Order(10)
void updateRobotSuccessDingEn() throws Exception {
setDingEn("用于更新钉钉企业机器人");
ProjectRobot projectRobot = getRobot("用于更新钉钉企业机器人");
checkUpdate(projectRobot, "更新钉钉企业机器人", status().isOk());
}
@Test
@Order(11)
void updateRobotFileIdNotExist() throws Exception {
setCustomRobot("测试没有ID失败");
ProjectRobot projectRobot = getRobot("测试没有ID失败");
projectRobot.setId("noId");
checkUpdate(projectRobot, "测试没有ID失败", status().is5xxServerError());
}
@Test
@Order(12)
void updateRobotFileIdNoId() throws Exception {
setCustomRobot("测试ID空失败");
ProjectRobot projectRobot = getRobot("测试ID空失败");
projectRobot.setId(null);
checkUpdate(projectRobot, "测试ID空失败", status().is5xxServerError());
}
@Test
@Order(13)
void updateRobotFileNoDingType() throws Exception {
setDingCustom("测试更新没有Type失败");
ProjectRobot projectRobot = getRobot("测试更新没有Type失败");
projectRobot.setType(null);
checkUpdate(projectRobot, "测试更新没有Type失败", status().is5xxServerError());
}
@Test
@Order(14)
void updateRobotFileNoDingKey() throws Exception {
setDingEn("测试更新没有key失败");
ProjectRobot projectRobot = getRobot("测试更新没有key失败");
projectRobot.setAppKey(null);
checkUpdate(projectRobot, "测试更新没有key失败", status().is5xxServerError());
}
@Test
@Order(15)
void updateRobotFileNoDingSecret() throws Exception {
setDingEn("测试更新没有Secret失败");
ProjectRobot projectRobot = getRobot("测试更新没有Secret失败");
projectRobot.setAppSecret(null);
checkUpdate(projectRobot, "测试更新没有Secret失败", status().is5xxServerError());
}
@Test
@Order(16)
void deleteRobotSuccess() throws Exception {
setCustomRobot("测试删除");
ProjectRobot projectRobot = getRobot("测试删除");
String projectRobotId = projectRobot.getId();
mockMvc.perform(MockMvcRequestBuilders.get(ROBOT_DELETE+"/"+ projectRobotId)
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
mockMvc.perform(MockMvcRequestBuilders.get(ROBOT_DETAIL + "/" + projectRobotId)
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken))
.andExpect(status().is5xxServerError())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
}
@Test
@Order(17)
void deleteRobotFail() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get(ROBOT_DELETE+"/no_id")
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken))
.andExpect(status().is5xxServerError())
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
}
@Test
@Order(18)
void getDetailFail() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get(ROBOT_DETAIL+"/no_id")
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken))
.andExpect(status().is5xxServerError())
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
}
@Test
@Order(16)
void getDetailSuccess() throws Exception {
setCustomRobot("测试获取详情");
ProjectRobot projectRobot = getRobot("测试获取详情");
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get(ROBOT_DETAIL + "/" + projectRobot.getId())
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
ProjectRobot result = getResult(mvcResult);
Assertions.assertTrue(StringUtils.equals(result.getName(), "测试获取详情"));
Assertions.assertTrue(StringUtils.equals(result.getWebhook(),"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=2b67ccf4-e0da-4cd6-ae74-8d42657865f8"));
}
@Test
@Order(17)
void getListSuccessNoKeyword() throws Exception {
ProjectRobotRequest request = new ProjectRobotRequest();
request.setCurrent(1);
request.setPageSize(5);
Pager<?> sortPageData = getPager(request);
List<ProjectRobot> projectRobots = JSON.parseArray(JSON.toJSONString(sortPageData.getList()), ProjectRobot.class);
Assertions.assertTrue(projectRobots.size()>0);
}
@Test
@Order(18)
void getListSuccessEnable() throws Exception {
setCustomRobot("测试集合");
ProjectRobotRequest request = new ProjectRobotRequest();
request.setCurrent(1);
request.setPageSize(5);
request.setKeyword("测试集合");
request.setEnable(true);
Pager<?> sortPageData = getPager(request);
List<ProjectRobot> projectRobots = JSON.parseArray(JSON.toJSONString(sortPageData.getList()), ProjectRobot.class);
ProjectRobot projectRobot = projectRobots.get(0);
Assertions.assertTrue(projectRobot.getEnable());
}
@Test
@Order(19)
void setEnableSuccess() throws Exception {
setCustomRobot("测试Enable");
ProjectRobot projectRobot = getRobot("测试Enable");
String projectRobotId = projectRobot.getId();
mockMvc.perform(MockMvcRequestBuilders.get(ROBOT_ENABLE+"/"+ projectRobotId)
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
ProjectRobot projectRobotEnable = getRobot("测试Enable");
Assertions.assertFalse(projectRobotEnable.getEnable());
}
@Test
@Order(20)
void setEnableFail() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get(ROBOT_ENABLE+"/no_id")
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken))
.andExpect(status().is5xxServerError())
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
}
private static ProjectRobot getResult(MvcResult mvcResult) throws UnsupportedEncodingException {
String contentAsString = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);;
ResultHolder resultHolder = JSON.parseObject(contentAsString, ResultHolder.class);
return JSON.parseObject(JSON.toJSONString(resultHolder.getData()), ProjectRobot.class);
}
private void checkUpdate(ProjectRobot projectRobot, String name, ResultMatcher resultMatcher) throws Exception {
projectRobot.setName(name);
ProjectRobotDTO projectRobotDTO = new ProjectRobotDTO();
BeanUtils.copyBean(projectRobotDTO, projectRobot);
getPostResult(projectRobotDTO, ROBOT_UPDATE, resultMatcher);
if (resultMatcher.equals(status().isOk())) {
ProjectRobot projectRobotUpdate = getRobot(name);
Assertions.assertTrue(StringUtils.equals(projectRobotUpdate.getName(), name));
}
}
private void setCustomRobot(String name) throws Exception {
ProjectRobotDTO projectRobotDTO = new ProjectRobotDTO();
projectRobotDTO.setName(name);
projectRobotDTO.setPlatform(ProjectRobotPlatform.CUSTOM.toString());
projectRobotDTO.setProjectId("test_project");
projectRobotDTO.setWebhook("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=2b67ccf4-e0da-4cd6-ae74-8d42657865f8");
getPostResult(projectRobotDTO, ROBOT_ADD, status().isOk());
}
private void getPostResult(ProjectRobotDTO projectRobotDTO, String url, ResultMatcher resultMatcher) throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post(url)
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.content(JSON.toJSONString(projectRobotDTO))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(resultMatcher)
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
}
void listByKeyWord(String keyWord) throws Exception {
ProjectRobot projectRobot = getRobot(keyWord);
Assertions.assertTrue(StringUtils.equals(projectRobot.getName(), keyWord));
}
private ProjectRobot getRobot(String keyWord) throws Exception {
ProjectRobotRequest request = new ProjectRobotRequest();
request.setCurrent(1);
request.setPageSize(5);
request.setKeyword(keyWord);
Pager<?> sortPageData = getPager(request);
ProjectRobot projectRobot = JSON.parseArray(JSON.toJSONString(sortPageData.getList()), ProjectRobot.class).get(0);
return projectRobot;
}
private Pager<?> getPager(ProjectRobotRequest request) throws Exception {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post(ROBOT_LIST)
.header(SessionConstants.HEADER_TOKEN, sessionId)
.header(SessionConstants.CSRF_TOKEN, csrfToken)
.content(JSON.toJSONString(request))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON)).andReturn();
String sortData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder sortHolder = JSON.parseObject(sortData, ResultHolder.class);
Pager<?> sortPageData = JSON.parseObject(JSON.toJSONString(sortHolder.getData()), Pager.class);
return sortPageData;
}
}

View File

@ -26,7 +26,10 @@ spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
#
# 单元测试初始化权限 sql
spring.sql.init.mode=always
spring.sql.init.schema-locations=classpath*:dml/init_permission_test.sql
# spring.kafka
spring.kafka.bootstrap-servers=${embedded.kafka.brokerList}
spring.kafka.consumer.group-id=metersphere_group_id

View File

@ -0,0 +1,29 @@
-- 初始化用于权限测试的用户
INSERT INTO user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
last_project_id, create_user, update_user, deleted)
VALUES ('SYSTEM', 'SYSTEM', 'SYSTEM@fit2cloud.com', MD5('metersphere'),
UNIX_TIMESTAMP() * 1000,
UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false);
-- 初始化一个用于权限测试的用户组,这里默认使用 SYSTEM 作为ID如果是组织和项目级别类似便于根据权限的前缀找到对应测试的用户组
INSERT INTO user_role (id, name, description, internal, type, create_time, update_time, create_user, scope_id)
VALUES ('SYSTEM', '系统级别权限校验', '', 1, 'SYSTEM', 1620674220005, 1620674220000, 'admin', 'global');
-- 初始化用户和组的关系
INSERT INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user)
VALUES ('SYSTEM', 'SYSTEM', 'SYSTEM', 'system', 1684747668375, 'admin');
-- 初始化用于权限测试的组织用户
INSERT INTO user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
last_project_id, create_user, update_user, deleted)
VALUES ('ORGANIZATION', 'ORGANIZATION', 'ORGANIZATION@fit2cloud.com', MD5('metersphere'),
UNIX_TIMESTAMP() * 1000,
UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false);
-- 初始化一个用于权限测试的用户组,这里默认使用 ORGANIZATION 作为ID如果是组织和项目级别类似便于根据权限的前缀找到对应测试的用户组
INSERT INTO user_role (id, name, description, internal, type, create_time, update_time, create_user, scope_id)
VALUES ('ORGANIZATION', '组织级别权限校验', '', 1, 'ORGANIZATION', 1620674220005, 1620674220000, 'admin', 'global');
-- 初始化用户和组的关系
INSERT INTO user_role_relation (id, user_id, role_id, source_id, create_time, create_user)
SELECT 'ORGANIZATION', 'ORGANIZATION', 'ORGANIZATION', id, 1684747668375, 'admin' FROM organization WHERE num = 100001;