Пример #1
0
class DuplicateFormTest(TestCase, TestFileMixin):
    ID = '7H46J37FGH3'
    file_path = ('data',)
    root = os.path.dirname(__file__)

    def setUp(self):
        self.interface = FormProcessorInterface()

    def tearDown(self):
        FormProcessorTestUtils.delete_all_xforms()

    @run_with_all_backends
    def test_basic_duplicate(self):
        xml_data = self.get_xml('duplicate')
        xform = self.interface.post_xform(xml_data)
        self.assertEqual(self.ID, xform.form_id)
        self.assertTrue(xform.is_normal)
        self.assertEqual("test-domain", xform.domain)

        xform = self.interface.post_xform(xml_data, domain='test-domain')
        self.assertNotEqual(self.ID, xform.form_id)
        self.assertTrue(xform.is_duplicate)
        self.assertTrue(self.ID in xform.problem)

    @run_with_all_backends
    def test_wrong_doc_type(self):
        domain = 'test-domain'
        instance = self.get_xml('duplicate')

        # Post an xform with an alternate doc_type
        xform1 = self.interface.post_xform(
            instance,
            domain=domain,
        )

        # Change the doc_type of the form by archiving it
        self.interface.xform_model.archive(xform1)
        xform1 = self.interface.xform_model.get(xform1.form_id)
        self.assertTrue(xform1.is_archived)

        # Post an xform with that has different doc_type but same id
        _, xform2, _ = self.interface.submit_form_locally(
            instance,
            domain=domain,
        )

        self.assertNotEqual(xform1.form_id, xform2.form_id)

    @run_with_all_backends
    def test_wrong_domain(self):
        domain = 'test-domain'
        instance = self.get_xml('duplicate')

        _, xform1, _ = self.interface.submit_form_locally(
            instance,
            domain='wrong-domain',
        )
        _, xform2, _ = self.interface.submit_form_locally(
            instance,
            domain=domain,
        )
        self.assertNotEqual(xform1.form_id, xform2.form_id)
Пример #2
0
class EditFormTest(TestCase, TestFileMixin):
    ID = '7H46J37FGH3'
    domain = 'test-form-edits'

    file_path = ('data', 'deprecation')
    root = os.path.dirname(__file__)

    def setUp(self):
        self.interface = FormProcessorInterface(TEST_DOMAIN_NAME)

    def tearDown(self):
        FormProcessorTestUtils.delete_all_xforms()
        UnfinishedSubmissionStub.objects.all().delete()

    @run_with_all_backends
    def test_basic_edit(self):
        original_xml = self.get_xml('original')
        edit_xml = self.get_xml('edit')
        yesterday = datetime.utcnow() - timedelta(days=1)

        def process(form):
            form.domain = self.domain
            form.received_on = yesterday

        xform = self.interface.post_xform(original_xml, process=process)
        self.assertEqual(self.ID, xform.form_id)
        self.assertTrue(xform.is_normal)
        self.assertEqual("", xform.form_data['vitals']['height'])
        self.assertEqual("other", xform.form_data['assessment']['categories'])

        xform = self.interface.post_xform(edit_xml, domain=self.domain)
        self.assertEqual(self.ID, xform.form_id)
        self.assertTrue(xform.is_normal)
        self.assertEqual("100", xform.form_data['vitals']['height'])
        self.assertEqual("Edited Baby!", xform.form_data['assessment']['categories'])

        deprecated_xform = self.interface.xform_model.get(xform.deprecated_form_id)

        self.assertEqual(self.ID, deprecated_xform.orig_id)
        self.assertNotEqual(self.ID, deprecated_xform.form_id)
        self.assertTrue(deprecated_xform.is_deprecated)
        self.assertEqual("", deprecated_xform.form_data['vitals']['height'])
        self.assertEqual("other", deprecated_xform.form_data['assessment']['categories'])

        self.assertEqual(xform.received_on, deprecated_xform.received_on)
        self.assertEqual(xform.deprecated_form_id, deprecated_xform.form_id)
        self.assertTrue(xform.edited_on > deprecated_xform.received_on)

        self.assertEqual(
            deprecated_xform.get_xml(),
            original_xml
        )
        self.assertEqual(xform.get_xml(), edit_xml)

    @run_with_all_backends
    def test_broken_save(self):
        """
        Test that if the second form submission terminates unexpectedly
        and the main form isn't saved, then there are no side effects
        such as the original having been marked as deprecated.
        """

        original_xml = self.get_xml('original')
        edit_xml = self.get_xml('edit')

        _, xform, _ = self.interface.submit_form_locally(original_xml, self.domain)
        self.assertEqual(self.ID, xform.form_id)
        self.assertTrue(xform.is_normal)
        self.assertEqual(self.domain, xform.domain)

        self.assertEqual(
            UnfinishedSubmissionStub.objects.filter(xform_id=self.ID).count(),
            0
        )

        with patch.object(self.interface.processor, 'bulk_save', side_effect=RequestFailed):
            with self.assertRaises(RequestFailed):
                self.interface.submit_form_locally(edit_xml, self.domain)

        # it didn't go through, so make sure there are no edits still
        self.assertIsNone(getattr(xform, 'deprecated_form_id', None))

        xform = self.interface.xform_model.get(self.ID)
        self.assertIsNotNone(xform)
        self.assertEqual(
            UnfinishedSubmissionStub.objects.filter(xform_id=self.ID,
                                                    saved=False).count(),
            1
        )
        self.assertEqual(
            UnfinishedSubmissionStub.objects.filter(xform_id=self.ID).count(),
            1
        )

    def test_case_management(self):
        form_id = uuid.uuid4().hex
        case_id = uuid.uuid4().hex
        owner_id = uuid.uuid4().hex
        case_block = CaseBlock(
            create=True,
            case_id=case_id,
            case_type='person',
            owner_id=owner_id,
            update={
                'property': 'original value'
            }
        ).as_string()
        submit_case_blocks(case_block, domain=self.domain, form_id=form_id)

        # validate some assumptions
        case = self.interface.case_model.get(case_id)
        self.assertEqual(case.type, 'person')
        self.assertEqual(case.property, 'original value')
        self.assertEqual([form_id], case.xform_ids)
        self.assertEqual(2, len(case.actions))
        for a in case.actions:
            self.assertEqual(form_id, a.xform_id)

        # submit a new form with a different case update
        case_block = CaseBlock(
            create=True,
            case_id=case_id,
            case_type='newtype',
            owner_id=owner_id,
            update={
                'property': 'edited value'
            }
        ).as_string()
        submit_case_blocks(case_block, domain=self.domain, form_id=form_id)

        case = self.interface.case_model.get(case_id)
        self.assertEqual(case.type, 'newtype')
        self.assertEqual(case.property, 'edited value')
        self.assertEqual([form_id], case.xform_ids)
        self.assertEqual(2, len(case.actions))
        for a in case.actions:
            self.assertEqual(form_id, a.xform_id)

    @run_with_all_backends
    def test_second_edit_fails(self):
        form_id = uuid.uuid4().hex
        case_id = uuid.uuid4().hex
        case_block = CaseBlock(
            create=True,
            case_id=case_id,
            case_type='person',
        ).as_string()
        submit_case_blocks(case_block, domain=self.domain, form_id=form_id)

        # submit an edit form with a bad case update (for example a bad ID)
        case_block = CaseBlock(
            create=True,
            case_id='',
            case_type='person',
        ).as_string()
        submit_case_blocks(case_block, domain=self.domain, form_id=form_id)

        xform = self.interface.xform_model.get(form_id)
        self.assertTrue(xform.is_error)

        deprecated_xform = self.interface.xform_model.get(xform.deprecated_form_id)
        self.assertTrue(deprecated_xform.is_deprecated)

    def test_case_management_ordering(self):
        case_id = uuid.uuid4().hex
        owner_id = uuid.uuid4().hex

        # create a case
        case_block = CaseBlock(
            create=True,
            case_id=case_id,
            case_type='person',
            owner_id=owner_id,
        ).as_string()
        create_form_id = submit_case_blocks(case_block, domain=self.domain)

        # validate that worked
        case = self.interface.case_model.get(case_id)
        self.assertEqual([create_form_id], case.xform_ids)
        self.assertEqual([create_form_id], [a.xform_id for a in case.actions])
        for a in case.actions:
            self.assertEqual(create_form_id, a.xform_id)

        edit_date = datetime.utcnow()
        # set some property value
        case_block = CaseBlock(
            create=False,
            case_id=case_id,
            date_modified=edit_date,
            update={
                'property': 'first value',
            }
        ).as_string()
        edit_form_id = submit_case_blocks(case_block, domain=self.domain)

        # validate that worked
        case = self.interface.case_model.get(case_id)
        self.assertEqual(case.property, 'first value')
        self.assertEqual([create_form_id, edit_form_id], case.xform_ids)
        self.assertEqual([create_form_id, edit_form_id], [a.xform_id for a in case.actions])

        # submit a second (new) form updating the value
        case_block = CaseBlock(
            create=False,
            case_id=case_id,
            update={
                'property': 'final value',
            }
        ).as_string()
        second_edit_form_id = submit_case_blocks(case_block, domain=self.domain)

        # validate that worked
        case = self.interface.case_model.get(case_id)
        self.assertEqual(case.property, 'final value')
        self.assertEqual([create_form_id, edit_form_id, second_edit_form_id], case.xform_ids)
        self.assertEqual([create_form_id, edit_form_id, second_edit_form_id], [a.xform_id for a in
            case.actions])

        # deprecate the middle edit
        case_block = CaseBlock(
            create=False,
            case_id=case_id,
            date_modified=edit_date,  # need to use the previous edit date for action sort comparisons
            update={
                'property': 'edited value',
                'added_property': 'added value',
            }
        ).as_string()
        submit_case_blocks(case_block, domain=self.domain, form_id=edit_form_id)

        # ensure that the middle edit stays in the right place and is applied
        # before the final one
        case = self.interface.case_model.get(case_id)
        self.assertEqual(case.property, 'final value')
        self.assertEqual(case.added_property, 'added value')
        self.assertEqual([create_form_id, edit_form_id, second_edit_form_id], case.xform_ids)
        self.assertEqual([create_form_id, edit_form_id, second_edit_form_id], [a.xform_id for a in
            case.actions])