Two minor faults found during the GNews capture/prioritisation diagnostic: 1. Hyphens/dashes reached the GNews query verbatim. '-' is GNews's exclusion operator, so a token like "El-Sayed" returned HTTP 400 and wasted a query. _PUNCT_RE now strips '-', en dash and em dash to spaces. 2. The per-cycle GNews budget counter incremented in evaluate() before get_sentiment() checked the API key, so with no key configured the [CYCLE SUMMARY] reported a phantom "gnews_queries_used: 5/5" with zero real requests. Added NewsClient.enabled and gated the GNews block on it; with no key the counter stays 0/5 and no spurious SKIP_GNEWS_PRIORITY is logged. No behaviour change when a key is present. Prioritisation itself was confirmed correct and is left untouched: politics markets are sorted by gnews_priority DESC and prior-extreme markets return before the budget is consumed, so no query is ever spent on a market that cannot trade. Tests: tests/test_news_query.py (4 new); full suite 66 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
78 lines
3.0 KiB
Python
78 lines
3.0 KiB
Python
"""Tests for the GNews layer minor fixes.
|
||
|
||
Two faults found during the GNews capture/prioritisation diagnostic:
|
||
|
||
1. Hyphens/dashes in a market question reached the GNews query verbatim and,
|
||
because '-' is GNews's exclusion operator, produced HTTP 400
|
||
(e.g. "Abdul El-Sayed Michigan Democratic Primary").
|
||
|
||
2. The per-cycle GNews budget counter incremented in evaluate() *before*
|
||
get_sentiment() checked the API key, so with no key configured the
|
||
[CYCLE SUMMARY] reported a phantom "gnews_queries_used: 5/5" even though
|
||
zero real requests left the process.
|
||
"""
|
||
import asyncio
|
||
|
||
from bot.data.news import NewsClient
|
||
from bot.data.external import ExternalSignals
|
||
from bot.data.polymarket import Market
|
||
from bot.strategy.bayesian import BayesianStrategy
|
||
|
||
|
||
# ── Fix 1: query sanitisation ────────────────────────────────────────────────
|
||
|
||
def test_build_query_strips_hyphen_that_breaks_gnews():
|
||
q = NewsClient._build_query(
|
||
"Will Abdul El-Sayed win the 2026 Michigan Democratic Primary?"
|
||
)
|
||
assert "-" not in q # the exclusion operator must be gone
|
||
assert "El-Sayed" not in q
|
||
assert "Sayed" in q # the meaningful token survives as its own word
|
||
|
||
|
||
def test_build_query_strips_unicode_dashes():
|
||
q = NewsClient._build_query("Trump–Putin summit — final outcome")
|
||
assert "–" not in q and "—" not in q
|
||
assert "Trump" in q and "Putin" in q
|
||
|
||
|
||
# ── Fix 2: enabled property + budget accounting ──────────────────────────────
|
||
|
||
def test_enabled_reflects_api_key(monkeypatch):
|
||
monkeypatch.delenv("GNEWS_API_KEY", raising=False)
|
||
assert NewsClient().enabled is False
|
||
monkeypatch.setenv("GNEWS_API_KEY", "deadbeefdeadbeefdeadbeefdeadbeef")
|
||
assert NewsClient().enabled is True
|
||
|
||
|
||
def _politics_market() -> Market:
|
||
return Market(
|
||
id="m1", condition_id="c1",
|
||
question="Will candidate X win the 2026 governor election?",
|
||
yes_token_id="y", no_token_id="n",
|
||
yes_price=0.50, no_price=0.50, volume_24h=10_000.0,
|
||
end_date="2026-07-15T00:00:00Z", active=True, category="politics",
|
||
)
|
||
|
||
|
||
def _signals() -> ExternalSignals:
|
||
return ExternalSignals(
|
||
btc_price=1.0, btc_change_24h=0.0, eth_price=1.0, eth_change_24h=0.0,
|
||
btc_dominance=50.0, fear_greed_index=50, fear_greed_label="neutral",
|
||
total_market_cap_change=0.0, valid=True,
|
||
)
|
||
|
||
|
||
def test_disabled_news_consumes_no_gnews_budget(monkeypatch):
|
||
"""Regression: no API key → gnews_queries_used stays 0 (was a phantom 1+)."""
|
||
monkeypatch.delenv("GNEWS_API_KEY", raising=False)
|
||
news = NewsClient()
|
||
assert news.enabled is False
|
||
|
||
strategy = BayesianStrategy(news=news, manifold=None, db=None)
|
||
strategy.reset_cycle()
|
||
asyncio.run(
|
||
strategy.evaluate(_politics_market(), _signals(), occupied_families=set())
|
||
)
|
||
assert strategy.get_cycle_stats()["gnews_queries_used"] == 0
|