统一接口前缀
This commit is contained in:
@@ -2,7 +2,7 @@ FROM registry.bjzgzp.com:4433/library/eclipse-temurin:21-jdk-ubi10-minimal
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ./target/label-backend-1.0.0-SNAPSHOT.jar /app/label-backend-1.0.0-SNAPSHOT.jar
|
||||
COPY ./label-backend-1.0.0-SNAPSHOT.jar /app/label-backend-1.0.0-SNAPSHOT.jar
|
||||
|
||||
EXPOSE 18082
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
*/
|
||||
@Tag(name = "认证管理", description = "登录、退出和当前用户信息")
|
||||
@RestController
|
||||
@RequestMapping("/api/auth")
|
||||
@RequestMapping("/label/api/auth")
|
||||
@RequiredArgsConstructor
|
||||
public class AuthController {
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.Map;
|
||||
|
||||
@Tag(name = "公司管理", description = "租户公司增删改查")
|
||||
@RestController
|
||||
@RequestMapping("/api/companies")
|
||||
@RequestMapping("/label/api/companies")
|
||||
@RequiredArgsConstructor
|
||||
public class CompanyController {
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Map;
|
||||
*/
|
||||
@Tag(name = "导出管理", description = "训练样本查询、导出批次和微调任务")
|
||||
@RestController
|
||||
@RequestMapping("/label")
|
||||
@RequiredArgsConstructor
|
||||
public class ExportController {
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import java.util.Map;
|
||||
*/
|
||||
@Tag(name = "提取标注", description = "提取阶段的查看、编辑、提交和审批")
|
||||
@RestController
|
||||
@RequestMapping("/api/extraction")
|
||||
@RequestMapping("/label/api/extraction")
|
||||
@RequiredArgsConstructor
|
||||
public class ExtractionController {
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import java.util.Map;
|
||||
*/
|
||||
@Tag(name = "问答生成", description = "问答生成阶段的查看、编辑、提交和审批")
|
||||
@RestController
|
||||
@RequestMapping("/api/qa")
|
||||
@RequestMapping("/label/api/qa")
|
||||
@RequiredArgsConstructor
|
||||
public class QaController {
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
*/
|
||||
@Tag(name = "资料管理", description = "原始资料上传、查询和删除")
|
||||
@RestController
|
||||
@RequestMapping("/api/source")
|
||||
@RequestMapping("/label/api/source")
|
||||
@RequiredArgsConstructor
|
||||
public class SourceController {
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.Map;
|
||||
*/
|
||||
@Tag(name = "系统配置", description = "全局和公司级系统配置管理")
|
||||
@RestController
|
||||
@RequestMapping("/label")
|
||||
@RequiredArgsConstructor
|
||||
public class SysConfigController {
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.Map;
|
||||
*/
|
||||
@Tag(name = "任务管理", description = "任务池、我的任务、审批队列和管理操作")
|
||||
@RestController
|
||||
@RequestMapping("/api/tasks")
|
||||
@RequestMapping("/label/api/tasks")
|
||||
@RequiredArgsConstructor
|
||||
public class TaskController {
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import lombok.RequiredArgsConstructor;
|
||||
*/
|
||||
@Tag(name = "用户管理", description = "管理员维护公司用户")
|
||||
@RestController
|
||||
@RequestMapping("/api/users")
|
||||
@RequestMapping("/label/api/users")
|
||||
@RequiredArgsConstructor
|
||||
public class UserController {
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.Map;
|
||||
@Tag(name = "视频处理", description = "视频处理任务创建、查询、重置和回调")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/label")
|
||||
@RequiredArgsConstructor
|
||||
public class VideoController {
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@RequiredArgsConstructor
|
||||
public class AuthInterceptor implements HandlerInterceptor {
|
||||
|
||||
private static final String API_PREFIX = "/label";
|
||||
private static final String API_ROOT = API_PREFIX + "/api/";
|
||||
|
||||
private final RedisService redisService;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@@ -155,9 +158,9 @@ public class AuthInterceptor implements HandlerInterceptor {
|
||||
}
|
||||
|
||||
private boolean isPublicPath(String path) {
|
||||
return !path.startsWith("/api/")
|
||||
|| path.equals("/api/auth/login")
|
||||
|| path.equals("/api/video/callback")
|
||||
return !path.startsWith(API_ROOT)
|
||||
|| path.equals(API_PREFIX + "/api/auth/login")
|
||||
|| path.equals(API_PREFIX + "/api/video/callback")
|
||||
|| path.startsWith("/swagger-ui")
|
||||
|| path.startsWith("/v3/api-docs");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
server:
|
||||
port: 8080
|
||||
port: 18082
|
||||
|
||||
spring:
|
||||
|
||||
@@ -147,7 +147,7 @@ abstract class AbstractBlackBoxTest {
|
||||
if (callbackSecret != null && !callbackSecret.isBlank()) {
|
||||
headers.set("X-Callback-Secret", callbackSecret);
|
||||
}
|
||||
return restTemplate.exchange(url("/api/video/callback"), HttpMethod.POST, new HttpEntity<>(body, headers), Map.class);
|
||||
return restTemplate.exchange(url("/label/api/video/callback"), HttpMethod.POST, new HttpEntity<>(body, headers), Map.class);
|
||||
}
|
||||
|
||||
protected String login(String targetCompanyCode, String username, String password) {
|
||||
@@ -156,7 +156,7 @@ abstract class AbstractBlackBoxTest {
|
||||
"username", username,
|
||||
"password", password
|
||||
);
|
||||
ResponseEntity<Map> response = postJson("/api/auth/login", body, null);
|
||||
ResponseEntity<Map> response = postJson("/label/api/auth/login", body, null);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> data = (Map<String, Object>) Objects.requireNonNull(response.getBody()).get("data");
|
||||
@@ -165,7 +165,7 @@ abstract class AbstractBlackBoxTest {
|
||||
|
||||
protected Long uploadTextSource(String token) {
|
||||
ResponseEntity<Map> response = upload(
|
||||
"/api/source/upload",
|
||||
"/label/api/source/upload",
|
||||
token,
|
||||
"bb-" + runId + ".txt",
|
||||
"TEXT",
|
||||
@@ -176,7 +176,7 @@ abstract class AbstractBlackBoxTest {
|
||||
|
||||
protected Long uploadVideoSource(String token) {
|
||||
ResponseEntity<Map> response = upload(
|
||||
"/api/source/upload",
|
||||
"/label/api/source/upload",
|
||||
token,
|
||||
"bb-" + runId + ".mp4",
|
||||
"VIDEO",
|
||||
@@ -186,7 +186,7 @@ abstract class AbstractBlackBoxTest {
|
||||
}
|
||||
|
||||
protected Long createTask(Long sourceId, String taskType) {
|
||||
ResponseEntity<Map> response = postJson("/api/tasks", Map.of(
|
||||
ResponseEntity<Map> response = postJson("/label/api/tasks", Map.of(
|
||||
"sourceId", sourceId,
|
||||
"taskType", taskType
|
||||
), adminToken);
|
||||
@@ -330,8 +330,8 @@ abstract class AbstractBlackBoxTest {
|
||||
|
||||
private void detectRuntimeAuthMode() {
|
||||
try {
|
||||
ResponseEntity<Map> adminMe = get("/api/auth/me", adminToken);
|
||||
ResponseEntity<Map> reviewerMe = get("/api/auth/me", reviewerToken);
|
||||
ResponseEntity<Map> adminMe = get("/label/api/auth/me", adminToken);
|
||||
ResponseEntity<Map> reviewerMe = get("/label/api/auth/me", reviewerToken);
|
||||
if (!adminMe.getStatusCode().is2xxSuccessful() || !reviewerMe.getStatusCode().is2xxSuccessful()) {
|
||||
this.roleAwareAuthEnabled = false;
|
||||
return;
|
||||
|
||||
@@ -19,12 +19,12 @@ class SwaggerLiveBlackBoxTest extends AbstractBlackBoxTest {
|
||||
void publicAndAuthEndpoints_shouldWork() {
|
||||
ResponseEntity<String> openApi = getRaw("/v3/api-docs");
|
||||
assertThat(openApi.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(openApi.getBody()).contains("/api/auth/login");
|
||||
assertThat(openApi.getBody()).contains("/label/api/auth/login");
|
||||
|
||||
ResponseEntity<String> swaggerUi = getRaw("/swagger-ui.html");
|
||||
assertThat(swaggerUi.getStatusCode().is2xxSuccessful() || swaggerUi.getStatusCode().is3xxRedirection()).isTrue();
|
||||
|
||||
ResponseEntity<Map> login = postJson("/api/auth/login", Map.of(
|
||||
ResponseEntity<Map> login = postJson("/label/api/auth/login", Map.of(
|
||||
"companyCode", companyCode,
|
||||
"username", adminUser.username(),
|
||||
"password", adminUser.password()
|
||||
@@ -35,17 +35,17 @@ class SwaggerLiveBlackBoxTest extends AbstractBlackBoxTest {
|
||||
return;
|
||||
}
|
||||
|
||||
ResponseEntity<Map> me = get("/api/auth/me", adminToken);
|
||||
ResponseEntity<Map> me = get("/label/api/auth/me", adminToken);
|
||||
assertSuccess(me, HttpStatus.OK);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> meData = (Map<String, Object>) me.getBody().get("data");
|
||||
assertThat(meData.get("username")).isEqualTo(adminUser.username());
|
||||
assertThat(meData.get("role")).isEqualTo("ADMIN");
|
||||
|
||||
ResponseEntity<Map> logout = postJson("/api/auth/logout", null, adminToken);
|
||||
ResponseEntity<Map> logout = postJson("/label/api/auth/logout", null, adminToken);
|
||||
assertSuccess(logout, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> meAfterLogout = get("/api/auth/me", adminToken);
|
||||
ResponseEntity<Map> meAfterLogout = get("/label/api/auth/me", adminToken);
|
||||
assertThat(meAfterLogout.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@@ -54,37 +54,37 @@ class SwaggerLiveBlackBoxTest extends AbstractBlackBoxTest {
|
||||
void companyAndUserEndpoints_shouldWork() {
|
||||
requireRoleAwareAuth();
|
||||
|
||||
ResponseEntity<Map> companyList = get("/api/companies?page=1&pageSize=20", adminToken);
|
||||
ResponseEntity<Map> companyList = get("/label/api/companies?page=1&pageSize=20", adminToken);
|
||||
assertSuccess(companyList, HttpStatus.OK);
|
||||
|
||||
String extraCompanyCode = ("EXT" + runId).toUpperCase();
|
||||
String extraCompanyName = "扩展公司-" + runId;
|
||||
ResponseEntity<Map> createCompany = postJson("/api/companies", Map.of(
|
||||
ResponseEntity<Map> createCompany = postJson("/label/api/companies", Map.of(
|
||||
"companyName", extraCompanyName,
|
||||
"companyCode", extraCompanyCode
|
||||
), adminToken);
|
||||
assertSuccess(createCompany, HttpStatus.CREATED);
|
||||
Long extraCompanyId = dataId(createCompany);
|
||||
|
||||
ResponseEntity<Map> updateCompany = putJson("/api/companies/" + extraCompanyId, Map.of(
|
||||
ResponseEntity<Map> updateCompany = putJson("/label/api/companies/" + extraCompanyId, Map.of(
|
||||
"companyName", extraCompanyName + "-改",
|
||||
"companyCode", extraCompanyCode
|
||||
), adminToken);
|
||||
assertSuccess(updateCompany, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> companyStatus = putJson("/api/companies/" + extraCompanyId + "/status",
|
||||
ResponseEntity<Map> companyStatus = putJson("/label/api/companies/" + extraCompanyId + "/status",
|
||||
Map.of("status", "DISABLED"), adminToken);
|
||||
assertSuccess(companyStatus, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> deleteCompany = delete("/api/companies/" + extraCompanyId, adminToken);
|
||||
ResponseEntity<Map> deleteCompany = delete("/label/api/companies/" + extraCompanyId, adminToken);
|
||||
assertSuccess(deleteCompany, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> userList = get("/api/users?page=1&pageSize=20", adminToken);
|
||||
ResponseEntity<Map> userList = get("/label/api/users?page=1&pageSize=20", adminToken);
|
||||
assertSuccess(userList, HttpStatus.OK);
|
||||
|
||||
String username = "bb_user_" + UUID.randomUUID().toString().substring(0, 8);
|
||||
String password = "BbUser@123";
|
||||
ResponseEntity<Map> createUser = postJson("/api/users", Map.of(
|
||||
ResponseEntity<Map> createUser = postJson("/label/api/users", Map.of(
|
||||
"username", username,
|
||||
"password", password,
|
||||
"realName", "黑盒用户",
|
||||
@@ -93,7 +93,7 @@ class SwaggerLiveBlackBoxTest extends AbstractBlackBoxTest {
|
||||
assertSuccess(createUser, HttpStatus.OK);
|
||||
Long userId = dataId(createUser);
|
||||
|
||||
ResponseEntity<Map> updateUser = putJson("/api/users/" + userId, Map.of(
|
||||
ResponseEntity<Map> updateUser = putJson("/label/api/users/" + userId, Map.of(
|
||||
"realName", "黑盒用户-改",
|
||||
"password", "BbUser@456"
|
||||
), adminToken);
|
||||
@@ -101,21 +101,21 @@ class SwaggerLiveBlackBoxTest extends AbstractBlackBoxTest {
|
||||
|
||||
String userToken = login(companyCode, username, "BbUser@456");
|
||||
|
||||
ResponseEntity<Map> beforeRoleChange = get("/api/tasks/pending-review", userToken);
|
||||
ResponseEntity<Map> beforeRoleChange = get("/label/api/tasks/pending-review", userToken);
|
||||
assertThat(beforeRoleChange.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
|
||||
ResponseEntity<Map> updateRole = putJson("/api/users/" + userId + "/role",
|
||||
ResponseEntity<Map> updateRole = putJson("/label/api/users/" + userId + "/role",
|
||||
Map.of("role", "REVIEWER"), adminToken);
|
||||
assertSuccess(updateRole, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> afterRoleChange = get("/api/tasks/pending-review", userToken);
|
||||
ResponseEntity<Map> afterRoleChange = get("/label/api/tasks/pending-review", userToken);
|
||||
assertThat(afterRoleChange.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> updateStatus = putJson("/api/users/" + userId + "/status",
|
||||
ResponseEntity<Map> updateStatus = putJson("/label/api/users/" + userId + "/status",
|
||||
Map.of("status", "DISABLED"), adminToken);
|
||||
assertSuccess(updateStatus, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> meAfterDisable = get("/api/auth/me", userToken);
|
||||
ResponseEntity<Map> meAfterDisable = get("/label/api/auth/me", userToken);
|
||||
assertThat(meAfterDisable.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@@ -125,51 +125,51 @@ class SwaggerLiveBlackBoxTest extends AbstractBlackBoxTest {
|
||||
requireRoleAwareAuth();
|
||||
|
||||
Long disposableSourceId = uploadTextSource(uploaderToken);
|
||||
ResponseEntity<Map> deleteDisposable = delete("/api/source/" + disposableSourceId, adminToken);
|
||||
ResponseEntity<Map> deleteDisposable = delete("/label/api/source/" + disposableSourceId, adminToken);
|
||||
assertSuccess(deleteDisposable, HttpStatus.OK);
|
||||
|
||||
Long sourceId = uploadTextSource(uploaderToken);
|
||||
|
||||
ResponseEntity<Map> uploaderList = get("/api/source/list?page=1&pageSize=20", uploaderToken);
|
||||
ResponseEntity<Map> uploaderList = get("/label/api/source/list?page=1&pageSize=20", uploaderToken);
|
||||
assertSuccess(uploaderList, HttpStatus.OK);
|
||||
assertThat(responseContainsId(uploaderList, sourceId)).isTrue();
|
||||
|
||||
ResponseEntity<Map> adminList = get("/api/source/list?page=1&pageSize=20", adminToken);
|
||||
ResponseEntity<Map> adminList = get("/label/api/source/list?page=1&pageSize=20", adminToken);
|
||||
assertSuccess(adminList, HttpStatus.OK);
|
||||
assertThat(responseContainsId(adminList, sourceId)).isTrue();
|
||||
|
||||
ResponseEntity<Map> sourceDetail = get("/api/source/" + sourceId, adminToken);
|
||||
ResponseEntity<Map> sourceDetail = get("/label/api/source/" + sourceId, adminToken);
|
||||
assertSuccess(sourceDetail, HttpStatus.OK);
|
||||
|
||||
Long taskId = createTask(sourceId, "EXTRACTION");
|
||||
|
||||
ResponseEntity<Map> pool = get("/api/tasks/pool?page=1&pageSize=20", annotatorToken);
|
||||
ResponseEntity<Map> pool = get("/label/api/tasks/pool?page=1&pageSize=20", annotatorToken);
|
||||
assertSuccess(pool, HttpStatus.OK);
|
||||
assertThat(responseContainsId(pool, taskId)).isTrue();
|
||||
|
||||
ResponseEntity<Map> allTasks = get("/api/tasks?page=1&pageSize=20&taskType=EXTRACTION", adminToken);
|
||||
ResponseEntity<Map> allTasks = get("/label/api/tasks?page=1&pageSize=20&taskType=EXTRACTION", adminToken);
|
||||
assertSuccess(allTasks, HttpStatus.OK);
|
||||
assertThat(responseContainsId(allTasks, taskId)).isTrue();
|
||||
|
||||
ResponseEntity<Map> taskDetail = get("/api/tasks/" + taskId, annotatorToken);
|
||||
ResponseEntity<Map> taskDetail = get("/label/api/tasks/" + taskId, annotatorToken);
|
||||
assertSuccess(taskDetail, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> claim = postJson("/api/tasks/" + taskId + "/claim", null, annotatorToken);
|
||||
ResponseEntity<Map> claim = postJson("/label/api/tasks/" + taskId + "/claim", null, annotatorToken);
|
||||
assertSuccess(claim, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> mine = get("/api/tasks/mine?page=1&pageSize=20", annotatorToken);
|
||||
ResponseEntity<Map> mine = get("/label/api/tasks/mine?page=1&pageSize=20", annotatorToken);
|
||||
assertSuccess(mine, HttpStatus.OK);
|
||||
assertThat(responseContainsId(mine, taskId)).isTrue();
|
||||
|
||||
ResponseEntity<Map> unclaim = postJson("/api/tasks/" + taskId + "/unclaim", null, annotatorToken);
|
||||
ResponseEntity<Map> unclaim = postJson("/label/api/tasks/" + taskId + "/unclaim", null, annotatorToken);
|
||||
assertSuccess(unclaim, HttpStatus.OK);
|
||||
|
||||
Long sourceId2 = uploadTextSource(uploaderToken);
|
||||
Long taskId2 = createTask(sourceId2, "EXTRACTION");
|
||||
ResponseEntity<Map> claimTask2 = postJson("/api/tasks/" + taskId2 + "/claim", null, annotatorToken);
|
||||
ResponseEntity<Map> claimTask2 = postJson("/label/api/tasks/" + taskId2 + "/claim", null, annotatorToken);
|
||||
assertSuccess(claimTask2, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> reassign = putJson("/api/tasks/" + taskId2 + "/reassign",
|
||||
ResponseEntity<Map> reassign = putJson("/label/api/tasks/" + taskId2 + "/reassign",
|
||||
Map.of("userId", annotator2User.id()), adminToken);
|
||||
assertSuccess(reassign, HttpStatus.OK);
|
||||
assertThat(claimedByOfTask(taskId2)).isEqualTo(annotator2User.id());
|
||||
@@ -180,10 +180,10 @@ class SwaggerLiveBlackBoxTest extends AbstractBlackBoxTest {
|
||||
void extractionQaConfigAndExportEndpoints_shouldWork() {
|
||||
requireRoleAwareAuth();
|
||||
|
||||
ResponseEntity<Map> listConfig = get("/api/config", adminToken);
|
||||
ResponseEntity<Map> listConfig = get("/label/api/config", adminToken);
|
||||
assertSuccess(listConfig, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> updateConfig = putJson("/api/config/model_default",
|
||||
ResponseEntity<Map> updateConfig = putJson("/label/api/config/model_default",
|
||||
Map.of("value", "glm-4-blackbox-" + runId, "description", "黑盒测试默认模型"),
|
||||
adminToken);
|
||||
assertSuccess(updateConfig, HttpStatus.OK);
|
||||
@@ -191,89 +191,89 @@ class SwaggerLiveBlackBoxTest extends AbstractBlackBoxTest {
|
||||
Long sourceId = uploadTextSource(uploaderToken);
|
||||
Long extractionTaskId = createTask(sourceId, "EXTRACTION");
|
||||
|
||||
assertSuccess(postJson("/api/tasks/" + extractionTaskId + "/claim", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/tasks/" + extractionTaskId + "/claim", null, annotatorToken), HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> extractionGet = get("/api/extraction/" + extractionTaskId, annotatorToken);
|
||||
ResponseEntity<Map> extractionGet = get("/label/api/extraction/" + extractionTaskId, annotatorToken);
|
||||
assertSuccess(extractionGet, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> extractionPut = putJson("/api/extraction/" + extractionTaskId,
|
||||
ResponseEntity<Map> extractionPut = putJson("/label/api/extraction/" + extractionTaskId,
|
||||
"{\"items\":[{\"label\":\"entity\",\"text\":\"北京\"}]}",
|
||||
annotatorToken);
|
||||
assertSuccess(extractionPut, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> extractionSubmit = postJson("/api/extraction/" + extractionTaskId + "/submit", null, annotatorToken);
|
||||
ResponseEntity<Map> extractionSubmit = postJson("/label/api/extraction/" + extractionTaskId + "/submit", null, annotatorToken);
|
||||
assertSuccess(extractionSubmit, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> pendingExtraction = get("/api/tasks/pending-review?page=1&pageSize=20&taskType=EXTRACTION", reviewerToken);
|
||||
ResponseEntity<Map> pendingExtraction = get("/label/api/tasks/pending-review?page=1&pageSize=20&taskType=EXTRACTION", reviewerToken);
|
||||
assertSuccess(pendingExtraction, HttpStatus.OK);
|
||||
assertThat(responseContainsId(pendingExtraction, extractionTaskId)).isTrue();
|
||||
|
||||
ResponseEntity<Map> extractionReject = postJson("/api/extraction/" + extractionTaskId + "/reject",
|
||||
ResponseEntity<Map> extractionReject = postJson("/label/api/extraction/" + extractionTaskId + "/reject",
|
||||
Map.of("reason", "黑盒驳回一次"), reviewerToken);
|
||||
assertSuccess(extractionReject, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> reclaim = postJson("/api/tasks/" + extractionTaskId + "/reclaim", null, annotatorToken);
|
||||
ResponseEntity<Map> reclaim = postJson("/label/api/tasks/" + extractionTaskId + "/reclaim", null, annotatorToken);
|
||||
assertSuccess(reclaim, HttpStatus.OK);
|
||||
|
||||
assertSuccess(putJson("/api/extraction/" + extractionTaskId,
|
||||
assertSuccess(putJson("/label/api/extraction/" + extractionTaskId,
|
||||
"{\"items\":[{\"label\":\"entity\",\"text\":\"上海\"}]}",
|
||||
annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/api/extraction/" + extractionTaskId + "/submit", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/extraction/" + extractionTaskId + "/submit", null, annotatorToken), HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> extractionApprove = postJson("/api/extraction/" + extractionTaskId + "/approve", null, reviewerToken);
|
||||
ResponseEntity<Map> extractionApprove = postJson("/label/api/extraction/" + extractionTaskId + "/approve", null, reviewerToken);
|
||||
assertSuccess(extractionApprove, HttpStatus.OK);
|
||||
|
||||
Long qaTaskId = latestTaskId(sourceId, "QA_GENERATION");
|
||||
assertThat(qaTaskId).isNotNull();
|
||||
|
||||
assertSuccess(postJson("/api/tasks/" + qaTaskId + "/claim", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/tasks/" + qaTaskId + "/claim", null, annotatorToken), HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> qaGet = get("/api/qa/" + qaTaskId, annotatorToken);
|
||||
ResponseEntity<Map> qaGet = get("/label/api/qa/" + qaTaskId, annotatorToken);
|
||||
assertSuccess(qaGet, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> qaPut = putJson("/api/qa/" + qaTaskId,
|
||||
ResponseEntity<Map> qaPut = putJson("/label/api/qa/" + qaTaskId,
|
||||
Map.of("items", List.of(Map.of("question", "北京在哪里", "answer", "中国"))),
|
||||
annotatorToken);
|
||||
assertSuccess(qaPut, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> qaSubmit = postJson("/api/qa/" + qaTaskId + "/submit", null, annotatorToken);
|
||||
ResponseEntity<Map> qaSubmit = postJson("/label/api/qa/" + qaTaskId + "/submit", null, annotatorToken);
|
||||
assertSuccess(qaSubmit, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> pendingQa = get("/api/tasks/pending-review?page=1&pageSize=20&taskType=QA_GENERATION", reviewerToken);
|
||||
ResponseEntity<Map> pendingQa = get("/label/api/tasks/pending-review?page=1&pageSize=20&taskType=QA_GENERATION", reviewerToken);
|
||||
assertSuccess(pendingQa, HttpStatus.OK);
|
||||
assertThat(responseContainsId(pendingQa, qaTaskId)).isTrue();
|
||||
|
||||
ResponseEntity<Map> qaApprove = postJson("/api/qa/" + qaTaskId + "/approve", null, reviewerToken);
|
||||
ResponseEntity<Map> qaApprove = postJson("/label/api/qa/" + qaTaskId + "/approve", null, reviewerToken);
|
||||
assertSuccess(qaApprove, HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> samples = get("/api/training/samples?page=1&pageSize=20&sampleType=TEXT", adminToken);
|
||||
ResponseEntity<Map> samples = get("/label/api/training/samples?page=1&pageSize=20&sampleType=TEXT", adminToken);
|
||||
assertSuccess(samples, HttpStatus.OK);
|
||||
|
||||
Long datasetId = latestApprovedDatasetId(sourceId);
|
||||
ResponseEntity<Map> createBatch = postJson("/api/export/batch",
|
||||
ResponseEntity<Map> createBatch = postJson("/label/api/export/batch",
|
||||
Map.of("sampleIds", List.of(datasetId)), adminToken);
|
||||
assertSuccess(createBatch, HttpStatus.CREATED);
|
||||
Long batchId = dataId(createBatch);
|
||||
|
||||
ResponseEntity<Map> exportList = get("/api/export/list?page=1&pageSize=20", adminToken);
|
||||
ResponseEntity<Map> exportList = get("/label/api/export/list?page=1&pageSize=20", adminToken);
|
||||
assertSuccess(exportList, HttpStatus.OK);
|
||||
assertThat(responseContainsId(exportList, batchId)).isTrue();
|
||||
|
||||
ResponseEntity<Map> exportStatus = get("/api/export/" + batchId + "/status", adminToken);
|
||||
ResponseEntity<Map> exportStatus = get("/label/api/export/" + batchId + "/status", adminToken);
|
||||
assertSuccess(exportStatus, HttpStatus.OK);
|
||||
|
||||
// 第二条链路覆盖 QA reject
|
||||
Long sourceId2 = uploadTextSource(uploaderToken);
|
||||
Long extractionTaskId2 = createTask(sourceId2, "EXTRACTION");
|
||||
assertSuccess(postJson("/api/tasks/" + extractionTaskId2 + "/claim", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/api/extraction/" + extractionTaskId2 + "/submit", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/api/extraction/" + extractionTaskId2 + "/approve", null, reviewerToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/tasks/" + extractionTaskId2 + "/claim", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/extraction/" + extractionTaskId2 + "/submit", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/extraction/" + extractionTaskId2 + "/approve", null, reviewerToken), HttpStatus.OK);
|
||||
|
||||
Long qaTaskId2 = latestTaskId(sourceId2, "QA_GENERATION");
|
||||
assertSuccess(postJson("/api/tasks/" + qaTaskId2 + "/claim", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/api/qa/" + qaTaskId2 + "/submit", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/tasks/" + qaTaskId2 + "/claim", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/qa/" + qaTaskId2 + "/submit", null, annotatorToken), HttpStatus.OK);
|
||||
|
||||
ResponseEntity<Map> qaReject = postJson("/api/qa/" + qaTaskId2 + "/reject",
|
||||
ResponseEntity<Map> qaReject = postJson("/label/api/qa/" + qaTaskId2 + "/reject",
|
||||
Map.of("reason", "黑盒问答驳回"), reviewerToken);
|
||||
assertSuccess(qaReject, HttpStatus.OK);
|
||||
}
|
||||
@@ -287,36 +287,36 @@ class SwaggerLiveBlackBoxTest extends AbstractBlackBoxTest {
|
||||
|
||||
Long sourceId = uploadTextSource(uploaderToken);
|
||||
Long extractionTaskId = createTask(sourceId, "EXTRACTION");
|
||||
assertSuccess(postJson("/api/tasks/" + extractionTaskId + "/claim", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/api/extraction/" + extractionTaskId + "/submit", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/api/extraction/" + extractionTaskId + "/approve", null, reviewerToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/tasks/" + extractionTaskId + "/claim", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/extraction/" + extractionTaskId + "/submit", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/extraction/" + extractionTaskId + "/approve", null, reviewerToken), HttpStatus.OK);
|
||||
|
||||
Long qaTaskId = latestTaskId(sourceId, "QA_GENERATION");
|
||||
assertSuccess(postJson("/api/tasks/" + qaTaskId + "/claim", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/api/qa/" + qaTaskId + "/submit", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/api/qa/" + qaTaskId + "/approve", null, reviewerToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/tasks/" + qaTaskId + "/claim", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/qa/" + qaTaskId + "/submit", null, annotatorToken), HttpStatus.OK);
|
||||
assertSuccess(postJson("/label/api/qa/" + qaTaskId + "/approve", null, reviewerToken), HttpStatus.OK);
|
||||
|
||||
Long datasetId = latestApprovedDatasetId(sourceId);
|
||||
ResponseEntity<Map> createBatch = postJson("/api/export/batch",
|
||||
ResponseEntity<Map> createBatch = postJson("/label/api/export/batch",
|
||||
Map.of("sampleIds", List.of(datasetId)), adminToken);
|
||||
assertSuccess(createBatch, HttpStatus.CREATED);
|
||||
Long batchId = dataId(createBatch);
|
||||
|
||||
ResponseEntity<Map> finetune = postJson("/api/export/" + batchId + "/finetune", null, adminToken);
|
||||
ResponseEntity<Map> finetune = postJson("/label/api/export/" + batchId + "/finetune", null, adminToken);
|
||||
assertSuccess(finetune, HttpStatus.OK);
|
||||
|
||||
Long videoSourceId = uploadVideoSource(uploaderToken);
|
||||
ResponseEntity<Map> createVideoJob = postJson("/api/video/process",
|
||||
ResponseEntity<Map> createVideoJob = postJson("/label/api/video/process",
|
||||
Map.of("sourceId", videoSourceId, "jobType", "FRAME_EXTRACT", "params", "{\"frameInterval\":30}"),
|
||||
adminToken);
|
||||
assertSuccess(createVideoJob, HttpStatus.OK);
|
||||
Long jobId = dataId(createVideoJob);
|
||||
|
||||
ResponseEntity<Map> getVideoJob = get("/api/video/jobs/" + jobId, adminToken);
|
||||
ResponseEntity<Map> getVideoJob = get("/label/api/video/jobs/" + jobId, adminToken);
|
||||
assertSuccess(getVideoJob, HttpStatus.OK);
|
||||
|
||||
Long failedJobId = insertFailedVideoJob(videoSourceId);
|
||||
ResponseEntity<Map> resetJob = postJson("/api/video/jobs/" + failedJobId + "/reset", null, adminToken);
|
||||
ResponseEntity<Map> resetJob = postJson("/label/api/video/jobs/" + failedJobId + "/reset", null, adminToken);
|
||||
assertSuccess(resetJob, HttpStatus.OK);
|
||||
|
||||
Long callbackJobId = insertPendingVideoJob(videoSourceId);
|
||||
|
||||
@@ -21,8 +21,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* 1. 正确密码登录 → 返回 token
|
||||
* 2. 错误密码登录 → 401
|
||||
* 3. 不存在的公司代码 → 401
|
||||
* 4. 有效 Token 访问 /api/auth/me → 200,返回用户信息
|
||||
* 5. 主动退出后,原 Token 访问 /api/auth/me → 401
|
||||
* 4. 有效 Token 访问 /label/api/auth/me → 200,返回用户信息
|
||||
* 5. 主动退出后,原 Token 访问 /label/api/auth/me → 401
|
||||
*
|
||||
* 测试数据来自 init.sql 种子(DEMO 公司 / admin / admin123)
|
||||
*/
|
||||
@@ -74,7 +74,7 @@ public class AuthIntegrationTest extends AbstractIntegrationTest {
|
||||
assertThat(token).isNotBlank();
|
||||
|
||||
ResponseEntity<Map> response = restTemplate.exchange(
|
||||
baseUrl("/api/auth/me"),
|
||||
baseUrl("/label/api/auth/me"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(token),
|
||||
Map.class);
|
||||
@@ -92,7 +92,7 @@ public class AuthIntegrationTest extends AbstractIntegrationTest {
|
||||
@DisplayName("无 Token 访问 /api/auth/me → 401")
|
||||
void me_withNoToken_returns401() {
|
||||
ResponseEntity<String> response = restTemplate.getForEntity(
|
||||
baseUrl("/api/auth/me"), String.class);
|
||||
baseUrl("/label/api/auth/me"), String.class);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ public class AuthIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 确认登录有效
|
||||
ResponseEntity<Map> meResponse = restTemplate.exchange(
|
||||
baseUrl("/api/auth/me"),
|
||||
baseUrl("/label/api/auth/me"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(token),
|
||||
Map.class);
|
||||
@@ -114,7 +114,7 @@ public class AuthIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 退出
|
||||
ResponseEntity<Map> logoutResponse = restTemplate.exchange(
|
||||
baseUrl("/api/auth/logout"),
|
||||
baseUrl("/label/api/auth/logout"),
|
||||
HttpMethod.POST,
|
||||
bearerRequest(token),
|
||||
Map.class);
|
||||
@@ -122,7 +122,7 @@ public class AuthIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 退出后再访问 /me → 401
|
||||
ResponseEntity<Map> meAfterLogout = restTemplate.exchange(
|
||||
baseUrl("/api/auth/me"),
|
||||
baseUrl("/label/api/auth/me"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(token),
|
||||
Map.class);
|
||||
@@ -137,7 +137,7 @@ public class AuthIntegrationTest extends AbstractIntegrationTest {
|
||||
req.setCompanyCode(companyCode);
|
||||
req.setUsername(username);
|
||||
req.setPassword(password);
|
||||
return restTemplate.postForEntity(baseUrl("/api/auth/login"), req, Map.class);
|
||||
return restTemplate.postForEntity(baseUrl("/label/api/auth/login"), req, Map.class);
|
||||
}
|
||||
|
||||
/** 登录并提取 token 字符串;失败时返回 null */
|
||||
|
||||
@@ -109,7 +109,7 @@ public class ExportIntegrationTest extends AbstractIntegrationTest {
|
||||
Map.of("sampleIds", List.of(approvedDatasetId)), headers);
|
||||
|
||||
ResponseEntity<Map> response = restTemplate.exchange(
|
||||
baseUrl("/api/export/batch"), HttpMethod.POST, req, Map.class);
|
||||
baseUrl("/label/api/export/batch"), HttpMethod.POST, req, Map.class);
|
||||
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
@@ -126,7 +126,7 @@ public class ExportIntegrationTest extends AbstractIntegrationTest {
|
||||
Map.of("sampleIds", List.of()), headers);
|
||||
|
||||
ResponseEntity<Map> response = restTemplate.exchange(
|
||||
baseUrl("/api/export/batch"), HttpMethod.POST, req, Map.class);
|
||||
baseUrl("/label/api/export/batch"), HttpMethod.POST, req, Map.class);
|
||||
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
assertThat(response.getBody().get("code")).isEqualTo("EMPTY_SAMPLES");
|
||||
@@ -143,7 +143,7 @@ public class ExportIntegrationTest extends AbstractIntegrationTest {
|
||||
Map.of("sampleIds", List.of(approvedDatasetId, pendingDatasetId)), headers);
|
||||
|
||||
ResponseEntity<Map> response = restTemplate.exchange(
|
||||
baseUrl("/api/export/batch"), HttpMethod.POST, req, Map.class);
|
||||
baseUrl("/label/api/export/batch"), HttpMethod.POST, req, Map.class);
|
||||
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
assertThat(response.getBody().get("code")).isEqualTo("INVALID_SAMPLES");
|
||||
@@ -153,7 +153,7 @@ public class ExportIntegrationTest extends AbstractIntegrationTest {
|
||||
@DisplayName("查询已审批样本列表 → 200,包含 APPROVED 样本")
|
||||
void listSamples_adminOnly_returns200() {
|
||||
ResponseEntity<Map> response = restTemplate.exchange(
|
||||
baseUrl("/api/training/samples"),
|
||||
baseUrl("/label/api/training/samples"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(ADMIN_TOKEN),
|
||||
Map.class);
|
||||
|
||||
@@ -68,13 +68,13 @@ public class ExtractionApprovalIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 1. 标注员领取任务
|
||||
ResponseEntity<Map> claimResp = restTemplate.exchange(
|
||||
baseUrl("/api/tasks/" + taskId + "/claim"),
|
||||
baseUrl("/label/api/tasks/" + taskId + "/claim"),
|
||||
HttpMethod.POST, bearerRequest(annotatorToken), Map.class);
|
||||
assertThat(claimResp.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
// 2. 标注员提交标注
|
||||
ResponseEntity<Map> submitResp = restTemplate.exchange(
|
||||
baseUrl("/api/extraction/" + taskId + "/submit"),
|
||||
baseUrl("/label/api/extraction/" + taskId + "/submit"),
|
||||
HttpMethod.POST, bearerRequest(annotatorToken), Map.class);
|
||||
assertThat(submitResp.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
@@ -82,7 +82,7 @@ public class ExtractionApprovalIntegrationTest extends AbstractIntegrationTest {
|
||||
// 注:ExtractionApprovedEventListener(@TransactionalEventListener AFTER_COMMIT)
|
||||
// 在同一线程中同步执行,HTTP 响应返回前已完成后续处理
|
||||
ResponseEntity<Map> approveResp = restTemplate.exchange(
|
||||
baseUrl("/api/extraction/" + taskId + "/approve"),
|
||||
baseUrl("/label/api/extraction/" + taskId + "/approve"),
|
||||
HttpMethod.POST, bearerRequest(reviewerToken), Map.class);
|
||||
assertThat(approveResp.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
@@ -127,7 +127,7 @@ public class ExtractionApprovalIntegrationTest extends AbstractIntegrationTest {
|
||||
String reviewerToken = loginAndGetToken("DEMO", "reviewer01", "review123");
|
||||
|
||||
ResponseEntity<Map> resp = restTemplate.exchange(
|
||||
baseUrl("/api/extraction/" + taskId + "/approve"),
|
||||
baseUrl("/label/api/extraction/" + taskId + "/approve"),
|
||||
HttpMethod.POST, bearerRequest(reviewerToken), Map.class);
|
||||
|
||||
assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
@@ -147,9 +147,9 @@ public class ExtractionApprovalIntegrationTest extends AbstractIntegrationTest {
|
||||
String reviewerToken = loginAndGetToken("DEMO", "reviewer01", "review123");
|
||||
|
||||
// 1. 标注员领取并提交
|
||||
restTemplate.exchange(baseUrl("/api/tasks/" + taskId + "/claim"),
|
||||
restTemplate.exchange(baseUrl("/label/api/tasks/" + taskId + "/claim"),
|
||||
HttpMethod.POST, bearerRequest(annotatorToken), Map.class);
|
||||
restTemplate.exchange(baseUrl("/api/extraction/" + taskId + "/submit"),
|
||||
restTemplate.exchange(baseUrl("/label/api/extraction/" + taskId + "/submit"),
|
||||
HttpMethod.POST, bearerRequest(annotatorToken), Map.class);
|
||||
|
||||
// 2. 审核员驳回(驳回原因必填)
|
||||
@@ -160,7 +160,7 @@ public class ExtractionApprovalIntegrationTest extends AbstractIntegrationTest {
|
||||
Map.of("reason", "实体识别有误,请重新标注"), rejectHeaders);
|
||||
|
||||
ResponseEntity<Map> rejectResp = restTemplate.exchange(
|
||||
baseUrl("/api/extraction/" + taskId + "/reject"),
|
||||
baseUrl("/label/api/extraction/" + taskId + "/reject"),
|
||||
HttpMethod.POST, rejectReq, Map.class);
|
||||
assertThat(rejectResp.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
@@ -171,7 +171,7 @@ public class ExtractionApprovalIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 3. 标注员重领任务(REJECTED → IN_PROGRESS)
|
||||
ResponseEntity<Map> reclaimResp = restTemplate.exchange(
|
||||
baseUrl("/api/tasks/" + taskId + "/reclaim"),
|
||||
baseUrl("/label/api/tasks/" + taskId + "/reclaim"),
|
||||
HttpMethod.POST, bearerRequest(annotatorToken), Map.class);
|
||||
assertThat(reclaimResp.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
@@ -182,7 +182,7 @@ public class ExtractionApprovalIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 4. 标注员再次提交(IN_PROGRESS → SUBMITTED)
|
||||
ResponseEntity<Map> resubmitResp = restTemplate.exchange(
|
||||
baseUrl("/api/extraction/" + taskId + "/submit"),
|
||||
baseUrl("/label/api/extraction/" + taskId + "/submit"),
|
||||
HttpMethod.POST, bearerRequest(annotatorToken), Map.class);
|
||||
assertThat(resubmitResp.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
@@ -200,7 +200,7 @@ public class ExtractionApprovalIntegrationTest extends AbstractIntegrationTest {
|
||||
req.setUsername(username);
|
||||
req.setPassword(password);
|
||||
ResponseEntity<Map> response = restTemplate.postForEntity(
|
||||
baseUrl("/api/auth/login"), req, Map.class);
|
||||
baseUrl("/label/api/auth/login"), req, Map.class);
|
||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ public class MultiTenantIsolationTest extends AbstractIntegrationTest {
|
||||
@DisplayName("公司 A 只能查看本公司资料,看不到公司 B 的资料")
|
||||
void sourceList_companyA_cannotSeeCompanyBData() {
|
||||
ResponseEntity<Map> resp = restTemplate.exchange(
|
||||
baseUrl("/api/source/list?page=1&pageSize=50"),
|
||||
baseUrl("/label/api/source/list?page=1&pageSize=50"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(TOKEN_A),
|
||||
Map.class);
|
||||
@@ -133,7 +133,7 @@ public class MultiTenantIsolationTest extends AbstractIntegrationTest {
|
||||
@DisplayName("公司 B 只能查看本公司资料,看不到公司 A 的资料")
|
||||
void sourceList_companyB_cannotSeeCompanyAData() {
|
||||
ResponseEntity<Map> resp = restTemplate.exchange(
|
||||
baseUrl("/api/source/list?page=1&pageSize=50"),
|
||||
baseUrl("/label/api/source/list?page=1&pageSize=50"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(TOKEN_B),
|
||||
Map.class);
|
||||
@@ -157,14 +157,14 @@ public class MultiTenantIsolationTest extends AbstractIntegrationTest {
|
||||
headersA.setContentType(MediaType.APPLICATION_JSON);
|
||||
|
||||
restTemplate.exchange(
|
||||
baseUrl("/api/config/model_default"),
|
||||
baseUrl("/label/api/config/model_default"),
|
||||
HttpMethod.PUT,
|
||||
new HttpEntity<>(Map.of("value", "glm-4-plus"), headersA),
|
||||
Map.class);
|
||||
|
||||
// 公司 B 查询配置列表
|
||||
ResponseEntity<Map> respB = restTemplate.exchange(
|
||||
baseUrl("/api/config"),
|
||||
baseUrl("/label/api/config"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(TOKEN_B),
|
||||
Map.class);
|
||||
|
||||
@@ -78,19 +78,19 @@ public class QaApprovalIntegrationTest extends AbstractIntegrationTest {
|
||||
// 但 TaskController.getPool 只给 ANNOTATOR 显示 EXTRACTION/UNCLAIMED
|
||||
// QA 任务由 ANNOTATOR 直接领取(不经过任务池)
|
||||
ResponseEntity<Map> claimResp = restTemplate.exchange(
|
||||
baseUrl("/api/tasks/" + taskId + "/claim"),
|
||||
baseUrl("/label/api/tasks/" + taskId + "/claim"),
|
||||
HttpMethod.POST, bearerRequest(annotatorToken), Map.class);
|
||||
assertThat(claimResp.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
// 提交 QA 结果
|
||||
ResponseEntity<Map> submitResp = restTemplate.exchange(
|
||||
baseUrl("/api/qa/" + taskId + "/submit"),
|
||||
baseUrl("/label/api/qa/" + taskId + "/submit"),
|
||||
HttpMethod.POST, bearerRequest(annotatorToken), Map.class);
|
||||
assertThat(submitResp.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
// 审批通过
|
||||
ResponseEntity<Map> approveResp = restTemplate.exchange(
|
||||
baseUrl("/api/qa/" + taskId + "/approve"),
|
||||
baseUrl("/label/api/qa/" + taskId + "/approve"),
|
||||
HttpMethod.POST, bearerRequest(reviewerToken), Map.class);
|
||||
assertThat(approveResp.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
@@ -120,9 +120,9 @@ public class QaApprovalIntegrationTest extends AbstractIntegrationTest {
|
||||
String reviewerToken = loginAndGetToken("DEMO", "reviewer01", "review123");
|
||||
|
||||
// 领取并提交
|
||||
restTemplate.exchange(baseUrl("/api/tasks/" + taskId + "/claim"),
|
||||
restTemplate.exchange(baseUrl("/label/api/tasks/" + taskId + "/claim"),
|
||||
HttpMethod.POST, bearerRequest(annotatorToken), Map.class);
|
||||
restTemplate.exchange(baseUrl("/api/qa/" + taskId + "/submit"),
|
||||
restTemplate.exchange(baseUrl("/label/api/qa/" + taskId + "/submit"),
|
||||
HttpMethod.POST, bearerRequest(annotatorToken), Map.class);
|
||||
|
||||
// 驳回(驳回原因必填)
|
||||
@@ -133,7 +133,7 @@ public class QaApprovalIntegrationTest extends AbstractIntegrationTest {
|
||||
Map.of("reason", "问题描述不准确,请修改"), headers);
|
||||
|
||||
ResponseEntity<Map> rejectResp = restTemplate.exchange(
|
||||
baseUrl("/api/qa/" + taskId + "/reject"),
|
||||
baseUrl("/label/api/qa/" + taskId + "/reject"),
|
||||
HttpMethod.POST, rejectReq, Map.class);
|
||||
assertThat(rejectResp.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
@@ -155,13 +155,13 @@ public class QaApprovalIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 标注员重领任务
|
||||
ResponseEntity<Map> reclaimResp = restTemplate.exchange(
|
||||
baseUrl("/api/tasks/" + taskId + "/reclaim"),
|
||||
baseUrl("/label/api/tasks/" + taskId + "/reclaim"),
|
||||
HttpMethod.POST, bearerRequest(annotatorToken), Map.class);
|
||||
assertThat(reclaimResp.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
// 再次提交
|
||||
ResponseEntity<Map> resubmitResp = restTemplate.exchange(
|
||||
baseUrl("/api/qa/" + taskId + "/submit"),
|
||||
baseUrl("/label/api/qa/" + taskId + "/submit"),
|
||||
HttpMethod.POST, bearerRequest(annotatorToken), Map.class);
|
||||
assertThat(resubmitResp.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
|
||||
@@ -179,7 +179,7 @@ public class QaApprovalIntegrationTest extends AbstractIntegrationTest {
|
||||
req.setUsername(username);
|
||||
req.setPassword(password);
|
||||
ResponseEntity<Map> response = restTemplate.postForEntity(
|
||||
baseUrl("/api/auth/login"), req, Map.class);
|
||||
baseUrl("/label/api/auth/login"), req, Map.class);
|
||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class SourceIntegrationTest extends AbstractIntegrationTest {
|
||||
@DisplayName("无 Token 访问上传接口 → 401")
|
||||
void upload_withoutToken_returns401() {
|
||||
ResponseEntity<String> response = restTemplate.postForEntity(
|
||||
baseUrl("/api/source/upload"), null, String.class);
|
||||
baseUrl("/label/api/source/upload"), null, String.class);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class SourceIntegrationTest extends AbstractIntegrationTest {
|
||||
@DisplayName("UPLOADER 访问列表接口(无数据)→ 200,items 为空")
|
||||
void list_uploaderWithNoData_returnsEmptyList() {
|
||||
ResponseEntity<Map> response = restTemplate.exchange(
|
||||
baseUrl("/api/source/list"),
|
||||
baseUrl("/label/api/source/list"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(UPLOADER_TOKEN),
|
||||
Map.class);
|
||||
@@ -94,7 +94,7 @@ public class SourceIntegrationTest extends AbstractIntegrationTest {
|
||||
@DisplayName("ADMIN 访问列表接口(无数据)→ 200,items 为空")
|
||||
void list_adminWithNoData_returnsEmptyList() {
|
||||
ResponseEntity<Map> response = restTemplate.exchange(
|
||||
baseUrl("/api/source/list"),
|
||||
baseUrl("/label/api/source/list"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(ADMIN_TOKEN),
|
||||
Map.class);
|
||||
@@ -110,7 +110,7 @@ public class SourceIntegrationTest extends AbstractIntegrationTest {
|
||||
@DisplayName("删除不存在的资料 → 404")
|
||||
void delete_nonExistentSource_returns404() {
|
||||
ResponseEntity<Map> response = restTemplate.exchange(
|
||||
baseUrl("/api/source/9999"),
|
||||
baseUrl("/label/api/source/9999"),
|
||||
HttpMethod.DELETE,
|
||||
bearerRequest(ADMIN_TOKEN),
|
||||
Map.class);
|
||||
@@ -122,7 +122,7 @@ public class SourceIntegrationTest extends AbstractIntegrationTest {
|
||||
@DisplayName("非 ADMIN 删除资料 → 403 Forbidden")
|
||||
void delete_byUploader_returns403() {
|
||||
ResponseEntity<Map> response = restTemplate.exchange(
|
||||
baseUrl("/api/source/9999"),
|
||||
baseUrl("/label/api/source/9999"),
|
||||
HttpMethod.DELETE,
|
||||
bearerRequest(UPLOADER_TOKEN),
|
||||
Map.class);
|
||||
@@ -145,7 +145,7 @@ public class SourceIntegrationTest extends AbstractIntegrationTest {
|
||||
assertThat(sourceId).isNotNull();
|
||||
|
||||
ResponseEntity<Map> response = restTemplate.exchange(
|
||||
baseUrl("/api/source/" + sourceId),
|
||||
baseUrl("/label/api/source/" + sourceId),
|
||||
HttpMethod.DELETE,
|
||||
bearerRequest(ADMIN_TOKEN),
|
||||
Map.class);
|
||||
|
||||
@@ -67,7 +67,7 @@ public class SysConfigIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 查询配置列表
|
||||
ResponseEntity<Map> listResp = restTemplate.exchange(
|
||||
baseUrl("/api/config"),
|
||||
baseUrl("/label/api/config"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(ADMIN_TOKEN),
|
||||
Map.class);
|
||||
@@ -99,7 +99,7 @@ public class SysConfigIntegrationTest extends AbstractIntegrationTest {
|
||||
void globalConfig_usedWhenNoCompanyOverride() {
|
||||
// 不设置公司专属,直接查询列表
|
||||
ResponseEntity<Map> listResp = restTemplate.exchange(
|
||||
baseUrl("/api/config"),
|
||||
baseUrl("/label/api/config"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(ADMIN_TOKEN),
|
||||
Map.class);
|
||||
@@ -170,7 +170,7 @@ public class SysConfigIntegrationTest extends AbstractIntegrationTest {
|
||||
: Map.of("value", value);
|
||||
|
||||
return restTemplate.exchange(
|
||||
baseUrl("/api/config/" + key),
|
||||
baseUrl("/label/api/config/" + key),
|
||||
HttpMethod.PUT,
|
||||
new HttpEntity<>(body, headers),
|
||||
Map.class);
|
||||
|
||||
@@ -97,7 +97,7 @@ public class TaskClaimConcurrencyTest extends AbstractIntegrationTest {
|
||||
HttpEntity<Void> request = new HttpEntity<>(headers);
|
||||
|
||||
ResponseEntity<Map> response = restTemplate.exchange(
|
||||
baseUrl("/api/tasks/" + taskId + "/claim"),
|
||||
baseUrl("/label/api/tasks/" + taskId + "/claim"),
|
||||
HttpMethod.POST, request, Map.class);
|
||||
|
||||
if (response.getStatusCode() == HttpStatus.OK) {
|
||||
|
||||
@@ -47,7 +47,7 @@ public class UserManagementIntegrationTest extends AbstractIntegrationTest {
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
|
||||
ResponseEntity<Map> createResp = restTemplate.exchange(
|
||||
baseUrl("/api/users"),
|
||||
baseUrl("/label/api/users"),
|
||||
HttpMethod.POST,
|
||||
new HttpEntity<>(Map.of(
|
||||
"username", uniqueUsername,
|
||||
@@ -68,7 +68,7 @@ public class UserManagementIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 3. 验证:ANNOTATOR 无法访问待审批队列(REVIEWER 专属)→ 403
|
||||
ResponseEntity<Map> beforeRoleChange = restTemplate.exchange(
|
||||
baseUrl("/api/tasks/pending-review"),
|
||||
baseUrl("/label/api/tasks/pending-review"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(userToken),
|
||||
Map.class);
|
||||
@@ -76,7 +76,7 @@ public class UserManagementIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 4. ADMIN 变更角色为 REVIEWER
|
||||
ResponseEntity<Map> roleResp = restTemplate.exchange(
|
||||
baseUrl("/api/users/" + newUserId + "/role"),
|
||||
baseUrl("/label/api/users/" + newUserId + "/role"),
|
||||
HttpMethod.PUT,
|
||||
new HttpEntity<>(Map.of("role", "REVIEWER"), headers),
|
||||
Map.class);
|
||||
@@ -84,7 +84,7 @@ public class UserManagementIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 5. 验证:同一 Token 下次请求立即具有 REVIEWER 权限 → 200
|
||||
ResponseEntity<Map> afterRoleChange = restTemplate.exchange(
|
||||
baseUrl("/api/tasks/pending-review"),
|
||||
baseUrl("/label/api/tasks/pending-review"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(userToken),
|
||||
Map.class);
|
||||
@@ -106,7 +106,7 @@ public class UserManagementIntegrationTest extends AbstractIntegrationTest {
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
|
||||
ResponseEntity<Map> createResp = restTemplate.exchange(
|
||||
baseUrl("/api/users"),
|
||||
baseUrl("/label/api/users"),
|
||||
HttpMethod.POST,
|
||||
new HttpEntity<>(Map.of(
|
||||
"username", uniqueUsername,
|
||||
@@ -127,7 +127,7 @@ public class UserManagementIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 3. 验证 Token 有效
|
||||
ResponseEntity<Map> meResp = restTemplate.exchange(
|
||||
baseUrl("/api/auth/me"),
|
||||
baseUrl("/label/api/auth/me"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(userToken),
|
||||
Map.class);
|
||||
@@ -135,7 +135,7 @@ public class UserManagementIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 4. ADMIN 禁用账号
|
||||
ResponseEntity<Map> disableResp = restTemplate.exchange(
|
||||
baseUrl("/api/users/" + newUserId + "/status"),
|
||||
baseUrl("/label/api/users/" + newUserId + "/status"),
|
||||
HttpMethod.PUT,
|
||||
new HttpEntity<>(Map.of("status", "DISABLED"), headers),
|
||||
Map.class);
|
||||
@@ -143,7 +143,7 @@ public class UserManagementIntegrationTest extends AbstractIntegrationTest {
|
||||
|
||||
// 5. 验证:禁用后,现有 Token 立即失效 → 401
|
||||
ResponseEntity<Map> meAfterDisable = restTemplate.exchange(
|
||||
baseUrl("/api/auth/me"),
|
||||
baseUrl("/label/api/auth/me"),
|
||||
HttpMethod.GET,
|
||||
bearerRequest(userToken),
|
||||
Map.class);
|
||||
@@ -160,7 +160,7 @@ public class UserManagementIntegrationTest extends AbstractIntegrationTest {
|
||||
req.setUsername(username);
|
||||
req.setPassword(password);
|
||||
ResponseEntity<Map> response = restTemplate.postForEntity(
|
||||
baseUrl("/api/auth/login"), req, Map.class);
|
||||
baseUrl("/label/api/auth/login"), req, Map.class);
|
||||
if (!response.getStatusCode().is2xxSuccessful()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ public class VideoCallbackIdempotencyTest extends AbstractIntegrationTest {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("Authorization", "Bearer " + ADMIN_TOKEN);
|
||||
ResponseEntity<Map> resp = restTemplate.exchange(
|
||||
baseUrl("/api/video/jobs/" + jobId + "/reset"),
|
||||
baseUrl("/label/api/video/jobs/" + jobId + "/reset"),
|
||||
HttpMethod.POST,
|
||||
new HttpEntity<>(headers),
|
||||
Map.class);
|
||||
@@ -175,7 +175,7 @@ public class VideoCallbackIdempotencyTest extends AbstractIntegrationTest {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
return restTemplate.exchange(
|
||||
baseUrl("/api/video/callback"),
|
||||
baseUrl("/label/api/video/callback"),
|
||||
HttpMethod.POST,
|
||||
new HttpEntity<>(body, headers),
|
||||
Map.class);
|
||||
|
||||
@@ -50,7 +50,7 @@ class AuthInterceptorTest {
|
||||
"username", "admin"
|
||||
));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/api/test/admin");
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/label/api/test/admin");
|
||||
request.addHeader("Authorization", "Bearer valid-token");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
@@ -76,7 +76,7 @@ class AuthInterceptorTest {
|
||||
"username", "admin"
|
||||
));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/api/test/reviewer");
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/label/api/test/reviewer");
|
||||
request.addHeader("Authorization", "Bearer admin-token");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
@@ -95,7 +95,7 @@ class AuthInterceptorTest {
|
||||
"username", "annotator"
|
||||
));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/api/test/reviewer");
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/label/api/test/reviewer");
|
||||
request.addHeader("Authorization", "Bearer annotator-token");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
@@ -107,7 +107,7 @@ class AuthInterceptorTest {
|
||||
@DisplayName("缺少 Token 时返回 401")
|
||||
void missingTokenReturnsUnauthorized() throws Exception {
|
||||
ReflectionTestUtils.setField(interceptor, "authEnabled", true);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/api/test/admin");
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/label/api/test/admin");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
|
||||
assertThat(interceptor.preHandle(request, response, handler("adminOnly"))).isFalse();
|
||||
|
||||
Reference in New Issue
Block a user