diff --git a/helpdesk/management/commands/get_email.py b/helpdesk/management/commands/get_email.py index fda915df..12979ccc 100644 --- a/helpdesk/management/commands/get_email.py +++ b/helpdesk/management/commands/get_email.py @@ -35,6 +35,7 @@ from django.utils import encoding, six, timezone from helpdesk import settings from helpdesk.lib import send_templated_mail, safe_template_context, process_attachments from helpdesk.models import Queue, Ticket, TicketCC, FollowUp, IgnoreEmail +from django.contrib.auth.models import User import logging @@ -382,9 +383,21 @@ def ticket_from_message(message, queue, logger): if t.assigned_to: other_emails.append(t.assigned_to.email) current_cc = set(current_cc_emails + current_cc_users + other_emails) - # add any email in cc that's not already in current_cc (set difference) - new_cc = cc.difference(current_cc) - # add emails alphabetically, makes testing easy + # first, add any User not previously CC'd (as identified by User's email) + all_users = User.objects.all() + all_user_emails = set([x.email for x in all_users]) + users_not_currently_ccd = all_user_emails.difference(set(current_cc)) + users_to_cc = cc.intersection( users_not_currently_ccd ) + for user in users_to_cc: + tcc = TicketCC.objects.create( + ticket=t, + user=User.objects.get(email=user), + can_view=True, + can_update=False + ) + tcc.save() + # then add remaining emails alphabetically, makes testing easy + new_cc = cc.difference(current_cc).difference(all_user_emails) new_cc = sorted(list(new_cc)) for ccemail in new_cc: tcc = TicketCC.objects.create( diff --git a/helpdesk/tests/test_get_email.py b/helpdesk/tests/test_get_email.py index f6d51a1e..381388c7 100644 --- a/helpdesk/tests/test_get_email.py +++ b/helpdesk/tests/test_get_email.py @@ -367,6 +367,7 @@ class GetEmailCCHandling(TestCase): "slug": 'CC', "allow_public_submission": True, "allow_email_submission": True, + "email_address": 'queue@example.com', "email_box_type": 'local', "email_box_local_dir": '/var/lib/mail/helpdesk/', "logging_dir": self.temp_logdir, @@ -394,6 +395,16 @@ class GetEmailCCHandling(TestCase): } self.assigned_user = User.objects.create(**user2_kwargs) + user3_kwargs = { + 'username': 'observer', + 'email': 'observer@example.com', + 'password': make_password('Test1234'), + 'is_staff': True, + 'is_superuser': False, + 'is_active': True + } + self.observer_user = User.objects.create(**user3_kwargs) + ticket_kwargs = { 'title': 'Original Ticket', 'queue': self.queue_public, @@ -426,9 +437,12 @@ class GetEmailCCHandling(TestCase): self.assertEqual(ticket1.title, "Original Ticket") # only the staff_user is CC'd for now self.assertEqual(len(TicketCC.objects.filter(ticket=1)), 1) + ccstaff = get_object_or_404(TicketCC, pk=1) + self.assertEqual(ccstaff.user, User.objects.get(username='staff')) + self.assertEqual(ticket1.assigned_to, User.objects.get(username='assigned')) # example email text from Django docs: https://docs.djangoproject.com/en/1.10/ref/unicode/ - test_email_from = "Arnbjörg Ráðormsdóttir " + test_email_from = "submitter@example.com" # NOTE: CC emails are in alphabetical order and must be tested as such! # implementation uses sets, so only way to ensure tickets created # in right order is to change set to list and sort it @@ -436,10 +450,10 @@ class GetEmailCCHandling(TestCase): test_email_cc_two = "nobody@example.com" test_email_cc_three = "other@example.com" test_email_cc_four = "someone@example.com" - ticket_user_emails = "assigned@example.com, staff@example.com, submitter@example.com" + ticket_user_emails = "assigned@example.com, staff@example.com, submitter@example.com, observer@example.com, queue@example.com" test_email_subject = "[CC-1] My visit to Sør-Trøndelag" test_email_body = "Unicode helpdesk comment with an s-hat (ŝ) via email." - test_email = "To: helpdesk@example.com\nCc: " + test_email_cc_one + ", " + test_email_cc_one + ", " + test_email_cc_two + ", " + test_email_cc_three + "\nCC: " + test_email_cc_one + ", " + test_email_cc_three + ", " + test_email_cc_four + ", " + ticket_user_emails + "\nFrom: " + test_email_from + "\nSubject: " + test_email_subject + "\n\n" + test_email_body + test_email = "To: queue@example.com\nCc: " + test_email_cc_one + ", " + test_email_cc_one + ", " + test_email_cc_two + ", " + test_email_cc_three + "\nCC: " + test_email_cc_one + ", " + test_email_cc_three + ", " + test_email_cc_four + ", " + ticket_user_emails + "\nFrom: " + test_email_from + "\nSubject: " + test_email_subject + "\n\n" + test_email_body test_mail_len = len(test_email) with mock.patch('helpdesk.management.commands.get_email.listdir') as mocked_listdir, \ @@ -453,22 +467,25 @@ class GetEmailCCHandling(TestCase): mocked_listdir.assert_called_with('/var/lib/mail/helpdesk/') mocked_isfile.assert_any_call('/var/lib/mail/helpdesk/filename1') - # next we make sure no duplicates were added, and the - # staff users nor submitter were not re-added as email TicketCCs - cc1 = get_object_or_404(TicketCC, pk=2) - self.assertEqual(cc1.email, test_email_cc_one) - cc2 = get_object_or_404(TicketCC, pk=3) - self.assertEqual(cc2.email, test_email_cc_two) - cc3 = get_object_or_404(TicketCC, pk=4) - self.assertEqual(cc3.email, test_email_cc_three) - cc4 = get_object_or_404(TicketCC, pk=5) - self.assertEqual(cc4.email, test_email_cc_four) # ensure these 4 CCs (test_email_cc one thru four) are the only ones # created and added to the existing staff_user that was CC'd, + # and the observer user that gets CC'd to new email., # and that submitter and assignee are not added as CC either # (in other words, even though everyone was CC'd to this email, - # we should come out with only 5 CCs after filtering) - self.assertEqual(len(TicketCC.objects.filter(ticket=1)), 5) + # we should come out with only 6 CCs after filtering) + self.assertEqual(len(TicketCC.objects.filter(ticket=1)), 6) + # next we make sure no duplicates were added, and the + # staff users nor submitter were not re-added as email TicketCCs + cc0 = get_object_or_404(TicketCC, pk=2) + self.assertEqual(cc0.user, User.objects.get(username='observer')) + cc1 = get_object_or_404(TicketCC, pk=3) + self.assertEqual(cc1.email, test_email_cc_one) + cc2 = get_object_or_404(TicketCC, pk=4) + self.assertEqual(cc2.email, test_email_cc_two) + cc3 = get_object_or_404(TicketCC, pk=5) + self.assertEqual(cc3.email, test_email_cc_three) + cc4 = get_object_or_404(TicketCC, pk=6) + self.assertEqual(cc4.email, test_email_cc_four) # build matrix of test cases