Files
goodbuddy/resources/skills/product-evidence/tests/test_validate_evidence.py
T

114 lines
4.3 KiB
Python

import copy
import importlib.util
import json
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
SKILL_DIR = Path(__file__).resolve().parents[1]
SCRIPT = SKILL_DIR / "scripts" / "validate_evidence.py"
SPEC = importlib.util.spec_from_file_location("validate_evidence", SCRIPT)
validate_evidence = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(validate_evidence)
class ProductEvidenceTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
template = SKILL_DIR / "templates" / "product-evidence.example.json"
cls.valid_data = json.loads(template.read_text(encoding="utf-8"))
def test_example_manifest_is_valid(self):
errors, warnings = validate_evidence.validate_manifest(self.valid_data)
self.assertEqual(errors, [])
self.assertEqual(warnings, [])
def test_rejects_duplicate_ids_and_unknown_references(self):
data = copy.deepcopy(self.valid_data)
data["parameters"][0]["id"] = "FEAT-001"
data["claims"][0]["evidence_ids"] = ["EVD-MISSING"]
errors, _ = validate_evidence.validate_manifest(data)
messages = "\n".join(item["message"] for item in errors)
self.assertIn("重复", messages)
self.assertIn("引用不存在", messages)
def test_rejects_secret_in_evidence_source(self):
data = copy.deepcopy(self.valid_data)
data["evidence"][0]["source"] = "https://example.test/doc?token=secret"
errors, _ = validate_evidence.validate_manifest(data)
self.assertTrue(
any("密钥" in item["message"] for item in errors)
)
def test_placeholder_is_warning(self):
data = copy.deepcopy(self.valid_data)
data["product"]["summary"] = "TODO"
errors, warnings = validate_evidence.validate_manifest(data)
self.assertEqual(errors, [])
self.assertTrue(warnings)
def test_rejects_record_more_public_than_evidence(self):
data = copy.deepcopy(self.valid_data)
for record in data["evidence"]:
if record["id"] == "EVD-001":
record["disclosure"] = "restricted"
errors, _ = validate_evidence.validate_manifest(data)
self.assertTrue(
any("仅为 restricted" in item["message"] for item in errors)
)
def test_restricted_parameter_is_not_a_public_channel_warning(self):
data = copy.deepcopy(self.valid_data)
data["parameters"][0]["disclosure"] = "restricted"
for record in data["evidence"]:
if record["id"] in data["parameters"][0]["evidence_ids"]:
record["disclosure"] = "restricted"
data["claims"][0]["evidence_ids"] = []
data["claims"][0]["type"] = "goal"
errors, warnings = validate_evidence.validate_manifest(
data, channel="public"
)
self.assertEqual(errors, [])
self.assertEqual(warnings, [])
def test_public_channel_rejects_internal_evidence(self):
data = copy.deepcopy(self.valid_data)
claim = data["claims"][0]
claim["allowed_outputs"] = ["one-pager"]
evidence_id = claim["evidence_ids"][0]
for record in data["evidence"]:
if record["id"] == evidence_id:
record["disclosure"] = "internal"
for parameter in data["parameters"]:
if evidence_id in parameter.get("evidence_ids", []):
parameter["disclosure"] = "internal"
errors, _ = validate_evidence.validate_manifest(data, channel="public")
self.assertTrue(
any("不足以支撑 public" in item["message"] for item in errors)
)
errors, _ = validate_evidence.validate_manifest(data, channel="internal")
self.assertEqual(errors, [])
def test_cli_json_report(self):
with tempfile.TemporaryDirectory() as tmp:
manifest = Path(tmp) / "product-evidence.json"
manifest.write_text(
json.dumps(self.valid_data, ensure_ascii=False),
encoding="utf-8",
)
result = subprocess.run(
[sys.executable, str(SCRIPT), str(manifest), "--json"],
check=True,
capture_output=True,
text=True,
)
report = json.loads(result.stdout)
self.assertTrue(report["valid"])
if __name__ == "__main__":
unittest.main()