예제 #1
0
    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',
            version=V2,
        ).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',
            version=V2,
        ).as_string()
        submit_case_blocks(case_block, domain=self.domain, form_id=form_id)

        form = XFormInstance.get(form_id)
        self.assertEqual('XFormError', form.doc_type)

        deprecated_form = XFormInstance.get(form.deprecated_form_id)
        self.assertEqual('XFormDeprecated', deprecated_form.doc_type)
예제 #2
0
    def test_simple_swap(self):
        # Test a form with a single dup
        bad_form_id = self._submit_form()._id
        good_dup_id = self._submit_form(bad_form_id)._id

        with tempdir() as tmp:
            ids_file_path = os.path.join(tmp, 'ids')

            with open(ids_file_path, "w") as ids_file:
                ids_file.write("{} {}\n".format(DOMAIN, bad_form_id))

            call_command('swap_duplicate_xforms', ids_file_path, '/dev/null', no_input=True)
            # Throw in a second call to the script to test idempotence as well
            call_command('swap_duplicate_xforms', ids_file_path, '/dev/null', no_input=True)

            bad_form = XFormInstance.get(bad_form_id)
            self.assertEqual(bad_form.doc_type, "XFormDuplicate")
            self.assertRegexpMatches(
                bad_form.problem, BAD_FORM_PROBLEM_TEMPLATE.format(good_dup_id, "")
            )

            good_dup_form = XFormInstance.get(good_dup_id)
            self.assertEqual(good_dup_form.doc_type, "XFormInstance")
            self.assertRegexpMatches(
                good_dup_form.problem, FIXED_FORM_PROBLEM_TEMPLATE.format(
                    id_=bad_form_id, datetime_=""
                )
            )
예제 #3
0
 def tearDown(self):
     self.case_repeater.delete()
     self.form_repeater.delete()
     XFormInstance.get(instance_id).delete()
     repeat_records = RepeatRecord.all()
     for repeat_record in repeat_records:
         repeat_record.delete()
예제 #4
0
    def swap_doc_types(self, log_file, bad_xform_id, duplicate_xform_id, domain, dry_run):
        bad_xform = XFormInstance.get(bad_xform_id)

        # confirm that the doc hasn't already been fixed:
        bad_xform_problem = None
        try:
            bad_xform_problem = bad_xform.problem or ""
        except AttributeError:
            pass
        if bad_xform_problem:
            if re.match(PROBLEM_TEMPLATE_START, bad_xform_problem):
                self.log_already_fixed(log_file, bad_xform_id, domain)
                return

        duplicate_xform = XFormInstance.get(duplicate_xform_id)
        now = datetime.now().isoformat()

        # Convert the XFormInstance to an XFormDuplicate
        bad_xform.doc_type = XFormDuplicate.__name__
        bad_xform.problem = BAD_FORM_PROBLEM_TEMPLATE.format(duplicate_xform_id, now)
        bad_xform = XFormDuplicate.wrap(bad_xform.to_json())

        # Convert the XFormDuplicate to an XFormInstance
        duplicate_xform.problem = FIXED_FORM_PROBLEM_TEMPLATE.format(
            id_=bad_xform_id, datetime_=now
        )
        duplicate_xform.doc_type = XFormInstance.__name__
        duplicate_xform = XFormInstance.wrap(duplicate_xform.to_json())

        self.log_swap(log_file, bad_xform_id, domain, duplicate_xform_id, dry_run)

        if not dry_run:
            duplicate_xform.save()
            bad_xform.save()
예제 #5
0
    def test_migration(self):
        now = datetime.utcnow()
        repeats = [
            {
                "url": "http://example.com/",
                "doc_type": "RepeatRecord",
                "next_check": now,
                "last_checked": None,
                "succeeded": False
            }
        ]
        xform = XFormInstance.get(instance_id)
        xform.repeats = repeats
        xform.save()

        def always_success():
            while True:
                yield 200

        self.clear_log()

        check_inline_form_repeaters(post_fn=self.make_post_fn(always_success()))

        self.assertEqual(len(self.log), 1)

        self.assertEqual(self.log[0], (repeats[0]['url'], 200, xform_xml))

        self.clear_log()

        check_inline_form_repeaters(post_fn=self.make_post_fn(always_success()))

        self.assertEqual(len(self.log), 0)
예제 #6
0
    def testArchivingOnlyForm(self):
        """
        Checks that archiving the only form associated with the case archives
        the case and unarchiving unarchives it.
        """
        case_id = _post_util(create=True, p1='p1-1', p2='p2-1')
        case = CommCareCase.get(case_id)

        self.assertEqual('CommCareCase', case._doc['doc_type'])
        self.assertEqual(2, len(case.actions))
        [form_id] = case.xform_ids
        form = XFormInstance.get(form_id)

        form.archive()
        case = CommCareCase.get(case_id)

        self.assertEqual('CommCareCase-Deleted', case._doc['doc_type'])
        # should just have the 'rebuild' action
        self.assertEqual(1, len(case.actions))
        self.assertEqual(const.CASE_ACTION_REBUILD, case.actions[0].action_type)

        form.unarchive()
        case = CommCareCase.get(case_id)
        self.assertEqual('CommCareCase', case._doc['doc_type'])
        self.assertEqual(3, len(case.actions))
        self.assertEqual(const.CASE_ACTION_REBUILD, case.actions[-1].action_type)
예제 #7
0
    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()
        with create_xform_from_xml(xml_data) as doc_id:
            xform = XFormInstance.get(doc_id)
        self.assertEqual(xform.metadata.appVersion, "2.0")
        self.assertEqual(
            xform.metadata.to_json(),
            {
                "username": u"admin",
                "doc_type": "Metadata",
                "instanceID": None,
                "userID": u"f7f0c79e-8b79-11df-b7de-005056c00008",
                "timeEnd": "2010-07-23T13:55:11Z",
                "appVersion": u"2.0",
                "timeStart": "2010-07-22T13:54:27Z",
                "deprecatedID": None,
                "deviceID": None,
                "clinic_id": u"5020280",
                "location": None,
            },
        )
예제 #8
0
    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)

        with create_and_save_xform(instance) as doc_id:
            xform = XFormInstance.get(doc_id)
            try:
                xform_json = xform.to_json()
                result['received_on'] = xform_json['received_on']
                result['_rev'] = xform_json['_rev']
                if any_id_ok:
                    result['_id'] = xform_json['_id']
                self.assertDictEqual(xform_json, result)
            except Exception:
                # to help when bootstrapping a new test case
                print json.dumps(xform_json)
                raise
            finally:
                xform.delete()
예제 #9
0
    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()
        with create_xform_from_xml(xml_data) as doc_id:
            xform = XFormInstance.get(doc_id)
            self.assertEqual(
                xform.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"),
                ),
            )

            j = xform.metadata.to_json()
            self.assertEqual(
                xform.metadata.to_json(),
                {
                    "username": u"*****@*****.**",
                    "doc_type": "Metadata",
                    "instanceID": u"5d3d01561f584e85b53669a48bfc6039",
                    "userID": u"f7f0c79e-8b79-11df-b7de-005056c00008",
                    "timeEnd": "2013-07-20T00:02:27Z",
                    "appVersion": u"2.0",
                    "timeStart": "2013-07-19T21:21:31Z",
                    "deprecatedID": None,
                    "deviceID": u"commconnect",
                    "location": "42.3739063 -71.1109113 0.0 886.0",
                },
            )
            xform.delete()
예제 #10
0
    def process_xform(self, form_id, new_domain, new_owner, level):
        if form_id not in self.forms_processing:
            self.forms_processing[form_id] = self.new_id()
        else:
            return

        print "{}=== xform: {} -> {}".format('    ' * (level+1), form_id, self.forms_processing[form_id])

        instance = XFormInstance.get(form_id)
        xml = instance.get_xml()
        referenced_case_ids = set(re.findall(r'case_id="([\w-]*)"', xml))
        for ref_case_id in referenced_case_ids:
            if ref_case_id not in self.cases_processing:
                self.duplicate_case(ref_case_id, new_domain, new_owner, level=level+1)

            xml = xml.replace(ref_case_id, self.cases_processing[ref_case_id])

        referenced_user_ids = set(re.findall(r'user_id="([\w-]*)"', xml))
        for ref_form_id in referenced_user_ids:
            xml = xml.replace(ref_form_id, new_owner)

        instance_ids = set(re.findall(r'instanceID>([\w-]*)</', xml))
        for inst_id in instance_ids:
            xml = xml.replace(inst_id, self.forms_processing[form_id])

        resp = simple_post(xml, self.submit_url, content_type='text/xml')
        if not resp.status in [200, 201]:
            raise Exception(resp.read())
        # with open("{}/{}.xml".format(OUT, self.forms_processing[form_id]), "w") as form:
        #     form.write(xml)

        self.processed_docs.append(('form', form_id, self.forms_processing[form_id]))
예제 #11
0
 def test_blank_product_id(self):
     initial = float(100)
     balances = [("", initial)]
     instance_id = self.submit_xml_form(balance_submission(balances))
     instance = XFormInstance.get(instance_id)
     self.assertEqual("XFormError", instance.doc_type)
     self.assertTrue("MissingProductId" in instance.problem)
예제 #12
0
    def test_form_pillow_indicators(self):
        form_id = self._save_doc_to_db("indicator_form.json", XFormInstance)
        form_instance = XFormInstance.get(form_id)

        # Form Label Indicator
        form_label = FormLabelIndicatorDefinition.increment_or_create_unique(
            INDICATOR_TEST_NAMESPACE,
            INDICATOR_TEST_DOMAIN,
            slug="create_form",
            xmlns="http://openrosa.org/formdesigner/indicator-create-xmlns",
        )
        form_label.save()

        # Form Alias
        form_alias = FormDataAliasIndicatorDefinition.increment_or_create_unique(
            INDICATOR_TEST_NAMESPACE,
            INDICATOR_TEST_DOMAIN,
            slug="club_name",
            question_id="location.club",
            xmlns="http://openrosa.org/formdesigner/indicator-create-xmlns",
        )
        form_alias.save()

        self.form_pillow.run_burst()

        indicator_form = IndicatorXForm.get(form_id)
        self.assertNotEqual(indicator_form.get_db().dbname, form_instance.get_db().dbname)
        self.assertNotEqual(indicator_form.computed_, {})
예제 #13
0
def update_sync_log_with_checks(sync_log, xform, cases, case_db,
                                case_id_blacklist=None):
    assert case_db is not None
    from casexml.apps.case.xform import CaseProcessingConfig

    case_id_blacklist = case_id_blacklist or []
    try:
        sync_log.update_phone_lists(xform, cases)
    except SyncLogAssertionError, e:
        if e.case_id and e.case_id not in case_id_blacklist:
            form_ids = get_case_xform_ids(e.case_id)
            case_id_blacklist.append(e.case_id)
            for form_id in form_ids:
                if form_id != xform._id:
                    form = XFormInstance.get(form_id)
                    if form.doc_type in ['XFormInstance', 'XFormError']:
                        reprocess_form_cases(
                            form,
                            CaseProcessingConfig(
                                strict_asserts=True,
                                case_id_blacklist=case_id_blacklist
                            ),
                            case_db=case_db
                        )
            updated_log = SyncLog.get(sync_log._id)

            update_sync_log_with_checks(updated_log, xform, cases, case_db,
                                        case_id_blacklist=case_id_blacklist)
예제 #14
0
 def testClosed(self):
     file_path = os.path.join(os.path.dirname(__file__), "data", "meta.xml")
     xml_data = open(file_path, "rb").read()
     with create_xform_from_xml(xml_data) as doc_id:
         xform = XFormInstance.get(doc_id)
     self.assertNotEqual(None, xform.metadata)
     self.assertEqual(date(2010, 07, 22), xform.metadata.timeStart.date())
     self.assertEqual(date(2010, 07, 23), xform.metadata.timeEnd.date())
     self.assertEqual("admin", xform.metadata.username)
     self.assertEqual("f7f0c79e-8b79-11df-b7de-005056c00008", xform.metadata.userID)
     self.assertEqual("v1.2.3 (biz bazzle)", xform.metadata.appVersion)
     self.assertEqual(
         xform.metadata.to_json(),
         {
             "username": u"admin",
             "doc_type": "Metadata",
             "instanceID": None,
             "userID": u"f7f0c79e-8b79-11df-b7de-005056c00008",
             "timeEnd": "2010-07-23T13:55:11Z",
             "appVersion": u"v1.2.3 (biz bazzle)",
             "timeStart": "2010-07-22T13:54:27Z",
             "deprecatedID": None,
             "deviceID": None,
             "clinic_id": u"5020280",
             "location": None,
         },
     )
예제 #15
0
def form_data(request, domain, instance_id):
    timezone = util.get_timezone(request.couch_user.user_id, domain)
    try:
        instance = XFormInstance.get(instance_id)
    except Exception:
        raise Http404()
    try:
        assert(domain == instance.domain)
    except AssertionError:
        raise Http404()
    cases = CommCareCase.view("case/by_xform_id", key=instance_id, reduce=False, include_docs=True).all()
    try:
        form_name = instance.get_form["@name"]
    except KeyError:
        form_name = "Untitled Form"
    is_archived = instance.doc_type == "XFormArchived"
    if is_archived:
        messages.info(request, _("This form is archived. To restore it, click 'Restore this form' at the bottom of the page."))
    return render(request, "reports/reportdata/form_data.html",
                              dict(domain=domain,
                                   instance=instance,
                                   cases=cases,
                                   timezone=timezone,
                                   slug=inspect.SubmitHistory.slug,
                                   is_archived=is_archived,
                                   form_data=dict(name=form_name,
                                                  modified=instance.received_on)))
예제 #16
0
    def process_indicators(self, doc_dict, domain, namespaces):
        case_type = doc_dict.get('type')
        if not case_type:
            return

        case_indicators = []
        for namespace in namespaces:
            case_indicators.extend(CaseIndicatorDefinition.get_all(namespace, domain, case_type=case_type))

        if case_indicators:
            case_doc = CommCareCase.get(doc_dict['_id'])
            case_doc.update_indicators_in_bulk(case_indicators, logger=pillow_logging)

        xform_ids = doc_dict.get('xform_ids', [])
        for namespace in namespaces:
            for xform_id in xform_ids:
                try:
                    xform_doc = XFormInstance.get(xform_id)
                    if not xform_doc.xmlns:
                        continue
                    related_xform_indicators = CaseDataInFormIndicatorDefinition.get_all(namespace, domain,
                                                                                         xmlns=xform_doc.xmlns)
                    xform_doc.update_indicators_in_bulk(related_xform_indicators, logger=pillow_logging)
                except ResourceNotFound:
                    pillow_logging.error("[INDICATOR %(namespace)s %(domain)s] Tried to form indicator %(xform_id)s "
                                         "from case %(case_id)s and failed." % {
                                             'namespace': namespace,
                                             'domain': domain,
                                             'xform_id': xform_id,
                                             'case_id': doc_dict['_id'],
                                         })
예제 #17
0
    def test_form_pillow_indicators(self):
        form_id = self._save_doc_to_db('indicator_form.json', XFormInstance)
        form_instance = XFormInstance.get(form_id)

        # Form Label Indicator
        form_label = FormLabelIndicatorDefinition.increment_or_create_unique(
            INDICATOR_TEST_NAMESPACE,
            INDICATOR_TEST_DOMAIN,
            slug='create_form',
            xmlns='http://openrosa.org/formdesigner/indicator-create-xmlns',
        )
        form_label.save()

        # Form Alias
        form_alias = FormDataAliasIndicatorDefinition.increment_or_create_unique(
            INDICATOR_TEST_NAMESPACE,
            INDICATOR_TEST_DOMAIN,
            slug='club_name',
            question_id='location.club',
            xmlns='http://openrosa.org/formdesigner/indicator-create-xmlns',
        )
        form_alias.save()
        self.form_pillow.process_changes(since=None, forever=False)

        indicator_form = IndicatorXForm.get(form_id)
        self.assertNotEqual(
            indicator_form.get_db().dbname, form_instance.get_db().dbname
        )
        self.assertNotEqual(indicator_form.computed_, {})
예제 #18
0
    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()
        with create_and_save_xform(xml_data) as doc_id:
            xform = XFormInstance.get(doc_id)
            self.assertEqual(
                xform.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.metadata.to_json(), {
                'username': u'*****@*****.**',
                'doc_type': 'Metadata',
                'instanceID': u'5d3d01561f584e85b53669a48bfc6039',
                'userID': u'f7f0c79e-8b79-11df-b7de-005056c00008',
                'timeEnd': '2013-07-20T00:02:27Z',
                'appVersion': u'2.0',
                'timeStart': '2013-07-19T21:21:31Z',
                'deprecatedID': None,
                'deviceID': u'commconnect',
                'location': '42.3739063 -71.1109113 0.0 886.0',
            })
            xform.delete()
예제 #19
0
 def _get_case(session):
     session = XFormsSession.get(session.get_id)
     self.assertTrue(session.submission_id)
     instance = XFormInstance.get(session.submission_id)
     case_id = instance.xpath("form/case/@case_id")
     self.assertTrue(case_id)
     return CommCareCase.get(case_id)
예제 #20
0
    def get_indicators_by_doc(self, doc_dict):
        indicators = []

        case_type = doc_dict.get('type')
        domain = doc_dict.get('domain')
        form_ids = doc_dict.get('xform_ids') or []

        if case_type and domain:
            # relevant namespaces
            namespaces = INDICATOR_CONFIG[domain]

            for namespace in namespaces:
                # need all the relevant Case Indicator Defs
                indicators.extend(CaseIndicatorDefinition.get_all(namespace, domain, case_type=case_type))

                # we also need to update forms that are related to this case and might use data which
                # may have just been updated
                for form_id in form_ids:
                    try:
                        xform = XFormInstance.get(form_id)
                        if xform.xmlns and isinstance(xform, XFormInstance):
                            case_related_indicators = CaseDataInFormIndicatorDefinition.get_all(namespace, domain,
                                xmlns=xform.xmlns)
                            logging.info("Grabbed Related XForm %s and now processing %d indicators." %
                                         (form_id, len(case_related_indicators)))
                            FormIndicatorPillow.update_indicators_in_doc_instance(xform, case_related_indicators)
                            logging.info("Done processing indicators.")
                    except Exception as e:
                        logging.error("Error grabbing related xform for CommCareCase %s: %s" % (doc_dict['_id'], e))

        return indicators
예제 #21
0
def form_inline_display(form_id):
    if form_id:
        form = XFormInstance.get(form_id)
        if form:
            return "%s: %s" % (form.received_on.date(), form.xmlns)
        return "missing form: %s" % form_id
    return "empty form id found"
예제 #22
0
    def testArchiveLastForm(self):
        initial_amounts = [(p._id, float(100)) for p in self.products]
        self.submit_xml_form(balance_submission(initial_amounts))

        final_amounts = [(p._id, float(50)) for i, p in enumerate(self.products)]
        second_form_id = self.submit_xml_form(balance_submission(final_amounts))

        def _assert_initial_state():
            self.assertEqual(1, StockReport.objects.filter(form_id=second_form_id).count())
            # 6 = 3 stockonhand and 3 inferred consumption txns
            self.assertEqual(6, StockTransaction.objects.filter(report__form_id=second_form_id).count())
            self.assertEqual(3, StockState.objects.filter(case_id=self.sp._id).count())
            for state in StockState.objects.filter(case_id=self.sp._id):
                self.assertEqual(Decimal(50), state.stock_on_hand)
                self.assertIsNotNone(state.daily_consumption)

        # check initial setup
        _assert_initial_state()

        # archive and confirm commtrack data is deleted
        form = XFormInstance.get(second_form_id)
        form.archive()
        self.assertEqual(0, StockReport.objects.filter(form_id=second_form_id).count())
        self.assertEqual(0, StockTransaction.objects.filter(report__form_id=second_form_id).count())
        self.assertEqual(3, StockState.objects.filter(case_id=self.sp._id).count())
        for state in StockState.objects.filter(case_id=self.sp._id):
            # balance should be reverted to 100 in the StockState
            self.assertEqual(Decimal(100), state.stock_on_hand)
            # consumption should be none since there will only be 1 data point
            self.assertIsNone(state.daily_consumption)

        # unarchive and confirm commtrack data is restored
        form.unarchive()
        _assert_initial_state()
예제 #23
0
 def _test_post(self, client, url, expected_auth_context):
     with open(self.file_path, "rb") as f:
         response = client.post(url, {"xml_submission_file": f})
     xform_id = response['X-CommCareHQ-FormID']
     xform = XFormInstance.get(xform_id)
     self.assertEqual(xform.auth_context, expected_auth_context)
     return xform
예제 #24
0
    def testArchiveOnlyForm(self):
        # check no data in stock states
        self.assertEqual(0, StockState.objects.filter(case_id=self.sp._id).count())

        initial_amounts = [(p._id, float(100)) for p in self.products]
        form_id = self.submit_xml_form(balance_submission(initial_amounts))

        # check that we made stuff
        def _assert_initial_state():
            self.assertEqual(1, StockReport.objects.filter(form_id=form_id).count())
            self.assertEqual(3, StockTransaction.objects.filter(report__form_id=form_id).count())
            self.assertEqual(3, StockState.objects.filter(case_id=self.sp._id).count())
            for state in StockState.objects.filter(case_id=self.sp._id):
                self.assertEqual(Decimal(100), state.stock_on_hand)
        _assert_initial_state()

        # archive and confirm commtrack data is cleared
        form = XFormInstance.get(form_id)
        form.archive()
        self.assertEqual(0, StockReport.objects.filter(form_id=form_id).count())
        self.assertEqual(0, StockTransaction.objects.filter(report__form_id=form_id).count())
        self.assertEqual(0, StockState.objects.filter(case_id=self.sp._id).count())

        # unarchive and confirm commtrack data is restored
        form.unarchive()
        _assert_initial_state()
예제 #25
0
 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()
     with create_and_save_xform(xml_data) as doc_id:
         xform = XFormInstance.get(doc_id)
     self.assertEqual(xform.metadata.appVersion, '2.0')
     self.assertEqual(xform.metadata.to_json(), {
         'username': u'admin',
         'doc_type': 'Metadata',
         'instanceID': None,
         'userID': u'f7f0c79e-8b79-11df-b7de-005056c00008',
         'timeEnd': '2010-07-23T13:55:11Z',
         'appVersion': u'2.0',
         'timeStart': '2010-07-22T13:54:27Z',
         'deprecatedID': None,
         'deviceID': None,
         'clinic_id': u'5020280',
         'location': None,
     })
예제 #26
0
def form_inline_display(form_id, timezone=pytz.utc):
    if form_id:
        form = XFormInstance.get(form_id)
        if form:
            return "%s: %s" % (tz_utils.adjust_datetime_to_timezone(form.received_on, pytz.utc.zone, timezone.zone).date(), form.xmlns)
        return "missing form: %s" % form_id
    return "empty form id found"
예제 #27
0
 def xform(self):
     try:
         return XFormInstance.get(self.xform_id) if self.xform_id else None
     except ResourceNotFound:
         logging.exception("couldn't access form {form} inside of a referenced case.".format(
             form=self.xform_id,
         ))
         return None
예제 #28
0
def download_form(request, instance_id):
    instance = XFormInstance.get(instance_id)
    response = HttpResponse(mimetype='application/xml')
    response.write(instance.get_xml())
    # if we want it to download like a file put somethingl like this
    # HttpResponse(mimetype='application/vnd.ms-excel')
    # response['Content-Disposition'] = 'attachment; filename=%s.xml' % instance_id
    return response
예제 #29
0
 def xform(self):
     try:
         return XFormInstance.get(self.xform_id) if self.xform_id else None
     except ResourceNotFound:
         logging.exception(
             "couldn't access form {form} inside of a referenced case.".
             format(form=self.xform_id, ))
         return None
예제 #30
0
 def testMetaDateInDatetimeFields(self):
     file_path = os.path.join(os.path.dirname(__file__), "data", "date_in_meta.xml")
     xml_data = open(file_path, "rb").read()
     with create_and_save_xform(xml_data) as doc_id:
         xform = XFormInstance.get(doc_id)
         self.assertEqual(datetime(2014, 7, 10), xform.metadata.timeStart)
         self.assertEqual(datetime(2014, 7, 11), xform.metadata.timeEnd)
         xform.delete()
예제 #31
0
 def test_form_extras_override_defaults(self):
     domain = uuid.uuid4().hex
     LOOSE_SYNC_TOKEN_VALIDATION.set(domain, True, namespace='domain')
     token_id = uuid.uuid4().hex
     factory = CaseFactory(domain=domain, form_extras={'last_sync_token': token_id})
     [case] = factory.create_or_update_case(CaseStructure(), form_extras={'last_sync_token': 'differenttoken'})
     form = XFormInstance.get(case.xform_ids[0])
     self.assertEqual('differenttoken', form.last_sync_token)
예제 #32
0
 def testMetaDateInDatetimeFields(self):
     file_path = os.path.join(os.path.dirname(__file__), "data", "date_in_meta.xml")
     xml_data = open(file_path, "rb").read()
     with create_and_save_xform(xml_data) as doc_id:
         xform = XFormInstance.get(doc_id)
         self.assertEqual(datetime(2014, 7, 10), xform.metadata.timeStart)
         self.assertEqual(datetime(2014, 7, 11), xform.metadata.timeEnd)
         xform.delete()
예제 #33
0
def download_form(request, instance_id):
    instance = XFormInstance.get(instance_id) 
    response = HttpResponse(content_type='application/xml')
    response.write(instance.get_xml())
    # if we want it to download like a file put somethingl like this
    # HttpResponse(content_type='application/vnd.ms-excel')
    # response['Content-Disposition'] = 'attachment; filename=%s.xml' % instance_id
    return response
예제 #34
0
def download_attachment(request, instance_id, attachment):
    instance = XFormInstance.get(instance_id)
    try:
        attach = instance._attachments[attachment]
    except KeyError:
        raise Http404()
    response = HttpResponse(content_type=attach["content_type"])
    response.write(instance.fetch_attachment(attachment))
    return response
예제 #35
0
    def form_exists(form_id, domain=None):
        if not domain:
            return XFormInstance.get_db().doc_exist(form_id)
        else:
            try:
                xform = XFormInstance.get(form_id)
            except ResourceNotFound:
                return False

            return xform.domain == domain
예제 #36
0
def form_inline_display(form_id, timezone=pytz.utc):
    if form_id:
        try:
            form = XFormInstance.get(form_id)
            if form:
                return "%s: %s" % (ServerTime(form.received_on).user_time(timezone).done().date(), form.xmlns)
        except ResourceNotFound:
            pass
        return "%s: %s" % (_("missing form"), form_id)
    return _("empty form id found")
예제 #37
0
    def test_archive_forms_basic(self):
        uploaded_file = WorkbookJSONReader(join(BASE_PATH, BASIC_XLSX))

        response = archive_forms(self.domain_name, self.user, list(uploaded_file.get_worksheet()))

        # Need to re-get instance from DB to get updated attributes
        for key, _id in self.XFORMS.iteritems():
            self.assertEqual(XFormInstance.get(_id).doc_type, 'XFormArchived')

        self.assertEqual(len(response['success']), len(self.xforms))
예제 #38
0
def submit_unfinished_form(session_id, include_case_side_effects=False):
    """
    Gets the raw instance of the session's form and submits it. This is used with
    sms and ivr surveys to save all questions answered so far in a session that
    needs to close.

    If include_case_side_effects is False, no case create / update / close actions
    will be performed, but the form will still be submitted.

    The form is only submitted if the smsforms session has not yet completed.
    """
    session = SQLXFormsSession.by_session_id(session_id)
    if session is not None and session.end_time is None:
        # Get and clean the raw xml
        try:
            xml = get_raw_instance(session_id)['output']
        except InvalidSessionIdException:
            session.end(completed=False)
            session.save()
            return
        root = XML(xml)
        case_tag_regex = re.compile("^(\{.*\}){0,1}case$") # Use regex in order to search regardless of namespace
        meta_tag_regex = re.compile("^(\{.*\}){0,1}meta$")
        timeEnd_tag_regex = re.compile("^(\{.*\}){0,1}timeEnd$")
        current_timstamp = json_format_datetime(datetime.utcnow())
        for child in root:
            if case_tag_regex.match(child.tag) is not None:
                # Found the case tag
                case_element = child
                case_element.set("date_modified", current_timstamp)
                if not include_case_side_effects:
                    # Remove case actions (create, update, close)
                    child_elements = [case_action for case_action in case_element]
                    for case_action in child_elements:
                        case_element.remove(case_action)
            elif meta_tag_regex.match(child.tag) is not None:
                # Found the meta tag, now set the value for timeEnd
                for meta_child in child:
                    if timeEnd_tag_regex.match(meta_child.tag):
                        meta_child.text = current_timstamp
        cleaned_xml = tostring(root)
        
        # Submit the xml and end the session
        resp = submit_form_locally(cleaned_xml, session.domain,
            app_id=session.app_id)
        xform_id = resp['X-CommCareHQ-FormID']
        session.end(completed=False)
        session.submission_id = xform_id
        session.save()
        
        # Tag the submission as a partial submission
        xform = XFormInstance.get(xform_id)
        xform.partial_submission = True
        xform.survey_incentive = session.survey_incentive
        xform.save()
예제 #39
0
    def test_archive_forms_missing(self):
        uploaded_file = WorkbookJSONReader(join(BASE_PATH, MISSING_XLSX))

        response = archive_forms(self.domain_name, self.user, list(uploaded_file.get_worksheet()))

        for key, _id in self.XFORMS.iteritems():
            self.assertEqual(XFormInstance.get(_id).doc_type, 'XFormArchived')

        self.assertEqual(len(response['success']), len(self.xforms))
        self.assertEqual(len(response['errors']), 1,
                         "One error for trying to archive a missing form")
예제 #40
0
 def _test(self, id, expected_app_id, expected_build_id):
     r = spoof_submission(
         '/a/{domain}/receiver/{id}/'.format(domain=self.domain, id=id),
         '<data xmlns="http://example.com/"><question1/></data>',
         hqsubmission=False,
     )
     form_id = r['X-CommCareHQ-FormID']
     form = XFormInstance.get(form_id)
     self.assertEqual(form.app_id, expected_app_id)
     self.assertEqual(form.build_id, expected_build_id)
     return form
예제 #41
0
 def test_couch_blob_migration_edit(self):
     form_id = uuid.uuid4().hex
     case_id = uuid.uuid4().hex
     case_block = CaseBlock(create=True, case_id=case_id).as_string()
     xform = submit_case_blocks(case_block,
                                domain=self.domain,
                                form_id=form_id)
     # explicitly convert to old-style couch attachments to test the migration workflow
     form_xml = xform.get_xml()
     xform.delete_attachment('form.xml')
     xform.get_db().put_attachment(xform.to_json(), form_xml, 'form.xml')
     # make sure that worked
     updated_form_xml = XFormInstance.get(xform._id).get_xml()
     self.assertEqual(form_xml, updated_form_xml)
     # this call was previously failing
     updated_form = submit_case_blocks(case_block,
                                       domain=self.domain,
                                       form_id=form_id)
     self.assertEqual(
         form_xml,
         XFormInstance.get(updated_form.deprecated_form_id).get_xml())
예제 #42
0
    def testArchiveAfterAttach(self):
        single_attach = 'fruity_file'
        self._doCreateCaseWithMultimedia(attachments=[single_attach])

        case = CommCareCase.get(TEST_CASE_ID)

        for xform in case.xform_ids:
            form = XFormInstance.get(xform)
            form.archive()
            self.assertEqual('XFormArchived', form.doc_type)
            form.unarchive()
            self.assertEqual('XFormInstance', form.doc_type)
예제 #43
0
    def handle(self, *args, **options):
        ids = get_form_ids_by_type('ipm-senegal', 'XFormInstance')

        to_save = []

        locations = SQLLocation.objects.filter(
            domain='ipm-senegal').values_list('location_id', 'name')
        locations_map = {
            location_id: name
            for (location_id, name) in locations
        }

        for doc in iter_docs(XFormInstance.get_db(), ids):
            try:
                if 'PPS_name' in doc['form'] and not doc['form']['PPS_name']:
                    case = SupplyPointCase.get(doc['form']['case']['@case_id'])
                    if case.type == 'supply-point':
                        print 'Updating XFormInstance:', doc['_id']

                        pps_name = locations_map[case.location_id]

                        instance = XFormInstance.get(doc['_id'])

                        # fix the XFormInstance
                        instance.form['PPS_name'] = pps_name
                        for instance_prod in instance.form['products']:
                            instance_prod['PPS_name'] = instance_prod[
                                'PPS_name'] or pps_name

                        # fix the actual form.xml
                        xml_object = etree.fromstring(instance.get_xml())
                        pps_name_node = xml_object.find(
                            re.sub('}.*', '}PPS_name', xml_object.tag))
                        pps_name_node.text = pps_name

                        products_nodes = xml_object.findall(
                            re.sub('}.*', '}products', xml_object.tag))
                        for product_node in products_nodes:
                            product_pps_name_node = product_node.find(
                                re.sub('}.*', '}PPS_name', xml_object.tag))
                            product_pps_name_node.text = pps_name
                        updated_xml = etree.tostring(xml_object)

                        attachment_builder = CouchAttachmentsBuilder(
                            instance._attachments)
                        attachment_builder.add(
                            name='form.xml',
                            content=updated_xml,
                            content_type=instance._attachments['form.xml']
                            ['content_type'])
                        instance._attachments = attachment_builder.to_json()

                        to_save.append(instance)
예제 #44
0
    def test_empty_gps_location(self):
        file_path = os.path.join(os.path.dirname(__file__), "data", "gps_empty_location.xml")
        xml_data = open(file_path, "rb").read()
        with create_xform_from_xml(xml_data) as doc_id:
            xform = XFormInstance.get(doc_id)
            self.assertEqual(
                xform.metadata.location,
                None
            )

            self.assertEqual(xform.metadata.to_json()['location'], None)
            xform.delete()
예제 #45
0
def _add_eligible_9months(row_data, start_date, end_date, domain):
    eligible_9months = McctStatus.objects\
        .filter(domain__exact=domain)\
        .filter(status__exact="eligible")\
        .filter(immunized=False)\
        .filter(is_booking=False)\
        .filter(received_on__range=(start_date, end_date))
    forms = [form for form in [XFormInstance.get(status.form_id) for status in eligible_9months]
             if form.xmlns in FOLLOW_UP_FORMS]
    forms_4th_visit = [form for form in forms if form.form.get("visits", "") == "4"]
    row_data["all_eligible_clients_total"]["value"] += len(forms) - len(forms_4th_visit)
    row_data["status_eligible_due_to_4th_visit"]["value"] += len(forms_4th_visit)
예제 #46
0
    def _doTestNoPillbox(self, bundle):
        submit_xform(self.submit_url, self.domain.name, bundle['xml'])
        submitted = XFormInstance.get(bundle['xform_id'])
        self.assertTrue(hasattr(submitted, PACT_DOTS_DATA_PROPERTY))
        observations = query_observations(CASE_ID, bundle['start_date'],
                                          bundle['end_date'])
        observed_dates = set()
        #assume to be five - 3,2 same as the regimen count, we are refilling empties
        self.assertEqual(
            5,
            len(observations),
            msg="Observations do not match regimen count: %d != %d" %
            (5, len(observations)))
        art_nonart = set()
        for obs in observations:
            observed_dates.add(obs.observed_date)
            self.assertEquals(
                obs.day_note, "No check, from form"
            )  #magic string from the view to indicate a generated DOT observation from form data.
            art_nonart.add(obs.is_art)
            self.assertEquals(obs.doc_id, bundle['xform_id'])

        art = filter(lambda x: x.is_art, observations)
        self.assertEquals(2, len(art))
        art_answered = filter(lambda x: x.adherence != "unchecked", art)
        self.assertEquals(1, len(art_answered))

        nonart = filter(lambda x: not x.is_art, observations)
        self.assertEquals(3, len(nonart))
        nonart_answered = filter(lambda x: x.adherence != "unchecked", nonart)
        self.assertEquals(1, len(nonart_answered))

        #this only does SINGLE observations for art and non art
        self.assertEquals(len(observed_dates), 1)
        self.assertEquals(len(art_nonart), 2)
        # inspect the regenerated submission and ensure the built xml block is correctly filled.

        case_json = get_dots_case_json(PactPatientCase.get(CASE_ID),
                                       anchor_date=bundle['anchor_date'])
        enddate = bundle['anchor_date']  # anchor date of this submission
        #encounter_date = datetime.strptime(submitted.form['encounter_date'], '%Y-%m-%d')
        encounter_date = submitted.form['encounter_date']

        for day_delta in range(DOT_DAYS_INTERVAL):
            obs_date = enddate - timedelta(days=day_delta)
            ret_index = DOT_DAYS_INTERVAL - day_delta - 1

            day_arr = case_json['days'][ret_index]
            nonart_day_data = day_arr[0]
            art_day_data = day_arr[1]

            self.assertEquals(len(nonart_day_data), 3)
            self.assertEquals(len(art_day_data), 2)
예제 #47
0
    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']

        self.assertEqual(access_edits(key=self.ID).count(), 0)
        self.assertFalse(XFormInstance.get_db().doc_exist(self.ID))

        xml_data1, xml_data2 = self._get_files()

        submit_form_locally(xml_data1, self.domain)
        doc = XFormInstance.get(self.ID)
        self.assertEqual(self.ID, doc.get_id)
        self.assertEqual("XFormInstance", doc.doc_type)
        self.assertEqual(self.domain, doc.domain)

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

        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
        self.assertEqual(access_edits(key=self.ID).count(), 0)
        self.assertTrue(XFormInstance.get_db().doc_exist(self.ID))
        self.assertEqual(
            UnfinishedSubmissionStub.objects.filter(xform_id=self.ID,
                                                    saved=False).count(),
            1
        )
        self.assertEqual(
            UnfinishedSubmissionStub.objects.filter(xform_id=self.ID).count(),
            1
        )
예제 #48
0
def form_inline_display(form_id, timezone=pytz.utc):
    if form_id:
        try:
            form = XFormInstance.get(form_id)
            if form:
                return "%s: %s" % (tz_utils.adjust_datetime_to_timezone\
                                   (form.received_on, pytz.utc.zone, timezone.zone).date(),
                                   form.xmlns)
        except ResourceNotFound:
            pass
        return "%s: %s" % (_("missing form"), form_id)
    return _("empty form id found")
예제 #49
0
def spoof_submission(submit_url, body, name="form.xml", hqsubmission=True, headers={}):
    client = Client()
    f = StringIO(body.encode('utf-8'))
    f.name = name
    response = client.post(submit_url, {
        'xml_submission_file': f,
    }, **headers)
    if hqsubmission:
        xform_id = response['X-CommCareHQ-FormID']
        xform = XFormInstance.get(xform_id)
        xform['doc_type'] = "HQSubmission"
        xform.save()
    return response
예제 #50
0
파일: sms.py 프로젝트: ekush/commcare-hq
 def template_context(self):
     return {
         'xforms_session':
         self.xforms_session,
         'xform_instance':
         (XFormInstance.get(self.xforms_session.submission_id)
          if self.xforms_session.submission_id else None),
         'contact':
         get_doc_info_by_id(self.domain, self.xforms_session.connection_id),
         'start_time':
         (ServerTime(self.xforms_session.start_time).user_time(
             self.timezone).done().strftime(SERVER_DATETIME_FORMAT)),
     }
예제 #51
0
def reprocess_form_cases(form):
    """
    For a given form, reprocess all case elements inside it. This operation
    should be a no-op if the form was sucessfully processed, but should
    correctly inject the update into the case history if the form was NOT
    successfully processed.
    """
    _process_cases(form)
    # mark cleaned up now that we've reprocessed it
    if form.doc_type != 'XFormInstance':
        form = XFormInstance.get(form._id)
        form.doc_type = 'XFormInstance'
        form.save()
예제 #52
0
    def testSignal(self):
        """
        Test to ensure that with a DOT submission the signal works
        """
        start_dot = len(XFormInstance.view(
            'reports_forms/all_forms',
            startkey=['submission xmlns', self.domain.name, XMLNS_DOTS_FORM],
            endkey=['submission xmlns', self.domain.name, XMLNS_DOTS_FORM, {}],
            reduce=False
        ).all())
        start_update = len(XFormInstance.view(
            'reports_forms/all_forms',
            startkey=['submission xmlns', self.domain.name, XMLNS_PATIENT_UPDATE_DOT],
            endkey=['submission xmlns', self.domain.name, XMLNS_PATIENT_UPDATE_DOT, {}],
            reduce=False
        ).all())

        submit_xform(self.submit_url, self.domain.name, self.pillbox_form)
        submitted = XFormInstance.get(PILLBOX_ID)
        self.assertTrue(hasattr(submitted, PACT_DOTS_DATA_PROPERTY))

        dot_count = XFormInstance.view(
            'reports_forms/all_forms',
            startkey=['submission xmlns', self.domain.name, XMLNS_DOTS_FORM],
            endkey=['submission xmlns', self.domain.name, XMLNS_DOTS_FORM, {}],
        ).all()[0]['value']
        update_count = XFormInstance.view(
            'reports_forms/all_forms',
            startkey=['submission xmlns', self.domain.name, XMLNS_PATIENT_UPDATE_DOT],
            endkey=['submission xmlns', self.domain.name, XMLNS_PATIENT_UPDATE_DOT, {}],
        ).all()[0]['value']

        self.assertEquals(dot_count, update_count)
        self.assertEquals(start_dot+start_update + 2, dot_count + update_count)

        casedoc = CommCareCase.get(CASE_ID)
        self.assertEqual(casedoc.xform_ids[-2], PILLBOX_ID)
        computed_submit = XFormInstance.get(casedoc.xform_ids[-1])
        self.assertEqual(computed_submit.xmlns, XMLNS_PATIENT_UPDATE_DOT)
예제 #53
0
def handle_sms_form_complete(sender, session_id, form, **kwargs):
    from corehq.apps.smsforms.models import XFormsSession
    session = XFormsSession.by_session_id(session_id)
    if session:
        resp = submit_form_locally(form, session.domain, app_id=session.app_id)
        xform_id = resp['X-CommCareHQ-FormID']
        session.end(completed=True)
        session.submission_id = xform_id
        session.save()

        xform = XFormInstance.get(xform_id)
        xform.survey_incentive = session.survey_incentive
        xform.save()
예제 #54
0
    def test_non_swaps(self):
        # Test a form with multiple dups
        form_with_multi_dups_id = self._submit_form()._id
        self._submit_form(form_with_multi_dups_id)
        self._submit_form(form_with_multi_dups_id)
        # Test a form with no dups
        another_form_id = self._submit_form()._id

        with tempdir() as tmp:
            ids_file_path = os.path.join(tmp, 'ids')

            with open(ids_file_path, "w") as ids_file:
                for id_ in (form_with_multi_dups_id, another_form_id):
                    ids_file.write("{} {}\n".format(DOMAIN, id_))

            call_command('swap_duplicate_xforms', ids_file_path, '/dev/null', no_input=True)

            form_with_multi_dups = XFormInstance.get(form_with_multi_dups_id)
            self.assertEqual(form_with_multi_dups.doc_type, "XFormInstance")

            another_form = XFormInstance.get(another_form_id)
            self.assertEqual(another_form.doc_type, "XFormInstance")
예제 #55
0
 def testClosed(self):
     file_path = os.path.join(os.path.dirname(__file__), "data", "meta.xml")
     xml_data = open(file_path, "rb").read()
     doc_id, errors = post_authenticated_data(xml_data,
                                              settings.XFORMS_POST_URL,
                                              settings.COUCH_USERNAME,
                                              settings.COUCH_PASSWORD)
     xform = XFormInstance.get(doc_id)
     self.assertNotEqual(None, xform.metadata)
     self.assertEqual(date(2010, 07, 22), xform.metadata.timeStart.date())
     self.assertEqual(date(2010, 07, 23), xform.metadata.timeEnd.date())
     self.assertEqual("admin", xform.metadata.username)
     self.assertEqual("f7f0c79e-8b79-11df-b7de-005056c00008",
                      xform.metadata.userID)
예제 #56
0
def submit_unfinished_form(session_id, include_case_side_effects=False):
    session = XFormsSession.latest_by_session_id(session_id)
    if session is not None and session.end_time is None:
        # Get and clean the raw xml
        try:
            xml = get_raw_instance(session_id)
        except InvalidSessionIdException:
            session.end(completed=False)
            session.save()
            return
        root = XML(xml)
        case_tag_regex = re.compile(
            "^(\{.*\}){0,1}case$"
        )  # Use regex in order to search regardless of namespace
        meta_tag_regex = re.compile("^(\{.*\}){0,1}meta$")
        timeEnd_tag_regex = re.compile("^(\{.*\}){0,1}timeEnd$")
        current_timstamp = json_format_datetime(datetime.utcnow())
        for child in root:
            if case_tag_regex.match(child.tag) is not None:
                # Found the case tag
                case_element = child
                case_element.set("date_modified", current_timstamp)
                if not include_case_side_effects:
                    # Remove case actions (create, update, close)
                    child_elements = [
                        case_action for case_action in case_element
                    ]
                    for case_action in child_elements:
                        case_element.remove(case_action)
            elif meta_tag_regex.match(child.tag) is not None:
                # Found the meta tag, now set the value for timeEnd
                for meta_child in child:
                    if timeEnd_tag_regex.match(meta_child.tag):
                        meta_child.text = current_timstamp
        cleaned_xml = tostring(root)

        # Submit the xml and end the session
        resp = submit_form_locally(cleaned_xml,
                                   session.domain,
                                   app_id=session.app_id)
        xform_id = resp['X-CommCareHQ-FormID']
        session.end(completed=False)
        session.submission_id = xform_id
        session.save()

        # Tag the submission as a partial submission
        xform = XFormInstance.get(xform_id)
        xform.partial_submission = True
        xform.survey_incentive = session.survey_incentive
        xform.save()
예제 #57
0
    def testArchiveLastForm(self):
        initial_amounts = [(p._id, float(100)) for p in self.products]
        self.submit_xml_form(balance_submission(initial_amounts))

        final_amounts = [(p._id, float(50))
                         for i, p in enumerate(self.products)]
        second_form_id = self.submit_xml_form(
            balance_submission(final_amounts))

        def _assert_initial_state():
            self.assertEqual(
                1,
                StockReport.objects.filter(form_id=second_form_id).count())
            # 6 = 3 stockonhand and 3 inferred consumption txns
            self.assertEqual(
                6,
                StockTransaction.objects.filter(
                    report__form_id=second_form_id).count())
            self.assertEqual(
                3,
                StockState.objects.filter(case_id=self.sp._id).count())
            for state in StockState.objects.filter(case_id=self.sp._id):
                self.assertEqual(Decimal(50), state.stock_on_hand)
                self.assertIsNotNone(state.daily_consumption)

        # check initial setup
        _assert_initial_state()

        # archive and confirm commtrack data is deleted
        form = XFormInstance.get(second_form_id)
        form.archive()
        self.assertEqual(
            0,
            StockReport.objects.filter(form_id=second_form_id).count())
        self.assertEqual(
            0,
            StockTransaction.objects.filter(
                report__form_id=second_form_id).count())
        self.assertEqual(
            3,
            StockState.objects.filter(case_id=self.sp._id).count())
        for state in StockState.objects.filter(case_id=self.sp._id):
            # balance should be reverted to 100 in the StockState
            self.assertEqual(Decimal(100), state.stock_on_hand)
            # consumption should be none since there will only be 1 data point
            self.assertIsNone(state.daily_consumption)

        # unarchive and confirm commtrack data is restored
        form.unarchive()
        _assert_initial_state()
예제 #58
0
 def testComplicatedGatesBug(self):
     # found this bug in the wild, used the real (test) forms to fix it
     # just running through this test used to fail hard, even though there
     # are no asserts
     self.assertEqual(
         0, len(CommCareCase.view("case/by_user", reduce=False).all()))
     folder_path = os.path.join("bugs", "dependent_case_conflicts")
     files = ["reg1.xml", "reg2.xml", "cf.xml", "close.xml"]
     for f in files:
         form = self._postWithSyncToken(os.path.join(folder_path, f),
                                        self.sync_log.get_id)
         form = XFormInstance.get(form.get_id)
         self.assertFalse(hasattr(form, "problem"))
         self.sync_log = synclog_from_restore_payload(
             generate_restore_payload(self.user, version="2.0"))
예제 #59
0
 def testClosed(self):
     file_path = os.path.join(os.path.dirname(__file__), "data", "namespaces.xml")
     xml_data = open(file_path, "rb").read()
     with create_and_save_xform(xml_data) as doc_id:
         xform = XFormInstance.get(doc_id)
     self.assertEqual("http://commcarehq.org/test/ns", xform.xmlns)
     self.assertEqual("no namespace here", xform.xpath("form/empty"))
     self.assertEqual("http://commcarehq.org/test/flatns", xform.xpath("form/flat")["@xmlns"])
     self.assertEqual("http://commcarehq.org/test/parent", xform.xpath("form/parent")["@xmlns"])
     self.assertEqual("cwo", xform.xpath("form/parent/childwithout"))
     self.assertEqual("http://commcarehq.org/test/child1", xform.xpath("form/parent/childwith")["@xmlns"])
     self.assertEqual("http://commcarehq.org/test/child2", xform.xpath("form/parent/childwithelement")["@xmlns"])
     self.assertEqual("gc", xform.xpath("form/parent/childwithelement/grandchild"))
     self.assertEqual("lcwo", xform.xpath("form/parent/lastchildwithout"))
     self.assertEqual("nothing here either", xform.xpath("form/lastempty"))
예제 #60
0
    def swap_doc_types(self, log_file, bad_xform_id, duplicate_xform_id,
                       domain, dry_run):
        bad_xform = XFormInstance.get(bad_xform_id)

        # confirm that the doc hasn't already been fixed:
        bad_xform_problem = None
        try:
            bad_xform_problem = bad_xform.problem or ""
        except AttributeError:
            pass
        if bad_xform_problem:
            if re.match(PROBLEM_TEMPLATE_START, bad_xform_problem):
                self.log_already_fixed(log_file, bad_xform_id, domain)
                return

        duplicate_xform = XFormInstance.get(duplicate_xform_id)
        now = datetime.now().isoformat()

        # Convert the XFormInstance to an XFormDuplicate
        bad_xform.doc_type = XFormDuplicate.__name__
        bad_xform.problem = BAD_FORM_PROBLEM_TEMPLATE.format(
            duplicate_xform_id, now)
        bad_xform = XFormDuplicate.wrap(bad_xform.to_json())

        # Convert the XFormDuplicate to an XFormInstance
        duplicate_xform.problem = FIXED_FORM_PROBLEM_TEMPLATE.format(
            id_=bad_xform_id, datetime_=now)
        duplicate_xform.doc_type = XFormInstance.__name__
        duplicate_xform = XFormInstance.wrap(duplicate_xform.to_json())

        self.log_swap(log_file, bad_xform_id, domain, duplicate_xform_id,
                      dry_run)

        if not dry_run:
            duplicate_xform.save()
            bad_xform.save()