Spaces:
Configuration error
Configuration error
File size: 5,979 Bytes
8904f7b 994a04c 8904f7b 994a04c 8904f7b 994a04c 8904f7b 994a04c 8904f7b 994a04c 8904f7b 994a04c 8904f7b 994a04c 8904f7b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | """Unit tests for the Repository Knowledge Graph architecture, builder, navigator, and endpoints."""
import sys
import os
from unittest.mock import MagicMock, patch
from fastapi.testclient import TestClient
# Ensure root directory is in sys.path
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from backend.api import app
from models.knowledge_graph import (
KnowledgeGraph,
KnowledgeGraphNode,
KnowledgeGraphEdge,
KnowledgeGraphSummary,
)
from services.knowledge_graph_builder import RepositoryKnowledgeGraphBuilder
from services.knowledge_graph_navigator import RepositoryKnowledgeGraphNavigator
client = TestClient(app)
def test_knowledge_graph_models() -> None:
"""Verifies that Knowledge Graph Pydantic models can be instantiated and validated."""
node = KnowledgeGraphNode(
id="repo1", type="repository", properties={"name": "test-repo"}
)
edge = KnowledgeGraphEdge(source="repo1", target="repo1::health", type="HAS_HEALTH")
kg = KnowledgeGraph(
repository_name="test-owner/test-repo", nodes=[node], edges=[edge]
)
assert kg.repository_name == "test-owner/test-repo"
assert len(kg.nodes) == 1
assert kg.nodes[0].id == "repo1"
assert kg.edges[0].type == "HAS_HEALTH"
@patch("backend.dependencies.symbol_service")
@patch("backend.dependencies.graph_service")
@patch("backend.dependencies.repository_twin_builder")
def test_knowledge_graph_builder_and_navigator(mock_tb, mock_gs, mock_ss) -> None:
"""Verifies that KnowledgeGraphBuilder correctly composes state and navigator navigates correctly."""
repo_name = "test-owner/test-repo"
# Mock Twin
mock_twin = MagicMock()
mock_twin.metadata = {"tech_stack": ["Python"], "total_loc": 100}
mock_twin.files = ["main.py", "utils.py"]
mock_twin.health_summary = {"overall_score": 90.0, "grade": "A", "breakdown": {}}
mock_twin.compliance_summary = {
"status": "compliant",
"reasons": [],
"dead_code_ratio": 0.0,
}
mock_twin.architecture_summary = {
"cycles_count": 0,
"strongly_connected_components": 1,
}
mock_twin.symbols_summary = {"total_symbols": 0}
mock_tb.build_twin.return_value = mock_twin
# Mock Symbol Service
mock_ss.load.return_value = MagicMock(symbols=[])
# Mock Dependency Graph Service
mock_dep_graph = MagicMock()
mock_dep_graph.edges.return_value = [("main.py", "utils.py")]
mock_gs.load_graph.return_value = mock_dep_graph
# 1. Test Builder
mock_cache = MagicMock()
mock_cache.get.return_value = None
builder = RepositoryKnowledgeGraphBuilder(
twin_builder=mock_tb,
cache=mock_cache,
)
kg = builder.build_graph(repo_name)
assert kg.repository_name == repo_name
# Assert nodes presence
node_ids = {node.id for node in kg.nodes}
assert repo_name in node_ids
assert f"{repo_name}::health" in node_ids
assert f"{repo_name}::compliance" in node_ids
assert f"{repo_name}::main.py" in node_ids
assert f"{repo_name}::utils.py" in node_ids
# Assert edges presence
edge_types = {edge.type for edge in kg.edges}
assert "HAS_HEALTH" in edge_types
assert "HAS_COMPLIANCE" in edge_types
assert "CONTAINS" in edge_types
assert "IMPORTS" in edge_types
summary = builder.build_graph_summary(repo_name)
assert summary.repository_name == repo_name
assert summary.nodes_count > 0
assert summary.node_types_breakdown["repository"] == 1
# 2. Test Navigator
navigator = RepositoryKnowledgeGraphNavigator(builder=builder)
# find_node
node = navigator.find_node(repo_name, repo_name)
assert node is not None
assert node.type == "repository"
# find_neighbors
neighbors = navigator.find_neighbors(repo_name, repo_name)
neighbor_ids = {n.id for n in neighbors}
assert f"{repo_name}::health" in neighbor_ids
# find_shortest_path
path = navigator.find_shortest_path(repo_name, repo_name, f"{repo_name}::main.py")
assert len(path) == 2
assert path[0] == repo_name
assert path[1] == f"{repo_name}::main.py"
# find_impact
impact = navigator.find_impact(repo_name, f"{repo_name}::main.py")
assert f"{repo_name}::utils.py" in impact
def test_knowledge_graph_endpoints() -> None:
"""Verifies that HTTP endpoints for knowledge-graph work correctly with mocks."""
repo_name = "test-owner/test-repo"
with (
patch(
"backend.routers.knowledge_graph.repository_knowledge_graph_builder"
) as mock_builder,
patch("backend.routers.knowledge_graph.repository_knowledge_graph_navigator"),
):
mock_builder.build_graph.return_value = KnowledgeGraph(
repository_name=repo_name,
nodes=[KnowledgeGraphNode(id=repo_name, type="repository")],
edges=[],
)
mock_builder.build_graph_summary.return_value = KnowledgeGraphSummary(
repository_name=repo_name,
nodes_count=1,
edges_count=0,
node_types_breakdown={"repository": 1},
edge_types_breakdown={},
)
mock_builder.twin_builder.store = {repo_name: {}}
# Test full KG route
response = client.get("/api/repositories/test-owner/test-repo/knowledge-graph")
assert response.status_code == 200
assert response.json()["repository_name"] == repo_name
# Test KG summary route
response_summary = client.get(
"/api/repositories/test-owner/test-repo/knowledge-graph/summary"
)
assert response_summary.status_code == 200
assert response_summary.json()["nodes_count"] == 1
# Test versioned v1 route
response_v1 = client.get(
"/api/v1/repositories/test-owner/test-repo/knowledge-graph/summary"
)
assert response_v1.status_code == 200
assert response_v1.json()["nodes_count"] == 1
|