feat: add telegram notification channel with outbox service and per-user preferences
Extend the notification system with a third channel (telegram) alongside existing in_app and push channels. Add `telegram_enabled` column to `notification_preferences` table, update `NOTIFICATION_CHANNELS` and `_NOTIFICATION_CHANNEL_COLUMNS` mappings, and set telegram default to off (`_NOTIFICATION_CHANNEL_DEFAULTS`). Create `telegram_outbox` table with columns for uid, user_uid, chat_id, text, status, attempts, created_at, and sent_at, plus an index on status/id for efficient polling. Register `TelegramOutboxService` in the service manager lifecycle. Update API documentation strings to describe the new channel and its pairing requirement. Extend admin notification defaults view to include telegram column. Pass `notif_telegram_paired` flag to profile template based on `telegram_store.is_paired()` check. Update `NotificationPrefForm` and `NotificationDefaultForm` model literals to accept "telegram" as a valid channel value.
This commit is contained in:
@@ -70,12 +70,38 @@ def test_state_returns_farm_json(app_server, seeded_db):
|
||||
assert len(farm["quests"]) == economy.DAILY_QUEST_COUNT
|
||||
|
||||
|
||||
def _set_farm(username, **fields):
|
||||
user = get_table("users").find_one(username=username)
|
||||
farm = store.get_farm(user["uid"])
|
||||
get_table("game_farms").update({"uid": farm["uid"], **fields}, ["uid"])
|
||||
|
||||
|
||||
def test_leaderboard_is_public_json(app_server, seeded_db):
|
||||
response = requests.get(f"{BASE_URL}/game/leaderboard", headers=JSON)
|
||||
assert response.status_code == 200
|
||||
assert "entries" in response.json()
|
||||
|
||||
|
||||
def test_leaderboard_entries_carry_score_and_prestige(app_server, seeded_db):
|
||||
session, name = _signup()
|
||||
_reset_farm(name)
|
||||
_set_farm(name, prestige=50, total_harvests=20, ci_tier=3)
|
||||
response = requests.get(f"{BASE_URL}/game/leaderboard", headers=JSON)
|
||||
assert response.status_code == 200
|
||||
entries = response.json()["entries"]
|
||||
assert entries
|
||||
scores = [entry["score"] for entry in entries]
|
||||
assert scores == sorted(scores, reverse=True)
|
||||
for entry in entries:
|
||||
assert "score" in entry and "prestige" in entry
|
||||
mine = next(entry for entry in entries if entry["username"] == name)
|
||||
assert mine["prestige"] == 50
|
||||
assert mine["score"] == economy.farm_score(store.get_farm(
|
||||
get_table("users").find_one(username=name)["uid"]
|
||||
))
|
||||
assert mine["score"] >= 50 * economy.SCORE_PRESTIGE
|
||||
|
||||
|
||||
def test_plant_returns_updated_farm(app_server, seeded_db):
|
||||
session, name = _signup()
|
||||
_reset_farm(name)
|
||||
|
||||
Reference in New Issue
Block a user