Example #1
0
    def _reset_case_state(self):
        """
        Clear known case properties, and all dynamic properties
        """
        self.case.case_json = {}
        self.case.deleted = False

        # hard-coded normal properties (from a create block)
        for prop, default_value in KNOWN_PROPERTIES.items():
            setattr(self.case, prop, default_value)

        self.case.closed = False
        self.case.modified_on = None
        self.case.closed_on = None
        self.case.closed_by = ''
        self.case.opened_by = None
Example #2
0
    def _reset_case_state(self):
        """
        Clear known case properties, and all dynamic properties
        """
        self.case.case_json = {}
        self.case.deleted = False

        # hard-coded normal properties (from a create block)
        for prop, default_value in KNOWN_PROPERTIES.items():
            setattr(self.case, prop, default_value)

        self.case.opened_on = None
        self.case.opened_by = ''
        self.case.modified_on = None
        self.case.modified_by = ''
        self.case.closed = False
        self.case.closed_on = None
        self.case.closed_by = ''
Example #3
0
    def reset_case_state(self):
        """
        Clear known case properties, and all dynamic properties
        """
        dynamic_properties = set([
            k for action in self.case.actions
            for k in action.updated_unknown_properties.keys()
        ])
        for k in dynamic_properties:
            try:
                delattr(self.case, k)
            except KeyError:
                pass
            except AttributeError:
                # 'case_id' is not a valid property so don't worry about spamming
                # this error.
                if k != 'case_id':
                    logging.error(
                        "Cannot delete attribute '%(attribute)s' from case '%(case_id)s'"
                        % {
                            'case_id': self.case.case_id,
                            'attribute': k,
                        })

        # Clear indices and attachments
        self.case.indices = []
        self.case.case_attachments = {}

        # already deleted means it was explicitly set to "deleted",
        # as opposed to getting set to that because it has no actions
        already_deleted = self.case.doc_type == 'CommCareCase-Deleted' and primary_actions(
            self.case)
        if not already_deleted:
            self.case.doc_type = 'CommCareCase'

        # hard-coded normal properties (from a create block)
        for prop, default_value in KNOWN_PROPERTIES.items():
            setattr(self.case, prop, default_value)

        self.case.closed = False
        self.case.modified_on = None
        self.case.closed_on = None
        self.case.closed_by = ''
        return self
Example #4
0
    def _reset_case_state(self):
        """
        Clear known case properties, and all dynamic properties
        Note: does not alter case indices or attachments. For indices this isn't an issue
        since we only allow creating indices at case creation (via the app builder) and also
        don't support optionally creating indices.
        """
        self.case.case_json = {}
        self.case.deleted = False

        # hard-coded normal properties (from a create block)
        for prop, default_value in KNOWN_PROPERTIES.items():
            setattr(self.case, prop, default_value)

        self.case.closed = False
        self.case.modified_on = None
        self.case.closed_on = None
        self.case.closed_by = ''
        self.case.opened_by = None
Example #5
0
    def reset_case_state(self):
        """
        Clear known case properties, and all dynamic properties
        """
        dynamic_properties = set([
            k for action in self.case.actions
            for k in action.updated_unknown_properties.keys()
        ])
        for k in dynamic_properties:
            try:
                delattr(self.case, k)
            except KeyError:
                pass
            except AttributeError:
                # 'case_id' is not a valid property so don't worry about spamming
                # this error.
                if k != 'case_id':
                    logging.error(
                        "Cannot delete attribute '%(attribute)s' from case '%(case_id)s'" % {
                            'case_id': self.case.case_id,
                            'attribute': k,
                        }
                    )

        # Clear indices and attachments
        self.case.indices = []
        self.case.case_attachments = {}

        # already deleted means it was explicitly set to "deleted",
        # as opposed to getting set to that because it has no actions
        already_deleted = self.case.doc_type == 'CommCareCase-Deleted' and primary_actions(self.case)
        if not already_deleted:
            self.case.doc_type = 'CommCareCase'

        # hard-coded normal properties (from a create block)
        for prop, default_value in KNOWN_PROPERTIES.items():
            setattr(self.case, prop, default_value)

        self.case.closed = False
        self.case.modified_on = None
        self.case.closed_on = None
        self.case.closed_by = ''
        return self
Example #6
0
            ProcessedForms(form, []),
            [case],
            # disable publish to Kafka to avoid intermittent errors caused by
            # the nexus of kafka's consumer thread and freeze_time
            publish_to_kafka=False,
        )

    def _check_for_reconciliation_error_soft_assert(self, soft_assert_mock):
        for call in soft_assert_mock.call_args_list:
            self.assertNotIn('ReconciliationError', call[0][1])
        soft_assert_mock.reset_mock()


def test_update_known_properties_with_empty_values():
    def test(prop):
        case = SqlCaseUpdateStrategy.case_implementation_class()
        setattr(case, prop, "value")
        action = CaseUpdateAction(block=None, **{prop: ""})

        SqlCaseUpdateStrategy(case)._update_known_properties(action)

        eq(getattr(case, prop), "")

    # verify that at least one property will be tested
    assert any(v is not None
               for v in KNOWN_PROPERTIES.values()), KNOWN_PROPERTIES

    for prop, default in KNOWN_PROPERTIES.items():
        if default is not None:
            yield test, prop
Example #7
0
                logging.error(
                    "Cannot delete attribute '%(attribute)s' from case '%(case_id)s'"
                    % {
                        'case_id': case._id,
                        'attribute': k,
                    })

    # already deleted means it was explicitly set to "deleted",
    # as opposed to getting set to that because it has no actions
    already_deleted = case.doc_type == 'CommCareCase-Deleted' and primary_actions(
        case)
    if not already_deleted:
        case.doc_type = 'CommCareCase'

    # hard-coded normal properties (from a create block)
    for prop, default_value in KNOWN_PROPERTIES.items():
        setattr(case, prop, default_value)

    case.closed = False
    case.modified_on = None
    case.closed_on = None
    case.closed_by = ''
    return case


def safe_hard_delete(case):
    """
    Hard delete a case - by deleting the case itself as well as all forms associated with it
    permanently from the database.

    Will fail hard if the case has any reverse indices or if any of the forms associated with
Example #8
0
            if has_illegal_props(self.diffs):
                raise CannotPatch([d.json_diff for d in self.diffs])
            props = dict(iter_dynamic_properties(self.diffs))
            self._dynamic_properties = props
            if props or has_known_props(self.diffs):
                updates.append(const.CASE_ACTION_UPDATE)

    def __getattr__(self, name):
        return getattr(self.case, name)

    def dynamic_case_properties(self):
        return self._dynamic_properties


ILLEGAL_PROPS = {"indices", "actions", "*"}
IGNORE_PROPS = {"xform_ids"} | KNOWN_PROPERTIES.keys()


def has_illegal_props(diffs):
    return any(d.json_diff.path[0] in ILLEGAL_PROPS for d in diffs)


def has_known_props(diffs):
    return any(d.json_diff.path[0] in KNOWN_PROPERTIES for d in diffs)


def iter_dynamic_properties(diffs):
    for doc_diff in diffs:
        diff = doc_diff.json_diff
        name = diff.path[0]
        if name in IGNORE_PROPS: