"""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