Пример #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
    def test_member_receives_application_update(self):
        application = ApplicationFactory(user=self.user, group=self.group)

        client = self.connect_as(self.member)

        application.status = 'accepted'
        application.save()

        messages = client.messages_by_topic['applications:update']
        self.assertEqual(len(messages), 1)
        response = messages[0]
        self.assertEqual(response['payload']['id'], application.id)

        messages = client.messages_by_topic['status']
        self.assertEqual(len(messages), 2, messages)
        # No pending applications
        self.assertEqual(
            messages[1]['payload'],
            {'groups': {
                self.group.id: {
                    'pending_application_count': 0
                }
            }})
        # Notification gets deleted because application has been accepted
        self.assertEqual(messages[0]['payload'],
                         {'unseen_notification_count': 0})
Пример #3
0
 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)
Пример #4
0
    def test_applicant_receives_application_update(self):
        application = ApplicationFactory(user=self.user, group=self.group)

        self.client = self.connect_as(self.user)

        application.status = 'accepted'
        application.save()

        messages = self.application_update_messages()
        self.assertEqual(len(messages), 1)
        response = messages[0]
        self.assertEqual(response['payload']['id'], application.id)
Пример #5
0
    def test_application_message_title(self):
        author = UserFactory()
        group = GroupFactory(members=[author])
        applicant = UserFactory()
        application = ApplicationFactory(group=group, user=applicant)
        conversation = Conversation.objects.get_or_create_for_target(application)
        message = conversation.messages.create(author=author, content='bla')

        title = get_message_title(message, 'en')
        self.assertEqual(title, '❓ {} / {}'.format(applicant.display_name, author.display_name))

        application.accept(author)
        message.refresh_from_db()
        title = get_message_title(message, 'en')
        self.assertEqual(title, '✅ {} / {}'.format(applicant.display_name, author.display_name))

        application.decline(author)
        message.refresh_from_db()
        title = get_message_title(message, 'en')
        self.assertEqual(title, '❌ {} / {}'.format(applicant.display_name, author.display_name))

        application.withdraw()
        message.refresh_from_db()
        title = get_message_title(message, 'en')
        self.assertEqual(title, '🗑️ {} / {}'.format(applicant.display_name, author.display_name))

        message = conversation.messages.create(author=applicant, content='bla')
        message.refresh_from_db()
        title = get_message_title(message, 'en')
        self.assertEqual(title, '🗑️ {}'.format(applicant.display_name))
Пример #6
0
    def test_creates_application_accepted_notification(self):
        member = UserFactory()
        group = GroupFactory(members=[member])

        user = UserFactory()
        application = ApplicationFactory(user=user, group=group)
        application.accept(member)

        self.assertEqual(
            Notification.objects.filter(
                user=user,
                type=NotificationType.APPLICATION_ACCEPTED.value).count(), 1)
        self.assertEqual(
            Notification.objects.filter(
                type=NotificationType.NEW_APPLICANT.value).count(), 0)
Пример #7
0
    def test_member_receives_application_create(self):
        client = self.connect_as(self.member)

        application = ApplicationFactory(user=self.user, group=self.group)

        messages = client.messages_by_topic['applications:update']
        self.assertEqual(len(messages), 1)
        self.assertEqual(messages[0]['payload']['id'], application.id)

        messages = client.messages_by_topic['status']
        self.assertEqual(len(messages), 2, messages)
        # We told the user that we have 1 pending application
        self.assertEqual(
            messages[0]['payload'],
            {'groups': {
                self.group.id: {
                    'pending_application_count': 1
                }
            }})
        # "There is an application for your group!"
        self.assertEqual(messages[1]['payload'],
                         {'unseen_notification_count': 1})

        client.reset_messages()
        # mark notification as read
        meta = self.member.notificationmeta
        meta.marked_at = timezone.now()
        meta.save()

        messages = client.messages_by_topic['status']
        self.assertEqual(len(messages), 1, messages)
        self.assertEqual(messages[0]['payload'],
                         {'unseen_notification_count': 0})
Пример #8
0
    def test_list_conversations_with_related_data_efficiently(self):
        user = UserFactory()
        group = GroupFactory(members=[user])
        place = PlaceFactory(group=group)
        pickup = PickupDateFactory(place=place)
        application = ApplicationFactory(user=UserFactory(), group=group)
        issue = IssueFactory(group=group)

        conversations = [
            t.conversation for t in (group, pickup, application, issue)
        ]
        [c.sync_users([user]) for c in conversations]
        [c.messages.create(content='hey', author=user) for c in conversations]

        ConversationMeta.objects.get_or_create(user=user)

        self.client.force_login(user=user)
        with self.assertNumQueries(13):
            response = self.client.get('/api/conversations/',
                                       {'group': group.id},
                                       format='json')
        results = response.data['results']

        self.assertEqual(len(results['conversations']), len(conversations))
        self.assertEqual(results['pickups'][0]['id'], pickup.id)
        self.assertEqual(results['applications'][0]['id'], application.id)
        self.assertEqual(results['issues'][0]['id'], issue.id)
Пример #9
0
 def test_unsubscribe_from_applications(self):
     application = ApplicationFactory(group=self.group, user=UserFactory())
     participant = application.conversation.conversationparticipant_set.filter(
         user=self.user)
     self.assertFalse(participant.get().muted)
     unsubscribe_from_all_conversations_in_group(self.user, self.group)
     self.assertTrue(participant.get().muted)
Пример #10
0
 def test_list_own_applications(self):
     [
         ApplicationFactory(group=self.group, user=UserFactory())
         for _ in range(4)
     ]
     self.client.force_login(user=self.applicant)
     response = self.get_results('/api/applications/?user={}'.format(
         self.applicant.id))
     self.assertEqual(len(response.data), 1)
Пример #11
0
    def test_member_receives_application_create(self):
        self.client = self.connect_as(self.member)

        application = ApplicationFactory(user=self.user, group=self.group)

        messages = self.application_update_messages()
        self.assertEqual(len(messages), 1)
        response = messages[0]
        self.assertEqual(response['payload']['id'], application.id)
Пример #12
0
    def test_application_status_update(self, write_points):
        write_points.reset_mock()

        two_hours_ago = timezone.now() - relativedelta(hours=2)

        application = ApplicationFactory(group=GroupFactory(),
                                         user=UserFactory(),
                                         created_at=two_hours_ago)

        write_points.assert_called_with([{
            'measurement': 'karrot.events',
            'tags': {
                'group': str(application.group.id),
                'group_status': application.group.status,
            },
            'fields': {
                'application_pending': 1,
            },
        }])

        write_points.reset_mock()
        application.status = 'accepted'
        application.save()

        self.assertEqual(len(write_points.mock_calls), 1)

        point = write_points.call_args[0][0][0]

        expected_seconds = 60 * 60 * 2
        # can take a little longer to run sometimes...
        expected_seconds_range = range(expected_seconds, expected_seconds + 3)

        self.assertEqual(point['measurement'], 'karrot.events')
        self.assertEqual(
            point['tags'], {
                'group': str(application.group.id),
                'group_status': application.group.status,
                'application_status': application.status,
            })
        self.assertEqual(point['fields']['application_accepted'], 1)
        self.assertIn(point['fields']['application_alive_seconds'],
                      expected_seconds_range)
        self.assertIn(point['fields']['application_accepted_alive_seconds'],
                      expected_seconds_range)
Пример #13
0
    def test_applicant_receives_application_update(self):
        application = ApplicationFactory(user=self.user, group=self.group)
        Notification.objects.all().delete()

        client = self.connect_as(self.user)

        application.status = 'accepted'
        application.save()

        messages = client.messages_by_topic['applications:update']
        self.assertEqual(len(messages), 1)
        response = messages[0]
        self.assertEqual(response['payload']['id'], application.id)

        messages = client.messages_by_topic['status']
        self.assertEqual(len(messages), 1, messages)
        # "Your application has been accepted"
        self.assertEqual(messages[0]['payload'],
                         {'unseen_notification_count': 1})
Пример #14
0
    def test_application_stats(self):
        group = GroupFactory()

        [
            ApplicationFactory(group=group,
                               user=UserFactory(),
                               status='pending') for _ in range(3)
        ]
        [
            ApplicationFactory(group=group,
                               user=UserFactory(),
                               status='accepted') for _ in range(4)
        ]
        [
            ApplicationFactory(group=group,
                               user=UserFactory(),
                               status='declined') for _ in range(5)
        ]
        [
            ApplicationFactory(group=group,
                               user=UserFactory(),
                               status='withdrawn') for _ in range(6)
        ]

        points = stats.get_application_stats(group)

        self.assertEqual(points, [{
            'measurement': 'karrot.group.applications',
            'tags': {
                'group': str(group.id),
                'group_status': 'active',
            },
            'fields': {
                'count_total': 18,
                'count_status_pending': 3,
                'count_status_accepted': 4,
                'count_status_declined': 5,
                'count_status_withdrawn': 6,
            },
        }])
Пример #15
0
    def test_cannot_have_two_pending_applications(self):
        ApplicationFactory(group=self.group, user=self.applicant)

        # create another application
        self.client.force_login(user=self.applicant)
        answers = faker.text()
        response = self.client.post(
            '/api/applications/',
            {
                'group': self.group.id,
                'answers': answers,
            },
        )
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
Пример #16
0
    def test_application_status_update(self, write_points):
        write_points.reset_mock()

        two_hours_ago = timezone.now() - relativedelta(hours=2)

        application = ApplicationFactory(group=GroupFactory(),
                                         user=UserFactory(),
                                         created_at=two_hours_ago)

        write_points.assert_called_with([{
            'measurement': 'karrot.events',
            'tags': {
                'group': str(application.group.id),
                'group_status': application.group.status,
            },
            'fields': {
                'application_pending': 1,
            },
        }])

        write_points.reset_mock()
        application.status = 'accepted'
        application.save()

        write_points.assert_called_with([{
            'measurement': 'karrot.events',
            'tags': {
                'group': str(application.group.id),
                'group_status': application.group.status,
                'application_status': application.status,
            },
            'fields': {
                'application_accepted': 1,
                'application_alive_seconds': 60 * 60 * 2,
                'application_accepted_alive_seconds': 60 * 60 * 2,
            },
        }])
Пример #17
0
    def test_creates_new_applicant_notification(self):
        member = UserFactory()
        group = GroupFactory(members=[member])
        self.assertEqual(
            Notification.objects.filter(
                user=member,
                type=NotificationType.NEW_APPLICANT.value).count(), 0)

        user = UserFactory()
        ApplicationFactory(user=user, group=group)

        self.assertEqual(
            Notification.objects.filter(
                user=member,
                type=NotificationType.NEW_APPLICANT.value).count(), 1)
Пример #18
0
    def test_removes_new_application_notification_when_decided(self):
        member = UserFactory()
        group = GroupFactory(members=[member])

        users = [UserFactory() for _ in range(3)]
        applications = [
            ApplicationFactory(user=user, group=group) for user in users
        ]
        applications[0].withdraw()
        applications[1].accept(member)
        applications[2].decline(member)

        self.assertEqual(
            Notification.objects.filter(
                type=NotificationType.NEW_APPLICANT.value).count(), 0)
Пример #19
0
def get_or_create_application():
    application = Application.objects.order_by('?').first()

    if application is None:
        new_user = VerifiedUserFactory()
        group = random_group()
        if group.application_questions == '':
            group.application_questions = faker.text()
            group.save()
        application = ApplicationFactory(
            group=group,
            user=new_user,
        )

    return application
Пример #20
0
    def setUpTestData(cls):
        cls.applicant = VerifiedUserFactory()
        cls.member = VerifiedUserFactory()
        cls.newcomer = VerifiedUserFactory()
        cls.group = GroupFactory(members=[cls.member],
                                 newcomers=[cls.newcomer])
        cls.application = ApplicationFactory(group=cls.group,
                                             user=cls.applicant)
        cls.conversation = Conversation.objects.get_for_target(cls.application)

        def make_application():
            applicant = VerifiedUserFactory()
            group = GroupFactory(members=[cls.member])
            ApplicationFactory(group=group, user=applicant)

        [make_application() for _ in range(5)]
Пример #21
0
    def setUp(self):
        self.applicant = VerifiedUserFactory()
        self.member = VerifiedUserFactory()
        self.newcomer = VerifiedUserFactory()
        self.group = GroupFactory(members=[self.member], newcomers=[self.newcomer])
        self.application = ApplicationFactory(group=self.group, user=self.applicant)
        self.conversation = Conversation.objects.get_for_target(self.application)

        def make_application():
            applicant = VerifiedUserFactory()
            group = GroupFactory(members=[self.member])
            ApplicationFactory(group=group, user=applicant)

        [make_application() for _ in range(5)]

        mail.outbox = []
Пример #22
0
    def test_can_apply_again(self):
        ApplicationFactory(
            group=self.group,
            user=self.applicant,
            status=ApplicationStatus.WITHDRAWN.value,
        )

        # create another application
        self.client.force_login(user=self.applicant)
        response = self.client.post(
            '/api/applications/',
            {
                'group': self.group.id,
                'answers': faker.text(),
            },
        )
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
Пример #23
0
    def test_get_conversation_status_efficiently(self):
        user = UserFactory()
        group = GroupFactory(members=[user])
        place = PlaceFactory(group=group)
        activity = ActivityFactory(place=place)
        application = ApplicationFactory(user=UserFactory(), group=group)
        issue = IssueFactory(group=group)
        offer = OfferFactory(group=group)

        conversations = [
            t.conversation
            for t in (group, activity, application, issue, offer)
        ]
        another_user = UserFactory()
        [c.sync_users([user, another_user]) for c in conversations]
        [
            c.messages.create(content='hey', author=another_user)
            for c in conversations
        ]

        with self.assertNumQueries(2):
            unread_conversations(user)
Пример #24
0
 def make_application():
     applicant = VerifiedUserFactory()
     group = GroupFactory(members=[self.member])
     ApplicationFactory(group=group, user=applicant)
Пример #25
0
 def test_list_pending_applications(self):
     [ApplicationFactory(group=self.group, user=self.applicant, status='withdrawn') for _ in range(4)]
     self.client.force_login(user=self.applicant)
     response = self.get_results('/api/applications/?status={}'.format(self.applicant.id))
     self.assertEqual(len(response.data), 1)
Пример #26
0
 def setUp(self):
     self.applicant = VerifiedUserFactory()
     self.member = VerifiedUserFactory()
     self.group = GroupFactory(members=[self.member])
     self.application = ApplicationFactory(group=self.group, user=self.applicant)