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

175 lines
7.4 KiB
Java
Raw Normal View History

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;
/**
* 鐢ㄦ埛绠悊闆嗘垚娴嬭瘯锛圲S7锛夈? *
* 娴嬭瘯鍦烘櫙锛? * 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. 楠岃瘉锛欰NNOTATOR 鏃犳硶璁块棶寰呭鎵归槦鍒楋紙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);
}
}