|
|
|
@ -288,4 +288,95 @@ class DictItemServiceTest extends AbstractDictH2Test { |
|
|
|
PageResult<DictItemDTO> after = dictItemService.pageItems(param); |
|
|
|
assertThat(after.getContent()).allMatch(v -> !v.getEffectiveSelectable()); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@DisplayName("树形:二级项 parent_id 必须指向同组一级项;跨组/非一级父/自引用被拒") |
|
|
|
void saveItem_treeParentValidation() { |
|
|
|
DictGroup g = newGroup("industry", "所属行业"); |
|
|
|
DictGroup other = newGroup("other_g", "其他组"); |
|
|
|
DictItem lv1 = newItem(g.getId(), "gov", "gov"); // 一级(parentId=null)
|
|
|
|
DictItem otherLv1 = newItem(other.getId(), "x", "x"); // 异组一级
|
|
|
|
|
|
|
|
// 正常:二级挂同组一级
|
|
|
|
DictItemDTO lv2 = new DictItemDTO(); |
|
|
|
lv2.setGroupId(g.getId()); |
|
|
|
lv2.setCode("gov_ncpol"); |
|
|
|
lv2.setName("人大政协"); |
|
|
|
lv2.setParentId(lv1.getId()); |
|
|
|
dictItemService.saveItem(lv2); |
|
|
|
DictItem savedLv2 = dictItemMapper.selectList(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<DictItem>() |
|
|
|
.eq(DictItem::getCode, "gov_ncpol")).get(0); |
|
|
|
assertThat(savedLv2.getParentId()).isEqualTo(lv1.getId()); |
|
|
|
|
|
|
|
// 父不存在 → 63012
|
|
|
|
DictItemDTO badParent = new DictItemDTO(); |
|
|
|
badParent.setGroupId(g.getId()); |
|
|
|
badParent.setCode("gov_x"); |
|
|
|
badParent.setName("坏父"); |
|
|
|
badParent.setParentId(888888L); |
|
|
|
assertDictError(() -> dictItemService.saveItem(badParent), DictConstants.CODE_ITEM_NOT_EXIST); |
|
|
|
|
|
|
|
// 跨组父 → 63001
|
|
|
|
DictItemDTO crossParent = new DictItemDTO(); |
|
|
|
crossParent.setGroupId(g.getId()); |
|
|
|
crossParent.setCode("gov_cross"); |
|
|
|
crossParent.setName("跨组父"); |
|
|
|
crossParent.setParentId(otherLv1.getId()); |
|
|
|
assertDictError(() -> dictItemService.saveItem(crossParent), DictConstants.CODE_DICT_INVALID); |
|
|
|
|
|
|
|
// 父自身是二级(超两级)→ 63001
|
|
|
|
DictItemDTO lv3 = new DictItemDTO(); |
|
|
|
lv3.setGroupId(g.getId()); |
|
|
|
lv3.setCode("gov_ncpol_sub"); |
|
|
|
lv3.setName("三级"); |
|
|
|
lv3.setParentId(savedLv2.getId()); |
|
|
|
assertDictError(() -> dictItemService.saveItem(lv3), DictConstants.CODE_DICT_INVALID); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@DisplayName("树形:删一级项若有存活子项被拦;先删子项后可删") |
|
|
|
void deleteItem_blockedWhenHasChildren() { |
|
|
|
DictGroup g = newGroup("industry", "所属行业"); |
|
|
|
DictItem lv1 = newItem(g.getId(), "gov", "gov"); |
|
|
|
DictItemDTO lv2 = new DictItemDTO(); |
|
|
|
lv2.setGroupId(g.getId()); |
|
|
|
lv2.setCode("gov_ncpol"); |
|
|
|
lv2.setName("人大政协"); |
|
|
|
lv2.setParentId(lv1.getId()); |
|
|
|
dictItemService.saveItem(lv2); |
|
|
|
DictItem child = dictItemMapper.selectList(new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<DictItem>() |
|
|
|
.eq(DictItem::getCode, "gov_ncpol")).get(0); |
|
|
|
|
|
|
|
// 有子项 → 删一级被拦 63010
|
|
|
|
assertDictError(() -> dictItemService.deleteItem(lv1.getId()), DictConstants.CODE_ITEM_REFERENCED); |
|
|
|
// 先删子项,再删一级→ 通过
|
|
|
|
dictItemService.deleteItem(child.getId()); |
|
|
|
dictItemService.deleteItem(lv1.getId()); |
|
|
|
assertThat(dictItemMapper.selectCount(null)).isZero(); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@DisplayName("树形:停用一级项 → 其二级子项 effectiveSelectable=false(Q3-a 回溯父状态)") |
|
|
|
void effectiveSelectable_childFollowsParentDisabled() { |
|
|
|
DictGroup g = newGroup("industry", "所属行业"); |
|
|
|
DictItem lv1 = newItem(g.getId(), "gov", "gov"); |
|
|
|
DictItemDTO lv2 = new DictItemDTO(); |
|
|
|
lv2.setGroupId(g.getId()); |
|
|
|
lv2.setCode("gov_ncpol"); |
|
|
|
lv2.setName("人大政协"); |
|
|
|
lv2.setParentId(lv1.getId()); |
|
|
|
dictItemService.saveItem(lv2); |
|
|
|
|
|
|
|
ItemPageParam param = new ItemPageParam(); |
|
|
|
param.setGroupId(g.getId()); |
|
|
|
// 父启用时子可选
|
|
|
|
assertThat(dictItemService.pageItems(param).getContent()) |
|
|
|
.filteredOn(v -> "gov_ncpol".equals(v.getCode())) |
|
|
|
.allMatch(DictItemDTO::getEffectiveSelectable); |
|
|
|
// 停用一级父 → 子项不可选
|
|
|
|
dictItemService.updateItemStatus(lv1.getId(), DictConstants.STATUS_DISABLED); |
|
|
|
assertThat(dictItemService.pageItems(param).getContent()) |
|
|
|
.filteredOn(v -> "gov_ncpol".equals(v.getCode())) |
|
|
|
.allMatch(v -> !v.getEffectiveSelectable()); |
|
|
|
} |
|
|
|
} |
|
|
|
|