def test_leave_group(self): place = PlaceFactory(group=self.group) activity = ActivityFactory(place=place, participants=[self.member, self.user], date=to_range(timezone.now() + relativedelta(weeks=1))) past_activity = ActivityFactory(place=place, participants=[ self.member, ], date=to_range(timezone.now() - relativedelta(weeks=1))) unrelated_activity = ActivityFactory( date=to_range(timezone.now() + relativedelta(weeks=1)), participants=[ self.member, ], ) GroupMembership.objects.create(group=unrelated_activity.place.group, user=self.member) self.client.force_login(user=self.member) response = self.client.post('/api/groups/{}/leave/'.format( self.group.id)) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertFalse(activity.participants.get_queryset().filter( id=self.member.id).exists()) self.assertTrue(past_activity.participants.get_queryset().filter( id=self.member.id).exists()) self.assertTrue(unrelated_activity.participants.get_queryset().filter( id=self.member.id).exists())
def test_create_activity_upcoming_notifications(self): users = [UserFactory() for _ in range(3)] group = GroupFactory(members=users) place = PlaceFactory(group=group) in_one_hour = to_range(timezone.now() + relativedelta(hours=1)) activity1 = ActivityFactory(place=place, date=in_one_hour, participants=users) in_two_hours = to_range(timezone.now() + relativedelta(hours=1)) ActivityFactory(place=place, date=in_two_hours, participants=users) Notification.objects.all().delete() create_activity_upcoming_notifications.call_local() notifications = Notification.objects.filter(type=NotificationType.ACTIVITY_UPCOMING.value) self.assertEqual(notifications.count(), 6) self.assertEqual(set(n.user.id for n in notifications), set(user.id for user in users)) activity1_user1_participant = ActivityParticipant.objects.get(user=users[0], activity=activity1) activity1_user1_notification = next( n for n in notifications if n.context['activity_participant'] == activity1_user1_participant.id ) self.assertEqual( activity1_user1_notification.context, { 'group': group.id, 'place': place.id, 'activity': activity1.id, 'activity_participant': activity1_user1_participant.id, } ) self.assertEqual(activity1_user1_notification.expires_at, activity1.date.start)
def test_activity_active_within(self): ActivityFactory(place=self.place, date=to_range(timezone.now() - timedelta(days=2)), participants=[self.user]) ActivityFactory( place=self.place, date=to_range(timezone.now() - timedelta(days=9)), participants=[self.other_user] ) memberships = self.group.groupmembership_set.activity_active_within(days=7) self.assertEqual(memberships.count(), 1)
def setUp(self): self.member = UserFactory() self.group = GroupFactory(members=[self.member]) self.place = PlaceFactory(group=self.group, status='archived') self.activity = ActivityFactory(place=self.place, date=to_range(timezone.now() - relativedelta(days=1))) self.activity.add_participant(self.member) ActivityFactory(place=self.place, date=to_range(timezone.now() - relativedelta(days=1), minutes=30)) Activity.objects.process_finished_activities()
def test_receive_dismissed_feedback(self): self.activity.date = to_range(timezone.now() - relativedelta(days=1)) self.activity.save() client = self.connect_as(self.member) Activity.objects.process_finished_activities() messages_by_topic = client.messages_by_topic status_messages = messages_by_topic['status'] self.assertEqual(len(status_messages), 2) self.assertEqual( status_messages[1]['payload'], {'groups': { self.group.id: { 'feedback_possible_count': 1 } }}) self.activity.dismiss_feedback(self.member) messages_by_topic = client.messages_by_topic status_messages = messages_by_topic['status'] self.assertEqual(len(status_messages), 3) self.assertEqual( status_messages[2]['payload'], {'groups': { self.group.id: { 'feedback_possible_count': 0 } }})
def test_receive_activity_changes(self): client = self.connect_as(self.member) # change property date = to_range( faker.future_datetime(end_date='+30d', tzinfo=timezone.utc)) self.activity.date = date self.activity.save() response = client.messages_by_topic.get('activities:activity')[0] self.assertEqual(parse(response['payload']['date'][0]), date.start) # join client = self.connect_as(self.member) self.activity.add_participant(self.member) response = client.messages_by_topic.get('activities:activity')[0] self.assertEqual(response['payload']['participants'], [self.member.id]) response = client.messages_by_topic.get( 'conversations:conversation')[0] self.assertEqual(response['payload']['participants'], [self.member.id]) # leave client = self.connect_as(self.member) self.activity.remove_participant(self.member) response = client.messages_by_topic.get('activities:activity')[0] self.assertEqual(response['payload']['participants'], []) self.assertIn('conversations:leave', client.messages_by_topic.keys())
def test_receive_history_and_notification(self): self.activity.date = to_range(timezone.now() - relativedelta(days=1)) self.activity.save() Notification.objects.all().delete() client = self.connect_as(self.member) Activity.objects.process_finished_activities() messages_by_topic = client.messages_by_topic response = messages_by_topic['history:history'][0] self.assertEqual(response['payload']['typus'], 'ACTIVITY_DONE') response = messages_by_topic['notifications:notification'][0] self.assertEqual(response['payload']['type'], 'feedback_possible') status_messages = messages_by_topic['status'] self.assertEqual(len(status_messages), 2) self.assertEqual(status_messages[0]['payload'], {'unseen_notification_count': 1}) self.assertEqual( status_messages[1]['payload'], {'groups': { self.group.id: { 'feedback_possible_count': 1 } }}) self.assertEqual(len(client.messages), 4, client.messages)
def test_creates_activity_disabled_notification_and_deletes_activity_upcoming_notification( self): user1, user2 = UserFactory(), UserFactory() group = GroupFactory(members=[user1, user2]) place = PlaceFactory(group=group) in_one_hour = to_range(timezone.now() + relativedelta(hours=1)) activity = ActivityFactory(place=place, date=in_one_hour, participants=[user1, user2]) Notification.objects.all().delete() create_activity_upcoming_notifications.call_local() activity.last_changed_by = user2 activity.is_disabled = True activity.save() activity_upcoming_notifications = Notification.objects.filter( type=NotificationType.ACTIVITY_UPCOMING.value) self.assertEqual(activity_upcoming_notifications.count(), 0) activity_disabled_notifications = Notification.objects.filter( type=NotificationType.ACTIVITY_DISABLED.value) self.assertEqual(activity_disabled_notifications.count(), 1) self.assertEqual(activity_disabled_notifications[0].user, user1) context = activity_disabled_notifications[0].context self.assertEqual(context['group'], group.id) self.assertEqual(context['activity'], activity.id) self.assertEqual(context['place'], place.id)
def create_empty_activity(self, delta, place=None): if place is None: place = self.place return ActivityFactory( place=place, date=to_range(timezone.localtime() + delta), max_participants=1, )
def activity_data(self, extra=None): if extra is None: extra = {} return { 'date': to_range(timezone.now() + relativedelta(days=2)).as_list(), 'max_participants': 5, 'place': self.place.id, **extra, }
def setUp(self): self.member = UserFactory() self.group = GroupFactory(members=[self.member]) self.place = PlaceFactory(group=self.group) self.activity = ActivityFactory(place=self.place, date=to_range(timezone.now() - relativedelta(days=1))) # No one joined the activity Activity.objects.process_finished_activities()
def test_matches_shifted_activities_within_few_seconds(self): now = timezone.now() every_day = [now + relativedelta(days=n) for n in range(1, 5)] activities = [Activity(date=to_range(d + relativedelta(seconds=20), minutes=30)) for d in every_day] self.assertIteratorEqual( match_activities_with_dates(activities, every_day), zip(activities, every_day), )
def test_matches_identical_activities(self): now = timezone.now() every_day = [now + relativedelta(days=n) for n in range(1, 5)] activities = [Activity(date=to_range(d, minutes=30)) for d in every_day] self.assertIteratorEqual( match_activities_with_dates(activities, every_day), zip(activities, every_day), )
def setUpTestData(cls): cls.url = '/api/activities/' # activity for group with one member and one place cls.member = UserFactory() cls.second_member = UserFactory() cls.group = GroupFactory(members=[cls.member, cls.second_member]) cls.place = PlaceFactory(group=cls.group) cls.activity_type = ActivityTypeFactory(group=cls.group) cls.archived_activity_type = ActivityTypeFactory(group=cls.group, status='archived') cls.activity = ActivityFactory(activity_type=cls.activity_type, place=cls.place) cls.activity_url = cls.url + str(cls.activity.id) + '/' cls.join_url = cls.activity_url + 'add/' cls.leave_url = cls.activity_url + 'remove/' cls.conversation_url = cls.activity_url + 'conversation/' # not a member of the group cls.user = UserFactory() # another activity for above place cls.activity_data = { 'activity_type': cls.activity_type.id, 'date': to_range(timezone.now() + relativedelta(days=2)).as_list(), 'max_participants': 5, 'place': cls.place.id } # past activity cls.past_activity_data = { 'activity_type': cls.activity_type.id, 'date': to_range(timezone.now() - relativedelta(days=1)).as_list(), 'max_participants': 5, 'place': cls.place.id } cls.past_activity = ActivityFactory( activity_type=cls.activity_type, place=cls.place, date=to_range(timezone.now() - relativedelta(days=1))) cls.past_activity_url = cls.url + str(cls.past_activity.id) + '/' cls.past_join_url = cls.past_activity_url + 'add/' cls.past_leave_url = cls.past_activity_url + 'remove/'
def test_matches_first_when_distance_is_equal(self): now = timezone.now() # shift activities every_minute = [now + relativedelta(minutes=n) for n in range(1, 5)] activities = [Activity(date=to_range(d + relativedelta(seconds=30), minutes=30)) for d in every_minute] self.assertIteratorEqual( match_activities_with_dates(activities, every_minute), zip(activities, every_minute), ) # shift dates activities = [Activity(date=to_range(d, minutes=30)) for d in every_minute] every_minute = [n + relativedelta(seconds=30) for n in every_minute] self.assertIteratorEqual( match_activities_with_dates(activities, every_minute), zip(activities, every_minute), )
def create_user_activity(self, delta, place=None, **kwargs): if place is None: place = self.place activity = ActivityFactory( place=place, date=to_range(timezone.localtime() + delta), **kwargs, ) activity.add_participant(self.user) activity.save() return activity
def create_not_full_activity(self, delta, place=None): if place is None: place = self.place activity = ActivityFactory( place=place, date=to_range(timezone.localtime() + delta), max_participants=2, ) activity.add_participant(self.other_user) activity.save() return activity
def test_creates_no_activity_upcoming_notification_when_too_far_in_future(self): user = UserFactory() group = GroupFactory(members=[user]) place = PlaceFactory(group=group) in_one_day = to_range(timezone.now() + relativedelta(days=1)) ActivityFactory(place=place, date=in_one_day, participants=[user]) Notification.objects.all().delete() create_activity_upcoming_notifications.call_local() notifications = Notification.objects.filter(type=NotificationType.ACTIVITY_UPCOMING.value) self.assertEqual(notifications.count(), 0)
def setUp(self): self.url = '/api/feedback/' # create a group with a user and two places self.participant = UserFactory() self.participant2 = UserFactory() self.group = GroupFactory( members=[self.participant, self.participant2]) self.group2 = GroupFactory( members=[self.participant, self.participant2]) self.place = PlaceFactory(group=self.group) self.place2 = PlaceFactory(group=self.group) self.activity = ActivityFactory(place=self.place, date=to_range(timezone.now() - relativedelta(days=1))) self.activity2 = ActivityFactory(place=self.place2, date=to_range(timezone.now() - relativedelta(days=1))) # create a feedback data self.feedback_get = { 'given_by': self.participant, 'about': self.activity, 'weight': 1, 'comment': 'asfjk' } self.feedback_get2 = { 'given_by': self.participant2, 'about': self.activity2, 'weight': 2, 'comment': 'bsfjk' } # create 2 instances of feedback self.feedback = Feedback.objects.create(**self.feedback_get) self.feedback2 = Feedback.objects.create(**self.feedback_get2) # transforms the user into a participant self.activity.add_participant(self.participant) self.activity2.add_participant(self.participant) self.activity2.add_participant(self.participant2)
def test_activity_message_title(self): author = UserFactory() group = GroupFactory(members=[author], timezone='Europe/Berlin') place = PlaceFactory(group=group) activity = ActivityFactory(place=place, participants=[author], date=to_range(parse('2018-11-11T20:00:00Z'))) conversation = Conversation.objects.get_or_create_for_target(activity) message = conversation.messages.create(author=author, content='bla') title = get_message_title(message, 'en') self.assertEqual( title, '{} Sunday 9:00 PM / {}'.format(activity.activity_type.get_translated_name(), author.display_name) )
def test_create_activity(self): self.client.force_login(self.member) self.client.post( '/api/activities/', { 'activity_type': self.activity_type.id, 'date': to_range(timezone.now() + relativedelta(days=1)).as_list(), 'place': self.place.id }, format='json') response = self.get_results(history_url) self.assertEqual(response.data[0]['typus'], 'ACTIVITY_CREATE')
def create_done_activity(place, user_id, activity_type): activity = Activity.objects.create( activity_type=activity_type, date=to_range(faker.date_time_between(start_date='-9d', end_date='-1d', tzinfo=pytz.utc), minutes=30), place_id=place, max_participants=10, ) activity.add_participant(User.objects.get(pk=user_id)) print('created done activity: ', activity) return activity
def test_not_matches_shifted_activities_with_more_difference(self): now = timezone.now() every_day = [now + relativedelta(days=n) for n in range(1, 3)] activities = [Activity(date=to_range(d + relativedelta(minutes=10), minutes=30)) for d in every_day] self.assertIteratorEqual( match_activities_with_dates(activities, every_day), [ (None, every_day[0]), (activities[0], None), (None, every_day[1]), (activities[1], None), ], )
def test_place_statistics_as_average(self): user = UserFactory() self.client.force_login(user=user) group = GroupFactory(members=[user]) place = PlaceFactory(group=group) response = self.client.get('/api/places/{}/statistics/'.format( place.id)) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data, { 'feedback_count': 0, 'feedback_weight': 0, 'activities_done': 0, }) one_day_ago = to_range(timezone.now() - relativedelta(days=1)) users = [UserFactory() for _ in range(9)] activities = [ ActivityFactory( place=place, date=one_day_ago, participants=users, is_done=True, ) for _ in range(3) ] feedback = [ FeedbackFactory(about=choice(activities), given_by=u) for u in users ] # calculate weight from feedback feedback.sort(key=attrgetter('about.id')) weight = 0 for _, fs in groupby(feedback, key=attrgetter('about.id')): len_list = [f.weight for f in fs] weight += float(sum(len_list)) / len(len_list) weight = round(weight) response = self.client.get('/api/places/{}/statistics/'.format( place.id)) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( response.data, { 'feedback_count': len(feedback), 'feedback_weight': weight, 'activities_done': len(activities), })
def test_deletes_activity_upcoming_notification(self): user = UserFactory() group = GroupFactory(members=[user]) place = PlaceFactory(group=group) in_one_hour = to_range(timezone.now() + relativedelta(hours=1)) activity = ActivityFactory(place=place, date=in_one_hour, participants=[user]) Notification.objects.all().delete() create_activity_upcoming_notifications.call_local() activity.remove_participant(user) notifications = Notification.objects.filter( type=NotificationType.ACTIVITY_UPCOMING.value) self.assertEqual(notifications.count(), 0)
def test_matches_empty(self): now = timezone.now() every_day = [now + relativedelta(days=n) for n in range(1, 3)] activities = [Activity(date=to_range(d, minutes=30)) for d in every_day] self.assertIteratorEqual( match_activities_with_dates([], every_day), zip((None, None), every_day), ) self.assertIteratorEqual( match_activities_with_dates(activities, []), zip(activities, (None, None)), ) self.assertIteratorEqual( match_activities_with_dates([], []), [], )
def test_matches_partially(self): now = timezone.now() every_day = [now + relativedelta(days=n) for n in range(1, 5)] activities = [Activity(date=to_range(d, minutes=30)) for d in every_day] self.assertIteratorEqual( match_activities_with_dates(activities[::2], every_day), zip((activities[0], None, activities[2], None), every_day), ) self.assertIteratorEqual( match_activities_with_dates(activities[1::2], every_day), zip((None, activities[1], None, activities[3]), every_day), ) self.assertIteratorEqual( match_activities_with_dates(activities, every_day[::2]), zip(activities, (every_day[0], None, every_day[2], None)), ) self.assertIteratorEqual( match_activities_with_dates(activities, every_day[1::2]), zip(activities, (None, every_day[1], None, every_day[3])), )
def make_activity(place, activity_type): date = to_range( faker.date_time_between(start_date='+2d', end_date='+7d', tzinfo=pytz.utc)) response = c.post( '/api/activities/', { 'activity_type': activity_type.id, 'date': date.as_list(), 'place': place, 'max_participants': 10 }, format='json', ) if response.status_code != 201: raise Exception('could not make activity', response.data) data = response.data p = Activity.objects.get(pk=data['id']) print('created activity: ', data, p.date) return data
def in_one_day(): return to_range(timezone.now() + timedelta(days=1))
def setup_activity(self, max_participants=1): self.date = to_range(timezone.now() + timedelta(days=33)) self.just_before_the_activity_starts = self.date.start - timedelta(hours=1) self.after_the_activity_is_over = self.date.end + timedelta(hours=2) self.activity = ActivityFactory(place=self.place, date=self.date, max_participants=max_participants)