Files
YG-Rules/tests/test_guidance_storage.py

109 lines
4.3 KiB
Python

import io
import json
import os
import unittest
from unittest.mock import patch
from app.utils.storage import DomainStorage
class GuidanceStorageAnalyzeTest(unittest.TestCase):
def setUp(self):
self.storage_path = os.path.join(os.getcwd(), "data", "test-domains-storage.json")
self.storage = DomainStorage(self.storage_path)
self.storage._write({
"domains": [
{
"token": "token-1",
"domain": "\u8fc7\u5ea6\u8d1f\u503a",
"note": "",
"created_at": "2026-04-20T00:00:00",
},
{
"token": "token-2",
"domain": "\u865a\u5047\u8d38\u6613",
"note": "",
"created_at": "2026-04-20T00:00:00",
},
],
})
def tearDown(self):
if os.path.exists(self.storage_path):
os.remove(self.storage_path)
def test_upload_only_saves_file_metadata(self):
record = self.storage.save_guidance_file(
"token-1",
io.BytesIO("\u8d44\u4ea7\u8d1f\u503a\u7387\u9884\u8b66\u3002".encode()),
"guide.txt",
)
self.assertIn("file_id", record)
self.assertNotIn("guidance_analysis", record)
def test_analyze_guidance_writes_analysis_after_upload(self):
record = self.storage.save_guidance_file(
"token-1",
io.BytesIO("\u8d44\u4ea7\u8d1f\u503a\u7387\u9884\u8b66\u3002".encode()),
"guide.txt",
)
fake_analysis = {
"status": "done",
"granularity": "low",
"description_patterns": [{"description_pattern": "\u8d44\u4ea7\u8d1f\u503a\u7387\u9884\u8b66"}],
}
with patch.object(DomainStorage, "_analyze_guidance_file", return_value=fake_analysis) as mocked:
results = self.storage.analyze_guidance(
analysis_options={"granularity": "low"},
)
self.assertEqual(results[0]["guidance_analysis"], fake_analysis)
mocked.assert_called_once()
self.assertEqual(results[0]["file_id"], record["file_id"])
with open(self.storage_path, encoding="utf-8") as f:
data = json.load(f)
saved = data["domains"][0]["guidance_files"][0]
self.assertEqual(saved["guidance_analysis"]["granularity"], "low")
def test_analyze_guidance_filters_by_token_id(self):
self.storage.save_guidance_file("token-1", io.BytesIO(b"debt"), "debt.txt")
second = self.storage.save_guidance_file("token-2", io.BytesIO(b"trade"), "trade.txt")
fake_analysis = {"status": "done", "granularity": "high", "description_patterns": []}
with patch.object(DomainStorage, "_analyze_guidance_file", return_value=fake_analysis) as mocked:
results = self.storage.analyze_guidance(token_id="token-2")
self.assertEqual([item["file_id"] for item in results], [second["file_id"]])
mocked.assert_called_once()
with open(self.storage_path, encoding="utf-8") as f:
data = json.load(f)
self.assertNotIn("guidance_analysis", data["domains"][0]["guidance_files"][0])
self.assertEqual(data["domains"][1]["guidance_files"][0]["file_id"], second["file_id"])
def test_analyze_guidance_without_token_analyzes_all_files(self):
self.storage.save_guidance_file("token-1", io.BytesIO(b"debt"), "debt.txt")
self.storage.save_guidance_file("token-2", io.BytesIO(b"trade"), "trade.txt")
fake_analysis = {"status": "done", "granularity": "high", "description_patterns": []}
with patch.object(DomainStorage, "_analyze_guidance_file", return_value=fake_analysis) as mocked:
results = self.storage.analyze_guidance()
self.assertEqual(len(results), 2)
self.assertEqual(mocked.call_count, 2)
def test_analyze_guidance_rejects_unknown_token_id(self):
with self.assertRaisesRegex(ValueError, "token_id=missing"):
self.storage.analyze_guidance(token_id="missing")
def test_analyze_guidance_rejects_unknown_granularity(self):
with self.assertRaisesRegex(ValueError, "granularity"):
self.storage.analyze_guidance(analysis_options={"granularity": "middle"})
if __name__ == "__main__":
unittest.main()