Skip to content

Commit 0e55b8e

Browse files
author
Arsen P
committed
Add unit tests for transformer application in batch processing
- Introduced multiple test cases for the `_apply_transformer_only` and `apply_batch_transformers` functions to ensure correct behavior when applying transformations to individual and household records. - Added tests to verify that transformers are only applied when necessary and handle various flex field types appropriately. - Included checks for error handling when transformer IDs are missing, enhancing the robustness of batch processing functionality.
1 parent 9e3e48c commit 0e55b8e

1 file changed

Lines changed: 185 additions & 0 deletions

File tree

tests/workspace/test_batch_reprocessing_task.py

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,3 +1142,188 @@ def test_reprocess_kobo_resolves_household_refs(program, user: User, force_migra
11421142
assert household.flex_fields["head_of_household_id"] == head.pk
11431143
assert household.flex_fields["primary_collector_id"] == primary.pk
11441144
assert household.flex_fields["alternate_collector_id"] == alternate.pk
1145+
1146+
1147+
def test_apply_transformer_only_updates_record(program, user: User, force_migrated_records) -> None:
1148+
from country_workspace.workspaces.admin.batch.reprocessing import _apply_transformer_only
1149+
from testutils.factories import CountryIndividualFactory, TransformerFactory
1150+
1151+
individual = CountryIndividualFactory(
1152+
household=None,
1153+
batch__program=program,
1154+
batch__country_office=program.country_office,
1155+
flex_fields={"gender": "F"},
1156+
)
1157+
transformer = TransformerFactory(
1158+
office=program.country_office,
1159+
value_transformations="function t(d) { d['gender'] = 'FEMALE'; return d; }",
1160+
)
1161+
1162+
applied = _apply_transformer_only(individual, transformer)
1163+
1164+
assert applied is True
1165+
individual.refresh_from_db()
1166+
assert individual.flex_fields["gender"] == "FEMALE"
1167+
1168+
1169+
def test_apply_transformer_only_returns_false_when_unchanged(program, user: User, force_migrated_records) -> None:
1170+
from country_workspace.workspaces.admin.batch.reprocessing import _apply_transformer_only
1171+
from testutils.factories import CountryIndividualFactory, TransformerFactory
1172+
1173+
individual = CountryIndividualFactory(
1174+
household=None,
1175+
batch__program=program,
1176+
batch__country_office=program.country_office,
1177+
flex_fields={"gender": "F"},
1178+
)
1179+
transformer = TransformerFactory(
1180+
office=program.country_office,
1181+
value_transformations="function t(d) { return d; }",
1182+
)
1183+
1184+
applied = _apply_transformer_only(individual, transformer)
1185+
1186+
assert applied is False
1187+
1188+
1189+
def test_apply_transformer_only_uses_empty_dict_for_non_dict_flex_fields(
1190+
program, user: User, force_migrated_records
1191+
) -> None:
1192+
from country_workspace.workspaces.admin.batch.reprocessing import _apply_transformer_only
1193+
from testutils.factories import CountryIndividualFactory, TransformerFactory
1194+
1195+
individual = CountryIndividualFactory(
1196+
household=None,
1197+
batch__program=program,
1198+
batch__country_office=program.country_office,
1199+
flex_fields="unexpected",
1200+
)
1201+
transformer = TransformerFactory(
1202+
office=program.country_office,
1203+
value_transformations="function t(d) { d['created'] = true; return d; }",
1204+
)
1205+
1206+
applied = _apply_transformer_only(individual, transformer)
1207+
1208+
assert applied is True
1209+
individual.refresh_from_db()
1210+
assert individual.flex_fields["created"] is True
1211+
1212+
1213+
def test_apply_batch_transformers_requires_transformer_ids(program, user: User) -> None:
1214+
from country_workspace.workspaces.admin.batch.reprocessing import apply_batch_transformers
1215+
from testutils.factories import AsyncJobFactory, CountryBatchFactory
1216+
1217+
batch = CountryBatchFactory(program=program, country_office=program.country_office)
1218+
job = AsyncJobFactory(program=program, batch=batch, owner=user, config={"batch_id": batch.pk})
1219+
1220+
with pytest.raises(ValueError, match="At least one transformer id is required"):
1221+
apply_batch_transformers(job)
1222+
1223+
1224+
def test_apply_batch_transformers_applies_individual_only(program, user: User, force_migrated_records) -> None:
1225+
from country_workspace.workspaces.admin.batch.reprocessing import apply_batch_transformers
1226+
from testutils.factories import AsyncJobFactory, CountryIndividualFactory, TransformerFactory
1227+
1228+
individual = CountryIndividualFactory(
1229+
household=None,
1230+
batch__program=program,
1231+
batch__country_office=program.country_office,
1232+
flex_fields={"status": "1"},
1233+
)
1234+
batch = individual.batch
1235+
transformer = TransformerFactory(
1236+
office=program.country_office,
1237+
value_transformations="function t(d) { d['status'] = 'ACTIVE'; return d; }",
1238+
)
1239+
job = AsyncJobFactory(
1240+
program=program,
1241+
batch=batch,
1242+
owner=user,
1243+
config={"batch_id": batch.pk, "individual_transformer_id": transformer.pk},
1244+
)
1245+
1246+
with patch("country_workspace.workspaces.admin.batch.reprocessing.sync_collector_links") as mock_sync:
1247+
result = apply_batch_transformers(job)
1248+
1249+
individual.refresh_from_db()
1250+
assert individual.flex_fields["status"] == "ACTIVE"
1251+
assert result["batch_id"] == batch.pk
1252+
assert result["transformed_individuals"] == 1
1253+
mock_sync.assert_called_once()
1254+
1255+
1256+
def test_apply_batch_transformers_applies_household_only_master_detail(
1257+
program, user: User, force_migrated_records
1258+
) -> None:
1259+
from country_workspace.workspaces.admin.batch.reprocessing import apply_batch_transformers
1260+
from testutils.factories import AsyncJobFactory, CountryHouseholdFactory, TransformerFactory
1261+
from testutils.factories.program import BeneficiaryGroupFactory
1262+
1263+
bg = BeneficiaryGroupFactory(master_detail=True)
1264+
program.beneficiary_group = bg
1265+
program.save()
1266+
1267+
household = CountryHouseholdFactory(
1268+
batch__program=program,
1269+
batch__country_office=program.country_office,
1270+
flex_fields={"category": "A"},
1271+
)
1272+
batch = household.batch
1273+
transformer = TransformerFactory(
1274+
office=program.country_office,
1275+
value_transformations="function t(d) { d['category'] = 'B'; return d; }",
1276+
)
1277+
job = AsyncJobFactory(
1278+
program=program,
1279+
batch=batch,
1280+
owner=user,
1281+
config={"batch_id": batch.pk, "household_transformer_id": transformer.pk},
1282+
)
1283+
1284+
with patch("country_workspace.workspaces.admin.batch.reprocessing._sync_household_refs") as mock_sync:
1285+
result = apply_batch_transformers(job)
1286+
1287+
household.refresh_from_db()
1288+
assert household.flex_fields["category"] == "B"
1289+
assert result["transformed_households"] == 1
1290+
assert result["transformed_individuals"] == 0
1291+
mock_sync.assert_called_once_with(batch)
1292+
1293+
1294+
def test_apply_batch_transformers_skips_households_for_non_master_detail(
1295+
program, user: User, force_migrated_records
1296+
) -> None:
1297+
from country_workspace.workspaces.admin.batch.reprocessing import apply_batch_transformers
1298+
from testutils.factories import AsyncJobFactory, CountryHouseholdFactory, TransformerFactory
1299+
from testutils.factories.program import BeneficiaryGroupFactory
1300+
1301+
bg = BeneficiaryGroupFactory(master_detail=False)
1302+
program.beneficiary_group = bg
1303+
program.save()
1304+
1305+
household = CountryHouseholdFactory(
1306+
batch__program=program,
1307+
batch__country_office=program.country_office,
1308+
flex_fields={"category": "A"},
1309+
)
1310+
batch = household.batch
1311+
transformer = TransformerFactory(
1312+
office=program.country_office,
1313+
value_transformations="function t(d) { d['category'] = 'B'; return d; }",
1314+
)
1315+
job = AsyncJobFactory(
1316+
program=program,
1317+
batch=batch,
1318+
owner=user,
1319+
config={"batch_id": batch.pk, "household_transformer_id": transformer.pk},
1320+
)
1321+
1322+
with patch("country_workspace.workspaces.admin.batch.reprocessing._sync_household_refs") as mock_sync:
1323+
result = apply_batch_transformers(job)
1324+
1325+
household.refresh_from_db()
1326+
assert household.flex_fields["category"] == "A"
1327+
assert "transformed_households" not in result
1328+
assert result["transformed_individuals"] == 0
1329+
mock_sync.assert_not_called()

0 commit comments

Comments
 (0)