You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

178 lines
5.2 KiB
Python

"""Integration test: feature pipeline with real Oracle (localhost:18001)."""
import datetime as dt
import pytest
ORACLE_URL = "http://localhost:18001"
@pytest.mark.integration
@pytest.mark.asyncio
async def test_feature_snapshot_created(db_session, sample_parser_output):
"""Real Oracle price data → market_v1/event_v1 snapshots created in DB."""
from libs.db.models import (
Document,
Event,
EventParse,
IssuerMaster,
SymbolMaster,
)
from libs.features.builder import build_features_for_event
from libs.oracle_client.client import OracleClient
from libs.oracle_client.price import PriceService
issuer = IssuerMaster(issuer_id="ISSUER::TEST::0000320193", issuer_name="Apple Inc.", ticker="AAPL")
db_session.add(issuer)
symbol = SymbolMaster(
symbol_id="SYM::AAPL::XNYS",
issuer_id="ISSUER::TEST::0000320193",
ticker="AAPL",
venue="XNYS",
)
db_session.add(symbol)
doc = Document(
document_id="DOC::test::ISSUER::TEST::2026-01-29::ACC001",
source_name="sec",
form_type="8-K",
filing_date=dt.date(2026, 1, 29),
accession_no="ACC001",
parsed_status="succeeded",
)
db_session.add(doc)
await db_session.flush()
event = Event(
event_id="EVT::test::earnings_release::0",
primary_document_id=doc.document_id,
symbol_id="SYM::AAPL::XNYS",
event_type="earnings_release",
event_direction="bullish",
event_date=dt.date(2026, 1, 29),
filed_at_utc=dt.datetime(2026, 1, 29, 22, 0, tzinfo=dt.UTC),
parser_version="rule-1.0.0",
status="pending",
)
db_session.add(event)
await db_session.flush()
parse = EventParse(
event_id=event.event_id,
parser_kind="rule",
parser_version="rule-1.0.0",
schema_version="1.0.0",
output_json=sample_parser_output,
validation_status="valid",
)
db_session.add(parse)
await db_session.flush()
async with OracleClient(ORACLE_URL) as client:
price_svc = PriceService(client)
result = await build_features_for_event(db_session, event, price_svc)
assert result is not None
market_snap, event_snap = result
assert market_snap.snapshot_name == "market_v1"
assert event_snap.snapshot_name == "event_v1"
assert "reaction_day_return" in market_snap.feature_json
assert "guidance_direction_score" in event_snap.feature_json
@pytest.mark.integration
@pytest.mark.asyncio
async def test_financial_v1_snapshot_created(db_session, sample_parser_output):
"""Real Oracle price + financial data → financial_v1 snapshot created in DB."""
from sqlalchemy import select
from libs.db.models import (
Document,
Event,
EventParse,
FeatureSnapshot,
IssuerMaster,
SymbolMaster,
)
from libs.features.builder import build_features_for_event
from libs.oracle_client.client import OracleClient
from libs.oracle_client.financial import FinancialService
from libs.oracle_client.price import PriceService
issuer = IssuerMaster(issuer_id="ISSUER::TEST::0000320193", issuer_name="Apple Inc.", ticker="AAPL")
db_session.add(issuer)
symbol = SymbolMaster(
symbol_id="SYM::AAPL::XNYS",
issuer_id="ISSUER::TEST::0000320193",
ticker="AAPL",
venue="XNYS",
)
db_session.add(symbol)
doc = Document(
document_id="DOC::test::ISSUER::TEST::2026-01-29::ACC002",
source_name="sec",
form_type="8-K",
filing_date=dt.date(2026, 1, 29),
accession_no="ACC002",
parsed_status="succeeded",
)
db_session.add(doc)
await db_session.flush()
event = Event(
event_id="EVT::test::earnings_release::fin",
primary_document_id=doc.document_id,
symbol_id="SYM::AAPL::XNYS",
event_type="earnings_release",
event_direction="bullish",
event_date=dt.date(2026, 1, 29),
filed_at_utc=dt.datetime(2026, 1, 29, 22, 0, tzinfo=dt.UTC),
parser_version="rule-1.0.0",
status="pending",
)
db_session.add(event)
await db_session.flush()
parse = EventParse(
event_id=event.event_id,
parser_kind="rule",
parser_version="rule-1.0.0",
schema_version="1.0.0",
output_json=sample_parser_output,
validation_status="valid",
)
db_session.add(parse)
await db_session.flush()
async with OracleClient(ORACLE_URL) as client:
price_svc = PriceService(client)
fin_svc = FinancialService(client)
result = await build_features_for_event(
db_session, event, price_svc, financial_service=fin_svc
)
assert result is not None
market_snap, event_snap = result
rows = (
(
await db_session.execute(
select(FeatureSnapshot).where(
FeatureSnapshot.event_id == event.event_id,
FeatureSnapshot.snapshot_name == "financial_v1",
)
)
)
.scalars()
.all()
)
assert len(rows) == 1
fin_snap = rows[0]
assert "latest_eps" in fin_snap.feature_json
assert "revenue_growth_qoq" in fin_snap.feature_json