feat(approval): 审批中心待办/已办与通过驳回撤回 (#20)
- 新增 ApprovalTaskService/Controller:通过、驳回、撤回、待办数量与节点推进 - 通过后同节点同轮其余待办取消,下一节点审批人事务外解析、事务内生成任务 - 任务条件更新(WHERE status='PENDING')保证并发抢办仅成功一次 - 新增 todo/done 列表(状态+关键词)与实例去重的待办计数 - ApprovalTaskIT 覆盖通过、驳回重提、或签、并发、自审、撤回、列表筛选
This commit is contained in:
@@ -0,0 +1,406 @@
|
||||
package com.gxwebsoft.approval;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.gxwebsoft.support.ApprovalTestData;
|
||||
import com.gxwebsoft.support.TestAuthentication;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* 审批中心:待办/已办、通过/驳回、撤回、或签与并发处理的集成测试。
|
||||
*
|
||||
* <p>本类不开启测试事务:动作接口各自独立提交,便于覆盖并发条件更新;
|
||||
* 数据由 {@link ApprovalTestData#cleanup()} 清理。</p>
|
||||
*/
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
@ActiveProfiles({"gxtyzx-test", "test"})
|
||||
class ApprovalTaskIT {
|
||||
|
||||
private static final int TENANT = TestAuthentication.TENANT_ID;
|
||||
private static final String LIST = "approval:instance:list";
|
||||
private static final String SUBMIT = "approval:instance:submit";
|
||||
private static final String APPROVE = "approval:instance:approve";
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
private ApprovalTestData data;
|
||||
private ApprovalTestData.TestUser reporter;
|
||||
private ApprovalTestData.TestUser leader;
|
||||
private Integer organizationId;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
data = new ApprovalTestData(dataSource);
|
||||
organizationId = data.createOrganization("任务部门" + data.uniqueSuffix(), 136);
|
||||
reporter = data.createUser("任务报送人" + data.uniqueSuffix(), organizationId);
|
||||
ApprovalTestData.TestRole leaderRole =
|
||||
data.createRole("dept_leader_" + organizationId, "部门负责人");
|
||||
leader = data.createUser("任务负责人" + data.uniqueSuffix(), organizationId);
|
||||
data.bind(leader.userId, leaderRole.roleId);
|
||||
ApprovalTestData.TestRole archivistRole = data.createRole("approval_archivist", "收文员");
|
||||
ApprovalTestData.TestUser archivist = data.createUser("任务收文员" + data.uniqueSuffix(), organizationId);
|
||||
data.bind(archivist.userId, archivistRole.roleId);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
data.cleanup();
|
||||
}
|
||||
|
||||
@Test
|
||||
void approvesTaskAndActivatesNextConfirmNode() throws Exception {
|
||||
long instanceId = createAndSubmit("通过测试");
|
||||
long taskId = pendingTaskId(instanceId, leader.userId);
|
||||
|
||||
mockMvc.perform(authed(post("/api/approval/task/" + taskId + "/approve"), leader, organizationId, APPROVE)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"opinion\":\"同意办理\"}"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data.id").value((int) instanceId))
|
||||
.andExpect(jsonPath("$.data.status").value("PENDING"))
|
||||
.andExpect(jsonPath("$.data.currentNodeName").value("存档"))
|
||||
.andExpect(jsonPath("$.data.confirms.length()").value(1))
|
||||
.andExpect(jsonPath("$.data.confirms[0].userId").value(reporter.userId))
|
||||
.andExpect(jsonPath("$.data.confirms[0].status").value("PENDING"));
|
||||
|
||||
assertThat(data.queryMaster("SELECT status FROM approval_task WHERE id = ?", String.class, taskId))
|
||||
.isEqualTo("DONE");
|
||||
assertThat(data.queryMaster("SELECT opinion FROM approval_task WHERE id = ?", String.class, taskId))
|
||||
.isEqualTo("同意办理");
|
||||
assertThat(data.queryMaster("SELECT handle_time FROM approval_task WHERE id = ?", Object.class, taskId))
|
||||
.isNotNull();
|
||||
assertThat(data.queryMaster("SELECT current_node_key FROM approval_instance WHERE id = ?", String.class, instanceId))
|
||||
.isEqualTo("confirm");
|
||||
assertThat(data.countMaster("SELECT COUNT(*) FROM approval_task WHERE instance_id = ? "
|
||||
+ "AND node_type = 'CONFIRM' AND assignee_id = ? AND status = 'PENDING'", instanceId, reporter.userId))
|
||||
.isEqualTo(1);
|
||||
assertThat(data.countMaster("SELECT COUNT(*) FROM approval_record WHERE instance_id = ? "
|
||||
+ "AND action = 'APPROVE' AND operator_id = ? AND opinion = '同意办理'", instanceId, leader.userId))
|
||||
.isEqualTo(1);
|
||||
|
||||
// 存档人能看到待确认任务与对应权限
|
||||
mockMvc.perform(authed(get("/api/approval/instance/" + instanceId), reporter, organizationId, LIST))
|
||||
.andExpect(jsonPath("$.data.myTask.nodeType").value("CONFIRM"))
|
||||
.andExpect(jsonPath("$.data.permissions.canConfirm").value(true))
|
||||
.andExpect(jsonPath("$.data.permissions.canApprove").value(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void requiresRejectOpinionAndResubmitsWithSameBizNo() throws Exception {
|
||||
long instanceId = createAndSubmit("驳回重提");
|
||||
long taskId = pendingTaskId(instanceId, leader.userId);
|
||||
String bizNo = data.queryMaster("SELECT biz_no FROM approval_instance WHERE id = ?", String.class, instanceId);
|
||||
|
||||
mockMvc.perform(authed(post("/api/approval/task/" + taskId + "/reject"), leader, organizationId, APPROVE)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"opinion\":\" \"}"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(1))
|
||||
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("驳回意见")));
|
||||
assertThat(data.queryMaster("SELECT status FROM approval_task WHERE id = ?", String.class, taskId))
|
||||
.isEqualTo("PENDING");
|
||||
|
||||
mockMvc.perform(authed(post("/api/approval/task/" + taskId + "/reject"), leader, organizationId, APPROVE)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"opinion\":\"材料不完整\"}"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data.status").value("REJECTED"))
|
||||
.andExpect(jsonPath("$.data.statusName").value("已驳回"))
|
||||
.andExpect(jsonPath("$.data.round").value(2));
|
||||
|
||||
// 单据回到报送人:可修改、可重新提交
|
||||
mockMvc.perform(authed(get("/api/approval/instance/" + instanceId), reporter, organizationId, LIST))
|
||||
.andExpect(jsonPath("$.data.permissions.canEdit").value(true))
|
||||
.andExpect(jsonPath("$.data.permissions.canSubmit").value(true));
|
||||
|
||||
assertThat(data.countMaster("SELECT COUNT(*) FROM approval_task WHERE instance_id = ? AND status = 'PENDING'",
|
||||
instanceId)).isZero();
|
||||
assertThat(data.countMaster("SELECT COUNT(*) FROM approval_record WHERE instance_id = ? "
|
||||
+ "AND action = 'REJECT' AND opinion = '材料不完整'", instanceId)).isEqualTo(1);
|
||||
|
||||
mockMvc.perform(authed(post("/api/approval/instance/" + instanceId + "/submit"), reporter, organizationId, SUBMIT))
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data.status").value("PENDING"))
|
||||
.andExpect(jsonPath("$.data.round").value(3))
|
||||
.andExpect(jsonPath("$.data.bizNo").value(bizNo))
|
||||
.andExpect(jsonPath("$.data.currentNodeName").value("报送部门负责人"));
|
||||
assertThat(pendingTaskId(instanceId, leader.userId)).isPositive();
|
||||
assertThat(data.countMaster("SELECT COUNT(*) FROM approval_record WHERE instance_id = ? "
|
||||
+ "AND action = 'RESUBMIT' AND round = 3", instanceId)).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void approvingOneCountersignTaskCancelsTheRest() throws Exception {
|
||||
ApprovalTestData.TestUser second =
|
||||
data.createUser("第二负责人" + data.uniqueSuffix(), organizationId);
|
||||
Integer leaderRoleId = data.server().queryForObject("SELECT role_id FROM sys_role WHERE role_code = ? AND tenant_id = ?",
|
||||
Integer.class, "dept_leader_" + organizationId, TENANT);
|
||||
data.bind(second.userId, leaderRoleId);
|
||||
|
||||
long instanceId = createAndSubmit("或签取消");
|
||||
long firstTask = pendingTaskId(instanceId, leader.userId);
|
||||
long secondTask = pendingTaskId(instanceId, second.userId);
|
||||
|
||||
mockMvc.perform(authed(post("/api/approval/task/" + firstTask + "/approve"), leader, organizationId, APPROVE)
|
||||
.contentType(MediaType.APPLICATION_JSON).content("{}"))
|
||||
.andExpect(jsonPath("$.code").value(0));
|
||||
|
||||
assertThat(data.queryMaster("SELECT status FROM approval_task WHERE id = ?", String.class, secondTask))
|
||||
.isEqualTo("CANCELLED");
|
||||
|
||||
mockMvc.perform(authed(get("/api/approval/todo/page"), second, organizationId, LIST))
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data.count").value(0));
|
||||
|
||||
mockMvc.perform(authed(post("/api/approval/task/" + secondTask + "/approve"), second, organizationId, APPROVE)
|
||||
.contentType(MediaType.APPLICATION_JSON).content("{}"))
|
||||
.andExpect(jsonPath("$.code").value(1))
|
||||
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("任务已处理")));
|
||||
|
||||
assertThat(data.countMaster("SELECT COUNT(*) FROM approval_record WHERE instance_id = ? AND action = 'APPROVE'",
|
||||
instanceId)).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void concurrentApprovalOnlyHandlesTaskOnce() throws Exception {
|
||||
long instanceId = createAndSubmit("并发处理");
|
||||
long taskId = pendingTaskId(instanceId, leader.userId);
|
||||
|
||||
CountDownLatch start = new CountDownLatch(1);
|
||||
CountDownLatch done = new CountDownLatch(2);
|
||||
ExecutorService executor = Executors.newFixedThreadPool(2);
|
||||
AtomicInteger success = new AtomicInteger();
|
||||
AtomicInteger conflict = new AtomicInteger();
|
||||
try {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
executor.submit(() -> {
|
||||
try {
|
||||
start.await();
|
||||
int code = mockMvc.perform(authed(post("/api/approval/task/" + taskId + "/approve"),
|
||||
leader, organizationId, APPROVE)
|
||||
.contentType(MediaType.APPLICATION_JSON).content("{\"opinion\":\"并发\"}"))
|
||||
.andReturn().getResponse().getContentAsString(StandardCharsets.UTF_8)
|
||||
.contains("\"code\":0") ? 0 : 1;
|
||||
if (code == 0) {
|
||||
success.incrementAndGet();
|
||||
} else {
|
||||
conflict.incrementAndGet();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
conflict.incrementAndGet();
|
||||
} finally {
|
||||
done.countDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
start.countDown();
|
||||
assertThat(done.await(30, TimeUnit.SECONDS)).isTrue();
|
||||
} finally {
|
||||
executor.shutdownNow();
|
||||
}
|
||||
|
||||
assertThat(success.get()).isEqualTo(1);
|
||||
assertThat(conflict.get()).isEqualTo(1);
|
||||
assertThat(data.countMaster("SELECT COUNT(*) FROM approval_record WHERE instance_id = ? AND action = 'APPROVE'",
|
||||
instanceId)).isEqualTo(1);
|
||||
assertThat(data.countMaster("SELECT COUNT(*) FROM approval_task WHERE instance_id = ? AND status = 'DONE'",
|
||||
instanceId)).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void allowsReporterToApproveOwnTask() throws Exception {
|
||||
Integer leaderRoleId = data.server().queryForObject("SELECT role_id FROM sys_role WHERE role_code = ? AND tenant_id = ?",
|
||||
Integer.class, "dept_leader_" + organizationId, TENANT);
|
||||
data.bind(reporter.userId, leaderRoleId);
|
||||
|
||||
long instanceId = createAndSubmit("自审单据");
|
||||
long taskId = pendingTaskId(instanceId, reporter.userId);
|
||||
|
||||
mockMvc.perform(authed(post("/api/approval/task/" + taskId + "/approve"),
|
||||
reporter, organizationId, APPROVE))
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data.status").value("PENDING"))
|
||||
.andExpect(jsonPath("$.data.currentNodeName").value("存档"));
|
||||
|
||||
assertThat(data.countMaster("SELECT COUNT(*) FROM approval_record WHERE instance_id = ? "
|
||||
+ "AND action = 'APPROVE' AND operator_id = ?", instanceId, reporter.userId)).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withdrawsOnlyBeforeAnyTaskHandled() throws Exception {
|
||||
long withdrawn = createAndSubmit("撤回单据");
|
||||
String bizNo = data.queryMaster("SELECT biz_no FROM approval_instance WHERE id = ?", String.class, withdrawn);
|
||||
|
||||
mockMvc.perform(authed(post("/api/approval/instance/" + withdrawn + "/withdraw"),
|
||||
reporter, organizationId, SUBMIT))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data.status").value("WITHDRAWN"))
|
||||
.andExpect(jsonPath("$.data.round").value(2))
|
||||
.andExpect(jsonPath("$.data.bizNo").value(bizNo))
|
||||
.andExpect(jsonPath("$.data.permissions.canSubmit").value(true));
|
||||
|
||||
assertThat(data.countMaster("SELECT COUNT(*) FROM approval_task WHERE instance_id = ? AND status = 'PENDING'",
|
||||
withdrawn)).isZero();
|
||||
assertThat(data.countMaster("SELECT COUNT(*) FROM approval_record WHERE instance_id = ? AND action = 'WITHDRAW'",
|
||||
withdrawn)).isEqualTo(1);
|
||||
|
||||
// 已有处理记录的实例不能撤回
|
||||
long handled = createAndSubmit("已审批撤回");
|
||||
long taskId = pendingTaskId(handled, leader.userId);
|
||||
mockMvc.perform(authed(post("/api/approval/task/" + taskId + "/approve"), leader, organizationId, APPROVE))
|
||||
.andExpect(jsonPath("$.code").value(0));
|
||||
mockMvc.perform(authed(post("/api/approval/instance/" + handled + "/withdraw"),
|
||||
reporter, organizationId, SUBMIT))
|
||||
.andExpect(jsonPath("$.code").value(1))
|
||||
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("已有审批人处理,无法撤回")));
|
||||
assertThat(data.queryMaster("SELECT status FROM approval_instance WHERE id = ?", String.class, handled))
|
||||
.isEqualTo("PENDING");
|
||||
|
||||
// 非报送人不能撤回
|
||||
long other = createAndSubmit("他人撤回");
|
||||
mockMvc.perform(authed(post("/api/approval/instance/" + other + "/withdraw"),
|
||||
leader, organizationId, SUBMIT))
|
||||
.andExpect(jsonPath("$.code").value(1))
|
||||
.andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("无权操作该单据")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void listsTodoDoneAndTodoCountWithFilters() throws Exception {
|
||||
long first = createAndSubmit("场馆维修A");
|
||||
long second = createAndSubmit("场馆维修B");
|
||||
|
||||
mockMvc.perform(authed(get("/api/approval/todo/count"), leader, organizationId, LIST))
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").value(2));
|
||||
|
||||
mockMvc.perform(authed(get("/api/approval/todo/page"), leader, organizationId, LIST))
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data.count").value(2))
|
||||
.andExpect(jsonPath("$.data.list[0].id").value((int) second))
|
||||
.andExpect(jsonPath("$.data.list[0].bizNo").isNotEmpty())
|
||||
.andExpect(jsonPath("$.data.list[0].status").value("PENDING"))
|
||||
.andExpect(jsonPath("$.data.list[0].currentNodeName").value("报送部门负责人"))
|
||||
.andExpect(jsonPath("$.data.list[0].submitTime").isNotEmpty());
|
||||
|
||||
mockMvc.perform(authed(get("/api/approval/todo/page").param("keywords", "B"), leader, organizationId, LIST))
|
||||
.andExpect(jsonPath("$.data.count").value(1))
|
||||
.andExpect(jsonPath("$.data.list[0].id").value((int) second));
|
||||
mockMvc.perform(authed(get("/api/approval/todo/page").param("status", "REJECTED"), leader, organizationId, LIST))
|
||||
.andExpect(jsonPath("$.data.count").value(0));
|
||||
|
||||
mockMvc.perform(authed(get("/api/approval/mine/page").param("keywords", "A"), reporter, organizationId, LIST))
|
||||
.andExpect(jsonPath("$.data.count").value(1))
|
||||
.andExpect(jsonPath("$.data.list[0].id").value((int) first));
|
||||
|
||||
long taskId = pendingTaskId(first, leader.userId);
|
||||
mockMvc.perform(authed(post("/api/approval/task/" + taskId + "/approve"), leader, organizationId, APPROVE))
|
||||
.andExpect(jsonPath("$.code").value(0));
|
||||
|
||||
mockMvc.perform(authed(get("/api/approval/todo/count"), leader, organizationId, LIST))
|
||||
.andExpect(jsonPath("$.data").value(1));
|
||||
mockMvc.perform(authed(get("/api/approval/done/page"), leader, organizationId, LIST))
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data.count").value(1))
|
||||
.andExpect(jsonPath("$.data.list[0].id").value((int) first))
|
||||
.andExpect(jsonPath("$.data.list[0].status").value("PENDING"))
|
||||
.andExpect(jsonPath("$.data.list[0].currentNodeName").value("存档"));
|
||||
mockMvc.perform(authed(get("/api/approval/done/page").param("keywords", "B"), leader, organizationId, LIST))
|
||||
.andExpect(jsonPath("$.data.count").value(0));
|
||||
|
||||
ApprovalTestData.TestUser outsider = data.createUser("任务路人" + data.uniqueSuffix(), organizationId);
|
||||
mockMvc.perform(authed(get("/api/approval/todo/page"), outsider, organizationId, LIST))
|
||||
.andExpect(jsonPath("$.data.count").value(0));
|
||||
mockMvc.perform(authed(get("/api/approval/done/page"), outsider, organizationId, LIST))
|
||||
.andExpect(jsonPath("$.data.count").value(0));
|
||||
}
|
||||
|
||||
// ---------- helpers ----------
|
||||
|
||||
private long createAndSubmit(String name) throws Exception {
|
||||
String body = "{\"name\":" + quote(name)
|
||||
+ ",\"implementOrg\":\"广西体育中心实施部\",\"fee\":123.45,"
|
||||
+ "\"serviceContent\":\"完成场馆设施维修与验收\"}";
|
||||
String response = mockMvc.perform(authed(post("/api/approval/instance/completion"),
|
||||
reporter, organizationId, SUBMIT)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(body))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andReturn().getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
long instanceId = objectMapper.readTree(response).path("data").asLong();
|
||||
data.trackInstance(instanceId);
|
||||
|
||||
uploadAttachment(instanceId);
|
||||
mockMvc.perform(authed(post("/api/approval/instance/" + instanceId + "/submit"),
|
||||
reporter, organizationId, SUBMIT))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0));
|
||||
return instanceId;
|
||||
}
|
||||
|
||||
private void uploadAttachment(long instanceId) throws Exception {
|
||||
MockMultipartFile file = new MockMultipartFile("file", "sign.png", "image/png",
|
||||
new byte[]{(byte) 0x89, 'P', 'N', 'G', 0x0D, 0x0A, 0x1A, 0x0A});
|
||||
mockMvc.perform(multipart("/api/approval/attachment/upload")
|
||||
.file(file)
|
||||
.param("instanceId", String.valueOf(instanceId))
|
||||
.param("category", "SIGNED")
|
||||
.header("tenantId", TENANT)
|
||||
.with(authentication(TestAuthentication.user(reporter.userId, reporter.username,
|
||||
organizationId, TENANT, SUBMIT))))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0));
|
||||
}
|
||||
|
||||
private long pendingTaskId(long instanceId, int userId) {
|
||||
Long taskId = data.queryMaster("SELECT id FROM approval_task WHERE instance_id = ? "
|
||||
+ "AND assignee_id = ? AND status = 'PENDING' LIMIT 1", Long.class, instanceId, userId);
|
||||
assertThat(taskId).as("待办任务应存在").isNotNull();
|
||||
return taskId;
|
||||
}
|
||||
|
||||
private MockHttpServletRequestBuilder authed(MockHttpServletRequestBuilder builder,
|
||||
ApprovalTestData.TestUser user, Integer org,
|
||||
String... authorities) {
|
||||
return builder.header("tenantId", TENANT)
|
||||
.with(authentication(TestAuthentication.user(user.userId, user.username, org, TENANT, authorities)));
|
||||
}
|
||||
|
||||
private String quote(String value) {
|
||||
return "\"" + value.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user