From 4e9ca9127e760527823a588f5bb4edac0d85c34d Mon Sep 17 00:00:00 2001 From: Todd Dembrey <todd.dembrey@torchbox.com> Date: Mon, 30 Jul 2018 09:53:24 +0100 Subject: [PATCH] Refactor to control recipients better --- opentech/apply/activity/messaging.py | 83 ++++++++++--------- .../apply/activity/tests/test_messaging.py | 18 ++-- 2 files changed, 57 insertions(+), 44 deletions(-) diff --git a/opentech/apply/activity/messaging.py b/opentech/apply/activity/messaging.py index b17d599d5..b63021282 100644 --- a/opentech/apply/activity/messaging.py +++ b/opentech/apply/activity/messaging.py @@ -50,19 +50,27 @@ class AdapterBase: def render_message(self, message, **kwargs): return message.format(**kwargs) + def extra_kwargs(self, message_type, **kwargs): + return {} + + def recipients(self, message_type, **kwargs): + raise NotImplementedError() + def process(self, message_type, **kwargs): message = self.message(message_type, **kwargs) - kwargs.update(self.extra_kwargs(message_type, **kwargs)) - if not message: return - if settings.SEND_MESSAGES or self.always_send: - self.send_message(message, **kwargs) + recipients = self.recipients(message_type, **kwargs) + kwargs.update(self.extra_kwargs(message_type, **kwargs)) + + for recipient in recipients: + if settings.SEND_MESSAGES or self.always_send: + self.send_message(message, recipient=recipient, **kwargs) - if not settings.SEND_MESSAGES: - message = self.adapter_type + ': ' + message - messages.add_message(kwargs['request'], messages.INFO, message) + if not settings.SEND_MESSAGES: + message = self.adapter_type + ': ' + message + messages.add_message(kwargs['request'], messages.INFO, message) def send_message(self, message, **kwargs): raise NotImplementedError() @@ -81,6 +89,9 @@ class ActivityAdapter(AdapterBase): MESSAGES.NEW_REVIEW: '{user} submitted a review' } + def recipients(self, message_type, **kwargs): + return [None] + def reviewers_updated(self, added, removed, **kwargs): message = ['Reviewers updated.'] if added: @@ -122,23 +133,15 @@ class SlackAdapter(AdapterBase): self.destination = settings.SLACK_DESTINATION_URL self.target_room = settings.SLACK_DESTINATION_ROOM - def message(self, message_type, **kwargs): - message = super().message(message_type, **kwargs) - - user = kwargs['user'] - submission = kwargs['submission'] - - slack_target = self.slack_id(submission.lead) - - message = ' '.join([slack_target, message]).strip() - return message - def extra_kwargs(self, message_type, **kwargs): submission = kwargs['submission'] request = kwargs['request'] link = link_to(submission, request) return {'link': link} + def recipients(self, message_type, message, **kwargs): + return [self.slack_id(submission.lead)] + def notify_reviewers(self, submission, **kwargs): reviewers_to_notify = [] for reviewer in submission.reviewers.all(): @@ -162,10 +165,12 @@ class SlackAdapter(AdapterBase): return f'<{user.slack}>' return '' - def send_message(self, message, **kwargs): + def send_message(self, message, recipient, **kwargs): if not self.destination or not self.target_room: return + message = ' '.join([recipient, message]).strip() + data = { "room": self.target_room, "message": message, @@ -183,22 +188,29 @@ class EmailAdapter(AdapterBase): MESSAGES.INVITED_TO_PROPOSAL: 'messages/email/invited_to_proposal.html', MESSAGES.READY_FOR_REVIEW: 'messages/email/ready_to_review.html', } - recipients = { - MESSAGES.READY_FOR_REVIEW: 'get_reviewers', - } + + def extra_kwargs(self, message_type, submission, **kwargs): + if message_type == MESSAGES.READY_FOR_REVIEW: + subject = 'Application ready to review: {submission.title}'.format(submission=submission) + else: + subject = submission.page.specific.subject or 'Your application to Open Technology Fund: {submission.title}'.format(submission=submission) + return { + 'subject': subject, + } def notify_comment(self, **kwargs): comment = kwargs['comment'] if not comment.private: return self.render_message('messages/email/comment.html', **kwargs) - def get_recipients(self, submission): - try: - return getattr(self, self.recipients['']) + def recipients(self, message_type, submission, **kwargs): + if message_type == MESSAGES.READY_FOR_REVIEW: + return self.reviewers(submission) + return [submission.user.email] - def get_reviewers(self, ) + def reviewers(self, submission): return [ - [reviewer.email] + reviewer.email for reviewer in submission.reviewers.all() if submission.phase.permissions.can_review(reviewer) ] @@ -206,16 +218,13 @@ class EmailAdapter(AdapterBase): def render_message(self, template, **kwargs): return render_to_string(template, kwargs) - def send_message(self, message, submission, **kwargs): - subject = submission.page.specific.subject or 'Your application to Open Technology Fund: {submission.title}'.format(submission=submission) - recipients = self.get_recipients(submission) or [(submission.user.email,)] - for recipient in recipients: - send_mail( - subject, - message, - submission.page.specific.from_address, - recipient, - ) + def send_message(self, message, submission, subject, recipient, **kwargs): + send_mail( + subject, + message, + submission.page.specific.from_address, + [recipient], + ) class MessengerBackend: diff --git a/opentech/apply/activity/tests/test_messaging.py b/opentech/apply/activity/tests/test_messaging.py index a27299f51..41ba22622 100644 --- a/opentech/apply/activity/tests/test_messaging.py +++ b/opentech/apply/activity/tests/test_messaging.py @@ -33,6 +33,9 @@ class TestAdapter(AdapterBase): def send_message(self, message, **kwargs): pass + def recipients(self, message_type, **kwargs): + return [message_type] + @override_settings(SEND_MESSAGES=True) class TestBaseAdapter(TestCase): @@ -46,7 +49,7 @@ class TestBaseAdapter(TestCase): message_type = MESSAGES.UPDATE_LEAD self.adapter.process(message_type) - self.adapter.send_message.assert_called_once_with(message_type.value) + self.adapter.send_message.assert_called_once_with(message_type.value, recipient=message_type) def test_doesnt_send_a_message_if_not_configured(self): self.adapter.process('this_is_not_a_message_type') @@ -61,14 +64,14 @@ class TestBaseAdapter(TestCase): self.adapter.process(method_name) - self.adapter.send_message.assert_called_once_with(return_message) + self.adapter.send_message.assert_called_once_with(return_message, recipient=method_name) def test_that_kwargs_passed_to_send_message(self): message_type = MESSAGES.UPDATE_LEAD kwargs = {'test': 'that', 'these': 'exist'} self.adapter.process(message_type, **kwargs) - self.adapter.send_message.assert_called_once_with(message_type.value, **kwargs) + self.adapter.send_message.assert_called_once_with(message_type.value, recipient=message_type, **kwargs) def test_that_message_is_formatted(self): message_type = MESSAGES.UPDATE_LEAD @@ -77,7 +80,7 @@ class TestBaseAdapter(TestCase): self.adapter.process(message_type, message_to_format=message) - self.adapter.send_message.assert_called_once_with(message, message_to_format=message) + self.adapter.send_message.assert_called_once_with(message, message_to_format=message, recipient=message_type) @override_settings(SEND_MESSAGES=False) def test_django_messages_used(self): @@ -168,7 +171,7 @@ class TestSlackAdapter(TestCase): @responses.activate def test_cant_send_with_no_room(self): adapter = SlackAdapter() - adapter.send_message('my message') + adapter.send_message('my message', '') self.assertEqual(len(responses.calls), 0) @override_settings( @@ -178,7 +181,7 @@ class TestSlackAdapter(TestCase): @responses.activate def test_cant_send_with_no_url(self): adapter = SlackAdapter() - adapter.send_message('my message') + adapter.send_message('my message', '') self.assertEqual(len(responses.calls), 0) @override_settings( @@ -190,7 +193,7 @@ class TestSlackAdapter(TestCase): responses.add(responses.POST, self.target_url, status=200) adapter = SlackAdapter() message = 'my message' - adapter.send_message(message) + adapter.send_message(message, '') self.assertEqual(len(responses.calls), 1) self.assertDictEqual( json.loads(responses.calls[0].request.body), @@ -218,3 +221,4 @@ class TestEmailAdapter(TestCase): adapter.process(MESSAGES.READY_FOR_REVIEW, submission=submission) self.assertEqual(len(mail.outbox), 4) + self.assertTrue(mail.outbox[0].subject, 'ready to review') -- GitLab