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.

129 lines
3.8 KiB
Python

"""Integration test: filing pipeline (poll → fetch → parse → event in DB)."""
import datetime as dt
from pathlib import Path
import pytest
FIXTURES = Path(__file__).parent.parent / "fixtures"
@pytest.mark.integration
@pytest.mark.asyncio
async def test_document_upsert_idempotency_via_helpers(db_session):
"""Upsert helper inserts same document twice → only one row."""
import datetime as dt
from sqlalchemy import func, select
from libs.db.helpers import upsert
from libs.db.models import Document
values = {
"document_id": "DOC::idempotency::test::2026-01-01::IDEMACC001",
"source_name": "sec",
"form_type": "8-K",
"filing_date": dt.date(2026, 1, 1),
"accession_no": "IDEMACC001",
"parsed_status": "pending",
"created_at_utc": dt.datetime.now(tz=dt.UTC),
"updated_at_utc": dt.datetime.now(tz=dt.UTC),
}
await upsert(db_session, Document, values, index_elements=["document_id"])
await upsert(db_session, Document, values, index_elements=["document_id"])
await db_session.flush()
result = await db_session.execute(
select(func.count()).where(
Document.document_id == "DOC::idempotency::test::2026-01-01::IDEMACC001"
)
)
count = result.scalar_one()
assert count == 1
@pytest.mark.integration
@pytest.mark.asyncio
async def test_document_upsert_idempotency(db_session):
"""Inserting same document twice should not create duplicates."""
from sqlalchemy import select
from libs.db.models import Document
doc_id = "DOC::test::ISSUER::X::2026-01-01::ACC001"
doc1 = Document(
document_id=doc_id,
source_name="sec",
form_type="8-K",
filing_date=dt.date(2026, 1, 29),
accession_no="ACC001",
parsed_status="pending",
)
db_session.add(doc1)
await db_session.flush()
# Try to insert again (should conflict on unique accession+form_type)
result = await db_session.execute(select(Document).where(Document.document_id == doc_id))
rows = result.scalars().all()
assert len(rows) == 1
@pytest.mark.integration
@pytest.mark.asyncio
async def test_event_parse_lifecycle(db_session):
"""Create issuer → document → event → event_parse chain."""
from libs.db.models import Document, Event, EventParse, IssuerMaster
# Create issuer — use TEST prefix to avoid conflicts with real pipeline data
issuer = IssuerMaster(
issuer_id="ISSUER::TEST::0000320193",
issuer_name="Apple Inc.",
ticker="AAPL_TEST",
)
db_session.add(issuer)
await db_session.flush()
# Create document
doc = Document(
document_id="DOC::test::ISSUER::TEST::2026-01-29::ACC001",
source_name="sec",
issuer_id="ISSUER::TEST::0000320193",
form_type="8-K",
filing_date=dt.date(2026, 1, 29),
accession_no="ACC001",
parsed_status="ready_for_parse",
)
db_session.add(doc)
await db_session.flush()
# Create event
event = Event(
event_id="EVT::test::ISSUER::TEST::2026-01-29::ACC001::earnings_release::0",
primary_document_id=doc.document_id,
issuer_id="ISSUER::TEST::0000320193",
event_type="earnings_release",
event_direction="bullish",
event_date=dt.date(2026, 1, 29),
parser_version="rule-1.0.0",
parse_confidence=0.78,
status="pending",
)
db_session.add(event)
await db_session.flush()
# Create event parse
parse = EventParse(
event_id=event.event_id,
parser_kind="rule",
parser_version="rule-1.0.0",
schema_version="1.0.0",
output_json={"event_type": "earnings_release"},
validation_status="valid",
)
db_session.add(parse)
await db_session.flush()
assert parse.event_parse_id is not None
assert event.status == "pending"