test_wechat_cert_schedule.py 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. """证件预警生成与微信摘要顺序、配置时区和失败隔离。"""
  2. import sys
  3. from types import SimpleNamespace
  4. import pytest
  5. from app.core.config import settings
  6. @pytest.mark.parametrize('enabled', [True, False])
  7. def test_scan_commits_before_enqueue_and_disabled_skips(monkeypatch, enabled):
  8. from app.tasks import pl_cert_expiry as task
  9. events = []
  10. db = SimpleNamespace(commit=lambda: events.append('commit'),
  11. rollback=lambda: events.append('rollback'),
  12. close=lambda: events.append('close'))
  13. monkeypatch.setattr(task, 'SessionLocal', lambda: db)
  14. monkeypatch.setattr(task, 'scan_cert_expiry', lambda session, **kwargs: events.append('scan') or 2)
  15. monkeypatch.setattr(settings, 'WECHAT_OA_ENABLED', enabled)
  16. monkeypatch.setattr(settings, 'WECHAT_OA_CERT_REMINDER_ENABLED', True)
  17. module = SimpleNamespace(enqueue_daily_cert_notices=lambda session: events.append('enqueue') or 1)
  18. monkeypatch.setitem(sys.modules, 'app.services.wechat_cert_notices', module)
  19. task.scan_pl_cert_expiry_job()
  20. assert events == (['scan', 'commit', 'enqueue', 'commit', 'close'] if enabled else
  21. ['scan', 'commit', 'close'])
  22. def test_enqueue_failure_preserves_scanned_reminders(monkeypatch):
  23. from app.tasks import pl_cert_expiry as task
  24. events = []
  25. db = SimpleNamespace(commit=lambda: events.append('commit'),
  26. rollback=lambda: events.append('rollback'),
  27. close=lambda: events.append('close'))
  28. monkeypatch.setattr(task, 'SessionLocal', lambda: db)
  29. monkeypatch.setattr(task, 'scan_cert_expiry', lambda session, **kwargs: events.append('scan') or 2)
  30. monkeypatch.setattr(settings, 'WECHAT_OA_ENABLED', True)
  31. monkeypatch.setattr(settings, 'WECHAT_OA_CERT_REMINDER_ENABLED', True)
  32. def fail(session):
  33. events.append('enqueue')
  34. raise RuntimeError('queue unavailable')
  35. monkeypatch.setitem(sys.modules, 'app.services.wechat_cert_notices',
  36. SimpleNamespace(enqueue_daily_cert_notices=fail))
  37. with pytest.raises(RuntimeError):
  38. task.scan_pl_cert_expiry_job()
  39. assert events == ['scan', 'commit', 'enqueue', 'rollback', 'close']
  40. def test_daily_job_uses_explicit_shanghai_configured_time(monkeypatch):
  41. import app.tasks as tasks
  42. jobs = {}
  43. scheduler = SimpleNamespace(running=False, start=lambda: None,
  44. add_job=lambda function, trigger, **kwargs: jobs.update({kwargs['id']: kwargs}))
  45. monkeypatch.setattr(tasks, 'scheduler', scheduler)
  46. monkeypatch.setattr(settings, 'WECHAT_OA_CERT_REMINDER_HOUR', 9)
  47. monkeypatch.setattr(settings, 'WECHAT_OA_CERT_REMINDER_MINUTE', 30)
  48. tasks.init_scheduled_tasks(None)
  49. job = jobs['scan_pl_cert_expiry']
  50. assert job['hour'] == 9
  51. assert job['minute'] == 30
  52. assert job['timezone'] == 'Asia/Shanghai'
  53. assert job['max_instances'] == 1
  54. assert job['coalesce'] is True
  55. def test_scan_uses_shanghai_day_even_when_host_is_previous_day(monkeypatch):
  56. from datetime import datetime, timezone, date
  57. from app.tasks import pl_cert_expiry as task
  58. captured = []
  59. class Clock:
  60. @staticmethod
  61. def now(tz):
  62. return datetime(2026, 10, 26, 17, tzinfo=timezone.utc).astimezone(tz)
  63. monkeypatch.setattr(task, 'datetime', Clock)
  64. monkeypatch.setattr(settings, 'WECHAT_OA_ENABLED', False)
  65. monkeypatch.setattr(task, 'SessionLocal', lambda: SimpleNamespace(
  66. commit=lambda: None, rollback=lambda: None, close=lambda: None))
  67. monkeypatch.setattr(task, 'scan_cert_expiry', lambda db, *, today: captured.append(today) or 0)
  68. task.scan_pl_cert_expiry_job()
  69. assert captured == [date(2026, 10, 27)]
  70. def test_default_certificate_scan_is_daily_at_ten_shanghai():
  71. from app.core.config import Settings
  72. assert Settings.model_fields['WECHAT_OA_CERT_REMINDER_HOUR'].default == 10
  73. assert Settings.model_fields['WECHAT_OA_CERT_REMINDER_MINUTE'].default == 0