mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-10-06 07:54:38 +01:00
Make IRC less spammy and require a bot name for conversatons (#1065)
First step towards fixing the friction created by shelfmark in #997
This commit is contained in:
+102
-1
@@ -84,11 +84,27 @@ def test_search_no_dcc_offer_releases_connection_and_caches_empty_result(monkeyp
|
||||
self.channel = channel
|
||||
self.message = message
|
||||
|
||||
def wait_for_dcc(self, *, timeout: float, result_type: bool) -> None:
|
||||
def wait_for_dcc(
|
||||
self, *, timeout: float, result_type: bool, expected_senders: object = None
|
||||
) -> None:
|
||||
return None
|
||||
|
||||
client = FakeClient()
|
||||
|
||||
# A search bot is required; make config report one so the channel send path runs.
|
||||
monkeypatch.setattr(
|
||||
irc_source,
|
||||
"_config_text",
|
||||
lambda key: {
|
||||
"IRC_SERVER": "irc.example.net",
|
||||
"IRC_CHANNEL": "ebooks",
|
||||
"IRC_NICK": "tester",
|
||||
"IRC_SEARCH_BOT": "search",
|
||||
}.get(key, ""),
|
||||
)
|
||||
# Ensure no leftover cooldown entry from a previous test blocks the send.
|
||||
irc_source._recent_query_times.clear()
|
||||
|
||||
monkeypatch.setattr(source, "is_available", lambda: True)
|
||||
monkeypatch.setattr(irc_source, "_enforce_rate_limit", lambda: None)
|
||||
monkeypatch.setattr(irc_source, "_emit_status", lambda *_args, **_kwargs: None)
|
||||
@@ -137,3 +153,88 @@ def test_search_no_dcc_offer_releases_connection_and_caches_empty_result(monkeyp
|
||||
"online_servers": ["AudioBot"],
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def test_search_without_search_bot_never_posts_to_channel(monkeypatch):
|
||||
"""A bare (unaddressed) query must never reach the channel; refuse to connect."""
|
||||
import shelfmark.release_sources.irc.source as irc_source
|
||||
|
||||
source = IRCReleaseSource()
|
||||
|
||||
# Force is_available True so we exercise the in-search guard (defense in depth).
|
||||
monkeypatch.setattr(source, "is_available", lambda: True)
|
||||
monkeypatch.setattr(irc_source, "_emit_status", lambda *_args, **_kwargs: None)
|
||||
monkeypatch.setattr(irc_source, "_enforce_rate_limit", lambda: None)
|
||||
monkeypatch.setattr(
|
||||
"shelfmark.release_sources.irc.cache.get_cached_results",
|
||||
lambda provider, provider_id, *, content_type: None,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
irc_source,
|
||||
"_config_text",
|
||||
lambda key: {
|
||||
"IRC_SERVER": "irc.example.net",
|
||||
"IRC_CHANNEL": "ebooks",
|
||||
"IRC_NICK": "tester",
|
||||
"IRC_SEARCH_BOT": "", # not configured
|
||||
}.get(key, ""),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"shelfmark.release_sources.irc.connection_manager.connection_manager.get_connection",
|
||||
lambda **_kwargs: (_ for _ in ()).throw(
|
||||
AssertionError("must not connect/post without a search bot")
|
||||
),
|
||||
)
|
||||
|
||||
book = BookMetadata(provider="hardcover", provider_id="nobot", title="No Bot")
|
||||
plan = SimpleNamespace(primary_query="No Bot")
|
||||
|
||||
assert source.search(book, plan) == []
|
||||
|
||||
|
||||
def test_search_on_cooldown_returns_cache_without_reposting(monkeypatch):
|
||||
"""An identical query within the cooldown window must not be re-posted to the channel."""
|
||||
import shelfmark.release_sources.irc.source as irc_source
|
||||
|
||||
source = IRCReleaseSource()
|
||||
cached_release = Release(source="irc", source_id="cached-line", title="Cached Result")
|
||||
|
||||
monkeypatch.setattr(source, "is_available", lambda: True)
|
||||
monkeypatch.setattr(irc_source, "_emit_status", lambda *_args, **_kwargs: None)
|
||||
monkeypatch.setattr(irc_source, "_enforce_rate_limit", lambda: None)
|
||||
monkeypatch.setattr(
|
||||
irc_source,
|
||||
"_config_text",
|
||||
lambda key: {
|
||||
"IRC_SERVER": "irc.example.net",
|
||||
"IRC_CHANNEL": "ebooks",
|
||||
"IRC_NICK": "tester",
|
||||
"IRC_SEARCH_BOT": "search",
|
||||
}.get(key, ""),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"shelfmark.release_sources.irc.cache.get_cached_results",
|
||||
lambda provider, provider_id, *, content_type: {
|
||||
"releases": [cached_release],
|
||||
"online_servers": ["AudioBot"],
|
||||
},
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"shelfmark.release_sources.irc.connection_manager.connection_manager.get_connection",
|
||||
lambda **_kwargs: (_ for _ in ()).throw(
|
||||
AssertionError("cooldown should skip IRC connection")
|
||||
),
|
||||
)
|
||||
|
||||
# Pretend the same query was just posted to the channel.
|
||||
irc_source._recent_query_times.clear()
|
||||
irc_source._record_query_sent(irc_source._query_cooldown_key("ebooks", "Cooldown Book"))
|
||||
|
||||
book = BookMetadata(provider="hardcover", provider_id="cd", title="Cooldown Book")
|
||||
plan = SimpleNamespace(primary_query="Cooldown Book")
|
||||
|
||||
# expand_search=True bypasses the normal top-level cache, forcing the cooldown path.
|
||||
releases = source.search(book, plan, expand_search=True)
|
||||
|
||||
assert releases == [cached_release]
|
||||
assert source._online_servers == {"AudioBot"}
|
||||
|
||||
Reference in New Issue
Block a user