From 8c892582a1eae9e0712654abe7c65bb0e36efeaa Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Thu, 1 Feb 2024 14:25:23 +0200 Subject: [PATCH 01/20] test passing with new field --- home/models.py | 6 ++++++ home/tests/page_builder.py | 1 + home/tests/test_content_import_export.py | 1 + home/tests/test_models.py | 2 ++ home/tests/test_page_builder.py | 4 ++++ 5 files changed, 14 insertions(+) diff --git a/home/models.py b/home/models.py index 02a1cc64..b9ffbf49 100644 --- a/home/models.py +++ b/home/models.py @@ -268,6 +268,12 @@ class WhatsappBlock(blocks.StructBlock): max_num=3, ) + footer = blocks.CharBlock( + help_text="Footer cannot exceed 60 characters.", + required=False, + validators=(MaxLengthValidator(60),), + ) + class Meta: icon = "user" form_classname = "whatsapp-message-block struct-block" diff --git a/home/tests/page_builder.py b/home/tests/page_builder.py index e3b3d39f..f921fbe3 100644 --- a/home/tests/page_builder.py +++ b/home/tests/page_builder.py @@ -112,6 +112,7 @@ class WABlk(ContentBlock): variation_messages: list[VarMsg] = field(default_factory=list) example_values: list[str] = field(default_factory=list) buttons: list[Btn] = field(default_factory=list) + footer: str | None = None def to_dict(self) -> dict[str, Any]: varmsgs = [vm.to_dict() for vm in self.variation_messages] diff --git a/home/tests/test_content_import_export.py b/home/tests/test_content_import_export.py index 31165973..0f83a473 100644 --- a/home/tests/test_content_import_export.py +++ b/home/tests/test_content_import_export.py @@ -334,6 +334,7 @@ def add_body_fields(page: DbDict) -> DbDict: "next_prompt": "", "example_values": [], "variation_messages": [], + "footer": None, }, ) if "sms_body" in page["fields"]: diff --git a/home/tests/test_models.py b/home/tests/test_models.py index dce1405d..f2c5fbc9 100644 --- a/home/tests/test_models.py +++ b/home/tests/test_models.py @@ -334,6 +334,7 @@ def create_message_value( example_values=None, next_prompt="", buttons=None, + footer="", ): return { "image": image, @@ -344,6 +345,7 @@ def create_message_value( "variation_messages": variation_messages, "next_prompt": next_prompt, "buttons": buttons or [], + "footer": footer, } def create_image(self, width=0, height=0): diff --git a/home/tests/test_page_builder.py b/home/tests/test_page_builder.py index f9a34173..6416d30b 100644 --- a/home/tests/test_page_builder.py +++ b/home/tests/test_page_builder.py @@ -137,6 +137,7 @@ def test_build_simple_pages() -> None: "buttons": [], "example_values": [], "variation_messages": [], + "footer": None, }, ), ] @@ -260,6 +261,7 @@ def test_build_variations() -> None: {"message": "Single male", "variation_restrictions": v_single_male}, {"message": "Comp male", "variation_restrictions": v_complicated_male}, ], + "footer": None, }, { "message": "Message 2, variable placeholders as well {{0}}", @@ -271,6 +273,7 @@ def test_build_variations() -> None: "variation_messages": [ {"message": "Teen", "variation_restrictions": [("age", "15-18")]} ], + "footer": None, }, { "message": "Message 3 with no variation", @@ -278,6 +281,7 @@ def test_build_variations() -> None: "buttons": [("next_message", {"title": "end"})], "example_values": [], "variation_messages": [], + "footer": None, }, ] From 1fc462300565fabec2fd9213409affc9083f1816 Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Thu, 1 Feb 2024 15:06:02 +0200 Subject: [PATCH 02/20] add footer to export --- contentrepo/settings/base.py | 2 +- home/export_content_pages.py | 4 + .../0048_alter_contentpage_whatsapp_body.py | 201 ++++++++++++++++++ home/tests/content2.csv | 10 +- ...ontent_20230911-variations-linked-page.csv | 24 +-- home/tests/multiple_messages.csv | 16 +- home/tests/no-translation-key-default.csv | 6 +- home/tests/translations-en.csv | 6 +- home/tests/translations-pt.csv | 6 +- home/tests/translations-sep-en.csv | 6 +- home/tests/translations-sep-pt.csv | 6 +- home/tests/translations-sep.csv | 10 +- home/tests/translations.csv | 10 +- 13 files changed, 256 insertions(+), 51 deletions(-) create mode 100644 home/migrations/0048_alter_contentpage_whatsapp_body.py diff --git a/contentrepo/settings/base.py b/contentrepo/settings/base.py index 2313f5cd..30f10ded 100644 --- a/contentrepo/settings/base.py +++ b/contentrepo/settings/base.py @@ -90,7 +90,7 @@ "default": dj_database_url.config( default=os.environ.get( "CONTENTREPO_DATABASE", - "postgres://postgres@localhost/contentrepo", + "postgres://postgres:myPassword@localhost/contentrepo", ), engine="django.db.backends.postgresql", ) diff --git a/home/export_content_pages.py b/home/export_content_pages.py index d194cda8..21cc93dc 100644 --- a/home/export_content_pages.py +++ b/home/export_content_pages.py @@ -76,6 +76,7 @@ class ExportRow: doc_link: str = "" media_link: str = "" related_pages: str = "" + footer: str = "" @classmethod def headings(cls) -> list[str]: @@ -132,6 +133,8 @@ def add_message_fields(self, msg_blocks: MsgBlocks) -> None: self.buttons = self.serialise_buttons(whatsapp.value["buttons"]) if "example_values" in whatsapp.value: self.example_values = ", ".join(whatsapp.value["example_values"]) + if "footer" in whatsapp.value: + self.footer = whatsapp.value["footer"] @staticmethod def serialise_buttons(buttons: blocks.StreamValue.StreamChild) -> str: @@ -341,6 +344,7 @@ def _set_xlsx_styles(wb: Workbook, sheet: Worksheet) -> None: "doc_link": 118, "media_link": 118, "related": 118, + "footer": 118, } for index, column_width in enumerate(column_widths_in_pts.values(), 2): diff --git a/home/migrations/0048_alter_contentpage_whatsapp_body.py b/home/migrations/0048_alter_contentpage_whatsapp_body.py new file mode 100644 index 00000000..7b61943e --- /dev/null +++ b/home/migrations/0048_alter_contentpage_whatsapp_body.py @@ -0,0 +1,201 @@ +# Generated by Django 4.1.10 on 2024-02-01 13:02 + +import django.core.validators +from django.db import migrations +import home.models +import wagtail.blocks +import wagtail.documents.blocks +import wagtail.fields +import wagtail.images.blocks + + +class Migration(migrations.Migration): + dependencies = [ + ("home", "0047_alter_contentpage_messenger_title_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="contentpage", + name="whatsapp_body", + field=wagtail.fields.StreamField( + [ + ( + "Whatsapp_Message", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + required=False + ), + ), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + icon="document", required=False + ), + ), + ( + "media", + home.models.MediaBlock( + icon="media", required=False + ), + ), + ( + "message", + wagtail.blocks.TextBlock( + help_text="each text message cannot exceed 4096 characters, messages with media cannot exceed 1024 characters.", + validators=( + django.core.validators.MaxLengthValidator( + 4096 + ), + ), + ), + ), + ( + "example_values", + wagtail.blocks.ListBlock( + wagtail.blocks.CharBlock(label="Example Value"), + default=[], + help_text="Please add example values for all variables used in a WhatsApp template", + label="Variable Example Values", + ), + ), + ( + "variation_messages", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "variation_restrictions", + wagtail.blocks.StreamBlock( + [ + ( + "gender", + wagtail.blocks.ChoiceBlock( + choices=home.models.get_gender_choices + ), + ), + ( + "age", + wagtail.blocks.ChoiceBlock( + choices=home.models.get_age_choices + ), + ), + ( + "relationship", + wagtail.blocks.ChoiceBlock( + choices=home.models.get_relationship_choices + ), + ), + ], + help_text="Restrict this variation to users with this profile value. Valid values must be added to the Site Settings", + max_num=1, + min_num=1, + required=False, + use_json_field=True, + ), + ), + ( + "message", + wagtail.blocks.TextBlock( + help_text="each message cannot exceed 4096 characters.", + validators=( + django.core.validators.MaxLengthValidator( + 4096 + ), + ), + ), + ), + ] + ), + default=[], + ), + ), + ( + "next_prompt", + wagtail.blocks.CharBlock( + help_text="prompt text for next message", + required=False, + validators=( + django.core.validators.MaxLengthValidator( + 20 + ), + ), + ), + ), + ( + "buttons", + wagtail.blocks.StreamBlock( + [ + ( + "next_message", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="text for the button, up to 20 characters.", + validators=( + django.core.validators.MaxLengthValidator( + 20 + ), + ), + ), + ) + ] + ), + ), + ( + "go_to_page", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="text for the button, up to 20 characters.", + validators=( + django.core.validators.MaxLengthValidator( + 20 + ), + ), + ), + ), + ( + "page", + wagtail.blocks.PageChooserBlock( + help_text="page the button should go to" + ), + ), + ] + ), + ), + ], + max_num=3, + required=False, + ), + ), + ( + "footer", + wagtail.blocks.CharBlock( + help_text="Footer cannot exceed 60 characters.", + required=False, + validators=( + django.core.validators.MaxLengthValidator( + 60 + ), + ), + ), + ), + ], + help_text="Each message will be sent with the text and media", + ), + ) + ], + blank=True, + null=True, + use_json_field=True, + ), + ), + ] diff --git a/home/tests/content2.csv b/home/tests/content2.csv index e828e85a..76b941ba 100644 --- a/home/tests/content2.csv +++ b/home/tests/content2.csv @@ -1,5 +1,5 @@ -structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages,example_values -Menu 1,0,,main-menu,,Main Menu,,,,,,,,,,,,,,,a0b85075-d01b-46bf-8997-8591e87ba171,,,,English,,,,,,,[] +structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages,example_values,footer +Menu 1,0,,main-menu,,Main Menu,,,,,,,,,,,,,,,a0b85075-d01b-46bf-8997-8591e87ba171,,,,English,,,,,,,[], Sub 1.1,1,,main-menu-first-time-user,Main Menu,main menu first time user,,,main menu first time user," *Welcome to HealthAlert* 🌍 This is a messaging service created by the _*World Health Organization*_ *(WHO)* that provides information on COVID-19 as well as emergency resources for disease outbreaks, natural, and man-made disasters. @@ -12,12 +12,12 @@ This is a messaging service created by the World Health Organization (WHO) that You can return to this main menu at any time by replying 🏠 -Choose what you'd like to know more about by tapping a button below ⬇️",,,5892bccd-8025-419d-9a8e-a6a37b755dbf,menu,"Self-help🌬️, Settings⚙️, Health Info🏥",Main menu🏠,English,,[],,,,,[] +Choose what you'd like to know more about by tapping a button below ⬇️",,,5892bccd-8025-419d-9a8e-a6a37b755dbf,menu,"Self-help🌬️, Settings⚙️, Health Info🏥",Main menu🏠,English,,[],,,,,[], Sub 1.1.1,1,,health-info,main menu first time user,health info,,,health info,"*Health information* 🏥 Get information and advice from WHO by tapping on a button below ⬇️",,,Health Info SMS Title,*Health Info SMS Body*,Health Info USSD Title,*Health Info USSD Body*,health info,"*Health information* 🏥 -Get information and advice from WHO by tapping on a button below ⬇️",,,c9d6309e-173f-4c1d-bbaf-440b1fd4415f,health_info,,,English,,[],,,,,[] +Get information and advice from WHO by tapping on a button below ⬇️",,,c9d6309e-173f-4c1d-bbaf-440b1fd4415f,health_info,,,English,,[],,,,,[], Sub 1.1.2,1,,self-help,main menu first time user,self-help,,,self-help,"*Self-help programs* 🌬️ Reply with a number to take part in a *free* self-help program created by WHO. @@ -32,4 +32,4 @@ Reply with a number to take part in a *free* self-help program created by WHO. 1. Quit tobacco 🚭 _Stop smoking with the help of a guided, 42-day program._ 2. Manage your stress 🧘🏽‍♀️ -_Learn how to cope with stress and improve your wellbeing._",,,3e5d77f7-4d34-430d-aad7-d9ca01f79732,self_help,,,English,,[],,,,,[] +_Learn how to cope with stress and improve your wellbeing._",,,3e5d77f7-4d34-430d-aad7-d9ca01f79732,self_help,,,English,,[],,,,,[], diff --git a/home/tests/exported_content_20230911-variations-linked-page.csv b/home/tests/exported_content_20230911-variations-linked-page.csv index 97d0c644..fea476f3 100644 --- a/home/tests/exported_content_20230911-variations-linked-page.csv +++ b/home/tests/exported_content_20230911-variations-linked-page.csv @@ -1,12 +1,12 @@ -structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages,example_values -Menu 1,0,5,appointment-reminders,,Appointment reminders,,,,,,,,,,,,,,,,8cff04aa-cf08-4120-88b4-e2269b7d5d80,,,,English,,,,,,, -Menu 2,0,6,stage-based-messages,,Stage-based messages,,,,,,,,,,,,,,,,5f2d9e63-f047-41ab-921a-c5ca7c04d643,,,,English,,,,,,, -Menu 3,0,7,health-info-messages,,Health info messages,,,,,,,,,,,,,,,,3db069a4-7112-4e66-a9a2-f35c6c18055a,,,,English,,,,,,, -Menu 4,0,17,whatsapp-template-testing,,whatsapp template testing,,,,,,,,,,,,,,,,5f7221f4-146a-48c2-b2e3-c8491aaead9d,,,,English,,,,,,, -Menu 5,0,164,import-export,,Import Export,,,,,,,,,,,,,,,,497bdc1f-43fc-4925-80a1-e68cb942faa4,,,,English,,,,,,, -Sub 5.1,1,165,cp-import-export,Import Export,CP-Import/export,,,WA import export data,Message 1 contains an image,,,,,,,,,,,,8ac50daf-de21-4d05-b697-6d983b7ed3d5,"Tag2, Tag1",Quick reply1,"Trigger2, Trigger1",English,,[],/admin/images/usage/4/,,,ma_qa_temp, -,1,165,cp-import-export,,,,,,,,gender: male,Variation message one for Gender Male,,,,,,,,,,,,,,,,,,,, -,2,165,cp-import-export,,,,,,"Message2 has a document attached, lets add some variable placeholders as well {{0}}",,,,,,,,,,,,,,,,,,[],,/admin/documents/usage/1/,,, -,2,165,cp-import-export,,,,,,,,gender: empty,Variation message one for Gender Rather not say,,,,,,,,,,,,,,,,,,,, -,3,165,cp-import-export,,,,,,Message 3 with no variation but has an audio clip,,,,,,,,,,,,,,,,,,[],,,/admin/media/usage/1/,, -Sub 5.2,1,166,ma_qa_temp,Import Export,MA QA Temp,,,,,,,,,,,,,,,,e9793b5f-f8c7-46c5-8a5e-bd9b8f00fee9,,,,English,,,,,,, +structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages,example_values,footer +Menu 1,0,5,appointment-reminders,,Appointment reminders,,,,,,,,,,,,,,,,8cff04aa-cf08-4120-88b4-e2269b7d5d80,,,,English,,,,,,,, +Menu 2,0,6,stage-based-messages,,Stage-based messages,,,,,,,,,,,,,,,,5f2d9e63-f047-41ab-921a-c5ca7c04d643,,,,English,,,,,,,, +Menu 3,0,7,health-info-messages,,Health info messages,,,,,,,,,,,,,,,,3db069a4-7112-4e66-a9a2-f35c6c18055a,,,,English,,,,,,,, +Menu 4,0,17,whatsapp-template-testing,,whatsapp template testing,,,,,,,,,,,,,,,,5f7221f4-146a-48c2-b2e3-c8491aaead9d,,,,English,,,,,,,, +Menu 5,0,164,import-export,,Import Export,,,,,,,,,,,,,,,,497bdc1f-43fc-4925-80a1-e68cb942faa4,,,,English,,,,,,,, +Sub 5.1,1,165,cp-import-export,Import Export,CP-Import/export,,,WA import export data,Message 1 contains an image,,,,,,,,,,,,8ac50daf-de21-4d05-b697-6d983b7ed3d5,"Tag2, Tag1",Quick reply1,"Trigger2, Trigger1",English,,[],/admin/images/usage/4/,,,ma_qa_temp,, +,1,165,cp-import-export,,,,,,,,gender: male,Variation message one for Gender Male,,,,,,,,,,,,,,,,,,,,, +,2,165,cp-import-export,,,,,,"Message2 has a document attached, lets add some variable placeholders as well {{0}}",,,,,,,,,,,,,,,,,,[],,/admin/documents/usage/1/,,,, +,2,165,cp-import-export,,,,,,,,gender: empty,Variation message one for Gender Rather not say,,,,,,,,,,,,,,,,,,,,, +,3,165,cp-import-export,,,,,,Message 3 with no variation but has an audio clip,,,,,,,,,,,,,,,,,,[],,,/admin/media/usage/1/,,, +Sub 5.2,1,166,ma_qa_temp,Import Export,MA QA Temp,,,,,,,,,,,,,,,,e9793b5f-f8c7-46c5-8a5e-bd9b8f00fee9,,,,English,,,,,,,, diff --git a/home/tests/multiple_messages.csv b/home/tests/multiple_messages.csv index 2d9255a0..daa9e1e2 100644 --- a/home/tests/multiple_messages.csv +++ b/home/tests/multiple_messages.csv @@ -1,8 +1,8 @@ -structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages -Menu 1,0,600,main-menu,,Main Menu,,,,,,,,,,,,,,,,,35a7f12c-7373-42a6-9ca6-a1caedea5822,,,,English,,,,,, -Sub 1.1,1,601,ha-menu,Main Menu,HealthAlert menu,,,HealthAlert menu,*Welcome to HealthAlert* WA,,UTILITY,,,,,,,HealthAlert menu,Welcome to HealthAlert M,HealthAlert menu,Welcome to HealthAlert V,5ab08854-228b-4f83-ae54-ec2dc6ebaf69,,,,English,,[],,,, -Sub 1.1.1,1,602,health-info,HealthAlert menu,health info,,,health info,wa1,,UTILITY,,,,,,,health info,m1,health info,v1,117e862d-57dd-4be6-a802-cdc075a725b2,,,,English,,[],,,, -,2,602,health-info,,,,,,wa2,,,,,,,,,,m2,,v2,,,,,,,[],,,, -,3,602,health-info,,,,,,wa3,,,,,,,,,,m3,,v3,,,,,,,[],,,, -,4,602,health-info,,,,,,wa4,,,,,,,,,,m4,,,,,,,,,[],,,, -,5,602,health-info,,,,,,wa5,,,,,,,,,,,,,,,,,,,[],,,, +structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages,footer +Menu 1,0,600,main-menu,,Main Menu,,,,,,,,,,,,,,,,,35a7f12c-7373-42a6-9ca6-a1caedea5822,,,,English,,,,,,, +Sub 1.1,1,601,ha-menu,Main Menu,HealthAlert menu,,,HealthAlert menu,*Welcome to HealthAlert* WA,,UTILITY,,,,,,,HealthAlert menu,Welcome to HealthAlert M,HealthAlert menu,Welcome to HealthAlert V,5ab08854-228b-4f83-ae54-ec2dc6ebaf69,,,,English,,[],,,,, +Sub 1.1.1,1,602,health-info,HealthAlert menu,health info,,,health info,wa1,,UTILITY,,,,,,,health info,m1,health info,v1,117e862d-57dd-4be6-a802-cdc075a725b2,,,,English,,[],,,,, +,2,602,health-info,,,,,,wa2,,,,,,,,,,m2,,v2,,,,,,,[],,,,, +,3,602,health-info,,,,,,wa3,,,,,,,,,,m3,,v3,,,,,,,[],,,,, +,4,602,health-info,,,,,,wa4,,,,,,,,,,m4,,,,,,,,,[],,,,, +,5,602,health-info,,,,,,wa5,,,,,,,,,,,,,,,,,,,[],,,,, diff --git a/home/tests/no-translation-key-default.csv b/home/tests/no-translation-key-default.csv index 3b25ad2d..7e34da4e 100644 --- a/home/tests/no-translation-key-default.csv +++ b/home/tests/no-translation-key-default.csv @@ -1,3 +1,3 @@ -structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages -Menu 1,0,659,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,,,,,English,,,,,, -Sub 1.1,1,660,locale-import,MA_import export,Locale import,,,import per locale,this is the english message..edit,,UTILITY,,,,,,,,,,,,,,,,English,,[],,,, +structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages,footer +Menu 1,0,659,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,,,,,English,,,,,,, +Sub 1.1,1,660,locale-import,MA_import export,Locale import,,,import per locale,this is the english message..edit,,UTILITY,,,,,,,,,,,,,,,,English,,[],,,,, diff --git a/home/tests/translations-en.csv b/home/tests/translations-en.csv index aec75abc..4d38cbba 100644 --- a/home/tests/translations-en.csv +++ b/home/tests/translations-en.csv @@ -1,3 +1,3 @@ -structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages -Menu 1,0,659,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,English,,,,,, -Sub 1.1,1,660,locale-import,MA_import export,Locale import,,,import per locale,this is the english message..edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,English,,[],,,, +structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages,footer +Menu 1,0,659,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,English,,,,,,, +Sub 1.1,1,660,locale-import,MA_import export,Locale import,,,import per locale,this is the english message..edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,English,,[],,,,, diff --git a/home/tests/translations-pt.csv b/home/tests/translations-pt.csv index 2498a7c1..5268f25a 100644 --- a/home/tests/translations-pt.csv +++ b/home/tests/translations-pt.csv @@ -1,3 +1,3 @@ -structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages -Menu 1,0,1297,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,Portuguese,,,,,, -Sub 1.1,1,1298,locale-import,MA_import export,Locale import,,,import per locale,this is the Portuguese message....edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,Portuguese,,[],,,, +structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages,footer +Menu 1,0,1297,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,Portuguese,,,,,,, +Sub 1.1,1,1298,locale-import,MA_import export,Locale import,,,import per locale,this is the Portuguese message....edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,Portuguese,,[],,,,, diff --git a/home/tests/translations-sep-en.csv b/home/tests/translations-sep-en.csv index aec75abc..4d38cbba 100644 --- a/home/tests/translations-sep-en.csv +++ b/home/tests/translations-sep-en.csv @@ -1,3 +1,3 @@ -structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages -Menu 1,0,659,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,English,,,,,, -Sub 1.1,1,660,locale-import,MA_import export,Locale import,,,import per locale,this is the english message..edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,English,,[],,,, +structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages,footer +Menu 1,0,659,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,English,,,,,,, +Sub 1.1,1,660,locale-import,MA_import export,Locale import,,,import per locale,this is the english message..edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,English,,[],,,,, diff --git a/home/tests/translations-sep-pt.csv b/home/tests/translations-sep-pt.csv index b6cdb175..d3d88a64 100644 --- a/home/tests/translations-sep-pt.csv +++ b/home/tests/translations-sep-pt.csv @@ -1,3 +1,3 @@ -structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages -Menu 1,0,1297,ma_import-export-pt,,MA_import export (pt),,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,Portuguese,,,,,, -Sub 1.1,1,1298,locale-import-pt,MA_import export (pt),Locale import,,,import per locale,this is the Portuguese message....edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,Portuguese,,[],,,, +structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages,footer +Menu 1,0,1297,ma_import-export-pt,,MA_import export (pt),,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,Portuguese,,,,,,, +Sub 1.1,1,1298,locale-import-pt,MA_import export (pt),Locale import,,,import per locale,this is the Portuguese message....edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,Portuguese,,[],,,,, diff --git a/home/tests/translations-sep.csv b/home/tests/translations-sep.csv index ea6b0f4a..941cf29c 100644 --- a/home/tests/translations-sep.csv +++ b/home/tests/translations-sep.csv @@ -1,5 +1,5 @@ -structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages -Menu 1,0,659,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,English,,,,,, -Sub 1.1,1,660,locale-import,MA_import export,Locale import,,,import per locale,this is the english message..edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,English,,[],,,, -Menu 1,0,1297,ma_import-export-pt,,MA_import export (pt),,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,Portuguese,,,,,, -Sub 1.1,1,1298,locale-import-pt,MA_import export (pt),Locale import,,,import per locale,this is the Portuguese message....edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,Portuguese,,[],,,, +structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages,footer +Menu 1,0,659,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,English,,,,,,, +Sub 1.1,1,660,locale-import,MA_import export,Locale import,,,import per locale,this is the english message..edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,English,,[],,,,, +Menu 1,0,1297,ma_import-export-pt,,MA_import export (pt),,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,Portuguese,,,,,,, +Sub 1.1,1,1298,locale-import-pt,MA_import export (pt),Locale import,,,import per locale,this is the Portuguese message....edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,Portuguese,,[],,,,, diff --git a/home/tests/translations.csv b/home/tests/translations.csv index 926a92d2..44c5cc47 100644 --- a/home/tests/translations.csv +++ b/home/tests/translations.csv @@ -1,5 +1,5 @@ -structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages -Menu 1,0,659,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,English,,,,,, -Sub 1.1,1,660,locale-import,MA_import export,Locale import,,,import per locale,this is the english message..edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,English,,[],,,, -Menu 1,0,1297,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,Portuguese,,,,,, -Sub 1.1,1,1298,locale-import,MA_import export,Locale import,,,import per locale,this is the Portuguese message....edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,Portuguese,,[],,,, +structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,example_values,variation_title,variation_body,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages,footer +Menu 1,0,659,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,English,,,,,,, +Sub 1.1,1,660,locale-import,MA_import export,Locale import,,,import per locale,this is the english message..edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,English,,[],,,,, +Menu 1,0,1297,ma_import-export,,MA_import export,,,,,,,,,,,,,,,,,,38a22433-e474-4f5a-b06b-7367d1a7f664,,,,Portuguese,,,,,,, +Sub 1.1,1,1298,locale-import,MA_import export,Locale import,,,import per locale,this is the Portuguese message....edit,,UTILITY,,,,,,,,,,,,9aab62ab-caf7-4606-b9bf-ac3148309319,,,,Portuguese,,[],,,,, From 91ed2fb4bbe41b28d2ba686ff14dce1f97dcf7e7 Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Thu, 1 Feb 2024 15:51:32 +0200 Subject: [PATCH 03/20] add footer to import --- home/import_content_pages.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/home/import_content_pages.py b/home/import_content_pages.py index 07ae6c21..ebfe5660 100644 --- a/home/import_content_pages.py +++ b/home/import_content_pages.py @@ -326,6 +326,7 @@ def add_message_to_shadow_content_page_from_row( next_prompt=row.next_prompt, example_values=row.example_values, buttons=buttons, + footer=row.footer, ) ) if row.is_sms_message: @@ -528,6 +529,7 @@ class ShadowWhatsappBlock: buttons: list[dict[str, Any]] = field(default_factory=list) example_values: list[str] = field(default_factory=list) variation_messages: list["ShadowVariationBlock"] = field(default_factory=list) + footer: str = "" @property def wagtail_format( @@ -539,6 +541,7 @@ def wagtail_format( "example_values": self.example_values, "buttons": self.buttons, "variation_messages": [m.wagtail_format for m in self.variation_messages], + "footer": self.footer, } @@ -627,6 +630,7 @@ class ContentRow: doc_link: str = "" media_link: str = "" related_pages: list[str] = field(default_factory=list) + footer: str = "" @classmethod def from_flat(cls, row: dict[str, str]) -> "ContentRow": @@ -646,6 +650,7 @@ def from_flat(cls, row: dict[str, str]) -> "ContentRow": related_pages=deserialise_list(row.pop("related_pages", "")), example_values=deserialise_list(row.pop("example_values", "")), buttons=json.loads(row.pop("buttons", "")) if row.get("buttons") else [], + footer=str(row.pop("footer")) if row.get("footer") else None, **row, ) From d42497730c68d6f20369c542159270ec28a0b5d8 Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Thu, 1 Feb 2024 16:02:38 +0200 Subject: [PATCH 04/20] add footer test --- home/tests/test_content_import_export.py | 34 ++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/home/tests/test_content_import_export.py b/home/tests/test_content_import_export.py index 0f83a473..eab12a66 100644 --- a/home/tests/test_content_import_export.py +++ b/home/tests/test_content_import_export.py @@ -1657,6 +1657,40 @@ def test_translations_en(self, new_impexp: ImportExport) -> None: imported = new_impexp.get_page_json() assert imported == orig_en + def test_footer(self, new_impexp: ImportExport) -> None: + """ + ContentPages with footer in whatsapp messages are preserved + across export/import. + """ + home_page = HomePage.objects.first() + main_menu = PageBuilder.build_cpi(home_page, "main-menu", "Main Menu") + + ha_menu = PageBuilder.build_cp( + parent=main_menu, + slug="ha-menu", + title="HealthAlert menu", + bodies=[WABody("HealthAlert menu", [WABlk("*Welcome to HealthAlert* WA")])], + ) + + footer = "Test footer" + _health_info = PageBuilder.build_cp( + parent=ha_menu, + slug="health-info", + title="health info", + bodies=[ + WABody( + "health info", + [WABlk("*Health information* WA", footer=footer)], + ) + ], + whatsapp_template_name="template-health-info", + ) + + orig = new_impexp.get_page_json() + new_impexp.export_reimport() + imported = new_impexp.get_page_json() + assert imported == orig + def test_example_values(self, new_impexp: ImportExport) -> None: """ ContentPages with example values in whatsapp messages are preserved From 1f47ea300810342cc8a2e58de892ce7d52aaa35f Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Thu, 1 Feb 2024 16:05:08 +0200 Subject: [PATCH 05/20] fix linting --- home/migrations/0048_alter_contentpage_whatsapp_body.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/home/migrations/0048_alter_contentpage_whatsapp_body.py b/home/migrations/0048_alter_contentpage_whatsapp_body.py index 7b61943e..003b1f0a 100644 --- a/home/migrations/0048_alter_contentpage_whatsapp_body.py +++ b/home/migrations/0048_alter_contentpage_whatsapp_body.py @@ -1,12 +1,13 @@ # Generated by Django 4.1.10 on 2024-02-01 13:02 import django.core.validators -from django.db import migrations -import home.models import wagtail.blocks import wagtail.documents.blocks import wagtail.fields import wagtail.images.blocks +from django.db import migrations + +import home.models class Migration(migrations.Migration): From 3c101e4194283920f98507355fa6591e21f59709 Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Thu, 1 Feb 2024 16:09:06 +0200 Subject: [PATCH 06/20] fix linting --- contentrepo/settings/base.py | 2 +- home/import_content_pages.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contentrepo/settings/base.py b/contentrepo/settings/base.py index 30f10ded..2313f5cd 100644 --- a/contentrepo/settings/base.py +++ b/contentrepo/settings/base.py @@ -90,7 +90,7 @@ "default": dj_database_url.config( default=os.environ.get( "CONTENTREPO_DATABASE", - "postgres://postgres:myPassword@localhost/contentrepo", + "postgres://postgres@localhost/contentrepo", ), engine="django.db.backends.postgresql", ) diff --git a/home/import_content_pages.py b/home/import_content_pages.py index ebfe5660..35704728 100644 --- a/home/import_content_pages.py +++ b/home/import_content_pages.py @@ -650,7 +650,7 @@ def from_flat(cls, row: dict[str, str]) -> "ContentRow": related_pages=deserialise_list(row.pop("related_pages", "")), example_values=deserialise_list(row.pop("example_values", "")), buttons=json.loads(row.pop("buttons", "")) if row.get("buttons") else [], - footer=str(row.pop("footer")) if row.get("footer") else None, + footer=row.pop("footer") if row.get("footer") else None, **row, ) From 56bd54cd740d94e7c3021b7110f8958027edbf2d Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Thu, 1 Feb 2024 16:17:04 +0200 Subject: [PATCH 07/20] fix linting --- home/export_content_pages.py | 14 +++-------- home/import_content_pages.py | 21 +++++----------- .../0032_alter_pageview_timestamp.py | 6 ++--- home/models.py | 5 ++-- home/tests/helpers.py | 3 ++- home/tests/page_builder.py | 14 +++-------- home/tests/test_api.py | 24 ++++--------------- home/tests/test_content_import_export.py | 19 +++------------ home/tests/test_models.py | 11 ++------- home/tests/test_page_builder.py | 14 ++--------- 10 files changed, 31 insertions(+), 100 deletions(-) diff --git a/home/export_content_pages.py b/home/export_content_pages.py index 21cc93dc..f0450328 100644 --- a/home/export_content_pages.py +++ b/home/export_content_pages.py @@ -14,17 +14,9 @@ from wagtail.models import Locale, Page # type: ignore from wagtail.query import PageQuerySet # type: ignore -from home.models import ( - ContentPage, - ContentPageIndex, - HomePage, - MessengerBlock, - SMSBlock, - USSDBlock, - VariationBlock, - ViberBlock, - WhatsappBlock, -) +from home.models import (ContentPage, ContentPageIndex, HomePage, + MessengerBlock, SMSBlock, USSDBlock, VariationBlock, + ViberBlock, WhatsappBlock) HP_CTYPE = HomePage._meta.verbose_name CP_CTYPE = ContentPage._meta.verbose_name diff --git a/home/import_content_pages.py b/home/import_content_pages.py index 35704728..377e1c58 100644 --- a/home/import_content_pages.py +++ b/home/import_content_pages.py @@ -19,18 +19,9 @@ from wagtail.models.sites import Site # type: ignore from wagtail.rich_text import RichText # type: ignore -from home.models import ( - ContentPage, - ContentPageIndex, - ContentQuickReply, - ContentTrigger, - HomePage, - MessengerBlock, - SMSBlock, - USSDBlock, - ViberBlock, - WhatsappBlock, -) +from home.models import (ContentPage, ContentPageIndex, ContentQuickReply, + ContentTrigger, HomePage, MessengerBlock, SMSBlock, + USSDBlock, ViberBlock, WhatsappBlock) PageId = tuple[str, Locale] @@ -64,9 +55,9 @@ def __init__( self.locale = locale self.locale_map: dict[str, Locale] = {} self.shadow_pages: dict[PageId, ShadowContentPage] = {} - self.go_to_page_buttons: dict[PageId, dict[int, list[dict[str, Any]]]] = ( - defaultdict(lambda: defaultdict(list)) - ) + self.go_to_page_buttons: dict[ + PageId, dict[int, list[dict[str, Any]]] + ] = defaultdict(lambda: defaultdict(list)) def locale_from_display_name(self, langname: str) -> Locale: if langname not in self.locale_map: diff --git a/home/migrations/0032_alter_pageview_timestamp.py b/home/migrations/0032_alter_pageview_timestamp.py index bf4771c0..bc26afcb 100644 --- a/home/migrations/0032_alter_pageview_timestamp.py +++ b/home/migrations/0032_alter_pageview_timestamp.py @@ -1,9 +1,7 @@ # Generated by Django 4.1.9 on 2023-06-21 09:23 -from django.contrib.postgres.operations import ( - AddIndexConcurrently, - RemoveIndexConcurrently, -) +from django.contrib.postgres.operations import (AddIndexConcurrently, + RemoveIndexConcurrently) from django.db import migrations, models diff --git a/home/models.py b/home/models.py index b9ffbf49..9184298e 100644 --- a/home/models.py +++ b/home/models.py @@ -1,3 +1,4 @@ +import logging import re from django.conf import settings @@ -14,7 +15,8 @@ from taggit.models import ItemBase, TagBase, TaggedItemBase from wagtail import blocks from wagtail.api import APIField -from wagtail.blocks import StreamBlockValidationError, StructBlockValidationError +from wagtail.blocks import (StreamBlockValidationError, + StructBlockValidationError) from wagtail.contrib.settings.models import BaseSiteSetting, register_setting from wagtail.documents.blocks import DocumentChooserBlock from wagtail.fields import StreamField @@ -40,7 +42,6 @@ ObjectList, TabbedInterface, ) -import logging logger = logging.getLogger(__name__) diff --git a/home/tests/helpers.py b/home/tests/helpers.py index 7f61f689..bd358c9e 100644 --- a/home/tests/helpers.py +++ b/home/tests/helpers.py @@ -2,7 +2,8 @@ from wagtail.models.sites import Site # type: ignore -from home.constants import AGE_CHOICES, GENDER_CHOICES, RELATIONSHIP_STATUS_CHOICES +from home.constants import (AGE_CHOICES, GENDER_CHOICES, + RELATIONSHIP_STATUS_CHOICES) from home.models import SiteSettings PFOption = tuple[str, list[str]] diff --git a/home/tests/page_builder.py b/home/tests/page_builder.py index f921fbe3..0c7c7600 100644 --- a/home/tests/page_builder.py +++ b/home/tests/page_builder.py @@ -6,17 +6,9 @@ from wagtail.blocks import RichTextBlock, StructBlock # type: ignore from wagtail.models import Page # type: ignore -from home.models import ( - ContentPage, - ContentPageIndex, - ContentQuickReply, - ContentTrigger, - MessengerBlock, - SMSBlock, - USSDBlock, - ViberBlock, - WhatsappBlock, -) +from home.models import (ContentPage, ContentPageIndex, ContentQuickReply, + ContentTrigger, MessengerBlock, SMSBlock, USSDBlock, + ViberBlock, WhatsappBlock) TPage = TypeVar("TPage", bound=Page) diff --git a/home/tests/test_api.py b/home/tests/test_api.py index f09b7369..4d9ad882 100644 --- a/home/tests/test_api.py +++ b/home/tests/test_api.py @@ -6,25 +6,11 @@ from wagtail import blocks from home.content_import_export import import_content -from home.models import ( - ContentPage, - HomePage, - OrderedContentSet, - PageView, - VariationBlock, -) - -from .page_builder import ( - MBlk, - MBody, - PageBuilder, - SBlk, - SBody, - UBlk, - UBody, - WABlk, - WABody, -) +from home.models import (ContentPage, HomePage, OrderedContentSet, PageView, + VariationBlock) + +from .page_builder import (MBlk, MBody, PageBuilder, SBlk, SBody, UBlk, UBody, + WABlk, WABody) from .utils import create_page diff --git a/home/tests/test_content_import_export.py b/home/tests/test_content_import_export.py index eab12a66..54b43e44 100644 --- a/home/tests/test_content_import_export.py +++ b/home/tests/test_content_import_export.py @@ -22,22 +22,9 @@ from home.models import ContentPage, ContentPageIndex, HomePage from .helpers import set_profile_field_options -from .page_builder import ( - MBlk, - MBody, - NextBtn, - PageBtn, - PageBuilder, - SBlk, - SBody, - UBlk, - UBody, - VarMsg, - VBlk, - VBody, - WABlk, - WABody, -) +from .page_builder import (MBlk, MBody, NextBtn, PageBtn, PageBuilder, SBlk, + SBody, UBlk, UBody, VarMsg, VBlk, VBody, WABlk, + WABody) ExpDict = dict[str, Any] ExpPair = tuple[ExpDict, ExpDict] diff --git a/home/tests/test_models.py b/home/tests/test_models.py index f2c5fbc9..f454245a 100644 --- a/home/tests/test_models.py +++ b/home/tests/test_models.py @@ -6,15 +6,8 @@ from wagtail.blocks import StructBlockValidationError from wagtail.images import get_image_model -from home.models import ( - GoToPageButton, - HomePage, - NextMessageButton, - PageView, - SMSBlock, - USSDBlock, - WhatsappBlock, -) +from home.models import (GoToPageButton, HomePage, NextMessageButton, PageView, + SMSBlock, USSDBlock, WhatsappBlock) from .page_builder import PageBuilder, WABlk, WABody from .utils import create_page, create_page_rating diff --git a/home/tests/test_page_builder.py b/home/tests/test_page_builder.py index 6416d30b..9e5bee13 100644 --- a/home/tests/test_page_builder.py +++ b/home/tests/test_page_builder.py @@ -11,18 +11,8 @@ from home.models import ContentPage, ContentPageIndex, HomePage from .helpers import set_profile_field_options -from .page_builder import ( - MBlk, - MBody, - NextBtn, - PageBtn, - PageBuilder, - VarMsg, - VBlk, - VBody, - WABlk, - WABody, -) +from .page_builder import (MBlk, MBody, NextBtn, PageBtn, PageBuilder, VarMsg, + VBlk, VBody, WABlk, WABody) def unwagtail(val): # type: ignore[no-untyped-def] # No type info From 432dfcb3337ebe63d1114febf851ab53bbac639e Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Thu, 1 Feb 2024 16:21:55 +0200 Subject: [PATCH 08/20] fix linting --- home/export_content_pages.py | 14 +++++++++++--- home/import_content_pages.py | 15 ++++++++++++--- home/models.py | 3 +-- home/tests/helpers.py | 3 +-- home/tests/page_builder.py | 14 +++++++++++--- home/tests/test_api.py | 24 +++++++++++++++++++----- home/tests/test_content_import_export.py | 19 ++++++++++++++++--- home/tests/test_models.py | 11 +++++++++-- home/tests/test_page_builder.py | 14 ++++++++++++-- 9 files changed, 92 insertions(+), 25 deletions(-) diff --git a/home/export_content_pages.py b/home/export_content_pages.py index f0450328..21cc93dc 100644 --- a/home/export_content_pages.py +++ b/home/export_content_pages.py @@ -14,9 +14,17 @@ from wagtail.models import Locale, Page # type: ignore from wagtail.query import PageQuerySet # type: ignore -from home.models import (ContentPage, ContentPageIndex, HomePage, - MessengerBlock, SMSBlock, USSDBlock, VariationBlock, - ViberBlock, WhatsappBlock) +from home.models import ( + ContentPage, + ContentPageIndex, + HomePage, + MessengerBlock, + SMSBlock, + USSDBlock, + VariationBlock, + ViberBlock, + WhatsappBlock, +) HP_CTYPE = HomePage._meta.verbose_name CP_CTYPE = ContentPage._meta.verbose_name diff --git a/home/import_content_pages.py b/home/import_content_pages.py index 377e1c58..060bd557 100644 --- a/home/import_content_pages.py +++ b/home/import_content_pages.py @@ -19,9 +19,18 @@ from wagtail.models.sites import Site # type: ignore from wagtail.rich_text import RichText # type: ignore -from home.models import (ContentPage, ContentPageIndex, ContentQuickReply, - ContentTrigger, HomePage, MessengerBlock, SMSBlock, - USSDBlock, ViberBlock, WhatsappBlock) +from home.models import ( + ContentPage, + ContentPageIndex, + ContentQuickReply, + ContentTrigger, + HomePage, + MessengerBlock, + SMSBlock, + USSDBlock, + ViberBlock, + WhatsappBlock, +) PageId = tuple[str, Locale] diff --git a/home/models.py b/home/models.py index 9184298e..6723fd94 100644 --- a/home/models.py +++ b/home/models.py @@ -15,8 +15,7 @@ from taggit.models import ItemBase, TagBase, TaggedItemBase from wagtail import blocks from wagtail.api import APIField -from wagtail.blocks import (StreamBlockValidationError, - StructBlockValidationError) +from wagtail.blocks import StreamBlockValidationError, StructBlockValidationError from wagtail.contrib.settings.models import BaseSiteSetting, register_setting from wagtail.documents.blocks import DocumentChooserBlock from wagtail.fields import StreamField diff --git a/home/tests/helpers.py b/home/tests/helpers.py index bd358c9e..7f61f689 100644 --- a/home/tests/helpers.py +++ b/home/tests/helpers.py @@ -2,8 +2,7 @@ from wagtail.models.sites import Site # type: ignore -from home.constants import (AGE_CHOICES, GENDER_CHOICES, - RELATIONSHIP_STATUS_CHOICES) +from home.constants import AGE_CHOICES, GENDER_CHOICES, RELATIONSHIP_STATUS_CHOICES from home.models import SiteSettings PFOption = tuple[str, list[str]] diff --git a/home/tests/page_builder.py b/home/tests/page_builder.py index 0c7c7600..f921fbe3 100644 --- a/home/tests/page_builder.py +++ b/home/tests/page_builder.py @@ -6,9 +6,17 @@ from wagtail.blocks import RichTextBlock, StructBlock # type: ignore from wagtail.models import Page # type: ignore -from home.models import (ContentPage, ContentPageIndex, ContentQuickReply, - ContentTrigger, MessengerBlock, SMSBlock, USSDBlock, - ViberBlock, WhatsappBlock) +from home.models import ( + ContentPage, + ContentPageIndex, + ContentQuickReply, + ContentTrigger, + MessengerBlock, + SMSBlock, + USSDBlock, + ViberBlock, + WhatsappBlock, +) TPage = TypeVar("TPage", bound=Page) diff --git a/home/tests/test_api.py b/home/tests/test_api.py index 4d9ad882..f09b7369 100644 --- a/home/tests/test_api.py +++ b/home/tests/test_api.py @@ -6,11 +6,25 @@ from wagtail import blocks from home.content_import_export import import_content -from home.models import (ContentPage, HomePage, OrderedContentSet, PageView, - VariationBlock) - -from .page_builder import (MBlk, MBody, PageBuilder, SBlk, SBody, UBlk, UBody, - WABlk, WABody) +from home.models import ( + ContentPage, + HomePage, + OrderedContentSet, + PageView, + VariationBlock, +) + +from .page_builder import ( + MBlk, + MBody, + PageBuilder, + SBlk, + SBody, + UBlk, + UBody, + WABlk, + WABody, +) from .utils import create_page diff --git a/home/tests/test_content_import_export.py b/home/tests/test_content_import_export.py index 54b43e44..eab12a66 100644 --- a/home/tests/test_content_import_export.py +++ b/home/tests/test_content_import_export.py @@ -22,9 +22,22 @@ from home.models import ContentPage, ContentPageIndex, HomePage from .helpers import set_profile_field_options -from .page_builder import (MBlk, MBody, NextBtn, PageBtn, PageBuilder, SBlk, - SBody, UBlk, UBody, VarMsg, VBlk, VBody, WABlk, - WABody) +from .page_builder import ( + MBlk, + MBody, + NextBtn, + PageBtn, + PageBuilder, + SBlk, + SBody, + UBlk, + UBody, + VarMsg, + VBlk, + VBody, + WABlk, + WABody, +) ExpDict = dict[str, Any] ExpPair = tuple[ExpDict, ExpDict] diff --git a/home/tests/test_models.py b/home/tests/test_models.py index f454245a..f2c5fbc9 100644 --- a/home/tests/test_models.py +++ b/home/tests/test_models.py @@ -6,8 +6,15 @@ from wagtail.blocks import StructBlockValidationError from wagtail.images import get_image_model -from home.models import (GoToPageButton, HomePage, NextMessageButton, PageView, - SMSBlock, USSDBlock, WhatsappBlock) +from home.models import ( + GoToPageButton, + HomePage, + NextMessageButton, + PageView, + SMSBlock, + USSDBlock, + WhatsappBlock, +) from .page_builder import PageBuilder, WABlk, WABody from .utils import create_page, create_page_rating diff --git a/home/tests/test_page_builder.py b/home/tests/test_page_builder.py index 9e5bee13..6416d30b 100644 --- a/home/tests/test_page_builder.py +++ b/home/tests/test_page_builder.py @@ -11,8 +11,18 @@ from home.models import ContentPage, ContentPageIndex, HomePage from .helpers import set_profile_field_options -from .page_builder import (MBlk, MBody, NextBtn, PageBtn, PageBuilder, VarMsg, - VBlk, VBody, WABlk, WABody) +from .page_builder import ( + MBlk, + MBody, + NextBtn, + PageBtn, + PageBuilder, + VarMsg, + VBlk, + VBody, + WABlk, + WABody, +) def unwagtail(val): # type: ignore[no-untyped-def] # No type info From 2518768486b0eb8b4c6b2ff22f998a4ed14d50d6 Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Thu, 1 Feb 2024 16:29:56 +0200 Subject: [PATCH 09/20] fix linting --- home/export_content_pages.py | 14 +++----------- home/import_content_pages.py | 15 +++------------ home/models.py | 3 ++- home/tests/helpers.py | 3 ++- home/tests/page_builder.py | 14 +++----------- home/tests/test_api.py | 24 +++++------------------- home/tests/test_content_import_export.py | 19 +++---------------- home/tests/test_models.py | 11 ++--------- home/tests/test_page_builder.py | 14 ++------------ 9 files changed, 25 insertions(+), 92 deletions(-) diff --git a/home/export_content_pages.py b/home/export_content_pages.py index 21cc93dc..f0450328 100644 --- a/home/export_content_pages.py +++ b/home/export_content_pages.py @@ -14,17 +14,9 @@ from wagtail.models import Locale, Page # type: ignore from wagtail.query import PageQuerySet # type: ignore -from home.models import ( - ContentPage, - ContentPageIndex, - HomePage, - MessengerBlock, - SMSBlock, - USSDBlock, - VariationBlock, - ViberBlock, - WhatsappBlock, -) +from home.models import (ContentPage, ContentPageIndex, HomePage, + MessengerBlock, SMSBlock, USSDBlock, VariationBlock, + ViberBlock, WhatsappBlock) HP_CTYPE = HomePage._meta.verbose_name CP_CTYPE = ContentPage._meta.verbose_name diff --git a/home/import_content_pages.py b/home/import_content_pages.py index 060bd557..377e1c58 100644 --- a/home/import_content_pages.py +++ b/home/import_content_pages.py @@ -19,18 +19,9 @@ from wagtail.models.sites import Site # type: ignore from wagtail.rich_text import RichText # type: ignore -from home.models import ( - ContentPage, - ContentPageIndex, - ContentQuickReply, - ContentTrigger, - HomePage, - MessengerBlock, - SMSBlock, - USSDBlock, - ViberBlock, - WhatsappBlock, -) +from home.models import (ContentPage, ContentPageIndex, ContentQuickReply, + ContentTrigger, HomePage, MessengerBlock, SMSBlock, + USSDBlock, ViberBlock, WhatsappBlock) PageId = tuple[str, Locale] diff --git a/home/models.py b/home/models.py index 6723fd94..9184298e 100644 --- a/home/models.py +++ b/home/models.py @@ -15,7 +15,8 @@ from taggit.models import ItemBase, TagBase, TaggedItemBase from wagtail import blocks from wagtail.api import APIField -from wagtail.blocks import StreamBlockValidationError, StructBlockValidationError +from wagtail.blocks import (StreamBlockValidationError, + StructBlockValidationError) from wagtail.contrib.settings.models import BaseSiteSetting, register_setting from wagtail.documents.blocks import DocumentChooserBlock from wagtail.fields import StreamField diff --git a/home/tests/helpers.py b/home/tests/helpers.py index 7f61f689..bd358c9e 100644 --- a/home/tests/helpers.py +++ b/home/tests/helpers.py @@ -2,7 +2,8 @@ from wagtail.models.sites import Site # type: ignore -from home.constants import AGE_CHOICES, GENDER_CHOICES, RELATIONSHIP_STATUS_CHOICES +from home.constants import (AGE_CHOICES, GENDER_CHOICES, + RELATIONSHIP_STATUS_CHOICES) from home.models import SiteSettings PFOption = tuple[str, list[str]] diff --git a/home/tests/page_builder.py b/home/tests/page_builder.py index f921fbe3..0c7c7600 100644 --- a/home/tests/page_builder.py +++ b/home/tests/page_builder.py @@ -6,17 +6,9 @@ from wagtail.blocks import RichTextBlock, StructBlock # type: ignore from wagtail.models import Page # type: ignore -from home.models import ( - ContentPage, - ContentPageIndex, - ContentQuickReply, - ContentTrigger, - MessengerBlock, - SMSBlock, - USSDBlock, - ViberBlock, - WhatsappBlock, -) +from home.models import (ContentPage, ContentPageIndex, ContentQuickReply, + ContentTrigger, MessengerBlock, SMSBlock, USSDBlock, + ViberBlock, WhatsappBlock) TPage = TypeVar("TPage", bound=Page) diff --git a/home/tests/test_api.py b/home/tests/test_api.py index f09b7369..4d9ad882 100644 --- a/home/tests/test_api.py +++ b/home/tests/test_api.py @@ -6,25 +6,11 @@ from wagtail import blocks from home.content_import_export import import_content -from home.models import ( - ContentPage, - HomePage, - OrderedContentSet, - PageView, - VariationBlock, -) - -from .page_builder import ( - MBlk, - MBody, - PageBuilder, - SBlk, - SBody, - UBlk, - UBody, - WABlk, - WABody, -) +from home.models import (ContentPage, HomePage, OrderedContentSet, PageView, + VariationBlock) + +from .page_builder import (MBlk, MBody, PageBuilder, SBlk, SBody, UBlk, UBody, + WABlk, WABody) from .utils import create_page diff --git a/home/tests/test_content_import_export.py b/home/tests/test_content_import_export.py index eab12a66..54b43e44 100644 --- a/home/tests/test_content_import_export.py +++ b/home/tests/test_content_import_export.py @@ -22,22 +22,9 @@ from home.models import ContentPage, ContentPageIndex, HomePage from .helpers import set_profile_field_options -from .page_builder import ( - MBlk, - MBody, - NextBtn, - PageBtn, - PageBuilder, - SBlk, - SBody, - UBlk, - UBody, - VarMsg, - VBlk, - VBody, - WABlk, - WABody, -) +from .page_builder import (MBlk, MBody, NextBtn, PageBtn, PageBuilder, SBlk, + SBody, UBlk, UBody, VarMsg, VBlk, VBody, WABlk, + WABody) ExpDict = dict[str, Any] ExpPair = tuple[ExpDict, ExpDict] diff --git a/home/tests/test_models.py b/home/tests/test_models.py index f2c5fbc9..f454245a 100644 --- a/home/tests/test_models.py +++ b/home/tests/test_models.py @@ -6,15 +6,8 @@ from wagtail.blocks import StructBlockValidationError from wagtail.images import get_image_model -from home.models import ( - GoToPageButton, - HomePage, - NextMessageButton, - PageView, - SMSBlock, - USSDBlock, - WhatsappBlock, -) +from home.models import (GoToPageButton, HomePage, NextMessageButton, PageView, + SMSBlock, USSDBlock, WhatsappBlock) from .page_builder import PageBuilder, WABlk, WABody from .utils import create_page, create_page_rating diff --git a/home/tests/test_page_builder.py b/home/tests/test_page_builder.py index 6416d30b..9e5bee13 100644 --- a/home/tests/test_page_builder.py +++ b/home/tests/test_page_builder.py @@ -11,18 +11,8 @@ from home.models import ContentPage, ContentPageIndex, HomePage from .helpers import set_profile_field_options -from .page_builder import ( - MBlk, - MBody, - NextBtn, - PageBtn, - PageBuilder, - VarMsg, - VBlk, - VBody, - WABlk, - WABody, -) +from .page_builder import (MBlk, MBody, NextBtn, PageBtn, PageBuilder, VarMsg, + VBlk, VBody, WABlk, WABody) def unwagtail(val): # type: ignore[no-untyped-def] # No type info From 3f63e5c0b2bd609e4f15b44805cc5d2ae5b8cab0 Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Thu, 1 Feb 2024 16:36:58 +0200 Subject: [PATCH 10/20] fix linting --- home/export_content_pages.py | 14 ++++++++--- home/import_content_pages.py | 15 +++++++++--- .../0032_alter_pageview_timestamp.py | 6 +++-- home/models.py | 3 +-- home/tests/helpers.py | 3 +-- home/tests/page_builder.py | 14 ++++++++--- home/tests/test_api.py | 24 +++++++++++++++---- home/tests/test_content_import_export.py | 19 ++++++++++++--- home/tests/test_models.py | 11 +++++++-- home/tests/test_page_builder.py | 14 +++++++++-- 10 files changed, 96 insertions(+), 27 deletions(-) diff --git a/home/export_content_pages.py b/home/export_content_pages.py index f0450328..21cc93dc 100644 --- a/home/export_content_pages.py +++ b/home/export_content_pages.py @@ -14,9 +14,17 @@ from wagtail.models import Locale, Page # type: ignore from wagtail.query import PageQuerySet # type: ignore -from home.models import (ContentPage, ContentPageIndex, HomePage, - MessengerBlock, SMSBlock, USSDBlock, VariationBlock, - ViberBlock, WhatsappBlock) +from home.models import ( + ContentPage, + ContentPageIndex, + HomePage, + MessengerBlock, + SMSBlock, + USSDBlock, + VariationBlock, + ViberBlock, + WhatsappBlock, +) HP_CTYPE = HomePage._meta.verbose_name CP_CTYPE = ContentPage._meta.verbose_name diff --git a/home/import_content_pages.py b/home/import_content_pages.py index 377e1c58..060bd557 100644 --- a/home/import_content_pages.py +++ b/home/import_content_pages.py @@ -19,9 +19,18 @@ from wagtail.models.sites import Site # type: ignore from wagtail.rich_text import RichText # type: ignore -from home.models import (ContentPage, ContentPageIndex, ContentQuickReply, - ContentTrigger, HomePage, MessengerBlock, SMSBlock, - USSDBlock, ViberBlock, WhatsappBlock) +from home.models import ( + ContentPage, + ContentPageIndex, + ContentQuickReply, + ContentTrigger, + HomePage, + MessengerBlock, + SMSBlock, + USSDBlock, + ViberBlock, + WhatsappBlock, +) PageId = tuple[str, Locale] diff --git a/home/migrations/0032_alter_pageview_timestamp.py b/home/migrations/0032_alter_pageview_timestamp.py index bc26afcb..bf4771c0 100644 --- a/home/migrations/0032_alter_pageview_timestamp.py +++ b/home/migrations/0032_alter_pageview_timestamp.py @@ -1,7 +1,9 @@ # Generated by Django 4.1.9 on 2023-06-21 09:23 -from django.contrib.postgres.operations import (AddIndexConcurrently, - RemoveIndexConcurrently) +from django.contrib.postgres.operations import ( + AddIndexConcurrently, + RemoveIndexConcurrently, +) from django.db import migrations, models diff --git a/home/models.py b/home/models.py index 9184298e..6723fd94 100644 --- a/home/models.py +++ b/home/models.py @@ -15,8 +15,7 @@ from taggit.models import ItemBase, TagBase, TaggedItemBase from wagtail import blocks from wagtail.api import APIField -from wagtail.blocks import (StreamBlockValidationError, - StructBlockValidationError) +from wagtail.blocks import StreamBlockValidationError, StructBlockValidationError from wagtail.contrib.settings.models import BaseSiteSetting, register_setting from wagtail.documents.blocks import DocumentChooserBlock from wagtail.fields import StreamField diff --git a/home/tests/helpers.py b/home/tests/helpers.py index bd358c9e..7f61f689 100644 --- a/home/tests/helpers.py +++ b/home/tests/helpers.py @@ -2,8 +2,7 @@ from wagtail.models.sites import Site # type: ignore -from home.constants import (AGE_CHOICES, GENDER_CHOICES, - RELATIONSHIP_STATUS_CHOICES) +from home.constants import AGE_CHOICES, GENDER_CHOICES, RELATIONSHIP_STATUS_CHOICES from home.models import SiteSettings PFOption = tuple[str, list[str]] diff --git a/home/tests/page_builder.py b/home/tests/page_builder.py index 0c7c7600..f921fbe3 100644 --- a/home/tests/page_builder.py +++ b/home/tests/page_builder.py @@ -6,9 +6,17 @@ from wagtail.blocks import RichTextBlock, StructBlock # type: ignore from wagtail.models import Page # type: ignore -from home.models import (ContentPage, ContentPageIndex, ContentQuickReply, - ContentTrigger, MessengerBlock, SMSBlock, USSDBlock, - ViberBlock, WhatsappBlock) +from home.models import ( + ContentPage, + ContentPageIndex, + ContentQuickReply, + ContentTrigger, + MessengerBlock, + SMSBlock, + USSDBlock, + ViberBlock, + WhatsappBlock, +) TPage = TypeVar("TPage", bound=Page) diff --git a/home/tests/test_api.py b/home/tests/test_api.py index 4d9ad882..f09b7369 100644 --- a/home/tests/test_api.py +++ b/home/tests/test_api.py @@ -6,11 +6,25 @@ from wagtail import blocks from home.content_import_export import import_content -from home.models import (ContentPage, HomePage, OrderedContentSet, PageView, - VariationBlock) - -from .page_builder import (MBlk, MBody, PageBuilder, SBlk, SBody, UBlk, UBody, - WABlk, WABody) +from home.models import ( + ContentPage, + HomePage, + OrderedContentSet, + PageView, + VariationBlock, +) + +from .page_builder import ( + MBlk, + MBody, + PageBuilder, + SBlk, + SBody, + UBlk, + UBody, + WABlk, + WABody, +) from .utils import create_page diff --git a/home/tests/test_content_import_export.py b/home/tests/test_content_import_export.py index 54b43e44..eab12a66 100644 --- a/home/tests/test_content_import_export.py +++ b/home/tests/test_content_import_export.py @@ -22,9 +22,22 @@ from home.models import ContentPage, ContentPageIndex, HomePage from .helpers import set_profile_field_options -from .page_builder import (MBlk, MBody, NextBtn, PageBtn, PageBuilder, SBlk, - SBody, UBlk, UBody, VarMsg, VBlk, VBody, WABlk, - WABody) +from .page_builder import ( + MBlk, + MBody, + NextBtn, + PageBtn, + PageBuilder, + SBlk, + SBody, + UBlk, + UBody, + VarMsg, + VBlk, + VBody, + WABlk, + WABody, +) ExpDict = dict[str, Any] ExpPair = tuple[ExpDict, ExpDict] diff --git a/home/tests/test_models.py b/home/tests/test_models.py index f454245a..f2c5fbc9 100644 --- a/home/tests/test_models.py +++ b/home/tests/test_models.py @@ -6,8 +6,15 @@ from wagtail.blocks import StructBlockValidationError from wagtail.images import get_image_model -from home.models import (GoToPageButton, HomePage, NextMessageButton, PageView, - SMSBlock, USSDBlock, WhatsappBlock) +from home.models import ( + GoToPageButton, + HomePage, + NextMessageButton, + PageView, + SMSBlock, + USSDBlock, + WhatsappBlock, +) from .page_builder import PageBuilder, WABlk, WABody from .utils import create_page, create_page_rating diff --git a/home/tests/test_page_builder.py b/home/tests/test_page_builder.py index 9e5bee13..6416d30b 100644 --- a/home/tests/test_page_builder.py +++ b/home/tests/test_page_builder.py @@ -11,8 +11,18 @@ from home.models import ContentPage, ContentPageIndex, HomePage from .helpers import set_profile_field_options -from .page_builder import (MBlk, MBody, NextBtn, PageBtn, PageBuilder, VarMsg, - VBlk, VBody, WABlk, WABody) +from .page_builder import ( + MBlk, + MBody, + NextBtn, + PageBtn, + PageBuilder, + VarMsg, + VBlk, + VBody, + WABlk, + WABody, +) def unwagtail(val): # type: ignore[no-untyped-def] # No type info From 5ac8b426d12cb0b96ce06f14a098e6fd35dd0215 Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Mon, 5 Feb 2024 09:08:44 +0200 Subject: [PATCH 11/20] fix linting --- home/import_content_pages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/home/import_content_pages.py b/home/import_content_pages.py index 060bd557..d74c7adb 100644 --- a/home/import_content_pages.py +++ b/home/import_content_pages.py @@ -630,7 +630,7 @@ class ContentRow: doc_link: str = "" media_link: str = "" related_pages: list[str] = field(default_factory=list) - footer: str = "" + footer: str | None = None @classmethod def from_flat(cls, row: dict[str, str]) -> "ContentRow": From a66d3f298aaf765327be0b746cbba5c74c1166b9 Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Mon, 5 Feb 2024 09:32:31 +0200 Subject: [PATCH 12/20] fix linting --- home/import_content_pages.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/home/import_content_pages.py b/home/import_content_pages.py index d74c7adb..78beafe9 100644 --- a/home/import_content_pages.py +++ b/home/import_content_pages.py @@ -64,9 +64,9 @@ def __init__( self.locale = locale self.locale_map: dict[str, Locale] = {} self.shadow_pages: dict[PageId, ShadowContentPage] = {} - self.go_to_page_buttons: dict[ - PageId, dict[int, list[dict[str, Any]]] - ] = defaultdict(lambda: defaultdict(list)) + self.go_to_page_buttons: dict[PageId, dict[int, list[dict[str, Any]]]] = ( + defaultdict(lambda: defaultdict(list)) + ) def locale_from_display_name(self, langname: str) -> Locale: if langname not in self.locale_map: From 033d87ceb4b5dbd005d3282d62d0df1c39f1d1c7 Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Mon, 5 Feb 2024 10:32:30 +0200 Subject: [PATCH 13/20] fix linting --- home/import_content_pages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/home/import_content_pages.py b/home/import_content_pages.py index 78beafe9..8eca4329 100644 --- a/home/import_content_pages.py +++ b/home/import_content_pages.py @@ -529,7 +529,7 @@ class ShadowWhatsappBlock: buttons: list[dict[str, Any]] = field(default_factory=list) example_values: list[str] = field(default_factory=list) variation_messages: list["ShadowVariationBlock"] = field(default_factory=list) - footer: str = "" + footer: str | None = None @property def wagtail_format( From eb70fb04b5de229c991f831d4817f8fcebf03238 Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Mon, 5 Feb 2024 10:43:10 +0200 Subject: [PATCH 14/20] fix linting --- home/import_content_pages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/home/import_content_pages.py b/home/import_content_pages.py index 8eca4329..78beafe9 100644 --- a/home/import_content_pages.py +++ b/home/import_content_pages.py @@ -529,7 +529,7 @@ class ShadowWhatsappBlock: buttons: list[dict[str, Any]] = field(default_factory=list) example_values: list[str] = field(default_factory=list) variation_messages: list["ShadowVariationBlock"] = field(default_factory=list) - footer: str | None = None + footer: str = "" @property def wagtail_format( From 963316a777e65fea24f9fd9e78425f4962011917 Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Mon, 5 Feb 2024 10:56:09 +0200 Subject: [PATCH 15/20] fix linting --- home/import_content_pages.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/home/import_content_pages.py b/home/import_content_pages.py index 78beafe9..7a205d54 100644 --- a/home/import_content_pages.py +++ b/home/import_content_pages.py @@ -630,7 +630,7 @@ class ContentRow: doc_link: str = "" media_link: str = "" related_pages: list[str] = field(default_factory=list) - footer: str | None = None + footer: str = "" @classmethod def from_flat(cls, row: dict[str, str]) -> "ContentRow": @@ -650,7 +650,7 @@ def from_flat(cls, row: dict[str, str]) -> "ContentRow": related_pages=deserialise_list(row.pop("related_pages", "")), example_values=deserialise_list(row.pop("example_values", "")), buttons=json.loads(row.pop("buttons", "")) if row.get("buttons") else [], - footer=row.pop("footer") if row.get("footer") else None, + footer=row.pop("footer") if row.get("footer") else "", **row, ) From d5d742f85716f2f7ecd2070763519ded663e225b Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Mon, 5 Feb 2024 11:14:46 +0200 Subject: [PATCH 16/20] fix formating --- home/tests/page_builder.py | 2 +- home/tests/test_content_import_export.py | 2 +- home/tests/test_page_builder.py | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/home/tests/page_builder.py b/home/tests/page_builder.py index f921fbe3..8237c794 100644 --- a/home/tests/page_builder.py +++ b/home/tests/page_builder.py @@ -112,7 +112,7 @@ class WABlk(ContentBlock): variation_messages: list[VarMsg] = field(default_factory=list) example_values: list[str] = field(default_factory=list) buttons: list[Btn] = field(default_factory=list) - footer: str | None = None + footer: str = "" def to_dict(self) -> dict[str, Any]: varmsgs = [vm.to_dict() for vm in self.variation_messages] diff --git a/home/tests/test_content_import_export.py b/home/tests/test_content_import_export.py index eab12a66..19f7933e 100644 --- a/home/tests/test_content_import_export.py +++ b/home/tests/test_content_import_export.py @@ -334,7 +334,7 @@ def add_body_fields(page: DbDict) -> DbDict: "next_prompt": "", "example_values": [], "variation_messages": [], - "footer": None, + "footer": "", }, ) if "sms_body" in page["fields"]: diff --git a/home/tests/test_page_builder.py b/home/tests/test_page_builder.py index 6416d30b..f936e15a 100644 --- a/home/tests/test_page_builder.py +++ b/home/tests/test_page_builder.py @@ -137,7 +137,7 @@ def test_build_simple_pages() -> None: "buttons": [], "example_values": [], "variation_messages": [], - "footer": None, + "footer": "", }, ), ] @@ -261,7 +261,7 @@ def test_build_variations() -> None: {"message": "Single male", "variation_restrictions": v_single_male}, {"message": "Comp male", "variation_restrictions": v_complicated_male}, ], - "footer": None, + "footer": "", }, { "message": "Message 2, variable placeholders as well {{0}}", @@ -273,7 +273,7 @@ def test_build_variations() -> None: "variation_messages": [ {"message": "Teen", "variation_restrictions": [("age", "15-18")]} ], - "footer": None, + "footer": "", }, { "message": "Message 3 with no variation", @@ -281,7 +281,7 @@ def test_build_variations() -> None: "buttons": [("next_message", {"title": "end"})], "example_values": [], "variation_messages": [], - "footer": None, + "footer": "", }, ] From 5e721533b75eff5687b0edbb0c1f7e3271c99748 Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Mon, 5 Feb 2024 11:31:41 +0200 Subject: [PATCH 17/20] fix merge conflict --- home/content_import_export.py | 484 ----------------------- home/models.py | 39 +- home/templates/home/content_page.html | 12 + home/tests/test_content_import_export.py | 390 +++++------------- home/tests/test_models.py | 13 +- 5 files changed, 138 insertions(+), 800 deletions(-) diff --git a/home/content_import_export.py b/home/content_import_export.py index cc82bcee..48acb1ba 100644 --- a/home/content_import_export.py +++ b/home/content_import_export.py @@ -15,27 +15,17 @@ from openpyxl.utils import get_column_letter from openpyxl.workbook import Workbook from openpyxl.worksheet.worksheet import Worksheet -from taggit.models import Tag from wagtail import blocks -from wagtail.documents.blocks import DocumentChooserBlock from wagtail.documents.models import Document -from wagtail.images.blocks import ImageChooserBlock from wagtail.images.models import Image from wagtail.models import Locale -from wagtail.models.sites import Site from wagtail.query import PageQuerySet -from wagtail.rich_text import RichText from wagtailmedia.models import Media from home.models import ( # isort:skip ContentPage, ContentPageIndex, - ContentQuickReply, - ContentTrigger, HomePage, - MediaBlock, - Page, - VariationBlock, OrderedContentSet, ) @@ -102,460 +92,6 @@ def export_csv_content(queryset: PageQuerySet, response: HttpResponse) -> None: ExportWriter(export_rows).write_csv(response) -@transaction.atomic -def old_import_content(file, filetype, progress_queue, purge=True, locale="en"): - def set_variation_blocks(body_values, message_number): - variation_blocks = [] - for variation_message in variation_messages: - if variation_message["message_number"] == str(message_number): - profile_field, profile_field_value = variation_message[ - "variation_title" - ].split(": ") - site = Site.objects.get(is_default_site=True) - for profile_block in site.sitesettings.profile_field_options: - if profile_block.block_type == profile_field: - variation_blocks.append( - { - "variation_restrictions": [ - { - "type": profile_field, - "value": profile_field_value, - } - ], - "message": variation_message["variation_body"], - } - ) - break - body_values["variation_messages"] = variation_blocks - return body_values - - def get_rich_text_body(text=None): - if text: - body = [] - lines = text.splitlines() - for line in lines: - if len(line) != 0: - body = body + [("paragraph", RichText(line))] - return body - - def get_body(messages, type_of_message, variation_messages=()): - struct_blocks = [] - for message_number, raw in enumerate(messages, 1): - im = None - doc = None - media = None - if not raw: - return struct_blocks - split_body = raw.split("/n") - for line in split_body: - if "image_link:" in line: - link = raw[raw.index(":") + 1 :] - im = Image.objects.get(url=link).id - if "doc_link:" in line: - link = raw[raw.index(":") + 1 :] - doc = Document.objects.get(url=link).id - if "media_link:" in line: - link = raw[raw.index(":") + 1 :] - doc = Media.objects.get(url=link).id - message_body = raw - if message_body: - body_blocks = [ - ("message", blocks.TextBlock()), - ] - if im: - body_blocks.append(("image", ImageChooserBlock())) - if doc: - body_blocks.append( - ("document", DocumentChooserBlock()), - ) - if media: - body_blocks.append( - ("media", MediaBlock()), - ) - if type_of_message == "Whatsapp_Message" and variation_messages: - body_blocks.append( - ("variation_messages", blocks.ListBlock(VariationBlock())) - ) - block = blocks.StructBlock(body_blocks) - body_values = { - "message": message_body, - } - if im: - body_values["image"] = im - if doc: - body_values["document"] = doc - if media: - body_values["media"] = media - - if type_of_message == "Whatsapp_Message" and variation_messages: - body_values = set_variation_blocks( - body_values=body_values, - message_number=message_number, - ) - - block_value = block.to_python(body_values) - struct_blocks.append((type_of_message, block_value)) - return struct_blocks - - def create_tags(row, page): - page.tags.clear() - if row["tags"]: - tags = row["tags"].split(", ") - for tag in tags: - created_tag, _ = Tag.objects.get_or_create(name=tag.strip()) - page.tags.add(created_tag) - - if "translation_tag" in row: - translation_tag = row["translation_tag"] - created_tag, _ = Tag.objects.get_or_create(name=translation_tag.strip()) - page.tags.add(created_tag) - - def add_quick_replies(row, page): - if row["quick_replies"]: - replies = row["quick_replies"].split(", ") - for reply in replies: - created_tag, _ = ContentQuickReply.objects.get_or_create( - name=reply.strip() - ) - page.quick_replies.add(created_tag) - - def add_triggers(row, page): - if row["triggers"]: - triggers = row["triggers"].split(", ") - for trigger in triggers: - created_tag, _ = ContentTrigger.objects.get_or_create( - name=trigger.strip() - ) - page.triggers.add(created_tag) - - def add_parent(row, page, home_page): - if row["parent"]: - parent = Page.objects.filter(title=row["parent"], locale=page.locale).last() - parent.add_child(instance=page) - else: - home_page.add_child(instance=page) - - def add_web(row, page=None): - if not row.get("web_title"): - return - - if page: # update - page.title = row["web_title"] - page.subtitle = row["web_subtitle"] - page.body = get_rich_text_body(row["web_body"]) - page.enable_web = True - page.locale = home_page.locale - return page - return ContentPage( - title=row["web_title"], - slug=row["slug"], - subtitle=row["web_subtitle"], - body=get_rich_text_body(row["web_body"]), - enable_web=True, - locale=home_page.locale, - ) - - def add_whatsapp(row, whatsapp_messages, page=None, variation_messages=()): - if not row.get("whatsapp_title"): - return page - - whatsapp_template_name = row.get("whatsapp_template_name", "") - whatsapp_template_category = row.get("whatsapp_template_category") or "UTILITY" - - if not page: - return ContentPage( - title=row["whatsapp_title"], - slug=row["slug"], - enable_whatsapp=True, - whatsapp_title=row["whatsapp_title"], - whatsapp_body=get_body( - whatsapp_messages, "Whatsapp_Message", variation_messages - ), - whatsapp_template_name=whatsapp_template_name, - whatsapp_template_category=whatsapp_template_category, - is_whatsapp_template=bool(whatsapp_template_name), - locale=home_page.locale, - ) - else: - page.enable_whatsapp = True - page.whatsapp_title = row["whatsapp_title"] - page.whatsapp_body = get_body( - whatsapp_messages, "Whatsapp_Message", variation_messages - ) - page.whatsapp_template_name = whatsapp_template_name - page.whatsapp_template_category = whatsapp_template_category - page.is_whatsapp_template = bool(whatsapp_template_name) - return page - - def add_sms(row, sms_messages, page=None): - if not row.get("sms_title"): - return page - - if not page: - return ContentPage( - title=row["sms_title"], - slug=row["slug"], - enable_sms=True, - sms_title=row["sms_title"], - sms_body=get_body(sms_messages, "SMS_Message"), - locale=home_page.locale, - ) - else: - page.enable_sms = True - page.sms_title = row["sms_title"] - page.sms_body = get_body(sms_messages, "SMS_Message") - return page - - def add_ussd(row, ussd_messages, page=None): - if not row.get("ussd_title"): - return page - - if not page: - return ContentPage( - title=row["ussd_title"], - slug=row["slug"], - enable_ussd=True, - ussd_title=row["ussd_title"], - ussd_body=get_body(ussd_messages, "USSD_Message"), - locale=home_page.locale, - ) - else: - page.enable_ussd = True - page.ussd_title = row["ussd_title"] - page.ussd_body = get_body(ussd_messages, "USSD_Message") - return page - - def add_messenger(row, messenger_messages, page=None): - if not row.get("messenger_title"): - return page - - if not page: - return ContentPage( - title=row["messenger_title"], - slug=row["slug"], - enable_messenger=True, - messenger_title=row["messenger_title"], - messenger_body=get_body(messenger_messages, "messenger_block"), - locale=home_page.locale, - ) - else: - page.enable_messenger = True - page.messenger_title = row["messenger_title"] - page.messenger_body = get_body(messenger_messages, "messenger_block") - return page - - def add_viber(row, viber_messages, page=None): - if not row.get("viber_title"): - return page - - if not page: - return ContentPage( - title=row["viber_title"], - slug=row["slug"], - enable_viberr=True, - viber_title=row["viber_title"], - viber_body=get_body(viber_messages, "viber_message"), - locale=home_page.locale, - ) - else: - page.enable_viber = True - page.viber_title = row["viber_title"] - page.viber_body = get_body(viber_messages, "viber_message") - return page - - def clean_row(row): - for field in ( - "web_title", - "web_subtitle", - "web_body", - "whatsapp_title", - "whatsapp_body", - "whataspp_template_name", - "whatsapp_template_category", - "example_values", - "variation_title", - "variation_body", - "next_prompt", - "buttons", - "sms_title", - "sms_body", - "ussd_title", - "ussd_body", - "viber_title", - "viber_body", - "messenger_title", - "messenger_body", - "parent", - ): - if field in row and row[field]: - row[field] = str(row[field]).strip() - return row - - def get_side_panel_width(ws, column_heading): - column_lookup = {} - iterator = 1 - for column in ws.iter_cols(1, ws.max_column): - column_lookup[column[1].value] = iterator - iterator += 1 - if column_heading in column_lookup: - return column_lookup[column_heading] - raise KeyError(f"{column_heading} not found in column headings {column_lookup}") - - file = file.read() - lines = [] - if filetype == "XLSX": - wb = load_workbook(filename=BytesIO(file)) - ws = wb.worksheets[0] - side_pannel = get_side_panel_width(ws, "message") - if side_pannel: - ws.delete_cols(1, side_pannel) - ws.delete_rows(1, 2) - for row in ws.iter_rows(): - row_dict = {} - for index, x in enumerate(row): - row_dict[EXPORT_FIELDNAMES[index]] = ( - x.value.replace("_x000D_", "") if x.value else None - ) - lines.append(row_dict) - else: - if isinstance(file, bytes): - file = file.decode("utf-8") - reader = csv.DictReader(io.StringIO(file)) - for dictionary in reader: - lines.append(dictionary) - - # 10% progress for loading file - progress_queue.put_nowait(10) - - if purge in ["True", "yes", True]: - ContentPage.objects.all().delete() - ContentPageIndex.objects.all().delete() - - # 10-20% progress for purging - progress_queue.put_nowait(20) - - if isinstance(locale, str): - locale = Locale.objects.get(language_code=locale) - - home_page = HomePage.objects.get(locale__pk=locale.pk) - - for index, row in enumerate(lines): - slug = row["slug"] - - if row["web_title"] in ["", None]: - continue - if ( - row["parent"] in ["", None] - and row["web_body"] in ["", None] - and row["whatsapp_body"] in ["", None] - and row["messenger_body"] in ["", None] - and row["sms_body"] in ["", None] - and row["ussd_body"] in ["", None] - ): - cpi = ContentPageIndex.objects.filter(slug=slug).first() - if cpi: - cpi.title = row["web_title"] - cpi.save_revision().publish() - else: - cpi = ContentPageIndex(title=row["web_title"], slug=slug) - home_page.add_child(instance=cpi) - cpi.save_revision().publish() - continue - row = clean_row(row) - variation_messages = [] - whatsapp_messages = [row["whatsapp_body"]] - sms_messages = [row["sms_body"]] - ussd_messages = [row["ussd_body"]] - messenger_messages = [row["messenger_body"]] - viber_messages = [row["viber_body"]] - for next_row in lines[index + 1 :]: - if next_row["web_title"] not in ["", None]: - break - if next_row["whatsapp_body"] not in ["", None]: - whatsapp_messages.append(next_row["whatsapp_body"]) - - if next_row["variation_body"] not in ["", None]: - variation_messages.append( - { - "variation_body": next_row["variation_body"], - "variation_title": next_row["variation_title"], - "message_number": next_row["message"], - } - ) - - if next_row["sms_body"] not in ["", None]: - sms_messages.append(next_row["sms_body"]) - if next_row["ussd_body"] not in ["", None]: - ussd_messages.append(next_row["ussd_body"]) - if next_row["messenger_body"] not in ["", None]: - messenger_messages.append(next_row["messenger_body"]) - if next_row["viber_body"] not in ["", None]: - viber_messages.append(next_row["viber_body"]) - - exiting_contentpage = ContentPage.objects.filter(slug=slug).first() - - contentpage = add_web(row=row, page=exiting_contentpage) - contentpage = add_whatsapp( - row=row, - whatsapp_messages=whatsapp_messages, - page=contentpage, - variation_messages=variation_messages, - ) - contentpage = add_sms(row=row, sms_messages=sms_messages, page=contentpage) - contentpage = add_ussd(row=row, ussd_messages=ussd_messages, page=contentpage) - contentpage = add_messenger( - row=row, messenger_messages=messenger_messages, page=contentpage - ) - contentpage = add_viber( - row=row, viber_messages=viber_messages, page=contentpage - ) - if contentpage: - create_tags(row, contentpage) - add_quick_replies(row, contentpage) - add_triggers(row, contentpage) - if not exiting_contentpage: - add_parent(row, contentpage, home_page) - contentpage.save_revision().publish() - try: - pages = contentpage.tags.first().home_contentpagetag_items.all() - for page in pages: - if page.content_object.pk != contentpage.pk: - contentpage.translation_key = ( - page.content_object.translation_key - ) - contentpage.save_revision().publish() - except Exception as e: - print(e) - else: - print(f"Content page not created for {row}") - - # 20-80% progress for uploading content - progress_queue.put_nowait(20 + (index * 60 / len(lines))) - - # add related pages - for row in lines: - related_pages_raw_data = [] - if row["related_pages"]: - slug = row["slug"] - page = ContentPage.objects.filter(slug=slug).first() - related_page_slugs = row["related_pages"].split(", ") - for related_page_slug in related_page_slugs: - related_page = ContentPage.objects.filter( - slug=related_page_slug - ).first() - if related_page: - related_pages_raw_data.append( - {"type": "related_page", "value": related_page.id} - ) - else: - print(f"Content page not found for slug '{related_page_slug}'") - if related_pages_raw_data: - page.related_pages = dumps(related_pages_raw_data) - page.save_revision().publish() - # 80-100% progress for uploading content - progress_queue.put_nowait(80 + (index * 20 / len(lines))) - - def style_sheet(wb: Workbook, sheet: Worksheet) -> Tuple[Workbook, Worksheet]: """Sets the style for the workbook adding any formatting that will make the sheet more aesthetically pleasing""" # Adjustment is because the size in openxlsx and google sheets are not equivalent @@ -742,26 +278,6 @@ def get_content_sheet(queryset: PageQuerySet) -> List[list]: return content_sheet -def old_export_xlsx_content(queryset: PageQuerySet, response: HttpResponse) -> None: - """Export contentpages within the queryset to an xlsx""" - workbook = Workbook() - worksheet = workbook.active - - content_sheet = get_content_sheet(queryset) - for row in content_sheet: - worksheet.append(row) - workbook, worksheet = style_sheet(workbook, worksheet) - workbook.save(response) - - -def old_export_csv_content(queryset: PageQuerySet, response: HttpResponse) -> None: - """Export contentpages within the queryset to a csv""" - content_sheet = get_content_sheet(queryset) - writer = csv.writer(response) - for row in content_sheet: - writer.writerow(row) - - def import_ordered_sets(file, filetype, progress_queue, purge=False): def create_ordered_set_from_row(row): set_name = row["Name"] diff --git a/home/models.py b/home/models.py index 6723fd94..880566e4 100644 --- a/home/models.py +++ b/home/models.py @@ -8,7 +8,6 @@ from django.db.models.signals import pre_save from django.dispatch import receiver from django.forms import CheckboxSelectMultiple -from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ from modelcluster.contrib.taggit import ClusterTaggableManager from modelcluster.fields import ParentalKey @@ -40,6 +39,7 @@ MultiFieldPanel, ObjectList, TabbedInterface, + TitleFieldPanel, ) logger = logging.getLogger(__name__) @@ -66,17 +66,6 @@ def get_unique_slug(self, slug): candidate_slug = f"{slug}-{suffix}" return candidate_slug - def full_clean(self, *args, **kwargs): - # Autogenerate slug if not present - if not self.slug: - allow_unicode = getattr(settings, "WAGTAIL_ALLOW_UNICODE_SLUGS", True) - base_slug = slugify(self.title, allow_unicode=allow_unicode) - - if base_slug: - self.slug = self.get_unique_slug(base_slug) - - super().full_clean(*args, **kwargs) - def clean(self): super().clean() @@ -489,7 +478,7 @@ class WhatsAppTemplateCategory(models.TextChoices): web_panels = [ MultiFieldPanel( [ - FieldPanel("title"), + TitleFieldPanel("title"), FieldPanel("subtitle"), FieldPanel("body"), FieldPanel("include_in_footer"), @@ -870,6 +859,26 @@ def clean(self): # The variable check is only for templates if self.is_whatsapp_template and len(self.whatsapp_body.raw_data) > 0: whatsapp_message = self.whatsapp_body.raw_data[0]["value"]["message"] + + right_mismatch = re.findall(r"(?{{ page.title }} +

{{ page.subtitle }}

+ {% include_block page.body %} + +{% endblock %} \ No newline at end of file diff --git a/home/tests/test_content_import_export.py b/home/tests/test_content_import_export.py index 19f7933e..17c2e908 100644 --- a/home/tests/test_content_import_export.py +++ b/home/tests/test_content_import_export.py @@ -17,7 +17,7 @@ from wagtail.images.models import Image # type: ignore from wagtail.models import Locale, Page # type: ignore -from home.content_import_export import import_content, old_import_content +from home.content_import_export import import_content from home.import_content_pages import ImportException from home.models import ContentPage, ContentPageIndex, HomePage @@ -69,14 +69,6 @@ def add_new_fields(entry: ExpDict) -> ExpDict: } -def remove_translation_tag_from_tags(src: ExpDict, dst: ExpDict) -> ExpPair: - # FIXME: Do we actually need translation_tag to be added to tags? - if not src["translation_tag"]: - return src, dst - dtags = [tag for tag in dst["tags"].split(", ") if tag != src["translation_tag"]] - return src, dst | {"tags": ", ".join(dtags)} - - @filter_both def ignore_certain_fields(entry: ExpDict) -> ExpDict: # FIXME: Do we need page.id to be imported? At the moment nothing in the @@ -91,12 +83,6 @@ def ignore_certain_fields(entry: ExpDict) -> ExpDict: return {k: v for k, v in entry.items() if k not in ignored_fields} -@filter_both -def ignore_old_fields(entry: ExpDict) -> ExpDict: - ignored_fields = {"next_prompt", "translation_tag", "buttons"} - return {k: v for k, v in entry.items() if k not in ignored_fields} - - @filter_both def strip_leading_whitespace(entry: ExpDict) -> ExpDict: # FIXME: Do we expect imported content to have leading spaces removed? @@ -110,20 +96,12 @@ def strip_leading_whitespace(entry: ExpDict) -> ExpDict: strip_leading_whitespace, ] -OLD_EXPORT_FILTER_FUNCS = [ - remove_translation_tag_from_tags, - ignore_old_fields, -] - -def filter_exports(srcs: ExpDicts, dsts: ExpDicts, importer: str) -> ExpDictsPair: +def filter_exports(srcs: ExpDicts, dsts: ExpDicts) -> ExpDictsPair: fsrcs, fdsts = [], [] for src, dst in zip(srcs, dsts, strict=True): for ff in EXPORT_FILTER_FUNCS: src, dst = ff(src, dst) - if importer == "old": - for ff in OLD_EXPORT_FILTER_FUNCS: - src, dst = ff(src, dst) fsrcs.append(src) fdsts.append(dst) return fsrcs, fdsts @@ -285,18 +263,6 @@ def normalise_related_page_ids(page: DbDict) -> DbDict: return page | {"fields": fields} -def remove_translation_key(pages: DbDicts) -> DbDicts: - # For old importer. - return _remove_fields(pages, {"translation_key"}) - - -def remove_revisions(pages: DbDicts) -> DbDicts: - # For old importer. Sometimes (maybe for the ContentPages imported after - # the first language?) we get higher revision numbers. Let's just strip - # them all and be done with it. - return _remove_fields(pages, {"latest_revision", "live_revision"}) - - @per_page def null_to_emptystr(page: DbDict) -> DbDict: # FIXME: Confirm that there's no meaningful difference here, potentially @@ -317,41 +283,6 @@ def null_to_emptystr(page: DbDict) -> DbDict: return page | {"fields": fields} -def _add_fields(body: dict[str, Any], extra_fields: dict[str, Any]) -> None: - body["value"] = extra_fields | body["value"] - - -@per_page -def add_body_fields(page: DbDict) -> DbDict: - if "whatsapp_body" in page["fields"]: - for body in page["fields"]["whatsapp_body"]: - _add_fields( - body, - { - "document": None, - "image": None, - "media": None, - "next_prompt": "", - "example_values": [], - "variation_messages": [], - "footer": "", - }, - ) - if "sms_body" in page["fields"]: - for body in page["fields"]["sms_body"]: - _add_fields(body, {"image": None}) - if "ussd_body" in page["fields"]: - for body in page["fields"]["ussd_body"]: - _add_fields(body, {"image": None}) - if "messenger_body" in page["fields"]: - for body in page["fields"]["messenger_body"]: - _add_fields(body, {"image": None}) - if "viber_body" in page["fields"]: - for body in page["fields"]["viber_body"]: - _add_fields(body, {"image": None}) - return page - - WEB_PARA_RE = re.compile(r'^
(.*)
$') @@ -367,46 +298,6 @@ def clean_web_paragraphs(page: DbDict) -> DbDict: return page -@per_page -def remove_next_prompt(page: DbDict) -> DbDict: - if "whatsapp_body" in page["fields"]: - for body in page["fields"]["whatsapp_body"]: - body["value"].pop("next_prompt", None) - return page - - -@per_page -def remove_buttons(page: DbDict) -> DbDict: - if "whatsapp_body" in page["fields"]: - for body in page["fields"]["whatsapp_body"]: - body["value"].pop("buttons", None) - return page - - -@per_page -def remove_example_values(page: DbDict) -> DbDict: - if "whatsapp_body" in page["fields"]: - for body in page["fields"]["whatsapp_body"]: - body["value"].pop("example_values", None) - return page - - -@per_page -def remove_sms_fields(page: DbDict) -> DbDict: - if "sms_body" in page["fields"]: - for body in page["fields"]["sms_body"]: - body["value"].pop("sms_body", None) - return page - - -@per_page -def remove_ussd_fields(page: DbDict) -> DbDict: - if "ussd_body" in page["fields"]: - for body in page["fields"]["ussd_body"]: - body["value"].pop("ussd_body", None) - return page - - @per_page def remove_button_ids(page: DbDict) -> DbDict: if "whatsapp_body" in page["fields"]: @@ -427,12 +318,6 @@ def remove_example_value_ids(page: DbDict) -> DbDict: return page -@per_page -def enable_web(page: DbDict) -> DbDict: - page["fields"]["enable_web"] = True - return page - - PAGE_FILTER_FUNCS = [ normalise_pks, normalise_revisions, @@ -445,32 +330,12 @@ def enable_web(page: DbDict) -> DbDict: remove_example_value_ids, ] -OLD_PAGE_FILTER_FUNCS = [ - remove_translation_key, - remove_revisions, - add_body_fields, - remove_next_prompt, - remove_buttons, - remove_example_values, - enable_web, - remove_sms_fields, - remove_ussd_fields, -] - @dataclass class ImportExport: admin_client: Any - importer: str format: str - @property - def _import_content(self) -> Callable[..., None]: - return { - "new": import_content, - "old": old_import_content, - }[self.importer] - @property def _filter_export(self) -> Callable[..., bytes]: return { @@ -543,7 +408,7 @@ def import_content(self, content_bytes: bytes, **kw: Any) -> None: """ Import given content in the configured format with the configured importer. """ - self._import_content(BytesIO(content_bytes), self.format.upper(), Queue(), **kw) + import_content(BytesIO(content_bytes), self.format.upper(), Queue(), **kw) def read_bytes(self, path_str: str, path_base: str = "home/tests") -> bytes: return (Path(path_base) / path_str).read_bytes() @@ -570,9 +435,6 @@ def get_page_json(self, locale: str | None = None) -> DbDicts: things that vary across import/export. """ pages = decode_json_fields(get_page_json()) - if self.importer == "old": - for ff in OLD_PAGE_FILTER_FUNCS: - pages = ff(pages) for ff in PAGE_FILTER_FUNCS: pages = ff(pages) if locale is not None: @@ -583,17 +445,12 @@ def get_page_json(self, locale: str | None = None) -> DbDicts: def csvs2dicts(self, src_bytes: bytes, dst_bytes: bytes) -> ExpDictsPair: src = csv2dicts(src_bytes) dst = csv2dicts(dst_bytes) - return filter_exports(src, dst, self.importer) - - -@pytest.fixture(params=["old", "new"]) -def csv_impexp(request: Any, admin_client: Any) -> ImportExport: - return ImportExport(admin_client, request.param, "csv") + return filter_exports(src, dst) @pytest.fixture() -def newcsv_impexp(request: Any, admin_client: Any) -> ImportExport: - return ImportExport(admin_client, "new", "csv") +def csv_impexp(request: Any, admin_client: Any) -> ImportExport: + return ImportExport(admin_client, "csv") @pytest.mark.django_db @@ -657,36 +514,12 @@ def test_multiple_messages(self, csv_impexp: ImportExport) -> None: src, dst = csv_impexp.csvs2dicts(csv_bytes, content) assert dst == src - def test_translations_sep(self, csv_impexp: ImportExport) -> None: - """ - Importing a CSV file split into separate parts per locale and then - exporting it produces a duplicate of the original file. - - (This uses translations-sp.csv and the two language-specific subsets thereof.) - - FIXME: - * Remove this test when the old importer goes away completely. - """ - # Create a new homepage for Portuguese. - pt, _created = Locale.objects.get_or_create(language_code="pt") - HomePage.add_root(locale=pt, title="Home (pt)", slug="home-pt") - - set_profile_field_options() - csv_impexp.import_file("translations-sep-en.csv") - csv_impexp.import_file("translations-sep-pt.csv", locale="pt", purge=False) - csv_bytes = csv_impexp.read_bytes("translations-sep.csv") - content = csv_impexp.export_content() - src, dst = csv_impexp.csvs2dicts(csv_bytes, content) - assert dst == src - - def test_default_locale(self, newcsv_impexp: ImportExport) -> None: + def test_default_locale(self, csv_impexp: ImportExport) -> None: """ Importing a CSV file with multiple languages and specifying a locale and then exporting it produces a duplicate of the original file but with only pages from the specifyied specified locale included. - NOTE: Old importer can't handle multiple languages at once. - (This uses translations.csv and the en language-specific subset thereof.) """ # Create a new homepage for Portuguese. @@ -694,20 +527,18 @@ def test_default_locale(self, newcsv_impexp: ImportExport) -> None: HomePage.add_root(locale=pt, title="Home (pt)", slug="home-pt") set_profile_field_options() - newcsv_impexp.import_file("translations.csv", locale="en") - csv_bytes = newcsv_impexp.read_bytes("translations-en.csv") - content = newcsv_impexp.export_content() - src, dst = newcsv_impexp.csvs2dicts(csv_bytes, content) + csv_impexp.import_file("translations.csv", locale="en") + csv_bytes = csv_impexp.read_bytes("translations-en.csv") + content = csv_impexp.export_content() + src, dst = csv_impexp.csvs2dicts(csv_bytes, content) assert dst == src - def test_translated_locale(self, newcsv_impexp: ImportExport) -> None: + def test_translated_locale(self, csv_impexp: ImportExport) -> None: """ Importing a CSV file with multiple languages and specifying a locale and then exporting it produces a duplicate of the original file but with only pages from the specifyied specified locale included. - NOTE: Old importer can't handle multiple languages at once. - (This uses translations.csv and the pt language-specific subset thereof.) """ # Create a new homepage for Portuguese. @@ -715,19 +546,17 @@ def test_translated_locale(self, newcsv_impexp: ImportExport) -> None: HomePage.add_root(locale=pt, title="Home (pt)", slug="home-pt") set_profile_field_options() - newcsv_impexp.import_file("translations.csv", locale="pt") - csv_bytes = newcsv_impexp.read_bytes("translations-pt.csv") - content = newcsv_impexp.export_content() - src, dst = newcsv_impexp.csvs2dicts(csv_bytes, content) + csv_impexp.import_file("translations.csv", locale="pt") + csv_bytes = csv_impexp.read_bytes("translations-pt.csv") + content = csv_impexp.export_content() + src, dst = csv_impexp.csvs2dicts(csv_bytes, content) assert dst == src - def test_all_locales(self, newcsv_impexp: ImportExport) -> None: + def test_all_locales(self, csv_impexp: ImportExport) -> None: """ Importing a CSV file containing translations and then exporting it produces a duplicate of the original file. - NOTE: Old importer can't handle multiple languages at once. - (This uses translations.csv.) """ # Create a new homepage for Portuguese. @@ -735,18 +564,16 @@ def test_all_locales(self, newcsv_impexp: ImportExport) -> None: HomePage.add_root(locale=pt, title="Home (pt)", slug="home-pt") set_profile_field_options() - csv_bytes = newcsv_impexp.import_file("translations.csv") - content = newcsv_impexp.export_content() - src, dst = newcsv_impexp.csvs2dicts(csv_bytes, content) + csv_bytes = csv_impexp.import_file("translations.csv") + content = csv_impexp.export_content() + src, dst = csv_impexp.csvs2dicts(csv_bytes, content) assert dst == src - def test_all_locales_split(self, newcsv_impexp: ImportExport) -> None: + def test_all_locales_split(self, csv_impexp: ImportExport) -> None: """ Importing a CSV file split into separate parts per locale and then exporting it produces a duplicate of the original file. - NOTE: Old importer can't handle non-unique slugs. - (This uses translations.csv and the two language-specific subsets thereof.) """ # Create a new homepage for Portuguese. @@ -754,12 +581,12 @@ def test_all_locales_split(self, newcsv_impexp: ImportExport) -> None: HomePage.add_root(locale=pt, title="Home (pt)", slug="home-pt") set_profile_field_options() - csv_bytes = newcsv_impexp.read_bytes("translations.csv") - newcsv_impexp.import_file("translations.csv", locale="en") - newcsv_impexp.import_file("translations.csv", purge=False, locale="pt") + csv_bytes = csv_impexp.read_bytes("translations.csv") + csv_impexp.import_file("translations.csv", locale="en") + csv_impexp.import_file("translations.csv", purge=False, locale="pt") - content = newcsv_impexp.export_content() - src, dst = newcsv_impexp.csvs2dicts(csv_bytes, content) + content = csv_impexp.export_content() + src, dst = csv_impexp.csvs2dicts(csv_bytes, content) assert dst == src @@ -791,17 +618,17 @@ def test_import_error(self, csv_impexp: ImportExport) -> None: src, dst = csv_impexp.csvs2dicts(csv_bytes, content) assert dst == src - def test_no_translation_key_default(self, newcsv_impexp: ImportExport) -> None: + def test_no_translation_key_default(self, csv_impexp: ImportExport) -> None: """ Importing pages without translation keys in the default locale causes wagtail to generate new translation keys. (This uses no-translation-key-default.csv.) """ - csv_bytes = newcsv_impexp.import_file("no-translation-key-default.csv") + csv_bytes = csv_impexp.import_file("no-translation-key-default.csv") - content = newcsv_impexp.export_content() - src, dst = newcsv_impexp.csvs2dicts(csv_bytes, content) + content = csv_impexp.export_content() + src, dst = csv_impexp.csvs2dicts(csv_bytes, content) # Check that the export has translation keys for all rows and clear # them to match the imported data for row in dst: @@ -809,7 +636,7 @@ def test_no_translation_key_default(self, newcsv_impexp: ImportExport) -> None: row["translation_tag"] = "" assert dst == src - def test_no_translation_key_nondefault(self, newcsv_impexp: ImportExport) -> None: + def test_no_translation_key_nondefault(self, csv_impexp: ImportExport) -> None: """ Importing pages without translation keys in the non-default locale causes a validation error. @@ -822,7 +649,7 @@ def test_no_translation_key_nondefault(self, newcsv_impexp: ImportExport) -> Non # A ContentPageIndex without a translation key fails with pytest.raises(ImportException) as e: - newcsv_impexp.import_file("no-translation-key-cpi.csv") + csv_impexp.import_file("no-translation-key-cpi.csv") assert e.value.row_num == 4 # FIXME: Find a better way to represent this. @@ -831,26 +658,26 @@ def test_no_translation_key_nondefault(self, newcsv_impexp: ImportExport) -> Non # A ContentPage without a translation key fails with pytest.raises(ImportException) as e: - newcsv_impexp.import_file("no-translation-key-cp.csv") + csv_impexp.import_file("no-translation-key-cp.csv") assert e.value.row_num == 5 # FIXME: Find a better way to represent this. assert "translation_key" in e.value.message assert "“” is not a valid UUID." in e.value.message - def test_invalid_locale_name(self, newcsv_impexp: ImportExport) -> None: + def test_invalid_locale_name(self, csv_impexp: ImportExport) -> None: """ Importing pages with invalid locale names should raise an error that results in an error message that gets sent back to the user """ with pytest.raises(ImportException) as e: - newcsv_impexp.import_file("invalid-locale-name.csv") + csv_impexp.import_file("invalid-locale-name.csv") assert e.value.row_num == 2 assert e.value.message == "Language not found: NotEnglish" def test_multiple_locales_for_name( - self, newcsv_impexp: ImportExport, settings: SettingsWrapper + self, csv_impexp: ImportExport, settings: SettingsWrapper ) -> None: """ Importing pages with locale names that represent multiple locales should raise @@ -861,7 +688,7 @@ def test_multiple_locales_for_name( ("en2", "NotEnglish"), ] with pytest.raises(ImportException) as e: - newcsv_impexp.import_file("invalid-locale-name.csv") + csv_impexp.import_file("invalid-locale-name.csv") assert e.value.row_num == 2 assert ( @@ -869,13 +696,13 @@ def test_multiple_locales_for_name( == "Multiple codes for language: NotEnglish -> ['en1', 'en2']" ) - def test_missing_parent(self, newcsv_impexp: ImportExport) -> None: + def test_missing_parent(self, csv_impexp: ImportExport) -> None: """ If the import file specifies a parent title, but there are no pages with that title, then an error message should get sent back to the user. """ with pytest.raises(ImportException) as e: - newcsv_impexp.import_file("missing-parent.csv") + csv_impexp.import_file("missing-parent.csv") assert e.value.row_num == 2 assert ( @@ -884,7 +711,7 @@ def test_missing_parent(self, newcsv_impexp: ImportExport) -> None: "'English'" ) - def test_multiple_parents(self, newcsv_impexp: ImportExport) -> None: + def test_multiple_parents(self, csv_impexp: ImportExport) -> None: """ Because we use the title to find a parent page, and it's possible to have multiple pages with the same title, it's possible to have the situation where @@ -896,7 +723,7 @@ def test_multiple_parents(self, newcsv_impexp: ImportExport) -> None: PageBuilder.build_cpi(home_page, "missing-parent2", "missing-parent") with pytest.raises(ImportException) as e: - newcsv_impexp.import_file("missing-parent.csv", purge=False) + csv_impexp.import_file("missing-parent.csv", purge=False) assert e.value.row_num == 2 assert ( e.value.message @@ -904,14 +731,14 @@ def test_multiple_parents(self, newcsv_impexp: ImportExport) -> None: "parent page: ['missing-parent1', 'missing-parent2']" ) - def test_go_to_page_button_missing_page(self, newcsv_impexp: ImportExport) -> None: + def test_go_to_page_button_missing_page(self, csv_impexp: ImportExport) -> None: """ Go to page buttons in the import file link to other pages using the slug. But if no page with that slug exists, then we should give the user an error message that tells them where and how to fix it. """ with pytest.raises(ImportException) as e: - newcsv_impexp.import_file("missing-gotopage.csv") + csv_impexp.import_file("missing-gotopage.csv") assert e.value.row_num == 2 assert ( e.value.message @@ -919,14 +746,14 @@ def test_go_to_page_button_missing_page(self, newcsv_impexp: ImportExport) -> No "button 'Missing' on page 'ma_import-export'" ) - def test_missing_related_pages(self, newcsv_impexp: ImportExport) -> None: + def test_missing_related_pages(self, csv_impexp: ImportExport) -> None: """ Related pages are listed as comma separated slugs in imported files. If there is a slug listed that we cannot find the page for, then we should show the user an error with information about the missing page. """ with pytest.raises(ImportException) as e: - newcsv_impexp.import_file("missing-related-page.csv") + csv_impexp.import_file("missing-related-page.csv") assert e.value.row_num == 2 assert ( e.value.message @@ -934,13 +761,13 @@ def test_missing_related_pages(self, newcsv_impexp: ImportExport) -> None: "'English'" ) - def test_invalid_wa_template_category(self, newcsv_impexp: ImportExport) -> None: + def test_invalid_wa_template_category(self, csv_impexp: ImportExport) -> None: """ Importing a WhatsApp template with an invalid category should raise an error that results in an error message that gets sent back to the user. """ with pytest.raises(ImportException) as e: - newcsv_impexp.import_file("bad-whatsapp-template-category.csv") + csv_impexp.import_file("bad-whatsapp-template-category.csv") assert e.value.row_num == 3 # FIXME: Find a better way to represent this. @@ -949,13 +776,13 @@ def test_invalid_wa_template_category(self, newcsv_impexp: ImportExport) -> None == "Validation error: {'whatsapp_template_category': [\"Value 'Marketing' is not a valid choice.\"]}" ) - def test_invalid_wa_template_vars(self, newcsv_impexp: ImportExport) -> None: + def test_invalid_wa_template_vars(self, csv_impexp: ImportExport) -> None: """ Importing a WhatsApp template with invalid variables should raise an error that results in an error message that gets sent back to the user. """ with pytest.raises(ImportException) as e: - newcsv_impexp.import_file("bad-whatsapp-template-vars.csv") + csv_impexp.import_file("bad-whatsapp-template-vars.csv") assert e.value.row_num == 3 # FIXME: Find a better way to represent this. @@ -964,19 +791,19 @@ def test_invalid_wa_template_vars(self, newcsv_impexp: ImportExport) -> None: == "Validation error: {'whatsapp_body': ['Validation error in StreamBlock']}" ) - def test_invalid_wa_template_vars_update(self, newcsv_impexp: ImportExport) -> None: + def test_invalid_wa_template_vars_update(self, csv_impexp: ImportExport) -> None: """ Updating a valid WhatsApp template with invalid variables should raise an error that results in an error message that gets sent back to the user. The update validation happens in a different code path from the initial import. """ - newcsv_impexp.import_file("good-whatsapp-template-vars.csv") + csv_impexp.import_file("good-whatsapp-template-vars.csv") # Update an existing page, which does the validation in # `page.save_revision()` rather than `parent.add_child()`. with pytest.raises(ImportException) as e: - newcsv_impexp.import_file("bad-whatsapp-template-vars.csv", purge=False) + csv_impexp.import_file("bad-whatsapp-template-vars.csv", purge=False) assert e.value.row_num == 3 # FIXME: Find a better way to represent this. @@ -985,14 +812,14 @@ def test_invalid_wa_template_vars_update(self, newcsv_impexp: ImportExport) -> N == "Validation error: {'whatsapp_body': ['Validation error in StreamBlock']}" ) - def test_cpi_validation_failure(self, newcsv_impexp: ImportExport) -> None: + def test_cpi_validation_failure(self, csv_impexp: ImportExport) -> None: """ Importing a ContentPageIndex with an invalid translation key should raise an error that results in an error message that gets sent back to the user. """ with pytest.raises(ImportException) as e: - newcsv_impexp.import_file("bad-cpi-translation-key.csv") + csv_impexp.import_file("bad-cpi-translation-key.csv") assert e.value.row_num == 2 # FIXME: Find a better way to represent this. @@ -1001,17 +828,17 @@ def test_cpi_validation_failure(self, newcsv_impexp: ImportExport) -> None: == "Validation error: {'translation_key': ['“BADUUID” is not a valid UUID.']}" ) - def test_cpi_validation_failure_update(self, newcsv_impexp: ImportExport) -> None: + def test_cpi_validation_failure_update(self, csv_impexp: ImportExport) -> None: """ Updating a valid ContentPageIndex with an invalid translation key should raise an error that results in an error message that gets sent back to the user. The update validation happens in a different code path from the initial import. """ - newcsv_impexp.import_file("good-cpi-translation-key.csv") + csv_impexp.import_file("good-cpi-translation-key.csv") with pytest.raises(ImportException) as e: - newcsv_impexp.import_file("bad-cpi-translation-key.csv", purge=False) + csv_impexp.import_file("bad-cpi-translation-key.csv", purge=False) assert e.value.row_num == 2 # FIXME: Find a better way to represent this. @@ -1021,16 +848,9 @@ def test_cpi_validation_failure_update(self, newcsv_impexp: ImportExport) -> Non ) -# "old-xlsx" has at least three bugs, so we don't bother testing it. -@pytest.fixture(params=["old-csv", "new-csv", "new-xlsx"]) -def impexp(request: Any, admin_client: Any) -> ImportExport: - importer, format = request.param.split("-") - return ImportExport(admin_client, importer, format) - - @pytest.fixture(params=["csv", "xlsx"]) -def new_impexp(request: Any, admin_client: Any) -> ImportExport: - return ImportExport(admin_client, "new", request.param) +def impexp(request: Any, admin_client: Any) -> ImportExport: + return ImportExport(admin_client, request.param) @pytest.fixture() @@ -1164,12 +984,11 @@ def test_multiple_messages(self, impexp: ImportExport) -> None: assert imported == orig @pytest.mark.xfail(reason="Image imports are currently broken.") - def test_images(self, new_impexp: ImportExport) -> None: + def test_images(self, impexp: ImportExport) -> None: """ ContentPages with images in multiple message types are preserved across export/import. - NOTE: Old importer can't handle images. """ img_path = Path("home/tests/test_static") / "test.jpeg" img_wa = mk_img(img_path, "wa_image") @@ -1189,9 +1008,9 @@ def test_images(self, new_impexp: ImportExport) -> None: ], ) - orig = new_impexp.get_page_json() - new_impexp.export_reimport() - imported = new_impexp.get_page_json() + orig = impexp.get_page_json() + impexp.export_reimport() + imported = impexp.get_page_json() assert imported == orig def test_variations(self, impexp: ImportExport) -> None: @@ -1199,8 +1018,6 @@ def test_variations(self, impexp: ImportExport) -> None: ContentPages with variation messages (and buttons and next prompts) are preserved across export/import. - NOTE: The old importer can't handle multiple restrictions on a - variation, so it gets a slightly simpler dataset. """ set_profile_field_options() @@ -1211,11 +1028,6 @@ def test_variations(self, impexp: ImportExport) -> None: VarMsg("Single male", gender="male", relationship="single"), VarMsg("Complicated male", gender="male", relationship="complicated"), ] - if impexp.importer == "old": - m1vars = [ - VarMsg("Single", relationship="single"), - VarMsg("Complicated", relationship="complicated"), - ] cp_imp_exp_wablks = [ WABlk( @@ -1250,9 +1062,6 @@ def test_tags_and_related(self, impexp: ImportExport) -> None: """ ContentPages with tags and related pages are preserved across export/import. - - NOTE: The old importer can't handle non-ContentPage related pages, so - it doesn't get one of those. """ home_page = HomePage.objects.first() main_menu = PageBuilder.build_cpi(home_page, "main-menu", "Main Menu") @@ -1281,10 +1090,7 @@ def test_tags_and_related(self, impexp: ImportExport) -> None: tags=["tag4"], ) PageBuilder.link_related(health_info, [self_help]) - if impexp.importer == "old": - PageBuilder.link_related(self_help, [health_info]) - else: - PageBuilder.link_related(self_help, [health_info, main_menu]) + PageBuilder.link_related(self_help, [health_info, main_menu]) orig = impexp.get_page_json() impexp.export_reimport() @@ -1355,12 +1161,10 @@ def test_whatsapp_template(self, impexp: ImportExport) -> None: imported = impexp.get_page_json() assert imported == orig - def test_translations(self, new_impexp: ImportExport) -> None: + def test_translations(self, impexp: ImportExport) -> None: """ ContentPages in multiple languages (with unique-per-locale slugs and titles) are preserved across export/import. - - NOTE: Old importer can't handle non-unique slugs. """ # Create a new homepage for Portuguese. pt, _created = Locale.objects.get_or_create(language_code="pt") @@ -1429,9 +1233,9 @@ def test_translations(self, new_impexp: ImportExport) -> None: assert imp_exp.translation_key == imp_exp_pt.translation_key assert non_tmpl.translation_key == non_tmpl_pt.translation_key - orig = new_impexp.get_page_json() - new_impexp.export_reimport() - imported = new_impexp.get_page_json() + orig = impexp.get_page_json() + impexp.export_reimport() + imported = impexp.get_page_json() assert imported == orig def test_translations_sep(self, impexp: ImportExport) -> None: @@ -1507,13 +1311,11 @@ def test_translations_sep(self, impexp: ImportExport) -> None: imported = impexp.get_page_json() assert imported == orig - def test_translations_split(self, new_impexp: ImportExport) -> None: + def test_translations_split(self, impexp: ImportExport) -> None: """ ContentPages in multiple languages (with unique-per-locale slugs and titles) are preserved across export/import with each language imported separately. - - NOTE: Old importer can't handle non-unique slugs. """ # Create a new homepage for Portuguese. pt, _created = Locale.objects.get_or_create(language_code="pt") @@ -1574,22 +1376,20 @@ def test_translations_split(self, new_impexp: ImportExport) -> None: assert imp_exp.translation_key == imp_exp_pt.translation_key assert non_tmpl.translation_key == non_tmpl_pt.translation_key - orig = new_impexp.get_page_json() - content_en = new_impexp.export_content(locale="en") - content_pt = new_impexp.export_content(locale="pt") + orig = impexp.get_page_json() + content_en = impexp.export_content(locale="en") + content_pt = impexp.export_content(locale="pt") - new_impexp.import_content(content_en, locale="en") - new_impexp.import_content(content_pt, locale="pt", purge=False) - imported = new_impexp.get_page_json() + impexp.import_content(content_en, locale="en") + impexp.import_content(content_pt, locale="pt", purge=False) + imported = impexp.get_page_json() assert imported == orig - def test_translations_en(self, new_impexp: ImportExport) -> None: + def test_translations_en(self, impexp: ImportExport) -> None: """ ContentPages in multiple languages are that are imported with a locale specified have pages in that locale preserved and all other locales are removed. - - NOTE: Old importer can't handle multiple languages at once. """ # Create a new homepage for Portuguese. pt, _created = Locale.objects.get_or_create(language_code="pt") @@ -1650,11 +1450,11 @@ def test_translations_en(self, new_impexp: ImportExport) -> None: assert imp_exp.translation_key == imp_exp_pt.translation_key assert non_tmpl.translation_key == non_tmpl_pt.translation_key - orig_en = new_impexp.get_page_json(locale="en") - content = new_impexp.export_content() + orig_en = impexp.get_page_json(locale="en") + content = impexp.export_content() - new_impexp.import_content(content, locale="en") - imported = new_impexp.get_page_json() + impexp.import_content(content, locale="en") + imported = impexp.get_page_json() assert imported == orig_en def test_footer(self, new_impexp: ImportExport) -> None: @@ -1691,12 +1491,10 @@ def test_footer(self, new_impexp: ImportExport) -> None: imported = new_impexp.get_page_json() assert imported == orig - def test_example_values(self, new_impexp: ImportExport) -> None: + def test_example_values(self, impexp: ImportExport) -> None: """ ContentPages with example values in whatsapp messages are preserved across export/import. - - NOTE: Old importer can't handle example values. """ home_page = HomePage.objects.first() main_menu = PageBuilder.build_cpi(home_page, "main-menu", "Main Menu") @@ -1722,9 +1520,9 @@ def test_example_values(self, new_impexp: ImportExport) -> None: whatsapp_template_name="template-health-info", ) - orig = new_impexp.get_page_json() - new_impexp.export_reimport() - imported = new_impexp.get_page_json() + orig = impexp.get_page_json() + impexp.export_reimport() + imported = impexp.get_page_json() assert imported == orig def test_export_missing_related_page(self, impexp: ImportExport) -> None: @@ -1776,12 +1574,10 @@ def test_export_missing_related_page(self, impexp: ImportExport) -> None: imported = impexp.get_page_json() assert imported == orig_without_self_help - def test_ussd_values(self, new_impexp: ImportExport) -> None: + def test_ussd_values(self, impexp: ImportExport) -> None: """ ContentPages with USSD messages are preserved across export/import. - - NOTE: Old importer can't handle USSD values. """ home_page = HomePage.objects.first() main_menu = PageBuilder.build_cpi(home_page, "main-menu", "Main Menu") @@ -1793,17 +1589,15 @@ def test_ussd_values(self, new_impexp: ImportExport) -> None: bodies=[UBody("HealthAlert menu", [UBlk("*Welcome to HealthAlert* USSD")])], ) - orig = new_impexp.get_page_json() - new_impexp.export_reimport() - imported = new_impexp.get_page_json() + orig = impexp.get_page_json() + impexp.export_reimport() + imported = impexp.get_page_json() assert imported == orig - def test_sms_values(self, new_impexp: ImportExport) -> None: + def test_sms_values(self, impexp: ImportExport) -> None: """ ContentPages with SMS messages are preserved across export/import. - - NOTE: Old importer can't handle SMS values. """ home_page = HomePage.objects.first() main_menu = PageBuilder.build_cpi(home_page, "main-menu", "Main Menu") @@ -1815,7 +1609,7 @@ def test_sms_values(self, new_impexp: ImportExport) -> None: bodies=[SBody("HealthAlert menu", [SBlk("*Welcome to HealthAlert* SMS")])], ) - orig = new_impexp.get_page_json() - new_impexp.export_reimport() - imported = new_impexp.get_page_json() + orig = impexp.get_page_json() + impexp.export_reimport() + imported = impexp.get_page_json() assert imported == orig diff --git a/home/tests/test_models.py b/home/tests/test_models.py index f2c5fbc9..7c2cf87f 100644 --- a/home/tests/test_models.py +++ b/home/tests/test_models.py @@ -1,6 +1,8 @@ +from io import StringIO from unittest import mock from django.core.exceptions import ValidationError +from django.core.management import call_command from django.test import TestCase, override_settings from requests import HTTPError from wagtail.blocks import StructBlockValidationError @@ -277,7 +279,7 @@ def test_clean_text_valid_variables(self): "WA Title", [ WABlk( - "{{2}}{{1}} {{foo}}", + "{{2}}{{1}} {{foo}} {{mismatch1} {mismatch2}}", ) ], ) @@ -322,6 +324,15 @@ def test_create_whatsapp_template_submit_return_error( self.assertRaises(ValidationError) self.assertEqual(e.exception.message, "Failed to submit template") + def test_for_missing_migrations(self): + output = StringIO() + call_command("makemigrations", no_input=True, dry_run=True, stdout=output) + self.assertEqual( + output.getvalue().strip(), + "No changes detected", + "There are missing migrations:\n %s" % output.getvalue(), + ) + class WhatsappBlockTests(TestCase): def create_message_value( From 9d006fb652b28fe3e2d264cb1a4665bf4866fe21 Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Mon, 5 Feb 2024 11:41:54 +0200 Subject: [PATCH 18/20] fix test --- home/tests/test_content_import_export.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/home/tests/test_content_import_export.py b/home/tests/test_content_import_export.py index 17c2e908..74b563d3 100644 --- a/home/tests/test_content_import_export.py +++ b/home/tests/test_content_import_export.py @@ -1457,7 +1457,7 @@ def test_translations_en(self, impexp: ImportExport) -> None: imported = impexp.get_page_json() assert imported == orig_en - def test_footer(self, new_impexp: ImportExport) -> None: + def test_footer(self, impexp: ImportExport) -> None: """ ContentPages with footer in whatsapp messages are preserved across export/import. @@ -1486,9 +1486,9 @@ def test_footer(self, new_impexp: ImportExport) -> None: whatsapp_template_name="template-health-info", ) - orig = new_impexp.get_page_json() - new_impexp.export_reimport() - imported = new_impexp.get_page_json() + orig = impexp.get_page_json() + impexp.export_reimport() + imported = impexp.get_page_json() assert imported == orig def test_example_values(self, impexp: ImportExport) -> None: From 74bd287681b19fa16bb837a834ffcf48be01c87f Mon Sep 17 00:00:00 2001 From: Hlamalani Date: Mon, 5 Feb 2024 12:56:58 +0200 Subject: [PATCH 19/20] merge conflict fix --- requirements-dev.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 2e69ff69..aa631277 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,7 +1,7 @@ -black -ruff +black==24.1.1 +ruff==0.1.14 responses -pytest +pytest==8.0.0 pytest-django pytest-cov pytest-xdist From bd86f8629d23bf5458421b4223f777949b8b9c98 Mon Sep 17 00:00:00 2001 From: Fritz Brand Date: Tue, 6 Feb 2024 11:29:38 +0200 Subject: [PATCH 20/20] Fixed test csv file --- home/tests/list_items.csv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/home/tests/list_items.csv b/home/tests/list_items.csv index 861516a7..38717cfe 100644 --- a/home/tests/list_items.csv +++ b/home/tests/list_items.csv @@ -1,3 +1,3 @@ -structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,variation_title,variation_body,list_items,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages -Menu 1,0,600,main-menu,,Main Menu,,,,,,,,,,,,,,,,,,35a7f12c-7373-42a6-9ca6-a1caedea5822,,,,English,,,,,, -Sub 1.1,1,601,ha-menu,Main Menu,HealthAlert menu,,,HealthAlert menu,*Welcome to HealthAlert* WA,,UTILITY,,,"['Item 1', 'Item 2']",,,,,HealthAlert menu,Welcome to HealthAlert M,HealthAlert menu,Welcome to HealthAlert V,5ab08854-228b-4f83-ae54-ec2dc6ebaf69,,,,English,,[],,,, \ No newline at end of file +structure,message,page_id,slug,parent,web_title,web_subtitle,web_body,whatsapp_title,whatsapp_body,whatsapp_template_name,whatsapp_template_category,variation_title,variation_body,list_items,sms_title,sms_body,ussd_title,ussd_body,messenger_title,messenger_body,viber_title,viber_body,translation_tag,tags,quick_replies,triggers,locale,next_prompt,buttons,image_link,doc_link,media_link,related_pages,footer +Menu 1,0,600,main-menu,,Main Menu,,,,,,,,,,,,,,,,,,35a7f12c-7373-42a6-9ca6-a1caedea5822,,,,English,,,,,,, +Sub 1.1,1,601,ha-menu,Main Menu,HealthAlert menu,,,HealthAlert menu,*Welcome to HealthAlert* WA,,UTILITY,,,"['Item 1', 'Item 2']",,,,,HealthAlert menu,Welcome to HealthAlert M,HealthAlert menu,Welcome to HealthAlert V,5ab08854-228b-4f83-ae54-ec2dc6ebaf69,,,,English,,[],,,,, \ No newline at end of file