Navegador

navegador / tests / test_enrichment_laravel.py
Source Blame History 272 lines
93cfcc4… lmata 1 """Tests for navegador.enrichment.laravel — LaravelEnricher."""
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.laravel import LaravelEnricher
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 TestLaravelEnricherIdentity:
93cfcc4… lmata 37 def test_framework_name(self):
93cfcc4… lmata 38 store = _mock_store()
93cfcc4… lmata 39 assert LaravelEnricher(store).framework_name == "laravel"
93cfcc4… lmata 40
93cfcc4… lmata 41 def test_is_framework_enricher_subclass(self):
93cfcc4… lmata 42 assert issubclass(LaravelEnricher, FrameworkEnricher)
93cfcc4… lmata 43
93cfcc4… lmata 44 def test_detection_patterns_contains_illuminate(self):
93cfcc4… lmata 45 store = _mock_store()
93cfcc4… lmata 46 assert "Illuminate" in LaravelEnricher(store).detection_patterns
93cfcc4… lmata 47
2c266d2… lmata 48 def test_detection_files_contains_artisan(self):
2c266d2… lmata 49 store = _mock_store()
2c266d2… lmata 50 assert "artisan" in LaravelEnricher(store).detection_files
2c266d2… lmata 51
2c266d2… lmata 52 def test_detection_patterns_has_one_entry(self):
93cfcc4… lmata 53 store = _mock_store()
2c266d2… lmata 54 assert len(LaravelEnricher(store).detection_patterns) == 1
93cfcc4… lmata 55
2c266d2… lmata 56 def test_detection_files_is_nonempty(self):
93cfcc4… lmata 57 store = _mock_store()
2c266d2… lmata 58 assert len(LaravelEnricher(store).detection_files) >= 1
93cfcc4… lmata 59
93cfcc4… lmata 60
93cfcc4… lmata 61 # ── enrich() return type ──────────────────────────────────────────────────────
93cfcc4… lmata 62
93cfcc4… lmata 63
93cfcc4… lmata 64 class TestLaravelEnricherEnrichReturnType:
93cfcc4… lmata 65 def test_returns_enrichment_result(self):
93cfcc4… lmata 66 store = _mock_store(result_set=[])
93cfcc4… lmata 67 result = LaravelEnricher(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 = LaravelEnricher(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 = LaravelEnricher(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 = LaravelEnricher(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 TestLaravelEnricherNoMatches:
93cfcc4… lmata 90 def test_promoted_is_zero_when_no_nodes(self):
93cfcc4… lmata 91 store = _mock_store(result_set=[])
93cfcc4… lmata 92 result = LaravelEnricher(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 = LaravelEnricher(store).enrich()
93cfcc4… lmata 98 for key in ("controllers", "routes", "jobs", "policies", "models"):
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 = LaravelEnricher(store).enrich()
93cfcc4… lmata 104 assert set(result.patterns_found.keys()) == {
93cfcc4… lmata 105 "controllers", "routes", "jobs", "policies", "models"
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 TestLaravelEnricherWithMatches:
93cfcc4… lmata 113 def _make_store_for_fragment(self, target_fragment, rows):
93cfcc4… lmata 114 """Return a store that returns `rows` only when the fragment matches."""
93cfcc4… lmata 115
93cfcc4… lmata 116 def side_effect(cypher, params):
93cfcc4… lmata 117 fragment = params.get("fragment", "")
93cfcc4… lmata 118 if fragment == target_fragment:
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_fragment(
93cfcc4… lmata 126 "Controllers/",
93cfcc4… lmata 127 [["UserController", "app/Http/Controllers/UserController.php"]],
93cfcc4… lmata 128 )
93cfcc4… lmata 129 result = LaravelEnricher(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_route_promoted(self):
93cfcc4… lmata 134 store = self._make_store_for_fragment(
93cfcc4… lmata 135 "routes/",
93cfcc4… lmata 136 [["web", "routes/web.php"]],
93cfcc4… lmata 137 )
93cfcc4… lmata 138 result = LaravelEnricher(store).enrich()
93cfcc4… lmata 139 assert result.patterns_found["routes"] == 1
93cfcc4… lmata 140 assert result.promoted >= 1
93cfcc4… lmata 141
93cfcc4… lmata 142 def test_job_promoted(self):
93cfcc4… lmata 143 store = self._make_store_for_fragment(
93cfcc4… lmata 144 "Jobs/",
93cfcc4… lmata 145 [["SendEmailJob", "app/Jobs/SendEmailJob.php"]],
93cfcc4… lmata 146 )
93cfcc4… lmata 147 result = LaravelEnricher(store).enrich()
93cfcc4… lmata 148 assert result.patterns_found["jobs"] == 1
93cfcc4… lmata 149 assert result.promoted >= 1
93cfcc4… lmata 150
93cfcc4… lmata 151 def test_policy_promoted(self):
93cfcc4… lmata 152 store = self._make_store_for_fragment(
93cfcc4… lmata 153 "Policies/",
93cfcc4… lmata 154 [["UserPolicy", "app/Policies/UserPolicy.php"]],
93cfcc4… lmata 155 )
93cfcc4… lmata 156 result = LaravelEnricher(store).enrich()
93cfcc4… lmata 157 assert result.patterns_found["policies"] == 1
93cfcc4… lmata 158 assert result.promoted >= 1
93cfcc4… lmata 159
93cfcc4… lmata 160 def test_model_promoted_via_model_keyword(self):
93cfcc4… lmata 161 store = self._make_store_for_fragment(
93cfcc4… lmata 162 "Model",
93cfcc4… lmata 163 [["User", "app/Models/User.php"]],
93cfcc4… lmata 164 )
93cfcc4… lmata 165 result = LaravelEnricher(store).enrich()
93cfcc4… lmata 166 assert result.patterns_found["models"] == 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 "Controllers/": [
93cfcc4… lmata 172 ["UserController", "app/Http/Controllers/UserController.php"],
93cfcc4… lmata 173 ["PostController", "app/Http/Controllers/PostController.php"],
93cfcc4… lmata 174 ],
93cfcc4… lmata 175 "routes/": [["web", "routes/web.php"]],
93cfcc4… lmata 176 "Jobs/": [],
93cfcc4… lmata 177 "Policies/": [["UserPolicy", "app/Policies/UserPolicy.php"]],
93cfcc4… lmata 178 "Model": [],
93cfcc4… lmata 179 }
93cfcc4… lmata 180
93cfcc4… lmata 181 def side_effect(cypher, params):
93cfcc4… lmata 182 fragment = params.get("fragment", "")
93cfcc4… lmata 183 return MagicMock(result_set=rows_map.get(fragment, []))
93cfcc4… lmata 184
93cfcc4… lmata 185 store = _store_with_side_effect(side_effect)
93cfcc4… lmata 186 result = LaravelEnricher(store).enrich()
93cfcc4… lmata 187 assert result.promoted == 4
93cfcc4… lmata 188 assert result.patterns_found["controllers"] == 2
93cfcc4… lmata 189 assert result.patterns_found["routes"] == 1
93cfcc4… lmata 190 assert result.patterns_found["policies"] == 1
93cfcc4… lmata 191 assert result.patterns_found["jobs"] == 0
93cfcc4… lmata 192 assert result.patterns_found["models"] == 0
93cfcc4… lmata 193
93cfcc4… lmata 194 def test_promote_node_called_with_laravel_controller_type(self):
93cfcc4… lmata 195 store = self._make_store_for_fragment(
93cfcc4… lmata 196 "Controllers/",
93cfcc4… lmata 197 [["UserController", "app/Http/Controllers/UserController.php"]],
93cfcc4… lmata 198 )
93cfcc4… lmata 199 LaravelEnricher(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 "LaravelController" in c]
93cfcc4… lmata 202 assert len(promote_calls) >= 1
93cfcc4… lmata 203
93cfcc4… lmata 204 def test_promote_node_called_with_laravel_model_type(self):
93cfcc4… lmata 205 store = self._make_store_for_fragment(
93cfcc4… lmata 206 "Model",
93cfcc4… lmata 207 [["User", "app/Models/User.php"]],
93cfcc4… lmata 208 )
93cfcc4… lmata 209 LaravelEnricher(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 "LaravelModel" in c]
93cfcc4… lmata 212 assert len(promote_calls) >= 1
93cfcc4… lmata 213
93cfcc4… lmata 214 def test_promote_node_called_with_laravel_route_type(self):
93cfcc4… lmata 215 store = self._make_store_for_fragment(
93cfcc4… lmata 216 "routes/",
93cfcc4… lmata 217 [["web", "routes/web.php"]],
93cfcc4… lmata 218 )
93cfcc4… lmata 219 LaravelEnricher(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 "LaravelRoute" in c]
93cfcc4… lmata 222 assert len(promote_calls) >= 1
93cfcc4… lmata 223
93cfcc4… lmata 224 def test_promote_node_called_with_laravel_job_type(self):
93cfcc4… lmata 225 store = self._make_store_for_fragment(
93cfcc4… lmata 226 "Jobs/",
93cfcc4… lmata 227 [["SendEmailJob", "app/Jobs/SendEmailJob.php"]],
93cfcc4… lmata 228 )
93cfcc4… lmata 229 LaravelEnricher(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 "LaravelJob" in c]
93cfcc4… lmata 232 assert len(promote_calls) >= 1
93cfcc4… lmata 233
93cfcc4… lmata 234 def test_promote_node_called_with_laravel_policy_type(self):
93cfcc4… lmata 235 store = self._make_store_for_fragment(
93cfcc4… lmata 236 "Policies/",
93cfcc4… lmata 237 [["UserPolicy", "app/Policies/UserPolicy.php"]],
93cfcc4… lmata 238 )
93cfcc4… lmata 239 LaravelEnricher(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 "LaravelPolicy" in c]
93cfcc4… lmata 242 assert len(promote_calls) >= 1
93cfcc4… lmata 243
93cfcc4… lmata 244 def test_model_query_uses_fragment_param_named_fragment(self):
93cfcc4… lmata 245 """Model detection must pass fragment='Model', not an 'annotation' key."""
93cfcc4… lmata 246 captured = []
93cfcc4… lmata 247
93cfcc4… lmata 248 def side_effect(cypher, params):
93cfcc4… lmata 249 captured.append(dict(params))
93cfcc4… lmata 250 return MagicMock(result_set=[])
93cfcc4… lmata 251
93cfcc4… lmata 252 store = _store_with_side_effect(side_effect)
93cfcc4… lmata 253 LaravelEnricher(store).enrich()
93cfcc4… lmata 254 model_queries = [p for p in captured if p.get("fragment") == "Model"]
93cfcc4… lmata 255 assert len(model_queries) >= 1
93cfcc4… lmata 256
93cfcc4… lmata 257
93cfcc4… lmata 258 # ── detect() integration ──────────────────────────────────────────────────────
93cfcc4… lmata 259
93cfcc4… lmata 260
93cfcc4… lmata 261 class TestLaravelEnricherDetect:
93cfcc4… lmata 262 def test_detect_true_when_artisan_present(self):
93cfcc4… lmata 263 store = _mock_store(result_set=[[1]])
93cfcc4… lmata 264 assert LaravelEnricher(store).detect() is True
93cfcc4… lmata 265
93cfcc4… lmata 266 def test_detect_false_when_no_patterns_match(self):
93cfcc4… lmata 267 store = _mock_store(result_set=[[0]])
93cfcc4… lmata 268 assert LaravelEnricher(store).detect() is False
93cfcc4… lmata 269
93cfcc4… lmata 270 def test_detect_false_on_empty_result_set(self):
93cfcc4… lmata 271 store = _mock_store(result_set=[])
93cfcc4… lmata 272 assert LaravelEnricher(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