conftest.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. from __future__ import annotations
  2. import importlib
  3. import sys
  4. import types
  5. from pathlib import Path
  6. from types import SimpleNamespace
  7. import pytest
  8. from mongomock_motor import AsyncMongoMockClient
  9. from pyrogram.enums import ChatMemberStatus
  10. ROOT = Path(__file__).resolve().parents[1]
  11. class FakeTelegramApp:
  12. def __init__(self) -> None:
  13. self.members: dict[tuple[int, int], object] = {}
  14. self.chats: dict[int, object] = {}
  15. self.histories: dict[int, list[object]] = {}
  16. self.sent_messages: list[tuple[int, str]] = []
  17. self.sent_photos: list[tuple[int, object, str]] = []
  18. self.edited_messages: list[tuple[int, int, str]] = []
  19. self.pinned_messages: list[tuple[int, int]] = []
  20. self.unpinned_messages: list[tuple[int, int]] = []
  21. self.deleted_messages: list[tuple[int, int]] = []
  22. async def get_chat_member(self, chat_id: int, user_id: int):
  23. member = self.members.get((int(chat_id), int(user_id)))
  24. if member is not None:
  25. return member
  26. return SimpleNamespace(
  27. status=ChatMemberStatus.MEMBER,
  28. privileges=None,
  29. user=SimpleNamespace(
  30. id=int(user_id),
  31. username=None,
  32. first_name=str(user_id),
  33. last_name=None,
  34. is_bot=False,
  35. is_deleted=False,
  36. ),
  37. custom_title=None,
  38. until_date=None,
  39. )
  40. async def get_chat(self, chat_id: int):
  41. chat = self.chats.get(int(chat_id))
  42. if chat is None:
  43. raise ValueError("chat not found")
  44. return chat
  45. async def get_chat_history(self, chat_id: int, limit: int = 100):
  46. for message in self.histories.get(int(chat_id), [])[:limit]:
  47. yield message
  48. async def send_message(self, chat_id: int, text: str, **_kwargs):
  49. self.sent_messages.append((int(chat_id), text))
  50. return SimpleNamespace(chat=SimpleNamespace(id=int(chat_id)), id=len(self.sent_messages))
  51. async def send_photo(self, chat_id: int, photo: object, caption: str = "", **_kwargs):
  52. self.sent_photos.append((int(chat_id), photo, caption))
  53. return SimpleNamespace(chat=SimpleNamespace(id=int(chat_id)), id=len(self.sent_photos))
  54. async def edit_message_text(
  55. self, chat_id: int, message_id: int, text: str, **_kwargs
  56. ):
  57. self.edited_messages.append((int(chat_id), int(message_id), text))
  58. return SimpleNamespace(chat=SimpleNamespace(id=int(chat_id)), id=int(message_id))
  59. async def pin_chat_message(
  60. self, chat_id: int, message_id: int, **_kwargs
  61. ) -> None:
  62. self.pinned_messages.append((int(chat_id), int(message_id)))
  63. async def unpin_chat_message(self, chat_id: int, message_id: int) -> None:
  64. self.unpinned_messages.append((int(chat_id), int(message_id)))
  65. async def delete_messages(self, chat_id: int, message_id: int) -> None:
  66. self.deleted_messages.append((int(chat_id), int(message_id)))
  67. def on_message(self, *_args, **_kwargs):
  68. return lambda function: function
  69. def on_callback_query(self, *_args, **_kwargs):
  70. return lambda function: function
  71. def on_edited_message(self, *_args, **_kwargs):
  72. return lambda function: function
  73. def on_deleted_messages(self, *_args, **_kwargs):
  74. return lambda function: function
  75. def on_chat_member_updated(self, *_args, **_kwargs):
  76. return lambda function: function
  77. @pytest.fixture
  78. def app_modules(tmp_path):
  79. previous = {
  80. name: module
  81. for name, module in sys.modules.items()
  82. if name == "wbb" or name.startswith("wbb.")
  83. }
  84. for name in list(previous):
  85. sys.modules.pop(name, None)
  86. fake_app = FakeTelegramApp()
  87. fake_wbb = types.ModuleType("wbb")
  88. fake_wbb.__path__ = [str(ROOT / "wbb")]
  89. fake_wbb.db = AsyncMongoMockClient().wbb
  90. fake_wbb.control_db = fake_wbb.db
  91. fake_wbb.app = fake_app
  92. fake_wbb.log = SimpleNamespace(info=lambda _message: None, error=lambda _message: None)
  93. fake_wbb.BOT_ID = 999
  94. fake_wbb.BOT_NAME = "Test Bot"
  95. fake_wbb.BOT_USERNAME = "test_bot"
  96. fake_wbb.BOT_PROFILE_ID = "primary"
  97. fake_wbb.BOT_PERMISSIONS = {"*"}
  98. fake_wbb.LOG_GROUP_ID = 0
  99. fake_wbb.TELEGRAM_CONNECTED = True
  100. fake_wbb.SUPERVISOR_MODE = False
  101. fake_wbb.ADMIN_BOOTSTRAP_MODE = False
  102. fake_wbb.BOT_SUPERVISOR = None
  103. fake_wbb.SUDOERS = set()
  104. fake_wbb.MOD_LOAD = []
  105. fake_wbb.MOD_NOLOAD = []
  106. fake_wbb.MESSAGE_DUMP_CHAT = 0
  107. fake_wbb.ADMIN_WEB_USERNAME = "admin"
  108. fake_wbb.ADMIN_WEB_INITIAL_PASSWORD = "qwe0.123456"
  109. fake_wbb.ADMIN_WEB_SESSION_HOURS = 12
  110. fake_wbb.ADMIN_WEB_COOKIE_SECURE = False
  111. fake_wbb.ADMIN_WEB_UPLOAD_MAX_MB = 20
  112. fake_wbb.ADMIN_WEB_HOST = "127.0.0.1"
  113. fake_wbb.ADMIN_WEB_PORT = 8088
  114. fake_wbb.SERVICE_ADDRESS_ENCRYPTION_KEY = (
  115. "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA="
  116. )
  117. fake_wbb.SERVICE_ADDRESS_RETENTION_DAYS = 7
  118. fake_wbb.SERVICE_REVIEW_QR_EXPIRY_HOURS = 24
  119. fake_wbb.SERVICE_CUSTOMER_MAX_OPEN_ORDERS = 3
  120. fake_wbb.SERVICE_CUSTOMER_DAILY_REQUEST_LIMIT = 10
  121. fake_wbb.BOT_PROFILES_PATH = str(tmp_path / "bot_profiles.json")
  122. sys.modules["wbb"] = fake_wbb
  123. def load(name: str):
  124. return importlib.import_module(name)
  125. yield SimpleNamespace(wbb=fake_wbb, app=fake_app, load=load)
  126. for name in list(sys.modules):
  127. if name == "wbb" or name.startswith("wbb."):
  128. sys.modules.pop(name, None)
  129. sys.modules.update(previous)