"""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"