feat: add daily manual price review workflow
This commit is contained in:
@@ -23,8 +23,9 @@ from arr_ingestion.direct_contracts import (
|
||||
)
|
||||
from arr_ingestion.direct_service import DirectSubmissionService
|
||||
from arr_ingestion.direct_validation import DirectResultValidator
|
||||
from arr_processing.policy import load_legacy_direct_processor_policy
|
||||
from tests.test_arr_ingestion_validation import MemoryStore, policy, processor
|
||||
from tests.test_arr_opera_daily_ingest import success_xml
|
||||
from tests.test_arr_opera_daily_ingest import reservation, success_xml, xml_document
|
||||
|
||||
|
||||
GRANT = "G" * 43
|
||||
@@ -33,6 +34,11 @@ SOURCE_KEY = (
|
||||
"arr/jobs/arrjob-direct-001/attempts/0001/committed/"
|
||||
"source_xml/source.xml"
|
||||
)
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def legacy_policy():
|
||||
return load_legacy_direct_processor_policy(PROJECT_ROOT)
|
||||
|
||||
|
||||
def run_direct_processor(
|
||||
@@ -51,6 +57,7 @@ def run_direct_processor(
|
||||
output_dir=str(output.resolve()),
|
||||
result_json=str(result.resolve()),
|
||||
structured_result_json=str(structured.resolve()),
|
||||
legacy_v3_output=True,
|
||||
)
|
||||
)
|
||||
if exit_code != 0:
|
||||
@@ -215,6 +222,36 @@ class DirectContractTests(unittest.TestCase):
|
||||
DirectSubmissionRequest.from_dict(request_dict(oversize))
|
||||
self.assertEqual(raised.exception.code, "DIRECT_PAYLOAD_TOO_LARGE")
|
||||
|
||||
def test_legacy_direct_projection_never_enters_manual_price_review(self) -> None:
|
||||
source_xml = xml_document(
|
||||
reservation(1, rate_code="GRPA1", rate_amount="999999")
|
||||
)
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
root = Path(temp_dir)
|
||||
source = root / "source.xml"
|
||||
output = root / "output"
|
||||
result = output / "result.json"
|
||||
structured = output / "structured-result.json"
|
||||
source.write_text(source_xml, encoding="utf-8")
|
||||
with contextlib.redirect_stdout(io.StringIO()):
|
||||
exit_code = processor.process(
|
||||
argparse.Namespace(
|
||||
xml=str(source.resolve()),
|
||||
output_dir=str(output.resolve()),
|
||||
result_json=str(result.resolve()),
|
||||
structured_result_json=str(structured.resolve()),
|
||||
legacy_v3_output=True,
|
||||
)
|
||||
)
|
||||
result_payload = json.loads(result.read_text(encoding="utf-8"))
|
||||
structured_payload = json.loads(structured.read_text(encoding="utf-8"))
|
||||
self.assertEqual(exit_code, 2)
|
||||
self.assertEqual(result_payload["version"], "3.0")
|
||||
self.assertEqual(result_payload["status"], "failed")
|
||||
self.assertEqual(structured_payload["result_schema_version"], "3.0")
|
||||
self.assertEqual(structured_payload["status"], "failed")
|
||||
self.assertNotIn("review_required", json.dumps(structured_payload))
|
||||
|
||||
def test_receipt_round_trip_is_minimal_and_strict(self) -> None:
|
||||
value = receipt()
|
||||
payload = value.to_dict()
|
||||
@@ -232,7 +269,7 @@ class DirectReplayValidationTests(unittest.TestCase):
|
||||
state = received(payload, source)
|
||||
validator = DirectResultValidator(
|
||||
MemoryStore({SOURCE_KEY: source}),
|
||||
policy(),
|
||||
legacy_policy(),
|
||||
)
|
||||
verified = validator.validate(state)
|
||||
self.assertEqual(verified.submission.submission_id, 17)
|
||||
@@ -250,7 +287,7 @@ class DirectReplayValidationTests(unittest.TestCase):
|
||||
retained["total_price"] += 1
|
||||
validator = DirectResultValidator(
|
||||
MemoryStore({SOURCE_KEY: source}),
|
||||
policy(),
|
||||
legacy_policy(),
|
||||
)
|
||||
with self.assertRaises(IngestionError) as raised:
|
||||
validator.validate(received(tampered, source))
|
||||
|
||||
Reference in New Issue
Block a user