|
2 | 2 | # -*- coding: utf-8 -*- |
3 | 3 |
|
4 | 4 |
|
| 5 | +import mock |
5 | 6 | from pyquery import PyQuery |
6 | 7 |
|
| 8 | +from django.test.utils import override_settings |
7 | 9 | from django.urls import reverse as urlreverse |
8 | 10 |
|
9 | 11 | import debug # pyflakes:ignore |
10 | 12 |
|
11 | 13 | from ietf.community.models import CommunityList, SearchRule, EmailSubscription |
12 | 14 | from ietf.community.utils import docs_matching_community_list_rule, community_list_rules_matching_doc |
13 | | -from ietf.community.utils import reset_name_contains_index_for_rule |
| 15 | +from ietf.community.utils import reset_name_contains_index_for_rule, notify_event_to_subscribers |
| 16 | +from ietf.community.tasks import notify_event_to_subscribers_task |
14 | 17 | import ietf.community.views |
15 | 18 | from ietf.group.models import Group |
16 | 19 | from ietf.group.utils import setup_default_community_list_for_group |
17 | 20 | from ietf.doc.models import State |
18 | 21 | from ietf.doc.utils import add_state_change_event |
19 | 22 | from ietf.person.models import Person, Email, Alias |
20 | 23 | from ietf.utils.test_utils import TestCase, login_testing_unauthorized |
21 | | -from ietf.utils.mail import outbox |
22 | | -from ietf.doc.factories import WgDraftFactory |
| 24 | +from ietf.doc.factories import DocEventFactory, WgDraftFactory |
23 | 25 | from ietf.group.factories import GroupFactory, RoleFactory |
24 | 26 | from ietf.person.factories import PersonFactory, EmailFactory, AliasFactory |
25 | 27 |
|
@@ -423,26 +425,105 @@ def test_subscription_for_group(self): |
423 | 425 | r = self.client.get(url) |
424 | 426 | self.assertEqual(r.status_code, 200) |
425 | 427 |
|
426 | | - def test_notification(self): |
| 428 | + @mock.patch("ietf.community.models.notify_event_to_subscribers_task") |
| 429 | + def test_notification_signal_receiver(self, mock_notify_task): |
| 430 | + """Saving a DocEvent should notify subscribers |
| 431 | + |
| 432 | + This implicitly tests that notify_events is hooked up to the post_save signal. |
| 433 | + """ |
| 434 | + # Arbitrary model that's not a DocEvent |
| 435 | + p = PersonFactory() |
| 436 | + mock_notify_task.reset_mock() # clear any calls that resulted from the factories |
| 437 | + # be careful overriding SERVER_MODE - we do it here because the method |
| 438 | + # under test does not make this call when in "test" mode |
| 439 | + with override_settings(SERVER_MODE="not-test"): |
| 440 | + p.save() |
| 441 | + self.assertFalse(mock_notify_task.delay.called) |
| 442 | + |
| 443 | + d = DocEventFactory() |
| 444 | + mock_notify_task.reset_mock() # clear any calls that resulted from the factories |
| 445 | + # be careful overriding SERVER_MODE - we do it here because the method |
| 446 | + # under test does not make this call when in "test" mode |
| 447 | + with override_settings(SERVER_MODE="not-test"): |
| 448 | + d.save() |
| 449 | + self.assertEqual(mock_notify_task.delay.call_count, 1) |
| 450 | + self.assertEqual(mock_notify_task.delay.call_args, mock.call(event_id = d.pk)) |
| 451 | + |
| 452 | + mock_notify_task.reset_mock() |
| 453 | + d.skip_community_list_notification = True |
| 454 | + # be careful overriding SERVER_MODE - we do it here because the method |
| 455 | + # under test does not make this call when in "test" mode |
| 456 | + with override_settings(SERVER_MODE="not-test"): |
| 457 | + d.save() |
| 458 | + self.assertFalse(mock_notify_task.delay.called) |
| 459 | + |
| 460 | + del(d.skip_community_list_notification) |
| 461 | + d.doc.type_id="rfc" # not "draft" |
| 462 | + d.doc.save() |
| 463 | + # be careful overriding SERVER_MODE - we do it here because the method |
| 464 | + # under test does not make this call when in "test" mode |
| 465 | + with override_settings(SERVER_MODE="not-test"): |
| 466 | + d.save() |
| 467 | + self.assertFalse(mock_notify_task.delay.called) |
| 468 | + |
| 469 | + @mock.patch("ietf.utils.mail.send_mail_text") |
| 470 | + def test_notify_event_to_subscribers(self, mock_send_mail_text): |
427 | 471 | person = PersonFactory(user__username='plain') |
428 | 472 | draft = WgDraftFactory() |
429 | 473 |
|
430 | 474 | clist = CommunityList.objects.create(person=person) |
431 | 475 | if not draft in clist.added_docs.all(): |
432 | 476 | clist.added_docs.add(draft) |
433 | 477 |
|
434 | | - EmailSubscription.objects.create(community_list=clist, email=Email.objects.filter(person__user__username="plain").first(), notify_on="significant") |
| 478 | + sub_to_significant = EmailSubscription.objects.create( |
| 479 | + community_list=clist, |
| 480 | + email=Email.objects.filter(person__user__username="plain").first(), |
| 481 | + notify_on="significant", |
| 482 | + ) |
| 483 | + sub_to_all = EmailSubscription.objects.create( |
| 484 | + community_list=clist, |
| 485 | + email=Email.objects.filter(person__user__username="plain").first(), |
| 486 | + notify_on="all", |
| 487 | + ) |
435 | 488 |
|
436 | | - mailbox_before = len(outbox) |
437 | 489 | active_state = State.objects.get(type="draft", slug="active") |
438 | 490 | system = Person.objects.get(name="(System)") |
439 | | - add_state_change_event(draft, system, None, active_state) |
440 | | - self.assertEqual(len(outbox), mailbox_before) |
| 491 | + event = add_state_change_event(draft, system, None, active_state) |
| 492 | + notify_event_to_subscribers(event) |
| 493 | + self.assertEqual(mock_send_mail_text.call_count, 1) |
| 494 | + address = mock_send_mail_text.call_args[0][1] |
| 495 | + subject = mock_send_mail_text.call_args[0][3] |
| 496 | + content = mock_send_mail_text.call_args[0][4] |
| 497 | + self.assertEqual(address, sub_to_all.email.address) |
| 498 | + self.assertIn(draft.name, subject) |
| 499 | + self.assertIn(clist.long_name(), content) |
441 | 500 |
|
442 | | - mailbox_before = len(outbox) |
443 | 501 | rfc_state = State.objects.get(type="draft", slug="rfc") |
444 | | - add_state_change_event(draft, system, active_state, rfc_state) |
445 | | - self.assertEqual(len(outbox), mailbox_before + 1) |
446 | | - self.assertTrue(draft.name in outbox[-1]["Subject"]) |
447 | | - |
448 | | - |
| 502 | + event = add_state_change_event(draft, system, active_state, rfc_state) |
| 503 | + mock_send_mail_text.reset_mock() |
| 504 | + notify_event_to_subscribers(event) |
| 505 | + self.assertEqual(mock_send_mail_text.call_count, 2) |
| 506 | + addresses = [call_args[0][1] for call_args in mock_send_mail_text.call_args_list] |
| 507 | + subjects = {call_args[0][3] for call_args in mock_send_mail_text.call_args_list} |
| 508 | + contents = {call_args[0][4] for call_args in mock_send_mail_text.call_args_list} |
| 509 | + self.assertCountEqual( |
| 510 | + addresses, |
| 511 | + [sub_to_significant.email.address, sub_to_all.email.address], |
| 512 | + ) |
| 513 | + self.assertEqual(len(subjects), 1) |
| 514 | + self.assertIn(draft.name, subjects.pop()) |
| 515 | + self.assertEqual(len(contents), 1) |
| 516 | + self.assertIn(clist.long_name(), contents.pop()) |
| 517 | + |
| 518 | + @mock.patch("ietf.community.utils.notify_event_to_subscribers") |
| 519 | + def test_notify_event_to_subscribers_task(self, mock_notify): |
| 520 | + d = DocEventFactory() |
| 521 | + notify_event_to_subscribers_task(event_id=d.pk) |
| 522 | + self.assertEqual(mock_notify.call_count, 1) |
| 523 | + self.assertEqual(mock_notify.call_args, mock.call(d)) |
| 524 | + mock_notify.reset_mock() |
| 525 | + |
| 526 | + d.delete() |
| 527 | + notify_event_to_subscribers_task(event_id=d.pk) |
| 528 | + self.assertFalse(mock_notify.called) |
| 529 | + |
0 commit comments