Navegador

navegador / tests / test_enrichment_spring.py
Source Blame History 273 lines
93cfcc4… lmata 1 """Tests for navegador.enrichment.spring — SpringEnricher."""
93cfcc4… lmata 2
93cfcc4… lmata 3 from unittest.mock import MagicMock
93cfcc4… lmata 4
93cfcc4… lmata 5 import pytest
93cfcc4… lmata 6
93cfcc4… lmata 7 from navegador.enrichment.base import EnrichmentResult, FrameworkEnricher
93cfcc4… lmata 8 from navegador.enrichment.spring import SpringEnricher
93cfcc4… lmata 9 from navegador.graph.store import GraphStore
93cfcc4… lmata 10
93cfcc4… lmata 11
93cfcc4… lmata 12 # ── Helpers ───────────────────────────────────────────────────────────────────
93cfcc4… lmata 13
93cfcc4… lmata 14
93cfcc4… lmata 15 def _mock_store(result_set=None):
93cfcc4… lmata 16 """Return a GraphStore backed by a mock FalkorDB graph."""
93cfcc4… lmata 17 client = MagicMock()
93cfcc4… lmata 18 graph = MagicMock()
93cfcc4… lmata 19 graph.query.return_value = MagicMock(result_set=result_set)
93cfcc4… lmata 20 client.select_graph.return_value = graph
93cfcc4… lmata 21 return GraphStore(client)
93cfcc4… lmata 22
93cfcc4… lmata 23
93cfcc4… lmata 24 def _store_with_side_effect(side_effect):
93cfcc4… lmata 25 """Return a GraphStore whose graph.query uses a side_effect callable."""
93cfcc4… lmata 26 client = MagicMock()
93cfcc4… lmata 27 graph = MagicMock()
93cfcc4… lmata 28 graph.query.side_effect = side_effect
93cfcc4… lmata 29 client.select_graph.return_value = graph
93cfcc4… lmata 30 return GraphStore(client)
93cfcc4… lmata 31
93cfcc4… lmata 32
93cfcc4… lmata 33 # ── Identity / contract ───────────────────────────────────────────────────────
93cfcc4… lmata 34
93cfcc4… lmata 35
93cfcc4… lmata 36 class TestSpringEnricherIdentity:
93cfcc4… lmata 37 def test_framework_name(self):
93cfcc4… lmata 38 store = _mock_store()
93cfcc4… lmata 39 assert SpringEnricher(store).framework_name == "spring"
93cfcc4… lmata 40
93cfcc4… lmata 41 def test_is_framework_enricher_subclass(self):
93cfcc4… lmata 42 assert issubclass(SpringEnricher, FrameworkEnricher)
93cfcc4… lmata 43
2c266d2… lmata 44 def test_detection_patterns_contains_org_springframework(self):
2c266d2… lmata 45 store = _mock_store()
2c266d2… lmata 46 assert "org.springframework" in SpringEnricher(store).detection_patterns
2c266d2… lmata 47
2c266d2… lmata 48 def test_detection_files_contains_application_properties(self):
2c266d2… lmata 49 store = _mock_store()
2c266d2… lmata 50 assert "application.properties" in SpringEnricher(store).detection_files
2c266d2… lmata 51
2c266d2… lmata 52 def test_detection_files_contains_application_yml(self):
2c266d2… lmata 53 store = _mock_store()
2c266d2… lmata 54 assert "application.yml" in SpringEnricher(store).detection_files
2c266d2… lmata 55
2c266d2… lmata 56 def test_detection_patterns_has_one_entry(self):
2c266d2… lmata 57 store = _mock_store()
2c266d2… lmata 58 assert len(SpringEnricher(store).detection_patterns) == 1
93cfcc4… lmata 59
93cfcc4… lmata 60
93cfcc4… lmata 61 # ── enrich() return type ──────────────────────────────────────────────────────
93cfcc4… lmata 62
93cfcc4… lmata 63
93cfcc4… lmata 64 class TestSpringEnricherEnrichReturnType:
93cfcc4… lmata 65 def test_returns_enrichment_result(self):
93cfcc4… lmata 66 store = _mock_store(result_set=[])
93cfcc4… lmata 67 result = SpringEnricher(store).enrich()
93cfcc4… lmata 68 assert isinstance(result, EnrichmentResult)
93cfcc4… lmata 69
93cfcc4… lmata 70 def test_result_has_promoted_attribute(self):
93cfcc4… lmata 71 store = _mock_store(result_set=[])
93cfcc4… lmata 72 result = SpringEnricher(store).enrich()
93cfcc4… lmata 73 assert hasattr(result, "promoted")
93cfcc4… lmata 74
93cfcc4… lmata 75 def test_result_has_edges_added_attribute(self):
93cfcc4… lmata 76 store = _mock_store(result_set=[])
93cfcc4… lmata 77 result = SpringEnricher(store).enrich()
93cfcc4… lmata 78 assert hasattr(result, "edges_added")
93cfcc4… lmata 79
93cfcc4… lmata 80 def test_result_has_patterns_found_attribute(self):
93cfcc4… lmata 81 store = _mock_store(result_set=[])
93cfcc4… lmata 82 result = SpringEnricher(store).enrich()
93cfcc4… lmata 83 assert hasattr(result, "patterns_found")
93cfcc4… lmata 84
93cfcc4… lmata 85
93cfcc4… lmata 86 # ── enrich() with no matching nodes ──────────────────────────────────────────
93cfcc4… lmata 87
93cfcc4… lmata 88
93cfcc4… lmata 89 class TestSpringEnricherNoMatches:
93cfcc4… lmata 90 def test_promoted_is_zero_when_no_nodes(self):
93cfcc4… lmata 91 store = _mock_store(result_set=[])
93cfcc4… lmata 92 result = SpringEnricher(store).enrich()
93cfcc4… lmata 93 assert result.promoted == 0
93cfcc4… lmata 94
93cfcc4… lmata 95 def test_all_pattern_counts_zero_when_no_nodes(self):
93cfcc4… lmata 96 store = _mock_store(result_set=[])
93cfcc4… lmata 97 result = SpringEnricher(store).enrich()
93cfcc4… lmata 98 for key in ("controllers", "rest_controllers", "services", "repositories", "entities"):
93cfcc4… lmata 99 assert result.patterns_found[key] == 0
93cfcc4… lmata 100
93cfcc4… lmata 101 def test_patterns_found_has_five_keys(self):
93cfcc4… lmata 102 store = _mock_store(result_set=[])
93cfcc4… lmata 103 result = SpringEnricher(store).enrich()
93cfcc4… lmata 104 assert set(result.patterns_found.keys()) == {
93cfcc4… lmata 105 "controllers", "rest_controllers", "services", "repositories", "entities"
93cfcc4… lmata 106 }
93cfcc4… lmata 107
93cfcc4… lmata 108
93cfcc4… lmata 109 # ── enrich() with matching nodes ─────────────────────────────────────────────
93cfcc4… lmata 110
93cfcc4… lmata 111
93cfcc4… lmata 112 class TestSpringEnricherWithMatches:
93cfcc4… lmata 113 def _make_store_for_annotation(self, target_annotation, rows):
93cfcc4… lmata 114 """Return a store that returns `rows` only when the annotation matches."""
93cfcc4… lmata 115
93cfcc4… lmata 116 def side_effect(cypher, params):
93cfcc4… lmata 117 annotation = params.get("annotation", "")
93cfcc4… lmata 118 if annotation == target_annotation:
93cfcc4… lmata 119 return MagicMock(result_set=rows)
93cfcc4… lmata 120 return MagicMock(result_set=[])
93cfcc4… lmata 121
93cfcc4… lmata 122 return _store_with_side_effect(side_effect)
93cfcc4… lmata 123
93cfcc4… lmata 124 def test_controller_promoted(self):
93cfcc4… lmata 125 store = self._make_store_for_annotation(
93cfcc4… lmata 126 "@Controller",
93cfcc4… lmata 127 [["UserController", "src/main/java/com/example/UserController.java"]],
93cfcc4… lmata 128 )
93cfcc4… lmata 129 result = SpringEnricher(store).enrich()
93cfcc4… lmata 130 assert result.patterns_found["controllers"] == 1
93cfcc4… lmata 131 assert result.promoted >= 1
93cfcc4… lmata 132
93cfcc4… lmata 133 def test_rest_controller_promoted(self):
93cfcc4… lmata 134 store = self._make_store_for_annotation(
93cfcc4… lmata 135 "@RestController",
93cfcc4… lmata 136 [["UserRestController", "src/main/java/com/example/UserRestController.java"]],
93cfcc4… lmata 137 )
93cfcc4… lmata 138 result = SpringEnricher(store).enrich()
93cfcc4… lmata 139 assert result.patterns_found["rest_controllers"] == 1
93cfcc4… lmata 140 assert result.promoted >= 1
93cfcc4… lmata 141
93cfcc4… lmata 142 def test_service_promoted(self):
93cfcc4… lmata 143 store = self._make_store_for_annotation(
93cfcc4… lmata 144 "@Service",
93cfcc4… lmata 145 [["UserService", "src/main/java/com/example/UserService.java"]],
93cfcc4… lmata 146 )
93cfcc4… lmata 147 result = SpringEnricher(store).enrich()
93cfcc4… lmata 148 assert result.patterns_found["services"] == 1
93cfcc4… lmata 149 assert result.promoted >= 1
93cfcc4… lmata 150
93cfcc4… lmata 151 def test_repository_promoted(self):
93cfcc4… lmata 152 store = self._make_store_for_annotation(
93cfcc4… lmata 153 "@Repository",
93cfcc4… lmata 154 [["UserRepository", "src/main/java/com/example/UserRepository.java"]],
93cfcc4… lmata 155 )
93cfcc4… lmata 156 result = SpringEnricher(store).enrich()
93cfcc4… lmata 157 assert result.patterns_found["repositories"] == 1
93cfcc4… lmata 158 assert result.promoted >= 1
93cfcc4… lmata 159
93cfcc4… lmata 160 def test_entity_promoted(self):
93cfcc4… lmata 161 store = self._make_store_for_annotation(
93cfcc4… lmata 162 "@Entity",
93cfcc4… lmata 163 [["User", "src/main/java/com/example/User.java"]],
93cfcc4… lmata 164 )
93cfcc4… lmata 165 result = SpringEnricher(store).enrich()
93cfcc4… lmata 166 assert result.patterns_found["entities"] == 1
93cfcc4… lmata 167 assert result.promoted >= 1
93cfcc4… lmata 168
93cfcc4… lmata 169 def test_promoted_count_accumulates_across_types(self):
93cfcc4… lmata 170 rows_map = {
93cfcc4… lmata 171 "@Controller": [
93cfcc4… lmata 172 ["UserController", "src/main/java/UserController.java"],
93cfcc4… lmata 173 ],
93cfcc4… lmata 174 "@RestController": [
93cfcc4… lmata 175 ["ApiController", "src/main/java/ApiController.java"],
93cfcc4… lmata 176 ["OrderController", "src/main/java/OrderController.java"],
93cfcc4… lmata 177 ],
93cfcc4… lmata 178 "@Service": [],
93cfcc4… lmata 179 "@Repository": [["UserRepository", "src/main/java/UserRepository.java"]],
93cfcc4… lmata 180 "@Entity": [],
93cfcc4… lmata 181 }
93cfcc4… lmata 182
93cfcc4… lmata 183 def side_effect(cypher, params):
93cfcc4… lmata 184 annotation = params.get("annotation", "")
93cfcc4… lmata 185 return MagicMock(result_set=rows_map.get(annotation, []))
93cfcc4… lmata 186
93cfcc4… lmata 187 store = _store_with_side_effect(side_effect)
93cfcc4… lmata 188 result = SpringEnricher(store).enrich()
93cfcc4… lmata 189 assert result.promoted == 4
93cfcc4… lmata 190 assert result.patterns_found["controllers"] == 1
93cfcc4… lmata 191 assert result.patterns_found["rest_controllers"] == 2
93cfcc4… lmata 192 assert result.patterns_found["repositories"] == 1
93cfcc4… lmata 193
93cfcc4… lmata 194 def test_promote_node_called_with_spring_controller_type(self):
93cfcc4… lmata 195 store = self._make_store_for_annotation(
93cfcc4… lmata 196 "@Controller",
93cfcc4… lmata 197 [["UserController", "src/main/java/UserController.java"]],
93cfcc4… lmata 198 )
93cfcc4… lmata 199 SpringEnricher(store).enrich()
93cfcc4… lmata 200 calls = [str(c) for c in store._graph.query.call_args_list]
93cfcc4… lmata 201 promote_calls = [c for c in calls if "semantic_type" in c and "SpringController" in c]
93cfcc4… lmata 202 assert len(promote_calls) >= 1
93cfcc4… lmata 203
93cfcc4… lmata 204 def test_promote_node_called_with_spring_service_type(self):
93cfcc4… lmata 205 store = self._make_store_for_annotation(
93cfcc4… lmata 206 "@Service",
93cfcc4… lmata 207 [["UserService", "src/main/java/UserService.java"]],
93cfcc4… lmata 208 )
93cfcc4… lmata 209 SpringEnricher(store).enrich()
93cfcc4… lmata 210 calls = [str(c) for c in store._graph.query.call_args_list]
93cfcc4… lmata 211 promote_calls = [c for c in calls if "semantic_type" in c and "SpringService" in c]
93cfcc4… lmata 212 assert len(promote_calls) >= 1
93cfcc4… lmata 213
93cfcc4… lmata 214 def test_promote_node_called_with_spring_repository_type(self):
93cfcc4… lmata 215 store = self._make_store_for_annotation(
93cfcc4… lmata 216 "@Repository",
93cfcc4… lmata 217 [["UserRepository", "src/main/java/UserRepository.java"]],
93cfcc4… lmata 218 )
93cfcc4… lmata 219 SpringEnricher(store).enrich()
93cfcc4… lmata 220 calls = [str(c) for c in store._graph.query.call_args_list]
93cfcc4… lmata 221 promote_calls = [c for c in calls if "semantic_type" in c and "SpringRepository" in c]
93cfcc4… lmata 222 assert len(promote_calls) >= 1
93cfcc4… lmata 223
93cfcc4… lmata 224 def test_promote_node_called_with_spring_entity_type(self):
93cfcc4… lmata 225 store = self._make_store_for_annotation(
93cfcc4… lmata 226 "@Entity",
93cfcc4… lmata 227 [["User", "src/main/java/User.java"]],
93cfcc4… lmata 228 )
93cfcc4… lmata 229 SpringEnricher(store).enrich()
93cfcc4… lmata 230 calls = [str(c) for c in store._graph.query.call_args_list]
93cfcc4… lmata 231 promote_calls = [c for c in calls if "semantic_type" in c and "SpringEntity" in c]
93cfcc4… lmata 232 assert len(promote_calls) >= 1
93cfcc4… lmata 233
93cfcc4… lmata 234 def test_promote_node_called_with_spring_rest_controller_type(self):
93cfcc4… lmata 235 store = self._make_store_for_annotation(
93cfcc4… lmata 236 "@RestController",
93cfcc4… lmata 237 [["ApiController", "src/main/java/ApiController.java"]],
93cfcc4… lmata 238 )
93cfcc4… lmata 239 SpringEnricher(store).enrich()
93cfcc4… lmata 240 calls = [str(c) for c in store._graph.query.call_args_list]
93cfcc4… lmata 241 promote_calls = [c for c in calls if "semantic_type" in c and "SpringRestController" in c]
93cfcc4… lmata 242 assert len(promote_calls) >= 1
93cfcc4… lmata 243
93cfcc4… lmata 244 def test_query_uses_annotation_param_not_fragment(self):
93cfcc4… lmata 245 """Verify enrich() passes 'annotation' key, not 'fragment', to the store."""
93cfcc4… lmata 246 captured = []
93cfcc4… lmata 247
93cfcc4… lmata 248 def side_effect(cypher, params):
93cfcc4… lmata 249 captured.append(params)
93cfcc4… lmata 250 return MagicMock(result_set=[])
93cfcc4… lmata 251
93cfcc4… lmata 252 store = _store_with_side_effect(side_effect)
93cfcc4… lmata 253 SpringEnricher(store).enrich()
93cfcc4… lmata 254 # All enrich queries (not _promote_node queries) should use 'annotation'
93cfcc4… lmata 255 enrich_queries = [p for p in captured if "annotation" in p]
93cfcc4… lmata 256 assert len(enrich_queries) == 5
93cfcc4… lmata 257
93cfcc4… lmata 258
93cfcc4… lmata 259 # ── detect() integration ──────────────────────────────────────────────────────
93cfcc4… lmata 260
93cfcc4… lmata 261
93cfcc4… lmata 262 class TestSpringEnricherDetect:
93cfcc4… lmata 263 def test_detect_true_when_spring_boot_annotation_present(self):
93cfcc4… lmata 264 store = _mock_store(result_set=[[1]])
93cfcc4… lmata 265 assert SpringEnricher(store).detect() is True
93cfcc4… lmata 266
93cfcc4… lmata 267 def test_detect_false_when_no_patterns_match(self):
93cfcc4… lmata 268 store = _mock_store(result_set=[[0]])
93cfcc4… lmata 269 assert SpringEnricher(store).detect() is False
93cfcc4… lmata 270
93cfcc4… lmata 271 def test_detect_false_on_empty_result_set(self):
93cfcc4… lmata 272 store = _mock_store(result_set=[])
93cfcc4… lmata 273 assert SpringEnricher(store).detect() is False

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button