|
@@ -425,6 +425,100 @@ class FinalReviewApiTests(unittest.TestCase):
|
|
|
worker.assert_not_called()
|
|
worker.assert_not_called()
|
|
|
shutil.rmtree(root / "jobs", ignore_errors=True)
|
|
shutil.rmtree(root / "jobs", ignore_errors=True)
|
|
|
|
|
|
|
|
|
|
+ def test_relative_reference_bid_prefers_reference_dir_when_both_exist(self):
|
|
|
|
|
+ with tempfile.TemporaryDirectory() as temp_dir:
|
|
|
|
|
+ root = Path(temp_dir)
|
|
|
|
|
+ reference_dir = root / "reference_root"
|
|
|
|
|
+ reference_dir1 = root / "dms_upload"
|
|
|
|
|
+ reference_dir.mkdir()
|
|
|
|
|
+ reference_dir1.mkdir()
|
|
|
|
|
+ primary = reference_dir / "reference.docx"
|
|
|
|
|
+ secondary = reference_dir1 / "reference.docx"
|
|
|
|
|
+ primary.write_bytes(_docx_bytes("primary"))
|
|
|
|
|
+ secondary.write_bytes(_docx_bytes("secondary"))
|
|
|
|
|
+
|
|
|
|
|
+ with patch.object(http_api, "REFERENCE_DIR", str(reference_dir)), patch.object(
|
|
|
|
|
+ http_api, "REFERENCE_DIR1", str(reference_dir1)
|
|
|
|
|
+ ):
|
|
|
|
|
+ resolved = http_api._resolve_reference_path(
|
|
|
|
|
+ "/reference.docx", is_absolute=False
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ self.assertEqual(Path(resolved), primary)
|
|
|
|
|
+
|
|
|
|
|
+ def test_json_relative_reference_bid_falls_back_to_reference_dir1(self):
|
|
|
|
|
+ with tempfile.TemporaryDirectory() as temp_dir:
|
|
|
|
|
+ root = Path(temp_dir)
|
|
|
|
|
+ reference_dir = root / "reference_root"
|
|
|
|
|
+ reference_dir1 = root / "dms_upload"
|
|
|
|
|
+ reference_dir.mkdir()
|
|
|
|
|
+ reference_dir1.mkdir()
|
|
|
|
|
+ reference_file = reference_dir1 / "参考投书.docx"
|
|
|
|
|
+ reference_file.write_bytes(_docx_bytes("reference-dir1"))
|
|
|
|
|
+ tender = root / "招标文件.pdf"
|
|
|
|
|
+ procurement = root / "采购需求.docx"
|
|
|
|
|
+ tender.write_bytes(_pdf_bytes())
|
|
|
|
|
+ procurement.write_bytes(_docx_bytes("procurement"))
|
|
|
|
|
+ executor = RecordingExecutor()
|
|
|
|
|
+ payload = {
|
|
|
|
|
+ "CALLBACK_URL": "http://127.0.0.1:9999/callback",
|
|
|
|
|
+ "txbId": 1,
|
|
|
|
|
+ "TENDER_FILE": str(tender),
|
|
|
|
|
+ "PROCUREMENT_FILE": str(procurement),
|
|
|
|
|
+ "TPC_IS_ABSOLUTE": True,
|
|
|
|
|
+ "REFERENCE_BID": "/参考投书.docx",
|
|
|
|
|
+ "REFERENCE_IS_ABSOLUTE": False,
|
|
|
|
|
+ "CLA_FILE": "",
|
|
|
|
|
+ }
|
|
|
|
|
+ with patch.object(http_api, "REFERENCE_DIR", str(reference_dir)), patch.object(
|
|
|
|
|
+ http_api, "REFERENCE_DIR1", str(reference_dir1)
|
|
|
|
|
+ ), patch.object(http_api, "API_WORK_ROOT", root / "jobs"), patch.object(
|
|
|
|
|
+ http_api, "_JOB_EXECUTOR", executor
|
|
|
|
|
+ ), patch.object(http_api, "_run_pipeline_worker") as worker:
|
|
|
|
|
+ response = TestClient(http_api.app).post(
|
|
|
|
|
+ "/api/v1/final-review",
|
|
|
|
|
+ json=payload,
|
|
|
|
|
+ )
|
|
|
|
|
+ function, args = executor.submitted[0]
|
|
|
|
|
+ job = args[0]
|
|
|
|
|
+
|
|
|
|
|
+ self.assertEqual(response.status_code, 202)
|
|
|
|
|
+ self.assertEqual(
|
|
|
|
|
+ job["files"]["REFERENCE_BID"]["filename"], reference_file.name
|
|
|
|
|
+ )
|
|
|
|
|
+ worker.assert_not_called()
|
|
|
|
|
+ shutil.rmtree(root / "jobs", ignore_errors=True)
|
|
|
|
|
+
|
|
|
|
|
+ def test_json_relative_reference_bid_rejects_when_both_candidates_missing(self):
|
|
|
|
|
+ with tempfile.TemporaryDirectory() as temp_dir:
|
|
|
|
|
+ root = Path(temp_dir)
|
|
|
|
|
+ reference_dir = root / "reference_root"
|
|
|
|
|
+ reference_dir1 = root / "dms_upload"
|
|
|
|
|
+ reference_dir.mkdir()
|
|
|
|
|
+ reference_dir1.mkdir()
|
|
|
|
|
+ with patch.object(http_api, "REFERENCE_DIR", str(reference_dir)), patch.object(
|
|
|
|
|
+ http_api, "REFERENCE_DIR1", str(reference_dir1)
|
|
|
|
|
+ ), patch.object(http_api, "_JOB_EXECUTOR") as executor:
|
|
|
|
|
+ response = TestClient(http_api.app).post(
|
|
|
|
|
+ "/api/v1/final-review",
|
|
|
|
|
+ json={
|
|
|
|
|
+ "CALLBACK_URL": "http://127.0.0.1:9999/callback",
|
|
|
|
|
+ "txbId": "missing-reference",
|
|
|
|
|
+ "TENDER_FILE": "tender.pdf",
|
|
|
|
|
+ "PROCUREMENT_FILE": "procurement.docx",
|
|
|
|
|
+ "TPC_IS_ABSOLUTE": True,
|
|
|
|
|
+ "REFERENCE_BID": "/missing.docx",
|
|
|
|
|
+ "REFERENCE_IS_ABSOLUTE": False,
|
|
|
|
|
+ },
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ self.assertEqual(response.status_code, 400)
|
|
|
|
|
+ self.assertEqual(
|
|
|
|
|
+ response.json()["detail"],
|
|
|
|
|
+ "REFERENCE_BID 在 REFERENCE_DIR 和 REFERENCE_DIR1 下均不存在: missing.docx",
|
|
|
|
|
+ )
|
|
|
|
|
+ executor.submit.assert_not_called()
|
|
|
|
|
+
|
|
|
def test_invalid_tpc_is_absolute_value_is_rejected(self):
|
|
def test_invalid_tpc_is_absolute_value_is_rejected(self):
|
|
|
with patch.object(http_api, "_JOB_EXECUTOR") as executor:
|
|
with patch.object(http_api, "_JOB_EXECUTOR") as executor:
|
|
|
response = TestClient(http_api.app).post(
|
|
response = TestClient(http_api.app).post(
|