"""部分更新防 NULL 覆盖:编辑时未传的可选字段不得把数据库旧值清空为 NULL。""" import json from modules.file_template.schemas import FileTemplateForm from modules.file_template.service import file_template_service from modules.city.schemas import CityForm from modules.city.service import update_city from modules.city.repository import city_repo from modules.system.dept.schemas import DeptForm from modules.system.dept.service import update_dept from modules.system.dept.repository import dept_repo from modules.article.schemas import ArticleForm from modules.article.service import update_article from modules.article.repository import article_repo def _body(result): return json.loads(result.body) # ============ base 层 _build_update_fields ============ def test_build_update_fields_excludes_none(fake_request): data = FileTemplateForm(id=1, name='模板', sort=5) # code/file_name/file_path/note 未传 → None fields = file_template_service._build_update_fields(fake_request, data) assert 'id' not in fields assert 'name' in fields assert 'sort' in fields assert 'code' not in fields assert 'filePath' not in fields assert 'update_user' in fields assert 'update_time' in fields # ============ city:编辑顶级时 parent_id 不被清空 ============ def test_update_city_preserves_parent_id_when_omitted(monkeypatch, fake_request): monkeypatch.setattr(city_repo, 'get_by_id', lambda uid: object()) captured = {} monkeypatch.setattr(city_repo, 'update', lambda uid, fields: captured.update(fields) or True) data = CityForm( id=1, name='省', shortName='s', pinyin='p', cityCode='010', areaCode='11', zipCode='100', level=1, lng='0', lat='0', ) # parentId 未传 → None result = update_city(fake_request, data) assert _body(result)['ok'] is True assert 'parentId' not in captured # ============ dept:编辑顶级时 parent_id 不被清空 ============ def test_update_dept_preserves_parent_id_when_omitted(monkeypatch, fake_request): monkeypatch.setattr(dept_repo, 'exists_by_field', lambda *a, **k: False) monkeypatch.setattr(dept_repo, 'get_by_id', lambda uid: object()) captured = {} monkeypatch.setattr(dept_repo, 'update', lambda uid, fields: captured.update(fields) or True) data = DeptForm(id=1, name='部门', code='D1', type=1, sort=1) # parent_id/note 未传 → None result = update_dept(fake_request, data) assert _body(result)['ok'] is True assert 'parentId' not in captured assert 'note' not in captured # ============ article:未传的 category_id/intro/author 不被清空 ============ def test_update_article_preserves_optional_fields_when_omitted(monkeypatch, fake_request): class _OldArticle: cover = None images = None content = None monkeypatch.setattr(article_repo, 'get_by_id', lambda uid: _OldArticle()) captured = {} monkeypatch.setattr(article_repo, 'update', lambda uid, fields: captured.update(fields) or True) data = ArticleForm(id=1, title='标题', status=0) # category_id/intro/author 未传 → None result = update_article(fake_request, data) assert _body(result)['ok'] is True assert 'title' in captured assert 'categoryId' not in captured assert 'intro' not in captured assert 'author' not in captured