Commit 0017a259116cfd31ab45bca69435bd7e09bf77c0

Authored by zichun
1 parent 7eec9887

feat(mod): module create error branches REQ-MOD-001

backend/src/main/java/com/xly/erp/module/mod/service/impl/ModuleServiceImpl.java
... ... @@ -8,15 +8,19 @@ import com.xly.erp.module.mod.dto.CreateModuleDTO;
8 8 import com.xly.erp.module.mod.entity.Module;
9 9 import com.xly.erp.module.mod.mapper.ModuleMapper;
10 10 import com.xly.erp.module.mod.service.ModuleService;
  11 +import org.springframework.dao.DuplicateKeyException;
11 12 import org.springframework.stereotype.Service;
12 13 import org.springframework.transaction.annotation.Transactional;
13 14  
14 15 import java.time.LocalDateTime;
  16 +import java.util.Set;
15 17  
16 18 @Service
17 19 @Transactional(rollbackFor = Exception.class)
18 20 public class ModuleServiceImpl implements ModuleService {
19 21  
  22 + private static final Set<String> DISPLAY_TYPES = Set.of("手机端", "前端业务", "系统配置", "接口");
  23 +
20 24 private final ModuleMapper moduleMapper;
21 25 private final TenantProperties tenant;
22 26 private final StubSecurityProperties stub;
... ... @@ -31,6 +35,9 @@ public class ModuleServiceImpl implements ModuleService {
31 35  
32 36 @Override
33 37 public Integer create(CreateModuleDTO dto) {
  38 + if (!DISPLAY_TYPES.contains(dto.getSDisplayType())) {
  39 + throw new BizException(40010, "显示类型枚举不合法");
  40 + }
34 41 if (dto.getIParentId() != null && !moduleMapper.existsActiveById(dto.getIParentId())) {
35 42 throw new BizException(40021, "父模块不存在或已删除");
36 43 }
... ... @@ -51,7 +58,11 @@ public class ModuleServiceImpl implements ModuleService {
51 58 m.setSCreatedBy(authedUserNo != null ? authedUserNo : stub.getStubUserNo());
52 59 m.setBDeleted(false);
53 60  
54   - moduleMapper.insert(m);
  61 + try {
  62 + moduleMapper.insert(m);
  63 + } catch (DuplicateKeyException e) {
  64 + throw new BizException(40020, "存储过程名称已存在");
  65 + }
55 66 return m.getIIncrement();
56 67 }
57 68 }
... ...
backend/src/test/java/com/xly/erp/module/mod/service/ModuleServiceImplTest.java
... ... @@ -11,8 +11,12 @@ import org.junit.jupiter.api.AfterEach;
11 11 import org.junit.jupiter.api.BeforeEach;
12 12 import org.junit.jupiter.api.Test;
13 13 import org.mockito.ArgumentCaptor;
  14 +import org.springframework.dao.DuplicateKeyException;
  15 +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
14 16 import org.springframework.security.core.context.SecurityContextHolder;
15 17  
  18 +import java.util.Collections;
  19 +
16 20 import static org.assertj.core.api.Assertions.assertThat;
17 21 import static org.assertj.core.api.Assertions.assertThatThrownBy;
18 22 import static org.mockito.ArgumentMatchers.any;
... ... @@ -82,6 +86,52 @@ class ModuleServiceImplTest {
82 86 verify(moduleMapper, never()).insert(any(Module.class));
83 87 }
84 88  
  89 + @Test
  90 + void createWithInvalidDisplayType_throws40010() {
  91 + CreateModuleDTO dto = baseDto();
  92 + dto.setSDisplayType("未知");
  93 +
  94 + assertThatThrownBy(() -> service.create(dto))
  95 + .isInstanceOf(BizException.class)
  96 + .hasFieldOrPropertyWithValue("code", 40010);
  97 + verify(moduleMapper, never()).insert(any(Module.class));
  98 + }
  99 +
  100 + @Test
  101 + void createWithNullParentId_skipsParentCheck() {
  102 + CreateModuleDTO dto = baseDto();
  103 + dto.setIParentId(null);
  104 +
  105 + service.create(dto);
  106 +
  107 + verify(moduleMapper, never()).findActiveFlagById(any());
  108 + verify(moduleMapper, times(1)).insert(any(Module.class));
  109 + }
  110 +
  111 + @Test
  112 + void mapperDuplicateKey_throws40020() {
  113 + CreateModuleDTO dto = baseDto();
  114 + when(moduleMapper.insert(any(Module.class)))
  115 + .thenThrow(new DuplicateKeyException("uk_procedure_name"));
  116 +
  117 + assertThatThrownBy(() -> service.create(dto))
  118 + .isInstanceOf(BizException.class)
  119 + .hasFieldOrPropertyWithValue("code", 40020);
  120 + }
  121 +
  122 + @Test
  123 + void usesAuthenticatedUserNoAsCreatedBy() {
  124 + SecurityContextHolder.getContext().setAuthentication(
  125 + new UsernamePasswordAuthenticationToken("ALICE", null, Collections.emptyList()));
  126 + CreateModuleDTO dto = baseDto();
  127 +
  128 + service.create(dto);
  129 +
  130 + ArgumentCaptor<Module> captor = ArgumentCaptor.forClass(Module.class);
  131 + verify(moduleMapper).insert(captor.capture());
  132 + assertThat(captor.getValue().getSCreatedBy()).isEqualTo("ALICE");
  133 + }
  134 +
85 135 private CreateModuleDTO baseDto() {
86 136 CreateModuleDTO dto = new CreateModuleDTO();
87 137 dto.setSDisplayType("手机端");
... ...