Skip to content

Commit c7ab7ad

Browse files
test+docs(spp_metric_service): assert applies_to CASE wrapping; document expansion semantics
Addresses the review's two verify-items and its test gap: - two tests assert the CASE WHEN is_group = FALSE/TRUE wrapping for individuals-/groups-scoped dimensions (previously unexercised); - compute_breakdown docstring and HISTORY state the endorsed semantics: all-or-nothing expansion when any individuals dimension is present, and member-counted totals that need not reconcile with group-level scope counts.
1 parent 34f0b9f commit c7ab7ad

3 files changed

Lines changed: 49 additions & 1 deletion

File tree

spp_metric_service/models/breakdown_service.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ def compute_breakdown(self, registrant_ids, group_by, statistics=None, context=N
2424
2525
Uses dimension cache for 5-10x performance improvement.
2626
27+
Expansion semantics (deliberate): if ANY requested dimension has
28+
``applies_to == "individuals"``, the ENTIRE registrant set is expanded
29+
from groups to their active individual members before evaluation —
30+
including for any non-individual dimensions mixed into the same
31+
request (mixing scopes in one breakdown is inherently ambiguous; the
32+
expansion is all-or-nothing by design). Consequently breakdown totals
33+
count members and intentionally need not reconcile with a group-level
34+
scope count.
35+
2736
:param registrant_ids: List of partner IDs
2837
:param group_by: List of dimension names
2938
:param statistics: List of statistic names (optional)

spp_metric_service/readme/HISTORY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
### 19.0.2.1.0
22

3-
- feat: demographic breakdown expansion and SQL column support for metric disaggregation (re-land from #76; uses the spp_cel_domain SQL CASE compiler).
3+
- feat: demographic breakdown expansion and SQL column support for metric disaggregation (re-land from #76; uses the spp_cel_domain SQL CASE compiler). Expansion is all-or-nothing: any individuals-scoped dimension expands the whole registrant set to active members, so breakdown totals count members and need not reconcile with a group-level scope count.
44

55
### 19.0.2.0.0
66

spp_metric_service/tests/test_sql_column.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,42 @@ def test_cross_module_cel_call(self):
153153
# Should reference the correct alias
154154
self.assertIn("t", sql_str)
155155
self.assertIn("birthdate", sql_str)
156+
157+
def test_applies_to_individuals_wraps_in_is_group_false_case(self):
158+
"""An individuals-scoped dimension wraps its SQL in CASE WHEN is_group = FALSE."""
159+
dim = self.env["spp.demographic.dimension"].create(
160+
{
161+
"name": "test_individuals_scope",
162+
"label": "Individuals Scope",
163+
"dimension_type": "field",
164+
"field_path": "is_group",
165+
"default_value": "unknown",
166+
"applies_to": "individuals",
167+
}
168+
)
169+
result = dim.to_sql_column("p", 0)
170+
self.assertIsNotNone(result)
171+
sql_str = str(result.expression)
172+
self.assertIn("CASE WHEN", sql_str)
173+
self.assertIn("is_group", sql_str)
174+
self.assertIn("= FALSE", sql_str)
175+
# Non-matching registrants fall through to the dimension default
176+
self.assertIn("unknown", str(result.expression.params))
177+
178+
def test_applies_to_groups_wraps_in_is_group_true_case(self):
179+
"""A groups-scoped dimension wraps its SQL in CASE WHEN is_group = TRUE."""
180+
dim = self.env["spp.demographic.dimension"].create(
181+
{
182+
"name": "test_groups_scope",
183+
"label": "Groups Scope",
184+
"dimension_type": "field",
185+
"field_path": "is_group",
186+
"default_value": "unknown",
187+
"applies_to": "groups",
188+
}
189+
)
190+
result = dim.to_sql_column("p", 0)
191+
self.assertIsNotNone(result)
192+
sql_str = str(result.expression)
193+
self.assertIn("CASE WHEN", sql_str)
194+
self.assertIn("= TRUE", sql_str)

0 commit comments

Comments
 (0)