Skip to content

Commit 5477051

Browse files
authored
Merge pull request #164 from unicef/feature/show-fieldsets-in-columns
Show fieldset prefixes for household and individual columns
2 parents cde4644 + 55f407f commit 5477051

File tree

3 files changed

+218
-5
lines changed

3 files changed

+218
-5
lines changed

src/country_workspace/utils/flex_fields.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@
1414
from country_workspace.models.base import Validable
1515

1616

17-
def get_checker_fields(checker: DataChecker) -> Generator[tuple[str, str], None, None]:
18-
for fs in checker.members.select_related("fieldset").all():
17+
def get_checker_fields(checker: DataChecker, with_fs_prefix: bool = False) -> Generator[tuple[str, str], None, None]:
18+
for fs in checker.members.select_related("fieldset").order_by("fieldset_id", "prefix").all():
1919
for field in fs.fieldset.get_fields():
20-
yield field.name, (field.attrs.get("label", field.name) or field.name)
20+
yield (
21+
field.name,
22+
f"{fs.prefix if with_fs_prefix else ''}{(field.attrs.get('label', field.name) or field.name)}",
23+
)
2124

2225

2326
def get_obj_checksum(obj: "Validable") -> str:

src/country_workspace/workspaces/admin/program.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
5151
super().__init__(*args, **kwargs)
5252
columns: list[tuple[str, str]] = []
5353

54-
for name, label in get_checker_fields(self.checker):
54+
for name, label in get_checker_fields(self.checker, with_fs_prefix=True):
5555
columns.append((f"flex_fields__{name}", label))
5656

57-
self.fields["columns"].choices = self.model_core_fields + sorted(columns)
57+
self.fields["columns"].choices = self.model_core_fields + columns
5858

5959

6060
class SelectIndividualColumnsForm(SelectColumnsForm):
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
from django import forms
2+
3+
from country_workspace.workspaces.admin.program import SelectColumnsForm, SelectIndividualColumnsForm
4+
from tests.extras.testutils.factories.smart_fields import (
5+
DataCheckerFactory,
6+
DataCheckerFieldsetFactory,
7+
FieldDefinitionFactory,
8+
FieldsetFactory,
9+
FlexFieldFactory,
10+
)
11+
12+
13+
def test_init_with_checker_creates_choices_with_prefix():
14+
checker = DataCheckerFactory()
15+
fieldset1 = FieldsetFactory()
16+
fieldset2 = FieldsetFactory()
17+
18+
char_field_def = FieldDefinitionFactory(field_type=forms.CharField)
19+
int_field_def = FieldDefinitionFactory(field_type=forms.IntegerField)
20+
21+
FlexFieldFactory(fieldset=fieldset1, name="field1", definition=char_field_def, attrs={"label": "Field One"})
22+
FlexFieldFactory(fieldset=fieldset2, name="field2", definition=int_field_def, attrs={"label": "Field Two"})
23+
24+
DataCheckerFieldsetFactory(checker=checker, fieldset=fieldset1, prefix="prefix1_")
25+
DataCheckerFieldsetFactory(checker=checker, fieldset=fieldset2, prefix="prefix2_")
26+
27+
form = SelectColumnsForm(checker=checker)
28+
29+
expected_choices = [
30+
("name", "name"),
31+
("id", "id"),
32+
("flex_fields__field1", "prefix1_Field One"),
33+
("flex_fields__field2", "prefix2_Field Two"),
34+
]
35+
36+
assert form.fields["columns"].choices == expected_choices
37+
38+
39+
def test_init_with_checker_no_prefix_when_with_fs_prefix_false(monkeypatch):
40+
checker = DataCheckerFactory()
41+
called_with_prefix = None
42+
43+
def mock_get_checker_fields(checker_instance, with_fs_prefix=False):
44+
nonlocal called_with_prefix
45+
called_with_prefix = with_fs_prefix
46+
return []
47+
48+
monkeypatch.setattr("country_workspace.workspaces.admin.program.get_checker_fields", mock_get_checker_fields)
49+
50+
SelectColumnsForm(checker=checker)
51+
52+
assert called_with_prefix is True
53+
54+
55+
def test_init_with_checker_field_without_label_uses_field_name():
56+
checker = DataCheckerFactory()
57+
fieldset = FieldsetFactory()
58+
59+
char_field_def = FieldDefinitionFactory(field_type=forms.CharField)
60+
61+
FlexFieldFactory(fieldset=fieldset, name="field_without_label", definition=char_field_def, attrs={})
62+
63+
DataCheckerFieldsetFactory(checker=checker, fieldset=fieldset, prefix="test_")
64+
65+
form = SelectColumnsForm(checker=checker)
66+
67+
expected_choices = [
68+
("name", "name"),
69+
("id", "id"),
70+
("flex_fields__field_without_label", "test_field_without_label"),
71+
]
72+
73+
assert form.fields["columns"].choices == expected_choices
74+
75+
76+
def test_init_with_checker_field_with_empty_label_uses_field_name():
77+
checker = DataCheckerFactory()
78+
fieldset = FieldsetFactory()
79+
80+
char_field_def = FieldDefinitionFactory(field_type=forms.CharField)
81+
82+
FlexFieldFactory(fieldset=fieldset, name="field_with_empty_label", definition=char_field_def, attrs={"label": ""})
83+
84+
DataCheckerFieldsetFactory(checker=checker, fieldset=fieldset, prefix="test_")
85+
86+
form = SelectColumnsForm(checker=checker)
87+
88+
expected_choices = [
89+
("name", "name"),
90+
("id", "id"),
91+
("flex_fields__field_with_empty_label", "test_field_with_empty_label"),
92+
]
93+
94+
assert form.fields["columns"].choices == expected_choices
95+
96+
97+
def test_init_with_checker_field_with_none_label_uses_field_name():
98+
checker = DataCheckerFactory()
99+
fieldset = FieldsetFactory()
100+
101+
char_field_def = FieldDefinitionFactory(field_type=forms.CharField)
102+
103+
FlexFieldFactory(fieldset=fieldset, name="field_with_none_label", definition=char_field_def, attrs={"label": None})
104+
105+
DataCheckerFieldsetFactory(checker=checker, fieldset=fieldset, prefix="test_")
106+
107+
form = SelectColumnsForm(checker=checker)
108+
109+
expected_choices = [
110+
("name", "name"),
111+
("id", "id"),
112+
("flex_fields__field_with_none_label", "test_field_with_none_label"),
113+
]
114+
115+
assert form.fields["columns"].choices == expected_choices
116+
117+
118+
def test_init_with_checker_no_fieldsets_returns_only_core_fields():
119+
checker = DataCheckerFactory()
120+
121+
form = SelectColumnsForm(checker=checker)
122+
123+
expected_choices = [
124+
("name", "name"),
125+
("id", "id"),
126+
]
127+
128+
assert form.fields["columns"].choices == expected_choices
129+
130+
131+
def test_init_with_checker_empty_fieldset_returns_only_core_fields():
132+
checker = DataCheckerFactory()
133+
fieldset = FieldsetFactory()
134+
135+
DataCheckerFieldsetFactory(checker=checker, fieldset=fieldset, prefix="test_")
136+
137+
form = SelectColumnsForm(checker=checker)
138+
139+
expected_choices = [
140+
("name", "name"),
141+
("id", "id"),
142+
]
143+
144+
assert form.fields["columns"].choices == expected_choices
145+
146+
147+
def test_inherits_from_select_columns_form():
148+
assert issubclass(SelectIndividualColumnsForm, SelectColumnsForm)
149+
150+
151+
def test_has_individual_specific_core_fields():
152+
checker = DataCheckerFactory()
153+
154+
form = SelectIndividualColumnsForm(checker=checker)
155+
156+
expected_choices = [
157+
("name", "name"),
158+
("id", "id"),
159+
("household", "household"),
160+
]
161+
162+
assert form.fields["columns"].choices == expected_choices
163+
164+
165+
def test_init_with_checker_creates_choices_with_prefix_and_household_field():
166+
checker = DataCheckerFactory()
167+
fieldset = FieldsetFactory()
168+
169+
char_field_def = FieldDefinitionFactory(field_type=forms.CharField)
170+
171+
FlexFieldFactory(
172+
fieldset=fieldset, name="individual_field", definition=char_field_def, attrs={"label": "Individual Field"}
173+
)
174+
175+
DataCheckerFieldsetFactory(checker=checker, fieldset=fieldset, prefix="ind_")
176+
177+
form = SelectIndividualColumnsForm(checker=checker)
178+
179+
expected_choices = [
180+
("name", "name"),
181+
("id", "id"),
182+
("household", "household"),
183+
("flex_fields__individual_field", "ind_Individual Field"),
184+
]
185+
186+
assert form.fields["columns"].choices == expected_choices
187+
188+
189+
def test_init_with_checker_ordering_by_fieldset_id_and_prefix():
190+
checker = DataCheckerFactory()
191+
192+
fieldset1 = FieldsetFactory()
193+
fieldset2 = FieldsetFactory()
194+
195+
char_field_def = FieldDefinitionFactory(field_type=forms.CharField)
196+
197+
FlexFieldFactory(fieldset=fieldset1, name="field1", definition=char_field_def, attrs={"label": "Field One"})
198+
FlexFieldFactory(fieldset=fieldset2, name="field2", definition=char_field_def, attrs={"label": "Field Two"})
199+
200+
DataCheckerFieldsetFactory(checker=checker, fieldset=fieldset1, prefix="aaa")
201+
DataCheckerFieldsetFactory(checker=checker, fieldset=fieldset2, prefix="bbb")
202+
203+
form = SelectIndividualColumnsForm(checker=checker)
204+
205+
flex_choices = [choice for choice in form.fields["columns"].choices if choice[0].startswith("flex_fields__")]
206+
207+
expected_field_names = ["field1", "field2"]
208+
actual_field_names = [choice[0].replace("flex_fields__", "") for choice in flex_choices]
209+
210+
assert actual_field_names == expected_field_names

0 commit comments

Comments
 (0)