Skip to content

Commit fb71689

Browse files
authored
Merge pull request #675 from praekeltfoundation/update-turn-migration-scripts
Small bug fixes for fetch and migrate to Turn
2 parents d472daf + 31732fa commit fb71689

File tree

6 files changed

+2644
-9
lines changed

6 files changed

+2644
-9
lines changed

poetry.lock

Lines changed: 2550 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ dev = [
6363
"responses>=0.23.1",
6464
"pre-commit>=3.2.0",
6565
"freezegun>=1.2.2",
66+
"aiohttp (>=3.13.3,<4.0.0)",
6667
]
6768

6869
[tool.pytest.ini_options]

scripts/migrate_to_turn/fetch_rapidpro_contacts.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,16 @@
1919
RAPIDPRO_URL = "https://rapidpro.qa.momconnect.co.za"
2020

2121
START_DATE = "2025-11-01 01:13:06"
22-
END_DATE = "2026-01-12 19:13:06"
22+
END_DATE = "2026-01-22 19:13:06"
2323
LIMIT = 1000
24+
INCLUDE_OPTED_OUT = False
25+
26+
MSISDN_FILTER = (
27+
os.environ.get("MSISDN_FILTER", "").split(",")
28+
if os.environ.get("MSISDN_FILTER")
29+
else []
30+
)
31+
2432

2533
FIELD_MAPPING = {
2634
"edd": {
@@ -118,7 +126,11 @@ def get_rapidpro_contacts(client, start_date=None, end_date=None):
118126
for contact in contact_batch:
119127
wa_id = get_wa_id(contact)
120128

121-
if is_opted_out(contact):
129+
if is_opted_out(contact) and not INCLUDE_OPTED_OUT:
130+
continue
131+
132+
# TODO: filtering for testing only, remove later()
133+
if wa_id and MSISDN_FILTER and wa_id not in MSISDN_FILTER:
122134
continue
123135

124136
if wa_id:

scripts/migrate_to_turn/process_fields.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def get_truthy_field(field_name):
8484
if opted_out:
8585
user_type = "deregistered_user"
8686
elif prebirth_messaging or postbirth_messaging:
87-
user_type = "push_comprehensive_user"
87+
user_type = "comprehensive_user"
8888

8989
if (
9090
not prebirth_messaging

scripts/migrate_to_turn/tests/test_fetch_rapidpro_contacts.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,75 @@ def test_fetch_rapidpro_contacts_writes_csv(self):
132132
}
133133

134134
self.assertEqual(rows[0], expected_row)
135+
136+
def test_fetch_rapidpro_contacts_skips_opted_out(self):
137+
contact = type(
138+
"Contact",
139+
(),
140+
{
141+
"fields": {"opted_out": "TRUE"},
142+
"urns": ["whatsapp:27820000000"],
143+
"modified_on": datetime(2025, 1, 3, 12, 0, 0, tzinfo=pytz.utc),
144+
},
145+
)()
146+
147+
client = FakeClient([[contact]])
148+
start_date = "2025-01-01 00:00:00"
149+
end_date = "2025-01-31 00:00:00"
150+
151+
with tempfile.TemporaryDirectory() as tmp_dir, chdir(tmp_dir):
152+
with (
153+
patch.object(fetch_rapidpro_contacts, "START_DATE", start_date),
154+
patch.object(fetch_rapidpro_contacts, "END_DATE", end_date),
155+
):
156+
fetch_rapidpro_contacts.fetch_rapidpro_contacts(client)
157+
158+
output_path = Path(tmp_dir) / "contacts-2025-01-01-2025-01-31.csv"
159+
self.assertFalse(output_path.exists())
160+
161+
def test_fetch_rapidpro_contacts_msisdn_filter(self):
162+
contact1 = type(
163+
"Contact",
164+
(),
165+
{
166+
"fields": {"opted_out": "FALSE"},
167+
"urns": ["whatsapp:27820000001"],
168+
"modified_on": datetime(2025, 1, 3, 12, 0, 0, tzinfo=pytz.utc),
169+
},
170+
)()
171+
172+
contact2 = type(
173+
"Contact",
174+
(),
175+
{
176+
"fields": {"opted_out": "FALSE"},
177+
"urns": ["whatsapp:27820000002"],
178+
"modified_on": datetime(2025, 1, 4, 12, 0, 0, tzinfo=pytz.utc),
179+
"name": "Alice",
180+
"language": "eng",
181+
},
182+
)()
183+
184+
client = FakeClient([[contact1, contact2]])
185+
start_date = "2025-01-01 00:00:00"
186+
end_date = "2025-01-31 00:00:00"
187+
188+
with tempfile.TemporaryDirectory() as tmp_dir, chdir(tmp_dir):
189+
with (
190+
patch.object(fetch_rapidpro_contacts, "START_DATE", start_date),
191+
patch.object(fetch_rapidpro_contacts, "END_DATE", end_date),
192+
patch.object(
193+
fetch_rapidpro_contacts,
194+
"MSISDN_FILTER",
195+
["27820000002"],
196+
),
197+
):
198+
fetch_rapidpro_contacts.fetch_rapidpro_contacts(client)
199+
200+
output_path = Path(tmp_dir) / "contacts-2025-01-01-2025-01-31.csv"
201+
with output_path.open(newline="") as csv_file:
202+
reader = csv.DictReader(csv_file)
203+
rows = list(reader)
204+
205+
self.assertEqual(len(rows), 1)
206+
self.assertEqual(rows[0]["urn"], "27820000002")

scripts/migrate_to_turn/tests/test_process_fields.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,22 +195,22 @@ def test_opted_out_is_deregistered(self):
195195
contact = type("Contact", (), {"fields": {"opted_out": "TRUE"}})()
196196
self.assertEqual(get_user_type(contact), "deregistered_user")
197197

198-
def test_prebirth_messaging_is_push_comprehensive(self):
198+
def test_prebirth_messaging_is_comprehensive(self):
199199
"""
200-
Prebirth messaging users are push comprehensive
200+
Prebirth messaging users are comprehensive
201201
"""
202202
contact = type("Contact", (), {"fields": {"prebirth_messaging": "TRUE"}})()
203-
self.assertEqual(get_user_type(contact), "push_comprehensive_user")
203+
self.assertEqual(get_user_type(contact), "comprehensive_user")
204204

205-
def test_postbirth_with_active_baby_is_push_comprehensive(self):
205+
def test_postbirth_with_active_baby_is_comprehensive(self):
206206
"""
207-
Postbirth users with active baby are push comprehensive
207+
Postbirth users with active baby are comprehensive
208208
"""
209209
contact = type("Contact", (), {"fields": {"postbirth_messaging": "TRUE"}})()
210210
with mock.patch(
211211
"scripts.migrate_to_turn.process_fields.has_active_baby", return_value=True
212212
):
213-
self.assertEqual(get_user_type(contact), "push_comprehensive_user")
213+
self.assertEqual(get_user_type(contact), "comprehensive_user")
214214

215215
def test_postbirth_without_active_baby_is_alumni(self):
216216
"""

0 commit comments

Comments
 (0)