test_pl_scan_cert_expiry.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. """证件到期扫描:有效期拉长后应关闭旧 pending,待真正进入提醒窗口再生成。"""
  2. from __future__ import annotations
  3. from datetime import date, timedelta
  4. from sqlalchemy import create_engine
  5. from sqlalchemy.orm import sessionmaker
  6. from app.models.pl_models import PlCert, PlDocumentReminder, PlVehicle
  7. from app.services.pl_cert_service import scan_cert_expiry
  8. def _session():
  9. engine = create_engine("sqlite://")
  10. PlCert.__table__.create(engine)
  11. PlDocumentReminder.__table__.create(engine)
  12. PlVehicle.__table__.create(engine)
  13. db = sessionmaker(bind=engine)()
  14. db.add(
  15. PlVehicle(
  16. id="veh-1",
  17. vehicle_type="self",
  18. license_plate="皖LB1283",
  19. tenant_no="t1",
  20. create_dept_id="d1",
  21. )
  22. )
  23. db.commit()
  24. return db
  25. def _add_cert(db, *, cert_id: str, expire_date: date, remind_days: int = 30, del_flag: int = 0, status: str = "valid"):
  26. db.add(
  27. PlCert(
  28. id=cert_id,
  29. owner_type="vehicle",
  30. owner_id="veh-1",
  31. cert_name="罐检报告",
  32. cert_no="皖R8440挂",
  33. expire_date=expire_date,
  34. remind_days=remind_days,
  35. status=status,
  36. tenant_no="t1",
  37. create_dept_id="d1",
  38. del_flag=del_flag,
  39. )
  40. )
  41. def _add_pending_reminder(db, *, rem_id: str, cert_id: str, expire_date: date, days_remaining: int):
  42. db.add(
  43. PlDocumentReminder(
  44. id=rem_id,
  45. cert_id=cert_id,
  46. owner_type="vehicle",
  47. owner_id="veh-1",
  48. owner_label="皖LB1283",
  49. document_type="罐检报告",
  50. document_no="皖R8440挂",
  51. expire_date=expire_date,
  52. days_remaining=days_remaining,
  53. status="pending",
  54. tenant_no="t1",
  55. create_dept_id="d1",
  56. )
  57. )
  58. def test_scan_resolves_pending_when_expire_moved_outside_remind_window():
  59. """复现生产:证已改到远期,旧 pending 提醒应被自动关闭。"""
  60. db = _session()
  61. today = date.today()
  62. old_expire = today + timedelta(days=1)
  63. new_expire = today + timedelta(days=337) # > remind_days=30
  64. _add_cert(db, cert_id="cert-tank", expire_date=new_expire, remind_days=30)
  65. _add_pending_reminder(
  66. db,
  67. rem_id="rem-stale",
  68. cert_id="cert-tank",
  69. expire_date=old_expire,
  70. days_remaining=21,
  71. )
  72. db.commit()
  73. created = scan_cert_expiry(db, tenant_no="t1")
  74. db.commit()
  75. assert created == 0
  76. rem = db.query(PlDocumentReminder).filter_by(id="rem-stale").one()
  77. assert rem.status == "resolved"
  78. assert rem.expire_date == new_expire
  79. assert rem.days_remaining == (new_expire - today).days
  80. assert rem.remark and "退出提醒窗口" in rem.remark
  81. def test_scan_keeps_and_updates_pending_inside_remind_window():
  82. db = _session()
  83. today = date.today()
  84. expire = today + timedelta(days=10)
  85. _add_cert(db, cert_id="cert-near", expire_date=expire, remind_days=30)
  86. _add_pending_reminder(
  87. db,
  88. rem_id="rem-near",
  89. cert_id="cert-near",
  90. expire_date=today + timedelta(days=5),
  91. days_remaining=5,
  92. )
  93. db.commit()
  94. created = scan_cert_expiry(db, tenant_no="t1")
  95. db.commit()
  96. assert created == 0
  97. rem = db.query(PlDocumentReminder).filter_by(id="rem-near").one()
  98. assert rem.status == "pending"
  99. assert rem.expire_date == expire
  100. assert rem.days_remaining == 10
  101. def test_scan_creates_reminder_when_entering_window():
  102. db = _session()
  103. today = date.today()
  104. expire = today + timedelta(days=15)
  105. _add_cert(db, cert_id="cert-new", expire_date=expire, remind_days=30)
  106. db.commit()
  107. created = scan_cert_expiry(db, tenant_no="t1")
  108. db.commit()
  109. assert created == 1
  110. rem = (
  111. db.query(PlDocumentReminder)
  112. .filter_by(cert_id="cert-new", status="pending", del_flag=0)
  113. .one()
  114. )
  115. assert rem.expire_date == expire
  116. assert rem.days_remaining == 15
  117. def test_scan_resolves_pending_when_cert_soft_deleted():
  118. db = _session()
  119. today = date.today()
  120. expire = today + timedelta(days=5)
  121. _add_cert(db, cert_id="cert-gone", expire_date=expire, del_flag=1)
  122. _add_pending_reminder(
  123. db,
  124. rem_id="rem-gone",
  125. cert_id="cert-gone",
  126. expire_date=expire,
  127. days_remaining=5,
  128. )
  129. db.commit()
  130. scan_cert_expiry(db, tenant_no="t1")
  131. db.commit()
  132. rem = db.query(PlDocumentReminder).filter_by(id="rem-gone").one()
  133. assert rem.status == "resolved"
  134. assert rem.remark and "失效" in rem.remark