def test_merged_datasets_retrieve(self):
        """Test retrieving a specific merged dataset"""
        merged_dataset = self._create_merged_dataset(geo=True)
        merged_xform = MergedXForm.objects.get(pk=merged_dataset['id'])

        # make submission to form b
        form_b = merged_xform.xforms.all()[1]
        xml = '<data id="b"><fruit>mango</fruit></data>'
        instance = Instance(xform=form_b, xml=xml)
        instance.save()
        form_b.refresh_from_db()
        form_b.last_submission_time = instance.date_created
        form_b.save()
        view = MergedXFormViewSet.as_view({'get': 'retrieve'})
        request = self.factory.get('/')

        # status_code is 404 when the pk doesn't exist
        response = view(request, pk=(1000 * merged_dataset['id']))
        self.assertEqual(response.status_code, 404)

        # status_code is 404 when: pk exists, user is not authenticated
        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 404)

        # status_code is 200 when: pk exists, user is authenticated
        request = self.factory.get('/', **self.extra)
        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)

        # data has expected fields
        self.assertIn('id', response.data)
        self.assertIn('title', response.data)
        self.assertIn('xforms', response.data)
        self.assertEqual(response.data['num_of_submissions'], 1)
        self.assertEqual(response.data['last_submission_time'],
                         form_b.last_submission_time.isoformat())

        # merged dataset should be available at api/forms/[pk] endpoint
        request = self.factory.get('/', **self.extra)
        view = XFormViewSet.as_view({'get': 'retrieve'})
        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(merged_dataset['id'], response.data['formid'])
        self.assertIn('is_merged_dataset', response.data)
        self.assertTrue(response.data['is_merged_dataset'])
        self.assertTrue(response.data['instances_with_geopoints'])
        self.assertEqual(response.data['num_of_submissions'], 1)
        self.assertEqual(response.data['last_submission_time'],
                         form_b.last_submission_time.isoformat())
    def test_merged_datasets_retrieve(self):
        """Test retrieving a specific merged dataset"""
        merged_dataset = self._create_merged_dataset(geo=True)
        merged_xform = MergedXForm.objects.get(pk=merged_dataset['id'])

        # make submission to form b
        form_b = merged_xform.xforms.all()[1]
        xml = '<data id="b"><fruit>mango</fruit></data>'
        instance = Instance(xform=form_b, xml=xml)
        instance.save()
        form_b.refresh_from_db()
        form_b.last_submission_time = instance.date_created
        form_b.save()
        view = MergedXFormViewSet.as_view({'get': 'retrieve'})
        request = self.factory.get('/')

        # status_code is 404 when the pk doesn't exist
        response = view(request, pk=(1000 * merged_dataset['id']))
        self.assertEqual(response.status_code, 404)

        # status_code is 404 when: pk exists, user is not authenticated
        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 404)

        # status_code is 200 when: pk exists, user is authenticated
        request = self.factory.get('/', **self.extra)
        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)

        # data has expected fields
        self.assertIn('id', response.data)
        self.assertIn('title', response.data)
        self.assertIn('xforms', response.data)
        self.assertEqual(response.data['num_of_submissions'], 1)
        self.assertEqual(response.data['last_submission_time'],
                         form_b.last_submission_time.isoformat())

        # merged dataset should be available at api/forms/[pk] endpoint
        request = self.factory.get('/', **self.extra)
        view = XFormViewSet.as_view({'get': 'retrieve'})
        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(merged_dataset['id'], response.data['formid'])
        self.assertIn('is_merged_dataset', response.data)
        self.assertTrue(response.data['is_merged_dataset'])
        self.assertTrue(response.data['instances_with_geopoints'])
        self.assertEqual(response.data['num_of_submissions'], 1)
        self.assertEqual(response.data['last_submission_time'],
                         form_b.last_submission_time.isoformat())
Exemple #3
0
def _get_instance(
    request: 'rest_framework.request.Request',
    xml: str,
    new_uuid: str,
    status: str,
    xform: XForm,
    defer_counting: bool = False,
) -> Instance:
    """
    `defer_counting=False` will set a Python-only attribute of the same name on
    the *new* `Instance` if one is created. This will prevent
    `update_xform_submission_count()` from doing anything, which avoids locking
    any rows in `logger_xform` or `main_userprofile`.
    """
    # check if its an edit submission
    old_uuid = get_deprecated_uuid_from_xml(xml)
    instances = Instance.objects.filter(uuid=old_uuid)

    if instances:
        # edits
        instance = instances[0]
        check_edit_submission_permissions(request, xform, instance)
        InstanceHistory.objects.create(xml=instance.xml,
                                       xform_instance=instance,
                                       uuid=old_uuid)
        instance.xml = xml
        instance._populate_xml_hash()
        instance.uuid = new_uuid
        instance.save()
    else:
        submitted_by = (request.user
                        if request and request.user.is_authenticated else None)
        # new submission
        # Avoid `Instance.objects.create()` so that we can set a Python-only
        # attribute, `defer_counting`, before saving
        instance = Instance()
        instance.xml = xml
        instance.user = submitted_by
        instance.status = status
        instance.xform = xform
        if defer_counting:
            # Only set the attribute if requested, i.e. don't bother ever
            # setting it to `False`
            instance.defer_counting = True
        instance.save()

    return instance
Exemple #4
0
def _get_instance(xml,
                  new_uuid,
                  submitted_by,
                  status,
                  xform,
                  defer_counting=False):
    '''
    `defer_counting=False` will set a Python-only attribute of the same name on
    the *new* `Instance` if one is created. This will prevent
    `update_xform_submission_count()` from doing anything, which avoids locking
    any rows in `logger_xform` or `main_userprofile`.
    '''
    # check if its an edit submission
    old_uuid = get_deprecated_uuid_from_xml(xml)
    instances = Instance.objects.filter(uuid=old_uuid)

    if instances:
        # edits
        check_edit_submission_permissions(submitted_by, xform)
        instance = instances[0]
        InstanceHistory.objects.create(xml=instance.xml,
                                       xform_instance=instance,
                                       uuid=old_uuid)
        instance.xml = xml
        instance._populate_xml_hash()
        instance.uuid = new_uuid
        instance.save()
    else:
        # new submission

        # Avoid `Instance.objects.create()` so that we can set a Python-only
        # attribute, `defer_counting`, before saving
        instance = Instance()
        instance.xml = xml
        instance.user = submitted_by
        instance.status = status
        instance.xform = xform
        if defer_counting:
            # Only set the attribute if requested, i.e. don't bother ever
            # setting it to `False`
            instance.defer_counting = True
        instance.save()

    return instance
Exemple #5
0
def _get_instance(xml, new_uuid, submitted_by, status, xform,
                  defer_counting=False):
    '''
    `defer_counting=False` will set a Python-only attribute of the same name on
    the *new* `Instance` if one is created. This will prevent
    `update_xform_submission_count()` from doing anything, which avoids locking
    any rows in `logger_xform` or `main_userprofile`.
    '''
    # check if its an edit submission
    old_uuid = get_deprecated_uuid_from_xml(xml)
    instances = Instance.objects.filter(uuid=old_uuid)

    if instances:
        # edits
        check_edit_submission_permissions(submitted_by, xform)
        instance = instances[0]
        InstanceHistory.objects.create(
            xml=instance.xml, xform_instance=instance, uuid=old_uuid)
        instance.xml = xml
        instance._populate_xml_hash()
        instance.uuid = new_uuid
        instance.save()
    else:
        # new submission

        # Avoid `Instance.objects.create()` so that we can set a Python-only
        # attribute, `defer_counting`, before saving
        instance = Instance()
        instance.xml = xml
        instance.user = submitted_by
        instance.status = status
        instance.xform = xform
        if defer_counting:
            # Only set the attribute if requested, i.e. don't bother ever
            # setting it to `False`
            instance.defer_counting = True
        instance.save()

    return instance
    def test_merged_datasets_deleted_parent_retrieve(self):
        """Test retrieving a specific merged dataset when the parent is deleted
        """
        merged_dataset = self._create_merged_dataset(geo=True)
        merged_xform = MergedXForm.objects.get(pk=merged_dataset['id'])

        # make submission to form b
        form_b = merged_xform.xforms.all()[1]
        xml = '<data id="b"><fruit>mango</fruit></data>'
        instance = Instance(xform=form_b, xml=xml)
        instance.save()
        form_b.refresh_from_db()
        form_b.last_submission_time = instance.date_created
        form_b.save()
        view = MergedXFormViewSet.as_view({'get': 'retrieve'})

        # status_code is 200 when: pk exists, user is authenticated

        request = self.factory.get('/', **self.extra)
        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)

        # delete parents
        [parent.delete() for parent in merged_xform.xforms.all()]
        merged_xform.refresh_from_db()

        # merged dataset should be available at api/forms/[pk] endpoint
        request = self.factory.get('/', **self.extra)
        view = XFormViewSet.as_view({'get': 'retrieve'})
        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(merged_dataset['id'], response.data['formid'])
        self.assertTrue(response.data['is_merged_dataset'])
        self.assertTrue(response.data['instances_with_geopoints'])
        # deleted parents, 0 submissions
        self.assertEqual(response.data['num_of_submissions'], 0)
    def test_merged_datasets_deleted_parent_retrieve(self):
        """Test retrieving a specific merged dataset when the parent is deleted
        """
        merged_dataset = self._create_merged_dataset(geo=True)
        merged_xform = MergedXForm.objects.get(pk=merged_dataset['id'])

        # make submission to form b
        form_b = merged_xform.xforms.all()[1]
        xml = '<data id="b"><fruit>mango</fruit></data>'
        instance = Instance(xform=form_b, xml=xml)
        instance.save()
        form_b.refresh_from_db()
        form_b.last_submission_time = instance.date_created
        form_b.save()
        view = MergedXFormViewSet.as_view({'get': 'retrieve'})

        # status_code is 200 when: pk exists, user is authenticated

        request = self.factory.get('/', **self.extra)
        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)

        # delete parents
        [parent.delete() for parent in merged_xform.xforms.all()]
        merged_xform.refresh_from_db()

        # merged dataset should be available at api/forms/[pk] endpoint
        request = self.factory.get('/', **self.extra)
        view = XFormViewSet.as_view({'get': 'retrieve'})
        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(merged_dataset['id'], response.data['formid'])
        self.assertTrue(response.data['is_merged_dataset'])
        self.assertTrue(response.data['instances_with_geopoints'])
        # deleted parents, 0 submissions
        self.assertEqual(response.data['num_of_submissions'], 0)
    def test_merged_datasets_data(self):
        """Test retrieving data of a merged dataset"""
        merged_dataset = self._create_merged_dataset()
        request = self.factory.get('/', **self.extra)
        view = MergedXFormViewSet.as_view({'get': 'data'})
        merged_xform = MergedXForm.objects.get(pk=merged_dataset['id'])
        detail_view = MergedXFormViewSet.as_view({
            'get': 'retrieve',
        })
        xform_detail_view = XFormViewSet.as_view({
            'get': 'retrieve',
        })

        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 0)

        # check num_of_submissions
        response = detail_view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['num_of_submissions'], 0)

        # 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()
        response = 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)

        # check num_of_submissions
        response = detail_view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['num_of_submissions'], 1)

        # make submission to form b
        form_b = merged_xform.xforms.all()[1]
        xml = '<data id="b"><fruit>mango</fruit></data>'
        last_submission = Instance(xform=form_b, xml=xml)
        last_submission.save()
        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 2)

        fruit = [d['fruit'] for d in response.data]
        expected_fruit = ['orange', 'mango']
        self.assertEqual(fruit, expected_fruit)

        # check num_of_submissions /merged-datasets/[pk]
        response = detail_view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['num_of_submissions'], 2)

        # check last_submission_time
        self.assertEqual(response.data['last_submission_time'],
                         last_submission.date_created.isoformat())

        # check num_of_submissions /forms/[pk]
        response = xform_detail_view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['num_of_submissions'], 2)

        # check last_submission_time
        self.assertEqual(response.data['last_submission_time'],
                         last_submission.date_created.isoformat())
    def test_merged_datasets_data(self):
        """Test retrieving data of a merged dataset"""
        merged_dataset = self._create_merged_dataset()
        request = self.factory.get('/', **self.extra)
        view = MergedXFormViewSet.as_view({'get': 'data'})
        merged_xform = MergedXForm.objects.get(pk=merged_dataset['id'])
        detail_view = MergedXFormViewSet.as_view({
            'get': 'retrieve',
        })
        xform_detail_view = XFormViewSet.as_view({
            'get': 'retrieve',
        })

        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 0)

        # check num_of_submissions
        response = detail_view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['num_of_submissions'], 0)

        # 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()
        response = 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)

        # check num_of_submissions
        response = detail_view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['num_of_submissions'], 1)

        # make submission to form b
        form_b = merged_xform.xforms.all()[1]
        xml = '<data id="b"><fruit>mango</fruit></data>'
        last_submission = Instance(xform=form_b, xml=xml)
        last_submission.save()
        response = view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 2)

        fruit = [d['fruit'] for d in response.data]
        expected_fruit = ['orange', 'mango']
        self.assertEqual(fruit, expected_fruit)

        # check num_of_submissions /merged-datasets/[pk]
        response = detail_view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['num_of_submissions'], 2)

        # check last_submission_time
        self.assertEqual(response.data['last_submission_time'],
                         last_submission.date_created.isoformat())

        # check num_of_submissions /forms/[pk]
        response = xform_detail_view(request, pk=merged_dataset['id'])
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['num_of_submissions'], 2)

        # check last_submission_time
        self.assertEqual(response.data['last_submission_time'],
                         last_submission.date_created.isoformat())