test_replace_step_outputs.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. """保存步骤产出物时保留原行 ID,避免质检工单等外键被整表替换打断。"""
  2. import unittest
  3. from datetime import datetime
  4. from sqlalchemy import create_engine
  5. from sqlalchemy.orm import sessionmaker
  6. from app.crud.production_task import replace_step_outputs
  7. from app.models.models import BizProductionTaskStepOutput
  8. def _session():
  9. engine = create_engine("sqlite://")
  10. BizProductionTaskStepOutput.__table__.create(bind=engine)
  11. return sessionmaker(bind=engine)()
  12. def _output(**kwargs):
  13. now = datetime(2026, 9, 2, 9, 1, 8)
  14. data = dict(
  15. step_id="step-1",
  16. tenant_no="tenant-a",
  17. output_type_id="type-valid",
  18. output_name="细胞悬液",
  19. output_barcode="NK-UBMC202603009",
  20. create_dept_id="",
  21. create_time=now,
  22. update_time=now,
  23. del_flag=0,
  24. )
  25. data.update(kwargs)
  26. return BizProductionTaskStepOutput(**data)
  27. class TestReplaceStepOutputsKeepsIdentity(unittest.TestCase):
  28. def test_existing_row_keeps_id_when_fields_change(self):
  29. db = _session()
  30. db.add(_output(id="out-keep"))
  31. db.commit()
  32. saved = replace_step_outputs(
  33. db,
  34. "step-1",
  35. "tenant-a",
  36. "user-1",
  37. [
  38. {
  39. "id": "out-keep",
  40. "output_type_id": "type-valid",
  41. "output_name": "细胞悬液",
  42. "output_barcode": "NK-UBMC202603009-NEW",
  43. "remark": "",
  44. }
  45. ],
  46. )
  47. self.assertEqual(saved[0]["id"], "out-keep")
  48. self.assertEqual(saved[0]["outputBarcode"], "NK-UBMC202603009-NEW")
  49. alive = (
  50. db.query(BizProductionTaskStepOutput)
  51. .filter(BizProductionTaskStepOutput.del_flag == 0)
  52. .all()
  53. )
  54. self.assertEqual([row.id for row in alive], ["out-keep"])
  55. def test_insert_new_update_old_and_soft_delete_only_removed(self):
  56. db = _session()
  57. db.add(_output(id="out-keep", output_name="细胞悬液", output_barcode="NK-OLD"))
  58. db.add(_output(id="out-drop", output_name="细胞上清", output_barcode="NK-DROP"))
  59. db.commit()
  60. saved = replace_step_outputs(
  61. db,
  62. "step-1",
  63. "tenant-a",
  64. "user-1",
  65. [
  66. {
  67. "id": "out-keep",
  68. "output_type_id": "type-valid",
  69. "output_name": "细胞悬液",
  70. "output_barcode": "NK-UPDATED",
  71. "remark": "改条码",
  72. },
  73. {
  74. "output_type_id": "type-valid",
  75. "output_name": "废液",
  76. "output_barcode": "NK-NEW",
  77. "remark": "",
  78. },
  79. ],
  80. )
  81. self.assertEqual(saved[0]["id"], "out-keep")
  82. self.assertEqual(saved[0]["outputBarcode"], "NK-UPDATED")
  83. self.assertTrue(saved[1]["id"])
  84. self.assertNotEqual(saved[1]["id"], "out-keep")
  85. self.assertEqual(saved[1]["outputName"], "废液")
  86. rows = {row.id: row for row in db.query(BizProductionTaskStepOutput).all()}
  87. self.assertEqual(rows["out-keep"].del_flag, 0)
  88. self.assertEqual(rows["out-keep"].output_barcode, "NK-UPDATED")
  89. self.assertEqual(rows["out-drop"].del_flag, 1)
  90. self.assertEqual(rows[saved[1]["id"]].del_flag, 0)
  91. self.assertEqual(rows[saved[1]["id"]].output_barcode, "NK-NEW")
  92. def test_removed_row_is_soft_deleted_and_kept_row_stays(self):
  93. db = _session()
  94. db.add(_output(id="out-keep", output_name="细胞悬液"))
  95. db.add(_output(id="out-drop", output_name="细胞上清"))
  96. db.commit()
  97. replace_step_outputs(
  98. db,
  99. "step-1",
  100. "tenant-a",
  101. "user-1",
  102. [
  103. {
  104. "id": "out-keep",
  105. "output_type_id": "type-valid",
  106. "output_name": "细胞悬液",
  107. "output_barcode": "NK-UBMC202603009",
  108. "remark": "",
  109. }
  110. ],
  111. )
  112. rows = {row.id: row for row in db.query(BizProductionTaskStepOutput).all()}
  113. self.assertEqual(rows["out-keep"].del_flag, 0)
  114. self.assertEqual(rows["out-drop"].del_flag, 1)
  115. def test_id_from_another_step_is_rejected(self):
  116. db = _session()
  117. db.add(_output(id="out-other", step_id="step-2"))
  118. db.commit()
  119. with self.assertRaises(ValueError):
  120. replace_step_outputs(
  121. db,
  122. "step-1",
  123. "tenant-a",
  124. "user-1",
  125. [
  126. {
  127. "id": "out-other",
  128. "output_type_id": "type-valid",
  129. "output_name": "细胞悬液",
  130. "output_barcode": "NK-UBMC202603009",
  131. "remark": "",
  132. }
  133. ],
  134. )
  135. other = db.query(BizProductionTaskStepOutput).filter_by(id="out-other").one()
  136. self.assertEqual(other.step_id, "step-2")
  137. self.assertEqual(other.del_flag, 0)
  138. if __name__ == "__main__":
  139. unittest.main()