mirror of https://github.com/zulip/zulip.git
send_custom_email: Add dry-run flag to verify recipients and email.
Add a `--dry-run` flag to send_custom_email management command in order to provide a mechanism to verify the emails of the recipients and the text of the email being sent before actually sending them. Add tests to: - Check that no emails are actually sent when we are in the dry-run mode. - Check if the emails are printed correctly when we are in the dry-run mode. Fixes #17767
This commit is contained in:
parent
9e19490c52
commit
a81c4b5e4c
|
@ -213,6 +213,7 @@ def send_email(
|
||||||
context: Dict[str, Any] = {},
|
context: Dict[str, Any] = {},
|
||||||
realm: Optional[Realm] = None,
|
realm: Optional[Realm] = None,
|
||||||
connection: Optional[BaseEmailBackend] = None,
|
connection: Optional[BaseEmailBackend] = None,
|
||||||
|
dry_run: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
mail = build_email(
|
mail = build_email(
|
||||||
template_prefix,
|
template_prefix,
|
||||||
|
@ -228,6 +229,10 @@ def send_email(
|
||||||
template = template_prefix.split("/")[-1]
|
template = template_prefix.split("/")[-1]
|
||||||
logger.info("Sending %s email to %s", template, mail.to)
|
logger.info("Sending %s email to %s", template, mail.to)
|
||||||
|
|
||||||
|
if dry_run:
|
||||||
|
print(mail.message().get_payload()[0])
|
||||||
|
return
|
||||||
|
|
||||||
if connection is None:
|
if connection is None:
|
||||||
connection = get_connection()
|
connection = get_connection()
|
||||||
# This will call .open() for us, which is a no-op if it's already open;
|
# This will call .open() for us, which is a no-op if it's already open;
|
||||||
|
@ -469,4 +474,8 @@ def send_custom_email(users: List[UserProfile], options: Dict[str, Any]) -> None
|
||||||
options.get("from_name"), parsed_email_template.get("from"), "from_name"
|
options.get("from_name"), parsed_email_template.get("from"), "from_name"
|
||||||
),
|
),
|
||||||
context=context,
|
context=context,
|
||||||
|
dry_run=options["dry_run"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if options["dry_run"]:
|
||||||
|
break
|
||||||
|
|
|
@ -37,6 +37,11 @@ class Command(ZulipBaseCommand):
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--admins-only", help="Send only to organization administrators", action="store_true"
|
"--admins-only", help="Send only to organization administrators", action="store_true"
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--dry-run",
|
||||||
|
action="store_true",
|
||||||
|
help="Prints emails of the recipients and text of the email.",
|
||||||
|
)
|
||||||
|
|
||||||
self.add_user_list_args(
|
self.add_user_list_args(
|
||||||
parser,
|
parser,
|
||||||
|
@ -60,3 +65,8 @@ class Command(ZulipBaseCommand):
|
||||||
raise error
|
raise error
|
||||||
|
|
||||||
send_custom_email(users, options)
|
send_custom_email(users, options)
|
||||||
|
|
||||||
|
if options["dry_run"]:
|
||||||
|
print("Would send the above email to:")
|
||||||
|
for user in users:
|
||||||
|
print(f" {user.email}")
|
||||||
|
|
|
@ -38,6 +38,7 @@ class TestCustomEmails(ZulipTestCase):
|
||||||
"reply_to": reply_to,
|
"reply_to": reply_to,
|
||||||
"subject": email_subject,
|
"subject": email_subject,
|
||||||
"from_name": from_name,
|
"from_name": from_name,
|
||||||
|
"dry_run": False,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
self.assertEqual(len(mail.outbox), 1)
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
|
@ -56,6 +57,7 @@ class TestCustomEmails(ZulipTestCase):
|
||||||
[hamlet],
|
[hamlet],
|
||||||
{
|
{
|
||||||
"markdown_template_path": markdown_template_path,
|
"markdown_template_path": markdown_template_path,
|
||||||
|
"dry_run": False,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
self.assertEqual(len(mail.outbox), 1)
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
|
@ -79,6 +81,7 @@ class TestCustomEmails(ZulipTestCase):
|
||||||
{
|
{
|
||||||
"markdown_template_path": markdown_template_path,
|
"markdown_template_path": markdown_template_path,
|
||||||
"from_name": from_name,
|
"from_name": from_name,
|
||||||
|
"dry_run": False,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -89,6 +92,7 @@ class TestCustomEmails(ZulipTestCase):
|
||||||
{
|
{
|
||||||
"markdown_template_path": markdown_template_path,
|
"markdown_template_path": markdown_template_path,
|
||||||
"subject": email_subject,
|
"subject": email_subject,
|
||||||
|
"dry_run": False,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -109,6 +113,7 @@ class TestCustomEmails(ZulipTestCase):
|
||||||
{
|
{
|
||||||
"markdown_template_path": markdown_template_path,
|
"markdown_template_path": markdown_template_path,
|
||||||
"subject": email_subject,
|
"subject": email_subject,
|
||||||
|
"dry_run": False,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -119,6 +124,7 @@ class TestCustomEmails(ZulipTestCase):
|
||||||
{
|
{
|
||||||
"markdown_template_path": markdown_template_path,
|
"markdown_template_path": markdown_template_path,
|
||||||
"from_name": from_name,
|
"from_name": from_name,
|
||||||
|
"dry_run": False,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -136,11 +142,31 @@ class TestCustomEmails(ZulipTestCase):
|
||||||
{
|
{
|
||||||
"markdown_template_path": markdown_template_path,
|
"markdown_template_path": markdown_template_path,
|
||||||
"admins_only": True,
|
"admins_only": True,
|
||||||
|
"dry_run": False,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
self.assertEqual(len(mail.outbox), 1)
|
self.assertEqual(len(mail.outbox), 1)
|
||||||
self.assertIn(admin_user.delivery_email, mail.outbox[0].to[0])
|
self.assertIn(admin_user.delivery_email, mail.outbox[0].to[0])
|
||||||
|
|
||||||
|
def test_send_custom_email_dry_run(self) -> None:
|
||||||
|
hamlet = self.example_user("hamlet")
|
||||||
|
email_subject = "subject_test"
|
||||||
|
reply_to = "reply_to_test"
|
||||||
|
from_name = "from_name_test"
|
||||||
|
markdown_template_path = "templates/zerver/tests/markdown/test_nested_code_blocks.md"
|
||||||
|
with patch("builtins.print") as _:
|
||||||
|
send_custom_email(
|
||||||
|
[hamlet],
|
||||||
|
{
|
||||||
|
"markdown_template_path": markdown_template_path,
|
||||||
|
"reply_to": reply_to,
|
||||||
|
"subject": email_subject,
|
||||||
|
"from_name": from_name,
|
||||||
|
"dry_run": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.assertEqual(len(mail.outbox), 0)
|
||||||
|
|
||||||
|
|
||||||
class TestFollowupEmails(ZulipTestCase):
|
class TestFollowupEmails(ZulipTestCase):
|
||||||
def test_day1_email_context(self) -> None:
|
def test_day1_email_context(self) -> None:
|
||||||
|
|
|
@ -569,3 +569,29 @@ class TestExport(ZulipTestCase):
|
||||||
call("\033[94mExporting realm\033[0m: zulip"),
|
call("\033[94mExporting realm\033[0m: zulip"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestSendCustomEmail(ZulipTestCase):
|
||||||
|
COMMAND_NAME = "send_custom_email"
|
||||||
|
|
||||||
|
def test_custom_email_with_dry_run(self) -> None:
|
||||||
|
path = "templates/zerver/tests/markdown/test_nested_code_blocks.md"
|
||||||
|
user = self.example_user("hamlet")
|
||||||
|
|
||||||
|
with patch("builtins.print") as mock_print:
|
||||||
|
call_command(
|
||||||
|
self.COMMAND_NAME,
|
||||||
|
"-r=zulip",
|
||||||
|
f"--path={path}",
|
||||||
|
f"-u={user.delivery_email}",
|
||||||
|
"--subject=Test email",
|
||||||
|
"--from-name=zulip@testserver.com",
|
||||||
|
"--dry-run",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
mock_print.mock_calls[1:],
|
||||||
|
[
|
||||||
|
call("Would send the above email to:"),
|
||||||
|
call(" user10@zulip.testserver"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue