phase 14-15: docker build validation and helm deployment
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
"""Tests for sector and market rollup aggregation.
|
||||
|
||||
Tests the pure rollup logic (no DB required).
|
||||
|
||||
Requirements: 6.3, 6.4, 6.5
|
||||
"""
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from services.aggregation.rollups import (
|
||||
CompanyTrendRow,
|
||||
rollup_trends,
|
||||
_build_rollup_disagreement,
|
||||
_derive_rollup_direction,
|
||||
)
|
||||
from services.shared.schemas import TrendDirection, TrendWindow
|
||||
|
||||
NOW = datetime(2026, 4, 11, 12, 0, 0, tzinfo=timezone.utc)
|
||||
|
||||
|
||||
def _make_trend(
|
||||
ticker: str = "AAPL",
|
||||
sector: str = "Technology",
|
||||
window: str = "7d",
|
||||
direction: str = "bullish",
|
||||
strength: float = 0.6,
|
||||
confidence: float = 0.8,
|
||||
contradiction: float = 0.1,
|
||||
catalysts: list[str] | None = None,
|
||||
risks: list[str] | None = None,
|
||||
supporting: list[str] | None = None,
|
||||
opposing: list[str] | None = None,
|
||||
) -> CompanyTrendRow:
|
||||
return CompanyTrendRow(
|
||||
entity_id=ticker,
|
||||
sector=sector,
|
||||
window=window,
|
||||
trend_direction=direction,
|
||||
trend_strength=strength,
|
||||
confidence=confidence,
|
||||
contradiction_score=contradiction,
|
||||
dominant_catalysts=catalysts or ["earnings"],
|
||||
material_risks=risks or [],
|
||||
top_supporting_evidence=supporting or ["doc-1"],
|
||||
top_opposing_evidence=opposing or [],
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# rollup_trends
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_rollup_empty():
|
||||
summary = rollup_trends([], "sector", "Technology", "7d", NOW)
|
||||
assert summary.entity_type == "sector"
|
||||
assert summary.entity_id == "Technology"
|
||||
assert summary.trend_direction == TrendDirection.NEUTRAL
|
||||
assert summary.trend_strength == 0.0
|
||||
assert summary.confidence == 0.0
|
||||
|
||||
|
||||
def test_rollup_single_bullish():
|
||||
trends = [_make_trend("AAPL", direction="bullish", strength=0.7, confidence=0.9)]
|
||||
summary = rollup_trends(trends, "sector", "Technology", "7d", NOW)
|
||||
assert summary.trend_direction == TrendDirection.BULLISH
|
||||
assert summary.trend_strength > 0
|
||||
assert summary.confidence > 0
|
||||
assert summary.window == TrendWindow.SEVEN_DAY
|
||||
|
||||
|
||||
def test_rollup_mixed_directions():
|
||||
trends = [
|
||||
_make_trend("AAPL", direction="bullish", strength=0.6, confidence=0.8),
|
||||
_make_trend("MSFT", direction="bearish", strength=0.6, confidence=0.8),
|
||||
]
|
||||
summary = rollup_trends(trends, "sector", "Technology", "7d", NOW)
|
||||
# Equal and opposite → neutral or mixed
|
||||
assert summary.trend_direction in (TrendDirection.NEUTRAL, TrendDirection.MIXED)
|
||||
|
||||
|
||||
def test_rollup_confidence_weighted():
|
||||
"""Higher-confidence company should dominate the rollup direction."""
|
||||
trends = [
|
||||
_make_trend("AAPL", direction="bullish", strength=0.8, confidence=0.95),
|
||||
_make_trend("MSFT", direction="bearish", strength=0.3, confidence=0.2),
|
||||
]
|
||||
summary = rollup_trends(trends, "sector", "Technology", "7d", NOW)
|
||||
assert summary.trend_direction == TrendDirection.BULLISH
|
||||
|
||||
|
||||
def test_rollup_catalysts_aggregated():
|
||||
trends = [
|
||||
_make_trend("AAPL", catalysts=["earnings", "product"], confidence=0.8),
|
||||
_make_trend("MSFT", catalysts=["product", "macro"], confidence=0.6),
|
||||
]
|
||||
summary = rollup_trends(trends, "sector", "Technology", "7d", NOW)
|
||||
# "product" appears in both → should be top catalyst
|
||||
assert "product" in summary.dominant_catalysts
|
||||
|
||||
|
||||
def test_rollup_risks_deduplicated():
|
||||
trends = [
|
||||
_make_trend("AAPL", risks=["regulatory risk", "supply chain"], confidence=0.8),
|
||||
_make_trend("MSFT", risks=["Regulatory Risk", "tariffs"], confidence=0.6),
|
||||
]
|
||||
summary = rollup_trends(trends, "sector", "Technology", "7d", NOW)
|
||||
risk_lower = [r.lower() for r in summary.material_risks]
|
||||
assert risk_lower.count("regulatory risk") == 1
|
||||
|
||||
|
||||
def test_rollup_evidence_collected():
|
||||
trends = [
|
||||
_make_trend("AAPL", supporting=["doc-1", "doc-2"], opposing=["doc-3"]),
|
||||
_make_trend("MSFT", supporting=["doc-4"], opposing=["doc-5"]),
|
||||
]
|
||||
summary = rollup_trends(trends, "market", "all", "7d", NOW)
|
||||
assert "doc-1" in summary.top_supporting_evidence
|
||||
assert "doc-4" in summary.top_supporting_evidence
|
||||
assert "doc-3" in summary.top_opposing_evidence
|
||||
|
||||
|
||||
def test_rollup_market_entity_type():
|
||||
trends = [_make_trend("AAPL"), _make_trend("JPM", sector="Financials")]
|
||||
summary = rollup_trends(trends, "market", "all", "7d", NOW)
|
||||
assert summary.entity_type == "market"
|
||||
assert summary.entity_id == "all"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _derive_rollup_direction
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_derive_direction_bullish():
|
||||
assert _derive_rollup_direction(0.5, 0.0) == TrendDirection.BULLISH
|
||||
|
||||
|
||||
def test_derive_direction_bearish():
|
||||
assert _derive_rollup_direction(-0.5, 0.0) == TrendDirection.BEARISH
|
||||
|
||||
|
||||
def test_derive_direction_neutral():
|
||||
assert _derive_rollup_direction(0.05, 0.0) == TrendDirection.NEUTRAL
|
||||
|
||||
|
||||
def test_derive_direction_mixed_high_contradiction():
|
||||
assert _derive_rollup_direction(0.1, 0.2) == TrendDirection.MIXED
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# _build_rollup_disagreement
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_disagreement_no_conflict():
|
||||
trends = [
|
||||
_make_trend("AAPL", direction="bullish"),
|
||||
_make_trend("MSFT", direction="bullish"),
|
||||
]
|
||||
details = _build_rollup_disagreement(trends, "Technology")
|
||||
assert details == []
|
||||
|
||||
|
||||
def test_disagreement_with_conflict():
|
||||
trends = [
|
||||
_make_trend("AAPL", direction="bullish", confidence=0.8),
|
||||
_make_trend("MSFT", direction="bearish", confidence=0.7),
|
||||
]
|
||||
details = _build_rollup_disagreement(trends, "Technology")
|
||||
assert len(details) == 1
|
||||
assert details[0].dimension == "company_direction"
|
||||
assert "AAPL" in details[0].positive_doc_ids
|
||||
assert "MSFT" in details[0].negative_doc_ids
|
||||
Reference in New Issue
Block a user