| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- import importlib.util
- import os
- import sys
- import tempfile
- import unittest
- from unittest.mock import patch
- from docx import Document
- from models import (
- BidOutline,
- Chapter,
- ChapterType,
- ExtractedTable,
- ProjectData,
- TenderAnalysis,
- )
- SCRIPT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
- if SCRIPT_DIR not in sys.path:
- sys.path.insert(0, SCRIPT_DIR)
- SPEC = importlib.util.spec_from_file_location(
- "manual_test_step4", os.path.join(SCRIPT_DIR, "test_step4.py")
- )
- MODULE = importlib.util.module_from_spec(SPEC)
- SPEC.loader.exec_module(MODULE)
- class Step4ReportingTests(unittest.TestCase):
- def test_reference_bid_loader_extracts_paragraphs_and_tables(self):
- table = ExtractedTable(
- table_id="REF-T01",
- table_type="bid_detail_table",
- source_type="reference_docx",
- )
- project_data = ProjectData(project_id="test", project_name="测试项目")
- with tempfile.TemporaryDirectory() as directory:
- reference_path = os.path.join(directory, "reference.docx")
- Document().save(reference_path)
- with (
- patch(
- "doc_reader.reader.read_docx_paragraph_texts_et",
- return_value=["参考投书正文"],
- ),
- patch(
- "step1_parsing.table_extractor.extract_reference_tables_with_llm",
- return_value=[table],
- ) as extractor,
- ):
- count = MODULE._load_reference_bid(
- reference_path, project_data, directory
- )
- self.assertEqual(count, 1)
- self.assertEqual(project_data.reference_bids[0].content, "参考投书正文")
- self.assertIs(project_data.reference_tables[0], table)
- extractor.assert_called_once_with(
- reference_path,
- output_dir=os.path.join(directory, "内容提取_参考投书"),
- )
- def test_report_exposes_step2_project_fill_fields(self):
- analysis = TenderAnalysis(
- project_name="测试",
- agency_name="采购中心",
- project_fields={
- "服务内容": "物业管理服务",
- "服务要求": "符合质量考核要求",
- "服务期限": "三年",
- },
- )
- report = MODULE._build_report(
- BidOutline(project_name="测试", chapters=[]),
- analysis,
- )
- self.assertEqual(report["project_fields"]["采购机构名称"], "采购中心")
- self.assertEqual(report["project_fields"]["服务期限"], "三年")
- def test_unchanged_template_child_is_not_reported_as_empty(self):
- mapped = Chapter(
- id="1.2",
- title="响应能力",
- level=2,
- direct_scoring_bindings=["SC-01#1"],
- supplement_content="针对本项目建立可核验的响应机制。",
- )
- unchanged = Chapter(
- id="1.1", title="模板原有说明", level=2, from_template=True
- )
- top = Chapter(
- id="1",
- title="需求理解",
- chapter_type=ChapterType.TECHNICAL,
- children=[unchanged, mapped],
- preserve_template_layout=True,
- template_fill_completed=True,
- generated_content="模板原文",
- content_blocks=[
- {"order": 0, "block_type": "template_base"},
- {"order": 1, "block_type": "native_table_plan"},
- ],
- )
- outline = BidOutline(
- project_name="测试",
- chapters=[top],
- evaluation_index_entries=[{
- "entry_id": "SC-01#1",
- "entry_type": "scoring",
- "final_heading_id": "1.2",
- }],
- )
- report = MODULE._build_report(outline)
- self.assertTrue(report["passed"], report["errors"])
- self.assertEqual(report["chapters"][0]["supplement_node_count"], 1)
- def test_missing_direct_supplement_fails_gate(self):
- node = Chapter(
- id="1.1",
- title="响应能力",
- level=2,
- direct_scoring_bindings=["SC-01#1"],
- )
- outline = BidOutline(
- project_name="测试",
- chapters=[Chapter(id="1", title="技术章", children=[node])],
- evaluation_index_entries=[{
- "entry_id": "SC-01#1",
- "entry_type": "scoring",
- "final_heading_id": "1.1",
- }],
- )
- report = MODULE._build_report(outline)
- self.assertFalse(report["passed"])
- self.assertIn("直接落点缺少补充正文", report["errors"][0])
- def test_unresolved_placeholder_in_chapter_artifact_fails_gate(self):
- with tempfile.TemporaryDirectory() as directory:
- artifact_path = os.path.join(directory, "chapter.docx")
- document = Document()
- document.add_paragraph("项目编号:%%项目编号%%")
- document.save(artifact_path)
- chapter = Chapter(
- id="1",
- title="投标人资格、资信证明",
- artifact_path=artifact_path,
- )
- report = MODULE._build_report(BidOutline(
- project_name="测试",
- chapters=[chapter],
- ))
- self.assertFalse(report["passed"])
- self.assertTrue(any(
- "章节产物仍有未解析占位符" in error
- for error in report["errors"]
- ))
- if __name__ == "__main__":
- unittest.main()
|