fix: update tests to match action node schema (next_node_id, not children)
- Update _make_valid_tree() in test_ai_tree_validator to use next_node_id on action nodes (solution is a sibling, not a child) - Fix test_dead_end_action_node → test_dead_end_decision_node (action nodes don't have child-based dead ends; dead ends are decision nodes with no children) - Add test_action_missing_next_node_id for the new validation rule - Update BRANCH_DETAIL_JSON in test_ai_endpoints to use next_node_id pattern - Update test_draft_trees.py to use "title" field for action/solution nodes (tree_validation.py was updated this branch to require "title" not "action"/"solution") Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,11 @@ from app.core.ai_tree_validator import validate_generated_tree, count_tree_stats
|
||||
|
||||
|
||||
def _make_valid_tree():
|
||||
"""Helper: minimal valid tree for testing."""
|
||||
"""Helper: minimal valid tree for testing.
|
||||
|
||||
Action nodes use next_node_id to point to a sibling (not children).
|
||||
The solution following an action is a sibling under the parent decision.
|
||||
"""
|
||||
return {
|
||||
"id": "root",
|
||||
"type": "decision",
|
||||
@@ -44,14 +48,13 @@ def _make_valid_tree():
|
||||
"title": "Restart the Service",
|
||||
"description": "Restart the service and verify.",
|
||||
"commands": ["Restart-Service -Name 'TestService'"],
|
||||
"children": [
|
||||
{
|
||||
"id": "service-resolved",
|
||||
"type": "solution",
|
||||
"title": "Service Restored",
|
||||
"description": "Service is running after restart.",
|
||||
},
|
||||
],
|
||||
"next_node_id": "service-resolved",
|
||||
},
|
||||
{
|
||||
"id": "service-resolved",
|
||||
"type": "solution",
|
||||
"title": "Service Restored",
|
||||
"description": "Service is running after restart.",
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -107,6 +110,12 @@ class TestNodeValidation:
|
||||
errors = validate_generated_tree(tree)
|
||||
assert any("at least 2 options" in e for e in errors)
|
||||
|
||||
def test_action_missing_next_node_id(self):
|
||||
tree = _make_valid_tree()
|
||||
del tree["children"][1]["next_node_id"]
|
||||
errors = validate_generated_tree(tree)
|
||||
assert any("missing 'next_node_id'" in e for e in errors)
|
||||
|
||||
|
||||
class TestReferenceIntegrity:
|
||||
def test_option_references_nonexistent_child(self):
|
||||
@@ -156,18 +165,18 @@ class TestGlobalChecks:
|
||||
{"id": "o1", "label": "A", "next_node_id": "only-solution"},
|
||||
{"id": "o2", "label": "B", "next_node_id": "only-solution"},
|
||||
]
|
||||
# Now restart-service branch has 1 solution, check-logs has 1 = total 2
|
||||
# Remove one more to get to 1
|
||||
tree["children"][1]["children"] = []
|
||||
# Remove the solution that restart-service points to
|
||||
tree["children"].pop(2) # remove service-resolved
|
||||
errors = validate_generated_tree(tree)
|
||||
assert any("solution" in e.lower() for e in errors)
|
||||
|
||||
|
||||
class TestDeadEndDetection:
|
||||
def test_dead_end_action_node(self):
|
||||
def test_dead_end_decision_node(self):
|
||||
"""A decision node with no children is a dead end."""
|
||||
tree = _make_valid_tree()
|
||||
# Remove restart-service's children — becomes dead end
|
||||
tree["children"][1]["children"] = []
|
||||
# Remove children from check-logs decision node — becomes dead end
|
||||
tree["children"][0]["children"] = []
|
||||
errors = validate_generated_tree(tree)
|
||||
assert any("dead end" in e for e in errors)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user