Пример #1
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)
Пример #2
0
 def test_form_extras(self):
     domain = uuid.uuid4().hex
     LOOSE_SYNC_TOKEN_VALIDATION.set(domain, True, namespace='domain')
     token_id = uuid.uuid4().hex
     factory = CaseFactory(domain=domain)
     [case] = factory.create_or_update_case(CaseStructure(), form_extras={'last_sync_token': token_id})
     form = FormProcessorInterface(domain).xform_model.get(case.xform_ids[0])
     self.assertEqual(token_id, form.last_sync_token)
Пример #3
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 = FormAccessors(domain).get_form(case.xform_ids[0])
     self.assertEqual("differenttoken", form.last_sync_token)
Пример #4
0
 def test_form_extras(self):
     domain = uuid.uuid4().hex
     LOOSE_SYNC_TOKEN_VALIDATION.set(domain, True, namespace='domain')
     token_id = uuid.uuid4().hex
     factory = CaseFactory(domain=domain)
     [case] = factory.create_or_update_case(
         CaseStructure(), form_extras={'last_sync_token': token_id})
     form = FormAccessors(domain).get_form(case.xform_ids[0])
     self.assertEqual(token_id, form.last_sync_token)
Пример #5
0
 def test_form_extras_default(self):
     domain = uuid.uuid4().hex
     # have to enable loose sync token validation for the domain or create actual SyncLog documents.
     # this is the easier path.
     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_case()
     form = XFormInstance.get(case.xform_ids[0])
     self.assertEqual(token_id, form.last_sync_token)
Пример #6
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)
Пример #7
0
 def test_form_extras_default(self):
     domain = uuid.uuid4().hex
     # have to enable loose sync token validation for the domain or create actual SyncLog documents.
     # this is the easier path.
     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_case()
     form = FormAccessors(domain).get_form(case.xform_ids[0])
     self.assertEqual(token_id, form.last_sync_token)
Пример #8
0
def process_cases_with_casedb(xforms, case_db, config=None):
    config = config or CaseProcessingConfig()
    case_processing_result = _get_or_update_cases(xforms, case_db)
    cases = case_processing_result.cases
    xform = xforms[0]

    # attach domain and export tag
    domain = xform.domain

    def attach_extras(case):
        case.domain = domain
        if domain:
            assert hasattr(case, 'type')
            case['#export_tag'] = ["domain", "type"]
        return case

    cases = [attach_extras(case) for case in cases]

    # handle updating the sync records for apps that use sync mode
    try:
        relevant_log = xform.get_sync_token()
    except ResourceNotFound:
        if LOOSE_SYNC_TOKEN_VALIDATION.enabled(xform.domain):
            relevant_log = None
        else:
            raise

    if relevant_log:
        # in reconciliation mode, things can be unexpected
        relevant_log.strict = config.strict_asserts
        from casexml.apps.case.util import update_sync_log_with_checks
        update_sync_log_with_checks(relevant_log, xform, cases, case_db,
                                    case_id_blacklist=config.case_id_blacklist)

    try:
        cases_received.send(sender=None, xform=xform, cases=cases)
    except Exception as e:
        # don't let the exceptions in signals prevent standard case processing
        notify_exception(
            None,
            'something went wrong sending the cases_received signal '
            'for form %s: %s' % (xform._id, e)
        )

    for case in cases:
        ActionsUpdateStrategy(case).reconcile_actions_if_necessary(xform)
        case_db.mark_changed(case)

        action_xforms = {action.xform_id for action in case.actions if action.xform_id}
        mismatched_forms = action_xforms ^ set(case.xform_ids)
        if mismatched_forms:
            logging.warning(
                "CASE XFORM MISMATCH /a/{},{}".format(
                    domain,
                    case.case_id
                )
            )

    case_processing_result.set_cases(cases)
    return case_processing_result
Пример #9
0
    def test_submission_with_bad_log_toggle_enabled(self):
        domain = 'submission-domain-with-toggle'

        def _test():
            post_case_blocks(
                [CaseBlock(create=True, case_id='bad-log-toggle-enabled', version=V2).as_xml()],
                form_extras={"last_sync_token": 'not-a-valid-synclog-id'},
                domain=domain,
            )

        LOOSE_SYNC_TOKEN_VALIDATION.set(domain, False, namespace='domain')
        with self.assertRaises(ResourceNotFound):
            _test()

        LOOSE_SYNC_TOKEN_VALIDATION.set(domain, True, namespace='domain')
        # this is just asserting that an exception is not raised after the toggle is set
        _test()
Пример #10
0
def process_cases_with_casedb(xform, case_db, config=None):
    config = config or CaseProcessingConfig()
    cases = get_or_update_cases(xform, case_db).values()

    if config.reconcile:
        for c in cases:
            c.reconcile_actions(rebuild=True)

    # attach domain and export tag
    domain = xform.domain

    def attach_extras(case):
        case.domain = domain
        if domain:
            assert hasattr(case, 'type')
            case['#export_tag'] = ["domain", "type"]
        return case

    cases = [attach_extras(case) for case in cases]

    # handle updating the sync records for apps that use sync mode
    try:
        relevant_log = xform.get_sync_token()
    except ResourceNotFound:
        if LOOSE_SYNC_TOKEN_VALIDATION.enabled(xform.domain):
            relevant_log = None
        else:
            raise

    if relevant_log:
        # in reconciliation mode, things can be unexpected
        relevant_log.strict = config.strict_asserts
        from casexml.apps.case.util import update_sync_log_with_checks
        update_sync_log_with_checks(relevant_log, xform, cases, case_db,
                                    case_id_blacklist=config.case_id_blacklist)

        if config.reconcile and relevant_log.reconcile_cases():
            relevant_log.save()

    try:
        cases_received.send(sender=None, xform=xform, cases=cases)
    except Exception as e:
        # don't let the exceptions in signals prevent standard case processing
        notify_exception(
            None,
            'something went wrong sending the cases_received signal '
            'for form %s: %s' % (xform._id, e)
        )

    for case in cases:
        if not case.check_action_order():
            try:
                case.reconcile_actions(rebuild=True, xforms={xform._id: xform})
            except ReconciliationError:
                pass
        case_db.mark_changed(case)

    return cases
Пример #11
0
    def test_restore_with_bad_log_toggle_enabled(self):
        domain = 'restore-domain-with-toggle'

        def _test():
            RestoreConfig(
                self.user, version=V2,
                restore_id='not-a-valid-synclog-id',
                domain=Domain(name=domain),
            ).get_payload()

        LOOSE_SYNC_TOKEN_VALIDATION.set(domain, False, namespace='domain')
        with self.assertRaises(ResourceNotFound):
            _test()

        LOOSE_SYNC_TOKEN_VALIDATION.set(domain, True, namespace='domain')
        # when the toggle is set the exception should be an HttpException instead
        with self.assertRaises(HttpException):
            _test()
Пример #12
0
 def validate(self):
     try:
         self.restore_state.validate_state()
     except InvalidSyncLogException, e:
         if LOOSE_SYNC_TOKEN_VALIDATION.enabled(self.domain):
             # This exception will get caught by the view and a 412 will be returned to the phone for resync
             raise RestoreException(e)
         else:
             # This exception will fail hard and we'll get a 500 error message
             raise
Пример #13
0
 def validate(self):
     try:
         self.restore_state.validate_state()
     except InvalidSyncLogException, e:
         if LOOSE_SYNC_TOKEN_VALIDATION.enabled(self.domain):
             # This exception will get caught by the view and a 412 will be returned to the phone for resync
             raise RestoreException(e)
         else:
             # This exception will fail hard and we'll get a 500 error message
             raise
Пример #14
0
def _update_sync_logs(xform, case_db, config, cases):
    # handle updating the sync records for apps that use sync mode
    try:
        relevant_log = xform.get_sync_token()
    except ResourceNotFound:
        if LOOSE_SYNC_TOKEN_VALIDATION.enabled(xform.domain):
            relevant_log = None
        else:
            raise

    if relevant_log:
        # in reconciliation mode, things can be unexpected
        relevant_log.strict = config.strict_asserts
        from casexml.apps.case.util import update_sync_log_with_checks
        update_sync_log_with_checks(relevant_log, xform, cases, case_db,
                                    case_id_blacklist=config.case_id_blacklist)
Пример #15
0
def _update_sync_logs(xform, case_db, config, cases):
    # handle updating the sync records for apps that use sync mode
    try:
        relevant_log = xform.get_sync_token()
    except ResourceNotFound:
        if LOOSE_SYNC_TOKEN_VALIDATION.enabled(xform.domain):
            relevant_log = None
        else:
            raise

    if relevant_log:
        # in reconciliation mode, things can be unexpected
        relevant_log.strict = config.strict_asserts
        from casexml.apps.case.util import update_sync_log_with_checks
        update_sync_log_with_checks(relevant_log, xform, cases, case_db,
                                    case_id_blacklist=config.case_id_blacklist)
Пример #16
0
    def sync_log(self):
        if self.restore_id:
            try:
                sync_log = SyncLog.get(self.restore_id)
            except ResourceNotFound:
                # if we are in loose mode, return an HTTP 412 so that the phone will
                # just force a fresh sync
                if LOOSE_SYNC_TOKEN_VALIDATION.enabled(self.domain):
                    raise HttpException(412)
                else:
                    raise

            if sync_log.user_id == self.user.user_id \
                    and sync_log.doc_type == 'SyncLog':
                return sync_log
            else:
                raise HttpException(412)
        else:
            return None
Пример #17
0
def process_cases_with_casedb(xforms, case_db, config=None):
    config = config or CaseProcessingConfig()
    case_processing_result = _get_or_update_cases(xforms, case_db)
    cases = case_processing_result.cases
    xform = xforms[0]

    # handle updating the sync records for apps that use sync mode
    try:
        relevant_log = xform.get_sync_token()
    except ResourceNotFound:
        if LOOSE_SYNC_TOKEN_VALIDATION.enabled(xform.domain):
            relevant_log = None
        else:
            raise

    if relevant_log:
        # in reconciliation mode, things can be unexpected
        relevant_log.strict = config.strict_asserts
        from casexml.apps.case.util import update_sync_log_with_checks
        update_sync_log_with_checks(relevant_log, xform, cases, case_db,
                                    case_id_blacklist=config.case_id_blacklist)

    try:
        cases_received.send(sender=None, xform=xform, cases=cases)
    except Exception as e:
        # don't let the exceptions in signals prevent standard case processing
        notify_exception(
            None,
            'something went wrong sending the cases_received signal '
            'for form %s: %s' % (xform.form_id, e)
        )

    for case in cases:
        case_db.post_process_case(case, xform)
        case_db.mark_changed(case)

    case_processing_result.set_cases(cases)
    return case_processing_result
Пример #18
0
    domain = xform.domain

    def attach_extras(case):
        case.domain = domain
        if domain:
            assert hasattr(case, 'type')
            case['#export_tag'] = ["domain", "type"]
        return case

    cases = [attach_extras(case) for case in cases]

    # handle updating the sync records for apps that use sync mode
    try:
        relevant_log = xform.get_sync_token()
    except ResourceNotFound:
        if LOOSE_SYNC_TOKEN_VALIDATION.enabled(xform.domain):
            relevant_log = None
        else:
            raise

    if relevant_log:
        # in reconciliation mode, things can be unexpected
        relevant_log.strict = config.strict_asserts
        from casexml.apps.case.util import update_sync_log_with_checks
        update_sync_log_with_checks(relevant_log,
                                    xform,
                                    cases,
                                    case_db,
                                    case_id_blacklist=config.case_id_blacklist)

    try: