""" Integration tests for prompt CLI commands. Tests Click CLI commands with CliRunner and a real SQLite database. """ import json import pytest import tempfile from pathlib import Path from click.testing import CliRunner from markitect.prompts.cli import prompt_commands from markitect.prompts.dependencies.models import DependencyEdge, EdgeType from markitect.prompts.dependencies.repository import SQLiteDependencyRepository from markitect.prompts.models import Artifact, ArtifactType from markitect.prompts.repositories.sqlite import SQLiteArtifactRepository @pytest.fixture def temp_db(): """Create temporary database for testing.""" with tempfile.NamedTemporaryFile(suffix=".db", delete=False) as f: db_path = f.name yield db_path Path(db_path).unlink(missing_ok=True) @pytest.fixture def runner(): """Click CLI test runner.""" return CliRunner() @pytest.fixture def seeded_db(temp_db): """Seed database with test data and return path.""" art_repo = SQLiteArtifactRepository(temp_db) dep_repo = SQLiteDependencyRepository(temp_db) a = Artifact.create(space_id="s", name="a", content="content-a", artifact_type=ArtifactType.CONTENT) b = Artifact.create(space_id="s", name="b", content="content-b", artifact_type=ArtifactType.CONTENT) a = art_repo.create(a) b = art_repo.create(b) edge = DependencyEdge.create( source_artifact_id=a.id, target_artifact_id=b.id, run_id="run-1", edge_type=EdgeType.REQUIRES, ) dep_repo.create(edge) return temp_db, a.id, b.id class TestTraceCommand: """Tests for the 'trace' command.""" def test_trace_existing_artifact(self, runner, seeded_db): """Test tracing an existing artifact.""" db_path, art_a, art_b = seeded_db result = runner.invoke( prompt_commands, ["trace", art_a, "--database", db_path] ) assert result.exit_code == 0 data = json.loads(result.output) assert data["artifact_id"] == art_a def test_trace_nonexistent_artifact(self, runner, temp_db): """Test tracing a non-existent artifact.""" # Initialize tables SQLiteArtifactRepository(temp_db) SQLiteDependencyRepository(temp_db) result = runner.invoke( prompt_commands, ["trace", "nonexistent", "--database", temp_db] ) assert result.exit_code != 0 class TestGraphCommand: """Tests for the 'graph' command.""" def test_graph_mermaid(self, runner, seeded_db): """Test graph export in mermaid format.""" db_path, art_a, _ = seeded_db result = runner.invoke( prompt_commands, ["graph", art_a, "--format", "mermaid", "--database", db_path], ) assert result.exit_code == 0 assert "graph LR" in result.output def test_graph_dot(self, runner, seeded_db): """Test graph export in DOT format.""" db_path, art_a, _ = seeded_db result = runner.invoke( prompt_commands, ["graph", art_a, "--format", "dot", "--database", db_path], ) assert result.exit_code == 0 assert "digraph" in result.output class TestRunsCommand: """Tests for the 'runs' command.""" def test_runs_empty(self, runner, seeded_db): """Test listing runs when none are registered.""" db_path, _, _ = seeded_db result = runner.invoke( prompt_commands, ["runs", "--database", db_path] ) assert result.exit_code == 0 assert "No runs found" in result.output def test_runs_with_limit(self, runner, seeded_db): """Test listing runs with limit option.""" db_path, _, _ = seeded_db result = runner.invoke( prompt_commands, ["runs", "--limit", "5", "--database", db_path] ) assert result.exit_code == 0 class TestDebtCommand: """Tests for the 'debt' command.""" def test_debt_no_stale(self, runner, seeded_db): """Test debt when no stale artifacts exist.""" db_path, _, _ = seeded_db result = runner.invoke( prompt_commands, ["debt", "--database", db_path] ) assert result.exit_code == 0 assert "No stale artifacts" in result.output def test_debt_for_artifact(self, runner, seeded_db): """Test debt for a specific artifact.""" db_path, art_a, _ = seeded_db result = runner.invoke( prompt_commands, ["debt", "--artifact", art_a, "--database", db_path], ) assert result.exit_code == 0 assert "No impact debt" in result.output class TestStatsCommand: """Tests for the 'stats' command.""" def test_stats_with_data(self, runner, seeded_db): """Test stats with real graph data.""" db_path, _, _ = seeded_db result = runner.invoke( prompt_commands, ["stats", "--database", db_path] ) assert result.exit_code == 0 data = json.loads(result.output) assert data["total_nodes"] == 2 assert data["total_edges"] == 1 assert data["has_cycles"] is False def test_stats_empty_db(self, runner, temp_db): """Test stats on empty database.""" SQLiteArtifactRepository(temp_db) SQLiteDependencyRepository(temp_db) result = runner.invoke( prompt_commands, ["stats", "--database", temp_db] ) assert result.exit_code == 0 data = json.loads(result.output) assert data["total_nodes"] == 0 assert data["total_edges"] == 0