def test_data_anon(self): view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/') formid = self.xform.pk response = view(request, pk=formid) # permission denied for anonymous access to private data self.assertEqual(response.status_code, 401) self.xform.shared_data = True self.xform.save() response = view(request, pk=formid) # access to a public data self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = { u'_bamboo_dataset_id': u'', u'_attachments': [], u'_geolocation': [None, None], u'_xform_id_string': u'transportation_2011_07_25', u'transport/available_transportation_types_to_referral_facility': u'none', u'_status': u'submitted_via_web', u'_id': dataid } self.assertDictContainsSubset(data, sorted(response.data)[0]) view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, dict) self.assertDictContainsSubset(data, response.data)
def test_data(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request) self.assertEqual(response.status_code, 200) formid = self.xform.pk data = _data_list(formid) self.assertEqual(response.data, data) # redo the request since it's been consummed request = self.factory.get('/', **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = _data_instance(dataid) self.assertDictContainsSubset(data, sorted(response.data)[0]) view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, dict) self.assertDictContainsSubset(data, response.data)
def test_data_bad_dataid(self): view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request) self.assertEqual(response.status_code, 200) formid = self.xform.pk data = [{ u'id': formid, u'id_string': u'transportation_2011_07_25', u'title': 'transportation_2011_07_25', u'description': 'transportation_2011_07_25', u'url': u'http://testserver/api/v1/data/%s' % formid }] self.assertEqual(response.data, data) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = 'INVALID' data = { u'_bamboo_dataset_id': u'', u'_attachments': [], u'_geolocation': [None, None], u'_xform_id_string': u'transportation_2011_07_25', u'transport/available_transportation_types_to_referral_facility': u'none', u'_status': u'submitted_via_web', u'_id': dataid } view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, 400)
def test_geojson_polygon(self): self._publish_submit_geojson() dataid = self.xform.instances.all().order_by('id')[0].pk data_get = {"geo_field": 'shape', "fields": 'today,shape'} view = DataViewSet.as_view({'get': 'retrieve'}) request = self.factory.get('/', data=data_get, **self.extra) response = view(request, pk=self.xform.pk, dataid=dataid, format='geojson') self.assertEqual(response.status_code, 200) self.assertEquals(response.data['type'], 'Feature') self.assertEquals(len(response.data['geometry']['coordinates'][0]), 6) self.assertIn('shape', response.data['properties']) self.assertEquals(response.data['geometry']['type'], 'Polygon') view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', data=data_get, **self.extra) response = view(request, pk=self.xform.pk, format='geojson') self.assertEqual(response.status_code, 200) self.assertEquals(response.data['type'], 'FeatureCollection') self.assertEquals(len(response.data['features']), 4) self.assertEquals(response.data['features'][0]['type'], 'Feature') self.assertEquals(response.data['features'][0]['geometry']['type'], 'Polygon')
def test_data(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request) self.assertEqual(response.status_code, status.HTTP_200_OK) formid = self.xform.pk data = _data_list(formid) self.assertEqual(response.data, data) # redo the request since it's been consummed request = self.factory.get('/', **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = _data_instance(dataid) self.assertDictContainsSubset(data, sorted(response.data)[0]) view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertIsInstance(response.data, dict) self.assertDictContainsSubset(data, response.data)
def test_data_w_attachment(self): self._submit_transport_instance_w_attachment() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request) self.assertEqual(response.status_code, status.HTTP_200_OK) formid = self.xform.pk data = _data_list(formid) self.assertEqual(response.data, data) response = view(request, pk=formid) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = { '_attachments': [{ 'download_url': self.attachment.secure_url(), 'download_small_url': self.attachment.secure_url('small'), 'download_medium_url': self.attachment.secure_url('medium'), 'download_large_url': self.attachment.secure_url('large'), 'mimetype': self.attachment.mimetype, 'instance': self.attachment.instance.pk, 'filename': self.attachment.media_file.name, 'id': self.attachment.pk, 'xform': self.xform.id }], '_geolocation': [None, None], '_xform_id_string': 'transportation_2011_07_25', 'transport/available_transportation_types_to_referral_facility': 'none', '_status': 'submitted_via_web', '_id': dataid } self.assertDictContainsSubset(data, sorted(response.data)[0]) data = { '_xform_id_string': 'transportation_2011_07_25', 'transport/available_transportation_types_to_referral_facility': 'none', '_submitted_by': 'bob', } view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertIsInstance(response.data, dict) self.assertDictContainsSubset(data, response.data)
def test_data_in_public_project(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) formid = self.xform.pk response = view(request, pk=formid) self.assertEquals(response.status_code, 200) self.assertEqual(len(response.data), 4) # get project id projectid = self.xform.project.pk view = ProjectViewSet.as_view({ 'put': 'update' }) data = {'shared': True, 'name': 'test project', 'owner': 'http://testserver/api/v1/users/%s' % self.user.username} request = self.factory.put('/', data=data, **self.extra) response = view(request, pk=projectid) self.assertEqual(response.status_code, 200) # anonymous user view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/') formid = self.xform.pk response = view(request, pk=formid) self.assertEquals(response.status_code, 200) self.assertEqual(len(response.data), 4)
def test_data_anon(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/') formid = self.xform.pk response = view(request, pk=formid) # data not found for anonymous access to private data self.assertEqual(response.status_code, 404) self.xform.shared_data = True self.xform.save() response = view(request, pk=formid) # access to a public data self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = _data_instance(dataid) self.assertDictContainsSubset(data, sorted(response.data)[0]) data = { u'_xform_id_string': u'transportation_2011_07_25', u'transport/available_transportation_types_to_referral_facility': u'none', u'_submitted_by': u'bob', } view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, dict) self.assertDictContainsSubset(data, response.data)
def test_data(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request) self.assertNotEqual(response.get('Last-Modified'), None) self.assertEqual(response.status_code, 200) formid = self.xform.pk data = _data_list(formid) self.assertEqual(response.data, data) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = _data_instance(dataid) self.assertDictContainsSubset(data, sorted(response.data)[0]) data = { u'_xform_id_string': u'transportation_2011_07_25', u'transport/available_transportation_types_to_referral_facility': u'none', u'_submitted_by': u'bob', } view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertNotEqual(response.get('Last-Modified'), None) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, dict) self.assertDictContainsSubset(data, response.data)
def test_data(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request) self.assertNotEqual(response.get('Last-Modified'), None) self.assertEqual(response.status_code, 200) formid = self.xform.pk data = _data_list(formid) self.assertEqual(response.data, data) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = _data_instance(dataid) self.assertDictContainsSubset(data, sorted(response.data)[0]) data = { u'_xform_id_string': u'transportation_2011_07_25', u'transport/available_transportation_types_to_referral_facility': u'none', u'_submitted_by': u'bob', } view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, 200) self.assertNotEqual(response.get('Last-Modified'), None) self.assertIsInstance(response.data, dict) self.assertDictContainsSubset(data, response.data)
def test_geojson_polygon(self): self._publish_submit_geojson() dataid = self.xform.instances.all().order_by('id')[0].pk data_get = { "geo_field": 'shape', "fields": 'today,shape' } view = DataViewSet.as_view({'get': 'retrieve'}) request = self.factory.get('/', data=data_get, **self.extra) response = view(request, pk=self.xform.pk, dataid=dataid, format='geojson') self.assertEqual(response.status_code, 200) self.assertEquals(response.data['type'], 'Feature') self.assertEquals(len(response.data['geometry']['coordinates'][0]), 6) self.assertIn('shape', response.data['properties']) self.assertEquals(response.data['geometry']['type'], 'Polygon') view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', data=data_get, **self.extra) response = view(request, pk=self.xform.pk, format='geojson') self.assertEqual(response.status_code, 200) self.assertEquals(response.data['type'], 'FeatureCollection') self.assertEquals(len(response.data['features']), 4) self.assertEquals(response.data['features'][0]['type'], 'Feature') self.assertEquals(response.data['features'][0]['geometry']['type'], 'Polygon')
def test_data_in_public_project(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) formid = self.xform.pk response = view(request, pk=formid) self.assertEquals(response.status_code, 200) self.assertEqual(len(response.data), 4) # get project id projectid = self.xform.project.pk view = ProjectViewSet.as_view({'put': 'update'}) data = { 'shared': True, 'name': 'test project', 'owner': 'http://testserver/api/v1/users/%s' % self.user.username } request = self.factory.put('/', data=data, **self.extra) response = view(request, pk=projectid) self.assertEqual(response.status_code, 200) # anonymous user view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/') formid = self.xform.pk response = view(request, pk=formid) self.assertEquals(response.status_code, 200) self.assertEqual(len(response.data), 4)
def test_md_data_viewset_deleted_form(self): """Test retrieving data of a merged dataset with one form deleted""" merged_dataset = self._create_merged_dataset() merged_xform = MergedXForm.objects.get(pk=merged_dataset['id']) request = self.factory.get('/', **self.extra) data_view = DataViewSet.as_view({ 'get': 'list', }) # make submission to form a form_a = merged_xform.xforms.all()[0] xml = '<data id="a"><fruit>orange</fruit></data>' Instance(xform=form_a, xml=xml).save() # DataViewSet /data/[pk] endpoint response = data_view(request, pk=merged_dataset['id']) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) fruit = [d['fruit'] for d in response.data] expected_fruit = ['orange'] self.assertEqual(fruit, expected_fruit) # make submission to form b form_b = merged_xform.xforms.all()[1] xml = '<data id="b"><fruit>mango</fruit></data>' Instance(xform=form_b, xml=xml).save() # DataViewSet /data/[pk] endpoint response = data_view(request, pk=merged_dataset['id']) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 2) dataid = response.data[0]['_id'] fruit = [d['fruit'] for d in response.data] expected_fruit = ['orange', 'mango'] self.assertEqual(fruit, expected_fruit) # DataViewSet /data/[pk] endpoint, form_a deleted form_a.soft_delete() response = data_view(request, pk=merged_dataset['id']) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) fruit = [d['fruit'] for d in response.data] expected_fruit = ['mango'] self.assertEqual(fruit, expected_fruit) # DataViewSet /data/[pk]/[dataid] endpoint, form_a deleted data_view = DataViewSet.as_view({ 'get': 'retrieve', }) response = data_view(request, pk=merged_dataset['id'], dataid=dataid) self.assertEqual(response.status_code, 404)
def test_data_w_attachment(self): self._submit_transport_instance_w_attachment() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request) self.assertEqual(response.status_code, 200) formid = self.xform.pk data = _data_list(formid) self.assertEqual(response.data, data) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = { u'_bamboo_dataset_id': u'', u'_attachments': [{ 'download_url': get_attachment_url(self.attachment), 'small_download_url': get_attachment_url(self.attachment, 'small'), 'medium_download_url': get_attachment_url(self.attachment, 'medium'), u'mimetype': self.attachment.mimetype, u'instance': self.attachment.instance.pk, u'filename': self.attachment.media_file.name, u'id': self.attachment.pk, u'xform': self.xform.id} ], u'_geolocation': [None, None], u'_xform_id_string': u'transportation_2011_07_25', u'transport/available_transportation_types_to_referral_facility': u'none', u'_status': u'submitted_via_web', u'_id': dataid } self.assertDictContainsSubset(data, sorted(response.data)[0]) data = { u'_xform_id_string': u'transportation_2011_07_25', u'transport/available_transportation_types_to_referral_facility': u'none', u'_submitted_by': u'bob', } view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, dict) self.assertDictContainsSubset(data, response.data)
def test_form_inherits_permision_from_project(self): self._publish_xls_form_to_project() self._make_submissions() project_view = ProjectViewSet.as_view({'get': 'retrieve'}) xform_view = XFormViewSet.as_view({'get': 'retrieve'}) data_view = DataViewSet.as_view({'get': 'list'}) alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(extra_post_data=alice_data) formid = self.xform.pk project_id = self.project.pk request = self.factory.get('/', **self.extra) response = xform_view(request, pk=formid) self.assertEqual(response.status_code, 404) response = data_view(request, pk=formid) self.assertEqual(response.status_code, 404) # Give owner role to the project role.OwnerRole.add(self.user, self.project) response = project_view(request, pk=project_id) self.assertEqual(response.status_code, 200) response = xform_view(request, pk=formid) self.assertEqual(response.status_code, 200) response = data_view(request, pk=formid) self.assertEqual(response.status_code, 200)
def test_deleted_forms(self): """Test retrieving data of a merged dataset with no forms linked.""" merged_dataset = self._create_merged_dataset() merged_xform = MergedXForm.objects.get(pk=merged_dataset['id']) merged_xform.xforms.all().delete() request = self.factory.get( '/', data={'sort': '{"_submission_time":1}', 'limit': '10'}, **self.extra) data_view = DataViewSet.as_view({ 'get': 'list', }) # DataViewSet /data/[pk] endpoint response = data_view(request, pk=merged_dataset['id']) self.assertEqual(response.status_code, 200, response.data) self.assertEqual(response.data, []) data = {'field_name': 'fruit'} view = ChartsViewSet.as_view({'get': 'retrieve'}) request = self.factory.get('/charts', data, **self.extra) response = view(request, pk=merged_dataset['id'], format='html') self.assertEqual(response.status_code, 200) self.assertEqual(response.data['data'].__len__(), 0)
def test_deleted_forms(self): """Test retrieving data of a merged dataset with no forms linked.""" merged_dataset = self._create_merged_dataset() merged_xform = MergedXForm.objects.get(pk=merged_dataset['id']) merged_xform.xforms.all().delete() request = self.factory.get( '/', data={ 'sort': '{"_submission_time":1}', 'limit': '10' }, **self.extra) data_view = DataViewSet.as_view({ 'get': 'list', }) # DataViewSet /data/[pk] endpoint response = data_view(request, pk=merged_dataset['id']) self.assertEqual(response.status_code, 200, response.data) self.assertEqual(response.data, []) data = {'field_name': 'fruit'} view = ChartsViewSet.as_view({'get': 'retrieve'}) request = self.factory.get('/charts', data, **self.extra) response = view(request, pk=merged_dataset['id'], format='html') self.assertEqual(response.status_code, 200) self.assertEqual(response.data['data'].__len__(), 0)
def test_get_enketo_edit_url(self): self.user.profile.require_auth = True self.user.profile.save() self._make_submissions() for view_ in ['enketo', 'enketo_edit']: # ensure both legacy `/enketo` and the new `/enketo_edit` endpoints # do the same thing view = DataViewSet.as_view({'get': view_}) formid = self.xform.pk dataid = self.xform.instances.all().order_by('id')[0].pk request = self.factory.get('/', **self.extra) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) # add data check self.assertEqual( response.data['detail'], '`return_url` not provided.' ) request = self.factory.get( '/', data={'return_url': "http://test.io/test_url"}, **self.extra ) with HTTMock(enketo_mock): response = view(request, pk=formid, dataid=dataid) self.assertEqual( response.data['url'], "https://hmh2a.enketo.formhub.org" )
def test_data_list_with_xform_in_delete_async_queue(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request) self.assertNotEqual(response.get('Last-Modified'), None) self.assertEqual(response.status_code, 200) initial_count = len(response.data) self.xform.deleted_at = timezone.now() self.xform.save() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request) self.assertNotEqual(response.get('Last-Modified'), None) self.assertEqual(len(response.data), initial_count - 1)
def test_delete_submission(self): self._make_submissions() before_count = self.xform.instances.all().count() view = DataViewSet.as_view({'delete': 'destroy'}) request = self.factory.delete('/', **self.extra) formid = self.xform.pk dataid = self.xform.instances.all().order_by('id')[0].pk response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, 204) count = self.xform.instances.all().count() self.assertEquals(before_count - 1, count) self._create_user_and_login(username='******', password='******') # Only owners can delete role.ManagerRole.add(self.user, self.xform) self.extra = {'HTTP_AUTHORIZATION': 'Token %s' % self.user.auth_token} request = self.factory.delete('/', **self.extra) dataid = self.xform.instances.all().order_by('id')[0].pk response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, 403) # Nothing deleted count = self.xform.instances.all().count() self.assertEquals(before_count - 1, count)
def test_data(self): view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request) self.assertEqual(response.status_code, 200) formid = self.xform.pk data = { u'transportation_2011_07_25': 'http://testserver/api/v1/data/bob/%s' % formid } self.assertDictEqual(response.data, data) response = view(request, owner='bob', formid=formid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = { u'_bamboo_dataset_id': u'', u'_attachments': [], u'_geolocation': [None, None], u'_xform_id_string': u'transportation_2011_07_25', u'transport/available_transportation_types_to_referral_facility': u'none', u'_status': u'submitted_via_web', u'_id': dataid } self.assertDictContainsSubset(data, sorted(response.data)[0]) response = view(request, owner='bob', formid=formid, dataid=dataid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, dict) self.assertDictContainsSubset(data, response.data)
def test_data_export(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) formid = self.xform.pk # csv request = self.factory.get('/', **self.extra) response = view(request, pk=formid, format='csv') self.assertEqual(response.status_code, 200) headers = dict(response.items()) content_disposition = headers['Content-Disposition'] filename = self._filename_from_disposition(content_disposition) basename, ext = os.path.splitext(filename) self.assertEqual(headers['Content-Type'], 'application/csv') self.assertEqual(ext, '.csv') # xls request = self.factory.get('/', **self.extra) response = view(request, pk=formid, format='xls') self.assertEqual(response.status_code, 200) headers = dict(response.items()) content_disposition = headers['Content-Disposition'] filename = self._filename_from_disposition(content_disposition) basename, ext = os.path.splitext(filename) self.assertEqual(headers['Content-Type'], 'application/vnd.openxmlformats') self.assertEqual(ext, '.xlsx')
def test_get_form_public_data(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/') formid = self.xform.pk response = view(request, pk=formid) # data not found for anonymous access to private data self.assertEqual(response.status_code, 404) self.xform.shared_data = True self.xform.save() # access to a public data as anon response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = _data_instance(dataid) self.assertDictContainsSubset(data, sorted(response.data)[0]) # access to a public data as other user self._create_user_and_login('alice', 'alice') self.extra = {'HTTP_AUTHORIZATION': 'Token %s' % self.user.auth_token} request = self.factory.get('/', **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = _data_instance(dataid) self.assertDictContainsSubset(data, sorted(response.data)[0])
def test_cannot_get_enketo_edit_url_without_require_auth(self): """ It's not currently possible to support authenticated Enketo submission editing while simultaneously accepting anonymous submissions. The less-bad option is to reject edit requests with an explicit error message when anonymous submissions are enabled. """ self.assertFalse(self.user.profile.require_auth) self._make_submissions() for view_ in ['enketo', 'enketo_edit']: view = DataViewSet.as_view({'get': view_}) formid = self.xform.pk dataid = self.xform.instances.all().order_by('id')[0].pk request = self.factory.get( '/', data={'return_url': "http://test.io/test_url"}, **self.extra ) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertTrue( response.data[0].startswith( 'Cannot edit submissions while "Require authentication ' 'to see forms and submit data" is disabled for your ' 'account' ) )
def test_data_with_query_parameter(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) formid = self.xform.pk instance = self.xform.instances.all().order_by('pk')[0] dataid = instance.pk response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 4) query_str = '{"_id": "%s"}' % dataid request = self.factory.get('/?query=%s' % query_str, **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) submission_time = instance.date_created.strftime(MONGO_STRFTIME) query_str = '{"_submission_time": {"$gte": "%s"}}' % submission_time request = self.factory.get('/?query=%s' % query_str, **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 4) query_str = '{"_id: "%s"}' % dataid request = self.factory.get('/?query=%s' % query_str, **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 400) self.assertEqual(response.data.get('detail'), u"Expecting ':' delimiter: line 1 column 9 (char 8)")
def test_data_entry_role(self): self._publish_xls_form_to_project() self._make_submissions() view = XFormViewSet.as_view({'get': 'retrieve', 'put': 'update'}) data_view = DataViewSet.as_view({'get': 'list'}) alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(extra_post_data=alice_data) formid = self.xform.pk request = self.factory.get('/', **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 404) response = data_view(request, pk=formid) self.assertEqual(response.status_code, 404) role.DataEntryRole.add(self.user, self.xform) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) response = data_view(request, pk=formid) self.assertEqual(response.status_code, 200) data = {'public': True, 'description': "Some description"} request = self.factory.put('/', data=data, **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 403)
def test_editor_role(self): self._publish_xls_form_to_project() self._make_submissions() view = XFormViewSet.as_view({ 'get': 'retrieve', 'patch': 'update' }) data_view = DataViewSet.as_view({'get': 'list'}) alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(extra_post_data=alice_data) formid = self.xform.pk request = self.factory.get('/', **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 404) response = data_view(request, pk=formid) self.assertEqual(response.status_code, 404) role.EditorRole.add(self.user, self.xform) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) response = data_view(request, pk=formid) self.assertEqual(response.status_code, 200)
def test_delete_submission(self): self._make_submissions() before_count = self.xform.instances.all().count() view = DataViewSet.as_view({'delete': 'destroy'}) request = self.factory.delete('/', **self.extra) formid = self.xform.pk dataid = self.xform.instances.all().order_by('id')[0].pk response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) count = self.xform.instances.all().count() self.assertEquals(before_count - 1, count) self._create_user_and_login(username='******', password='******') # Allow Alice to delete submissions. assign_perm(CAN_VIEW_XFORM, self.user, self.xform) assign_perm(CAN_CHANGE_XFORM, self.user, self.xform) self.extra = {'HTTP_AUTHORIZATION': 'Token %s' % self.user.auth_token} request = self.factory.delete('/', **self.extra) dataid = self.xform.instances.all().order_by('id')[0].pk response = view(request, pk=formid, dataid=dataid) # Alice cannot delete submissions with `CAN_CHANGE_XFORM` self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) # Now, she should be able to remove_perm(CAN_CHANGE_XFORM, self.user, self.xform) assign_perm(CAN_DELETE_DATA_XFORM, self.user, self.xform) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) count = self.xform.instances.all().count() self.assertEquals(before_count - 2, count)
def test_data_export(self): self._make_submissions() view = DataViewSet.as_view({ 'get': 'list' }) formid = self.xform.pk # csv request = self.factory.get('/', **self.extra) response = view(request, pk=formid, format='csv') self.assertEqual(response.status_code, 200) headers = dict(response.items()) content_disposition = headers['Content-Disposition'] filename = self._filename_from_disposition(content_disposition) basename, ext = os.path.splitext(filename) self.assertEqual(headers['Content-Type'], 'application/csv') self.assertEqual(ext, '.csv') # xls request = self.factory.get('/', **self.extra) response = view(request, pk=formid, format='xls') self.assertEqual(response.status_code, 200) headers = dict(response.items()) content_disposition = headers['Content-Disposition'] filename = self._filename_from_disposition(content_disposition) basename, ext = os.path.splitext(filename) self.assertEqual(headers['Content-Type'], 'application/vnd.openxmlformats') self.assertEqual(ext, '.xlsx')
def test_readonly_role(self): self._publish_xls_form_to_project() self._make_submissions() view = XFormViewSet.as_view({ 'get': 'retrieve', 'put': 'update' }) data_view = DataViewSet.as_view({'get': 'list'}) alice_data = {'username': '******', 'email': '*****@*****.**'} self._login_user_and_profile(extra_post_data=alice_data) formid = self.xform.pk request = self.factory.get('/', **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 404) response = data_view(request, pk=formid) self.assertEqual(response.status_code, 403) role.ReadOnlyRole.add(self.user, self.xform) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) response = data_view(request, pk=formid) self.assertEqual(response.status_code, 200) data = {'public': True, 'description': "Some description"} request = self.factory.put('/', data=data, **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 403)
def test_get_form_public_data(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/') formid = self.xform.pk response = view(request, pk=formid) # data not found for anonymous access to private data self.assertEqual(response.status_code, 404) self.xform.shared_data = True self.xform.save() # access to a public data as anon response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = _data_instance(dataid) self.assertDictContainsSubset(data, sorted(response.data)[0]) # access to a public data as other user self._create_user_and_login('alice', 'alice') self.extra = { 'HTTP_AUTHORIZATION': 'Token %s' % self.user.auth_token} request = self.factory.get('/', **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = _data_instance(dataid) self.assertDictContainsSubset(data, sorted(response.data)[0])
def test_delete_submission(self): self._make_submissions() before_count = self.xform.instances.all().count() view = DataViewSet.as_view({'delete': 'destroy'}) request = self.factory.delete('/', **self.extra) formid = self.xform.pk dataid = self.xform.instances.all().order_by('id')[0].pk response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, 204) count = self.xform.instances.all().count() self.assertEquals(before_count - 1, count) self._create_user_and_login(username='******', password='******') # Only owners can delete role.ManagerRole.add(self.user, self.xform) self.extra = { 'HTTP_AUTHORIZATION': 'Token %s' % self.user.auth_token} request = self.factory.delete('/', **self.extra) dataid = self.xform.instances.all().order_by('id')[0].pk response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, 403) # Nothing deleted count = self.xform.instances.all().count() self.assertEquals(before_count - 1, count)
def test_data_bad_dataid(self): view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request) self.assertEqual(response.status_code, 200) formid = self.xform.pk data = _data_list(formid) self.assertEqual(response.data, data) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = 'INVALID' data = _data_instance(dataid) view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, 400)
def test_add_form_tag_propagates_to_data_tags(self): """Test that when a tag is applied on an xform, it propagates to the instance submissions """ self._make_submissions() xform = XForm.objects.all()[0] pk = xform.id view = XFormViewSet.as_view({ 'get': 'labels', 'post': 'labels', 'delete': 'labels' }) data_view = DataViewSet.as_view({ 'get': 'list', }) # no tags request = self.factory.get('/', **self.extra) response = view(request, pk=pk) self.assertEqual(response.data, []) request = self.factory.get('/', {'tags': 'hello'}, **self.extra) response = data_view(request) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 0) request = self.factory.get('/', {'not_tagged': 'hello'}, **self.extra) response = data_view(request) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) # add tag "hello" request = self.factory.post('/', data={"tags": "hello"}, **self.extra) response = view(request, pk=pk) self.assertEqual(response.status_code, 201) self.assertEqual(response.data, [u'hello']) for i in self.xform.instances.all(): self.assertIn(u'hello', i.tags.names()) request = self.factory.get('/', {'tags': 'hello'}, **self.extra) response = data_view(request) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) request = self.factory.get('/', {'not_tagged': 'hello'}, **self.extra) response = data_view(request) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 0) # remove tag "hello" request = self.factory.delete('/', data={"tags": "hello"}, **self.extra) response = view(request, pk=pk, label='hello') self.assertEqual(response.status_code, 200) self.assertEqual(response.data, []) for i in self.xform.instances.all(): self.assertNotIn(u'hello', i.tags.names())
def test_data_bad_dataid(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request) self.assertEqual(response.status_code, status.HTTP_200_OK) formid = self.xform.pk data = _data_list(formid) self.assertEqual(response.data, data) response = view(request, pk=formid) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = 'INVALID' data = _data_instance(dataid) view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
def test_process_error_osm_format(self): self._publish_xls_form_to_project() self._make_submissions() request = self.factory.get('/') view = DataViewSet.as_view({'get': 'retrieve'}) dataid = self.xform.instances.all().order_by('id')[0].pk response = view(request, pk=self.xform.pk, dataid=dataid, format='osm') self.assertContains(response, '<error>Not found.</error>', status_code=404)
def test_data_list_filter_by_user(self): view = DataViewSet.as_view({'get': 'list'}) formid = self.xform.pk bobs_data = { u'id': formid, u'id_string': u'transportation_2011_07_25', u'title': 'transportation_2011_07_25', u'description': 'transportation_2011_07_25', u'url': u'http://testserver/api/v1/data/%s' % formid } previous_user = self.user self._create_user_and_login('alice', 'alice') self.assertEqual(self.user.username, 'alice') self.assertNotEqual(previous_user, self.user) ReadOnlyRole.add(self.user, self.xform) # publish alice's form self._publish_transportation_form() self.extra = { 'HTTP_AUTHORIZATION': 'Token %s' % self.user.auth_token} formid = self.xform.pk alice_data = { u'id': formid, u'id_string': u'transportation_2011_07_25', u'title': 'transportation_2011_07_25', u'description': 'transportation_2011_07_25', u'url': u'http://testserver/api/v1/data/%s' % formid } request = self.factory.get('/', **self.extra) response = view(request) self.assertEqual(response.status_code, 200) # should be both bob's and alice's form self.assertEqual(sorted(response.data), sorted([bobs_data, alice_data])) # apply filter, see only bob's forms request = self.factory.get('/', data={'owner': 'bob'}, **self.extra) response = view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [bobs_data]) # apply filter, see only alice's forms request = self.factory.get('/', data={'owner': 'alice'}, **self.extra) response = view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [alice_data]) # apply filter, see a non existent user request = self.factory.get('/', data={'owner': 'noone'}, **self.extra) response = view(request) self.assertEqual(response.status_code, 200) self.assertEqual(response.data, [])
def test_data_pagination(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) formid = self.xform.pk # no page param no pagination request = self.factory.get('/', **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 4) request = self.factory.get('/', data={ "page": "1", "page_size": 2 }, **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 2) request = self.factory.get('/', data={"page_size": "3"}, **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 3) request = self.factory.get('/', data={ "page": "1", "page_size": "2" }, **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 2) # invalid page returns a 404 request = self.factory.get('/', data={"page": "invalid"}, **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 404) # invalid page size is ignores request = self.factory.get('/', data={"page_size": "invalid"}, **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 4) request = self.factory.get('/', data={ "page": "invalid", "page-size": "invalid" }, **self.extra) response = view(request, pk=formid)
def test_labels_action_with_params(self): self._make_submissions() xform = XForm.objects.all()[0] pk = xform.id dataid = xform.instances.all()[0].id view = DataViewSet.as_view({'get': 'labels'}) request = self.factory.get('/', **self.extra) response = view(request, pk=pk, dataid=dataid, label='hello') self.assertEqual(response.status_code, 200)
def test_geojson_geofield(self): self._publish_submit_geojson() dataid = self.xform.instances.all().order_by('id')[0].pk data_get = { "geo_field": 'location', "fields": 'today' } view = DataViewSet.as_view({'get': 'retrieve'}) request = self.factory.get('/', data=data_get, **self.extra) response = view(request, pk=self.xform.pk, dataid=dataid, format='geojson') self.assertEqual(response.status_code, 200) test_loc = geojson.Feature( geometry=geojson.GeometryCollection([ geojson.Point((36.787219, -1.294197))]), properties={ 'xform': self.xform.pk, 'id': dataid, u'today': '2015-01-15' } ) if 'id' in test_loc: test_loc.pop('id') self.assertEqual(response.data, test_loc) view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', data=data_get, **self.extra) response = view(request, pk=self.xform.pk, format='geojson') self.assertEqual(response.status_code, 200) self.assertEquals(response.data['type'], 'FeatureCollection') self.assertEquals(len(response.data['features']), 4) self.assertEquals(response.data['features'][0]['type'], 'Feature') self.assertEquals( response.data['features'][0]['geometry']['geometries'][0]['type'], 'Point' )
def test_get_enketo_view_url(self): self._make_submissions() view = DataViewSet.as_view({'get': 'enketo_view'}) request = self.factory.get('/', **self.extra) formid = self.xform.pk dataid = self.xform.instances.all().order_by('id')[0].pk with HTTMock(enketo_mock): response = view(request, pk=formid, dataid=dataid) self.assertEqual( response.data['url'], 'https://hmh2a.enketo.formhub.org' )
def test_labels_action_with_params(self): self._make_submissions() xform = XForm.objects.all()[0] pk = xform.id dataid = xform.instances.all()[0].id view = DataViewSet.as_view({ 'get': 'labels' }) request = self.factory.get('/', **self.extra) response = view(request, pk=pk, dataid=dataid, label='hello') self.assertEqual(response.status_code, 200)
def test_data_user_public(self): view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request, pk='public') self.assertEqual(response.status_code, 200) self.assertEqual(response.data, []) self.xform.shared_data = True self.xform.save() formid = self.xform.pk data = _data_list(formid) response = view(request, pk='public') self.assertEqual(response.status_code, 200) self.assertEqual(response.data, data)
def test_data_anon(self): # By default, `_create_user_and_login()` creates users without # authentication required. We force it when submitting data to persist # collector's username because this test expects it. # See `_submitted_data` in `data` below self._set_require_auth(True) self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/') formid = self.xform.pk response = view(request, pk=formid) # data not found for anonymous access to private data self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.xform.shared_data = True self.xform.save() response = view(request, pk=formid) # access to a public data self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = _data_instance(dataid) response_first_element = sorted(response.data, key=lambda x: x['_id'])[0] self.assertEqual(dict(response_first_element, **data), response_first_element) data = { '_xform_id_string': 'transportation_2011_07_25', 'transport/available_transportation_types_to_referral_facility': 'none', '_submitted_by': 'bob', } view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertIsInstance(response.data, dict) self.assertEqual(dict(response.data, **data), response.data)
def test_data_with_query_parameter(self): view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) formid = self.xform.pk dataid = self.xform.instances.all()[0].pk response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 4) query_str = '{"_id": "%s"}' % dataid request = self.factory.get('/?query=%s' % query_str, **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1)
def test_data(self): view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/', **self.extra) response = view(request) self.assertEqual(response.status_code, 200) formid = self.xform.pk data = _data_list(formid) self.assertEqual(response.data, data) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = _data_instance(dataid) self.assertDictContainsSubset(data, sorted(response.data)[0]) view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, dict) self.assertDictContainsSubset(data, response.data)
def test_data_retrieve_instance_osm_format(self): filenames = [ 'OSMWay234134797.osm', 'OSMWay34298972.osm', ] osm_fixtures_dir = os.path.realpath(os.path.join( os.path.dirname(__file__), '..', 'fixtures', 'osm')) paths = [ os.path.join(osm_fixtures_dir, filename) for filename in filenames] xlsform_path = os.path.join(osm_fixtures_dir, 'osm.xlsx') combined_osm_path = os.path.join(osm_fixtures_dir, 'combined.osm') self._publish_xls_form_to_project(xlsform_path=xlsform_path) submission_path = os.path.join(osm_fixtures_dir, 'instance_a.xml') files = [open(path) for path in paths] count = Attachment.objects.filter(extension='osm').count() self._make_submission(submission_path, media_file=files) self.assertTrue( Attachment.objects.filter(extension='osm').count() > count) formid = self.xform.pk dataid = self.xform.instances.latest('date_created').pk request = self.factory.get('/', **self.extra) # look at the data/[pk]/[dataid].osm endpoint view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid, format='osm') self.assertEqual(response.status_code, 200) with open(combined_osm_path) as f: osm = f.read() response.render() self.assertMultiLineEqual(response.content, osm) # look at the data/[pk].osm endpoint view = DataViewSet.as_view({'get': 'list'}) response = view(request, pk=formid, format='osm') self.assertEqual(response.status_code, 200) response.render() self.assertMultiLineEqual(response.content, osm)
def test_data_public_anon_user(self): self._make_submissions() view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/') response = view(request, pk='public') self.assertEqual(response.status_code, 200) self.assertEqual(response.data, []) self.xform.shared_data = True self.xform.save() formid = self.xform.pk data = _data_list(formid) response = view(request, pk='public') self.assertEqual(response.status_code, 200) self.assertEqual(response.data, data)
def test_data_start_limit_no_records(self): view = DataViewSet.as_view({'get': 'list'}) formid = self.xform.pk # no start, limit params request = self.factory.get('/', **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 0) request = self.factory.get('/', data={"start": "1", "limit": 2}, **self.extra) response = view(request, pk=formid) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 0)
def test_data_anon(self): view = DataViewSet.as_view({'get': 'list'}) request = self.factory.get('/') formid = self.xform.pk response = view(request, pk=formid) # data not found for anonymous access to private data self.assertEqual(response.status_code, 404) self.xform.shared_data = True self.xform.save() response = view(request, pk=formid) # access to a public data self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, list) self.assertTrue(self.xform.instances.count()) dataid = self.xform.instances.all().order_by('id')[0].pk data = _data_instance(dataid) self.assertDictContainsSubset(data, sorted(response.data)[0]) view = DataViewSet.as_view({'get': 'retrieve'}) response = view(request, pk=formid, dataid=dataid) self.assertEqual(response.status_code, 200) self.assertIsInstance(response.data, dict) self.assertDictContainsSubset(data, response.data)