Skip to content

Commit e56f9d4

Browse files
authored
Merge pull request #159 from unicef/bugfix/261280-consent-sharing-not-working-properly
AB#261280: Consent sharing now working properly
2 parents f14126a + 8f47af9 commit e56f9d4

File tree

3 files changed

+73
-16
lines changed

3 files changed

+73
-16
lines changed

src/country_workspace/utils/fields.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515

1616
TO_REMOVE_VALUES = "_h_c", "_h_f", "_i_c", "_i_f"
17-
TO_UPPERCASE_FIELDS = "relationship", "gender", "residence_status"
17+
TO_UPPERCASE_FIELDS = "relationship", "gender", "residence_status", "consent_sharing"
1818
TO_MAP_FIELDS = {"gender": "sex"}
1919

2020

src/country_workspace/utils/flex_fields.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,29 @@ def clean(self, data: UploadedFile | Literal[False] | None, initial: str | None
5151
return None
5252

5353

54+
def split_consent_sharing_options(value: str) -> list[str]:
55+
stripped = value.strip()
56+
57+
if not stripped:
58+
return []
59+
60+
# If there's a comma we split by comma, otherwise space is used as a separator
61+
for separator in (",", " "):
62+
if separator in stripped:
63+
return [s for part in value.split(separator) if (s := part.strip())]
64+
65+
return [stripped]
66+
67+
5468
class ConsentSharingChoice(forms.MultipleChoiceField):
5569
def to_python(self, value: str | list[str] | None) -> list[str]:
5670
if isinstance(value, str):
57-
return [stripped for v in value.split(",") if (stripped := v.strip())]
71+
return split_consent_sharing_options(value)
72+
5873
return super().to_python(value)
5974

6075
def prepare_value(self, value: str | list[str] | None) -> list[str]:
6176
if isinstance(value, str):
62-
return [v for v in value.split(",") if v]
77+
return split_consent_sharing_options(value)
78+
6379
return super().prepare_value(value)

tests/utils/test_utils_fields.py

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from unittest.mock import Mock
1+
from unittest.mock import Mock, call
22

33
import pytest
44
from django.core.files.uploadedfile import SimpleUploadedFile
@@ -15,7 +15,12 @@
1515
map_fields,
1616
extract_uuid,
1717
)
18-
from country_workspace.utils.flex_fields import Base64ImageInput, Base64ImageField, ConsentSharingChoice
18+
from country_workspace.utils.flex_fields import (
19+
Base64ImageInput,
20+
Base64ImageField,
21+
ConsentSharingChoice,
22+
split_consent_sharing_options,
23+
)
1924

2025

2126
@pytest.mark.parametrize(
@@ -131,17 +136,53 @@ def test_extract_uuid_errors(value: str | int, prefix: str | int | None, exc_typ
131136

132137

133138
@pytest.mark.parametrize(
134-
("raw", "expected_py", "expected_prep"),
139+
("value", "expected"),
140+
[
141+
pytest.param("a,b,c", abc := ["a", "b", "c"], id="comma"),
142+
pytest.param("a b c", abc, id="space"),
143+
pytest.param("a, b,c ", abc, id="comma-strip"),
144+
pytest.param("a b c ", abc, id="space-strip"),
145+
pytest.param("", [], id="empty"),
146+
pytest.param("a", ["a"], id="single"),
147+
],
148+
)
149+
def test_split_consent_sharing_options(value: str, expected: list[str]) -> None:
150+
assert split_consent_sharing_options(value) == expected
151+
152+
153+
@pytest.mark.parametrize(
154+
"value",
135155
[
136-
("a,b,c", ["a", "b", "c"], ["a", "b", "c"]),
137-
(" a , b ,c ", ["a", "b", "c"], [" a ", " b ", "c "]),
138-
("", [], []),
139-
(None, [], None),
140-
(["x", "y"], ["x", "y"], ["x", "y"]),
156+
pytest.param(None, id="none"),
157+
pytest.param(["a", "b"], id="list"),
141158
],
142-
ids=["comma", "spaces", "empty", "none", "list"],
143159
)
144-
def test_consent_sharing_choice_to_python_and_prepare_value(raw, expected_py, expected_prep):
145-
field = ConsentSharingChoice(choices=[])
146-
assert field.to_python(raw) == expected_py
147-
assert field.prepare_value(raw) == expected_prep
160+
def test_consent_sharing_choice_to_python_and_prepare_value_call_super_method(
161+
mocker: MockerFixture, value: list[str] | None
162+
) -> None:
163+
super_to_python_mock = mocker.patch("country_workspace.utils.flex_fields.forms.MultipleChoiceField.to_python")
164+
super_prepare_value_mock = mocker.patch(
165+
"country_workspace.utils.flex_fields.forms.MultipleChoiceField.prepare_value"
166+
)
167+
instance = Mock(spec=ConsentSharingChoice)
168+
169+
ConsentSharingChoice.prepare_value(instance, value)
170+
ConsentSharingChoice.to_python(instance, value)
171+
172+
super_to_python_mock.assert_called_once_with(value)
173+
super_prepare_value_mock.assert_called_once_with(value)
174+
175+
176+
def test_consent_sharing_choice_to_python_and_prepare_value_call_split_consent_sharing_options(
177+
mocker: MockerFixture,
178+
) -> None:
179+
value = "test"
180+
split_consent_sharing_options_mock = mocker.patch(
181+
"country_workspace.utils.flex_fields.split_consent_sharing_options"
182+
)
183+
instance = Mock(spec=ConsentSharingChoice)
184+
185+
ConsentSharingChoice.to_python(instance, value)
186+
ConsentSharingChoice.prepare_value(instance, value)
187+
188+
split_consent_sharing_options_mock.assert_has_calls([c := call(value), c])

0 commit comments

Comments
 (0)