@@ -560,6 +560,64 @@ def test_merge_data(self):
560560 ):
561561 self .message .send ()
562562
563+ def test_merge_headers (self ):
564+ # Amazon SES only supports merging when using templates (see below)
565+ self .message .merge_headers = {}
566+ with self .assertRaisesMessage (
567+ AnymailUnsupportedFeature , "merge_headers without template_id"
568+ ):
569+ self .message .send ()
570+
571+ @override_settings (
572+ # only way to use tags with template_id:
573+ ANYMAIL_AMAZON_SES_MESSAGE_TAG_NAME = "Campaign"
574+ )
575+ def test_template_dont_add_merge_headers (self ):
576+ """With template_id, Anymail switches to SESv2 SendBulkEmail"""
577+ # SendBulkEmail uses a completely different API call and payload
578+ # structure, so this re-tests a bunch of Anymail features that were handled
579+ # differently above. (See test_amazon_ses_integration for a more realistic
580+ # template example.)
581+ raw_response = {
582+ "BulkEmailEntryResults" : [
583+ {
584+ "Status" : "SUCCESS" ,
585+ "MessageId" : "1111111111111111-bbbbbbbb-3333-7777" ,
586+ },
587+ {
588+ "Status" : "ACCOUNT_DAILY_QUOTA_EXCEEDED" ,
589+ "Error" : "Daily message quota exceeded" ,
590+ },
591+ ],
592+ "ResponseMetadata" : self .DEFAULT_SEND_RESPONSE ["ResponseMetadata" ],
593+ }
594+ self .set_mock_response (raw_response , operation_name = "send_bulk_email" )
595+ message = AnymailMessage (
596+ template_id = "welcome_template" ,
597+ from_email = '"Example, Inc." <from@example.com>' ,
598+ to = ["alice@example.com" , "罗伯特 <bob@example.com>" ],
599+ cc = ["cc@example.com" ],
600+ reply_to = ["reply1@example.com" , "Reply 2 <reply2@example.com>" ],
601+ merge_data = {
602+ "alice@example.com" : {"name" : "Alice" , "group" : "Developers" },
603+ "bob@example.com" : {"name" : "Bob" }, # and leave group undefined
604+ "nobody@example.com" : {"name" : "Not a recipient for this message" },
605+ },
606+ merge_global_data = {"group" : "Users" , "site" : "ExampleCo" },
607+ # (only works with AMAZON_SES_MESSAGE_TAG_NAME when using template):
608+ tags = ["WelcomeVariantA" ],
609+ envelope_sender = "bounce@example.com" ,
610+ esp_extra = {
611+ "FromEmailAddressIdentityArn" : (
612+ "arn:aws:ses:us-east-1:123456789012:identity/example.com"
613+ )
614+ },
615+ )
616+ message .send ()
617+
618+ params = self .get_send_params (operation_name = "send_bulk_email" )
619+ self .assertNotIn ("ReplacementHeaders" , params ["BulkEmailEntries" ][0 ])
620+
563621 @override_settings (
564622 # only way to use tags with template_id:
565623 ANYMAIL_AMAZON_SES_MESSAGE_TAG_NAME = "Campaign"
@@ -595,6 +653,16 @@ def test_template(self):
595653 "bob@example.com" : {"name" : "Bob" }, # and leave group undefined
596654 "nobody@example.com" : {"name" : "Not a recipient for this message" },
597655 },
656+ merge_headers = {
657+ "alice@example.com" : {
658+ "List-Unsubscribe" : "<https://example.com/a/>" ,
659+ "List-Unsubscribe-Post" : "List-Unsubscribe=One-Click" ,
660+ },
661+ "nobody@example.com" : {
662+ "List-Unsubscribe" : "<mailto:unsubscribe@example.com>" ,
663+ "List-Unsubscribe-Post" : "List-Unsubscribe=One-Click" ,
664+ },
665+ },
598666 merge_global_data = {"group" : "Users" , "site" : "ExampleCo" },
599667 # (only works with AMAZON_SES_MESSAGE_TAG_NAME when using template):
600668 tags = ["WelcomeVariantA" ],
@@ -646,6 +714,21 @@ def test_template(self):
646714 ),
647715 {"name" : "Bob" },
648716 )
717+
718+ self .assertEqual (
719+ bulk_entries [0 ]["ReplacementHeaders" ],
720+ [
721+ {"Name" : "List-Unsubscribe" , "Value" : "<https://example.com/a/>" },
722+ {
723+ "Name" : "List-Unsubscribe-Post" ,
724+ "Value" : "List-Unsubscribe=One-Click" ,
725+ },
726+ ],
727+ )
728+ self .assertEqual (
729+ bulk_entries [1 ]["ReplacementHeaders" ],
730+ [],
731+ )
649732 self .assertEqual (
650733 json .loads (params ["DefaultContent" ]["Template" ]["TemplateData" ]),
651734 {"group" : "Users" , "site" : "ExampleCo" },
0 commit comments