|
6 | 6 | from django.db import connections |
7 | 7 | from django.utils import timezone |
8 | 8 | from flag_engine.segments.constants import EQUAL, REGEX |
9 | | -from pytest_django.fixtures import SettingsWrapper |
| 9 | +from pytest_django.fixtures import DjangoAssertNumQueries, SettingsWrapper |
10 | 10 | from pytest_mock import MockerFixture |
11 | 11 | from task_processor.models import Task |
12 | 12 | from task_processor.task_run_method import TaskRunMethod |
@@ -131,7 +131,7 @@ def test_compute_segment_counts_for_project__unknown_env_key_in_row__skips( |
131 | 131 | return_value="TRUE", |
132 | 132 | ) |
133 | 133 | cursor = MagicMock() |
134 | | - cursor.fetchall.return_value = [(segment.id, "ghost-env", 99)] |
| 134 | + cursor.fetchall.return_value = [("ghost-env", 99)] |
135 | 135 |
|
136 | 136 | # When |
137 | 137 | result = compute_segment_counts_for_project(project, cursor) |
@@ -198,6 +198,27 @@ def percent_regex_segment(segment: Segment) -> Segment: |
198 | 198 | return segment |
199 | 199 |
|
200 | 200 |
|
| 201 | +@pytest.fixture |
| 202 | +def three_segments(matching_segment: Segment, project: Project) -> dict[str, Segment]: |
| 203 | + """`matching_segment` matches foo == bar (alice, bob); add one matching a |
| 204 | + different value (carol) and one matching nobody.""" |
| 205 | + seg_baz = Segment.objects.create(name="baz", project=project) |
| 206 | + Condition.objects.create( |
| 207 | + rule=SegmentRule.objects.create(segment=seg_baz, type=SegmentRule.ALL_RULE), |
| 208 | + property="foo", |
| 209 | + operator=EQUAL, |
| 210 | + value="baz", |
| 211 | + ) |
| 212 | + seg_none = Segment.objects.create(name="none", project=project) |
| 213 | + Condition.objects.create( |
| 214 | + rule=SegmentRule.objects.create(segment=seg_none, type=SegmentRule.ALL_RULE), |
| 215 | + property="foo", |
| 216 | + operator=EQUAL, |
| 217 | + value="zzz", |
| 218 | + ) |
| 219 | + return {"bar": matching_segment, "baz": seg_baz, "none": seg_none} |
| 220 | + |
| 221 | + |
201 | 222 | @pytest.mark.clickhouse |
202 | 223 | def test_get_segment_members_page__deleted_identity__excluded( |
203 | 224 | segment_membership_identities: None, |
@@ -288,6 +309,43 @@ def test_compute_segment_counts_for_project__deleted_identity__excluded_from_cou |
288 | 309 | assert counts[0].count == 2 |
289 | 310 |
|
290 | 311 |
|
| 312 | +@pytest.mark.clickhouse |
| 313 | +def test_compute_segment_counts_for_project__multiple_segments__maps_each_count_drops_zeros( |
| 314 | + segment_membership_identities: None, |
| 315 | + three_segments: dict[str, Segment], |
| 316 | + project: Project, |
| 317 | +) -> None: |
| 318 | + # Given / When |
| 319 | + with connections["clickhouse"].cursor() as cursor: |
| 320 | + counts = compute_segment_counts_for_project(project, cursor) |
| 321 | + |
| 322 | + # Then |
| 323 | + by_segment = {c.segment_id: c.count for c in counts} |
| 324 | + assert by_segment == { |
| 325 | + three_segments["bar"].id: 2, |
| 326 | + three_segments["baz"].id: 1, |
| 327 | + } |
| 328 | + assert three_segments["none"].id not in by_segment |
| 329 | + |
| 330 | + |
| 331 | +@pytest.mark.clickhouse |
| 332 | +def test_compute_segment_counts_for_project__multiple_segments__uses_single_query( |
| 333 | + segment_membership_identities: None, |
| 334 | + three_segments: dict[str, Segment], |
| 335 | + project: Project, |
| 336 | + django_assert_num_queries: DjangoAssertNumQueries, |
| 337 | +) -> None: |
| 338 | + # Given |
| 339 | + # three_segments + identities are set up by fixtures |
| 340 | + |
| 341 | + # When / Then |
| 342 | + with ( |
| 343 | + django_assert_num_queries(1, connection=connections["clickhouse"]), |
| 344 | + connections["clickhouse"].cursor() as cursor, |
| 345 | + ): |
| 346 | + compute_segment_counts_for_project(project, cursor) |
| 347 | + |
| 348 | + |
291 | 349 | @pytest.mark.clickhouse |
292 | 350 | def test_get_segment_members_page__regex_with_percent__returns_matches( |
293 | 351 | segment_membership_identities: None, |
|
0 commit comments