def handle(self, *args, **options): if len(args) == 1: id = args[0] else: raise CommandError("Usage: %s\n%s" % (self.args, self.help)) reprocess_form_cases(XFormError.get(id))
def setUpClass(cls): from casexml.apps.case.tests.util import delete_all_xforms delete_all_xforms() cls.domain = 'evelyn' cls.now = datetime.datetime.utcnow() cls.user_id1 = 'xzy' cls.user_id2 = 'abc' metadata1 = TestFormMetadata( domain=cls.domain, user_id=cls.user_id1, received_on=cls.now - datetime.timedelta(days=10), ) metadata2 = TestFormMetadata( domain=cls.domain, user_id=cls.user_id2, received_on=cls.now, ) xform1 = get_simple_wrapped_form('123', metadata=metadata1) xform2 = get_simple_wrapped_form('456', metadata=metadata2) xform_error = get_simple_wrapped_form('789', metadata=metadata2) xform_error = XFormError.wrap(xform_error.to_json()) xform_error.save() cls.xform_deleted = get_simple_wrapped_form('101', metadata=metadata2) cls.xform_deleted.doc_type += '-Deleted' cls.xform_deleted.save() cls.xforms = [ xform1, xform2, ] cls.xform_errors = [xform_error]
def get_by_doc_type(domain, doc_type): return XFormError.view( 'domain/docs', startkey=[domain, doc_type], endkey=[domain, doc_type, {}], reduce=False, include_docs=True, ).all()
def get(self, count): # this is a hack, but override the doc type because there is an # equivalent doc type in the view def _update_doc_type(form): form.doc_type = self.doc_type return form return [_update_doc_type(form) for form in \ XFormError.view("couchforms/all_submissions_by_domain", include_docs=True, limit=count, **self._kwargs)]
def get_problem_ids(domain, since=None): startkey = [domain, "by_type", "XFormError"] endkey = startkey + [{}] if since: startkey.append(since.isoformat()) return [row['id'] for row in XFormError.get_db().view( "receiverwrapper/all_submissions_by_domain", startkey=startkey, endkey=endkey, reduce=False )]
def post_xform_to_couch(instance, attachments={}): """ Post an xform to couchdb, based on the settings.XFORMS_POST_URL. Returns the newly created document from couchdb, or raises an exception if anything goes wrong. attachments is a dictionary of the request.FILES that are not the xform. Key is the parameter name, and the value is the django MemoryFile object stream. """ def _has_errors(response, errors): return errors or "error" in response # check settings for authentication credentials try: response, errors = post_from_settings(instance) if not _has_errors(response, errors): doc_id = response try: xform = XFormInstance.get(doc_id) #put attachments onto the saved xform instance for key, val in attachments.items(): res = xform.put_attachment(val, name=key, content_type=val.content_type, content_length=val.size) # fire signals # We don't trap any exceptions here. This is by design. # If something fails (e.g. case processing), we quarantine the # form into an error location. xform_saved.send(sender="couchforms", xform=xform) return xform except Exception, e: logging.error("Problem with form %s" % doc_id) logging.exception(e) # "rollback" by changing the doc_type to XFormError try: bad = XFormError.get(doc_id) bad.problem = "%s" % e bad.save() return bad except ResourceNotFound: pass # no biggie, the failure must have been in getting it back raise else:
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 = XFormError.view( 'domain/docs', startkey=['my_very_special_domain', 'XFormError'], endkey=['my_very_special_domain', 'XFormError', {}], reduce=False, include_docs=True, ).all() related_errors = [xform_error for xform_error in xform_errors if xform_error.get_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')
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 = XFormError.view( 'domain/docs', startkey=['my_very_special_domain', 'XFormError'], endkey=['my_very_special_domain', 'XFormError', {}], reduce=False, include_docs=True, ).all() related_errors = [xform_error for xform_error in xform_errors if xform_error.get_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!')
def xformerror_from_xform_instance(self, instance, error_message, with_new_id=False): return XFormError.from_xform_instance(instance, error_message, with_new_id=with_new_id)
def iter_problem_forms(domain, since=None): for doc in iter_docs(XFormError.get_db(), get_problem_ids(domain, since)): yield XFormError.wrap(doc)
def total_records(self): return XFormError.view("couchforms/all_submissions_by_domain", startkey=[self.domain, "by_type"], endkey=[self.domain, "by_type", {}], reduce=False).count()
def get_total(self): return XFormError.view("couchforms/all_submissions_by_domain", **self._kwargs).count()
def iter_problem_forms(domain, since=None): problem_ids = get_form_ids_by_type(domain, 'XFormError', start=since) for doc in iter_docs(XFormError.get_db(), problem_ids): yield XFormError.wrap(doc)
def get_total(self): return XFormError.view("receiverwrapper/all_submissions_by_domain", **self._kwargs).count()