Add Telegram topic binding command

This commit is contained in:
2569718930@qq.com
2026-06-14 04:48:58 +08:00
parent e6c99c946a
commit e74dfb4953
6 changed files with 285 additions and 11 deletions
+85
View File
@@ -11,6 +11,7 @@ class DummyBot:
self.approved_join_requests = []
self.declined_join_requests = []
self.callback_handlers = []
self.chat_member_status = "administrator"
def reply_to(self, message, text, parse_mode=None, disable_web_page_preview=None, **kwargs):
self.replies.append(
@@ -65,6 +66,9 @@ class DummyBot:
def decline_chat_join_request(self, chat_id, user_id):
self.declined_join_requests.append({"chat_id": chat_id, "user_id": user_id})
def get_chat_member(self, chat_id, user_id):
return SimpleNamespace(status=self.chat_member_status)
def _message(text: str):
return SimpleNamespace(
@@ -74,6 +78,15 @@ def _message(text: str):
)
def _topic_message(text: str, *, thread_id: int = 13102):
return SimpleNamespace(
text=text,
from_user=SimpleNamespace(id=1, username="admin", first_name="Admin"),
chat=SimpleNamespace(id=-1003927451869, type="supergroup"),
message_thread_id=thread_id,
)
def test_basic_handler_diag_returns_html():
runtime = RuntimeStatus(
started_at="2026-03-12 00:00:00 UTC",
@@ -100,6 +113,78 @@ def test_basic_handler_diag_returns_html():
assert "Bot 启动诊断" in bot.replies[0]["text"]
def test_bindtopic_records_current_forum_thread(monkeypatch):
import src.bot.handlers.basic as basic
saved = []
monkeypatch.setenv("TELEGRAM_CHAT_IDS", "-1003927451869")
monkeypatch.setenv("POLYWEATHER_TELEGRAM_GROUP_ID", "-1003927451869")
monkeypatch.setattr(
basic,
"record_city_thread_id",
lambda city, thread_id: saved.append((city, thread_id))
or {"city": city, "thread_id": thread_id},
)
bot = DummyBot()
handler = BasicCommandHandler(
bot=bot,
io_layer=SimpleNamespace(
build_welcome_text=lambda: "WELCOME",
build_points_rank_text=lambda _user: "TOP",
),
runtime_status_provider=lambda: RuntimeStatus(
started_at="2026-03-12 00:00:00 UTC",
loops=[],
command_access_mode="public",
protected_commands=[],
required_group_chat_id="-1003927451869",
),
)
result = handler.handle_bindtopic(_topic_message("/bindtopic seoul"))
assert result == "bound"
assert saved == [("seoul", 13102)]
assert "seoul" in bot.replies[0]["text"].lower()
assert "13102" in bot.replies[0]["text"]
def test_bindtopic_rejects_non_admin(monkeypatch):
import src.bot.handlers.basic as basic
saved = []
monkeypatch.setenv("TELEGRAM_CHAT_IDS", "-1003927451869")
monkeypatch.setattr(
basic,
"record_city_thread_id",
lambda city, thread_id: saved.append((city, thread_id)),
)
bot = DummyBot()
bot.chat_member_status = "member"
handler = BasicCommandHandler(
bot=bot,
io_layer=SimpleNamespace(
build_welcome_text=lambda: "WELCOME",
build_points_rank_text=lambda _user: "TOP",
),
runtime_status_provider=lambda: RuntimeStatus(
started_at="2026-03-12 00:00:00 UTC",
loops=[],
command_access_mode="public",
protected_commands=[],
required_group_chat_id="-1003927451869",
),
)
result = handler.handle_bindtopic(_topic_message("/bindtopic seoul"))
assert result == "unauthorized"
assert saved == []
assert "管理员" in bot.replies[0]["text"]
def test_start_bind_token_binds_telegram_to_web_account():
bot = DummyBot()
consumed = []
+13 -3
View File
@@ -5,6 +5,7 @@ from src.utils.telegram_push import (
_build_airport_status_message,
_compute_slope_15m,
_due_airport_cities,
normalize_airport_push_city,
_parse_observation_time_epoch,
_run_high_freq_airport_cycle,
_telegram_push_language,
@@ -165,9 +166,14 @@ def test_singapore_is_in_telegram_push_city_lists():
assert HIGH_FREQ_AIRPORT_ICAO["singapore"] == "WSSS"
def test_shenzhen_is_not_in_airport_push_city_lists():
assert "shenzhen" not in HIGH_FREQ_AIRPORT_CITIES
assert "shenzhen" not in HIGH_FREQ_AIRPORT_ICAO
def test_shenzhen_lau_fau_shan_topic_is_in_airport_push_city_lists():
assert normalize_airport_push_city("LauFauShan") == "shenzhen"
assert normalize_airport_push_city("HongKong") == "hong kong"
assert normalize_airport_push_city("NewYork") == "new york"
assert normalize_airport_push_city("LosAngeles") == "los angeles"
assert normalize_airport_push_city("SanFrancisco") == "san francisco"
assert "shenzhen" in HIGH_FREQ_AIRPORT_CITIES
assert HIGH_FREQ_AIRPORT_ICAO["shenzhen"] == "LFS"
def test_china_airport_push_defaults_to_one_minute_city_interval():
@@ -182,6 +188,10 @@ def test_china_airport_push_defaults_to_one_minute_city_interval():
assert _AIRPORT_PUSH_INTERVAL["wuhan"] == 60
def test_shenzhen_lau_fau_shan_push_uses_hko_ten_minute_interval():
assert _AIRPORT_PUSH_INTERVAL["shenzhen"] == 600
def test_airport_push_prioritizes_china_markets():
due = _due_airport_cities(
{"paris", "shanghai", "wuhan", "ankara", "beijing"},