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.
176 lines
5.1 KiB
Python
176 lines
5.1 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::0000320193", issuer_name="Apple Inc.", ticker="AAPL")
|
|
db_session.add(issuer)
|
|
|
|
symbol = SymbolMaster(
|
|
symbol_id="SYM::AAPL::XNYS",
|
|
issuer_id="ISSUER::0000320193",
|
|
ticker="AAPL",
|
|
venue="XNYS",
|
|
)
|
|
db_session.add(symbol)
|
|
|
|
doc = Document(
|
|
document_id="DOC::sec::ISSUER::0000320193::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),
|
|
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::0000320193", issuer_name="Apple Inc.", ticker="AAPL")
|
|
db_session.add(issuer)
|
|
|
|
symbol = SymbolMaster(
|
|
symbol_id="SYM::AAPL::XNYS",
|
|
issuer_id="ISSUER::0000320193",
|
|
ticker="AAPL",
|
|
venue="XNYS",
|
|
)
|
|
db_session.add(symbol)
|
|
|
|
doc = Document(
|
|
document_id="DOC::sec::ISSUER::0000320193::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),
|
|
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
|