class DisasterSerializerTest(MongoTestCase):
    def setUp(self):
        self.district = Location(**dict(name="Kampala", type="district", parent=None))
        self.district.save()

        self.disaster_type = DisasterType(**dict(name="Fire", description="Fire"))
        self.disaster_type.save()

        self.serialized_location = dict(
            created_at=self.district.created_at,
            type=self.district.type,
            name=self.district.name,
            id=str(self.district.id),
            latlong=[],
        )

        self.serialized_disaster_type = dict(
            created_at=self.disaster_type.created_at,
            name=self.disaster_type.name,
            description=self.disaster_type.description,
            id=str(self.disaster_type.id),
        )

        self.disaster = dict(
            name=self.disaster_type,
            locations=[self.district],
            description="Big Flood",
            date=datetime.datetime(2014, 12, 1, 11, 3),
            status="Assessment",
        )

        self.serialized_disaster = dict(
            name=self.serialized_disaster_type,
            locations=[self.serialized_location],
            description="Big Flood",
            date="2014-12-01T11:03",
            status="Assessment",
        )

    def test_should_serialize_location_object(self):
        self.disaster["date"] = "2014-12-01"
        self.serialized_disaster["date"] = "2014-12-01"
        disaster = Disaster(**self.disaster).save()
        serialized_object = DisasterSerializer(disaster)
        self.assertDictContainsSubset(self.serialized_disaster, serialized_object.data)
        self.assertIsNotNone(serialized_object.data["id"])

    def test_should_deserialize_location_object(self):
        self.serialized_disaster["name"] = self.disaster_type.id
        self.serialized_disaster["locations"] = [self.district.id]

        serializer = DisasterSerializer(data=self.serialized_disaster)
        self.assertTrue(serializer.is_valid())

        saved_disaster = serializer.save()
        self.assertTrue(isinstance(saved_disaster, Disaster))
        for attribute, value in self.disaster.items():
            self.assertEqual(value, getattr(saved_disaster, attribute))
    def test_reset_password_saves_new_password(self, mock_send_email):
        district = Location(**dict(name='Kampala', parent=None, type='district'))
        district.save()
        profile = UserProfile(name='Andrew', email='*****@*****.**', location=district, phone='2570760540326')
        user = UserProfileService(profile).setup_new_user('andrew', str((Group.objects().first()).id))
        old_password = user.password
        profile.user = user

        UserProfileService(profile).reset_password()
        self.assertNotEqual(old_password, profile.user.password)
class DisasterSerializerTest(MongoTestCase):
    def setUp(self):
        self.district = Location(
            **dict(name='Kampala', type='district', parent=None))
        self.district.save()

        self.disaster_type = DisasterType(
            **dict(name="Fire", description="Fire"))
        self.disaster_type.save()

        self.serialized_location = dict(created_at=self.district.created_at,
                                        type=self.district.type,
                                        name=self.district.name,
                                        id=str(self.district.id),
                                        latlong=[])

        self.serialized_disaster_type = dict(
            created_at=self.disaster_type.created_at,
            name=self.disaster_type.name,
            description=self.disaster_type.description,
            id=str(self.disaster_type.id))

        self.disaster = dict(name=self.disaster_type,
                             locations=[self.district],
                             description="Big Flood",
                             date=datetime.datetime(2014, 12, 1, 11, 3),
                             status="Assessment")

        self.serialized_disaster = dict(name=self.serialized_disaster_type,
                                        locations=[self.serialized_location],
                                        description="Big Flood",
                                        date="2014-12-01T11:03",
                                        status="Assessment")

    def test_should_serialize_location_object(self):
        self.disaster['date'] = '2014-12-01'
        self.serialized_disaster['date'] = '2014-12-01'
        disaster = Disaster(**self.disaster).save()
        serialized_object = DisasterSerializer(disaster)
        self.assertDictContainsSubset(self.serialized_disaster,
                                      serialized_object.data)
        self.assertIsNotNone(serialized_object.data['id'])

    def test_should_deserialize_location_object(self):
        self.serialized_disaster['name'] = self.disaster_type.id
        self.serialized_disaster['locations'] = [self.district.id]

        serializer = DisasterSerializer(data=self.serialized_disaster)
        self.assertTrue(serializer.is_valid())

        saved_disaster = serializer.save()
        self.assertTrue(isinstance(saved_disaster, Disaster))
        for attribute, value in self.disaster.items():
            self.assertEqual(value, getattr(saved_disaster, attribute))
Exemplo n.º 4
0
class LocationDisasterStatsTest(MongoTestCase):
    def setUp(self):
        self.disaster_type = DisasterType(
            **dict(name='Flood', description="Some flood"))
        self.disaster_type.save()

        self.district = Location(
            **dict(name='Kampala', type='district', parent=None))
        self.district.save()

        self.disaster_attr = dict(name=self.disaster_type,
                                  locations=[self.district],
                                  description="Big Flood",
                                  date="2014-12-01",
                                  status="Assessment")

    def test_should_retrieve_message_count_in_a_location(self):
        Disaster(**self.disaster_attr).save()
        attr2 = self.disaster_attr.copy()
        attr2["status"] = "Closed"
        Disaster(**attr2).save()

        location_stats_service = LocationStatsService(location=self.district)
        stats = location_stats_service.aggregate_stats()
        disasters_stats = stats.disasters

        self.assertEqual(2, disasters_stats.count)
        self.assertEqual(100, disasters_stats.percentage)

    def test_should_retrieve_disasters_percentage_in_a_location(self):
        Disaster(**self.disaster_attr).save()
        attr2 = self.disaster_attr.copy()
        attr2["locations"] = [
            Location(**dict(name='Location that is not Kampala',
                            type='district')).save()
        ]
        Disaster(**attr2).save()

        location_stats_service = LocationStatsService(location=self.district)
        stats = location_stats_service.aggregate_stats()
        disasters_stats = stats.disasters

        self.assertEqual(1, disasters_stats.count)
        self.assertEqual(50, disasters_stats.percentage)

    def test_should_return_0_if_no_disaster_everywhere(self):
        location_stats_service = LocationStatsService(location=self.district)
        stats = location_stats_service.aggregate_stats()
        disasters_stats = stats.disasters

        self.assertEqual(0, disasters_stats.count)
        self.assertEqual(0, disasters_stats.percentage)
    def test_password_reset_sends_email(self, mock_send_mail, mock_make_password):
        message = "Andrew blabla http://necoc.org.ug [email protected]"
        mock_make_password.return_value = 'blabla'
        district = Location(**dict(name='Kampala', parent=None, type='district'))
        district.save()
        profile = UserProfile(name='Andrew', email='*****@*****.**', location=district, phone='2570760540326')
        user = UserProfileService(profile).setup_new_user('andrew', str((Group.objects().first()).id))
        profile.user = user

        UserProfileService(profile).reset_password()
        mock_send_mail.assert_any_call('NECOC Password Reset',
                                       message,
                                       "*****@*****.**",
                                       ['*****@*****.**'])
class LocationDisasterStatsTest(MongoTestCase):
    def setUp(self):
        self.disaster_type = DisasterType(**dict(name="Flood", description="Some flood"))
        self.disaster_type.save()

        self.district = Location(**dict(name="Kampala", type="district", parent=None))
        self.district.save()

        self.disaster_attr = dict(
            name=self.disaster_type,
            locations=[self.district],
            description="Big Flood",
            date="2014-12-01",
            status="Assessment",
        )

    def test_should_retrieve_message_count_in_a_location(self):
        Disaster(**self.disaster_attr).save()
        attr2 = self.disaster_attr.copy()
        attr2["status"] = "Closed"
        Disaster(**attr2).save()

        location_stats_service = LocationStatsService(location=self.district)
        stats = location_stats_service.aggregate_stats()
        disasters_stats = stats.disasters

        self.assertEqual(2, disasters_stats.count)
        self.assertEqual(100, disasters_stats.percentage)

    def test_should_retrieve_disasters_percentage_in_a_location(self):
        Disaster(**self.disaster_attr).save()
        attr2 = self.disaster_attr.copy()
        attr2["locations"] = [Location(**dict(name="Location that is not Kampala", type="district")).save()]
        Disaster(**attr2).save()

        location_stats_service = LocationStatsService(location=self.district)
        stats = location_stats_service.aggregate_stats()
        disasters_stats = stats.disasters

        self.assertEqual(1, disasters_stats.count)
        self.assertEqual(50, disasters_stats.percentage)

    def test_should_return_0_if_no_disaster_everywhere(self):
        location_stats_service = LocationStatsService(location=self.district)
        stats = location_stats_service.aggregate_stats()
        disasters_stats = stats.disasters

        self.assertEqual(0, disasters_stats.count)
        self.assertEqual(0, disasters_stats.percentage)
Exemplo n.º 7
0
class ProfileImageViewTest(MongoAPITestCase):

    PROFILE_IMAGE_ENDPOINT = '/api/v1/photo/'

    def setUp(self):
        self.district = Location(**dict(name='Kampala', type='district', parent=None))
        self.district.save()
        self.user_profile_attr = dict(name='timothy', phone='+256775019449', location=self.district, email=None)
        self.profile = UserProfile(**self.user_profile_attr)
        self.profile.photo.put(open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg', 'rb'), content_type='image/content_type')
        self.profile.save()
        self.client = Client()
        self.login_user()

    def test_successfully_retrieve_profile_image(self):
        response = self.client.get(self.PROFILE_IMAGE_ENDPOINT + str(self.profile.id) + '/')
        self.assertEqual(200, response.status_code)
        self.assertEqual(open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg', 'rb').read(), response.content)

    def test_not_permitted_to_view_profile(self):
        self.assert_permission_required_for_get(self.PROFILE_IMAGE_ENDPOINT + str(self.profile.id) + '/')

    def test_no_image_found(self):
        response = self.client.get(self.PROFILE_IMAGE_ENDPOINT + 'j34ks34344df234/')
        self.assertEqual(200, response.status_code)
        self.assertEqual(open(settings.PROJECT_ROOT + '/../dms/client/app/img/default_profile.jpg', 'rb').read(), response.content)

    def test_allow_user_to_see_their_own(self):
        self.client.logout()
        attr = self.user_profile_attr.copy()
        attr['phone'] = '+2555837295789'
        user = User(username='******', email='*****@*****.**')
        user.group = None
        user.set_password('weak_password')
        attr['user'] = user
        profile = UserProfile(**attr)
        profile.photo.put(open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg', 'rb'), content_type='image/content_type')
        profile.save()
        self.client.login(username='******', password='******')

        response = self.client.get(self.PROFILE_IMAGE_ENDPOINT + str(profile.id) + '/')
        self.assertEquals(response.status_code, 200)
class TestUserProfileEndpoint(MongoAPITestCase):
    API_ENDPOINT = '/api/v1/mobile-users/'
    CSV_ENDPOINT = '/api/v1/csv-mobile-users/'
    BULK_ENDPOINT = '/api/v1/bulk-mobile-users/'

    def setUp(self):
        self.login_user()
        self.district = Location(
            **dict(name='Kampala', type='district', parent=None))
        self.district.save()
        self.masaka = Location(
            **dict(name='Masaka', type='district', parent=None)).save()
        self.subcounty = Location(**dict(
            name='Nangabo', type='subcounty', parent=self.masaka)).save()

        self.mobile_user_to_post = dict(name='tim',
                                        phone='+256775019500',
                                        location=self.district.id,
                                        email='*****@*****.**')
        self.mobile_user = dict(name='timothy',
                                phone='+256775019449',
                                location=self.district,
                                email=None)
        self.masaka_user = dict(name='Munamasaka',
                                phone='+256775019441',
                                location=self.subcounty,
                                email='*****@*****.**')

    def tearDown(self):
        UserProfile.drop_collection()

    def test_should_post_a_mobile_user(self):
        response = self.client.post(self.API_ENDPOINT,
                                    data=self.mobile_user_to_post)
        self.assertEqual(201, response.status_code)

        retrieved_user = UserProfile.objects(name='tim')
        self.assertEqual(1, retrieved_user.count())

    def test_should_get_a_list_of_users(self):
        user_profile = UserProfile(**self.mobile_user).save()
        response = self.client.get(self.API_ENDPOINT, format='json')

        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.data))
        self.assertEqual(self.mobile_user['name'], response.data[0]['name'])
        self.assertEqual(self.mobile_user['phone'], response.data[0]['phone'])
        self.assertEqual(self.mobile_user['email'], response.data[0]['email'])
        self.assertEqual(user_profile.username(), '')
        self.assertEqual(self.district.name,
                         response.data[0]['location']['name'])

    def test_should_get_ordered_list_of_users(self):
        mob_users = [('aa', '+256775019441'), ('zz', '+256775019442'),
                     ('tim', '+256775019443'), ('abu', '+256775019444')]
        for user_name, mob in mob_users:
            new_dict = dict_replace('name', user_name, self.mobile_user)
            new_dict = dict_replace('phone', mob, new_dict)
            UserProfile(**new_dict).save()
            time.sleep(1)
        response = self.client.get(self.API_ENDPOINT, format='json')

        self.assertEqual(200, response.status_code)
        self.assertEqual(len(mob_users), len(response.data))
        self.assertEqual(response.data[0]['name'], 'abu')
        self.assertEqual(response.data[3]['name'], 'aa')

        #post order by name
        response = self.client.get(self.API_ENDPOINT + '?ordering=name',
                                   format='json')
        self.assertEqual(200, response.status_code)
        self.assertEqual(response.data[0]['name'], 'aa')
        self.assertEqual(response.data[1]['name'], 'abu')
        self.assertEqual(response.data[2]['name'], 'tim')
        self.assertEqual(response.data[3]['name'], 'zz')

        #post order by name desc
        response = self.client.get(self.API_ENDPOINT + '?ordering=-name',
                                   format='json')
        self.assertEqual(200, response.status_code)
        self.assertEqual(response.data[0]['name'], 'zz')
        self.assertEqual(response.data[1]['name'], 'tim')
        self.assertEqual(response.data[2]['name'], 'abu')
        self.assertEqual(response.data[3]['name'], 'aa')

    def test_raise_403_if_user_doesnt_have_manage_permission(self):
        self.assert_permission_required_for_get(self.API_ENDPOINT)
        self.assert_permission_required_for_post(self.API_ENDPOINT)

    def test_should_get_a_single_user(self):
        attr = self.mobile_user.copy()
        user = User(username='******', password='******').save()
        attr['user'] = user
        profile = UserProfile(**attr).save()

        response = self.client.get(self.API_ENDPOINT + str(profile.id) + '/')

        self.assertEqual(200, response.status_code)
        self.assertEqual(self.mobile_user['name'], response.data['name'])
        self.assertEqual(self.mobile_user['phone'], response.data['phone'])
        self.assertEqual(self.mobile_user['email'], response.data['email'])
        self.assertEqual(self.district.name, response.data['location']['name'])
        self.assertEqual('cage', response.data['username'])
        self.assertEqual(str(user.id), response.data['user_id'])

    def test_should_update_a_single_user(self):
        attr = self.mobile_user.copy()
        attr['email'] = '*****@*****.**'
        attr['phone'] = '+256775019500'
        attr['user'] = User(username='******', password='******').save()
        profile = UserProfile(**attr).save()
        response = self.client.post(self.API_ENDPOINT + str(profile.id) + '/',
                                    self.mobile_user_to_post)

        profile.reload()
        profiles = UserProfile.objects()
        self.assertEqual(1, profiles.count())

        self.assertEqual(200, response.status_code)
        self.assertEqual(self.mobile_user_to_post['name'], profile.name)
        self.assertEqual(self.mobile_user_to_post['phone'], profile.phone)
        self.assertEqual(self.mobile_user_to_post['email'], profile.email)

    def test_raise_403_given_user_is_trying_to_access_some_other_users_profile(
            self):
        attr = self.mobile_user.copy()
        attr['email'] = '*****@*****.**'
        attr['phone'] = '+256775029500'
        attr['user'] = User(username='******', password='******').save()
        profile = UserProfile(**attr).save()
        self.assert_permission_required_for_get(self.API_ENDPOINT +
                                                str(profile.id) + '/')
        self.assert_permission_required_for_post(self.API_ENDPOINT +
                                                 str(profile.id) + '/')

    def test_not_raising_403_if_user_only_wants_access_to_their_profile(self):
        self.client.logout()
        attr = self.mobile_user.copy()
        attr['email'] = '*****@*****.**'
        attr['phone'] = '+256775029500'
        user = User(username='******', email='*****@*****.**')
        user.group = None
        user.set_password('hahahah')
        attr['user'] = user
        profile = UserProfile(**attr).save()
        self.client.login(username='******', password='******')

        response = self.client.get(self.API_ENDPOINT + str(profile.id) + '/')
        self.assertEquals(response.status_code, 200)
        response = self.client.post(self.API_ENDPOINT + str(profile.id) + '/')
        self.assertEquals(response.status_code, 200)

    def test_post_with_non_empty_username_creates_system_user(self):
        attr = self.mobile_user_to_post.copy()
        attr['username'] = '******'
        response = self.client.post(self.API_ENDPOINT, data=attr)
        self.assertEqual(201, response.status_code)

        retrieved_user_profile = UserProfile.objects(name='tim')
        self.assertEqual(1, retrieved_user_profile.count())

        retrieved_user = User.objects(username='******')
        self.assertEqual(1, retrieved_user.count())
        self.assertEqual(retrieved_user.first(),
                         retrieved_user_profile.first().user)

    @mock.patch('dms.tasks.send_email.delay')
    def test_posting_new_system_user_sends_email(self, mock_send_email):
        attr = self.mobile_user_to_post.copy()
        attr['username'] = '******'
        attr['email'] = '*****@*****.**'
        response = self.client.post(self.API_ENDPOINT, data=attr)
        self.assertEqual(201, response.status_code)
        mock_send_email.assert_called_with('Your NECOC Account', mock.ANY,
                                           settings.DEFAULT_FROM_EMAIL,
                                           ['*****@*****.**'])

    def test_post_with_group_associates_user_to_group(self):
        attr = self.mobile_user_to_post.copy()
        attr['username'] = '******'
        group = Group.objects().first()
        attr['group'] = str(group.id)
        response = self.client.post(self.API_ENDPOINT, data=attr)
        self.assertEqual(201, response.status_code)

        retrieved_user = User.objects(username='******').first()
        self.assertEqual(group, retrieved_user.group)

    def test_update_with_group_associates_user_to_new_group(self):
        attr = self.mobile_user_to_post.copy()
        attr['username'] = '******'
        group = Group.objects().first()
        attr['group'] = str(group.id)
        self.client.post(self.API_ENDPOINT, data=attr)

        retrieved_user = User.objects(username='******').first()
        retrieved_user_profile = UserProfile.objects(
            user=retrieved_user).first()
        new_group = Group.objects().all()[2]

        new_attr = self.mobile_user_to_post.copy()
        new_attr['username'] = '******'
        new_attr['location'] = str(new_attr['location'])
        new_attr['group'] = str(new_group.id)
        new_attr['id'] = str(retrieved_user_profile.id)

        url = self.API_ENDPOINT + str(retrieved_user_profile.id) + '/'
        response = self.client.post(url, data=new_attr)
        self.assertEqual(200, response.status_code)
        retrieved_user = User.objects(username='******').first()
        self.assertEqual(new_group, retrieved_user.group)

    @mock.patch('dms.utils.image_resizer.ImageResizer', FakeImageResizer)
    def test_post_with_photo_file(self):
        attr = self.mobile_user_to_post.copy()
        attr['username'] = '******'

        with open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg',
                  'rb') as test_image:
            attr['file'] = test_image
            response = self.client.post(self.API_ENDPOINT, data=attr)

        self.assertEqual(201, response.status_code)

        retrieved_user = User.objects(username='******').first()
        reloaded_profile = UserProfile.objects(user=retrieved_user).first()
        self.assertEqual(
            reloaded_profile.photo.read(),
            open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg',
                 'rb').read())
        self.assertEqual(reloaded_profile.photo.content_type, 'image/jpeg')
        self.assertEqual(reloaded_profile.photo_uri(),
                         '/api/v1/photo/' + str(reloaded_profile.id))

    @mock.patch('dms.utils.image_resizer.ImageResizer', BadImageResizer)
    def test_post_with_photo_file(self):
        attr = self.mobile_user_to_post.copy()
        attr['username'] = '******'

        with open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg',
                  'rb') as test_image:
            attr['file'] = test_image
            response = self.client.post(self.API_ENDPOINT, data=attr)

        self.assertEqual(201, response.status_code)

        retrieved_user = User.objects(username='******').first()
        reloaded_profile = UserProfile.objects(user=retrieved_user).first()
        self.assertEqual(reloaded_profile.photo.read(), None)

    @mock.patch('dms.utils.image_resizer.ImageResizer', FakeImageResizer)
    def test_updating_profile_with_photo_file(self):
        attr = self.mobile_user_to_post.copy()
        attr['email'] = '*****@*****.**'
        attr['phone'] = '+256775019511'
        attr['user'] = User(username='******', password='******').save()
        profile = UserProfile(**attr)
        user_photo = open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg',
                          'rb')
        profile.photo.put(user_photo, content_type='image/content_type')
        profile.save()

        with open(settings.PROJECT_ROOT + '/../dms/tests/test2.jpg',
                  'rb') as test_image:
            attr['file'] = test_image
            response = self.client.post(
                self.API_ENDPOINT + str(profile.id) + '/', attr)
            self.assertEqual(200, response.status_code)

        retrieved_user = User.objects(username='******').first()
        reloaded_profile = UserProfile.objects(user=retrieved_user).first()
        self.assertEqual(
            reloaded_profile.photo.read(),
            open(settings.PROJECT_ROOT + '/../dms/tests/test2.jpg',
                 'rb').read())
        self.assertEqual(reloaded_profile.photo.content_type, 'image/jpeg')
        self.assertEqual(reloaded_profile.photo_uri(),
                         '/api/v1/photo/' + str(reloaded_profile.id))

    @mock.patch('dms.utils.image_resizer.ImageResizer', BadImageResizer)
    def test_handling_photo_update_exception(self):
        attr = self.mobile_user_to_post.copy()
        attr['email'] = '*****@*****.**'
        attr['phone'] = '+256775019511'
        attr['user'] = User(username='******', password='******').save()
        profile = UserProfile(**attr)
        user_photo = open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg',
                          'rb')
        profile.photo.put(user_photo, content_type='image/content_type')
        profile.save()

        with open(settings.PROJECT_ROOT + '/../dms/tests/test2.jpg',
                  'rb') as test_image:
            attr['file'] = test_image
            response = self.client.post(
                self.API_ENDPOINT + str(profile.id) + '/', attr)
            self.assertEqual(200, response.status_code)

        retrieved_user = User.objects(username='******').first()
        reloaded_profile = UserProfile.objects(user=retrieved_user).first()
        self.assertEqual(reloaded_profile.photo.read(), None)

    def test_should_return_csv_when_csv_endpoint_is_called(self):
        self.mobile_user['email'] = '*****@*****.**'
        UserProfile(**self.mobile_user).save()
        UserProfile(**self.masaka_user).save()
        response = self.client.get(self.CSV_ENDPOINT, format='csv')

        expected_response = "name,phone,email,district,subcounty\r\n" \
                            "timothy,+256775019449,[email protected],%s,%s" % (self.district.name,'')
        expected_response = expected_response + "\r\nMunamasaka,+256775019441,[email protected],%s,%s" % (
            self.masaka.name, self.subcounty.name)

        self.assertEqual(200, response.status_code)
        self.assertEqual(2, len(response.data))
        self.assertTrue(isinstance(response.accepted_renderer, CSVRenderer))
        self.assertEqual(collections.Counter(split_text(expected_response)),
                         collections.Counter(split_text(response.content)))

    def test_should_return_csv_with_all_users_when_location_is_empty_when_csv_endpoint_is_called(
            self):
        self.mobile_user['email'] = '*****@*****.**'
        UserProfile(**self.mobile_user).save()
        UserProfile(**self.masaka_user).save()
        response = self.client.get(self.CSV_ENDPOINT + '?location=',
                                   format='csv')

        expected_response = "name,phone,email,district,subcounty\r\n" \
                            "timothy,+256775019449,[email protected],%s,%s" % (self.district.name,'')
        expected_response = expected_response + "\r\nMunamasaka,+256775019441,[email protected],%s,%s" % (
            self.masaka.name, self.subcounty.name)

        self.assertEqual(200, response.status_code)
        self.assertEqual(2, len(response.data))
        self.assertTrue(isinstance(response.accepted_renderer, CSVRenderer))
        self.assertEqual(collections.Counter(split_text(expected_response)),
                         collections.Counter(split_text(response.content)))

    def test_should_return_filtered_csv_when_csv_endpoint_is_called_with_location_filter(
            self):
        self.mobile_user['email'] = '*****@*****.**'
        UserProfile(**self.mobile_user).save()
        UserProfile(**self.masaka_user).save()
        response = self.client.get(self.CSV_ENDPOINT +
                                   '?location=%s' % self.masaka.id,
                                   format='csv')

        expected_response = "name,phone,email,district,subcounty\r\n" \
                            "Munamasaka,+256775019441,[email protected],%s,%s" % (self.masaka.name, self.subcounty.name)
        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.data))
        self.assertTrue(isinstance(response.accepted_renderer, CSVRenderer))
        result_set = set(split_text(expected_response)) & set(
            split_text(response.content))
        self.assertEqual(collections.Counter(split_text(expected_response)),
                         collections.Counter(split_text(response.content)))

    def test_should_bulk_save_streamed_csv_user_profiles(self):
        dup_user = self.masaka_user.copy()
        dup_user['name'] = 'AnotherMasakarian'
        UserProfile(**dup_user).save()
        self.assertEqual(dup_user['name'],
                         UserProfile.objects(**dup_user).first().name)
        dup_user['name'] = 'NamedChanged'
        bulk_mobile_users = [
            {
                "name": "%s" % self.masaka_user['name'],
                "phone": "%s" % self.masaka_user['phone'],
                "email": "%s" % self.masaka_user['email'],
                "district": "%s" % self.masaka.name,
                "subcounty": "%s" % self.subcounty.name,
            },
            {
                "name": "%s" % self.mobile_user['name'],
                "phone": "%s" % self.mobile_user['phone'],
                "email": None,
                "district": "%s" % self.district.name,
                "subcounty": "%s" % '',
            },
            {
                "name": "%s" % dup_user['name'],
                "phone": "%s" % dup_user['phone'],
                "email": "%s" % dup_user['email'],
                "district": "%s" % self.masaka.name,
                "subcounty": "%s" % self.subcounty.name,
            },
        ]

        response = self.client.post(self.BULK_ENDPOINT,
                                    bulk_mobile_users,
                                    format='json')

        self.assertEqual(2, UserProfile.objects.count())
        response = UserProfile.objects(**self.masaka_user)
        self.assertEqual(0, response.count())
        response = UserProfile.objects(**dup_user)
        self.assertEqual(1, response.count())
        self.assertEqual(dup_user['name'],
                         UserProfile.objects(**dup_user).first().name)
        self.mobile_user['email'] = ""  #empty string is not equal to None
        response = UserProfile.objects(**self.mobile_user)
        self.assertEqual(1, response.count())

    def test_should_omit_invalid_csv_rows_but_save_valid_ones(self):

        bulk_mobile_users = [
            {
                "name": "new name",
                "phone": "+256771289018",
                "email": "*****@*****.**",
                "district": "%s" % self.masaka.name,
                "subcounty": "unknownSub",  #unknown subcounty
            },
            {
                "name": "new name",
                "phone": "+256771289018",
                "email": "*****@*****.**",
                "district": "unknowndistrict",  #unknown district
                "subcounty": None,
            },
            {
                "name": "new name",
                "phone": "+256771289018",
                "email": "*****@*****.**",
                "district": "unknowndistrict",  #unknown district
                "subcounty": "badsubcounty",  #unknown subcounty
            },
            {
                "name": "%s" % self.mobile_user['name'],
                "phone": "%s" % self.mobile_user['phone'],
                "email": None,
                "district": "%s" % self.district.name,
                "subcounty": "%s" % '',
            },
        ]

        response = self.client.post(self.BULK_ENDPOINT,
                                    bulk_mobile_users,
                                    format='json')

        self.assertEqual(1, UserProfile.objects.count())
        masaka_users = UserProfile.objects(name=self.masaka_user['name'])
        self.assertEqual(0, masaka_users.count())
        self.mobile_user['email'] = ""  #empty string is not equal to None
        kampala_users = UserProfile.objects(**self.mobile_user)
        self.assertEqual(1, kampala_users.count())

    def test_should_omit_empty_csv_rows(self):

        bulk_mobile_users = [
            {
                "name": "new name",
                "phone": "+256771289018",
                "email": "*****@*****.**",
                "district": "%s" % self.masaka.name,
                "subcounty": "unknownSub",
            },
            {},
            {
                "name": "%s" % self.mobile_user['name'],
                "phone": "%s" % self.mobile_user['phone'],
                "email": None,
                "district": "%s" % self.district.name,
                "subcounty": "%s" % '',
            },
        ]

        response = self.client.post(self.BULK_ENDPOINT,
                                    bulk_mobile_users,
                                    format='json')

        self.assertEqual(1, UserProfile.objects.count())
        masaka_users = UserProfile.objects(name=self.masaka_user['name'])
        self.assertEqual(0, masaka_users.count())
        self.mobile_user['email'] = ""  #empty string is not equal to None
        kampala_users = UserProfile.objects(**self.mobile_user)
        self.assertEqual(1, kampala_users.count())

    def test_should_omit_blank_csv(self):

        bulk_mobile_users = [
            {},
        ]

        response = self.client.post(self.BULK_ENDPOINT,
                                    bulk_mobile_users,
                                    format='json')
        self.assertEqual(0, UserProfile.objects.count())
Exemplo n.º 9
0
class TestUserProfileModel(MongoTestCase):
    def setUp(self):
        self.district = Location(**dict(name='Kampala', type='district', parent=None))
        self.district.save()

    def tearDown(self):
        UserProfile.drop_collection()

    def test_should_create_new_user(self):
        mobile_user = dict(name='timothy', phone='+256775019449', location=self.district, email=None)
        UserProfile(**mobile_user).save()
        saved_mobile_user = UserProfile.objects(**mobile_user)
        self.assertEqual(1, saved_mobile_user.count())

    def test_should_not_save_a_user_without_a_phone_number_and_location(self):
        mobile_user = dict(name='timothy', email=None)
        self.assertRaises(ValidationError, UserProfile(**mobile_user).save)

    def test_should_not_save_a_users_with_the_same_phone_number(self):
        mobile_user_one = dict(name='timothy', phone='+256775019449', location=self.district, email=None)
        mobile_user_two = dict(name='James', phone='+256775019449', location=self.district, email=None)

        UserProfile(**mobile_user_one).save()
        self.assertRaises(NotUniqueError, UserProfile(**mobile_user_two).save)

    def test_saving_a_system_user(self):
        user = User(username='******', password='******').save()
        user_profile_attr = dict(name='timothy', phone='+256775019449', location=self.district, email=None, user=user)

        UserProfile(**user_profile_attr).save()

        self.assertEqual(user, UserProfile.objects.get(**user_profile_attr).user)

    def test_get_username(self):
        user = User(username='******', password='******').save()
        user_profile_attr = dict(name='timothy', phone='+256775019449', location=self.district, email=None, user=user)
        profile = UserProfile(**user_profile_attr).save()

        self.assertEqual('haha', profile.username())

    def test_get_user_id(self):
        user = User(username='******', password='******').save()
        user_profile_attr = dict(name='timothy', phone='+256775019449', location=self.district, email=None, user=user)
        profile = UserProfile(**user_profile_attr).save()

        self.assertEqual(str(user.id), profile.user_id())

    def test_get_username_from_regular_user(self):
        user_profile_attr = dict(name='timothy', phone='+256775019449', location=self.district, email=None)
        profile = UserProfile(**user_profile_attr).save()

        self.assertEqual('', profile.username())

    def test_should_save_photo_of_user(self):
        user_profile_attr = dict(name='timothy', phone='+256775019449', location=self.district, email=None)
        profile = UserProfile(**user_profile_attr)
        user_photo = open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg', 'rb')
        profile.photo.put(user_photo, content_type='image/content_type')
        profile.save()
        reloaded_profile = UserProfile.objects(id=profile.id).first()
        self.assertEqual(reloaded_profile.photo.read(),
                         open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg', 'rb').read())
        self.assertEqual(reloaded_profile.photo.content_type, 'image/content_type')
        self.assertEqual(reloaded_profile.photo_uri(), '/api/v1/photo/' + str(reloaded_profile.id))
Exemplo n.º 10
0
class TestUserProfileModel(MongoTestCase):
    def setUp(self):
        self.district = Location(
            **dict(name='Kampala', type='district', parent=None))
        self.district.save()

    def tearDown(self):
        UserProfile.drop_collection()

    def test_should_create_new_user(self):
        mobile_user = dict(name='timothy',
                           phone='+256775019449',
                           location=self.district,
                           email=None)
        UserProfile(**mobile_user).save()
        saved_mobile_user = UserProfile.objects(**mobile_user)
        self.assertEqual(1, saved_mobile_user.count())

    def test_should_not_save_a_user_without_a_phone_number_and_location(self):
        mobile_user = dict(name='timothy', email=None)
        self.assertRaises(ValidationError, UserProfile(**mobile_user).save)

    def test_should_not_save_a_users_with_the_same_phone_number(self):
        mobile_user_one = dict(name='timothy',
                               phone='+256775019449',
                               location=self.district,
                               email=None)
        mobile_user_two = dict(name='James',
                               phone='+256775019449',
                               location=self.district,
                               email=None)

        UserProfile(**mobile_user_one).save()
        self.assertRaises(NotUniqueError, UserProfile(**mobile_user_two).save)

    def test_saving_a_system_user(self):
        user = User(username='******', password='******').save()
        user_profile_attr = dict(name='timothy',
                                 phone='+256775019449',
                                 location=self.district,
                                 email=None,
                                 user=user)

        UserProfile(**user_profile_attr).save()

        self.assertEqual(user,
                         UserProfile.objects.get(**user_profile_attr).user)

    def test_get_username(self):
        user = User(username='******', password='******').save()
        user_profile_attr = dict(name='timothy',
                                 phone='+256775019449',
                                 location=self.district,
                                 email=None,
                                 user=user)
        profile = UserProfile(**user_profile_attr).save()

        self.assertEqual('haha', profile.username())

    def test_get_user_id(self):
        user = User(username='******', password='******').save()
        user_profile_attr = dict(name='timothy',
                                 phone='+256775019449',
                                 location=self.district,
                                 email=None,
                                 user=user)
        profile = UserProfile(**user_profile_attr).save()

        self.assertEqual(str(user.id), profile.user_id())

    def test_get_username_from_regular_user(self):
        user_profile_attr = dict(name='timothy',
                                 phone='+256775019449',
                                 location=self.district,
                                 email=None)
        profile = UserProfile(**user_profile_attr).save()

        self.assertEqual('', profile.username())

    def test_should_save_photo_of_user(self):
        user_profile_attr = dict(name='timothy',
                                 phone='+256775019449',
                                 location=self.district,
                                 email=None)
        profile = UserProfile(**user_profile_attr)
        user_photo = open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg',
                          'rb')
        profile.photo.put(user_photo, content_type='image/content_type')
        profile.save()
        reloaded_profile = UserProfile.objects(id=profile.id).first()
        self.assertEqual(
            reloaded_profile.photo.read(),
            open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg',
                 'rb').read())
        self.assertEqual(reloaded_profile.photo.content_type,
                         'image/content_type')
        self.assertEqual(reloaded_profile.photo_uri(),
                         '/api/v1/photo/' + str(reloaded_profile.id))
class TestUserProfileEndpoint(MongoAPITestCase):
    API_ENDPOINT = '/api/v1/mobile-users/'
    CSV_ENDPOINT = '/api/v1/csv-mobile-users/'
    BULK_ENDPOINT = '/api/v1/bulk-mobile-users/'

    def setUp(self):
        self.login_user()
        self.district = Location(**dict(name='Kampala', type='district', parent=None))
        self.district.save()
        self.masaka = Location(**dict(name='Masaka', type='district', parent=None)).save()
        self.subcounty = Location(**dict(name='Nangabo', type='subcounty', parent=self.masaka)).save()

        self.mobile_user_to_post = dict(name='tim', phone='+256775019500', location=self.district.id,
                                        email='*****@*****.**')
        self.mobile_user = dict(name='timothy', phone='+256775019449', location=self.district, email=None)
        self.masaka_user = dict(name='Munamasaka', phone='+256775019441', location=self.subcounty, email='*****@*****.**')

    def tearDown(self):
        UserProfile.drop_collection()

    def test_should_post_a_mobile_user(self):
        response = self.client.post(self.API_ENDPOINT, data=self.mobile_user_to_post)
        self.assertEqual(201, response.status_code)

        retrieved_user = UserProfile.objects(name='tim')
        self.assertEqual(1, retrieved_user.count())

    def test_should_get_a_list_of_users(self):
        user_profile = UserProfile(**self.mobile_user).save()
        response = self.client.get(self.API_ENDPOINT, format='json')

        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.data))
        self.assertEqual(self.mobile_user['name'], response.data[0]['name'])
        self.assertEqual(self.mobile_user['phone'], response.data[0]['phone'])
        self.assertEqual(self.mobile_user['email'], response.data[0]['email'])
        self.assertEqual(user_profile.username(), '')
        self.assertEqual(self.district.name, response.data[0]['location']['name'])

    def test_should_get_ordered_list_of_users(self):
        mob_users = [('aa', '+256775019441'), ('zz', '+256775019442'), ('tim', '+256775019443'), ('abu' , '+256775019444')]
        for user_name, mob in mob_users:
            new_dict = dict_replace('name', user_name, self.mobile_user)
            new_dict = dict_replace('phone', mob, new_dict)
            UserProfile(**new_dict).save()
            time.sleep(1)
        response = self.client.get(self.API_ENDPOINT, format='json')

        self.assertEqual(200, response.status_code)
        self.assertEqual(len(mob_users), len(response.data))
        self.assertEqual(response.data[0]['name'], 'abu')
        self.assertEqual(response.data[3]['name'], 'aa')

        #post order by name
        response = self.client.get(self.API_ENDPOINT + '?ordering=name', format='json')
        self.assertEqual(200, response.status_code)
        self.assertEqual(response.data[0]['name'], 'aa')
        self.assertEqual(response.data[1]['name'], 'abu')
        self.assertEqual(response.data[2]['name'], 'tim')
        self.assertEqual(response.data[3]['name'], 'zz')

        #post order by name desc
        response = self.client.get(self.API_ENDPOINT + '?ordering=-name', format='json')
        self.assertEqual(200, response.status_code)
        self.assertEqual(response.data[0]['name'], 'zz')
        self.assertEqual(response.data[1]['name'], 'tim')
        self.assertEqual(response.data[2]['name'], 'abu')
        self.assertEqual(response.data[3]['name'], 'aa')



    def test_raise_403_if_user_doesnt_have_manage_permission(self):
        self.assert_permission_required_for_get(self.API_ENDPOINT)
        self.assert_permission_required_for_post(self.API_ENDPOINT)

    def test_should_get_a_single_user(self):
        attr = self.mobile_user.copy()
        user = User(username='******', password='******').save()
        attr['user'] = user
        profile = UserProfile(**attr).save()

        response = self.client.get(self.API_ENDPOINT + str(profile.id) + '/')

        self.assertEqual(200, response.status_code)
        self.assertEqual(self.mobile_user['name'], response.data['name'])
        self.assertEqual(self.mobile_user['phone'], response.data['phone'])
        self.assertEqual(self.mobile_user['email'], response.data['email'])
        self.assertEqual(self.district.name, response.data['location']['name'])
        self.assertEqual('cage', response.data['username'])
        self.assertEqual(str(user.id), response.data['user_id'])


    def test_should_update_a_single_user(self):
        attr = self.mobile_user.copy()
        attr['email'] = '*****@*****.**'
        attr['phone'] = '+256775019500'
        attr['user'] = User(username='******', password='******').save()
        profile = UserProfile(**attr).save()
        response = self.client.post(self.API_ENDPOINT + str(profile.id) + '/', self.mobile_user_to_post)

        profile.reload()
        profiles = UserProfile.objects()
        self.assertEqual(1, profiles.count())

        self.assertEqual(200, response.status_code)
        self.assertEqual(self.mobile_user_to_post['name'], profile.name)
        self.assertEqual(self.mobile_user_to_post['phone'], profile.phone)
        self.assertEqual(self.mobile_user_to_post['email'], profile.email)

    def test_raise_403_given_user_is_trying_to_access_some_other_users_profile(self):
        attr = self.mobile_user.copy()
        attr['email'] = '*****@*****.**'
        attr['phone'] = '+256775029500'
        attr['user'] = User(username='******', password='******').save()
        profile = UserProfile(**attr).save()
        self.assert_permission_required_for_get(self.API_ENDPOINT + str(profile.id) + '/')
        self.assert_permission_required_for_post(self.API_ENDPOINT + str(profile.id) + '/')

    def test_not_raising_403_if_user_only_wants_access_to_their_profile(self):
        self.client.logout()
        attr = self.mobile_user.copy()
        attr['email'] = '*****@*****.**'
        attr['phone'] = '+256775029500'
        user = User(username='******', email='*****@*****.**')
        user.group = None
        user.set_password('hahahah')
        attr['user'] = user
        profile = UserProfile(**attr).save()
        self.client.login(username='******', password='******')

        response = self.client.get(self.API_ENDPOINT + str(profile.id) + '/')
        self.assertEquals(response.status_code, 200)
        response = self.client.post(self.API_ENDPOINT + str(profile.id) + '/')
        self.assertEquals(response.status_code, 200)

    def test_post_with_non_empty_username_creates_system_user(self):
        attr = self.mobile_user_to_post.copy()
        attr['username'] = '******'
        response = self.client.post(self.API_ENDPOINT, data=attr)
        self.assertEqual(201, response.status_code)

        retrieved_user_profile = UserProfile.objects(name='tim')
        self.assertEqual(1, retrieved_user_profile.count())

        retrieved_user = User.objects(username='******')
        self.assertEqual(1, retrieved_user.count())
        self.assertEqual(retrieved_user.first(), retrieved_user_profile.first().user)

    @mock.patch('dms.tasks.send_email.delay')
    def test_posting_new_system_user_sends_email(self, mock_send_email):
        attr = self.mobile_user_to_post.copy()
        attr['username'] = '******'
        attr['email'] = '*****@*****.**'
        response = self.client.post(self.API_ENDPOINT, data=attr)
        self.assertEqual(201, response.status_code)
        mock_send_email.assert_called_with('Your NECOC Account',
                                           mock.ANY,
                                           settings.DEFAULT_FROM_EMAIL,
                                           ['*****@*****.**'])

    def test_post_with_group_associates_user_to_group(self):
        attr = self.mobile_user_to_post.copy()
        attr['username'] = '******'
        group = Group.objects().first()
        attr['group'] = str(group.id)
        response = self.client.post(self.API_ENDPOINT, data=attr)
        self.assertEqual(201, response.status_code)

        retrieved_user = User.objects(username='******').first()
        self.assertEqual(group, retrieved_user.group)

    def test_update_with_group_associates_user_to_new_group(self):
        attr = self.mobile_user_to_post.copy()
        attr['username'] = '******'
        group = Group.objects().first()
        attr['group'] = str(group.id)
        self.client.post(self.API_ENDPOINT, data=attr)

        retrieved_user = User.objects(username='******').first()
        retrieved_user_profile = UserProfile.objects(user=retrieved_user).first()
        new_group = Group.objects().all()[2]

        new_attr = self.mobile_user_to_post.copy()
        new_attr['username'] = '******'
        new_attr['location'] = str(new_attr['location'])
        new_attr['group'] = str(new_group.id)
        new_attr['id'] = str(retrieved_user_profile.id)

        url = self.API_ENDPOINT + str(retrieved_user_profile.id) + '/'
        response = self.client.post(url,
                                    data=new_attr)
        self.assertEqual(200, response.status_code)
        retrieved_user = User.objects(username='******').first()
        self.assertEqual(new_group, retrieved_user.group)

    @mock.patch('dms.utils.image_resizer.ImageResizer', FakeImageResizer)
    def test_post_with_photo_file(self):
        attr = self.mobile_user_to_post.copy()
        attr['username'] = '******'

        with open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg', 'rb') as test_image:
            attr['file'] = test_image
            response = self.client.post(self.API_ENDPOINT, data=attr)

        self.assertEqual(201, response.status_code)

        retrieved_user = User.objects(username='******').first()
        reloaded_profile = UserProfile.objects(user=retrieved_user).first()
        self.assertEqual(reloaded_profile.photo.read(),
                         open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg', 'rb').read())
        self.assertEqual(reloaded_profile.photo.content_type, 'image/jpeg')
        self.assertEqual(reloaded_profile.photo_uri(), '/api/v1/photo/' + str(reloaded_profile.id))

    @mock.patch('dms.utils.image_resizer.ImageResizer', BadImageResizer)
    def test_post_with_photo_file(self):
        attr = self.mobile_user_to_post.copy()
        attr['username'] = '******'

        with open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg', 'rb') as test_image:
            attr['file'] = test_image
            response = self.client.post(self.API_ENDPOINT, data=attr)

        self.assertEqual(201, response.status_code)

        retrieved_user = User.objects(username='******').first()
        reloaded_profile = UserProfile.objects(user=retrieved_user).first()
        self.assertEqual(reloaded_profile.photo.read(), None)

    @mock.patch('dms.utils.image_resizer.ImageResizer', FakeImageResizer)
    def test_updating_profile_with_photo_file(self):
        attr = self.mobile_user_to_post.copy()
        attr['email'] = '*****@*****.**'
        attr['phone'] = '+256775019511'
        attr['user'] = User(username='******', password='******').save()
        profile = UserProfile(**attr)
        user_photo = open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg', 'rb')
        profile.photo.put(user_photo, content_type='image/content_type')
        profile.save()

        with open(settings.PROJECT_ROOT + '/../dms/tests/test2.jpg', 'rb') as test_image:
            attr['file'] = test_image
            response = self.client.post(self.API_ENDPOINT + str(profile.id) + '/', attr)
            self.assertEqual(200, response.status_code)

        retrieved_user = User.objects(username='******').first()
        reloaded_profile = UserProfile.objects(user=retrieved_user).first()
        self.assertEqual(reloaded_profile.photo.read(),
                         open(settings.PROJECT_ROOT + '/../dms/tests/test2.jpg', 'rb').read())
        self.assertEqual(reloaded_profile.photo.content_type, 'image/jpeg')
        self.assertEqual(reloaded_profile.photo_uri(), '/api/v1/photo/' + str(reloaded_profile.id))

    @mock.patch('dms.utils.image_resizer.ImageResizer', BadImageResizer)
    def test_handling_photo_update_exception(self):
        attr = self.mobile_user_to_post.copy()
        attr['email'] = '*****@*****.**'
        attr['phone'] = '+256775019511'
        attr['user'] = User(username='******', password='******').save()
        profile = UserProfile(**attr)
        user_photo = open(settings.PROJECT_ROOT + '/../dms/tests/test.jpg', 'rb')
        profile.photo.put(user_photo, content_type='image/content_type')
        profile.save()

        with open(settings.PROJECT_ROOT + '/../dms/tests/test2.jpg', 'rb') as test_image:
            attr['file'] = test_image
            response = self.client.post(self.API_ENDPOINT + str(profile.id) + '/', attr)
            self.assertEqual(200, response.status_code)

        retrieved_user = User.objects(username='******').first()
        reloaded_profile = UserProfile.objects(user=retrieved_user).first()
        self.assertEqual(reloaded_profile.photo.read(), None)

    def test_should_return_csv_when_csv_endpoint_is_called(self):
        self.mobile_user['email'] = '*****@*****.**'
        UserProfile(**self.mobile_user).save()
        UserProfile(**self.masaka_user).save()
        response = self.client.get(self.CSV_ENDPOINT, format='csv')

        expected_response = "name,phone,email,district,subcounty\r\n" \
                            "timothy,+256775019449,[email protected],%s,%s" % (self.district.name,'')
        expected_response = expected_response + "\r\nMunamasaka,+256775019441,[email protected],%s,%s" % (self.masaka.name, self.subcounty.name)

        self.assertEqual(200, response.status_code)
        self.assertEqual(2, len(response.data))
        self.assertTrue(isinstance(response.accepted_renderer, CSVRenderer))
        self.assertEqual(collections.Counter(split_text(expected_response)), collections.Counter(split_text(response.content)))

    def test_should_return_csv_with_all_users_when_location_is_empty_when_csv_endpoint_is_called(self):
        self.mobile_user['email'] = '*****@*****.**'
        UserProfile(**self.mobile_user).save()
        UserProfile(**self.masaka_user).save()
        response = self.client.get(self.CSV_ENDPOINT + '?location=', format='csv')

        expected_response = "name,phone,email,district,subcounty\r\n" \
                            "timothy,+256775019449,[email protected],%s,%s" % (self.district.name,'')
        expected_response = expected_response + "\r\nMunamasaka,+256775019441,[email protected],%s,%s" % (self.masaka.name, self.subcounty.name)

        self.assertEqual(200, response.status_code)
        self.assertEqual(2, len(response.data))
        self.assertTrue(isinstance(response.accepted_renderer, CSVRenderer))
        self.assertEqual(collections.Counter(split_text(expected_response)), collections.Counter(split_text(response.content)))

    def test_should_return_filtered_csv_when_csv_endpoint_is_called_with_location_filter(self):
        self.mobile_user['email'] = '*****@*****.**'
        UserProfile(**self.mobile_user).save()
        UserProfile(**self.masaka_user).save()
        response = self.client.get(self.CSV_ENDPOINT + '?location=%s' % self.masaka.id, format='csv')

        expected_response = "name,phone,email,district,subcounty\r\n" \
                            "Munamasaka,+256775019441,[email protected],%s,%s" % (self.masaka.name, self.subcounty.name)
        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.data))
        self.assertTrue(isinstance(response.accepted_renderer, CSVRenderer))
        result_set = set(split_text(expected_response)) & set(split_text(response.content))
        self.assertEqual(collections.Counter(split_text(expected_response)), collections.Counter(split_text(response.content)))

    def test_should_bulk_save_streamed_csv_user_profiles(self):
        dup_user = self.masaka_user.copy()
        dup_user['name'] = 'AnotherMasakarian'
        UserProfile(**dup_user).save()
        self.assertEqual(dup_user['name'], UserProfile.objects(**dup_user).first().name)
        dup_user['name'] = 'NamedChanged'
        bulk_mobile_users = [
            {
                "name":"%s" % self.masaka_user['name'],
                "phone":"%s" % self.masaka_user['phone'],
                "email": "%s" % self.masaka_user['email'],
                "district": "%s" % self.masaka.name,
                "subcounty": "%s" % self.subcounty.name,
             },
            {
                "name":"%s" % self.mobile_user['name'],
                "phone":"%s" % self.mobile_user['phone'],
                "email": None,
                "district": "%s" % self.district.name,
                "subcounty": "%s" % '',
             },
            {
                "name":"%s" % dup_user['name'],
                "phone":"%s" % dup_user['phone'],
                "email": "%s" % dup_user['email'],
                "district": "%s" % self.masaka.name,
                "subcounty": "%s" % self.subcounty.name,
             },
        ]

        response = self.client.post(self.BULK_ENDPOINT, bulk_mobile_users, format='json')

        self.assertEqual(2, UserProfile.objects.count())
        response = UserProfile.objects(**self.masaka_user)
        self.assertEqual(0, response.count())
        response = UserProfile.objects(**dup_user)
        self.assertEqual(1, response.count())
        self.assertEqual(dup_user['name'], UserProfile.objects(**dup_user).first().name)
        self.mobile_user['email']="" #empty string is not equal to None
        response = UserProfile.objects(**self.mobile_user)
        self.assertEqual(1, response.count())

    def test_should_omit_invalid_csv_rows_but_save_valid_ones(self):

        bulk_mobile_users = [
            {
                "name":"new name",
                "phone":"+256771289018",
                "email": "*****@*****.**",
                "district": "%s" % self.masaka.name,
                "subcounty": "unknownSub", #unknown subcounty
             },
            {
                "name":"new name",
                "phone":"+256771289018",
                "email": "*****@*****.**",
                "district": "unknowndistrict", #unknown district
                "subcounty": None,
             },
            {
                "name":"new name",
                "phone":"+256771289018",
                "email": "*****@*****.**",
                "district": "unknowndistrict", #unknown district
                "subcounty": "badsubcounty", #unknown subcounty
             },
            {
                "name":"%s" % self.mobile_user['name'],
                "phone":"%s" % self.mobile_user['phone'],
                "email": None,
                "district": "%s" % self.district.name,
                "subcounty": "%s" % '',
             },
        ]

        response = self.client.post(self.BULK_ENDPOINT, bulk_mobile_users, format='json')

        self.assertEqual(1, UserProfile.objects.count())
        masaka_users = UserProfile.objects(name=self.masaka_user['name'])
        self.assertEqual(0, masaka_users.count())
        self.mobile_user['email']="" #empty string is not equal to None
        kampala_users = UserProfile.objects(**self.mobile_user)
        self.assertEqual(1, kampala_users.count())

    def test_should_omit_empty_csv_rows(self):

        bulk_mobile_users = [
            {
                "name":"new name",
                "phone":"+256771289018",
                "email": "*****@*****.**",
                "district": "%s" % self.masaka.name,
                "subcounty": "unknownSub",
             },
            {},
            {
                "name":"%s" % self.mobile_user['name'],
                "phone":"%s" % self.mobile_user['phone'],
                "email": None,
                "district": "%s" % self.district.name,
                "subcounty": "%s" % '',
             },
        ]

        response = self.client.post(self.BULK_ENDPOINT, bulk_mobile_users, format='json')

        self.assertEqual(1, UserProfile.objects.count())
        masaka_users = UserProfile.objects(name=self.masaka_user['name'])
        self.assertEqual(0, masaka_users.count())
        self.mobile_user['email']="" #empty string is not equal to None
        kampala_users = UserProfile.objects(**self.mobile_user)
        self.assertEqual(1, kampala_users.count())

    def test_should_omit_blank_csv(self):

        bulk_mobile_users = [
            {},
        ]

        response = self.client.post(self.BULK_ENDPOINT, bulk_mobile_users, format='json')
        self.assertEqual(0, UserProfile.objects.count())
Exemplo n.º 12
0
class TestDisasterEndpoint(MongoAPITestCase):

    API_ENDPOINT = '/api/v1/disasters/'
    CSV_ENDPOINT = '/api/v1/csv-disasters/'

    def setUp(self):
        self.user = self.login_user()
        self.district = Location(**dict(name='Kampala', type='district', parent=None))
        self.district.save()
        self.disaster_type = DisasterType(**dict(name="Fire", description="Fire"))
        self.disaster_type.save()
        self.disaster_type2 = DisasterType(**dict(name="Flood", description="Flood"))
        self.disaster_type2.save()
        self.disaster_to_post = dict(name=str(self.disaster_type.id), locations=[str(self.district.id)],
                                     description="Big Flood", date="2014-12-01 00:00:00", status="Assessment")
        self.disaster = dict(name=self.disaster_type, locations=[self.district],
                             description="Big Flood", date="2014-12-01 00:00:00", status="Assessment")

        self.mobile_user = UserProfile(**dict(name='timothy', phone="+256775019449",
                                             location=self.district, email=None)).save()
        self.cao_group, created = Group.objects.get_or_create(name='CAO')

    def test_should_post_a_disaster(self):
        response = self.client.post(self.API_ENDPOINT, data=json.dumps(self.disaster_to_post), content_type="application/json")
        self.assertEqual(201, response.status_code)

        retrieved_disaster = Disaster.objects(description="Big Flood")
        self.assertEqual(1, retrieved_disaster.count())

    def test_should_get_a_list_of_disasters(self):
        Disaster(**self.disaster).save()
        response = self.client.get(self.API_ENDPOINT, format='json')

        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.data))
        self.assertEqual(self.disaster_to_post['status'], response.data[0]['status'])
        self.assertEqual(self.disaster_to_post['date'], str(response.data[0]['date']))
        self.assertEqual(self.disaster_to_post['description'], response.data[0]['description'])

    def test_can_get_a_list_of_disasters_with_no_permissions(self):
        self.login_without_permissions()
        response = self.client.get(self.API_ENDPOINT)
        self.assertEquals(response.status_code, 200)

    def test_cant_post_to_disasters_without_permission(self):
        self.assert_permission_required_for_post(self.API_ENDPOINT)

    def test_can_post_to_disasters_with_permission(self):
        self.login_with_permission('can_manage_disasters')
        response = self.client.get(self.API_ENDPOINT)
        self.assertEquals(response.status_code, 200)
        response = self.client.post(self.API_ENDPOINT, data=json.dumps(self.disaster_to_post), content_type="application/json")
        self.assertEqual(201, response.status_code)

    def test_should_get_a_single_disaster(self):
        disaster = Disaster(**self.disaster).save()
        response = self.client.get(self.API_ENDPOINT + str(disaster.id) + '/', format='json')

        self.assertEqual(200, response.status_code)
        self.assertEqual(self.disaster_to_post['status'], response.data['status'])
        self.assertEqual(self.disaster_to_post['date'], str(response.data['date']))
        self.assertEqual(self.disaster_to_post['description'], response.data['description'])

    def test_cant_get_or_post_single_disaster_without_permission(self):
        disaster = Disaster(**self.disaster).save()
        self.assert_permission_required_for_get(self.API_ENDPOINT + str(disaster.id) + '/')
        self.assert_permission_required_for_post(self.API_ENDPOINT + str(disaster.id) + '/')

    def test_should_post_a_single_disaster(self):
        disaster = Disaster(**self.disaster_to_post).save()
        self.disaster_to_post['description'] = "Giant Flood"
        response = self.client.post(self.API_ENDPOINT + str(disaster.id) + '/',
                                    data=json.dumps(self.disaster_to_post),
                                    content_type="application/json")
        self.assertEqual(200, response.status_code)

        retrieved_disaster = Disaster.objects(description="Giant Flood")
        self.assertEqual(1, retrieved_disaster.count())

    def test_filter_disaster_by_status(self):
        Disaster(**self.disaster).save()
        disaster_attr2 = self.disaster.copy()
        disaster_attr2['status'] = "Closed"
        Disaster(**disaster_attr2).save()

        response = self.client.get(self.API_ENDPOINT+'?status=Closed&format=json')

        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.data))
        self.assertEqual('Closed', response.data[0]['status'])
        self.assertEqual(self.disaster_to_post['date'], str(response.data[0]['date']))
        self.assertEqual(self.disaster_to_post['description'], response.data[0]['description'])

    def test_filter_disaster_by_date(self):
        disaster_attr = self.disaster.copy()
        date_1_jan = "2014-01-01"
        disaster_attr['date'] = date_1_jan

        disaster_attr2 = self.disaster.copy()
        date_3_jan = "2014-01-03"
        disaster_attr2['date'] = date_3_jan

        Disaster(**disaster_attr).save()
        Disaster(**disaster_attr2).save()

        response = self.client.get(self.API_ENDPOINT+'?from=%s&to=%s&format=json' % (date_1_jan, date_3_jan))

        self.assertEqual(200, response.status_code)
        self.assertEqual(2, len(response.data))
        self.assertEqual(datetime.datetime.strptime(date_1_jan, "%Y-%m-%d"), response.data[0]['date'])
        self.assertEqual(datetime.datetime.strptime(date_3_jan, "%Y-%m-%d"), response.data[1]['date'])

        response = self.client.get(self.API_ENDPOINT+'?from=%s&format=json' % date_3_jan)

        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.data))
        self.assertEqual(datetime.datetime.strptime(date_3_jan, "%Y-%m-%d"), response.data[0]['date'])

        response = self.client.get(self.API_ENDPOINT+'?to=%s&format=json' % date_1_jan)

        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.data))
        self.assertEqual(datetime.datetime.strptime(date_1_jan, "%Y-%m-%d"), response.data[0]['date'])

    def test_filter_disaster_by_date_and_date(self):
        disaster_attr = self.disaster.copy()
        date_1_jan = "2014-01-01"
        disaster_attr['date'] = date_1_jan

        disaster_attr2 = self.disaster.copy()
        date_3_jan = "2014-01-03"
        disaster_attr2['status'] = "Closed"
        disaster_attr2['date'] = date_3_jan

        Disaster(**disaster_attr).save()
        Disaster(**disaster_attr2).save()

        response = self.client.get(self.API_ENDPOINT+'?from=%s&to=%s&status=Closed&format=json' % (date_1_jan, date_3_jan))

        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.data))
        self.assertEqual(datetime.datetime.strptime(date_3_jan, "%Y-%m-%d"), response.data[0]['date'])

        response = self.client.get(self.API_ENDPOINT+'?from=%s&status=closed&format=json' % date_3_jan)

        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.data))
        self.assertEqual(datetime.datetime.strptime(date_3_jan, "%Y-%m-%d"), response.data[0]['date'])

        response = self.client.get(self.API_ENDPOINT+'?to=%s&status=assessment&format=json' % date_1_jan)

        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.data))
        self.assertEqual(datetime.datetime.strptime(date_1_jan, "%Y-%m-%d"), response.data[0]['date'])

    def test_should_return_only_district_disasters_for_CAO(self):
        self.user.group = self.cao_group
        self.user.save()
        self.mobile_user.user = self.user
        self.mobile_user.save()

        masaka_district = Location(**dict(name='Masaka', parent=None, type='district')).save()

        masaka_disaster = dict(name=self.disaster_type, locations=[masaka_district],
                             description="Big Flood", date="2014-12-01 00:00:00", status="Assessment")

        Disaster(**self.disaster).save()
        Disaster(**masaka_disaster).save()
        response = self.client.get(self.API_ENDPOINT, format='json')

        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.data))
        self.assertEqual(self.disaster_to_post['status'], response.data[0]['status'])
        self.assertEqual(self.disaster_to_post['date'], str(response.data[0]['date']))
        self.assertEqual(self.disaster_to_post['description'], response.data[0]['description'])
        self.assertEqual('Kampala', response.data[0]['locations'][0]['name'])

    def test_should_return_csv_when_csv_endpoint_is_called(self):
        Disaster(**self.disaster).save()
        disaster_attr2 = self.disaster.copy()
        disaster_attr2['status'] = "Closed"
        Disaster(**disaster_attr2).save()
        disaster2 = self.disaster.copy()
        disaster2['name'] = self.disaster_type2
        Disaster(**disaster2).save()

        response = self.client.get(self.CSV_ENDPOINT, format='csv')

        expected_response = "name,description,location,status,date\r\n" \
                            "Fire,Big Flood,%s,Assessment,2014-12-01 00:00:00" % (self.district.name,)
        expected_response = expected_response + "\r\nFire,Big Flood,%s,Closed,2014-12-01 00:00:00" % (self.district.name)
        expected_response = expected_response + "\r\nFlood,Big Flood,%s,Assessment,2014-12-01 00:00:00" % (self.district.name)

        self.assertEqual(200, response.status_code)
        self.assertEqual(3, len(response.data))
        self.assertTrue(isinstance(response.accepted_renderer, CSVRenderer))
        self.assertEqual(collections.Counter(split_text(expected_response)), collections.Counter(split_text(response.content)))

    def test_should_return_filtered_csv_when_csv_endpoint_is_called(self):
        Disaster(**self.disaster).save()
        disaster_attr2 = self.disaster.copy()
        disaster_attr2['status'] = "Closed"
        Disaster(**disaster_attr2).save()
        disaster2 = self.disaster.copy()
        disaster2['name'] = self.disaster_type2
        sdisaster = Disaster(**disaster2).save()

        response = self.client.get(self.CSV_ENDPOINT, format='csv')

        expected_response = "name,description,location,status,date\r\n" \
                            "Fire,Big Flood,%s,Assessment,2014-12-01 00:00:00" % (self.district.name,)
        expected_response = expected_response + "\r\nFire,Big Flood,%s,Closed,2014-12-01 00:00:00" % (self.district.name)
        expected_response = expected_response + "\r\nFlood,Big Flood,%s,Assessment,2014-12-01 00:00:00" % (self.district.name)

        self.assertEqual(200, response.status_code)
        self.assertEqual(3, len(response.data))
        self.assertTrue(isinstance(response.accepted_renderer, CSVRenderer))
        self.assertEqual(collections.Counter(split_text(expected_response)), collections.Counter(split_text(response.content)))

        response = self.client.get(self.CSV_ENDPOINT + '?status=Assessment&from=undefined', format='csv')

        expected_response = "name,description,location,status,date\r\n" \
                            "Fire,Big Flood,%s,Assessment,2014-12-01 00:00:00" % (self.district.name,)
        expected_response = expected_response + "\r\nFlood,Big Flood,%s,Assessment,2014-12-01 00:00:00" % (self.district.name)

        self.assertEqual(200, response.status_code)
        self.assertEqual(2, len(response.data))
        self.assertTrue(isinstance(response.accepted_renderer, CSVRenderer))
        self.assertEqual(collections.Counter(split_text(expected_response)), collections.Counter(split_text(response.content)))

        sdisaster.date = "2014-12-02 00:00:00"
        sdisaster.save()

        response = self.client.get(self.CSV_ENDPOINT + '?status=Assessment&from=2014-12-02 00:00:00', format='csv')

        expected_response = "name,description,location,status,date\r\n" \
                            "Flood,Big Flood,%s,Assessment,2014-12-02 00:00:00" % (self.district.name)

        self.assertEqual(200, response.status_code)
        self.assertEqual(1, len(response.data))
        self.assertTrue(isinstance(response.accepted_renderer, CSVRenderer))
        self.assertEqual(collections.Counter(split_text(expected_response)), collections.Counter(split_text(response.content)))

        response = self.client.get(self.CSV_ENDPOINT + '?to=2014-12-01 00:00:00', format='csv')

        expected_response = "name,description,location,status,date\r\n" \
                            "Fire,Big Flood,%s,Assessment,2014-12-01 00:00:00" % (self.district.name,)
        expected_response = expected_response + "\r\nFire,Big Flood,%s,Closed,2014-12-01 00:00:00" % (self.district.name)

        self.assertEqual(200, response.status_code)
        self.assertEqual(2, len(response.data))
        self.assertTrue(isinstance(response.accepted_renderer, CSVRenderer))
        self.assertEqual(collections.Counter(split_text(expected_response)), collections.Counter(split_text(response.content)))

    def test_should_return_csv_with_all_records_when_empty_filters_are_used_on_csv_endpoint(self):
        Disaster(**self.disaster).save()
        disaster_attr2 = self.disaster.copy()
        disaster_attr2['status'] = "Closed"
        Disaster(**disaster_attr2).save()
        disaster2 = self.disaster.copy()
        disaster2['name'] = self.disaster_type2
        sdisaster = Disaster(**disaster2).save()

        response = self.client.get(self.CSV_ENDPOINT + '?status=undefined&from=undefined&to=undefined', format='csv')

        expected_response = "name,description,location,status,date\r\n" \
                            "Fire,Big Flood,%s,Assessment,2014-12-01 00:00:00" % (self.district.name,)
        expected_response = expected_response + "\r\nFire,Big Flood,%s,Closed,2014-12-01 00:00:00" % (self.district.name)
        expected_response = expected_response + "\r\nFlood,Big Flood,%s,Assessment,2014-12-01 00:00:00" % (self.district.name)

        self.assertEqual(200, response.status_code)
        self.assertEqual(3, len(response.data))
        self.assertTrue(isinstance(response.accepted_renderer, CSVRenderer))
        self.assertEqual(collections.Counter(split_text(expected_response)), collections.Counter(split_text(response.content)))

    @mock.patch('dms.tasks.send_email.delay')
    def test_changing_disaster_status_sends_email_to_stakeholders(self, mock_send_email):
        disaster = Disaster(**self.disaster).save()
        disaster.status = 'Closed'
        disaster.save()
        mock_send_email.assert_called_with('Status of Disaster Risk has changed',
                                           mock.ANY,
                                           settings.DEFAULT_FROM_EMAIL,
                                           settings.DISASTER_NOTIFY_STATUS)