"""字典项唯一性按所属字典隔离:同一字典下名称不可重复,不同字典同名放行。""" import json from modules.dictionary.dict_item.repository import dictitem_repo from modules.dictionary.dict_item.schemas import DictItemForm from modules.dictionary.dict_item.service import dict_item_service class _FakeQuery: """模拟 SQLAlchemy Query:记录是否调用 filter(排除自身),first() 返回行或 None。""" def __init__(self, has_row=True): self._has_row = has_row self.filter_called = False def filter(self, *criteria): self.filter_called = True # 排除自身后应无重复行 return _FakeQuery(False) def first(self): return object() if self._has_row else None def _body(result): return json.loads(result.body) def _set_filter_by(monkeypatch, query): monkeypatch.setattr(dictitem_repo, 'filter_by', lambda **kw: query) # ============ 查重范围:按 (dict_id, name) 隔离 ============ def test_dict_item_unique_scoped_to_dict(monkeypatch): captured = {} def fake_filter_by(**kw): captured.update(kw) return _FakeQuery(False) monkeypatch.setattr(dictitem_repo, 'filter_by', fake_filter_by) data = DictItemForm(name='启用', value='1', dictId=2, sort=1) assert dict_item_service._check_unique(data) is None # 查重条件是 dict_id + name,而非仅 name 全局查重 assert captured == {'dict_id': 2, 'name': '启用'} def test_dict_item_unique_blocks_same_name_in_same_dict(monkeypatch): captured = {} def fake_filter_by(**kw): captured.update(kw) return _FakeQuery(True) monkeypatch.setattr(dictitem_repo, 'filter_by', fake_filter_by) data = DictItemForm(name='启用', value='1', dictId=2, sort=1) assert dict_item_service._check_unique(data) == '字典项名称不能重复' assert captured == {'dict_id': 2, 'name': '启用'} # ============ 编辑时排除自身 ============ def test_dict_item_unique_excludes_self_on_update(monkeypatch): query = _FakeQuery(True) _set_filter_by(monkeypatch, query) data = DictItemForm(id=5, name='启用', value='1', dictId=2, sort=1) # 排除自身后无重复 → 放行 assert dict_item_service._check_unique(data, exclude_id=5) is None assert query.filter_called is True def test_dict_item_unique_add_does_not_exclude(monkeypatch): query = _FakeQuery(True) _set_filter_by(monkeypatch, query) data = DictItemForm(name='启用', value='1', dictId=2, sort=1) # 新增不排除自身 → 查到同名字段即判重 assert dict_item_service._check_unique(data) == '字典项名称不能重复' assert query.filter_called is False # ============ add 端到端:不同字典同名可新增,同字典同名被拒 ============ def test_dict_item_add_allows_same_name_in_different_dict(monkeypatch, fake_request): _set_filter_by(monkeypatch, _FakeQuery(False)) captured = {} monkeypatch.setattr(dictitem_repo, 'create', lambda **fields: captured.update(fields) or object()) data = DictItemForm(name='启用', value='1', dictId=2, sort=1) result = dict_item_service.add(fake_request, data) assert _body(result)['ok'] is True assert captured['dictId'] == 2 def test_dict_item_add_blocks_same_name_in_same_dict(monkeypatch, fake_request): _set_filter_by(monkeypatch, _FakeQuery(True)) data = DictItemForm(name='启用', value='1', dictId=2, sort=1) result = dict_item_service.add(fake_request, data) assert _body(result)['ok'] is False assert '重复' in _body(result)['msg']