test(discord): trim obfuscation tests to two invariants + one backfill regression

Seven near-identical predicate tests collapse into one invariant test
(flag OR sentinel name; neither on a normal channel; no flags attribute
is not obfuscated) plus the directory-filter test, per the repo's
<=2-invariant-tests-per-fix rule. The explicit-id backfill path gets its
own regression test in the existing backfill harness (fails on the
unfixed code, verified by sabotage).
This commit is contained in:
teknium1
2026-09-14 18:38:54 -07:00
committed by Teknium
parent 624777617c
commit d5cc6bd6fc
2 changed files with 47 additions and 75 deletions

View File

@@ -1,13 +1,7 @@
"""Tests for Discord channel-obfuscation handling.
"""Discord channel obfuscation (Aug 2026 privacy change, HTTP omission mandatory Nov 16 2026):
channels a bot lacks VIEW_CHANNEL on arrive named "___hidden___" with flag 1 << 17 set.
Enumeration sites must skip them. #90154"""
Discord's August 2026 privacy change ("Channel Obfuscation") dispatches
channels a bot lacks VIEW_CHANNEL on with the name "___hidden___", flag
1 << 17 (CHANNEL_OBFUSCATED) set, and sensitive fields nulled. Enumeration
sites (channel directory, missed-message backfill) must skip these
placeholders — the HTTP API omits them entirely starting Nov 16, 2026.
"""
import unittest
from types import SimpleNamespace
from gateway.platforms.helpers import (
@@ -18,72 +12,35 @@ from gateway.platforms.helpers import (
def _channel(name="general", flag_value=0, cid=123):
return SimpleNamespace(
id=cid,
name=name,
flags=SimpleNamespace(value=flag_value),
return SimpleNamespace(id=cid, name=name, flags=SimpleNamespace(value=flag_value))
def test_flag_or_sentinel_name_marks_obfuscated():
assert is_discord_channel_obfuscated(_channel(name="secret", flag_value=DISCORD_CHANNEL_OBFUSCATED_FLAG | (1 << 4)))
# Older discord.py builds may not surface the flag bit; the name is the fallback signal.
assert is_discord_channel_obfuscated(_channel(name=DISCORD_OBFUSCATED_CHANNEL_NAME))
assert not is_discord_channel_obfuscated(_channel())
assert not is_discord_channel_obfuscated(SimpleNamespace(id=1, name="ok")) # no flags attribute
def test_build_discord_filters_hidden_channels(monkeypatch):
from gateway import channel_directory as cd
guild = SimpleNamespace(
name="TestGuild",
text_channels=[
_channel(name="general", cid=1),
_channel(name="secret", flag_value=DISCORD_CHANNEL_OBFUSCATED_FLAG, cid=2),
_channel(name=DISCORD_OBFUSCATED_CHANNEL_NAME, cid=3),
],
forum_channels=[
_channel(name="forum-open", cid=4),
_channel(name="forum-secret", flag_value=DISCORD_CHANNEL_OBFUSCATED_FLAG, cid=5),
],
)
adapter = SimpleNamespace(_client=SimpleNamespace(guilds=[guild]))
monkeypatch.setattr(cd, "_build_from_sessions", lambda platform: [])
channels = cd._build_discord(adapter)
class TestIsDiscordChannelObfuscated(unittest.TestCase):
def test_normal_channel_not_obfuscated(self):
self.assertFalse(is_discord_channel_obfuscated(_channel()))
def test_flag_marks_obfuscated(self):
ch = _channel(name="whatever", flag_value=DISCORD_CHANNEL_OBFUSCATED_FLAG)
self.assertTrue(is_discord_channel_obfuscated(ch))
def test_flag_combined_with_other_flags(self):
ch = _channel(flag_value=DISCORD_CHANNEL_OBFUSCATED_FLAG | (1 << 4))
self.assertTrue(is_discord_channel_obfuscated(ch))
def test_sentinel_name_marks_obfuscated_without_flag(self):
# Older discord.py builds may not surface the new flag bit; the
# sentinel name is the fallback signal.
ch = _channel(name=DISCORD_OBFUSCATED_CHANNEL_NAME, flag_value=0)
self.assertTrue(is_discord_channel_obfuscated(ch))
def test_missing_flags_attribute(self):
ch = SimpleNamespace(id=1, name="ok")
self.assertFalse(is_discord_channel_obfuscated(ch))
def test_non_int_flag_value_falls_back_to_name(self):
ch = SimpleNamespace(id=1, name="ok", flags=SimpleNamespace(value=None))
self.assertFalse(is_discord_channel_obfuscated(ch))
class TestChannelDirectorySkipsObfuscated(unittest.TestCase):
def test_build_discord_filters_hidden_channels(self):
from gateway import channel_directory as cd
visible = _channel(name="general", cid=1)
hidden_flag = _channel(name="secret", flag_value=DISCORD_CHANNEL_OBFUSCATED_FLAG, cid=2)
hidden_name = _channel(name=DISCORD_OBFUSCATED_CHANNEL_NAME, cid=3)
visible_forum = _channel(name="forum-open", cid=4)
hidden_forum = _channel(
name="forum-secret", flag_value=DISCORD_CHANNEL_OBFUSCATED_FLAG, cid=5
)
guild = SimpleNamespace(
name="TestGuild",
text_channels=[visible, hidden_flag, hidden_name],
forum_channels=[visible_forum, hidden_forum],
)
adapter = SimpleNamespace(_client=SimpleNamespace(guilds=[guild]))
original = cd._build_from_sessions
cd._build_from_sessions = lambda platform: []
try:
channels = cd._build_discord(adapter)
finally:
cd._build_from_sessions = original
ids = {c["id"] for c in channels}
self.assertEqual(ids, {"1", "4"})
types = {c["id"]: c["type"] for c in channels}
self.assertEqual(types["1"], "channel")
self.assertEqual(types["4"], "forum")
if __name__ == "__main__":
unittest.main()
assert {c["id"]: c["type"] for c in channels} == {"1": "channel", "4": "forum"}

View File

@@ -458,3 +458,18 @@ async def test_iter_candidates_keeps_latest_messages_when_window_exceeds_limit(a
assert got == [2, 3, 4]
@pytest.mark.asyncio
async def test_iter_candidates_skips_obfuscated_channel_on_explicit_ids(adapter, monkeypatch):
"""A channel the bot lost VIEW_CHANNEL on (Discord obfuscation) is dropped even when
listed by explicit id — history reads on it always fail (#90154)."""
from gateway.platforms.helpers import DISCORD_CHANNEL_OBFUSCATED_FLAG
visible = FakeChannel(channel_id=1, history_messages=[make_message(message_id=11)])
hidden = FakeChannel(channel_id=2, history_messages=[make_message(message_id=22)])
hidden.name = "___hidden___"
hidden.flags = SimpleNamespace(value=DISCORD_CHANNEL_OBFUSCATED_FLAG)
adapter._client.get_channel = lambda channel_id: {1: visible, 2: hidden}[channel_id]
got = [msg.id async for msg in adapter._iter_missed_message_backfill_candidates({"1", "2"})]
assert got == [11]