コード例 #1
0
ファイル: test_casedata.py プロジェクト: johan--/commcare-hq
    def setUp(self):
        delete_all_xforms()
        delete_all_cases()

        FormProcessorInterface.post_case_blocks(
            [CaseBlock(create=True, case_id="mother_case_id", case_type="mother-case").as_xml()],
            {"domain": TEST_DOMAIN},
        )

        self.case_id = "test_case_1"
        self.date_modified = datetime.utcnow() - timedelta(hours=1)
        self.date_modified = self.date_modified.replace(microsecond=0)
        FormProcessorInterface.post_case_blocks(
            [
                CaseBlock(
                    create=True,
                    case_id=self.case_id,
                    owner_id="owner",
                    user_id="user",
                    case_type="c_type",
                    case_name=("a" * TEST_NAME_LEN) + "123456789",
                    external_id="external_id",
                    date_modified=self.date_modified,
                    update={"foo": "bar"},
                    index={"mom": ("mother-case", "mother_case_id")},
                ).as_xml()
            ],
            {"domain": TEST_DOMAIN},
        )

        instance = CommCareCase.get(self.case_id)
        self.casedata = CaseData.create_or_update_from_instance(instance)
コード例 #2
0
    def testUserRestoreWithCase(self):
        file_path = os.path.join(os.path.dirname(__file__), "data", "create_short.xml")
        with open(file_path, "rb") as f:
            xml_data = f.read()
        FormProcessorInterface.submit_form_locally(xml_data, self.domain)

        expected_case_block = """
        <case case_id="asdf" date_modified="2010-06-29T13:42:50.000000Z" user_id="foo"
            xmlns="http://commcarehq.org/case/transaction/v2">
            <create>
                <case_type>test_case_type</case_type>
                <case_name>test case name</case_name>
                <owner_id>foo</owner_id>
            </create>
            <update>
                <external_id>someexternal</external_id>
            </update>
        </case>"""

        restore_payload = generate_restore_payload(
            project=Domain(name=self.domain),
            user=dummy_user(),
            items=True,
            version=V3
        )
        sync_log_id = SyncLog.view(
            "phone/sync_logs_by_user",
            include_docs=True,
            reduce=False,
        ).one().get_id
        check_xml_line_by_line(
            self,
            dummy_restore_xml(sync_log_id, expected_case_block, items=4),
            restore_payload
        )
コード例 #3
0
 def testMismatch(self):
     self.assertEqual(CaseStateHash(EMPTY_HASH), self.sync_log.get_state_hash())
     
     c1 = CaseBlock(case_id="abc123", create=True, 
                    owner_id=self.user.user_id).as_xml()
     c2 = CaseBlock(case_id="123abc", create=True, 
                    owner_id=self.user.user_id).as_xml()
     FormProcessorInterface.post_case_blocks([c1, c2],
                      form_extras={"last_sync_token": self.sync_log.get_id})
     
     self.sync_log = get_properly_wrapped_sync_log(self.sync_log.get_id)
     real_hash = CaseStateHash("409c5c597fa2c2a693b769f0d2ad432b")
     bad_hash = CaseStateHash("thisisntright")
     self.assertEqual(real_hash, self.sync_log.get_state_hash())
     generate_restore_payload(
         self.project, self.user, self.sync_log.get_id,
         version=V2, state_hash=str(real_hash)
     )
     
     try:
         generate_restore_payload(self.project, self.user, self.sync_log.get_id,
                                  version=V2, state_hash=str(bad_hash))
         self.fail("Call to generate a payload with a bad hash should fail!")
     except BadStateException, e:
         self.assertEqual(real_hash, e.server_hash)
         self.assertEqual(bad_hash, e.phone_hash)
         self.assertEqual(2, len(e.case_ids))
         self.assertTrue("abc123" in e.case_ids)
         self.assertTrue("123abc" in e.case_ids)
コード例 #4
0
ファイル: retire.py プロジェクト: johan--/commcare-hq
    def test_deleted_indices_removed(self):
        factory = CaseFactory(
            self.domain,
            case_defaults={
                'user_id': self.commcare_user._id,
                'owner_id': self.commcare_user._id,
                'case_type': 'a-case',
                'create': True,
            },
        )
        # create a parent/child set of cases
        parent_id, child_id = [uuid.uuid4().hex for i in range(2)]
        child, parent = factory.create_or_update_case(CaseStructure(
            case_id=child_id,
            indices=[
                CaseIndex(CaseStructure(case_id=parent_id))
            ]
        ))
        # confirm the child has an index, and 1 form
        self.assertEqual(1, len(child.indices))
        self.assertEqual(parent_id, child.indices[0].referenced_id)
        self.assertEqual(1, len(child.xform_ids))

        # simulate parent deletion
        FormProcessorInterface.soft_delete_case(parent_id)

        # call the remove index task
        remove_indices_from_deleted_cases(self.domain, [parent_id])

        # check that the index is removed via a new form
        child = CommCareCase.get(child_id)
        self.assertEqual(0, len(child.indices))
        self.assertEqual(2, len(child.xform_ids))
コード例 #5
0
ファイル: test_bugs.py プロジェクト: johan--/commcare-hq
 def test_conflicting_ids(self):
     """
     If a form and a case share an ID it's a conflict
     """
     xml_data = self.get_xml('id_conflicts')
     with self.assertRaises(BulkSaveError):
         FormProcessorInterface.submit_form_locally(xml_data)
コード例 #6
0
ファイル: test_archive.py プロジェクト: johan--/commcare-hq
    def testSignal(self):
        global archive_counter, restore_counter
        archive_counter = 0
        restore_counter = 0

        def count_archive(**kwargs):
            global archive_counter
            archive_counter += 1

        def count_unarchive(**kwargs):
            global restore_counter
            restore_counter += 1

        xform_archived.connect(count_archive)
        xform_unarchived.connect(count_unarchive)

        xform = FormProcessorInterface.create_from_generic(
            GenericXFormInstance(form={'foo': 'bar'}),
            GenericFormAttachment(name='form.xml', content='<data/>')
        )

        self.assertEqual(0, archive_counter)
        self.assertEqual(0, restore_counter)

        FormProcessorInterface.archive_xform(xform)
        self.assertEqual(1, archive_counter)
        self.assertEqual(0, restore_counter)

        FormProcessorInterface.unarchive_xform(xform)
        self.assertEqual(1, archive_counter)
        self.assertEqual(1, restore_counter)
コード例 #7
0
 def update_and_test(case_id, owner=None, should_have=None, should_not_have=None):
     case_block = self.get_update_block(
         case_id=case_id,
         update={'greeting': "Hello!"},
         owner_id=owner.get_id if owner else None,
     )
     FormProcessorInterface.post_case_blocks([case_block], {'domain': self.domain})
     check_has_block(case_block, should_have, should_not_have, line_by_line=False)
コード例 #8
0
ファイル: util.py プロジェクト: johan--/commcare-hq
 def add_parent_access(self, user, case):
     case_block = CaseBlock(
         create=True,
         case_id=uuid.uuid4().hex,
         case_type='magic_map',
         owner_id=user._id,
         index={'parent': ('participant', case._id)}
     ).as_xml()
     FormProcessorInterface.post_case_blocks([case_block], {'domain': self.domain})
コード例 #9
0
 def create_and_test(case_id, user, owner, should_have, should_not_have):
     case_block = self.get_create_block(
         case_id=case_id,
         type="case",
         user_id=user.user_id,
         owner_id=owner.get_id,
     )
     FormProcessorInterface.post_case_blocks([case_block], {'domain': self.domain})
     check_has_block(case_block, should_have, should_not_have)
コード例 #10
0
ファイル: util.py プロジェクト: johan--/commcare-hq
 def update_case_owner(self, case, owner):
     case_block = CaseBlock(
         create=False,
         case_id=case._id,
         case_type='participant',
         owner_id=owner._id,
         user_id=owner._id,
     ).as_xml()
     FormProcessorInterface.post_case_blocks([case_block], {'domain': self.domain})
コード例 #11
0
ファイル: test_edits.py プロジェクト: johan--/commcare-hq
    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.
        """

        class BorkDB(object):
            """context manager for making a db's bulk_save temporarily fail"""
            def __init__(self, db):
                self.old = {}
                self.db = db

            def __enter__(self):
                self.old['bulk_save'] = self.db.bulk_save
                self.db.bulk_save = MagicMock(name='bulk_save',
                                              side_effect=RequestFailed())

            def __exit__(self, exc_type, exc_val, exc_tb):
                self.db.bulk_save = self.old['bulk_save']

        xforms = FormProcessorInterface.get_by_doc_type(self.domain, 'XFormInstance')
        self.assertEqual(len(xforms), 0)

        xml_data1, xml_data2 = self._get_files()

        submit_form_locally(xml_data1, self.domain)
        xform = FormProcessorInterface.get_xform(self.ID)
        self.assertEqual(self.ID, xform.id)
        self.assertEqual("XFormInstance", xform.doc_type)
        self.assertEqual(self.domain, xform.domain)

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

        # This seems like a couch specific test util. Will likely need postgres test utils
        with BorkDB(XFormInstance.get_db()):
            with self.assertRaises(RequestFailed):
                submit_form_locally(xml_data2, self.domain)

        # it didn't go through, so make sure there are no edits still
        xforms = FormProcessorInterface.get_by_doc_type(self.domain, 'XFormDeprecated')
        self.assertEqual(len(xforms), 0)
        xform = FormProcessorInterface.get_xform(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
        )
コード例 #12
0
ファイル: test_casedata.py プロジェクト: johan--/commcare-hq
    def test_empty_name(self):
        case_id = "case_with_no_name"
        FormProcessorInterface.post_case_blocks(
            [CaseBlock(create=True, case_id=case_id, case_type="nameless").as_xml()], {"domain": TEST_DOMAIN}
        )

        instance = CommCareCase.get(case_id)
        casedata = CaseData.create_or_update_from_instance(instance)
        self.assertIsNotNone(casedata)
        self.assertEqual("", casedata.name)
コード例 #13
0
ファイル: test_view.py プロジェクト: johan--/commcare-hq
 def _new_case(cls, properties):
     id = uuid.uuid4().hex
     case_block = CaseBlock(
         create=True,
         case_id=id,
         case_type=cls.case_type,
         update=properties,
     ).as_xml()
     FormProcessorInterface.post_case_blocks([case_block], {'domain': cls.domain})
     return CommCareCase.get(id)
コード例 #14
0
ファイル: test_exclusion.py プロジェクト: johan--/commcare-hq
    def testTopLevelExclusion(self):
        """
        Entire forms tagged as device logs should be excluded
        """
        file_path = os.path.join(os.path.dirname(__file__), "data", "exclusion", "device_report.xml")
        with open(file_path, "rb") as f:
            xml_data = f.read()

        FormProcessorInterface.submit_form_locally(xml_data)
        self.assertEqual(0, get_total_case_count())
コード例 #15
0
 def test_assign_bad_index_ref(self):
     # the case has to exist to create the index, but if we delete it later the assignment
     # shouldn't fail
     case = self._new_case()
     case_with_bad_ref = self._new_case(index={"parent": ("person", case._id)})
     FormProcessorInterface.soft_delete_case(case._id)
     # this call previously failed
     res = assign_case(case_with_bad_ref.id, self.primary_user._id, include_subcases=True, include_parent_cases=True)
     self.assertEqual(2, len(res))
     self.assertIn(case_with_bad_ref._id, res)
     self.assertIn(case._id, res)
コード例 #16
0
ファイル: test_bugs.py プロジェクト: johan--/commcare-hq
    def testDuplicateCasePropertiesBug(self):
        """
        Submit multiple values for the same property in an update block
        """
        xml_data = self.get_xml('duplicate_case_properties')
        response, form, [case] = FormProcessorInterface.submit_form_locally(xml_data)
        self.assertEqual("", case.foo)

        xml_data = self.get_xml('duplicate_case_properties_2')
        response, form, [case] = FormProcessorInterface.submit_form_locally(xml_data)
        self.assertEqual("2", case.bar)
コード例 #17
0
 def _check_state(self, new_owner_id, expected_changed, update=None):
     expected_ids = set(c._id for c in expected_changed)
     for case in expected_changed:
         expected = FormProcessorInterface.get_case(case._id)
         self.assertEqual(new_owner_id, expected.owner_id)
         if update:
             for prop, value in update.items():
                 self.assertEqual(getattr(expected, prop), value)
     for case in (c for c in self.all if c._id not in expected_ids):
         remaining = FormProcessorInterface.get_case(case._id)
         self.assertEqual(self.original_owner._id, remaining.owner_id)
コード例 #18
0
    def test_basic_duplicate(self):
        xml_data = self._get_file()
        xform = FormProcessorInterface.post_xform(xml_data)
        self.assertEqual(self.ID, xform.id)
        self.assertEqual("XFormInstance", xform.doc_type)
        self.assertEqual("test-domain", xform.domain)

        xform = FormProcessorInterface.post_xform(xml_data, domain='test-domain')
        self.assertNotEqual(self.ID, xform.id)
        self.assertEqual("XFormDuplicate", xform.doc_type)
        self.assertTrue(self.ID in xform.problem)
コード例 #19
0
ファイル: test_indexes.py プロジェクト: johan--/commcare-hq
    def testRelationshipGetsSet(self):
        user = User(user_id=USER_ID, username="", password="", date_joined="")
        create_index = CaseBlock(
            create=True,
            case_id=self.CASE_ID,
            user_id=USER_ID,
            owner_id=USER_ID,
            index={'mom': ('mother-case', self.MOTHER_CASE_ID, 'extension')},
        ).as_xml()

        FormProcessorInterface.post_case_blocks([create_index])
        check_user_has_case(self, user, create_index)
コード例 #20
0
    def testOutOfOrderSubmissions(self):
        dir = os.path.join(os.path.dirname(__file__), "data", "ordering")
        for fname in ('update_oo.xml', 'create_oo.xml'):
            with open(os.path.join(dir, fname), "rb") as f:
                xml_data = f.read()

            FormProcessorInterface.submit_form_locally(xml_data)

        case = FormProcessorInterface.get_case('30bc51f6-3247-4966-b4ae-994f572e85fe')
        self.assertEqual('from the update form', case.pupdate)
        self.assertEqual('from the create form', case.pcreate)
        self.assertEqual('overridden by the update form', case.pboth)
コード例 #21
0
    def test_wrong_domain(self):
        domain = 'test-domain'
        generic_xform = GenericXFormInstance(
            doc_type='XFormInstance',
            domain='wrong-domain',
        )
        xform = FormProcessorInterface.create_from_generic(generic_xform)

        instance = self._get_file()
        instance = instance.replace(self.ID, xform.id)
        xform = FormProcessorInterface.post_xform(instance, domain=domain)
        self.assertNotEqual(xform.id, self.ID)
コード例 #22
0
ファイル: test_dbcache.py プロジェクト: johan--/commcare-hq
def _make_some_cases(howmany, domain='dbcache-test'):
    ids = [uuid.uuid4().hex for i in range(howmany)]
    FormProcessorInterface.post_case_blocks([
        CaseBlock(
            create=True,
            case_id=ids[i],
            user_id='some-user',
            update={
                'my_index': i,
            }
        ).as_xml() for i in range(howmany)
    ], {'domain': domain})
    return ids
コード例 #23
0
ファイル: test_casedata.py プロジェクト: johan--/commcare-hq
    def test_update(self):
        FormProcessorInterface.post_case_blocks(
            [
                CaseBlock(
                    create=True, case_id="grand_mother_case_id", case_type="mother-case", owner_id="owner"
                ).as_xml()
            ],
            {"domain": TEST_DOMAIN},
        )

        date_modified = datetime.utcnow()
        FormProcessorInterface.post_case_blocks(
            [
                CaseBlock(
                    close=True,
                    case_id=self.case_id,
                    user_id="user2",
                    date_modified=date_modified,
                    index={"gmom": ("mother-case", "grand_mother_case_id")},
                ).as_xml()
            ],
            {"domain": TEST_DOMAIN},
        )

        instance = CommCareCase.get(self.case_id)
        updateddata = CaseData.create_or_update_from_instance(instance)
        self.assertEqual(date_modified, updateddata.modified_on)
        self.assertEqual("user2", updateddata.modified_by)
        self.assertEqual(date_modified, updateddata.closed_on)
        self.assertEqual(True, updateddata.closed)

        actions = updateddata.actions.all()
        self.assertEqual(5, len(actions))
        for action in actions:
            if action.index == 4:
                self.assertEqual("close", action.action_type)
                self.assertEqual(date.today(), action.date.date())
                self.assertEqual(date.today(), action.server_date.date())
                self.assertEqual("user2", action.user_id)
                self.assertEqual("owner", action.case_owner)
                self.assertEqual("c_type", action.case_type)

        indices = self.casedata.indices.all()
        self.assertEqual(2, len(indices))
        self.assertEqual("gmom", indices[0].identifier)
        self.assertEqual("mother-case", indices[0].referenced_type)
        self.assertEqual("grand_mother_case_id", indices[0].referenced_id)
        self.assertEqual("mom", indices[1].identifier)
        self.assertEqual("mother-case", indices[1].referenced_type)
        self.assertEqual("mother_case_id", indices[1].referenced_id)
コード例 #24
0
ファイル: test_meta.py プロジェクト: johan--/commcare-hq
    def test_gps_location(self):
        file_path = os.path.join(os.path.dirname(__file__), "data", "gps_location.xml")
        xml_data = open(file_path, "rb").read()

        xform_generic = FormProcessorInterface.post_xform(xml_data)

        self.assertEqual(
            xform_generic.metadata.location,
            # '42.3739063 -71.1109113 0.0 886.0'
            GeoPoint(
                latitude=Decimal('42.3739063'),
                longitude=Decimal('-71.1109113'),
                altitude=Decimal('0.0'),
                accuracy=Decimal('886.0'),
            )
        )

        self.assertEqual(xform_generic.metadata.to_json(), {
            'username': u'*****@*****.**',
            'doc_type': 'Metadata',
            'instanceID': u'5d3d01561f584e85b53669a48bfc6039',
            'userID': u'f7f0c79e-8b79-11df-b7de-005056c00008',
            'timeEnd': '2013-07-20T00:02:27.493000Z',
            'appVersion': u'2.0',
            'timeStart': '2013-07-19T21:21:31.188000Z',
            'deprecatedID': None,
            'deviceID': u'commconnect',
            'location': '42.3739063 -71.1109113 0.0 886.0',
        })
コード例 #25
0
ファイル: test_errors.py プロジェクト: johan--/commcare-hq
    def test_uses_referrals(self):
        """
        submit form with a case block that uses referrals

        check that
        - it errors
        - the form is not saved under its original id
        - an XFormError is saved with the original id as orig_id
        """
        submit_form_locally(
            """<data xmlns="example.com/foo">
                <meta>
                    <instanceID>abc-easy-as-456</instanceID>
                </meta>
            <case case_id="123" xmlns="http://commcarehq.org/case/transaction/v2">
                <referral>
                    <referral_id>456</referral_id>
                    <open>
                        <referral_types>t1 t2</referral_types>
                    </open>
                </referral>
            </case>
            </data>""",
            'my_very_special_domain',
        )
        xform_errors = FormProcessorInterface.get_by_doc_type('my_very_special_domain', 'XFormError')

        related_errors = [xform_error for xform_error in xform_errors
                          if xform_error.id == 'abc-easy-as-456']
        self.assertEqual(len(related_errors), 1)
        related_error = related_errors[0]
        self.assertEqual(related_error.problem,
                'UsesReferrals: Sorry, referrals are no longer supported!')
コード例 #26
0
ファイル: test_errors.py プロジェクト: johan--/commcare-hq
    def test_no_case_id(self):
        """
        submit form with a case block that has no case_id

        check that
        - it errors
        - the form is not saved under its original id
        - an XFormError is saved with the original id as orig_id
        - the error was logged (<-- is this hard to test?)

        <data xmlns="example.com/foo">
            <case case_id="">
                <update><foo>bar</foo></update>
            </case>
        </data>
        """
        submit_form_locally(
            """<data xmlns="example.com/foo">
                <meta>
                    <instanceID>abc-easy-as-123</instanceID>
                </meta>
            <case case_id="" xmlns="http://commcarehq.org/case/transaction/v2">
                <update><foo>bar</foo></update>
            </case>
            </data>""",
            'my_very_special_domain',
        )
        xform_errors = FormProcessorInterface.get_by_doc_type('my_very_special_domain', 'XFormError')

        related_errors = [xform_error for xform_error in xform_errors
                          if xform_error.id == 'abc-easy-as-123']
        self.assertEqual(len(related_errors), 1)
        related_error = related_errors[0]
        self.assertEqual(related_error.problem,
                         'IllegalCaseId: case_id must not be empty')
コード例 #27
0
 def testCasesInRepeats(self):
     file_path = os.path.join(os.path.dirname(__file__), "data", "multicase", "case_in_repeats.xml")
     with open(file_path, "rb") as f:
         xml_data = f.read()
     _, form, cases = FormProcessorInterface.submit_form_locally(xml_data, domain=self.domain)
     self.assertEqual(3, len(cases))
     self._check_ids(form, cases)
コード例 #28
0
ファイル: test_meta.py プロジェクト: johan--/commcare-hq
    def testMetaDateInDatetimeFields(self):
        file_path = os.path.join(os.path.dirname(__file__), "data", "date_in_meta.xml")
        xml_data = open(file_path, "rb").read()
        xform_generic = FormProcessorInterface.post_xform(xml_data)

        self.assertEqual(datetime(2014, 7, 10), xform_generic.metadata.timeStart)
        self.assertEqual(datetime(2014, 7, 11), xform_generic.metadata.timeEnd)
コード例 #29
0
ファイル: test_meta.py プロジェクト: johan--/commcare-hq
    def testDecimalAppVersion(self):
        '''
        Tests that an appVersion that looks like a decimal:
        (a) is not converted to a Decimal by couchdbkit
        (b) does not crash anything
        '''

        file_path = os.path.join(os.path.dirname(__file__), "data", "decimalmeta.xml")
        xml_data = open(file_path, "rb").read()
        xform_generic = FormProcessorInterface.post_xform(xml_data)

        self.assertEqual(xform_generic.metadata.appVersion, '2.0')
        self.assertEqual(xform_generic.metadata.to_json(), {
            'username': u'admin',
            'doc_type': 'Metadata',
            'instanceID': None,
            'userID': u'f7f0c79e-8b79-11df-b7de-005056c00008',
            'timeEnd': '2010-07-23T13:55:11.648000Z',
            'appVersion': u'2.0',
            'timeStart': '2010-07-22T13:54:27.971000Z',
            'deprecatedID': None,
            'deviceID': None,
            'clinic_id': u'5020280',
            'location': None,
        })
コード例 #30
0
ファイル: test_post.py プロジェクト: johan--/commcare-hq
    def _test(self, name, any_id_ok=False, tz_differs=False):
        with open(os.path.join(os.path.dirname(__file__), 'data', '{name}.xml'.format(name=name))) as f:
            instance = f.read()

        if tz_differs and phone_timezones_should_be_processed():
            expected_name = name + '-tz'
        else:
            expected_name = name

        with open(os.path.join(os.path.dirname(__file__), 'data',
                               '{name}.json'.format(name=expected_name))) as f:
            result = json.load(f)

        xform = FormProcessorInterface.post_xform(instance)
        xform_json = json.loads(json.dumps(xform.to_json()))
        for key in ['is_archived', 'is_deprecated', 'is_duplicate', 'is_error']:
            del xform_json[key]

        result['received_on'] = xform_json['received_on']
        result['_rev'] = xform_json['_rev']
        result['_attachments'] = None
        xform_json['_attachments'] = None
        if any_id_ok:
            result['_id'] = xform_json['_id']
            result['id'] = xform_json['id']

        self.assertDictEqual(xform_json, result)