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))
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)
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())
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 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())
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)