Files
label_backend/src/test/java/com/label/integration/UserManagementIntegrationTest.java

178 lines
7.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.label.integration;
import com.label.AbstractIntegrationTest;
import com.label.dto.LoginRequest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.*;
import java.util.Map;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
/**
* 用户管理集成测试US7
*
* 测试场景:
* 1. 变更角色后权限下一次请求立即生效(无需重新登录)
* 2. 禁用账号后现有 Token 下一次请求立即返回 401
*/
public class UserManagementIntegrationTest extends AbstractIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
private String adminToken;
@BeforeEach
void setup() {
adminToken = loginAndGetToken("DEMO", "admin", "admin123");
assertThat(adminToken).isNotBlank();
}
// ------------------------------------------------------------------ 测试 1: 角色变更立即生效 --
@Test
@DisplayName("创建用户为 ANNOTATOR变更为 REVIEWER 后同一 Token 立即可访问审批接口")
void updateRole_takesEffectImmediately() {
String uniqueUsername = "testuser-" + UUID.randomUUID().toString().substring(0, 8);
// 1. 创建 ANNOTATOR 用户
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + adminToken);
headers.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<Map> createResp = restTemplate.exchange(
baseUrl("/api/users"),
HttpMethod.POST,
new HttpEntity<>(Map.of(
"username", uniqueUsername,
"password", "test1234",
"realName", "测试用户",
"role", "ANNOTATOR"
), headers),
Map.class);
assertThat(createResp.getStatusCode()).isEqualTo(HttpStatus.OK);
@SuppressWarnings("unchecked")
Map<String, Object> userData = (Map<String, Object>) createResp.getBody().get("data");
Long newUserId = ((Number) userData.get("id")).longValue();
// 2. 新用户登录获取 Token
String userToken = loginAndGetToken("DEMO", uniqueUsername, "test1234");
assertThat(userToken).isNotBlank();
// 3. 验证ANNOTATOR 无法访问待审批队列REVIEWER 专属)→ 403
ResponseEntity<Map> beforeRoleChange = restTemplate.exchange(
baseUrl("/api/tasks/pending-review"),
HttpMethod.GET,
bearerRequest(userToken),
Map.class);
assertThat(beforeRoleChange.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
// 4. ADMIN 变更角色为 REVIEWER
ResponseEntity<Map> roleResp = restTemplate.exchange(
baseUrl("/api/users/" + newUserId + "/role"),
HttpMethod.PUT,
new HttpEntity<>(Map.of("role", "REVIEWER"), headers),
Map.class);
assertThat(roleResp.getStatusCode()).isEqualTo(HttpStatus.OK);
// 5. 验证:同一 Token 下次请求立即具有 REVIEWER 权限 → 200
ResponseEntity<Map> afterRoleChange = restTemplate.exchange(
baseUrl("/api/tasks/pending-review"),
HttpMethod.GET,
bearerRequest(userToken),
Map.class);
assertThat(afterRoleChange.getStatusCode())
.as("角色变更后同一 Token 应立即具有 REVIEWER 权限")
.isEqualTo(HttpStatus.OK);
}
// ------------------------------------------------------------------ 测试 2: 禁用账号 Token 立即失效 --
@Test
@DisplayName("禁用账号后,现有 Token 下一次请求立即返回 401")
void disableAccount_tokenInvalidatedImmediately() {
String uniqueUsername = "testuser-" + UUID.randomUUID().toString().substring(0, 8);
// 1. 创建用户
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + adminToken);
headers.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<Map> createResp = restTemplate.exchange(
baseUrl("/api/users"),
HttpMethod.POST,
new HttpEntity<>(Map.of(
"username", uniqueUsername,
"password", "test1234",
"realName", "测试用户",
"role", "ANNOTATOR"
), headers),
Map.class);
assertThat(createResp.getStatusCode()).isEqualTo(HttpStatus.OK);
@SuppressWarnings("unchecked")
Map<String, Object> userData = (Map<String, Object>) createResp.getBody().get("data");
Long newUserId = ((Number) userData.get("id")).longValue();
// 2. 新用户登录,获取 Token
String userToken = loginAndGetToken("DEMO", uniqueUsername, "test1234");
assertThat(userToken).isNotBlank();
// 3. 验证 Token 有效
ResponseEntity<Map> meResp = restTemplate.exchange(
baseUrl("/api/auth/me"),
HttpMethod.GET,
bearerRequest(userToken),
Map.class);
assertThat(meResp.getStatusCode()).isEqualTo(HttpStatus.OK);
// 4. ADMIN 禁用账号
ResponseEntity<Map> disableResp = restTemplate.exchange(
baseUrl("/api/users/" + newUserId + "/status"),
HttpMethod.PUT,
new HttpEntity<>(Map.of("status", "DISABLED"), headers),
Map.class);
assertThat(disableResp.getStatusCode()).isEqualTo(HttpStatus.OK);
// 5. 验证:禁用后,现有 Token 立即失效 → 401
ResponseEntity<Map> meAfterDisable = restTemplate.exchange(
baseUrl("/api/auth/me"),
HttpMethod.GET,
bearerRequest(userToken),
Map.class);
assertThat(meAfterDisable.getStatusCode())
.as("禁用账号后现有 Token 应立即失效")
.isEqualTo(HttpStatus.UNAUTHORIZED);
}
// ------------------------------------------------------------------ 工具方法 --
private String loginAndGetToken(String companyCode, String username, String password) {
LoginRequest req = new LoginRequest();
req.setCompanyCode(companyCode);
req.setUsername(username);
req.setPassword(password);
ResponseEntity<Map> response = restTemplate.postForEntity(
baseUrl("/api/auth/login"), req, Map.class);
if (!response.getStatusCode().is2xxSuccessful()) {
return null;
}
@SuppressWarnings("unchecked")
Map<String, Object> data = (Map<String, Object>) response.getBody().get("data");
return (String) data.get("token");
}
private HttpEntity<Void> bearerRequest(String token) {
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + token);
return new HttpEntity<>(headers);
}
}