Navegador

navegador / tests / test_enrichment_django.py
Source Blame History 463 lines
396dc34… lmata 1 """Tests for navegador.enrichment.django — DjangoEnricher."""
396dc34… lmata 2
396dc34… lmata 3 from unittest.mock import MagicMock, call
396dc34… lmata 4
396dc34… lmata 5 import pytest
396dc34… lmata 6
396dc34… lmata 7 from navegador.enrichment.base import EnrichmentResult, FrameworkEnricher
396dc34… lmata 8 from navegador.enrichment.django import DjangoEnricher
396dc34… lmata 9 from navegador.graph.store import GraphStore
396dc34… lmata 10
396dc34… lmata 11
396dc34… lmata 12 # ── Helpers ───────────────────────────────────────────────────────────────────
396dc34… lmata 13
396dc34… lmata 14
396dc34… lmata 15 def _mock_store(result_set=None):
396dc34… lmata 16 """Return a GraphStore backed by a mock FalkorDB graph."""
396dc34… lmata 17 client = MagicMock()
396dc34… lmata 18 graph = MagicMock()
396dc34… lmata 19 graph.query.return_value = MagicMock(result_set=result_set)
396dc34… lmata 20 client.select_graph.return_value = graph
396dc34… lmata 21 return GraphStore(client)
396dc34… lmata 22
396dc34… lmata 23
396dc34… lmata 24 def _store_with_side_effect(side_effect):
396dc34… lmata 25 """Return a GraphStore whose graph.query uses the given side_effect callable."""
396dc34… lmata 26 client = MagicMock()
396dc34… lmata 27 graph = MagicMock()
396dc34… lmata 28 graph.query.side_effect = side_effect
396dc34… lmata 29 client.select_graph.return_value = graph
396dc34… lmata 30 return GraphStore(client)
396dc34… lmata 31
396dc34… lmata 32
396dc34… lmata 33 # ── Metadata ──────────────────────────────────────────────────────────────────
396dc34… lmata 34
396dc34… lmata 35
396dc34… lmata 36 class TestDjangoEnricherMetadata:
396dc34… lmata 37 def test_framework_name(self):
396dc34… lmata 38 enricher = DjangoEnricher(_mock_store())
396dc34… lmata 39 assert enricher.framework_name == "django"
396dc34… lmata 40
2c266d2… lmata 41 def test_detection_patterns_contains_django(self):
396dc34… lmata 42 enricher = DjangoEnricher(_mock_store())
2c266d2… lmata 43 assert "django" in enricher.detection_patterns
396dc34… lmata 44
396dc34… lmata 45 def test_detection_patterns_contains_django_conf(self):
396dc34… lmata 46 enricher = DjangoEnricher(_mock_store())
396dc34… lmata 47 assert "django.conf" in enricher.detection_patterns
396dc34… lmata 48
2c266d2… lmata 49 def test_detection_patterns_contains_django_db(self):
396dc34… lmata 50 enricher = DjangoEnricher(_mock_store())
2c266d2… lmata 51 assert "django.db" in enricher.detection_patterns
396dc34… lmata 52
2c266d2… lmata 53 def test_detection_patterns_contains_django_http(self):
396dc34… lmata 54 enricher = DjangoEnricher(_mock_store())
2c266d2… lmata 55 assert "django.http" in enricher.detection_patterns
396dc34… lmata 56
396dc34… lmata 57 def test_detection_patterns_is_list_of_strings(self):
396dc34… lmata 58 enricher = DjangoEnricher(_mock_store())
396dc34… lmata 59 patterns = enricher.detection_patterns
396dc34… lmata 60 assert isinstance(patterns, list)
396dc34… lmata 61 assert all(isinstance(p, str) for p in patterns)
396dc34… lmata 62
396dc34… lmata 63 def test_is_subclass_of_framework_enricher(self):
396dc34… lmata 64 assert issubclass(DjangoEnricher, FrameworkEnricher)
396dc34… lmata 65
396dc34… lmata 66 def test_enrich_returns_enrichment_result(self):
396dc34… lmata 67 store = _mock_store(result_set=[])
396dc34… lmata 68 enricher = DjangoEnricher(store)
396dc34… lmata 69 result = enricher.enrich()
396dc34… lmata 70 assert isinstance(result, EnrichmentResult)
396dc34… lmata 71
396dc34… lmata 72
396dc34… lmata 73 # ── detect() ──────────────────────────────────────────────────────────────────
396dc34… lmata 74
396dc34… lmata 75
396dc34… lmata 76 class TestDjangoEnricherDetect:
396dc34… lmata 77 def test_detect_returns_true_when_urls_py_present(self):
396dc34… lmata 78 store = _mock_store(result_set=[[1]])
396dc34… lmata 79 enricher = DjangoEnricher(store)
396dc34… lmata 80 assert enricher.detect() is True
396dc34… lmata 81
396dc34… lmata 82 def test_detect_returns_false_when_no_patterns_match(self):
396dc34… lmata 83 store = _mock_store(result_set=[[0]])
396dc34… lmata 84 enricher = DjangoEnricher(store)
396dc34… lmata 85 assert enricher.detect() is False
396dc34… lmata 86
396dc34… lmata 87 def test_detect_returns_false_when_result_set_empty(self):
396dc34… lmata 88 store = _mock_store(result_set=[])
396dc34… lmata 89 enricher = DjangoEnricher(store)
396dc34… lmata 90 assert enricher.detect() is False
396dc34… lmata 91
396dc34… lmata 92 def test_detect_returns_false_when_result_set_none(self):
396dc34… lmata 93 store = _mock_store(result_set=None)
396dc34… lmata 94 enricher = DjangoEnricher(store)
396dc34… lmata 95 assert enricher.detect() is False
396dc34… lmata 96
396dc34… lmata 97 def test_detect_short_circuits_on_first_match(self):
396dc34… lmata 98 store = _mock_store(result_set=[[5]])
396dc34… lmata 99 enricher = DjangoEnricher(store)
396dc34… lmata 100 assert enricher.detect() is True
396dc34… lmata 101 # Should only query once (short-circuit)
396dc34… lmata 102 assert store._graph.query.call_count == 1
396dc34… lmata 103
396dc34… lmata 104 def test_detect_tries_all_patterns_before_giving_up(self):
396dc34… lmata 105 store = _mock_store(result_set=[[0]])
396dc34… lmata 106 enricher = DjangoEnricher(store)
396dc34… lmata 107 enricher.detect()
2c266d2… lmata 108 # All detection_patterns are checked, then all detection_files
2c266d2… lmata 109 expected = len(enricher.detection_patterns) + len(enricher.detection_files)
2c266d2… lmata 110 assert store._graph.query.call_count == expected
396dc34… lmata 111
396dc34… lmata 112
396dc34… lmata 113 # ── enrich() — views ──────────────────────────────────────────────────────────
396dc34… lmata 114
396dc34… lmata 115
396dc34… lmata 116 class TestDjangoEnricherViews:
396dc34… lmata 117 def _make_store_for_views(self, view_rows):
396dc34… lmata 118 """
396dc34… lmata 119 Return a store that yields view_rows for the views query and [] for everything else.
396dc34… lmata 120 """
396dc34… lmata 121 call_count = [0]
396dc34… lmata 122
396dc34… lmata 123 def side_effect(cypher, params=None):
396dc34… lmata 124 call_count[0] += 1
396dc34… lmata 125 # First enrich query targets views.py functions
396dc34… lmata 126 if "views.py" in cypher and "Function" in cypher and call_count[0] == 1:
396dc34… lmata 127 return MagicMock(result_set=view_rows)
396dc34… lmata 128 return MagicMock(result_set=[])
396dc34… lmata 129
396dc34… lmata 130 return _store_with_side_effect(side_effect)
396dc34… lmata 131
396dc34… lmata 132 def test_promotes_functions_in_views_py(self):
396dc34… lmata 133 view_rows = [["my_view", "app/views.py"], ["another_view", "app/views.py"]]
396dc34… lmata 134 store = self._make_store_for_views(view_rows)
396dc34… lmata 135 enricher = DjangoEnricher(store)
396dc34… lmata 136 result = enricher.enrich()
396dc34… lmata 137 assert result.patterns_found["views"] == 2
396dc34… lmata 138 assert result.promoted >= 2
396dc34… lmata 139
396dc34… lmata 140 def test_no_views_produces_zero_count(self):
396dc34… lmata 141 store = _mock_store(result_set=[])
396dc34… lmata 142 enricher = DjangoEnricher(store)
396dc34… lmata 143 result = enricher.enrich()
396dc34… lmata 144 assert result.patterns_found["views"] == 0
396dc34… lmata 145
396dc34… lmata 146 def test_view_promote_node_called_with_semantic_type_view(self):
396dc34… lmata 147 view_rows = [["index_view", "myapp/views.py"]]
396dc34… lmata 148
396dc34… lmata 149 call_count = [0]
396dc34… lmata 150
396dc34… lmata 151 def side_effect(cypher, params=None):
396dc34… lmata 152 call_count[0] += 1
396dc34… lmata 153 if "views.py" in cypher and "Function" in cypher and call_count[0] == 1:
396dc34… lmata 154 return MagicMock(result_set=view_rows)
396dc34… lmata 155 # _promote_node calls also go through store.query — return empty
396dc34… lmata 156 return MagicMock(result_set=[])
396dc34… lmata 157
396dc34… lmata 158 store = _store_with_side_effect(side_effect)
396dc34… lmata 159 enricher = DjangoEnricher(store)
396dc34… lmata 160 enricher.enrich()
396dc34… lmata 161
396dc34… lmata 162 # Find the _promote_node call for "index_view"
396dc34… lmata 163 promote_calls = [
396dc34… lmata 164 c for c in store._graph.query.call_args_list
396dc34… lmata 165 if "SET n.semantic_type" in c[0][0]
396dc34… lmata 166 and c[0][1].get("name") == "index_view"
396dc34… lmata 167 ]
396dc34… lmata 168 assert len(promote_calls) == 1
396dc34… lmata 169 assert promote_calls[0][0][1]["semantic_type"] == "View"
396dc34… lmata 170
396dc34… lmata 171
396dc34… lmata 172 # ── enrich() — models ─────────────────────────────────────────────────────────
396dc34… lmata 173
396dc34… lmata 174
396dc34… lmata 175 class TestDjangoEnricherModels:
396dc34… lmata 176 def _make_store_for_models(self, model_rows):
396dc34… lmata 177 call_count = [0]
396dc34… lmata 178
396dc34… lmata 179 def side_effect(cypher, params=None):
396dc34… lmata 180 call_count[0] += 1
396dc34… lmata 181 # Second enrich query targets Model-inheriting classes
396dc34… lmata 182 if "INHERITS" in cypher and call_count[0] == 2:
396dc34… lmata 183 return MagicMock(result_set=model_rows)
396dc34… lmata 184 return MagicMock(result_set=[])
396dc34… lmata 185
396dc34… lmata 186 return _store_with_side_effect(side_effect)
396dc34… lmata 187
396dc34… lmata 188 def test_promotes_classes_inheriting_from_model(self):
396dc34… lmata 189 model_rows = [["UserProfile", "app/models.py"], ["Post", "blog/models.py"]]
396dc34… lmata 190 store = self._make_store_for_models(model_rows)
396dc34… lmata 191 enricher = DjangoEnricher(store)
396dc34… lmata 192 result = enricher.enrich()
396dc34… lmata 193 assert result.patterns_found["models"] == 2
396dc34… lmata 194 assert result.promoted >= 2
396dc34… lmata 195
396dc34… lmata 196 def test_no_models_produces_zero_count(self):
396dc34… lmata 197 store = _mock_store(result_set=[])
396dc34… lmata 198 enricher = DjangoEnricher(store)
396dc34… lmata 199 result = enricher.enrich()
396dc34… lmata 200 assert result.patterns_found["models"] == 0
396dc34… lmata 201
396dc34… lmata 202 def test_model_promote_node_called_with_semantic_type_model(self):
396dc34… lmata 203 model_rows = [["Article", "news/models.py"]]
396dc34… lmata 204
396dc34… lmata 205 call_count = [0]
396dc34… lmata 206
396dc34… lmata 207 def side_effect(cypher, params=None):
396dc34… lmata 208 call_count[0] += 1
396dc34… lmata 209 if "INHERITS" in cypher and call_count[0] == 2:
396dc34… lmata 210 return MagicMock(result_set=model_rows)
396dc34… lmata 211 return MagicMock(result_set=[])
396dc34… lmata 212
396dc34… lmata 213 store = _store_with_side_effect(side_effect)
396dc34… lmata 214 enricher = DjangoEnricher(store)
396dc34… lmata 215 enricher.enrich()
396dc34… lmata 216
396dc34… lmata 217 promote_calls = [
396dc34… lmata 218 c for c in store._graph.query.call_args_list
396dc34… lmata 219 if "SET n.semantic_type" in c[0][0]
396dc34… lmata 220 and c[0][1].get("name") == "Article"
396dc34… lmata 221 ]
396dc34… lmata 222 assert len(promote_calls) == 1
396dc34… lmata 223 assert promote_calls[0][0][1]["semantic_type"] == "Model"
396dc34… lmata 224
396dc34… lmata 225
396dc34… lmata 226 # ── enrich() — serializers ────────────────────────────────────────────────────
396dc34… lmata 227
396dc34… lmata 228
396dc34… lmata 229 class TestDjangoEnricherSerializers:
396dc34… lmata 230 def _make_store_for_serializers(self, serializer_rows):
396dc34… lmata 231 call_count = [0]
396dc34… lmata 232
396dc34… lmata 233 def side_effect(cypher, params=None):
396dc34… lmata 234 call_count[0] += 1
396dc34… lmata 235 # Fourth enrich query targets serializers.py classes
396dc34… lmata 236 if "serializers.py" in cypher and call_count[0] == 4:
396dc34… lmata 237 return MagicMock(result_set=serializer_rows)
396dc34… lmata 238 return MagicMock(result_set=[])
396dc34… lmata 239
396dc34… lmata 240 return _store_with_side_effect(side_effect)
396dc34… lmata 241
396dc34… lmata 242 def test_promotes_classes_in_serializers_py(self):
396dc34… lmata 243 serializer_rows = [["UserSerializer", "api/serializers.py"]]
396dc34… lmata 244 store = self._make_store_for_serializers(serializer_rows)
396dc34… lmata 245 enricher = DjangoEnricher(store)
396dc34… lmata 246 result = enricher.enrich()
396dc34… lmata 247 assert result.patterns_found["serializers"] == 1
396dc34… lmata 248 assert result.promoted >= 1
396dc34… lmata 249
396dc34… lmata 250 def test_no_serializers_produces_zero_count(self):
396dc34… lmata 251 store = _mock_store(result_set=[])
396dc34… lmata 252 enricher = DjangoEnricher(store)
396dc34… lmata 253 result = enricher.enrich()
396dc34… lmata 254 assert result.patterns_found["serializers"] == 0
396dc34… lmata 255
396dc34… lmata 256 def test_serializer_promote_node_called_with_semantic_type_serializer(self):
396dc34… lmata 257 serializer_rows = [["PostSerializer", "blog/serializers.py"]]
396dc34… lmata 258
396dc34… lmata 259 call_count = [0]
396dc34… lmata 260
396dc34… lmata 261 def side_effect(cypher, params=None):
396dc34… lmata 262 call_count[0] += 1
396dc34… lmata 263 if "serializers.py" in cypher and call_count[0] == 4:
396dc34… lmata 264 return MagicMock(result_set=serializer_rows)
396dc34… lmata 265 return MagicMock(result_set=[])
396dc34… lmata 266
396dc34… lmata 267 store = _store_with_side_effect(side_effect)
396dc34… lmata 268 enricher = DjangoEnricher(store)
396dc34… lmata 269 enricher.enrich()
396dc34… lmata 270
396dc34… lmata 271 promote_calls = [
396dc34… lmata 272 c for c in store._graph.query.call_args_list
396dc34… lmata 273 if "SET n.semantic_type" in c[0][0]
396dc34… lmata 274 and c[0][1].get("name") == "PostSerializer"
396dc34… lmata 275 ]
396dc34… lmata 276 assert len(promote_calls) == 1
396dc34… lmata 277 assert promote_calls[0][0][1]["semantic_type"] == "Serializer"
396dc34… lmata 278
396dc34… lmata 279
396dc34… lmata 280 # ── enrich() — tasks ──────────────────────────────────────────────────────────
396dc34… lmata 281
396dc34… lmata 282
396dc34… lmata 283 class TestDjangoEnricherTasks:
396dc34… lmata 284 def _make_store_for_tasks(self, task_rows):
396dc34… lmata 285 call_count = [0]
396dc34… lmata 286
396dc34… lmata 287 def side_effect(cypher, params=None):
396dc34… lmata 288 call_count[0] += 1
396dc34… lmata 289 # Fifth enrich query targets tasks.py functions or @task decorator
396dc34… lmata 290 if "tasks.py" in cypher and call_count[0] == 5:
396dc34… lmata 291 return MagicMock(result_set=task_rows)
396dc34… lmata 292 return MagicMock(result_set=[])
396dc34… lmata 293
396dc34… lmata 294 return _store_with_side_effect(side_effect)
396dc34… lmata 295
396dc34… lmata 296 def test_promotes_functions_in_tasks_py(self):
396dc34… lmata 297 task_rows = [["send_email", "myapp/tasks.py"], ["process_order", "shop/tasks.py"]]
396dc34… lmata 298 store = self._make_store_for_tasks(task_rows)
396dc34… lmata 299 enricher = DjangoEnricher(store)
396dc34… lmata 300 result = enricher.enrich()
396dc34… lmata 301 assert result.patterns_found["tasks"] == 2
396dc34… lmata 302 assert result.promoted >= 2
396dc34… lmata 303
396dc34… lmata 304 def test_no_tasks_produces_zero_count(self):
396dc34… lmata 305 store = _mock_store(result_set=[])
396dc34… lmata 306 enricher = DjangoEnricher(store)
396dc34… lmata 307 result = enricher.enrich()
396dc34… lmata 308 assert result.patterns_found["tasks"] == 0
396dc34… lmata 309
396dc34… lmata 310 def test_task_cypher_includes_decorator_check(self):
396dc34… lmata 311 store = _mock_store(result_set=[])
396dc34… lmata 312 enricher = DjangoEnricher(store)
396dc34… lmata 313 enricher.enrich()
396dc34… lmata 314
396dc34… lmata 315 # Find the tasks query
396dc34… lmata 316 tasks_queries = [
396dc34… lmata 317 c[0][0] for c in store._graph.query.call_args_list
396dc34… lmata 318 if "tasks.py" in c[0][0]
396dc34… lmata 319 ]
396dc34… lmata 320 assert len(tasks_queries) == 1
396dc34… lmata 321 assert "decorators" in tasks_queries[0]
396dc34… lmata 322 assert "task" in tasks_queries[0]
396dc34… lmata 323
396dc34… lmata 324 def test_task_promote_node_called_with_semantic_type_task(self):
396dc34… lmata 325 task_rows = [["send_welcome_email", "users/tasks.py"]]
396dc34… lmata 326
396dc34… lmata 327 call_count = [0]
396dc34… lmata 328
396dc34… lmata 329 def side_effect(cypher, params=None):
396dc34… lmata 330 call_count[0] += 1
396dc34… lmata 331 if "tasks.py" in cypher and call_count[0] == 5:
396dc34… lmata 332 return MagicMock(result_set=task_rows)
396dc34… lmata 333 return MagicMock(result_set=[])
396dc34… lmata 334
396dc34… lmata 335 store = _store_with_side_effect(side_effect)
396dc34… lmata 336 enricher = DjangoEnricher(store)
396dc34… lmata 337 enricher.enrich()
396dc34… lmata 338
396dc34… lmata 339 promote_calls = [
396dc34… lmata 340 c for c in store._graph.query.call_args_list
396dc34… lmata 341 if "SET n.semantic_type" in c[0][0]
396dc34… lmata 342 and c[0][1].get("name") == "send_welcome_email"
396dc34… lmata 343 ]
396dc34… lmata 344 assert len(promote_calls) == 1
396dc34… lmata 345 assert promote_calls[0][0][1]["semantic_type"] == "Task"
396dc34… lmata 346
396dc34… lmata 347
396dc34… lmata 348 # ── enrich() — URL patterns ───────────────────────────────────────────────────
396dc34… lmata 349
396dc34… lmata 350
396dc34… lmata 351 class TestDjangoEnricherURLPatterns:
396dc34… lmata 352 def test_url_patterns_count_tracked(self):
396dc34… lmata 353 call_count = [0]
396dc34… lmata 354
396dc34… lmata 355 def side_effect(cypher, params=None):
396dc34… lmata 356 call_count[0] += 1
396dc34… lmata 357 if "urls.py" in cypher and call_count[0] == 3:
396dc34… lmata 358 return MagicMock(result_set=[["urlconf", "myapp/urls.py"]])
396dc34… lmata 359 return MagicMock(result_set=[])
396dc34… lmata 360
396dc34… lmata 361 store = _store_with_side_effect(side_effect)
396dc34… lmata 362 enricher = DjangoEnricher(store)
396dc34… lmata 363 result = enricher.enrich()
396dc34… lmata 364 assert result.patterns_found["url_patterns"] == 1
396dc34… lmata 365
396dc34… lmata 366 def test_url_pattern_promoted_with_correct_semantic_type(self):
396dc34… lmata 367 call_count = [0]
396dc34… lmata 368
396dc34… lmata 369 def side_effect(cypher, params=None):
396dc34… lmata 370 call_count[0] += 1
396dc34… lmata 371 if "urls.py" in cypher and call_count[0] == 3:
396dc34… lmata 372 return MagicMock(result_set=[["urlconf", "myapp/urls.py"]])
396dc34… lmata 373 return MagicMock(result_set=[])
396dc34… lmata 374
396dc34… lmata 375 store = _store_with_side_effect(side_effect)
396dc34… lmata 376 enricher = DjangoEnricher(store)
396dc34… lmata 377 enricher.enrich()
396dc34… lmata 378
396dc34… lmata 379 promote_calls = [
396dc34… lmata 380 c for c in store._graph.query.call_args_list
396dc34… lmata 381 if "SET n.semantic_type" in c[0][0]
396dc34… lmata 382 and c[0][1].get("name") == "urlconf"
396dc34… lmata 383 ]
396dc34… lmata 384 assert len(promote_calls) == 1
396dc34… lmata 385 assert promote_calls[0][0][1]["semantic_type"] == "URLPattern"
396dc34… lmata 386
396dc34… lmata 387
396dc34… lmata 388 # ── enrich() — admin ──────────────────────────────────────────────────────────
396dc34… lmata 389
396dc34… lmata 390
396dc34… lmata 391 class TestDjangoEnricherAdmin:
396dc34… lmata 392 def test_admin_count_tracked(self):
396dc34… lmata 393 call_count = [0]
396dc34… lmata 394
396dc34… lmata 395 def side_effect(cypher, params=None):
396dc34… lmata 396 call_count[0] += 1
396dc34… lmata 397 if "admin.py" in cypher and call_count[0] == 6:
396dc34… lmata 398 return MagicMock(result_set=[["UserAdmin", "myapp/admin.py"]])
396dc34… lmata 399 return MagicMock(result_set=[])
396dc34… lmata 400
396dc34… lmata 401 store = _store_with_side_effect(side_effect)
396dc34… lmata 402 enricher = DjangoEnricher(store)
396dc34… lmata 403 result = enricher.enrich()
396dc34… lmata 404 assert result.patterns_found["admin"] == 1
396dc34… lmata 405
396dc34… lmata 406 def test_admin_promoted_with_correct_semantic_type(self):
396dc34… lmata 407 call_count = [0]
396dc34… lmata 408
396dc34… lmata 409 def side_effect(cypher, params=None):
396dc34… lmata 410 call_count[0] += 1
396dc34… lmata 411 if "admin.py" in cypher and call_count[0] == 6:
396dc34… lmata 412 return MagicMock(result_set=[["PostAdmin", "blog/admin.py"]])
396dc34… lmata 413 return MagicMock(result_set=[])
396dc34… lmata 414
396dc34… lmata 415 store = _store_with_side_effect(side_effect)
396dc34… lmata 416 enricher = DjangoEnricher(store)
396dc34… lmata 417 enricher.enrich()
396dc34… lmata 418
396dc34… lmata 419 promote_calls = [
396dc34… lmata 420 c for c in store._graph.query.call_args_list
396dc34… lmata 421 if "SET n.semantic_type" in c[0][0]
396dc34… lmata 422 and c[0][1].get("name") == "PostAdmin"
396dc34… lmata 423 ]
396dc34… lmata 424 assert len(promote_calls) == 1
396dc34… lmata 425 assert promote_calls[0][0][1]["semantic_type"] == "Admin"
396dc34… lmata 426
396dc34… lmata 427
396dc34… lmata 428 # ── enrich() — aggregate result ───────────────────────────────────────────────
396dc34… lmata 429
396dc34… lmata 430
396dc34… lmata 431 class TestDjangoEnricherAggregateResult:
396dc34… lmata 432 def test_patterns_found_has_all_expected_keys(self):
396dc34… lmata 433 store = _mock_store(result_set=[])
396dc34… lmata 434 enricher = DjangoEnricher(store)
396dc34… lmata 435 result = enricher.enrich()
396dc34… lmata 436 expected_keys = {"views", "models", "url_patterns", "serializers", "tasks", "admin"}
396dc34… lmata 437 assert expected_keys == set(result.patterns_found.keys())
396dc34… lmata 438
396dc34… lmata 439 def test_promoted_count_is_sum_of_all_pattern_counts(self):
396dc34… lmata 440 """With no matches, promoted should be 0."""
396dc34… lmata 441 store = _mock_store(result_set=[])
396dc34… lmata 442 enricher = DjangoEnricher(store)
396dc34… lmata 443 result = enricher.enrich()
396dc34… lmata 444 assert result.promoted == 0
396dc34… lmata 445 assert sum(result.patterns_found.values()) == 0
396dc34… lmata 446
396dc34… lmata 447 def test_promoted_accumulates_across_all_patterns(self):
396dc34… lmata 448 """Each query returns one row — promoted should equal 6 (one per pattern)."""
396dc34… lmata 449 call_count = [0]
396dc34… lmata 450
396dc34… lmata 451 def side_effect(cypher, params=None):
396dc34… lmata 452 call_count[0] += 1
396dc34… lmata 453 # The 6 SELECT queries are calls 1, 2, 3, 4, 5, 6 (interleaved with SET calls)
396dc34… lmata 454 # We track by call_count on the non-SET queries
396dc34… lmata 455 if "SET n.semantic_type" not in cypher:
396dc34… lmata 456 return MagicMock(result_set=[["some_node", "some_file.py"]])
396dc34… lmata 457 return MagicMock(result_set=[])
396dc34… lmata 458
396dc34… lmata 459 store = _store_with_side_effect(side_effect)
396dc34… lmata 460 enricher = DjangoEnricher(store)
396dc34… lmata 461 result = enricher.enrich()
396dc34… lmata 462 assert result.promoted == 6
396dc34… lmata 463 assert sum(result.patterns_found.values()) == 6

Keyboard Shortcuts

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