Commit 087eb8f5feea91739008e6adc1cddc70bbbbee7a

Authored by zichun
1 parent bf2370ba

test(mod): module delete integration coverage REQ-MOD-003

backend/src/main/java/com/xly/erp/module/mod/controller/ModuleController.java
@@ -5,6 +5,7 @@ import com.xly.erp.module.mod.dto.CreateModuleDTO; @@ -5,6 +5,7 @@ import com.xly.erp.module.mod.dto.CreateModuleDTO;
5 import com.xly.erp.module.mod.dto.UpdateModuleDTO; 5 import com.xly.erp.module.mod.dto.UpdateModuleDTO;
6 import com.xly.erp.module.mod.service.ModuleService; 6 import com.xly.erp.module.mod.service.ModuleService;
7 import jakarta.validation.Valid; 7 import jakarta.validation.Valid;
  8 +import org.springframework.web.bind.annotation.DeleteMapping;
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;
@@ -36,4 +37,10 @@ public class ModuleController { @@ -36,4 +37,10 @@ public class ModuleController {
36 Integer updated = moduleService.update(id, dto); 37 Integer updated = moduleService.update(id, dto);
37 return Result.ok(Map.of("iIncrement", updated)); 38 return Result.ok(Map.of("iIncrement", updated));
38 } 39 }
  40 +
  41 + @DeleteMapping("/modules/{id}")
  42 + public Result<Void> delete(@PathVariable Integer id) {
  43 + moduleService.delete(id);
  44 + return Result.ok();
  45 + }
39 } 46 }
backend/src/test/java/com/xly/erp/module/mod/controller/ModuleControllerIT.java
@@ -287,6 +287,107 @@ class ModuleControllerIT { @@ -287,6 +287,107 @@ class ModuleControllerIT {
287 assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isEqualTo(20001); 287 assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isEqualTo(20001);
288 } 288 }
289 289
  290 + @Test
  291 + void deleteValidId_with_jwt_returns200_andSoftDeletes() throws Exception {
  292 + Integer id = insertOriginal("sp_test_del_ok", "原", "ORIG_USER");
  293 + String token = testJwtHelper.signFor("ADMIN001");
  294 + HttpHeaders headers = jsonHeaders();
  295 + headers.set("Authorization", "Bearer " + token);
  296 +
  297 + ResponseEntity<String> resp = rest.exchange(
  298 + idUrl(id), HttpMethod.DELETE, new HttpEntity<>(headers), String.class);
  299 +
  300 + assertThat(resp.getStatusCode().value()).isEqualTo(200);
  301 + JsonNode jb = objectMapper.readTree(resp.getBody());
  302 + assertThat(jb.get("code").asInt()).isZero();
  303 + assertThat(jb.get("data").isNull()).isTrue();
  304 +
  305 + Map<String, Object> row = jdbcTemplate.queryForMap(
  306 + "SELECT bDeleted, sDeletedBy, tDeletedDate, sProcedureName, sCreatedBy FROM tModule WHERE iIncrement = ?", id);
  307 + assertThat(row.get("bDeleted")).isEqualTo(true);
  308 + assertThat(row.get("sDeletedBy")).isEqualTo("ADMIN001");
  309 + assertThat(row.get("tDeletedDate")).isNotNull();
  310 + assertThat(row.get("sProcedureName")).isEqualTo("sp_test_del_ok");
  311 + assertThat(row.get("sCreatedBy")).isEqualTo("ORIG_USER");
  312 + }
  313 +
  314 + @Test
  315 + void deleteNonExistentId_returns40400() throws Exception {
  316 + String token = testJwtHelper.signFor("ADMIN001");
  317 + HttpHeaders headers = jsonHeaders();
  318 + headers.set("Authorization", "Bearer " + token);
  319 +
  320 + ResponseEntity<String> resp = rest.exchange(
  321 + idUrl(99999996), HttpMethod.DELETE, new HttpEntity<>(headers), String.class);
  322 +
  323 + assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isEqualTo(40400);
  324 + }
  325 +
  326 + @Test
  327 + void deleteAlreadyDeletedId_returns40400() throws Exception {
  328 + Integer id = insertOriginal("sp_test_del_already", "已删", "ORIG");
  329 + jdbcTemplate.update("UPDATE tModule SET bDeleted = 1 WHERE iIncrement = ?", id);
  330 + String token = testJwtHelper.signFor("ADMIN001");
  331 + HttpHeaders headers = jsonHeaders();
  332 + headers.set("Authorization", "Bearer " + token);
  333 +
  334 + ResponseEntity<String> resp = rest.exchange(
  335 + idUrl(id), HttpMethod.DELETE, new HttpEntity<>(headers), String.class);
  336 +
  337 + assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isEqualTo(40400);
  338 + }
  339 +
  340 + @Test
  341 + void deleteWithActiveChildren_returns40901() throws Exception {
  342 + Integer rootId = insertOriginal("sp_test_del_root", "根", "ORIG");
  343 + jdbcTemplate.update(
  344 + "INSERT INTO tModule (sBrandsId, sSubsidiaryId, tCreateDate, sDisplayType, sProcedureName, "
  345 + + "sModuleType, sManageDeptEn, bShowPermission, sModuleNameZh, iParentId, iSortOrder, sCreatedBy, bDeleted) "
  346 + + "VALUES ('XLY','XLY', NOW(), '手机端', 'sp_test_del_child', '业务模块', 'IT', 0, '子', ?, 0, 'ORIG', 0)",
  347 + rootId);
  348 + String token = testJwtHelper.signFor("ADMIN001");
  349 + HttpHeaders headers = jsonHeaders();
  350 + headers.set("Authorization", "Bearer " + token);
  351 +
  352 + ResponseEntity<String> resp = rest.exchange(
  353 + idUrl(rootId), HttpMethod.DELETE, new HttpEntity<>(headers), String.class);
  354 +
  355 + assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isEqualTo(40901);
  356 + Boolean stillAlive = jdbcTemplate.queryForObject(
  357 + "SELECT bDeleted FROM tModule WHERE iIncrement = ?", Boolean.class, rootId);
  358 + assertThat(stillAlive).isFalse();
  359 + }
  360 +
  361 + @Test
  362 + void deleteWithoutJwt_permitAllStub_returns200_andDeletedByIsSTUB() throws Exception {
  363 + Integer id = insertOriginal("sp_test_del_nojwt", "原", "ORIG");
  364 + HttpHeaders headers = jsonHeaders();
  365 +
  366 + ResponseEntity<String> resp = rest.exchange(
  367 + idUrl(id), HttpMethod.DELETE, new HttpEntity<>(headers), String.class);
  368 +
  369 + assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isZero();
  370 + Map<String, Object> row = jdbcTemplate.queryForMap(
  371 + "SELECT bDeleted, sDeletedBy FROM tModule WHERE iIncrement = ?", id);
  372 + assertThat(row.get("bDeleted")).isEqualTo(true);
  373 + assertThat(row.get("sDeletedBy")).isEqualTo("STUB_ADMIN");
  374 + }
  375 +
  376 + @Test
  377 + void deleteTamperedJwt_returns20001() throws Exception {
  378 + Integer id = insertOriginal("sp_test_del_tamper", "原", "ORIG");
  379 + HttpHeaders headers = jsonHeaders();
  380 + headers.set("Authorization", "Bearer not.a.real.jwt");
  381 +
  382 + ResponseEntity<String> resp = rest.exchange(
  383 + idUrl(id), HttpMethod.DELETE, new HttpEntity<>(headers), String.class);
  384 +
  385 + assertThat(objectMapper.readTree(resp.getBody()).get("code").asInt()).isEqualTo(20001);
  386 + Boolean stillAlive = jdbcTemplate.queryForObject(
  387 + "SELECT bDeleted FROM tModule WHERE iIncrement = ?", Boolean.class, id);
  388 + assertThat(stillAlive).isFalse();
  389 + }
  390 +
290 private Integer insertOriginal(String procedureName, String nameZh, String createdBy) { 391 private Integer insertOriginal(String procedureName, String nameZh, String createdBy) {
291 jdbcTemplate.update( 392 jdbcTemplate.update(
292 "INSERT INTO tModule (sBrandsId, sSubsidiaryId, tCreateDate, sDisplayType, sProcedureName, " 393 "INSERT INTO tModule (sBrandsId, sSubsidiaryId, tCreateDate, sDisplayType, sProcedureName, "