def test_cannot_delete_vote_in_decided_issue(self): issue = self.create_issue() voting = issue.votings.first() vote_for_no_change(voting=voting, user=self.member) with self.fast_forward_to_voting_expiration(voting): process_expired_votings() response = self.delete_vote_via_API(issue) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN, response.data)
def test_conflict_resolution_notifications(self): user1, user2, user3 = UserFactory(), UserFactory(), UserFactory() group = GroupFactory(members=[user1, user2, user3]) Notification.objects.all().delete() issue = IssueFactory(group=group, created_by=user1, affected_user=user2) notifications = Notification.objects.order_by('type') self.assertEqual(notifications.count(), 2) self.assertEqual( notifications[1].type, NotificationType.CONFLICT_RESOLUTION_CREATED_ABOUT_YOU.value) self.assertEqual(notifications[1].user, user2) self.assertEqual(notifications[1].context, { 'issue': issue.id, 'group': group.id, 'user': user2.id }) self.assertEqual(notifications[0].type, NotificationType.CONFLICT_RESOLUTION_CREATED.value) self.assertEqual(notifications[0].user, user3) # keep discussing Notification.objects.all().delete() voting = issue.latest_voting() vote_for_further_discussion(voting=voting, user=user1) with fast_forward_to_voting_expiration(voting): process_expired_votings() notifications = Notification.objects.order_by('type') self.assertEqual(notifications.count(), 3) self.assertEqual(notifications[0].type, NotificationType.CONFLICT_RESOLUTION_CONTINUED.value) self.assertEqual(notifications[1].type, NotificationType.CONFLICT_RESOLUTION_CONTINUED.value) self.assertEqual( notifications[2].type, NotificationType.CONFLICT_RESOLUTION_CONTINUED_ABOUT_YOU.value) # remove user Notification.objects.all().delete() voting = issue.latest_voting() vote_for_remove_user(voting=voting, user=user1) with fast_forward_to_voting_expiration(voting): process_expired_votings() notifications = Notification.objects.order_by('type') self.assertEqual(notifications.count(), 3) self.assertEqual([n.type for n in notifications], [ NotificationType.CONFLICT_RESOLUTION_DECIDED.value, NotificationType.CONFLICT_RESOLUTION_DECIDED.value, NotificationType.CONFLICT_RESOLUTION_YOU_WERE_REMOVED.value, ])
def test_removed_member_cannot_access_issue(self): issue = self.create_issue(affected_user=self.affected_member) vote_for_remove_user(voting=issue.latest_voting(), user=issue.created_by) with self.fast_forward_to_voting_expiration(issue.latest_voting()): process_expired_votings() self.client.force_login(user=self.affected_member) # cannot access issue response = self.get_results('/api/issues/{}/'.format(issue.id)) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND, response.data) # cannot access conversation response = self.get_results('/api/conversations/{}/'.format( issue.conversation.id)) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND, response.data)
def process_votings(self): with self.fast_forward_to_voting_expiration(): process_expired_votings()
def test_create_conflict_resolution_and_vote(self): # add another editor notification_member = VerifiedUserFactory() self.group.groupmembership_set.create( user=notification_member, roles=[roles.GROUP_EDITOR], notification_types=[GroupNotificationType.CONFLICT_RESOLUTION]) # add notification type to send out emails self.group.groupmembership_set.filter(user=self.member).update( notification_types=[GroupNotificationType.CONFLICT_RESOLUTION]) mail.outbox = [] # create issue self.client.force_login(user=self.member) response = self.client.post( '/api/issues/', { 'group': self.group.id, 'topic': 'I complain about this user', 'affected_user': self.affected_member.id, }) self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.data) issue = response.data self.assertEqual(issue['created_by'], self.member.id) self.assertEqual(issue['status'], IssueStatus.ONGOING.value) self.assertEqual(issue['type'], 'conflict_resolution') self.assertEqual(issue['topic'], 'I complain about this user') self.assertEqual(issue['group'], self.group.id) self.assertEqual(issue['affected_user'], self.affected_member.id) self.assertEqual(len(issue['votings']), 1) self.assertLessEqual(parse(issue['created_at']), timezone.now()) voting = issue['votings'][0] self.assertEqual(voting['participant_count'], 0) # check if emails have been sent self.assertEqual(len(mail.outbox), 2) email_to_affected_user = next( email for email in mail.outbox if email.to[0] == self.affected_member.email) email_to_editor = next(email for email in mail.outbox if email.to[0] == notification_member.email) self.assertIn('with you', email_to_affected_user.subject) self.assertIn('with {}'.format(self.affected_member.display_name), email_to_editor.subject) # vote on option response = self.client.post('/api/issues/{}/vote/'.format(issue['id']), make_vote_data(voting['options']), format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED, response.data) votes = response.data self.assertEqual(len(votes), 3) self.assertIn('option', votes[0]) self.assertIn('score', votes[0]) # get results time_when_voting_expires = parse( voting['expires_at']) + relativedelta(hours=1) with freeze_time(time_when_voting_expires, tick=True): process_expired_votings() response = self.client.get('/api/issues/{}/'.format(issue['id'])) self.assertEqual(response.status_code, status.HTTP_200_OK) # get conversation response = self.client.get('/api/issues/{}/conversation/'.format( issue['id'])) self.assertEqual(response.status_code, status.HTTP_200_OK) conversation_id = response.data['id'] # post message in conversation data = {'conversation': conversation_id, 'content': 'a nice message'} response = self.client.post('/api/messages/', data, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED)