test_point_settings.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. from __future__ import annotations
  2. from types import SimpleNamespace
  3. from unittest.mock import AsyncMock
  4. import pytest
  5. from pyrogram.types import ReplyKeyboardMarkup, ReplyKeyboardRemove
  6. async def test_enabling_checkin_button_sends_hideable_keyboard(
  7. app_modules, monkeypatch
  8. ):
  9. points = app_modules.load("wbb.utils.dbpoints")
  10. settings = app_modules.load("wbb.services.point_settings")
  11. await points.set_point_rules(
  12. -100, {"enabled": True, "checkin_enabled": True}
  13. )
  14. send_message = AsyncMock(return_value=SimpleNamespace(id=1))
  15. monkeypatch.setattr(settings.app, "send_message", send_message)
  16. rules = await settings.apply_point_rules(
  17. -100, {"checkin_button_enabled": True}
  18. )
  19. assert rules["checkin_button_enabled"] is True
  20. assert send_message.await_count == 2
  21. remove_call, keyboard_call = send_message.await_args_list
  22. assert isinstance(remove_call.kwargs["reply_markup"], ReplyKeyboardRemove)
  23. chat_id, text = keyboard_call.args
  24. reply_markup = keyboard_call.kwargs["reply_markup"]
  25. assert chat_id == -100
  26. assert "签到快捷按钮已开启" in text
  27. assert isinstance(reply_markup, ReplyKeyboardMarkup)
  28. assert reply_markup.is_persistent is False
  29. assert reply_markup.resize_keyboard is True
  30. assert reply_markup.one_time_keyboard is True
  31. assert reply_markup.keyboard[0][0].text == "签到"
  32. stored = await points.rulesdb.find_one({"chat_id": -100})
  33. assert stored["checkin_keyboard_version"] == settings.CHECKIN_KEYBOARD_VERSION
  34. async def test_checkin_button_sync_is_idempotent_and_follows_points_state(
  35. app_modules, monkeypatch
  36. ):
  37. points = app_modules.load("wbb.utils.dbpoints")
  38. settings = app_modules.load("wbb.services.point_settings")
  39. await points.set_point_rules(
  40. -100,
  41. {
  42. "enabled": True,
  43. "checkin_enabled": True,
  44. "checkin_button_enabled": True,
  45. },
  46. )
  47. send_message = AsyncMock(return_value=SimpleNamespace(id=1))
  48. monkeypatch.setattr(settings.app, "send_message", send_message)
  49. await settings.apply_point_rules(-100, {"checkin_button_enabled": True})
  50. send_message.assert_not_awaited()
  51. rules = await settings.apply_point_rules(-100, {"enabled": False})
  52. assert rules["checkin_button_enabled"] is True
  53. reply_markup = send_message.await_args.kwargs["reply_markup"]
  54. assert isinstance(reply_markup, ReplyKeyboardRemove)
  55. async def test_checkin_button_send_failure_rolls_back_rule(app_modules, monkeypatch):
  56. points = app_modules.load("wbb.utils.dbpoints")
  57. settings = app_modules.load("wbb.services.point_settings")
  58. await points.set_point_rules(
  59. -100, {"enabled": True, "checkin_enabled": True}
  60. )
  61. monkeypatch.setattr(
  62. settings.app,
  63. "send_message",
  64. AsyncMock(side_effect=RuntimeError("telegram unavailable")),
  65. )
  66. with pytest.raises(points.PointsError, match="无法更新群底部签到按钮"):
  67. await settings.apply_point_rules(
  68. -100, {"checkin_button_enabled": True}
  69. )
  70. rules = await points.get_point_rules(-100)
  71. assert rules["checkin_button_enabled"] is False
  72. async def test_active_checkin_keyboards_are_migrated_only_once(
  73. app_modules, monkeypatch
  74. ):
  75. points = app_modules.load("wbb.utils.dbpoints")
  76. settings = app_modules.load("wbb.services.point_settings")
  77. await points.set_point_rules(
  78. -100,
  79. {
  80. "enabled": True,
  81. "checkin_enabled": True,
  82. "checkin_button_enabled": True,
  83. },
  84. )
  85. send_message = AsyncMock(
  86. side_effect=[
  87. SimpleNamespace(id=1),
  88. SimpleNamespace(id=2),
  89. ]
  90. )
  91. monkeypatch.setattr(settings.app, "send_message", send_message)
  92. refreshed = await settings.refresh_active_checkin_keyboards()
  93. assert refreshed == 1
  94. assert send_message.await_count == 2
  95. assert isinstance(
  96. send_message.await_args_list[0].kwargs["reply_markup"],
  97. ReplyKeyboardRemove,
  98. )
  99. assert isinstance(
  100. send_message.await_args_list[1].kwargs["reply_markup"],
  101. ReplyKeyboardMarkup,
  102. )
  103. stored = await points.rulesdb.find_one({"chat_id": -100})
  104. assert stored["checkin_keyboard_version"] == settings.CHECKIN_KEYBOARD_VERSION
  105. send_message.reset_mock()
  106. assert await settings.refresh_active_checkin_keyboards() == 0
  107. send_message.assert_not_awaited()