コード例 #1
0
class TestApplicationConversationModel(APITestCase):
    def setUp(self):
        self.applicant = VerifiedUserFactory()
        self.member = VerifiedUserFactory()
        self.group = GroupFactory(members=[self.member])
        self.application = ApplicationFactory(group=self.group, user=self.applicant)
        self.conversation = Conversation.objects.get_for_target(self.application)

    def test_member_leaves_group(self):
        GroupMembership.objects.filter(user=self.member, group=self.group).delete()
        self.assertNotIn(
            self.member,
            self.conversation.participants.all(),
        )

    def test_user_erased(self):
        self.applicant.refresh_from_db()  # otherwise user.photo.name is None
        self.applicant.erase()

        self.application.refresh_from_db()
        self.assertEqual(self.application.status, ApplicationStatus.WITHDRAWN.value)

    def test_deleting_application_deletes_conversation(self):
        Application.objects.filter(user=self.applicant, group=self.group).delete()
        self.assertIsNone(Conversation.objects.get_for_target(self.application))

    def test_sets_group(self):
        self.assertEqual(self.conversation.group, self.group)

    def test_withdraw_pending_application_when_user_joins_group(self):
        self.group.add_member(self.applicant)

        self.application.refresh_from_db()
        self.assertEqual(self.application.status, ApplicationStatus.WITHDRAWN.value)
コード例 #2
0
class GroupConversationReceiverPushTests(TransactionTestCase):
    def setUp(self):
        self.group = GroupFactory()
        self.user = UserFactory()
        self.author = UserFactory()
        self.group.add_member(self.user)
        self.group.add_member(self.author)

        self.token = faker.uuid4()
        self.content = faker.text()

        self.conversation = self.group.conversation

        # add a push subscriber
        self.subscription = PushSubscription.objects.create(
            user=self.user,
            token=self.token,
            platform=PushSubscriptionPlatform.ANDROID.value,
        )

    def test_sends_to_push_subscribers(self, notify_subscribers):
        # add a message to the conversation
        ConversationMessage.objects.create(conversation=self.conversation,
                                           content=self.content,
                                           author=self.author)

        self.assertEqual(notify_subscribers.call_count, 2)
        kwargs = notify_subscribers.call_args_list[0][1]
        self.assertEqual(list(kwargs['subscriptions']), [self.subscription])
        self.assertEqual(kwargs['fcm_options']['message_title'],
                         self.group.name + ' / ' + self.author.display_name)
        self.assertEqual(kwargs['fcm_options']['message_body'], self.content)
コード例 #3
0
    def test_creates_new_member_notification(self):
        member1 = UserFactory()
        member2 = UserFactory()
        group = GroupFactory(members=[member1, member2])
        Notification.objects.all().delete()

        user = UserFactory()
        group.add_member(user, added_by=member1)

        notifications = Notification.objects.filter(
            type=NotificationType.NEW_MEMBER.value)
        # member1 doesn't get a notification, as they added the user
        self.assertEqual(notifications.count(), 1, notifications)
        self.assertEqual(notifications[0].user, member2)
        self.assertEqual(notifications[0].context['user'], user.id)
コード例 #4
0
class TestSendStatistics(TestCase):
    def setUp(self):
        self.user = UserFactory()
        self.member = UserFactory()
        self.group = GroupFactory(members=[self.member])

    @patch('karrot.groups.stats.write_points')
    def test_send_group_join_stats(self, write_mock):
        self.group.add_member(self.user)
        self.assertTrue(write_mock.called)

    @patch('karrot.groups.stats.write_points')
    def test_non_send_group_join_stats_on_update(self, write_mock):
        membership = GroupMembership.objects.get(group=self.group, user=self.member)
        membership.inactive_at = None
        membership.save()
        self.assertFalse(write_mock.called)
コード例 #5
0
class TestApplicationReceivers(APITestCase):
    def setUp(self):
        self.new_member = UserFactory()
        self.existing_member = UserFactory()
        self.group = GroupFactory(members=[self.existing_member],
                                  application_questions='')

    def test_group_add_member_marks_existing_messages_as_read(self):
        self.group.conversation.messages.create(author=self.existing_member,
                                                content='foo')
        second_message = self.group.conversation.messages.create(
            author=self.existing_member, content='bar')

        self.group.add_member(self.new_member)

        new_participant = ConversationParticipant.objects.get(
            user=self.new_member, conversation=self.group.conversation)
        self.assertTrue(new_participant.seen_up_to == second_message)
コード例 #6
0
class TestPlaceModel(TestCase):
    def setUp(self):
        self.group = GroupFactory()

    def test_create_fails_if_name_too_long(self):
        with self.assertRaises(DataError):
            Place.objects.create(name='a' * 81, group=self.group)

    def test_create_place_with_same_name_fails(self):
        Place.objects.create(name='abcdef', group=self.group)
        with self.assertRaises(IntegrityError):
            Place.objects.create(name='abcdef', group=self.group)

    def test_create_place_with_same_name_in_different_groups_works(self):
        Place.objects.create(name='abcdef', group=self.group)
        Place.objects.create(name='abcdef', group=GroupFactory())

    def test_get_active_status(self):
        s = Place.objects.create(name='my place', group=self.group)
        self.assertFalse(s.is_active())

        s.status = 'active'
        s.save()
        self.assertTrue(s.is_active())

        s.status = 'declined'
        s.save()
        self.assertFalse(s.is_active())

    def test_removes_subscription_when_leaving_group(self):
        place = Place.objects.create(name='abcdef', group=self.group)
        user = UserFactory()
        self.group.add_member(user)
        place.placesubscription_set.create(user=user)

        self.group.remove_member(user)

        self.assertFalse(place.placesubscription_set.filter(user=user).exists())
        conversation = place.conversation
        self.assertFalse(conversation.conversationparticipant_set.filter(user=user).exists())
コード例 #7
0
ファイル: test_trust.py プロジェクト: cstefanj/karrot-backend
class TestTrustThreshold(TestCase):
    def create_group_with_members(self, member_count):
        self.members = [UserFactory() for _ in range(member_count)]
        self.group = GroupFactory(members=self.members)
        # trust threshold calculation ignores recently joined users, so we need to create users before that
        two_days_ago = timezone.now() - relativedelta(days=2)
        GroupMembership.objects.filter(group=self.group).update(
            created_at=two_days_ago)

    def test_min_threshold(self):
        self.create_group_with_members(1)
        self.assertEqual(
            self.group.trust_threshold_for_newcomer(),
            1,
        )

    def test_ramp_up_threshold(self):
        self.create_group_with_members(5)
        self.assertEqual(
            self.group.trust_threshold_for_newcomer(),
            2,
        )

    def test_max_threshold(self):
        self.create_group_with_members(6)
        self.assertEqual(
            self.group.trust_threshold_for_newcomer(),
            3,
        )

    def test_ignores_recently_joined_users(self):
        self.create_group_with_members(1)
        [self.group.add_member(UserFactory()) for _ in range(5)]
        self.assertEqual(
            self.group.trust_threshold_for_newcomer(),
            1,
        )
コード例 #8
0
ファイル: test_tasks.py プロジェクト: cstefanj/karrot-backend
class TestConversationNotificationTask(TestCase):
    def setUp(self):
        self.user = VerifiedUserFactory()
        self.author = VerifiedUserFactory()
        self.group = GroupFactory(members=[self.author, self.user])
        mail.outbox = []
        with suppressed_notifications():
            self.message = self.group.conversation.messages.create(author=self.author, content='initial message')

    def test_only_notifies_active_group_members(self):
        self.group.add_member(UserFactory())
        inactive_user = VerifiedUserFactory()
        self.group.add_member(inactive_user)
        self.group.groupmembership_set.filter(user=inactive_user).update(inactive_at=timezone.now())
        mail.outbox = []
        self.group.conversation.messages.create(author=self.author, content='foo')

        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].to, [self.user.email])

    def test_notify_about_unseen_message(self):
        self.group.conversation.conversationparticipant_set.filter(user=self.user).update(seen_up_to=self.message)
        self.group.conversation.messages.create(author=self.author, content='this should be sent')

        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].to[0], self.user.email)
        self.assertIn('this should be sent', mail.outbox[0].body)
        self.assertNotIn('initial message', mail.outbox[0].body)

    def test_exclude_seen_message(self):
        with suppressed_notifications():
            another_message = self.group.conversation.messages.create(author=self.author, content='foo')
        self.group.conversation.conversationparticipant_set.filter(user=self.user).update(seen_up_to=another_message)

        tasks.notify_participants(another_message)
        self.assertEqual(len(mail.outbox), 0)

    def test_exclude_thread_replies_from_conversation_notification(self):
        with suppressed_notifications():
            self.group.conversation.messages.create(
                author=self.user, thread=self.message, content='first thread reply'
            )
        self.group.conversation.messages.create(author=self.author, content='conversation')

        self.assertNotIn('first thread reply', mail.outbox[0].body)

    def test_does_notification_batching_in_threads(self):
        with suppressed_notifications():
            self.group.conversation.messages.create(
                author=self.user, thread=self.message, content='first thread reply'
            )
        recent_message = self.group.conversation.messages.create(
            author=self.user, thread=self.message, content='second thread reply'
        )

        self.assertEqual(len(mail.outbox), 1)
        self.assertIn('first thread reply', mail.outbox[0].body)
        self.assertIn('second thread reply', mail.outbox[0].body)
        self.assertEqual(mail.outbox[0].to[0], self.author.email)
        participant = ConversationThreadParticipant.objects.get(thread=self.message, user=self.author)
        self.assertEqual(participant.notified_up_to.id, recent_message.id)

    def test_exclude_seen_message_in_thread(self):
        with suppressed_notifications():
            another_message = self.group.conversation.messages.create(
                author=self.user, thread=self.message, content='first thread reply'
            )
        ConversationThreadParticipant.objects.filter(
            thread=self.message, user=self.author
        ).update(seen_up_to=another_message)

        self.assertEqual(len(mail.outbox), 0)

    def test_exclude_already_notified_in_thread(self):
        self.group.conversation.messages.create(author=self.user, thread=self.message, content='first thread reply')
        mail.outbox = []
        self.group.conversation.messages.create(author=self.user, thread=self.message, content='second thread reply')

        self.assertEqual(len(mail.outbox), 1)
        self.assertIn('second thread reply', mail.outbox[0].body)
        self.assertNotIn('first thread reply', mail.outbox[0].body)
コード例 #9
0
ファイル: test_api.py プロジェクト: cstefanj/karrot-backend
class TestConversationsEmailNotificationsAPI(APITestCase):
    def setUp(self):
        self.user = VerifiedUserFactory()
        self.group = GroupFactory(members=[self.user])
        self.conversation = self.group.conversation
        self.participant = ConversationParticipant.objects.get(
            conversation=self.conversation, user=self.user)

    def test_mute(self):
        participant = ConversationParticipant.objects.get(
            conversation=self.conversation, user=self.user)
        self.assertFalse(participant.muted)

        self.client.force_login(user=self.user)

        data = {'notifications': ConversationNotificationStatus.MUTED.value}
        response = self.client.patch('/api/conversations/{}/'.format(
            self.conversation.id),
                                     data,
                                     format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['notifications'],
                         ConversationNotificationStatus.MUTED.value)

        participant.refresh_from_db()
        self.assertTrue(participant.muted)

    def test_unmute(self):
        participant = ConversationParticipant.objects.get(
            conversation=self.conversation, user=self.user)
        participant.muted = True
        participant.save()
        self.assertTrue(participant.muted)

        self.client.force_login(user=self.user)

        data = {'notifications': ConversationNotificationStatus.ALL.value}
        response = self.client.patch('/api/conversations/{}/'.format(
            self.conversation.id),
                                     data,
                                     format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['notifications'],
                         ConversationNotificationStatus.ALL.value)

        participant.refresh_from_db()
        self.assertFalse(participant.muted)

    def test_send_email_notifications(self):
        users = [VerifiedUserFactory() for _ in range(3)]
        [self.group.add_member(u) for u in users]

        mail.outbox = []
        ConversationMessage.objects.create(author=self.user,
                                           conversation=self.conversation,
                                           content='asdf')

        actual_recipients = set(m.to[0] for m in mail.outbox)
        expected_recipients = set(u.email for u in users)

        self.assertEqual(actual_recipients, expected_recipients)

        self.assertEqual(len(mail.outbox), 3)

    def test_exclude_bounced_addresses(self):
        bounce_user = VerifiedUserFactory()
        self.group.add_member(bounce_user)
        for _ in range(5):
            EmailEvent.objects.create(address=bounce_user.email,
                                      event='bounce',
                                      payload={})

        mail.outbox = []
        ConversationMessage.objects.create(author=self.user,
                                           conversation=self.conversation,
                                           content='asdf')
        self.assertEqual(len(mail.outbox), 0)

    def test_not_exclude_bounced_addresses_if_too_old(self):
        bounce_user = VerifiedUserFactory()
        self.group.add_member(bounce_user)

        some_months_ago = timezone.now() - relativedelta(months=4)
        for _ in range(5):
            EmailEvent.objects.create(created_at=some_months_ago,
                                      address=bounce_user.email,
                                      event='bounce',
                                      payload={})

        mail.outbox = []
        ConversationMessage.objects.create(author=self.user,
                                           conversation=self.conversation,
                                           content='asdf')
        self.assertEqual(len(mail.outbox), 1)

    def test_exclude_unverified_addresses(self):
        user = UserFactory()  # not verified
        self.group.add_member(user)

        mail.outbox = []
        ConversationMessage.objects.create(author=self.user,
                                           conversation=self.conversation,
                                           content='asdf')
        self.assertEqual(len(mail.outbox), 0)
コード例 #10
0
class GroupMembershipReceiverTests(WSTestCase):
    def setUp(self):
        super().setUp()
        self.member = UserFactory()
        self.user = UserFactory()
        self.group = GroupFactory(members=[self.member])

    def test_receive_group_join(self):
        member_client = self.connect_as(self.member)
        joining_client = self.connect_as(self.user)
        nonmember_client = self.connect_as(UserFactory())

        self.group.add_member(self.user)

        response = member_client.messages_by_topic.get(
            'groups:group_detail')[0]
        self.assertIn(self.user.id, response['payload']['members'])
        self.assertIn(self.user.id, response['payload']['memberships'].keys())

        response = member_client.messages_by_topic.get(
            'groups:group_preview')[0]
        self.assertIn(self.user.id, response['payload']['members'])
        self.assertNotIn('memberships', response['payload'])

        response = joining_client.messages_by_topic.get(
            'groups:group_detail')[0]
        self.assertIn(self.user.id, response['payload']['members'])

        response = joining_client.messages_by_topic.get(
            'groups:group_preview')[0]
        self.assertIn(self.user.id, response['payload']['members'])

        self.assertNotIn('groups:group_detail',
                         nonmember_client.messages_by_topic.keys())
        response = nonmember_client.messages_by_topic.get(
            'groups:group_preview')[0]
        self.assertIn(self.user.id, response['payload']['members'])
        self.assertNotIn('memberships', response['payload'])

    def test_receive_group_leave_as_leaving_user(self):
        # Clean up notifications from group setup, to prevent notification_deleted messages
        Notification.objects.all().delete()
        client = self.connect_as(self.member)

        self.group.remove_member(self.member)

        response = client.messages_by_topic.get('groups:group_preview')[0]
        self.assertNotIn(self.user.id, response['payload']['members'])
        self.assertNotIn('memberships', response['payload'])
        self.assertEqual([m['topic'] for m in client.messages], [
            'history:history',
            'conversations:leave',
            'conversations:conversation',
            'status',
            'groups:group_preview',
        ])

        status_messages = client.messages_by_topic['status']
        self.assertEqual(len(status_messages), 1, status_messages)
        self.assertEqual(
            status_messages[0]['payload'], {
                'unseen_conversation_count': 0,
                'unseen_thread_count': 0,
                'has_unread_conversations_or_threads': False,
                'groups': {
                    self.group.id: {
                        'unread_wall_message_count': 0
                    }
                },
                'places': {},
            })

    def test_receive_group_roles_update(self):
        membership = self.group.add_member(self.user)
        client = self.connect_as(self.member)

        membership.add_roles([roles.GROUP_EDITOR])
        membership.save()

        response = client.messages_by_topic.get('groups:group_detail')[0]
        self.assertIn(
            roles.GROUP_EDITOR,
            response['payload']['memberships'][self.user.id]['roles'])

        self.assertEqual([m['topic'] for m in client.messages], [
            'notifications:notification',
            'status',
            'groups:group_detail',
        ])
コード例 #11
0
class TestConversationsEmailNotificationsAPI(APITestCase):
    def setUp(self):
        self.user = VerifiedUserFactory()
        self.group = GroupFactory(members=[self.user])
        self.conversation = self.group.conversation
        self.participant = ConversationParticipant.objects.get(
            conversation=self.conversation, user=self.user)

    def test_mute(self):
        participant = ConversationParticipant.objects.get(
            conversation=self.conversation, user=self.user)
        self.assertFalse(participant.muted)

        self.client.force_login(user=self.user)

        data = {'notifications': ConversationNotificationStatus.MUTED.value}
        response = self.client.patch('/api/conversations/{}/'.format(
            self.conversation.id),
                                     data,
                                     format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['notifications'],
                         ConversationNotificationStatus.MUTED.value)

        participant.refresh_from_db()
        self.assertTrue(participant.muted)

    def test_unmute(self):
        participant = ConversationParticipant.objects.get(
            conversation=self.conversation, user=self.user)
        participant.muted = True
        participant.save()
        self.assertTrue(participant.muted)

        self.client.force_login(user=self.user)

        data = {'notifications': ConversationNotificationStatus.ALL.value}
        response = self.client.patch('/api/conversations/{}/'.format(
            self.conversation.id),
                                     data,
                                     format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['notifications'],
                         ConversationNotificationStatus.ALL.value)

        participant.refresh_from_db()
        self.assertFalse(participant.muted)

    def test_send_email_notifications(self):
        users = [VerifiedUserFactory() for _ in range(3)]
        [self.group.add_member(u) for u in users]

        mail.outbox = []
        with execute_scheduled_tasks_immediately():
            ConversationMessage.objects.create(author=self.user,
                                               conversation=self.conversation,
                                               content='asdf')

        actual_recipients = set(m.to[0] for m in mail.outbox)
        expected_recipients = set(u.email for u in users)

        self.assertEqual(actual_recipients, expected_recipients)

        self.assertEqual(len(mail.outbox), 3)

    def test_exclude_unverified_addresses(self):
        user = UserFactory()  # not verified
        self.group.add_member(user)

        mail.outbox = []
        ConversationMessage.objects.create(author=self.user,
                                           conversation=self.conversation,
                                           content='asdf')
        self.assertEqual(len(mail.outbox), 0)
コード例 #12
0
class TestGroupSummaryEmails(APITestCase):
    def setUp(self):
        self.group = GroupFactory()

        self.user_without_notifications = VerifiedUserFactory(language='en')
        self.group.add_member(self.user_without_notifications)
        m = GroupMembership.objects.get(group=self.group,
                                        user=self.user_without_notifications)
        m.notification_types = []
        m.save()

        # it should ignore unverified and inactive users so adding a random number
        # of them here should not change anything

        unverified_users = [
            UserFactory(language='en') for _ in list(range(randint(2, 5)))
        ]
        for user in unverified_users:
            self.group.add_member(user)

        inactive_users = [
            VerifiedUserFactory(language='en')
            for _ in list(range(randint(2, 5)))
        ]
        for user in inactive_users:
            membership = self.group.add_member(user)
            membership.inactive_at = timezone.now()
            membership.save()

    def test_creates_one_email_per_person(self):
        n = 5
        for i in list(range(n)):
            self.group.add_member(VerifiedUserFactory(language='en'))

        from_date, to_date = group_emails.calculate_group_summary_dates(
            self.group)
        context = group_emails.prepare_group_summary_data(
            self.group, from_date, to_date)
        emails = group_emails.prepare_group_summary_emails(self.group, context)
        self.assertEqual(len(emails), 5)

        expected_members = self.group.members.filter(
            groupmembership__in=GroupMembership.objects.active(
            ).with_notification_type(GroupNotificationType.WEEKLY_SUMMARY)
        ).exclude(groupmembership__user__in=get_user_model().objects.
                  unverified_or_ignored())

        self.assertEqual(sorted([email.to[0] for email in emails]),
                         sorted([member.email for member in expected_members]))
        self.assertNotIn(self.user_without_notifications.email, emails[0].to)

    def test_creates_one_email_per_person_with_different_languages(self):
        n = 5

        for _ in list(range(n)):
            self.group.add_member(VerifiedUserFactory(language='en'))

        for _ in list(range(n)):
            self.group.add_member(VerifiedUserFactory(language='de'))

        for _ in list(range(n)):
            self.group.add_member(VerifiedUserFactory(language='fr'))

        from_date, to_date = group_emails.calculate_group_summary_dates(
            self.group)
        context = group_emails.prepare_group_summary_data(
            self.group, from_date, to_date)
        emails = group_emails.prepare_group_summary_emails(self.group, context)
        self.assertEqual(len(emails), 15)

        to = []
        for email in emails:
            to.extend(email.to)

        expected_members = self.group.members.filter(
            groupmembership__in=GroupMembership.objects.active(
            ).with_notification_type(GroupNotificationType.WEEKLY_SUMMARY)
        ).exclude(groupmembership__user__in=get_user_model().objects.
                  unverified_or_ignored())

        self.assertEqual(sorted(to),
                         sorted([member.email for member in expected_members]))

        self.assertNotIn(self.user_without_notifications.email, to)

    def test_creates_emails_unknown_locale(self):
        n = 5

        for _ in list(range(n)):
            self.group.add_member(VerifiedUserFactory(language='dummy'))

        from_date, to_date = group_emails.calculate_group_summary_dates(
            self.group)
        context = group_emails.prepare_group_summary_data(
            self.group, from_date, to_date)
        emails = group_emails.prepare_group_summary_emails(self.group, context)
        self.assertEqual(len(emails), 5)

        expected_members = self.group.members.filter(
            groupmembership__in=GroupMembership.objects.active(
            ).with_notification_type(GroupNotificationType.WEEKLY_SUMMARY)
        ).exclude(groupmembership__user__in=get_user_model().objects.
                  unverified_or_ignored())

        self.assertEqual(sorted([email.to[0] for email in emails]),
                         sorted([member.email for member in expected_members]))
        self.assertNotIn(self.user_without_notifications.email, emails[0].to)

    def test_ignores_deleted_pickups(self):
        a_few_days_ago = timezone.now() - relativedelta(days=4)

        place = PlaceFactory(group=self.group)
        user = VerifiedUserFactory(mail_verified=True)
        self.group.add_member(user)

        with freeze_time(a_few_days_ago, tick=True):
            # fulfilled, but deleted
            PickupDateFactory(place=place,
                              max_collectors=1,
                              collectors=[user],
                              is_disabled=True)

        from_date, to_date = karrot.groups.emails.calculate_group_summary_dates(
            self.group)
        data = karrot.groups.emails.prepare_group_summary_data(
            self.group, from_date, to_date)

        self.assertEqual(data['pickups_done_count'], 0)

    def test_group_summary_data(self):

        a_couple_of_weeks_ago = timezone.now() - relativedelta(weeks=3)
        a_few_days_ago = timezone.now() - relativedelta(days=4)

        place = PlaceFactory(group=self.group)
        old_user = VerifiedUserFactory(mail_verified=True)
        user = VerifiedUserFactory(mail_verified=True)

        # should not be included in summary email
        with freeze_time(a_couple_of_weeks_ago, tick=True):
            self.group.add_member(old_user)
            self.group.conversation.messages.create(author=old_user,
                                                    content='old message')
            PickupDateFactory(place=place)
            PickupDateFactory(place=place,
                              max_collectors=1,
                              collectors=[old_user])

        # should be included in summary email
        with freeze_time(a_few_days_ago, tick=True):
            self.group.add_member(user)

            # a couple of messages
            self.group.conversation.messages.create(author=user,
                                                    content='hello')
            self.group.conversation.messages.create(author=user,
                                                    content='whats up')

            # a missed pickup
            PickupDateFactory(place=place)

            # a fulfilled pickup
            PickupDateFactory(place=place, max_collectors=1, collectors=[user])

        from_date, to_date = karrot.groups.emails.calculate_group_summary_dates(
            self.group)
        data = karrot.groups.emails.prepare_group_summary_data(
            self.group, from_date, to_date)
        self.assertEqual(data['pickups_done_count'], 1)
        self.assertEqual(data['pickups_missed_count'], 1)
        self.assertEqual(len(data['new_users']), 1)
        self.assertEqual(len(data['messages']), 2)