test_precommit_workflow.pyโข7.92 kB
"""
Unit tests for the workflow-based PrecommitTool
Tests the core functionality of the precommit workflow tool including:
- Tool metadata and configuration
- Request model validation
- Workflow step handling
- Tool categorization
"""
import pytest
from tools.models import ToolModelCategory
from tools.precommit import PrecommitRequest, PrecommitTool
class TestPrecommitWorkflowTool:
"""Test suite for the workflow-based PrecommitTool"""
def test_tool_metadata(self):
"""Test basic tool metadata"""
tool = PrecommitTool()
assert tool.get_name() == "precommit"
assert "git changes" in tool.get_description()
assert "systematic analysis" in tool.get_description()
def test_tool_model_category(self):
"""Test that precommit tool uses extended reasoning category"""
tool = PrecommitTool()
assert tool.get_model_category() == ToolModelCategory.EXTENDED_REASONING
def test_default_temperature(self):
"""Test analytical temperature setting"""
tool = PrecommitTool()
temp = tool.get_default_temperature()
# Should be analytical temperature (0.2)
assert temp == 0.2
def test_request_model_basic_validation(self):
"""Test basic request model validation"""
# Valid minimal workflow request
request = PrecommitRequest(
step="Initial validation step",
step_number=1,
total_steps=3,
next_step_required=True,
findings="Initial findings",
path="/test/repo", # Required for step 1
)
assert request.step == "Initial validation step"
assert request.step_number == 1
assert request.total_steps == 3
assert request.next_step_required is True
assert request.findings == "Initial findings"
assert request.path == "/test/repo"
def test_request_model_step_one_validation(self):
"""Test that step 1 requires path field"""
# Step 1 without path should fail
with pytest.raises(ValueError, match="Step 1 requires 'path' field"):
PrecommitRequest(
step="Initial validation step",
step_number=1,
total_steps=3,
next_step_required=True,
findings="Initial findings",
# Missing path for step 1
)
def test_request_model_later_steps_no_path_required(self):
"""Test that later steps don't require path"""
# Step 2+ without path should be fine
request = PrecommitRequest(
step="Continued validation",
step_number=2,
total_steps=3,
next_step_required=True,
findings="Detailed findings",
# No path needed for step 2+
)
assert request.step_number == 2
assert request.path is None
def test_request_model_optional_fields(self):
"""Test optional workflow fields"""
request = PrecommitRequest(
step="Validation with optional fields",
step_number=1,
total_steps=2,
next_step_required=False,
findings="Comprehensive findings",
path="/test/repo",
precommit_type="external",
files_checked=["/file1.py", "/file2.py"],
relevant_files=["/file1.py"],
relevant_context=["function_name", "class_name"],
issues_found=[{"severity": "medium", "description": "Test issue"}],
images=["/screenshot.png"],
)
assert request.precommit_type == "external"
assert len(request.files_checked) == 2
assert len(request.relevant_files) == 1
assert len(request.relevant_context) == 2
assert len(request.issues_found) == 1
assert len(request.images) == 1
def test_request_model_backtracking(self):
"""Test backtracking functionality"""
request = PrecommitRequest(
step="Backtracking from previous step",
step_number=3,
total_steps=4,
next_step_required=True,
findings="Revised findings after backtracking",
backtrack_from_step=2, # Backtrack from step 2
)
assert request.backtrack_from_step == 2
assert request.step_number == 3
def test_precommit_specific_fields(self):
"""Test precommit-specific configuration fields"""
request = PrecommitRequest(
step="Validation with git config",
step_number=1,
total_steps=1,
next_step_required=False,
findings="Complete validation",
path="/repo",
compare_to="main",
include_staged=True,
include_unstaged=False,
focus_on="security issues",
severity_filter="high",
)
assert request.compare_to == "main"
assert request.include_staged is True
assert request.include_unstaged is False
assert request.focus_on == "security issues"
assert request.severity_filter == "high"
def test_precommit_type_validation(self):
"""Test precommit type validation"""
valid_types = ["external", "internal"]
for precommit_type in valid_types:
request = PrecommitRequest(
step="Test precommit type",
step_number=1,
total_steps=1,
next_step_required=False,
findings="Test findings",
path="/repo",
precommit_type=precommit_type,
)
assert request.precommit_type == precommit_type
# Test default is external
request = PrecommitRequest(
step="Test default type",
step_number=1,
total_steps=1,
next_step_required=False,
findings="Test findings",
path="/repo",
)
assert request.precommit_type == "external"
def test_severity_filter_options(self):
"""Test severity filter validation"""
valid_severities = ["critical", "high", "medium", "low", "all"]
for severity in valid_severities:
request = PrecommitRequest(
step="Test severity filter",
step_number=1,
total_steps=1,
next_step_required=False,
findings="Test findings",
path="/repo",
severity_filter=severity,
)
assert request.severity_filter == severity
def test_input_schema_generation(self):
"""Test that input schema is generated correctly"""
tool = PrecommitTool()
schema = tool.get_input_schema()
# Check basic schema structure
assert schema["type"] == "object"
assert "properties" in schema
assert "required" in schema
# Check required fields are present
required_fields = {"step", "step_number", "total_steps", "next_step_required", "findings"}
assert all(field in schema["properties"] for field in required_fields)
# Check model field is present and configured correctly
assert "model" in schema["properties"]
assert schema["properties"]["model"]["type"] == "string"
def test_workflow_request_model_method(self):
"""Test get_workflow_request_model returns correct model"""
tool = PrecommitTool()
assert tool.get_workflow_request_model() == PrecommitRequest
assert tool.get_request_model() == PrecommitRequest
def test_system_prompt_integration(self):
"""Test system prompt integration"""
tool = PrecommitTool()
system_prompt = tool.get_system_prompt()
# Should get the precommit prompt
assert isinstance(system_prompt, str)
assert len(system_prompt) > 0