Skip to content

Commit 8937680

Browse files
author
John Tordoff
committed
update moderation notification tests
1 parent c646a43 commit 8937680

File tree

3 files changed

+61
-147
lines changed

3 files changed

+61
-147
lines changed

osf_tests/test_registration_moderation_notifications.py

Lines changed: 59 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from notifications.tasks import send_users_digest_email, send_moderators_digest_email
77
from osf.management.commands.populate_notification_types import populate_notification_types
88
from osf.migrations import update_provider_auth_groups
9-
from osf.models import Brand, NotificationSubscription
9+
from osf.models import Brand, NotificationSubscription, NotificationType
1010
from osf.models.action import RegistrationAction
1111
from osf.utils.notifications import (
1212
notify_submit,
@@ -128,208 +128,122 @@ def withdraw_action(self, registration, admin):
128128
)
129129
return registration_action
130130

131-
def test_submit_notifications(self, registration, moderator, admin, contrib, provider, mock_send_grid):
131+
def test_submit_notifications(self, registration, moderator, admin, contrib, provider):
132132
"""
133133
[REQS-96] "As moderator of branded registry, I receive email notification upon admin author(s) submission approval"
134-
:param mock_email:
135-
:param draft_registration:
136-
:return:
137134
"""
138-
# Set up mock_send_mail as a pass-through to the original function.
139-
# This lets us assert on the call/args and also implicitly ensures
140-
# that the email acutally renders as normal in send_mail.
141-
notify_submit(registration, admin)
142-
143-
assert len(mock_send_grid.call_args_list) == 2
144-
admin_message, contrib_message = mock_send_grid.call_args_list
135+
with capture_notifications() as notification:
136+
notify_submit(registration, admin)
145137

146-
assert admin_message[1]['to_addr'] == admin.email
147-
assert contrib_message[1]['to_addr'] == contrib.email
148-
assert admin_message[1]['subject'] == 'Confirmation of your submission to OSF Registries'
149-
assert contrib_message[1]['subject'] == 'Confirmation of your submission to OSF Registries'
138+
assert len(notification['emits']) == 2
139+
assert notification['emits'][0]['type'] == NotificationType.Type.PROVIDER_NEW_PENDING_SUBMISSIONS
140+
assert notification['emits'][0]['kwargs']['user'] == admin
141+
assert notification['emits'][1]['type'] == NotificationType.Type.PROVIDER_NEW_PENDING_SUBMISSIONS
142+
assert notification['emits'][1]['kwargs']['user'] == contrib
150143

151144
assert NotificationSubscription.objects.count() == 1
152145
digest = NotificationSubscription.objects.last()
153-
154146
assert digest.user == moderator
155-
assert digest.send_type == 'email_transactional'
156-
assert digest.event == 'new_pending_submissions'
157-
158-
def test_accept_notifications(self, registration, moderator, admin, contrib, accept_action):
159-
"""
160-
[REQS-98] "As registration authors, we receive email notification upon moderator acceptance"
161-
:param draft_registration:
162-
:return:
163-
"""
164-
165-
# Set up mock_email as a pass-through to the original function.
166-
# This lets us assert on the call count/args and also implicitly
167-
# ensures that the email acutally renders correctly.
168-
with capture_notifications():
169-
notify_accept_reject(registration, registration.creator, accept_action, RegistrationModerationStates)
170-
171-
def test_reject_notifications(self, registration, moderator, admin, contrib, accept_action):
172-
"""
173-
[REQS-100] "As authors of rejected by moderator registration, we receive email notification of registration returned
174-
to draft state"
175-
:param draft_registration:
176-
:return:
177-
"""
178-
179-
# Set up mock_email as a pass-through to the original function.
180-
# This lets us assert on the call count/args and also implicitly
181-
# ensures that the email acutally renders correctly
182-
with capture_notifications():
183-
notify_accept_reject(registration, registration.creator, accept_action, RegistrationModerationStates)
184147

185-
def test_notify_moderator_registration_requests_withdrawal_notifications(self, moderator, daily_moderator, registration, admin, provider):
148+
def test_withdrawal_registration_accepted_notifications(
149+
self, registration_with_retraction, contrib, admin, withdraw_action
150+
):
186151
"""
187-
[REQS-106] "As moderator, I receive registration withdrawal request notification email"
188-
189-
:param mock_email:
190-
:param draft_registration:
191-
:param contrib:
192-
:return:
152+
[REQS-109] Authors receive notification when withdrawal is accepted.
153+
Compare recipients by user objects via captured emits.
193154
"""
194-
assert NotificationSubscription.objects.count() == 0
195-
notify_moderator_registration_requests_withdrawal(registration, admin)
196-
197-
assert NotificationSubscription.objects.count() == 2
155+
with capture_notifications() as notification:
156+
notify_withdraw_registration(registration_with_retraction, withdraw_action)
198157

199-
daily_digest = NotificationSubscription.objects.get(message_frequency='daily')
200-
transactional_digest = NotificationSubscription.objects.get(send_type='instantly')
201-
assert daily_digest.user == daily_moderator
202-
assert transactional_digest.user == moderator
158+
recipients = {rec['kwargs']['user'] for rec in notification['emits'] if 'user' in rec['kwargs']}
159+
assert {admin, contrib}.issubset(recipients)
203160

204-
for digest in (daily_digest, transactional_digest):
205-
assert 'requested withdrawal' in digest.message
206-
assert digest.event == 'new_pending_withdraw_requests'
207-
assert digest.provider == provider
208-
209-
def test_withdrawal_registration_accepted_notifications(self, registration_with_retraction, contrib, admin, withdraw_action, mock_send_grid):
161+
def test_notify_accept_reject(
162+
self, registration_with_retraction, contrib, admin, withdraw_action
163+
):
210164
"""
211-
[REQS-109] "As registration author(s) requesting registration withdrawal, we receive notification email of moderator
212-
decision"
213-
214-
:param mock_email:
215-
:param draft_registration:
216-
:param contrib:
217-
:return:
165+
[REQS-109] Authors receive notification when registration is accepted.
166+
Compare recipients by user objects via captured emits.
218167
"""
219-
# Set up mock_send_mail as a pass-through to the original function.
220-
# This lets us assert on the call count/args and also implicitly
221-
# ensures that the email acutally renders as normal in send_mail.
222-
notify_withdraw_registration(registration_with_retraction, withdraw_action)
168+
with capture_notifications() as notification:
169+
notify_accept_reject(registration_with_retraction, contrib)
223170

224-
assert len(mock_send_grid.call_args_list) == 2
225-
admin_message, contrib_message = mock_send_grid.call_args_list
171+
recipients = {rec['kwargs']['user'] for rec in notification['emits'] if 'user' in rec['kwargs']}
172+
assert {admin, contrib}.issubset(recipients)
226173

227-
assert admin_message[1]['to_addr'] == admin.email
228-
assert contrib_message[1]['to_addr'] == contrib.email
229-
assert admin_message[1]['subject'] == 'Your registration has been withdrawn'
230-
assert contrib_message[1]['subject'] == 'Your registration has been withdrawn'
231-
232-
def test_withdrawal_registration_rejected_notifications(self, registration, contrib, admin, withdraw_request_action, mock_send_grid):
174+
def test_withdrawal_registration_rejected_notifications(
175+
self, registration, contrib, admin, withdraw_request_action
176+
):
233177
"""
234-
[REQS-109] "As registration author(s) requesting registration withdrawal, we receive notification email of moderator
235-
decision"
236-
237-
:param mock_email:
238-
:param draft_registration:
239-
:param contrib:
240-
:return:
178+
[REQS-109] Authors receive notification when withdrawal is rejected.
179+
Compare recipients by user objects via captured emits.
241180
"""
242-
# Set up mock_send_mail as a pass-through to the original function.
243-
# This lets us assert on the call count/args and also implicitly
244-
# ensures that the email acutally renders as normal in send_mail.
245-
notify_reject_withdraw_request(registration, withdraw_request_action)
246-
247-
assert len(mock_send_grid.call_args_list) == 2
248-
admin_message, contrib_message = mock_send_grid.call_args_list
181+
with capture_notifications() as notification:
182+
notify_reject_withdraw_request(registration, withdraw_request_action)
249183

250-
assert admin_message[1]['to_addr'] == admin.email
251-
assert contrib_message[1]['to_addr'] == contrib.email
252-
assert admin_message[1]['subject'] == 'Your withdrawal request has been declined'
253-
assert contrib_message[1]['subject'] == 'Your withdrawal request has been declined'
184+
recipients = {rec['kwargs']['user'] for rec in notification['emits'] if 'user' in rec['kwargs']}
185+
assert {admin, contrib}.issubset(recipients)
254186

255-
def test_withdrawal_registration_force_notifications(self, registration_with_retraction, contrib, admin, withdraw_action, mock_send_grid):
187+
def test_withdrawal_registration_force_notifications(
188+
self, registration_with_retraction, contrib, admin, withdraw_action
189+
):
256190
"""
257-
[REQS-109] "As registration author(s) requesting registration withdrawal, we receive notification email of moderator
258-
decision"
259-
260-
:param mock_email:
261-
:param draft_registration:
262-
:param contrib:
263-
:return:
191+
[REQS-109] Forced withdrawal route: compare recipients by user objects via captured emits.
264192
"""
265-
# Set up mock_send_mail as a pass-through to the original function.
266-
# This lets us assert on the call count/args and also implicitly
267-
# ensures that the email acutally renders as normal in send_mail.
268-
notify_withdraw_registration(registration_with_retraction, withdraw_action)
269-
270-
assert len(mock_send_grid.call_args_list) == 2
271-
admin_message, contrib_message = mock_send_grid.call_args_list
193+
with capture_notifications() as notification:
194+
notify_withdraw_registration(registration_with_retraction, withdraw_action)
272195

273-
assert admin_message[1]['to_addr'] == admin.email
274-
assert contrib_message[1]['to_addr'] == contrib.email
275-
assert admin_message[1]['subject'] == 'Your registration has been withdrawn'
276-
assert contrib_message[1]['subject'] == 'Your registration has been withdrawn'
196+
recipients = {rec['kwargs']['user'] for rec in notification['emits'] if 'user' in rec['kwargs']}
197+
assert {admin, contrib}.issubset(recipients)
277198

278199
@pytest.mark.parametrize(
279200
'digest_type, expected_recipient',
280201
[('email_transactional', get_moderator), ('email_digest', get_daily_moderator)]
281202
)
282-
def test_submissions_and_withdrawals_both_appear_in_moderator_digest(self, digest_type, expected_recipient, registration, admin, provider, mock_send_grid):
203+
def test_submissions_and_withdrawals_both_appear_in_moderator_digest(
204+
self, digest_type, expected_recipient, registration, admin, provider
205+
):
283206
# Invoke the fixture function to get the recipient because parametrize
284207
expected_recipient = expected_recipient(provider)
285208

286-
notify_submit(registration, admin)
287-
notify_moderator_registration_requests_withdrawal(registration, admin)
209+
with capture_notifications():
210+
notify_submit(registration, admin)
211+
notify_moderator_registration_requests_withdrawal(registration, admin)
288212

289-
# One user, one provider => one email
213+
# One user, one provider => one email/digest row saved for moderator
290214
grouped_notifications = list(NotificationSubscription.objects.filter(user=admin))
291215
assert len(grouped_notifications) == 1
292216

293217
moderator_message = grouped_notifications[0]
294218
assert moderator_message['user_id'] == expected_recipient._id
295219
assert moderator_message['provider_id'] == provider.id
296220

297-
# No fixed ordering of the entires, so just make sure that
298-
# keywords for each action type are in some message
299221
updates = moderator_message['info']
300222
assert len(updates) == 2
301223
assert any('submitted' in entry['message'] for entry in updates)
302224
assert any('requested withdrawal' in entry['message'] for entry in updates)
303225

304226
@pytest.mark.parametrize('digest_type', ['email_transactional', 'email_digest'])
305-
def test_submsissions_and_withdrawals_do_not_appear_in_node_digest(self, digest_type, registration, admin, moderator, daily_moderator):
306-
notify_submit(registration, admin)
307-
notify_moderator_registration_requests_withdrawal(registration, admin)
227+
def test_submsissions_and_withdrawals_do_not_appear_in_node_digest(
228+
self, digest_type, registration, admin, moderator, daily_moderator
229+
):
230+
with capture_notifications():
231+
notify_submit(registration, admin)
232+
notify_moderator_registration_requests_withdrawal(registration, admin)
308233

309234
assert not list(NotificationSubscription.objects.filter(user=admin))
310235

311-
def test_moderator_digest_emails_render(self, registration, admin, moderator, mock_send_grid):
312-
notify_moderator_registration_requests_withdrawal(registration, admin)
313-
# Set up mock_send_mail as a pass-through to the original function.
314-
# This lets us assert on the call count/args and also implicitly
315-
# ensures that the email acutally renders as normal in send_mail.
236+
def test_moderator_digest_emails_render(self, registration, admin, moderator):
316237
with capture_notifications():
238+
notify_moderator_registration_requests_withdrawal(registration, admin)
317239
send_users_digest_email()
318240

319241
def test_branded_provider_notification_renders(self, registration, admin, moderator):
320-
# Set brand details to be checked in notify_base.mako
321242
provider = registration.provider
322243
provider.brand = Brand.objects.create(hero_logo_image='not-a-url', primary_color='#FFA500')
323244
provider.name = 'Test Provider'
324245
provider.save()
325246

326-
# Implicitly check that all of our uses of notify_base.mako render with branded details:
327-
#
328-
# notify_submit renders reviews_submission_confirmation using context from
329-
# osf.utils.notifications and stores emails to be picked up in the moderator digest
330-
#
331-
# _send_Reviews_moderator_emails renders digest_reviews_moderators using context from
332-
# website.notifications.tasks
333247
with capture_notifications():
334248
notify_submit(registration, admin)
335249
send_moderators_digest_email()

website/templates/updates_pending_approval.html.mako

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
You submitted updates for ${resource_type} <a href="${parent_url}">"${title}"</a>
1010
for Admin approval.
1111
% else:
12-
${initiator} submitted updates for ${resource_type} <a href="${parent_url}">"${title}"</a>
12+
${initiator_fullname} submitted updates for ${resource_type} <a href="${parent_url}">"${title}"</a>
1313
for Admin approval.
1414
% endif
1515
<p>

website/templates/updates_rejected.html.mako

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
% if is_initiator:
99
You did not accept the updates for ${resource_type} <a href="${parent_url}">"${title}"</a>.
1010
% else:
11-
${initiator} did not accept the updates for ${resource_type} <a href="${parent_url}">"${title}"</a>.
11+
${initiator_fullname} did not accept the updates for ${resource_type} <a href="${parent_url}">"${title}"</a>.
1212
% endif
1313
<p>
1414
% if can_write:

0 commit comments

Comments
 (0)