Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions services/ingestion/tests/test_no_absolute_app_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,6 @@

INGESTION_APP = Path(__file__).resolve().parent.parent / "app"

# Absolute imports that open PRs already remove. Delete an entry once its fix
# lands; never add one.
PENDING_ELSEWHERE = {
("webhook_compat.py", "app.tenant_validation"), # PR #3774
("edi_ingestion/routes.py", "app.edi_ingestion.rejection_log"), # fix/csv-edi-ingest-monolith-imports
}


def _absolute_app_imports(path: Path) -> list[tuple[int, str]]:
found: list[tuple[int, str]] = []
Expand Down Expand Up @@ -50,6 +43,5 @@ def test_ingestion_app_has_no_new_absolute_app_imports() -> None:
f"{path.relative_to(INGESTION_APP).as_posix()}:{lineno} imports {module}"
for path in sorted(INGESTION_APP.rglob("*.py"))
for lineno, module in _absolute_app_imports(path)
if (path.relative_to(INGESTION_APP).as_posix(), module) not in PENDING_ELSEWHERE
]
assert offenders == [], "use a relative import (from .x / from ..x):\n" + "\n".join(offenders)
Original file line number Diff line number Diff line change
Expand Up @@ -423,3 +423,48 @@ def get(self, key):
# exercised under the poisoned top-level ``app`` for CSV and EDI.
assert "csv_upload" in seen, (csv_resp.status_code, csv_resp.text[:500], seen)
assert "edi_856_inbound" in seen, (edi_resp.status_code, edi_resp.text[:500], seen)


def test_edi_rejection_is_recorded_under_prod_path(prod_path_webhook_compat, monkeypatch: pytest.MonkeyPatch):
"""A rejected EDI document returns its 4xx and leaves an audit record.

``_record_edi_rejection`` resolves the rejection log lazily. With an
absolute ``app.edi_ingestion`` name that lookup raised under the prod
layout, so each rejection became a 500 and lost its audit record.
"""
from fastapi import FastAPI # noqa: PLC0415
from fastapi.testclient import TestClient # noqa: PLC0415
from services.ingestion.app.authz import ( # noqa: PLC0415
IngestionPrincipal,
get_ingestion_principal,
)
from services.ingestion.app.edi_ingestion import router as edi_router # noqa: PLC0415
import services.ingestion.app.edi_ingestion.rejection_log as rejection_log # noqa: PLC0415

monkeypatch.delenv("EDI_REQUIRE_PARTNER_ID", raising=False)
monkeypatch.delenv("EDI_PARTNER_ALLOWLIST", raising=False)
rejection_log.reset_edi_rejections()
app = FastAPI()
app.include_router(edi_router)
app.dependency_overrides[get_ingestion_principal] = lambda: IngestionPrincipal(
key_id="test-key", scopes=["*"], tenant_id=TENANT, auth_mode="test"
)

future_dated = _EDI_FIXTURE.read_text(encoding="utf-8").replace(
"BSN*00*ASN-12345*20260310*1200~", "BSN*00*ASN-12345*20991231*1200~"
)
assert "20991231" in future_dated

with TestClient(app, raise_server_exceptions=False) as client:
for route in ("", "/document"):
response = client.post(
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
f"/api/v1/ingest/edi{route}",
data={"traceability_lot_code": "00012345678901-LOT001", "tenant_id": TENANT},
files={"file": ("asn_856.edi", future_dated.encode(), "application/edi-x12")},
)
assert response.status_code == 400, response.text
assert response.json()["detail"]["error"] == "edi_date_in_future"

records = rejection_log.list_edi_rejections(TENANT)
assert len(records) == 2
assert {record["reason"] for record in records} == {"edi_date_in_future"}
Loading