From b2a5e32705f5dc0de0e8dbad6703816986c6ded8 Mon Sep 17 00:00:00 2001 From: grahamalama Date: Wed, 30 Aug 2023 14:39:57 -0400 Subject: [PATCH] Fix special boolean text values on the main table (#804) These values that we sync to the main contact table of Acoustic - "double_opt_in", - "has_opted_out_of_email", - "fxa_account_deleted", - "amo_email_opt_in", are booleans in our database. We were writing them as `1`/ `0` to Acoustic until https:/github.com/mozilla-it/ctms-api/pull/762, where we started recording values as `Yes` / `No`, which is how boolean values are recorded in Acoustic elsewhere. The queries built on top of the Acoustic contact database expected `1` / `0`, though. Until we can migrate the columns and queries that use these colums to proper boolean types in Acoustic, we're going to temporarily handle these special cases and backfill `Yes`/ `No` values to their `1` / `0` notation. --- ctms/acoustic_service.py | 13 ++++++++++- tests/unit/test_acoustic_service.py | 36 +++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/ctms/acoustic_service.py b/ctms/acoustic_service.py index 6339bd97..4a1ad680 100644 --- a/ctms/acoustic_service.py +++ b/ctms/acoustic_service.py @@ -257,7 +257,18 @@ def _main_table_converter(self, contact, main_fields): inner_value = self.fxa_created_date_string_to_datetime( inner_value ) - + # TODO: These are boolean values on our models, but in Acoustic + # they are configured as text values where we record `True` + # and `False` as `1` and `0` respectively. We should + # configure Acoustic to use a boolean column for this data. + # This is being tracked in https://github.com/mozilla-it/ctms-api/issues/803 + if acoustic_field_name in ( + "double_opt_in", + "has_opted_out_of_email", + "fxa_account_deleted", + "amo_email_opt_in", + ): + inner_value = "1" if inner_value else "0" acoustic_main_table[ acoustic_field_name ] = transform_field_for_acoustic(inner_value) diff --git a/tests/unit/test_acoustic_service.py b/tests/unit/test_acoustic_service.py index ee4590f4..21f53d7e 100644 --- a/tests/unit/test_acoustic_service.py +++ b/tests/unit/test_acoustic_service.py @@ -81,6 +81,42 @@ def test_ctms_to_acoustic_no_product( assert len(products) == 0, f"{i + 1}/3: no products in contact." +@pytest.mark.parametrize("model_value,acoustic_value", [(False, "0"), (True, "1")]) +def test_ctms_to_acoustic_special_booleans( + dbsession, + base_ctms_acoustic_service, + email_factory, + main_acoustic_fields, + waitlist_acoustic_fields, + acoustic_newsletters_mapping, + model_value, + acoustic_value, +): + email = email_factory( + double_opt_in=model_value, + has_opted_out_of_email=model_value, + fxa=True, + amo=True, + amo__email_opt_in=model_value, + fxa__account_deleted=model_value, + ) + dbsession.commit() + + contact = ContactSchema.from_email(email) + + (main, _, _, _) = base_ctms_acoustic_service.convert_ctms_to_acoustic( + contact, + main_acoustic_fields, + waitlist_acoustic_fields, + acoustic_newsletters_mapping, + ) + + assert main["double_opt_in"] == acoustic_value + assert main["has_opted_out_of_email"] == acoustic_value + assert main["fxa_account_deleted"] == acoustic_value + assert main["amo_email_opt_in"] == acoustic_value + + def test_ctms_to_acoustic_newsletters( dbsession, base_ctms_acoustic_service,