Restore YG rules generation flow

This commit is contained in:
2026-06-10 19:15:24 +08:00
parent 52a2be755f
commit 73b9bb5622
50 changed files with 156 additions and 0 deletions

BIN
CLAUDE.md

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
run.py

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,38 @@
import io
import unittest
from unittest.mock import patch
from app.utils.guidance_analysis import GuidanceAnalyzer
class GuidanceFileExtractionTest(unittest.TestCase):
def test_extracts_plain_text_and_markdown(self):
analyzer = GuidanceAnalyzer()
txt = analyzer.extract_text("资产负债率预警。".encode("utf-8"), "guide.txt")
md = analyzer.extract_text("# 标题\n\n资产负债率预警。".encode("utf-8"), "guide.md")
self.assertIn("资产负债率预警", txt["text"])
self.assertIn("资产负债率预警", md["text"])
self.assertEqual(txt["method"], "plain_text")
self.assertEqual(md["method"], "markdown")
def test_extracts_docx_text(self):
from docx import Document
document = Document()
document.add_paragraph("资产负债率预警。")
stream = io.BytesIO()
document.save(stream)
result = GuidanceAnalyzer().extract_text(stream.getvalue(), "guide.docx")
self.assertEqual(result["method"], "docx")
self.assertIn("资产负债率预警", result["text"])
def test_pdf_extractor_result_shape(self):
with patch.object(GuidanceAnalyzer, "_extract_pdf_text", return_value="资产负债率预警。"):
result = GuidanceAnalyzer().extract_text(b"%PDF", "guide.pdf")
self.assertEqual(result["method"], "pdf")
self.assertIn("资产负债率预警", result["text"])

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

20
tests/test_response.py Normal file
View File

@@ -0,0 +1,20 @@
import unittest
from flask import Flask
from app.utils.response import success
class ResponseMessageTest(unittest.TestCase):
def test_success_message_defaults_to_chinese(self):
app = Flask(__name__)
with app.app_context():
response, status_code = success({"ok": True})
self.assertEqual(status_code, 200)
self.assertEqual(response.get_json()["message"], "操作成功")
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,66 @@
import unittest
from unittest.mock import patch
from app import create_app
class RouteMessageTest(unittest.TestCase):
def setUp(self):
self.app = create_app("testing")
self.client = self.app.test_client()
def test_success_messages_include_business_action(self):
response = self.client.get("/api/health")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get_json()["message"], "健康检查成功")
def test_failure_messages_include_business_action(self):
response = self.client.get("/api/rules/status")
self.assertEqual(response.status_code, 400)
self.assertEqual(response.get_json()["message"], "查询失败:缺少 task_id")
def test_clear_domains_message_is_delete_success(self):
with patch("app.routes.domain.DomainStorage") as domain_storage_cls:
with patch("app.routes.domain.SchemaStorage") as schema_storage_cls:
domain_storage_cls.return_value.clear_all.return_value = 3
schema_storage_cls.return_value.delete_file.return_value = True
response = self.client.post("/api/domains/clear")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get_json()["message"], "删除成功")
self.assertEqual(response.get_json()["data"]["deleted_count"], 3)
def test_generate_rules_returns_compact_async_task_info(self):
with patch("app.routes.rules.RuleGenerationService") as service_cls:
service_cls.return_value.start.return_value = {
"task_id": "task-1",
"status": "running",
"limit": 3,
"generated_count": 0,
"output_file": "/app/output/rules-task-1/rules-task-1.xlsx",
"markdown_file": "/app/output/rules-task-1/rules-task-1.md",
"files": {
"excel": "/app/output/rules-task-1/rules-task-1.xlsx",
"markdown": "/app/output/rules-task-1/rules-task-1.md",
},
}
response = self.client.post("/api/rules/generate", json={"limit": 3})
body = response.get_json()
self.assertEqual(response.status_code, 200)
self.assertEqual(body["message"], "规则生成任务创建成功")
self.assertEqual(body["data"], {
"task_id": "task-1",
"status": "running",
"async": True,
"limit": 3,
"status_url": "/api/rules/status?task_id=task-1",
})
if __name__ == "__main__":
unittest.main()

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,32 @@
import unittest
from unittest.mock import patch
from flask import Flask
from app.routes.schema import schema_bp
class SchemaRouteTest(unittest.TestCase):
def setUp(self):
self.app = Flask(__name__)
self.app.register_blueprint(schema_bp)
self.client = self.app.test_client()
def test_schema_status_returns_processing_summary(self):
with patch("app.routes.schema.SchemaStorage") as storage_cls:
storage_cls.return_value.status.return_value = {
"processing_status": "done",
"module_count": 2,
"uploaded_at": "2026-06-10 15:50:00",
}
response = self.client.get("/api/schema/status")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.get_json()["message"], "查询成功")
self.assertEqual(response.get_json()["data"]["processing_status"], "done")
self.assertEqual(response.get_json()["data"]["module_count"], 2)
if __name__ == "__main__":
unittest.main()