Commit c00054eaf325c698ccf2e7342eced4ef0d0958a2

Authored by zichun
1 parent 57a1bbfc

test(usr): user list integration coverage REQ-USR-003

backend/src/main/java/com/xly/erp/module/usr/controller/UserController.java
@@ -5,11 +5,13 @@ import com.xly.erp.module.usr.dto.CreateUserDTO; @@ -5,11 +5,13 @@ import com.xly.erp.module.usr.dto.CreateUserDTO;
5 import com.xly.erp.module.usr.dto.UpdateUserDTO; 5 import com.xly.erp.module.usr.dto.UpdateUserDTO;
6 import com.xly.erp.module.usr.service.UserService; 6 import com.xly.erp.module.usr.service.UserService;
7 import jakarta.validation.Valid; 7 import jakarta.validation.Valid;
  8 +import org.springframework.web.bind.annotation.GetMapping;
8 import org.springframework.web.bind.annotation.PathVariable; 9 import org.springframework.web.bind.annotation.PathVariable;
9 import org.springframework.web.bind.annotation.PostMapping; 10 import org.springframework.web.bind.annotation.PostMapping;
10 import org.springframework.web.bind.annotation.PutMapping; 11 import org.springframework.web.bind.annotation.PutMapping;
11 import org.springframework.web.bind.annotation.RequestBody; 12 import org.springframework.web.bind.annotation.RequestBody;
12 import org.springframework.web.bind.annotation.RequestMapping; 13 import org.springframework.web.bind.annotation.RequestMapping;
  14 +import org.springframework.web.bind.annotation.RequestParam;
13 import org.springframework.web.bind.annotation.RestController; 15 import org.springframework.web.bind.annotation.RestController;
14 16
15 import java.util.Map; 17 import java.util.Map;
@@ -35,4 +37,13 @@ public class UserController { @@ -35,4 +37,13 @@ public class UserController {
35 Integer updated = userService.update(id, dto); 37 Integer updated = userService.update(id, dto);
36 return Result.ok(Map.of("iIncrement", updated)); 38 return Result.ok(Map.of("iIncrement", updated));
37 } 39 }
  40 +
  41 + @GetMapping("/users")
  42 + public Result<Map<String, Object>> list(@RequestParam(required = false) String field,
  43 + @RequestParam(required = false) String match,
  44 + @RequestParam(required = false) String value,
  45 + @RequestParam(required = false) Integer pageNum,
  46 + @RequestParam(required = false) Integer pageSize) {
  47 + return Result.ok(userService.list(field, match, value, pageNum, pageSize));
  48 + }
38 } 49 }
backend/src/test/java/com/xly/erp/module/usr/controller/UserControllerIT.java
@@ -370,6 +370,115 @@ class UserControllerIT { @@ -370,6 +370,115 @@ class UserControllerIT {
370 assertThat(name).isEqualTo("原"); 370 assertThat(name).isEqualTo("原");
371 } 371 }
372 372
  373 + @Test
  374 + void getDefaults_with_jwt_returns200_andList() throws Exception {
  375 + insertUserWithPerms("sp_test_lst_1", "查询1", null, null);
  376 + insertUserWithPerms("sp_test_lst_2", "查询2", null, null);
  377 + String token = testJwtHelper.signFor("ADMIN001");
  378 + HttpHeaders headers = jsonHeaders();
  379 + headers.set("Authorization", "Bearer " + token);
  380 +
  381 + ResponseEntity<String> resp = rest.exchange(
  382 + listUrl(""), HttpMethod.GET, new HttpEntity<>(headers), String.class);
  383 +
  384 + JsonNode jb = objectMapper.readTree(resp.getBody());
  385 + assertThat(jb.get("code").asInt()).isZero();
  386 + assertThat(jb.get("data").get("records").isArray()).isTrue();
  387 + assertThat(jb.get("data").get("total").asInt()).isPositive();
  388 + assertThat(jb.get("data").get("pageSize").asInt()).isEqualTo(20);
  389 + }
  390 +
  391 + @Test
  392 + void getKeywordContains_filtersByUsername() throws Exception {
  393 + insertUserWithPerms("sp_test_lst_kw1", "包含查询用户", null, null);
  394 + String token = testJwtHelper.signFor("ADMIN001");
  395 + HttpHeaders headers = jsonHeaders();
  396 + headers.set("Authorization", "Bearer " + token);
  397 +
  398 + ResponseEntity<String> resp = rest.exchange(
  399 + listUrl("?field=用户名&match=包含&value=包含查询"), HttpMethod.GET, new HttpEntity<>(headers), String.class);
  400 +
  401 + JsonNode data = objectMapper.readTree(resp.getBody()).get("data");
  402 + for (JsonNode node : data.get("records")) {
  403 + assertThat(node.get("sUserName").asText()).contains("包含查询");
  404 + }
  405 + }
  406 +
  407 + @Test
  408 + void getKeywordEquals_filtersExact() throws Exception {
  409 + insertUserWithPerms("sp_test_lst_eq", "等于精确", null, null);
  410 + String token = testJwtHelper.signFor("ADMIN001");
  411 + HttpHeaders headers = jsonHeaders();
  412 + headers.set("Authorization", "Bearer " + token);
  413 +
  414 + ResponseEntity<String> resp = rest.exchange(
  415 + listUrl("?field=用户号&match=等于&value=sp_test_lst_eq"), HttpMethod.GET, new HttpEntity<>(headers), String.class);
  416 +
  417 + JsonNode records = objectMapper.readTree(resp.getBody()).get("data").get("records");
  418 + assertThat(records.size()).isEqualTo(1);
  419 + assertThat(records.get(0).get("sUserNo").asText()).isEqualTo("sp_test_lst_eq");
  420 + }
  421 +
  422 + @Test
  423 + void getInvalidField_returns40001() throws Exception {
  424 + String token = testJwtHelper.signFor("ADMIN001");
  425 + HttpHeaders headers = jsonHeaders();
  426 + headers.set("Authorization", "Bearer " + token);
  427 +
  428 + ResponseEntity<String> resp = rest.exchange(
  429 + listUrl("?field=未知"), HttpMethod.GET, new HttpEntity<>(headers), String.class);
  430 +
  431 + assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isEqualTo(40001);
  432 + }
  433 +
  434 + @Test
  435 + void getPageSizeExceeds100_returns40002() throws Exception {
  436 + String token = testJwtHelper.signFor("ADMIN001");
  437 + HttpHeaders headers = jsonHeaders();
  438 + headers.set("Authorization", "Bearer " + token);
  439 +
  440 + ResponseEntity<String> resp = rest.exchange(
  441 + listUrl("?pageSize=200"), HttpMethod.GET, new HttpEntity<>(headers), String.class);
  442 +
  443 + assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isEqualTo(40002);
  444 + }
  445 +
  446 + @Test
  447 + void getNoMatch_returnsEmptyArray() throws Exception {
  448 + String token = testJwtHelper.signFor("ADMIN001");
  449 + HttpHeaders headers = jsonHeaders();
  450 + headers.set("Authorization", "Bearer " + token);
  451 +
  452 + ResponseEntity<String> resp = rest.exchange(
  453 + listUrl("?field=用户号&match=等于&value=不存在的用户号XYZ"), HttpMethod.GET, new HttpEntity<>(headers), String.class);
  454 +
  455 + JsonNode data = objectMapper.readTree(resp.getBody()).get("data");
  456 + assertThat(data.get("records").isArray()).isTrue();
  457 + assertThat(data.get("records").size()).isZero();
  458 + assertThat(data.get("total").asInt()).isZero();
  459 + }
  460 +
  461 + @Test
  462 + void getWithoutJwt_permitAllStub_returns200() throws Exception {
  463 + HttpHeaders headers = jsonHeaders();
  464 + ResponseEntity<String> resp = rest.exchange(
  465 + listUrl(""), HttpMethod.GET, new HttpEntity<>(headers), String.class);
  466 + assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isZero();
  467 + }
  468 +
  469 + @Test
  470 + void getTamperedJwt_returns20001() throws Exception {
  471 + HttpHeaders headers = jsonHeaders();
  472 + headers.set("Authorization", "Bearer not.a.real.jwt");
  473 + ResponseEntity<String> resp = rest.exchange(
  474 + listUrl(""), HttpMethod.GET, new HttpEntity<>(headers), String.class);
  475 + assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isEqualTo(20001);
  476 + }
  477 +
  478 + private String listUrl(String querySuffix) {
  479 + return "http://localhost:" + port + "/api/usr/users" + querySuffix;
  480 + }
  481 +
373 private String idUrl(Integer id) { 482 private String idUrl(Integer id) {
374 return "http://localhost:" + port + "/api/usr/users/" + id; 483 return "http://localhost:" + port + "/api/usr/users/" + id;
375 } 484 }