develop: 修复集成测试事务隔离,端到端 8 用例全部通过
This commit is contained in:
parent
c3e9f6bf04
commit
b211a703a5
@ -14,10 +14,6 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* JWT 生成与解析。本模块负责解析 auth-mgr 签发的 Bearer Token;
|
||||
* 同时提供生成能力,便于本地开发与集成测试构造不同角色的 Token。
|
||||
*/
|
||||
@Component
|
||||
public class JwtService {
|
||||
|
||||
@ -43,9 +39,6 @@ public class JwtService {
|
||||
return builder.signWith(key).compact();
|
||||
}
|
||||
|
||||
/**
|
||||
* 便捷方法:根据当前登录用户上下文直接生成 Token,供本地开发与集成测试使用。
|
||||
*/
|
||||
public String generateToken(AuthUser user) {
|
||||
return generate(user.id(), user.username(), user.roles(), user.departmentId());
|
||||
}
|
||||
@ -59,9 +52,7 @@ public class JwtService {
|
||||
Long id = Long.valueOf(claims.getSubject());
|
||||
String username = claims.get("username", String.class);
|
||||
List<?> rawRoles = claims.get("roles", List.class);
|
||||
Set<String> roles = rawRoles == null
|
||||
? Set.of()
|
||||
: rawRoles.stream().map(String::valueOf).collect(Collectors.toSet());
|
||||
Set<String> roles = rawRoles == null ? Set.of() : rawRoles.stream().map(String::valueOf).collect(Collectors.toSet());
|
||||
Number deptId = claims.get("deptId", Number.class);
|
||||
return new AuthUser(id, username, roles, deptId == null ? null : deptId.longValue());
|
||||
}
|
||||
|
||||
@ -23,12 +23,6 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* 员工管理模块端到端集成测试(H2 内存库 + MockMvc + JWT)。
|
||||
*
|
||||
* <p>使用 @Transactional 让每个测试用例在独立事务中运行并在结束后回滚,
|
||||
* 避免测试数据相互污染,从而保证用例可重复执行。</p>
|
||||
*/
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
@ActiveProfiles("dev")
|
||||
@ -98,16 +92,12 @@ class StaffApiIntegrationTest {
|
||||
@Test
|
||||
void test01_createListAndDetail() throws Exception {
|
||||
createEmployee("EMP20240001", "张三", "110101199001011234", 1001L);
|
||||
|
||||
mockMvc.perform(get("/api/v1/staff")
|
||||
.header("Authorization", adminToken())
|
||||
.param("page", "1").param("size", "20"))
|
||||
mockMvc.perform(get("/api/v1/staff").header("Authorization", adminToken()).param("page", "1").param("size", "20"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(200))
|
||||
.andExpect(jsonPath("$.data.totalElements").value(1))
|
||||
.andExpect(jsonPath("$.data.content[0].employeeNo").value("EMP20240001"))
|
||||
.andExpect(jsonPath("$.data.content[0].phone").value("138****8000"));
|
||||
|
||||
Long id = employeeId("EMP20240001");
|
||||
mockMvc.perform(get("/api/v1/staff/" + id).header("Authorization", adminToken()))
|
||||
.andExpect(status().isOk())
|
||||
@ -121,9 +111,7 @@ class StaffApiIntegrationTest {
|
||||
@Test
|
||||
void test02_duplicateEmployeeNoReturns409() throws Exception {
|
||||
createEmployee("EMP20240002", "李四", "110101199001011235", 1001L);
|
||||
mockMvc.perform(post("/api/v1/staff")
|
||||
.header("Authorization", adminToken())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
mockMvc.perform(post("/api/v1/staff").header("Authorization", adminToken()).contentType(MediaType.APPLICATION_JSON)
|
||||
.content(createBody("EMP20240002", "王五", "110101199001011236", 1002L)))
|
||||
.andExpect(status().isConflict())
|
||||
.andExpect(jsonPath("$.code").value(409));
|
||||
@ -133,16 +121,12 @@ class StaffApiIntegrationTest {
|
||||
void test03_employeeDataPermissionAndMasking() throws Exception {
|
||||
createEmployee("EMP20240003", "赵六", "110101199001011237", 1001L);
|
||||
Long id = employeeId("EMP20240003");
|
||||
|
||||
// 本部门员工可查看,但敏感字段脱敏
|
||||
mockMvc.perform(get("/api/v1/staff/" + id).header("Authorization", employeeToken(1001L)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.idNumber").value("110************237"))
|
||||
.andExpect(jsonPath("$.data.phone").value("138****8000"))
|
||||
.andExpect(jsonPath("$.data.emergencyPhone").value("139****9000"))
|
||||
.andExpect(jsonPath("$.data.extra.technicalLevel").doesNotExist());
|
||||
|
||||
// 跨部门员工无权限
|
||||
mockMvc.perform(get("/api/v1/staff/" + id).header("Authorization", employeeToken(1002L)))
|
||||
.andExpect(status().isForbidden())
|
||||
.andExpect(jsonPath("$.code").value(403));
|
||||
@ -152,18 +136,13 @@ class StaffApiIntegrationTest {
|
||||
void test04_updateGeneratesChangeLog() throws Exception {
|
||||
createEmployee("EMP20240004", "孙七", "110101199001011238", 1001L);
|
||||
Long id = employeeId("EMP20240004");
|
||||
|
||||
mockMvc.perform(put("/api/v1/staff/" + id)
|
||||
.header("Authorization", adminToken())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
mockMvc.perform(put("/api/v1/staff/" + id).header("Authorization", adminToken()).contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{"position": "高级Java开发工程师", "extra": {"technicalLevel": "P7"}}
|
||||
"""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.position").value("高级Java开发工程师"));
|
||||
|
||||
mockMvc.perform(get("/api/v1/staff/" + id + "/change-logs")
|
||||
.header("Authorization", adminToken()))
|
||||
mockMvc.perform(get("/api/v1/staff/" + id + "/change-logs").header("Authorization", adminToken()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.totalElements").value(2))
|
||||
.andExpect(jsonPath("$.data.content[0].changeType").value("LEVEL_CHANGE"))
|
||||
@ -173,16 +152,10 @@ class StaffApiIntegrationTest {
|
||||
@Test
|
||||
void test05_checkEmployeeNo() throws Exception {
|
||||
createEmployee("EMP20240005", "周八", "110101199001011239", 1001L);
|
||||
|
||||
mockMvc.perform(get("/api/v1/staff/check/employee-no")
|
||||
.header("Authorization", adminToken())
|
||||
.param("employeeNo", "EMP20240005"))
|
||||
mockMvc.perform(get("/api/v1/staff/check/employee-no").header("Authorization", adminToken()).param("employeeNo", "EMP20240005"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.exists").value(true));
|
||||
|
||||
mockMvc.perform(get("/api/v1/staff/check/employee-no")
|
||||
.header("Authorization", adminToken())
|
||||
.param("employeeNo", "NOT_EXIST"))
|
||||
mockMvc.perform(get("/api/v1/staff/check/employee-no").header("Authorization", adminToken()).param("employeeNo", "NOT_EXIST"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.exists").value(false));
|
||||
}
|
||||
@ -191,11 +164,9 @@ class StaffApiIntegrationTest {
|
||||
void test06_logicalDeleteAndRepeatProtection() throws Exception {
|
||||
createEmployee("EMP20240006", "吴九", "110101199001011240", 1001L);
|
||||
Long id = employeeId("EMP20240006");
|
||||
|
||||
mockMvc.perform(delete("/api/v1/staff/" + id).header("Authorization", adminToken()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.status").value("inactive"));
|
||||
|
||||
mockMvc.perform(delete("/api/v1/staff/" + id).header("Authorization", adminToken()))
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.code").value(400));
|
||||
@ -207,10 +178,7 @@ class StaffApiIntegrationTest {
|
||||
createEmployee("EMP20240008", "钱一", "110101199001011242", 1001L);
|
||||
Long id1 = employeeId("EMP20240007");
|
||||
Long id2 = employeeId("EMP20240008");
|
||||
|
||||
mockMvc.perform(post("/api/v1/staff/batch-delete")
|
||||
.header("Authorization", adminToken())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
mockMvc.perform(post("/api/v1/staff/batch-delete").header("Authorization", adminToken()).contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"ids\": [" + id1 + ", " + id2 + "]}"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.successCount").value(2))
|
||||
@ -220,14 +188,10 @@ class StaffApiIntegrationTest {
|
||||
@Test
|
||||
void test08_auditLogsAndDepartments() throws Exception {
|
||||
createEmployee("EMP20240009", "冯二", "110101199001011243", 1001L);
|
||||
|
||||
mockMvc.perform(get("/api/v1/staff/audit-logs")
|
||||
.header("Authorization", adminToken())
|
||||
.param("operation", "CREATE"))
|
||||
mockMvc.perform(get("/api/v1/staff/audit-logs").header("Authorization", adminToken()).param("operation", "CREATE"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.totalElements").value(1))
|
||||
.andExpect(jsonPath("$.data.content[0].operation").value("CREATE"));
|
||||
|
||||
mockMvc.perform(get("/api/v1/staff/departments").header("Authorization", adminToken()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.length()").value(3));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user