from io import BytesIO from app.schemas.risk_prediction import AiSolutionReport, ReportCard, RiskAssessmentResult from app.services.reports import ( build_risk_report_docx, build_risk_report_pdf, effective_report_cards, report_card_lines, ) from docx import Document def _result() -> RiskAssessmentResult: return RiskAssessmentResult( subject_id="洗发水新品", score=72, level="medium", model_version="test", factors=[], report_cards=[ ReportCard( type="supplier", title="供应商深度画像", name="佳供应商", party_type="供应商", supplier_score=88.5, frequency_coefficient=1.2, top_problems=[{"name": "泄漏", "count": 3}], suggestions=["安排首单全检"], ) ], ) def test_report_card_lines_are_canonical() -> None: lines = dict(report_card_lines(_result().report_cards[0])) assert lines["分析对象"] == "佳供应商" assert lines["供应商得分"] == "88.50 分" assert lines["高频问题"] == "泄漏(3次)" assert lines["建议方案"] == "安排首单全检" def test_old_ai_solution_payload_is_supported() -> None: result = _result().model_copy( update={"report_cards": [], "ai_solution_cards": [AiSolutionReport(title="旧方案")]} ) cards = effective_report_cards(result) assert len(cards) == 1 assert cards[0].title == "旧方案" def test_pdf_and_word_include_appended_card_content() -> None: result = _result() pdf = build_risk_report_pdf(result) word = build_risk_report_docx(result) assert pdf.startswith(b"%PDF") document = Document(BytesIO(word)) text = "\n".join(paragraph.text for paragraph in document.paragraphs) text += "\n" + "\n".join(cell.text for table in document.tables for row in table.rows for cell in row.cells) assert "佳供应商" in text assert "88.50 分" in text assert "安排首单全检" in text