test(business): smoke test every query template

Add a shared Kingdee sales-order fixture and execute every schema-listed business template at least once, ensuring each returns JSON-serializable output. Keep existing exact assertions for representative totals, rankings, staff, status, and delivery-plan templates.

Validation: python3 -m unittest discover -v; python3 -m compileall obsidian_wiki tests scripts; git diff --check
This commit is contained in:
Codex
2026-07-06 22:35:45 +00:00
parent 9885420fdb
commit 00ce531e53
+120 -83
View File
@@ -28,6 +28,91 @@ class BusinessFactsTests(unittest.TestCase):
def tearDown(self):
self.tempdir.cleanup()
def seed_template_fixture(self):
sync_kingdee_orders(
self.vault,
[
{
"id": "1001",
"billno": "SO-001",
"bizdate": "2026-06-03",
"customer_number": "C01",
"customer_name": "Customer A",
"totalallamount": "100.00",
"settlecurrency_number": "CNY",
"billstatus": "C",
"orderstatus": "D",
"closestatus": "A",
"org_name": "Org A",
"dept_name": "Dept A",
"operator_operatorname": "徐丽",
"billentry": [
{
"id": "L1",
"material_masterid_number": "P01",
"material_masterid_name": "Part 1",
"qty": "2",
"amountandtax": "60",
"project_name": "Project A",
"warehouse_name": "Warehouse A",
"orderdeliverentry": [
{
"id": "D1",
"d_plandate": "2026-06-10",
"d_plandeliverydate": "2026-06-08",
"d_planqty": "2",
}
],
},
{
"id": "L2",
"material_masterid_number": "P02",
"material_masterid_name": "Part 2",
"qty": "1",
"amountandtax": "40",
"project_name": "Project B",
"warehouse_name": "Warehouse B",
},
],
},
{
"id": "1002",
"billno": "SO-002",
"bizdate": "2026-06-04",
"customer_number": "C02",
"customer_name": "Customer B",
"totalallamount": "300.00",
"settlecurrency_number": "CNY",
"billstatus": "B",
"orderstatus": "C",
"closestatus": "A",
"org_name": "Org B",
"dept_name": "Dept B",
"operator_operatorname": "王五",
"h5a3_basedatafield2_operatorname": "徐丽",
"billentry": [
{
"id": "L1",
"material_masterid_number": "P01",
"material_masterid_name": "Part 1",
"qty": "3",
"amountandtax": "300",
"project_name": "Project A",
"warehouse_name": "Warehouse A",
"orderdeliverentry": [
{
"id": "D2",
"d_plandate": "2026-06-11",
"d_planqty": "3",
}
],
}
],
},
],
synced_at="2026-07-06T09:00:00Z",
)
def test_monthly_order_count_deduplicates_order_lines(self):
sync_kingdee_orders(
self.vault,
@@ -523,89 +608,7 @@ class BusinessFactsTests(unittest.TestCase):
self.assertIn("raw_snapshots", schema["sql_guardrails"]["forbidden_tables"])
def test_execute_business_templates_cover_core_totals_rankings_lists_and_delivery_plans(self):
sync_kingdee_orders(
self.vault,
[
{
"id": "1001",
"billno": "SO-001",
"bizdate": "2026-06-03",
"customer_number": "C01",
"customer_name": "Customer A",
"totalallamount": "100.00",
"settlecurrency_number": "CNY",
"billstatus": "C",
"orderstatus": "D",
"closestatus": "A",
"org_name": "Org A",
"dept_name": "Dept A",
"operator_operatorname": "徐丽",
"billentry": [
{
"id": "L1",
"material_masterid_number": "P01",
"material_masterid_name": "Part 1",
"qty": "2",
"amountandtax": "60",
"project_name": "Project A",
"warehouse_name": "Warehouse A",
"orderdeliverentry": [
{
"id": "D1",
"d_plandate": "2026-06-10",
"d_plandeliverydate": "2026-06-08",
"d_planqty": "2",
}
],
},
{
"id": "L2",
"material_masterid_number": "P02",
"material_masterid_name": "Part 2",
"qty": "1",
"amountandtax": "40",
"project_name": "Project B",
"warehouse_name": "Warehouse B",
},
],
},
{
"id": "1002",
"billno": "SO-002",
"bizdate": "2026-06-04",
"customer_number": "C02",
"customer_name": "Customer B",
"totalallamount": "300.00",
"settlecurrency_number": "CNY",
"billstatus": "B",
"orderstatus": "C",
"closestatus": "A",
"org_name": "Org B",
"dept_name": "Dept B",
"operator_operatorname": "王五",
"h5a3_basedatafield2_operatorname": "徐丽",
"billentry": [
{
"id": "L1",
"material_masterid_number": "P01",
"material_masterid_name": "Part 1",
"qty": "3",
"amountandtax": "300",
"project_name": "Project A",
"warehouse_name": "Warehouse A",
"orderdeliverentry": [
{
"id": "D2",
"d_plandate": "2026-06-11",
"d_planqty": "3",
}
],
}
],
},
],
synced_at="2026-07-06T09:00:00Z",
)
self.seed_template_fixture()
count = execute_business_template(self.db_path, "order_count", start_date="2026-06-01", end_date="2026-07-01")
sales = execute_business_template(self.db_path, "sales_amount", year=2026, month=6)
@@ -641,6 +644,40 @@ class BusinessFactsTests(unittest.TestCase):
[("B", 1), ("C", 1)],
)
def test_all_business_templates_execute_with_fixture_data(self):
self.seed_template_fixture()
required_values = {
"customer": "Customer A",
"product": "P01",
"staff": "徐丽",
}
templates = business_schema()["templates"]
template_names = [template["name"] for template in templates]
for template in templates:
params = {
"year": 2026,
"month": 6,
"limit": 5,
"granularity": "day",
"staff_role_scope": "all",
}
for required in template["required_parameters"]:
params[required] = required_values[required]
with self.subTest(template=template["name"]):
result = execute_business_template(self.db_path, template["name"], **params)
self.assertEqual(result["template"], template["name"])
self.assertIsInstance(result["data"], dict)
self.assertIn("answer", result)
self.assertEqual(result["last_sync"], "2026-07-06T09:00:00Z")
self.assertIsInstance(result["is_stale"], bool)
if "rows" in result:
self.assertIsInstance(result["rows"], list)
json.dumps(result, ensure_ascii=False)
self.assertEqual(len(template_names), len(set(template_names)))
def test_execute_business_template_rejects_unknown_or_missing_parameters(self):
with self.assertRaisesRegex(RuntimeError, "unknown business template"):
execute_business_template(self.db_path, "not_a_template", year=2026, month=6)