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)
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})
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_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)
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))
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)
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})
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)
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)
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)
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)
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)
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})
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, }, }])
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)
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, }, }])
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)
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)
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
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)]
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 = []
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)
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)
def make_application(): applicant = VerifiedUserFactory() group = GroupFactory(members=[self.member]) ApplicationFactory(group=group, user=applicant)
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)
def setUp(self): self.applicant = VerifiedUserFactory() self.member = VerifiedUserFactory() self.group = GroupFactory(members=[self.member]) self.application = ApplicationFactory(group=self.group, user=self.applicant)