test_dict_ensure.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. from types import SimpleNamespace
  2. from unittest.mock import MagicMock
  3. import pytest
  4. from app.models.models import SysDictData
  5. from app.services.dict_ensure import (
  6. DICT_ENSURE_WHITELIST,
  7. DictEnsureError,
  8. ensure_dict_data,
  9. ensure_remove_dict_data,
  10. )
  11. def test_whitelist_contains_crm_types():
  12. assert "crm_product_gg" in DICT_ENSURE_WHITELIST
  13. assert "crm_shfs" in DICT_ENSURE_WHITELIST
  14. assert "crm_product_unit" in DICT_ENSURE_WHITELIST
  15. assert "crm_customer_park" in DICT_ENSURE_WHITELIST
  16. def test_ensure_rejects_unknown_dict_type():
  17. db = MagicMock()
  18. with pytest.raises(DictEnsureError, match="不支持"):
  19. ensure_dict_data(
  20. db, tenant_no="t1", dict_type="sys_user_sex", label="男", user_id="u1"
  21. )
  22. def test_ensure_rejects_empty_label():
  23. db = MagicMock()
  24. with pytest.raises(DictEnsureError, match="不能为空"):
  25. ensure_dict_data(
  26. db, tenant_no="t1", dict_type="crm_shfs", label=" ", user_id="u1"
  27. )
  28. def test_ensure_reuses_existing_label():
  29. db = MagicMock()
  30. existing = SimpleNamespace(dict_label="自提", dict_value="自提")
  31. q = MagicMock()
  32. q.filter.return_value.first.return_value = existing
  33. db.query.return_value = q
  34. result = ensure_dict_data(
  35. db, tenant_no="t1", dict_type="crm_shfs", label="自提", user_id="u1"
  36. )
  37. assert result == {"label": "自提", "value": "自提", "created": False}
  38. db.add.assert_not_called()
  39. def test_ensure_inserts_new_with_value_equals_label():
  40. db = MagicMock()
  41. q = MagicMock()
  42. # existing by label: None; clash by value: None
  43. q.filter.return_value.first.side_effect = [None, None]
  44. db.query.return_value = q
  45. result = ensure_dict_data(
  46. db, tenant_no="t1", dict_type="crm_product_gg", label="吨袋装", user_id="u1"
  47. )
  48. assert result == {"label": "吨袋装", "value": "吨袋装", "created": True}
  49. db.add.assert_called_once()
  50. db.flush.assert_called_once()
  51. db.commit.assert_not_called()
  52. added = db.add.call_args[0][0]
  53. assert isinstance(added, SysDictData)
  54. assert added.dict_type == "crm_product_gg"
  55. assert added.dict_label == "吨袋装"
  56. assert added.dict_value == "吨袋装"
  57. assert added.tenant_no == "t1"
  58. assert added.create_by == "u1"
  59. def test_ensure_reuses_existing_by_preferred_value():
  60. """label miss, but preferred value already exists → reuse, no insert"""
  61. db = MagicMock()
  62. existing = SimpleNamespace(dict_label="旧标签", dict_value="吨袋装")
  63. q = MagicMock()
  64. # first query by label → None; second by value → existing
  65. q.filter.return_value.first.side_effect = [None, existing]
  66. db.query.return_value = q
  67. result = ensure_dict_data(
  68. db, tenant_no="t1", dict_type="crm_product_gg", label="吨袋装", user_id="u1"
  69. )
  70. assert result == {"label": "旧标签", "value": "吨袋装", "created": False}
  71. db.add.assert_not_called()
  72. def test_ensure_honors_explicit_preferred_value_on_insert():
  73. db = MagicMock()
  74. q = MagicMock()
  75. q.filter.return_value.first.side_effect = [None, None]
  76. db.query.return_value = q
  77. result = ensure_dict_data(
  78. db,
  79. tenant_no="t1",
  80. dict_type="crm_product_gg",
  81. label="吨袋装",
  82. user_id="u1",
  83. preferred_value="custom_gg",
  84. )
  85. assert result == {"label": "吨袋装", "value": "custom_gg", "created": True}
  86. added = db.add.call_args[0][0]
  87. assert added.dict_value == "custom_gg"
  88. def test_ensure_remove_soft_deletes_own_row():
  89. db = MagicMock()
  90. row = SimpleNamespace(
  91. dict_value="吨袋装",
  92. create_by="u1",
  93. del_flag=0,
  94. update_by=None,
  95. update_time=None,
  96. )
  97. q = MagicMock()
  98. q.filter.return_value.first.return_value = row
  99. db.query.return_value = q
  100. ensure_remove_dict_data(
  101. db,
  102. tenant_no="t1",
  103. dict_type="crm_product_gg",
  104. value="吨袋装",
  105. user_id="u1",
  106. )
  107. assert row.del_flag == 1
  108. assert row.update_by == "u1"
  109. db.add.assert_called_once_with(row)
  110. db.flush.assert_called_once()
  111. def test_ensure_remove_rejects_other_users_row():
  112. db = MagicMock()
  113. row = SimpleNamespace(dict_value="吨袋装", create_by="other", del_flag=0)
  114. q = MagicMock()
  115. q.filter.return_value.first.return_value = row
  116. db.query.return_value = q
  117. with pytest.raises(DictEnsureError, match="无权|不能删除|不允许"):
  118. ensure_remove_dict_data(
  119. db,
  120. tenant_no="t1",
  121. dict_type="crm_product_gg",
  122. value="吨袋装",
  123. user_id="u1",
  124. )
  125. def test_ensure_remove_rejects_unknown_type():
  126. db = MagicMock()
  127. with pytest.raises(DictEnsureError, match="不支持"):
  128. ensure_remove_dict_data(
  129. db,
  130. tenant_no="t1",
  131. dict_type="sys_user_sex",
  132. value="1",
  133. user_id="u1",
  134. )