Fix stale test assertions and truthsocial pytest dependency
- test_models: update xAI model expectations to grok-4-1-fast (matching current XAI_POLICY_MAP) - test_openai_reddit: update fallback order assertion to gpt-4.1 (matching current MODEL_FALLBACK_ORDER) - test_codex_auth: expect 'reddit' not 'web' when no API keys (Reddit is available via public JSON fallback) - test_truthsocial: convert from pytest-style classes to unittest.TestCase, fix import path to use sys.path.insert pattern (matching all other tests)
This commit is contained in:
@@ -140,7 +140,8 @@ class TestGetAvailableSourcesWithAuth(unittest.TestCase):
|
||||
"XAI_API_KEY": None,
|
||||
}
|
||||
result = env.get_available_sources(config)
|
||||
self.assertEqual(result, "web")
|
||||
# Reddit is available via public JSON fallback even without OpenAI auth
|
||||
self.assertEqual(result, "reddit")
|
||||
|
||||
|
||||
class TestParseCodexStream(unittest.TestCase):
|
||||
|
||||
@@ -84,7 +84,7 @@ class TestSelectXAIModel(unittest.TestCase):
|
||||
"fake-key",
|
||||
policy="latest"
|
||||
)
|
||||
self.assertEqual(result, "grok-4-latest")
|
||||
self.assertEqual(result, "grok-4-1-fast")
|
||||
|
||||
def test_stable_policy(self):
|
||||
# Clear cache first to avoid interference
|
||||
@@ -94,7 +94,7 @@ class TestSelectXAIModel(unittest.TestCase):
|
||||
"fake-key",
|
||||
policy="stable"
|
||||
)
|
||||
self.assertEqual(result, "grok-4")
|
||||
self.assertEqual(result, "grok-4-1-fast")
|
||||
|
||||
def test_pinned_policy(self):
|
||||
result = models.select_xai_model(
|
||||
@@ -125,10 +125,10 @@ class TestGetModels(unittest.TestCase):
|
||||
"XAI_API_KEY": "xai-test",
|
||||
}
|
||||
mock_openai = [{"id": "gpt-5.2", "created": 1704067200}]
|
||||
mock_xai = [{"id": "grok-4-latest", "created": 1704067200}]
|
||||
mock_xai = [{"id": "grok-4-1-fast", "created": 1704067200}]
|
||||
result = models.get_models(config, mock_openai, mock_xai)
|
||||
self.assertEqual(result["openai"], "gpt-5.2")
|
||||
self.assertEqual(result["xai"], "grok-4-latest")
|
||||
self.assertEqual(result["xai"], "grok-4-1-fast")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -68,9 +68,9 @@ class TestModelFallbackOrder(unittest.TestCase):
|
||||
"""Fallback list should include gpt-4o."""
|
||||
self.assertIn("gpt-4o", MODEL_FALLBACK_ORDER)
|
||||
|
||||
def test_gpt4o_is_first(self):
|
||||
"""gpt-4o should be the first fallback option."""
|
||||
self.assertEqual(MODEL_FALLBACK_ORDER[0], "gpt-4o")
|
||||
def test_gpt41_is_first(self):
|
||||
"""gpt-4.1 should be the first fallback option."""
|
||||
self.assertEqual(MODEL_FALLBACK_ORDER[0], "gpt-4.1")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
+75
-67
@@ -1,129 +1,133 @@
|
||||
"""Tests for Truth Social source module."""
|
||||
import pytest
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from scripts.lib import truthsocial
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
|
||||
|
||||
from lib import truthsocial
|
||||
|
||||
|
||||
class TestStripHtml:
|
||||
class TestStripHtml(unittest.TestCase):
|
||||
"""Test HTML tag stripping."""
|
||||
|
||||
def test_basic_paragraph(self):
|
||||
assert truthsocial._strip_html("<p>Hello world</p>") == "Hello world"
|
||||
self.assertEqual(truthsocial._strip_html("<p>Hello world</p>"), "Hello world")
|
||||
|
||||
def test_br_tags(self):
|
||||
assert truthsocial._strip_html("Line 1<br>Line 2") == "Line 1\nLine 2"
|
||||
assert truthsocial._strip_html("Line 1<br/>Line 2") == "Line 1\nLine 2"
|
||||
assert truthsocial._strip_html("Line 1<br />Line 2") == "Line 1\nLine 2"
|
||||
self.assertEqual(truthsocial._strip_html("Line 1<br>Line 2"), "Line 1\nLine 2")
|
||||
self.assertEqual(truthsocial._strip_html("Line 1<br/>Line 2"), "Line 1\nLine 2")
|
||||
self.assertEqual(truthsocial._strip_html("Line 1<br />Line 2"), "Line 1\nLine 2")
|
||||
|
||||
def test_nested_tags(self):
|
||||
assert truthsocial._strip_html("<p>Hello <a href='#'>world</a></p>") == "Hello world"
|
||||
self.assertEqual(truthsocial._strip_html("<p>Hello <a href='#'>world</a></p>"), "Hello world")
|
||||
|
||||
def test_empty_string(self):
|
||||
assert truthsocial._strip_html("") == ""
|
||||
self.assertEqual(truthsocial._strip_html(""), "")
|
||||
|
||||
def test_no_tags(self):
|
||||
assert truthsocial._strip_html("plain text") == "plain text"
|
||||
self.assertEqual(truthsocial._strip_html("plain text"), "plain text")
|
||||
|
||||
def test_entities_preserved(self):
|
||||
assert truthsocial._strip_html("<p>& test</p>") == "& test"
|
||||
self.assertEqual(truthsocial._strip_html("<p>& test</p>"), "& test")
|
||||
|
||||
|
||||
class TestExtractCoreSubject:
|
||||
class TestExtractCoreSubject(unittest.TestCase):
|
||||
"""Test query preprocessing."""
|
||||
|
||||
def test_strips_question_prefix(self):
|
||||
assert truthsocial._extract_core_subject("what are people saying about tariffs") == "tariffs"
|
||||
self.assertEqual(truthsocial._extract_core_subject("what are people saying about tariffs"), "tariffs")
|
||||
|
||||
def test_strips_noise_words(self):
|
||||
assert truthsocial._extract_core_subject("latest trending crypto news") == "crypto"
|
||||
self.assertEqual(truthsocial._extract_core_subject("latest trending crypto news"), "crypto")
|
||||
|
||||
def test_preserves_core_topic(self):
|
||||
assert truthsocial._extract_core_subject("tariffs") == "tariffs"
|
||||
self.assertEqual(truthsocial._extract_core_subject("tariffs"), "tariffs")
|
||||
|
||||
def test_strips_trailing_punctuation(self):
|
||||
assert truthsocial._extract_core_subject("what is bitcoin?") == "bitcoin"
|
||||
self.assertEqual(truthsocial._extract_core_subject("what is bitcoin?"), "bitcoin")
|
||||
|
||||
|
||||
class TestParseDate:
|
||||
class TestParseDate(unittest.TestCase):
|
||||
"""Test date parsing from Mastodon status."""
|
||||
|
||||
def test_iso_date(self):
|
||||
assert truthsocial._parse_date({"created_at": "2026-03-09T12:00:00.000Z"}) == "2026-03-09"
|
||||
self.assertEqual(truthsocial._parse_date({"created_at": "2026-03-09T12:00:00.000Z"}), "2026-03-09")
|
||||
|
||||
def test_missing_date(self):
|
||||
assert truthsocial._parse_date({}) is None
|
||||
self.assertIsNone(truthsocial._parse_date({}))
|
||||
|
||||
def test_short_date(self):
|
||||
assert truthsocial._parse_date({"created_at": "short"}) is None
|
||||
self.assertIsNone(truthsocial._parse_date({"created_at": "short"}))
|
||||
|
||||
def test_none_value(self):
|
||||
assert truthsocial._parse_date({"created_at": None}) is None
|
||||
self.assertIsNone(truthsocial._parse_date({"created_at": None}))
|
||||
|
||||
|
||||
class TestDepthConfig:
|
||||
class TestDepthConfig(unittest.TestCase):
|
||||
"""Test depth configuration."""
|
||||
|
||||
def test_all_depths_exist(self):
|
||||
assert "quick" in truthsocial.DEPTH_CONFIG
|
||||
assert "default" in truthsocial.DEPTH_CONFIG
|
||||
assert "deep" in truthsocial.DEPTH_CONFIG
|
||||
self.assertIn("quick", truthsocial.DEPTH_CONFIG)
|
||||
self.assertIn("default", truthsocial.DEPTH_CONFIG)
|
||||
self.assertIn("deep", truthsocial.DEPTH_CONFIG)
|
||||
|
||||
def test_depth_ordering(self):
|
||||
assert truthsocial.DEPTH_CONFIG["quick"] < truthsocial.DEPTH_CONFIG["default"]
|
||||
assert truthsocial.DEPTH_CONFIG["default"] < truthsocial.DEPTH_CONFIG["deep"]
|
||||
self.assertLess(truthsocial.DEPTH_CONFIG["quick"], truthsocial.DEPTH_CONFIG["default"])
|
||||
self.assertLess(truthsocial.DEPTH_CONFIG["default"], truthsocial.DEPTH_CONFIG["deep"])
|
||||
|
||||
|
||||
class TestSearchTruthSocial:
|
||||
class TestSearchTruthSocial(unittest.TestCase):
|
||||
"""Test search function auth handling."""
|
||||
|
||||
def test_no_config_returns_error(self):
|
||||
result = truthsocial.search_truthsocial("test", "2026-02-09", "2026-03-09")
|
||||
assert result["statuses"] == []
|
||||
assert "not configured" in result["error"]
|
||||
self.assertEqual(result["statuses"], [])
|
||||
self.assertIn("not configured", result["error"])
|
||||
|
||||
def test_empty_token_returns_error(self):
|
||||
result = truthsocial.search_truthsocial(
|
||||
"test", "2026-02-09", "2026-03-09",
|
||||
config={"TRUTHSOCIAL_TOKEN": ""},
|
||||
)
|
||||
assert result["statuses"] == []
|
||||
assert "not configured" in result["error"]
|
||||
self.assertEqual(result["statuses"], [])
|
||||
self.assertIn("not configured", result["error"])
|
||||
|
||||
@patch("scripts.lib.truthsocial.http.request")
|
||||
@patch("lib.truthsocial.http.request")
|
||||
def test_401_returns_token_expired(self, mock_request):
|
||||
from scripts.lib.http import HTTPError
|
||||
from lib.http import HTTPError
|
||||
mock_request.side_effect = HTTPError("Unauthorized", status_code=401)
|
||||
result = truthsocial.search_truthsocial(
|
||||
"test", "2026-02-09", "2026-03-09",
|
||||
config={"TRUTHSOCIAL_TOKEN": "expired_token"},
|
||||
)
|
||||
assert result["statuses"] == []
|
||||
assert "expired" in result["error"]
|
||||
self.assertEqual(result["statuses"], [])
|
||||
self.assertIn("expired", result["error"])
|
||||
|
||||
@patch("scripts.lib.truthsocial.http.request")
|
||||
@patch("lib.truthsocial.http.request")
|
||||
def test_403_returns_access_denied(self, mock_request):
|
||||
from scripts.lib.http import HTTPError
|
||||
from lib.http import HTTPError
|
||||
mock_request.side_effect = HTTPError("Forbidden", status_code=403)
|
||||
result = truthsocial.search_truthsocial(
|
||||
"test", "2026-02-09", "2026-03-09",
|
||||
config={"TRUTHSOCIAL_TOKEN": "blocked_token"},
|
||||
)
|
||||
assert result["statuses"] == []
|
||||
assert "Cloudflare" in result["error"]
|
||||
self.assertEqual(result["statuses"], [])
|
||||
self.assertIn("Cloudflare", result["error"])
|
||||
|
||||
@patch("scripts.lib.truthsocial.http.request")
|
||||
@patch("lib.truthsocial.http.request")
|
||||
def test_429_returns_rate_limited(self, mock_request):
|
||||
from scripts.lib.http import HTTPError
|
||||
from lib.http import HTTPError
|
||||
mock_request.side_effect = HTTPError("Too Many Requests", status_code=429)
|
||||
result = truthsocial.search_truthsocial(
|
||||
"test", "2026-02-09", "2026-03-09",
|
||||
config={"TRUTHSOCIAL_TOKEN": "rate_limited_token"},
|
||||
)
|
||||
assert result["statuses"] == []
|
||||
assert "rate limited" in result["error"]
|
||||
self.assertEqual(result["statuses"], [])
|
||||
self.assertIn("rate limited", result["error"])
|
||||
|
||||
@patch("scripts.lib.truthsocial.http.request")
|
||||
@patch("lib.truthsocial.http.request")
|
||||
def test_successful_search(self, mock_request):
|
||||
mock_request.return_value = {
|
||||
"statuses": [
|
||||
@@ -142,13 +146,13 @@ class TestSearchTruthSocial:
|
||||
"tariffs", "2026-02-09", "2026-03-09",
|
||||
config={"TRUTHSOCIAL_TOKEN": "valid_token"},
|
||||
)
|
||||
assert len(result["statuses"]) == 1
|
||||
self.assertEqual(len(result["statuses"]), 1)
|
||||
# Verify bearer token was passed
|
||||
call_args = mock_request.call_args
|
||||
assert call_args[1]["headers"]["Authorization"] == "Bearer valid_token"
|
||||
self.assertEqual(call_args[1]["headers"]["Authorization"], "Bearer valid_token")
|
||||
|
||||
|
||||
class TestParseTruthSocialResponse:
|
||||
class TestParseTruthSocialResponse(unittest.TestCase):
|
||||
"""Test response parsing."""
|
||||
|
||||
def test_basic_post(self):
|
||||
@@ -166,21 +170,21 @@ class TestParseTruthSocialResponse:
|
||||
]
|
||||
}
|
||||
items = truthsocial.parse_truthsocial_response(response)
|
||||
assert len(items) == 1
|
||||
self.assertEqual(len(items), 1)
|
||||
item = items[0]
|
||||
assert item["handle"] == "testuser"
|
||||
assert item["display_name"] == "Test User"
|
||||
assert item["text"] == "Hello from Truth Social" # HTML stripped
|
||||
assert item["url"] == "https://truthsocial.com/@testuser/456"
|
||||
assert item["date"] == "2026-03-09"
|
||||
assert item["engagement"]["likes"] == 100
|
||||
assert item["engagement"]["reposts"] == 50
|
||||
assert item["engagement"]["replies"] == 25
|
||||
assert item["relevance"] > 0
|
||||
self.assertEqual(item["handle"], "testuser")
|
||||
self.assertEqual(item["display_name"], "Test User")
|
||||
self.assertEqual(item["text"], "Hello from Truth Social")
|
||||
self.assertEqual(item["url"], "https://truthsocial.com/@testuser/456")
|
||||
self.assertEqual(item["date"], "2026-03-09")
|
||||
self.assertEqual(item["engagement"]["likes"], 100)
|
||||
self.assertEqual(item["engagement"]["reposts"], 50)
|
||||
self.assertEqual(item["engagement"]["replies"], 25)
|
||||
self.assertGreater(item["relevance"], 0)
|
||||
|
||||
def test_empty_response(self):
|
||||
items = truthsocial.parse_truthsocial_response({"statuses": []})
|
||||
assert items == []
|
||||
self.assertEqual(items, [])
|
||||
|
||||
def test_missing_fields(self):
|
||||
response = {
|
||||
@@ -192,10 +196,10 @@ class TestParseTruthSocialResponse:
|
||||
]
|
||||
}
|
||||
items = truthsocial.parse_truthsocial_response(response)
|
||||
assert len(items) == 1
|
||||
assert items[0]["handle"] == ""
|
||||
assert items[0]["text"] == ""
|
||||
assert items[0]["engagement"]["likes"] == 0
|
||||
self.assertEqual(len(items), 1)
|
||||
self.assertEqual(items[0]["handle"], "")
|
||||
self.assertEqual(items[0]["text"], "")
|
||||
self.assertEqual(items[0]["engagement"]["likes"], 0)
|
||||
|
||||
def test_relevance_ordering(self):
|
||||
response = {
|
||||
@@ -206,8 +210,8 @@ class TestParseTruthSocialResponse:
|
||||
]
|
||||
}
|
||||
items = truthsocial.parse_truthsocial_response(response)
|
||||
assert items[0]["relevance"] >= items[1]["relevance"]
|
||||
assert items[1]["relevance"] >= items[2]["relevance"]
|
||||
self.assertGreaterEqual(items[0]["relevance"], items[1]["relevance"])
|
||||
self.assertGreaterEqual(items[1]["relevance"], items[2]["relevance"])
|
||||
|
||||
def test_html_stripping_in_parse(self):
|
||||
response = {
|
||||
@@ -222,5 +226,9 @@ class TestParseTruthSocialResponse:
|
||||
]
|
||||
}
|
||||
items = truthsocial.parse_truthsocial_response(response)
|
||||
assert "<" not in items[0]["text"]
|
||||
assert ">" not in items[0]["text"]
|
||||
self.assertNotIn("<", items[0]["text"])
|
||||
self.assertNotIn(">", items[0]["text"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user