"""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 @pytest.mark.integration @pytest.mark.asyncio async def test_feature_builder_overrides_unknown_time_bucket_from_event_filed_time( db_session, sample_parser_output ): 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 parser_output = dict(sample_parser_output) parser_output["filing_time_bucket"] = "unknown" 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::ACC003", source_name="sec", form_type="8-K", filing_date=dt.date(2026, 1, 29), accession_no="ACC003", parsed_status="succeeded", ) db_session.add(doc) await db_session.flush() event = Event( event_id="EVT::test::earnings_release::timefix", 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=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 _, event_snap = result assert event_snap.feature_json["filing_time_bucket"] == "post_market"