fix: update remaining tests and session_to_tree for title field rename

- test_tree_validation.py: replace "action"/"solution" content fields with "title"
- test_procedural_flows.py: update solution node fixtures to use "title"
- test_save_session_as_tree.py: update fixtures and assertions for "title" field
- session_to_tree.py: generate "title" instead of "action"/"solution" on converted nodes;
  fall back to legacy field names when reading from old tree snapshots for compatibility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-22 23:55:37 -05:00
parent 5acf94b6c2
commit 8475f780d1
4 changed files with 47 additions and 47 deletions

View File

@@ -28,7 +28,7 @@ def convert_session_to_tree(
return {
"id": str(uuid.uuid4()),
"type": "solution",
"solution": "Session had no recorded path",
"title": "Session had no recorded path",
"children": []
}
@@ -63,7 +63,7 @@ def convert_session_to_tree(
new_node = {
"id": node_id,
"type": "action",
"action": f"Step from original tree (node {node_id})",
"title": f"Step from original tree (node {node_id})",
"children": []
}
@@ -130,15 +130,15 @@ def _create_node_from_original(
if decision and decision.get("answer"):
new_node["question"] += f"\n\nAnswer: {decision['answer']}"
elif node_type == "action":
new_node["action"] = original_node.get("action", "")
new_node["title"] = original_node.get("title", original_node.get("action", ""))
if decision and decision.get("action_performed"):
new_node["action"] = decision["action_performed"]
new_node["title"] = decision["action_performed"]
if decision and decision.get("command_output"):
output = decision["command_output"].strip()
if output:
new_node["action"] += f"\n\nCommand Output:\n{output}"
new_node["title"] += f"\n\nCommand Output:\n{output}"
elif node_type == "solution":
new_node["solution"] = original_node.get("solution", "")
new_node["title"] = original_node.get("title", original_node.get("solution", ""))
return new_node
@@ -169,18 +169,18 @@ def _create_node_from_custom_step(
if step_type == "decision":
new_node["question"] = content
elif step_type == "action":
new_node["action"] = content
new_node["title"] = content
elif step_type == "solution":
new_node["solution"] = content
new_node["title"] = content
# Add notes if present
if custom_step.get("notes"):
if step_type == "decision":
new_node["question"] += f"\n\nNotes: {custom_step['notes']}"
elif step_type == "action":
new_node["action"] += f"\n\nNotes: {custom_step['notes']}"
new_node["title"] += f"\n\nNotes: {custom_step['notes']}"
elif step_type == "solution":
new_node["solution"] += f"\n\nNotes: {custom_step['notes']}"
new_node["title"] += f"\n\nNotes: {custom_step['notes']}"
return new_node

View File

@@ -228,8 +228,8 @@ class TestCanPublishTreeDispatch:
"type": "decision",
"question": "Test?",
"children": [
{"id": "y", "type": "solution", "solution": "Yes"},
{"id": "n", "type": "solution", "solution": "No"},
{"id": "y", "type": "solution", "title": "Yes"},
{"id": "n", "type": "solution", "title": "No"},
]
}
can, errors = can_publish_tree(structure, "My Tree", tree_type="troubleshooting")

View File

@@ -20,7 +20,7 @@ class TestSessionToTreeConversion:
"""Test converting a session with no path."""
tree_structure = convert_session_to_tree([], {}, [], [])
assert tree_structure["type"] == "solution"
assert "no recorded path" in tree_structure["solution"].lower()
assert "no recorded path" in tree_structure["title"].lower()
def test_convert_simple_linear_path(self):
"""Test converting a simple linear path."""
@@ -29,8 +29,8 @@ class TestSessionToTreeConversion:
"type": "decision",
"question": "Is it working?",
"children": [
{"id": "yes", "type": "solution", "solution": "Great!"},
{"id": "no", "type": "action", "action": "Fix it"}
{"id": "yes", "type": "solution", "title": "Great!"},
{"id": "no", "type": "action", "title": "Fix it"}
]
}
path_taken = ["root", "no"]
@@ -51,7 +51,7 @@ class TestSessionToTreeConversion:
tree_snapshot = {
"id": "root",
"type": "solution",
"solution": "Done"
"title": "Done"
}
custom_step_id = "custom-123"
path_taken = ["root", custom_step_id]
@@ -70,7 +70,7 @@ class TestSessionToTreeConversion:
assert len(result["children"]) == 1
custom_node = result["children"][0]
assert custom_node["type"] == "action"
assert "Custom troubleshooting step" in custom_node["action"]
assert "Custom troubleshooting step" in custom_node["title"]
def test_find_node_in_tree(self):
"""Test finding a node in nested tree structure."""
@@ -142,7 +142,7 @@ class TestSaveSessionAsTreeAPI:
tree = Tree(
name="Test Tree",
description="Test",
tree_structure={"id": "root", "type": "solution", "solution": "Fix"},
tree_structure={"id": "root", "type": "solution", "title": "Fix"},
author_id=UUID(test_user["user_data"]["id"]),
account_id=UUID(test_user["user_data"]["account_id"]),
status='published'
@@ -187,7 +187,7 @@ class TestSaveSessionAsTreeAPI:
tree = Tree(
name="Original Tree",
tree_structure={"id": "root", "type": "solution", "solution": "Fix"},
tree_structure={"id": "root", "type": "solution", "title": "Fix"},
author_id=UUID(test_user["user_data"]["id"]),
account_id=UUID(test_user["user_data"]["account_id"]),
status='published'
@@ -227,7 +227,7 @@ class TestSaveSessionAsTreeAPI:
# Create a simple tree with just a solution (will convert to valid linear tree)
tree = Tree(
name="Test Tree",
tree_structure={"id": "root", "type": "solution", "solution": "Fixed"},
tree_structure={"id": "root", "type": "solution", "title": "Fixed"},
author_id=UUID(test_user["user_data"]["id"]),
account_id=UUID(test_user["user_data"]["account_id"]),
status='published'
@@ -267,7 +267,7 @@ class TestSaveSessionAsTreeAPI:
tree = Tree(
name="Original Tree",
tree_structure={"id": "root", "type": "solution", "solution": "Fix"},
tree_structure={"id": "root", "type": "solution", "title": "Fix"},
author_id=UUID(test_user["user_data"]["id"]),
account_id=UUID(test_user["user_data"]["account_id"]),
status='published'
@@ -326,7 +326,7 @@ class TestSaveSessionAsTreeAPI:
# Create a tree
tree = Tree(
name="Test Tree",
tree_structure={"id": "root", "type": "solution", "solution": "Fix"},
tree_structure={"id": "root", "type": "solution", "title": "Fix"},
author_id=UUID(test_user["user_data"]["id"]),
account_id=UUID(test_user["user_data"]["account_id"]),
status='published'

View File

@@ -15,7 +15,7 @@ class TestValidateTreeStructure:
def test_valid_solution_tree(self):
valid, errors = validate_tree_structure({
"id": "root", "type": "solution", "solution": "Done"
"id": "root", "type": "solution", "title": "Done"
})
assert valid
assert errors == []
@@ -26,8 +26,8 @@ class TestValidateTreeStructure:
"type": "decision",
"question": "Is it on?",
"children": [
{"id": "yes", "type": "solution", "solution": "Great"},
{"id": "no", "type": "action", "action": "Turn it on"},
{"id": "yes", "type": "solution", "title": "Great"},
{"id": "no", "type": "action", "title": "Turn it on"},
],
})
assert valid
@@ -39,7 +39,7 @@ class TestValidateTreeStructure:
assert any("empty" in e["message"].lower() for e in errors)
def test_missing_id_on_root(self):
valid, errors = validate_tree_structure({"type": "solution", "solution": "X"})
valid, errors = validate_tree_structure({"type": "solution", "title": "X"})
assert not valid
assert any("id" in e["field"] for e in errors)
@@ -67,7 +67,7 @@ class TestValidateTreeStructure:
"type": "decision",
"question": "Q?",
"children": [
{"id": "only", "type": "solution", "solution": "S"},
{"id": "only", "type": "solution", "title": "S"},
],
})
assert not valid
@@ -80,29 +80,29 @@ class TestValidateTreeStructure:
})
assert valid
def test_action_missing_action_field(self):
def test_action_missing_title_field(self):
valid, errors = validate_tree_structure({
"id": "root", "type": "action"
})
assert not valid
assert any("action" in e["message"].lower() for e in errors)
assert any("title" in e["message"].lower() for e in errors)
def test_action_with_empty_action(self):
def test_action_with_empty_title(self):
valid, errors = validate_tree_structure({
"id": "root", "type": "action", "action": ""
"id": "root", "type": "action", "title": ""
})
assert not valid
def test_solution_missing_solution_field(self):
def test_solution_missing_title_field(self):
valid, errors = validate_tree_structure({
"id": "root", "type": "solution"
})
assert not valid
assert any("solution" in e["message"].lower() for e in errors)
assert any("title" in e["message"].lower() for e in errors)
def test_solution_with_empty_solution(self):
def test_solution_with_empty_title(self):
valid, errors = validate_tree_structure({
"id": "root", "type": "solution", "solution": ""
"id": "root", "type": "solution", "title": ""
})
assert not valid
@@ -119,8 +119,8 @@ class TestValidateTreeStructure:
"type": "decision",
"question": "Q?",
"children": [
{"type": "solution", "solution": "S1"},
{"id": "c2", "type": "solution", "solution": "S2"},
{"type": "solution", "title": "S1"},
{"id": "c2", "type": "solution", "title": "S2"},
],
})
assert not valid
@@ -133,7 +133,7 @@ class TestValidateTreeStructure:
"question": "Q?",
"children": [
{"id": "c1"},
{"id": "c2", "type": "solution", "solution": "S2"},
{"id": "c2", "type": "solution", "title": "S2"},
],
})
assert not valid
@@ -151,11 +151,11 @@ class TestValidateTreeStructure:
"type": "decision",
"question": "Level 2?",
"children": [
{"id": "l3a", "type": "solution", "solution": "Deep"},
{"id": "l3b", "type": "solution"}, # Missing solution
{"id": "l3a", "type": "solution", "title": "Deep"},
{"id": "l3b", "type": "solution"}, # Missing title
],
},
{"id": "l2b", "type": "solution", "solution": "Shallow"},
{"id": "l2b", "type": "solution", "title": "Shallow"},
],
})
assert not valid
@@ -167,8 +167,8 @@ class TestValidateTreeStructure:
"type": "decision",
"question": "Q?",
"children": [
{"id": "c1", "type": "solution"}, # missing solution
{"id": "c2", "type": "action"}, # missing action
{"id": "c1", "type": "solution"}, # missing title
{"id": "c2", "type": "action"}, # missing title
],
})
assert not valid
@@ -179,7 +179,7 @@ class TestCanPublishTree:
def test_valid_tree_can_publish(self):
can, errors = can_publish_tree(
{"id": "root", "type": "solution", "solution": "Done"},
{"id": "root", "type": "solution", "title": "Done"},
"My Tree"
)
assert can
@@ -187,7 +187,7 @@ class TestCanPublishTree:
def test_empty_name_cannot_publish(self):
can, errors = can_publish_tree(
{"id": "root", "type": "solution", "solution": "Done"},
{"id": "root", "type": "solution", "title": "Done"},
""
)
assert not can
@@ -195,14 +195,14 @@ class TestCanPublishTree:
def test_whitespace_name_cannot_publish(self):
can, errors = can_publish_tree(
{"id": "root", "type": "solution", "solution": "Done"},
{"id": "root", "type": "solution", "title": "Done"},
" "
)
assert not can
def test_none_name_cannot_publish(self):
can, errors = can_publish_tree(
{"id": "root", "type": "solution", "solution": "Done"},
{"id": "root", "type": "solution", "title": "Done"},
None
)
assert not can