import unittest from io import BytesIO from datetime import datetime from unittest.mock import patch from flask import Flask from app.routes.guidance import guidance_bp class GuidanceAnalyzeRouteTest(unittest.TestCase): def setUp(self): self.app = Flask(__name__) self.app.register_blueprint(guidance_bp) self.client = self.app.test_client() def test_analyze_accepts_json_token_id(self): fake_results = [{"file_id": "file-2", "filename": "trade.txt", "guidance_analysis": {"status": "done"}}] with patch("app.routes.guidance.DomainStorage") as storage_cls: storage = storage_cls.return_value storage.analyze_guidance.return_value = fake_results response = self.client.post( "/api/guidance/analyze", json={"token_id": "token-2", "granularity": "high"}, ) self.assertEqual(response.status_code, 200) storage.analyze_guidance.assert_called_once_with( analysis_options={"granularity": "high"}, token_id="token-2", ) body = response.get_json() self.assertEqual(body["data"]["analysis_options"]["token_id"], "token-2") self.assertEqual(body["data"]["total"], 1) def test_analyze_omits_token_id_for_all_files(self): with patch("app.routes.guidance.DomainStorage") as storage_cls: storage = storage_cls.return_value storage.analyze_guidance.return_value = [] response = self.client.post("/api/guidance/analyze", data={"granularity": "low"}) self.assertEqual(response.status_code, 200) storage.analyze_guidance.assert_called_once_with( analysis_options={"granularity": "low"}, token_id="", ) def test_analyze_normalizes_legacy_granularity(self): with patch("app.routes.guidance.DomainStorage") as storage_cls: storage = storage_cls.return_value storage.analyze_guidance.return_value = [] response = self.client.post("/api/guidance/analyze", json={"granularity": "fine"}) self.assertEqual(response.status_code, 200) storage.analyze_guidance.assert_called_once_with( analysis_options={"granularity": "high"}, token_id="", ) self.assertEqual(response.get_json()["data"]["analysis_options"]["granularity"], "high") def test_analyze_rejects_unknown_granularity(self): with patch("app.routes.guidance.DomainStorage") as storage_cls: response = self.client.post("/api/guidance/analyze", json={"granularity": "middle"}) self.assertEqual(response.status_code, 400) storage_cls.assert_not_called() def test_upload_accepts_token_field_alias(self): with patch("app.routes.guidance.DomainStorage") as storage_cls: storage = storage_cls.return_value storage.save_guidance_file.return_value = { "file_id": "file-1", "filename": "guide.txt", "stored_path": "/private/path/guide.txt", "uploaded_at": "2026-06-10 15:08:09", } response = self.client.post( "/api/guidance/upload", data={ "token": "token-1", "file": (BytesIO(b"policy"), "guide.txt"), }, content_type="multipart/form-data", ) self.assertEqual(response.status_code, 200) storage.save_guidance_file.assert_called_once() self.assertEqual(storage.save_guidance_file.call_args.args[0], "token-1") body = response.get_json() self.assertEqual(body["message"], "上传成功") self.assertNotIn("stored_path", body["data"]) datetime.strptime(body["data"]["uploaded_at"], "%Y-%m-%d %H:%M:%S") if __name__ == "__main__": unittest.main()