class GroupReceiverTests(WSTestCase):
    def setUp(self):
        super().setUp()
        self.member = UserFactory()
        self.user = UserFactory()
        self.group = GroupFactory(members=[self.member])

    def test_receive_group_changes(self):
        self.client = self.connect_as(self.member)

        name = faker.name()
        self.group.name = name
        self.group.save()

        response = self.client.messages[0]
        self.assertEqual(response['topic'], 'groups:group_detail')
        self.assertEqual(response['payload']['name'], name)
        self.assertTrue('description' in response['payload'])

        response = self.client.messages[1]
        self.assertEqual(response['topic'], 'groups:group_preview')
        self.assertEqual(response['payload']['name'], name)
        self.assertTrue('description' not in response['payload'])

        self.assertEqual(len(self.client.messages), 2)

    def test_receive_group_changes_as_nonmember(self):
        self.client = self.connect_as(self.user)

        name = faker.name()
        self.group.name = name
        self.group.save()

        response = self.client.messages[0]
        self.assertEqual(response['topic'], 'groups:group_preview')
        self.assertEqual(response['payload']['name'], name)
        self.assertTrue('description' not in response['payload'])

        self.assertEqual(len(self.client.messages), 1)
예제 #2
0
    def setUp(self):

        self.now = timezone.now()
        self.url = '/api/stores/'
        self.member = UserFactory()
        self.group = GroupFactory(members=[
            self.member,
        ])
        self.store = StoreFactory(group=self.group)
        self.store_url = self.url + str(self.store.id) + '/'
        self.series = PickupDateSeriesFactory(max_collectors=3,
                                              store=self.store)
        self.series.update_pickup_dates(start=lambda: self.now)
예제 #3
0
    def setUp(self):
        self.url = '/api/feedback/'

        # create a group with a user and two stores
        self.collector = UserFactory()
        self.collector2 = UserFactory()
        self.group = GroupFactory(members=[self.collector, self.collector2])
        self.group2 = GroupFactory(members=[self.collector, self.collector2])
        self.store = StoreFactory(group=self.group)
        self.store2 = StoreFactory(group=self.group)
        self.pickup = PickupDateFactory(store=self.store,
                                        date=timezone.now() -
                                        relativedelta(days=1))
        self.pickup2 = PickupDateFactory(store=self.store2,
                                         date=timezone.now() -
                                         relativedelta(days=1))

        # create a feedback data
        self.feedback_get = {
            'given_by': self.collector,
            'about': self.pickup,
            'weight': 1,
            'comment': 'asfjk'
        }
        self.feedback_get2 = {
            'given_by': self.collector2,
            'about': self.pickup2,
            '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 collector
        self.pickup.add_collector(self.collector)
        self.pickup2.add_collector(self.collector)
        self.pickup2.add_collector(self.collector2)
예제 #4
0
 def setUp(self):
     self.user = VerifiedUserFactory()
     self.unverified_user = UserFactory()
     self.inactive_user = VerifiedUserFactory()
     self.author = VerifiedUserFactory()
     self.group = GroupFactory(members=[
         self.author, self.user, self.inactive_user, self.unverified_user
     ])
     self.group.groupmembership_set.filter(user=self.inactive_user).update(
         inactive_at=timezone.now())
     self.message = self.group.conversation.messages.create(
         author=self.author, content='foo')
     mail.outbox = []
예제 #5
0
    def test_deletes_pickup_upcoming_notification(self):
        user = UserFactory()
        group = GroupFactory(members=[user])
        store = StoreFactory(group=group)
        in_one_hour = timezone.now() + relativedelta(hours=1)
        pickup = PickupDateFactory(store=store, date=in_one_hour, collectors=[user])
        Notification.objects.all().delete()

        create_pickup_upcoming_notifications.call_local()
        pickup.remove_collector(user)

        notifications = Notification.objects.filter(type=NotificationType.PICKUP_UPCOMING.value)
        self.assertEqual(notifications.count(), 0)
예제 #6
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()
        GroupApplicationFactory(user=user, group=group)

        self.assertEqual(
            Notification.objects.filter(user=member, type=NotificationType.NEW_APPLICANT.value).count(), 1
        )
    def setUp(self):
        self.url = '/api/pickup-dates/'

        # pickup date for group with one member and one store
        self.member = UserFactory()
        self.group = GroupFactory(members=[
            self.member,
        ])
        self.active_store = StoreFactory(group=self.group, status='active')
        self.inactive_store = StoreFactory(group=self.group, status='created')

        PickupDateFactory(store=self.active_store)
        PickupDateFactory(store=self.inactive_store)
예제 #8
0
class TestWallMessagesUpdateStatus(APITestCase):
    def setUp(self):
        self.user = UserFactory()
        self.group = GroupFactory(members=[self.user])
        self.conversation = Conversation.objects.get_or_create_for_target(
            self.group)
        self.conversation.join(self.user)

    def test_wall_message_activates_inactive_group(self):
        self.group.status = GroupStatus.INACTIVE.value
        self.group.save()
        self.client.force_login(user=self.user)
        data = {
            'conversation': self.conversation.id,
            'content': 'a nice message'
        }
        response = self.client.post('/api/messages/', data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED,
                         response.data)
        self.assertEqual(response.data['content'], data['content'])
        self.group.refresh_from_db()
        self.assertEqual(self.group.status, GroupStatus.ACTIVE.value)
예제 #9
0
 def setUp(self):
     self.client = WSClient()
     self.member = UserFactory()
     self.other_member = UserFactory()
     self.unrelated_user = UserFactory()
     self.group = GroupFactory(members=[self.member, self.other_member])
     pathlib.Path(settings.MEDIA_ROOT).mkdir(exist_ok=True)
     copyfile(os.path.join(os.path.dirname(__file__), './photo.jpg'),
              os.path.join(settings.MEDIA_ROOT, 'photo.jpg'))
     self.member.photo = 'photo.jpg'
     self.member.save()
     self.other_member.photo = 'photo.jpg'
     self.other_member.save()
예제 #10
0
    def setUp(self):
        self.member = UserFactory()
        self.group = GroupFactory(members=[
            self.member,
        ])
        self.store = StoreFactory(group=self.group, status='archived')
        self.pickup = PickupDateFactory(store=self.store,
                                        date=timezone.now() -
                                        relativedelta(days=1))
        self.pickup.collectors.add(self.member)

        PickupDateFactory(store=self.store,
                          date=timezone.now() - relativedelta(days=1))
        call_command('process_finished_pickup_dates')
예제 #11
0
    def setUp(self):
        self.url = '/api/stores/'

        # group with two members and one store
        self.member = UserFactory()
        self.member2 = UserFactory()
        self.group = GroupFactory(members=[self.member, self.member2])
        self.store = StoreFactory(group=self.group)
        self.store_url = self.url + str(self.store.id) + '/'

        # not a member
        self.user = UserFactory()

        # another store for above group
        self.store_data = {'name': faker.name(),
                           'description': faker.name(),
                           'group': self.group.id,
                           'address': faker.address(),
                           'latitude': faker.latitude(),
                           'longitude': faker.longitude()}

        # another group
        self.different_group = GroupFactory(members=[self.member2, ])
예제 #12
0
    def test_reply_message_title(self):
        author = UserFactory()
        group = GroupFactory(members=[author])
        conversation = Conversation.objects.get_or_create_for_target(group)
        message = conversation.messages.create(author=author,
                                               content='bla' * 10)
        reply = ConversationMessage.objects.create(author=author,
                                                   conversation=conversation,
                                                   thread=message,
                                                   content='reply')

        title = get_message_title(reply, 'en')
        self.assertEqual(title,
                         'blablablabla... / {}'.format(author.display_name))
예제 #13
0
    def test_do_not_send_too_many_updates(self):
        [
            GroupFactory(members=[self.member, self.other_member])
            for _ in range(3)
        ]

        self.client = self.connect_as(self.member)

        name = faker.name()
        self.other_member.display_name = name
        self.other_member.save()

        self.assertEqual(len(self.client.messages), 1)
        self.assertIn('users:user', self.client.messages_by_topic.keys())
예제 #14
0
    def setUp(self):
        self.active_user = UserFactory()
        self.inactive_user = UserFactory()
        self.group = GroupFactory(members=[self.active_user, self.inactive_user])

        now = timezone.now()

        inactive_email_date = now - timedelta(days=settings.NUMBER_OF_DAYS_UNTIL_INACTIVE_IN_GROUP + 1)
        self.active_membership = GroupMembership.objects.get(group=self.group, user=self.active_user)
        self.inactive_membership = GroupMembership.objects.get(group=self.group, user=self.inactive_user)
        self.inactive_membership.lastseen_at = inactive_email_date
        self.inactive_membership.save()

        mail.outbox = []
    def setUp(self):
        self.url = '/api/pickup-dates/'

        # pickup date for group with one member and one store
        self.member = UserFactory()
        self.group = GroupFactory(members=[
            self.member,
        ])
        self.store = StoreFactory(group=self.group)
        self.pickup = PickupDateFactory(store=self.store)
        self.pickup_url = self.url + str(self.pickup.id) + '/'
        self.join_url = self.pickup_url + 'add/'
        self.leave_url = self.pickup_url + 'remove/'
        self.conversation_url = self.pickup_url + 'conversation/'

        # not a member of the group
        self.user = UserFactory()

        # another pickup date for above store
        self.pickup_data = {
            'date': timezone.now() + relativedelta(days=2),
            'max_collectors': 5,
            'store': self.store.id
        }

        # past pickup date
        self.past_pickup_data = {
            'date': timezone.now() - relativedelta(days=1),
            'max_collectors': 5,
            'store': self.store.id
        }
        self.past_pickup = PickupDateFactory(store=self.store,
                                             date=timezone.now() -
                                             relativedelta(days=1))
        self.past_pickup_url = self.url + str(self.past_pickup.id) + '/'
        self.past_join_url = self.past_pickup_url + 'add/'
        self.past_leave_url = self.past_pickup_url + 'remove/'
예제 #16
0
class GroupConversationReceiverPushTests(ChannelTestCase):
    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
        PushSubscription.objects.create(
            user=self.user,
            token=self.token,
            platform=PushSubscriptionPlatform.ANDROID)

    def test_sends_to_push_subscribers(self, m):
        def check_json_data(request):
            data = json.loads(request.body.decode('utf-8'))
            self.assertEqual(
                data['notification']['title'],
                self.group.name + ' / ' + self.author.display_name)
            self.assertEqual(data['notification']['body'], self.content)
            self.assertEqual(data['to'], self.token)
            return True

        m.post(FCMApi.FCM_END_POINT,
               json={},
               additional_matcher=check_json_data)

        # add a message to the conversation
        ConversationMessage.objects.create(conversation=self.conversation,
                                           content=self.content,
                                           author=self.author)
예제 #17
0
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.get_trust_threshold_for_newcomer(),
            1,
        )

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

    def test_max_threshold(self):
        self.create_group_with_members(6)
        self.assertEqual(
            self.group.get_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.get_trust_threshold_for_newcomer(),
            1,
        )
예제 #18
0
    def test_group_members_stats(self):
        def update_member_activity(user, **kwargs):
            GroupMembership.objects.filter(user=user).update(
                lastseen_at=timezone.now() - relativedelta(**kwargs))

        def set_as_newcomer(user):
            membership = GroupMembership.objects.filter(user=user).first()
            membership.remove_roles([roles.GROUP_EDITOR])
            membership.save()

        members = [UserFactory() for _ in range(10)]
        group = GroupFactory(members=members)

        set_as_newcomer(members[0])
        update_member_activity(members[0], days=2)
        update_member_activity(members[1], days=8)
        update_member_activity(members[2], days=31)
        update_member_activity(members[3], days=61)
        update_member_activity(members[4], days=91)

        points = stats.get_group_members_stats(group)

        self.assertEqual(points, [{
            'measurement': 'karrot.group.members',
            'tags': {
                'group': str(group.id),
                'group_status': 'active',
            },
            'fields': {
                'count_active_1d': 5,
                'count_active_7d': 6,
                'count_active_30d': 7,
                'count_active_60d': 8,
                'count_active_90d': 9,
                'count_active_editors_1d': 5,
                'count_active_editors_7d': 5,
                'count_active_editors_30d': 6,
                'count_active_editors_60d': 7,
                'count_active_editors_90d': 8,
                'count_active_newcomers_1d': 0,
                'count_active_newcomers_7d': 1,
                'count_active_newcomers_30d': 1,
                'count_active_newcomers_60d': 1,
                'count_active_newcomers_90d': 1,
                'count_total': 10,
                'count_editors_total': 9,
                'count_newcomers_total': 1,
            },
        }])
 def setUp(self):
     self.user = UserFactory()
     self.user2 = UserFactory()
     self.group = GroupFactory(members=[self.user, self.user2])
     self.store = StoreFactory(group=self.group)
     self.pickupdate = PickupDateFactory(
         store=self.store,
         date=timezone.now() + relativedelta(days=1),
         collectors=[self.user, ])
     self.past_pickupdate = PickupDateFactory(
         store=self.store,
         date=timezone.now() - relativedelta(days=1),
         collectors=[self.user, ]
     )
     self.url = '/api/auth/user/'
예제 #20
0
 def setUpClass(cls):
     super().setUpClass()
     cls.user = UserFactory()
     cls.group = GroupFactory(members=[cls.user, ])
     cls.store = StoreFactory(group=cls.group)
     cls.pickupdate = PickupDateFactory(
         store=cls.store,
         date=timezone.now() + relativedelta(days=1),
         collectors=[cls.user, ])
     cls.past_pickupdate = PickupDateFactory(
         store=cls.store,
         date=timezone.now() - relativedelta(days=1),
         collectors=[cls.user, ]
     )
     cls.url = '/api/users/{}/'.format(cls.user.id)
예제 #21
0
    def setUp(self):
        self.user = UserFactory()
        self.user2 = UserFactory()
        self.group = GroupFactory(members=[self.user])
        self.conversation = Conversation.objects.get_or_create_for_target(
            self.group)
        self.conversation.join(self.user)
        self.participant = ConversationParticipant.objects.get(
            conversation=self.conversation, user=self.user)
        self.message = self.conversation.messages.create(author=self.user,
                                                         content='hello')

        self.group2 = GroupFactory(members=[self.user, self.user2])
        self.conversation2 = Conversation.objects.get_or_create_for_target(
            self.group2)
        self.conversation2.join(self.user)
        self.conversation2.join(self.user2)
        self.message2 = self.conversation2.messages.create(author=self.user,
                                                           content='hello2')
        self.message3 = self.conversation2.messages.create(
            author=self.user,
            content='hello3',
            created_at=(timezone.now() - timedelta(days=10)),
        )
예제 #22
0
    def test_does_not_delete_active_notifications(self):
        in_one_hour = timezone.now() + relativedelta(hours=1)
        group = GroupFactory()
        Notification.objects.create(
            type=NotificationType.PICKUP_UPCOMING.value,
            user=UserFactory(),
            expires_at=in_one_hour,
            context={
                'group': group.id,
            }
        )

        tasks.delete_expired_notifications.call_local()

        self.assertEqual(Notification.objects.count(), 1)
예제 #23
0
    def test_creates_feedback_possible_notification(self):
        member = UserFactory()
        group = GroupFactory(members=[member])
        store = StoreFactory(group=group)
        pickup = PickupDateFactory(store=store)

        pickup.add_collector(member)
        pickup.done_and_processed = True
        pickup.save()

        notification = Notification.objects.filter(user=member, type=NotificationType.FEEDBACK_POSSIBLE.value)
        self.assertEqual(notification.count(), 1)
        self.assertLessEqual(
            notification[0].expires_at, pickup.date + relativedelta(days=settings.FEEDBACK_POSSIBLE_DAYS)
        )
    def setUpClass(cls):
        super().setUpClass()
        cls.url = '/api/stores/'

        # group with two members and one store
        cls.member = UserFactory()
        cls.member2 = UserFactory()
        cls.group = GroupFactory(members=[cls.member, cls.member2])
        cls.store = StoreFactory(group=cls.group)
        cls.store_url = cls.url + str(cls.store.id) + '/'

        # not a member
        cls.user = UserFactory()

        # another store for above group
        cls.store_data = {'name': faker.name(),
                          'description': faker.name(),
                          'group': cls.group.id,
                          'address': faker.address(),
                          'latitude': faker.latitude(),
                          'longitude': faker.longitude()}

        # another group
        cls.different_group = GroupFactory(members=[cls.member2, ])
예제 #25
0
    def test_creates_user_became_editor(self):
        user = UserFactory()
        user1 = UserFactory()
        group = GroupFactory(newcomers=[user, user1])
        membership = GroupMembership.objects.get(user=user, group=group)
        Notification.objects.all().delete()

        membership.roles.append(GROUP_EDITOR)
        membership.save()

        self.assertEqual(Notification.objects.count(), 2)
        you_became_editor = Notification.objects.get(type=NotificationType.YOU_BECAME_EDITOR.value)
        self.assertEqual(you_became_editor.user, user)
        user_became_editor = Notification.objects.get(type=NotificationType.USER_BECAME_EDITOR.value)
        self.assertEqual(user_became_editor.user, user1)
예제 #26
0
    def test_adds_participant_marks_existing_messages_as_read(self):
        existing_member = UserFactory()
        group = GroupFactory(members=[existing_member])

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

        new_member = UserFactory()
        GroupMembership.objects.create(group=group, user=new_member)

        new_participant = ConversationParticipant.objects.get(
            user=new_member, conversation=group.conversation)
        self.assertTrue(new_participant.seen_up_to == second_message)
예제 #27
0
    def setUp(self):
        self.applicant = VerifiedUserFactory()
        self.member = VerifiedUserFactory()
        self.group = GroupFactory(members=[self.member])
        self.application = GroupApplicationFactory(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])
            GroupApplicationFactory(group=group, user=applicant)

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

        mail.outbox = []
예제 #28
0
    def test_do_not_send_notification_again(self):
        editor = UserFactory()
        editor2 = UserFactory()
        group = GroupFactory(members=[editor, editor2])
        two_days_ago = timezone.now() - relativedelta(days=2)
        GroupMembership.objects.filter(group=group).update(
            created_at=two_days_ago)
        mail.outbox = []

        membership = GroupMembership.objects.get(user=editor, group=group)
        Trust.objects.create(membership=membership, given_by=editor2)

        self.assertEqual(len(mail.outbox), 0)
        self.assertEqual(
            History.objects.filter(
                typus=HistoryTypus.MEMBER_BECAME_EDITOR).count(), 0)
예제 #29
0
    def test_store_statistics(self):
        user = UserFactory()
        self.client.force_login(user=user)
        group = GroupFactory(members=[user])
        store = StoreFactory(group=group)

        response = self.client.get('/api/stores/{}/statistics/'.format(
            store.id))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, {
            'feedback_count': 0,
            'feedback_weight': 0,
            'pickups_done': 0,
        })

        one_day_ago = timezone.now() - relativedelta(days=1)

        users = [UserFactory() for _ in range(9)]
        pickups = [
            PickupDateFactory(
                store=store,
                date=one_day_ago,
                collectors=users,
                done_and_processed=True,
            ) for _ in range(3)
        ]
        feedback = [
            FeedbackFactory(about=choice(pickups), 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/stores/{}/statistics/'.format(
            store.id))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(
            response.data, {
                'feedback_count': len(feedback),
                'feedback_weight': weight,
                'pickups_done': len(pickups),
            })
예제 #30
0
    def test_message_notification(self, notify):
        author = UserFactory()
        user = UserFactory()
        group = GroupFactory(members=[author, user])
        conversation = Conversation.objects.get_or_create_for_target(group)
        message = conversation.messages.create(author=author, content='bla')

        subscriptions = [
            PushSubscription.objects.create(
                user=user,
                token='',
                platform=PushSubscriptionPlatform.ANDROID.value)
        ]

        notify.reset_mock()
        notify_message_push_subscribers(message)
        notify.assert_called_once_with(message, subscriptions, 'en')