Discord picker: per-bot permission status + owner's preferred bot (#225 S4) — merge after S3 #250
@@ -87,6 +87,16 @@ def _channel_state(rows: list[dict], enabled: bool) -> str:
|
||||
return "no_bot"
|
||||
|
||||
|
||||
def _checked_at(snaps: dict) -> str:
|
||||
"""When Discord was last actually asked: the OLDEST cached snapshot behind
|
||||
this answer (a denied result is cached for 10 min), so the picker's
|
||||
"Permissions checked N ago" never calls a stale answer fresh (server-26#225
|
||||
S4). No snapshot (check off, no member bots) = now."""
|
||||
times = [s.fetched_at for s in snaps.values() if s is not None and getattr(s, "fetched_at", None)]
|
||||
ts = min(times) if times else time.time()
|
||||
return datetime.fromtimestamp(ts, timezone.utc).isoformat()
|
||||
|
||||
|
||||
async def voice_check(*, guild_id: str, org_id: Optional[str], node_id: Optional[str],
|
||||
channels: list[dict], channel_id: Optional[str], refresh: bool,
|
||||
with_token_ids: bool) -> dict:
|
||||
@@ -171,7 +181,7 @@ async def voice_check(*, guild_id: str, org_id: Optional[str], node_id: Optional
|
||||
"guild_id": guild_id,
|
||||
"node_id": node_id,
|
||||
"enabled": enabled,
|
||||
"checked_at": datetime.now(timezone.utc).isoformat(),
|
||||
"checked_at": _checked_at(snaps),
|
||||
"refreshed": refresh,
|
||||
"channels": out_channels,
|
||||
"invite": invite,
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
"""
|
||||
voice-check's ``checked_at`` is when Discord was last asked — the oldest
|
||||
cached snapshot behind the answer — not the time of the HTTP response, so the
|
||||
picker's "Permissions checked N ago" footer never calls a 10-minute-old
|
||||
denied result fresh (server-26#225 S4).
|
||||
"""
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
from app.internal import discord_rest
|
||||
from app.routers import discord_checks as checks
|
||||
from tests.test_discord_perm_check import GUILD, OWNER, _snap, _token, fs, run # noqa: F401 (fs = fixture)
|
||||
|
||||
|
||||
def _age(out) -> float:
|
||||
return time.time() - datetime.fromisoformat(out["checked_at"]).timestamp()
|
||||
|
||||
|
||||
def test_checked_at_is_the_oldest_snapshot_not_now(fs, monkeypatch):
|
||||
_token(fs, "t1"); _token(fs, "t2")
|
||||
ages = {"t1": 30, "t2": 420}
|
||||
|
||||
async def _old(token_doc, guild_id, *, refresh=False):
|
||||
s = _snap(token_doc["token_id"])
|
||||
s.fetched_at = time.time() - (0 if refresh else ages[token_doc["token_id"]])
|
||||
return s
|
||||
monkeypatch.setattr(discord_rest, "guild_snapshot", _old)
|
||||
|
||||
out = run(checks.node_voice_check("n1", GUILD, refresh=0, channel_id=None, decoded=OWNER))
|
||||
assert 415 <= _age(out) <= 430
|
||||
out = run(checks.node_voice_check("n1", GUILD, refresh=1, channel_id=None, decoded=OWNER))
|
||||
assert _age(out) < 5
|
||||
|
||||
|
||||
def test_checked_at_without_snapshots_is_now(fs):
|
||||
out = run(checks.node_voice_check("n1", GUILD, refresh=0, channel_id=None, decoded=OWNER)) # no bots
|
||||
assert _age(out) < 5
|
||||
Reference in New Issue
Block a user