From 1a6d8d07d0003178e761c129d08ccd859a8902c8 Mon Sep 17 00:00:00 2001 From: Jeffrey Sperling Date: Mon, 13 Apr 2026 11:54:49 -0700 Subject: [PATCH] fix(bird_x): skip all-None engagement dicts When a tweet has no engagement metrics, _first_of() returns None for every key, producing {"likes": None, "reposts": None, ...}. This all-None dict propagates to signals.py where it is treated as "data exists but is zero" rather than "no data available." Return None instead when every engagement field is missing. --- scripts/lib/bird_x.py | 2 +- tests/test_bird_x.py | 28 +++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/scripts/lib/bird_x.py b/scripts/lib/bird_x.py index 9ab906d..efd0a0b 100644 --- a/scripts/lib/bird_x.py +++ b/scripts/lib/bird_x.py @@ -460,7 +460,7 @@ def parse_bird_response(response: Dict[str, Any], query: str = "") -> List[Dict[ "url": url, "author_handle": author_handle.lstrip("@"), "date": date, - "engagement": engagement, + "engagement": engagement if any(v is not None for v in engagement.values()) else None, "why_relevant": "", # Bird doesn't provide relevance explanations "relevance": _compute_relevance(query, str(tweet.get("text", ""))) if query else 0.7, } diff --git a/tests/test_bird_x.py b/tests/test_bird_x.py index f85708c..c436908 100644 --- a/tests/test_bird_x.py +++ b/tests/test_bird_x.py @@ -175,7 +175,7 @@ class TestVendoredBirdRuntime(unittest.TestCase): } ] items = parse_bird_response(tweets, "test query") - self.assertIsNone(items[0]["engagement"]["likes"]) + self.assertIsNone(items[0]["engagement"]) def test_fallback_to_second_key(self): tweets = [ @@ -203,6 +203,32 @@ class TestVendoredBirdRuntime(unittest.TestCase): items = parse_bird_response(tweets, "test query") self.assertEqual(0, items[0]["engagement"]["likes"]) + def test_engagement_none_when_all_fields_missing(self): + """All-None engagement dict should become None, not propagate.""" + tweets = [ + { + "id": "1", + "text": "test", + "permanent_url": "https://x.com/u/status/1", + } + ] + items = parse_bird_response(tweets, "test query") + self.assertIsNone(items[0]["engagement"]) + + def test_engagement_preserved_when_any_field_present(self): + """Engagement dict kept when at least one metric exists.""" + tweets = [ + { + "id": "1", + "text": "test", + "permanent_url": "https://x.com/u/status/1", + "likeCount": 5, + } + ] + items = parse_bird_response(tweets, "test query") + self.assertIsNotNone(items[0]["engagement"]) + self.assertEqual(5, items[0]["engagement"]["likes"]) + if __name__ == "__main__": unittest.main()