def test_hard_delete_case(self):
        case1 = _create_case()
        case2 = _create_case(domain='other_domain')
        self.addCleanup(lambda: CaseAccessorSQL.hard_delete_cases('other_domain', [case2.case_id]))

        case1.track_create(CommCareCaseIndexSQL(
            case=case1,
            identifier='parent',
            referenced_type='mother',
            referenced_id=uuid.uuid4().hex,
            relationship_id=CommCareCaseIndexSQL.CHILD
        ))
        case1.track_create(CaseAttachmentSQL(
            case=case1,
            attachment_id=uuid.uuid4().hex,
            name='pic.jpg',
            content_type='image/jpeg',
            blob_id='122',
            md5='123',
            identifier='pic.jpg',
        ))
        CaseAccessorSQL.save_case(case1)

        num_deleted = CaseAccessorSQL.hard_delete_cases(DOMAIN, [case1.case_id, case2.case_id])
        self.assertEqual(1, num_deleted)
        with self.assertRaises(CaseNotFound):
            CaseAccessorSQL.get_case(case1.case_id)

        self.assertEqual([], CaseAccessorSQL.get_indices(case1.domain, case1.case_id))
        self.assertEqual([], CaseAccessorSQL.get_attachments(case1.case_id))
        self.assertEqual([], CaseAccessorSQL.get_transactions(case1.case_id))
    def test_reconcile_transactions_within_fudge_factor(self, soft_assert_mock):
        """ tests a transanction with an early client date and late server date """
        with freeze_time("2018-10-10"):
            case = self._create_case()

        with freeze_time("2018-10-11 06:00"):
            new_old_xform = self._create_form()
        with freeze_time("2018-10-10 18:00"):
            new_old_trans = self._create_case_transaction(case, new_old_xform)
        with freeze_time("2018-10-11 06:00"):
            case.track_create(new_old_trans)
            FormProcessorSQL.save_processed_models(ProcessedForms(new_old_xform, []), [case])

        with freeze_time("2018-10-11"):
            new_old_xform = self._create_form()
            new_old_trans = self._create_case_transaction(case, new_old_xform)
            case.track_create(new_old_trans)
            FormProcessorSQL.save_processed_models(ProcessedForms(new_old_xform, []), [case])

        case = CaseAccessorSQL.get_case(case.case_id)
        update_strategy = SqlCaseUpdateStrategy(case)
        self.assertTrue(update_strategy.reconcile_transactions_if_necessary())
        self._check_for_reconciliation_error_soft_assert(soft_assert_mock)

        CaseAccessorSQL.save_case(case)

        case = CaseAccessorSQL.get_case(case.case_id)
        update_strategy = SqlCaseUpdateStrategy(case)
        self.assertFalse(update_strategy.reconcile_transactions_if_necessary())
        self._check_for_reconciliation_error_soft_assert(soft_assert_mock)
Exemplo n.º 3
0
 def _get_case(self, case_id):
     try:
         if self.lock:
             try:
                 case, lock = CommCareCaseSQL.get_locked_obj(_id=case_id)
             except redis.RedisError:
                 case = CaseAccessorSQL.get_case(case_id)
Exemplo n.º 4
0
 def get_case_with_lock(case_id, lock=False, wrap=False):
     try:
         if lock:
             try:
                 return CommCareCaseSQL.get_locked_obj(_id=case_id)
             except redis.RedisError:
                 case = CaseAccessorSQL.get_case(case_id)
         else:
Exemplo n.º 5
0
def _hard_delete_data(args_json):
    def discard_case_diffs(statedb):
        statedb.add_diffed_cases([case_id])
        statedb.replace_case_diffs([("CommCareCase", case_id, [])])
        statedb.replace_case_changes([("CommCareCase", case_id, [])])
        return []

    # TODO remove form and case diffs, if any, for hard-deleted items
    case_id, form_ids = args_json
    try:
        case = CaseAccessorSQL.get_case(case_id)
Exemplo n.º 6
0
    def test_reprocess_unfinished_submission_ledger_create(self):
        from corehq.apps.commtrack.tests.util import get_single_balance_block
        case_id = uuid.uuid4().hex
        self.factory.create_or_update_cases([
            CaseStructure(case_id=case_id,
                          attrs={
                              'case_type': 'parent',
                              'create': True
                          })
        ])

        transaction_patch = patch(
            'corehq.form_processor.backends.sql.processor.transaction')
        ledger_save_patch = patch(
            'corehq.form_processor.backends.sql.dbaccessors.LedgerAccessorSQL.save_ledger_values',
            side_effect=InternalError)
        with transaction_patch, ledger_save_patch, self.assertRaises(
                InternalError):
            submit_case_blocks(
                get_single_balance_block(case_id, 'product1', 100),
                self.domain)

        stubs = UnfinishedSubmissionStub.objects.filter(domain=self.domain,
                                                        saved=False).all()
        self.assertEqual(1, len(stubs))

        ledgers = LedgerAccessorSQL.get_ledger_values_for_case(case_id)
        self.assertEqual(0, len(ledgers))

        # case transaction got saved
        case = CaseAccessorSQL.get_case(case_id)
        self.assertEqual(2, len(case.transactions))
        self.assertTrue(case.transactions[0].is_case_create)
        self.assertTrue(case.transactions[1].is_ledger_transaction)

        ledger_transactions = LedgerAccessorSQL.get_ledger_transactions_for_case(
            case_id)
        self.assertEqual(0, len(ledger_transactions))

        result = reprocess_unfinished_stub(stubs[0])
        self.assertEqual(0, len(result.cases))
        self.assertEqual(1, len(result.ledgers))

        ledgers = LedgerAccessorSQL.get_ledger_values_for_case(case_id)
        self.assertEqual(1, len(ledgers))

        ledger_transactions = LedgerAccessorSQL.get_ledger_transactions_for_case(
            case_id)
        self.assertEqual(1, len(ledger_transactions))

        # case still only has 2 transactions
        case = CaseAccessorSQL.get_case(case_id)
        self.assertEqual(2, len(case.transactions))
Exemplo n.º 7
0
    def get_case_with_lock(case_id, lock=False, strip_history=False, wrap=False):
        try:
            if lock:
                try:
                    return CommCareCaseSQL.get_locked_obj(_id=case_id)
                except redis.RedisError:
                    case = CaseAccessorSQL.get_case(case_id)
            else:
                case = CaseAccessorSQL.get_case(case_id)
        except CaseNotFound:
            return None, None

        return case, None
Exemplo n.º 8
0
    def test_reprocess_unfinished_submission_case_update(self):
        case_id = uuid.uuid4().hex
        form_ids = []
        form_ids.append(
            submit_case_blocks(
                CaseBlock(case_id=case_id, create=True,
                          case_type='box').as_string(),
                self.domain)[0].form_id)

        transaction_patch = patch(
            'corehq.form_processor.backends.sql.processor.transaction')
        case_save_patch = patch(
            'corehq.form_processor.backends.sql.dbaccessors.CaseAccessorSQL.save_case',
            side_effect=InternalError)
        with transaction_patch, case_save_patch, self.assertRaises(
                InternalError):
            submit_case_blocks(
                CaseBlock(case_id=case_id, update={
                    'prop': 'a'
                }).as_string(), self.domain)

        stubs = UnfinishedSubmissionStub.objects.filter(domain=self.domain,
                                                        saved=False).all()
        self.assertEqual(1, len(stubs))

        form_ids.append(stubs[0].xform_id)

        # submit second form with case update
        form_ids.append(
            submit_case_blocks(
                CaseBlock(case_id=case_id, update={
                    'prop': 'b'
                }).as_string(), self.domain)[0].form_id)

        case = CaseAccessorSQL.get_case(case_id)
        self.assertEqual(2, len(case.transactions))
        self.assertEqual('b', case.get_case_property('prop'))

        result = reprocess_unfinished_stub(stubs[0])
        self.assertEqual(1, len(result.cases))
        self.assertEqual(0, len(result.ledgers))

        case = CaseAccessorSQL.get_case(case_id)
        self.assertEqual('b', case.get_case_property(
            'prop'))  # should be property value from most recent form
        self.assertEqual(4, len(case.transactions))
        self.assertEqual(form_ids + [None],
                         [trans.form_id for trans in case.transactions])

        with self.assertRaises(UnfinishedSubmissionStub.DoesNotExist):
            UnfinishedSubmissionStub.objects.get(pk=stubs[0].pk)
Exemplo n.º 9
0
    def _get_case(self, case_id):
        try:
            if self.lock:
                try:
                    case, lock = CommCareCaseSQL.get_locked_obj(_id=case_id)
                except redis.RedisError:
                    case = CaseAccessorSQL.get_case(case_id)
                else:
                    self.locks.append(lock)
            else:
                case = CaseAccessorSQL.get_case(case_id)
        except CaseNotFound:
            return None

        return case
Exemplo n.º 10
0
 def test_get_case_by_id(self):
     case = _create_case()
     with self.assertNumQueries(1, using=db_for_read_write(CommCareCaseSQL)):
         case = CaseAccessorSQL.get_case(case.case_id)
     self.assertIsNotNone(case)
     self.assertIsInstance(case, CommCareCaseSQL)
     self.assertEqual(DOMAIN, case.domain)
     self.assertEqual('user1', case.owner_id)
Exemplo n.º 11
0
    def referenced_case(self):
        """
        For a 'forward' index this is the case that the the index points to.
        For a 'reverse' index this is the case that owns the index.
        See ``CaseAccessorSQL.get_reverse_indices``

        :return: referenced case
        """
        from corehq.form_processor.backends.sql.dbaccessors import CaseAccessorSQL
        return CaseAccessorSQL.get_case(self.referenced_id)
Exemplo n.º 12
0
    def referenced_case(self):
        """
        For a 'forward' index this is the case that the the index points to.
        For a 'reverse' index this is the case that owns the index.
        See ``CaseAccessorSQL.get_reverse_indices``

        :return: referenced case
        """
        from corehq.form_processor.backends.sql.dbaccessors import CaseAccessorSQL
        return CaseAccessorSQL.get_case(self.referenced_id)
Exemplo n.º 13
0
    def get_case(self, case_id):
        try:
            return CaseAccessorSQL.get_case(case_id)
        except CaseNotFound:
            pass

        try:
            return CaseAccessorCouch.get_case(case_id)
        except ResourceNotFound:
            pass

        return None
Exemplo n.º 14
0
    def get_case(self, case_id):
        try:
            return CaseAccessorSQL.get_case(case_id)
        except CaseNotFound:
            pass

        try:
            return CaseAccessorCouch.get_case(case_id)
        except ResourceNotFound:
            pass

        return None
Exemplo n.º 15
0
    def test_reconcile_not_necessary(self):
        with freeze_time("2018-10-10"):
            case = self._create_case()

        with freeze_time("2018-10-11"):
            new_old_xform = self._create_form()
            new_old_trans = self._create_case_transaction(case, new_old_xform)
            case.track_create(new_old_trans)
            FormProcessorSQL.save_processed_models(ProcessedForms(new_old_xform, []), [case])

        case = CaseAccessorSQL.get_case(case.case_id)
        update_strategy = SqlCaseUpdateStrategy(case)
        self.assertFalse(update_strategy.reconcile_transactions_if_necessary())
Exemplo n.º 16
0
    def hard_rebuild_case(domain, case_id, detail):
        try:
            case = CaseAccessorSQL.get_case(case_id)
            assert case.domain == domain
            found = True
        except CaseNotFound:
            case = CommCareCaseSQL(case_id=case_id, domain=domain)
            found = False

        case = FormProcessorSQL._rebuild_case_from_transactions(case, detail)
        if case.is_deleted and not found:
            return None
        CaseAccessorSQL.save_case(case)
Exemplo n.º 17
0
    def test_first_transaction_not_create(self):
        with freeze_time("2018-10-10"):
            case = self._create_case()

        with freeze_time("2018-10-08"):
            new_old_xform = self._create_form()
            new_old_trans = self._create_case_transaction(case, new_old_xform)
            case.track_create(new_old_trans)
            FormProcessorSQL.save_processed_models(ProcessedForms(new_old_xform, []), [case])

        self.assertTrue(case.check_transaction_order())

        case = CaseAccessorSQL.get_case(case.case_id)
        update_strategy = SqlCaseUpdateStrategy(case)
        self.assertRaises(ReconciliationError, update_strategy.reconcile_transactions)
Exemplo n.º 18
0
    def _create_case(self, case_type=None, user_id=None, case_id=None):
        case_id = case_id or uuid.uuid4().hex
        user_id = user_id or 'mr_wednesday'
        utcnow = datetime.utcnow()

        case = CommCareCaseSQL(
            case_id=case_id,
            domain=self.DOMAIN,
            type=case_type or '',
            owner_id=user_id,
            opened_on=utcnow,
            modified_on=utcnow,
            modified_by=utcnow,
            server_modified_on=utcnow
        )

        form = self._create_form(user_id, utcnow)
        case.track_create(self._create_case_transaction(case, form, utcnow, action_types=[128]))
        FormProcessorSQL.save_processed_models(ProcessedForms(form, []), [case])

        return CaseAccessorSQL.get_case(case_id)
Exemplo n.º 19
0
    def _create_case(self, case_type=None, user_id=None, case_id=None):
        case_id = case_id or uuid.uuid4().hex
        user_id = user_id or 'mr_wednesday'
        utcnow = datetime.utcnow()

        case = CommCareCaseSQL(case_id=case_id,
                               domain=self.DOMAIN,
                               type=case_type or '',
                               owner_id=user_id,
                               opened_on=utcnow,
                               modified_on=utcnow,
                               modified_by=utcnow,
                               server_modified_on=utcnow)

        form = self._create_form(user_id, utcnow)
        trans = self._create_case_transaction(case,
                                              form,
                                              utcnow,
                                              action_types=[128])
        self._save(form, case, trans)

        return CaseAccessorSQL.get_case(case_id)
Exemplo n.º 20
0
def _create_case(domain=None, form_id=None, case_type=None, user_id=None, closed=False):
    """
    Create the models directly so that these tests aren't dependent on any
    other apps. Not testing form processing here anyway.
    :return: case_id
    """
    domain = domain or DOMAIN
    form_id = form_id or uuid.uuid4().hex
    case_id = uuid.uuid4().hex
    user_id = user_id or 'user1'
    utcnow = datetime.utcnow()

    form = XFormInstanceSQL(
        form_id=form_id,
        xmlns='http://openrosa.org/formdesigner/form-processor',
        received_on=utcnow,
        user_id=user_id,
        domain=domain
    )

    cases = []
    if case_id:
        case = CommCareCaseSQL(
            case_id=case_id,
            domain=domain,
            type=case_type or '',
            owner_id=user_id,
            opened_on=utcnow,
            modified_on=utcnow,
            modified_by=user_id,
            server_modified_on=utcnow,
            closed=closed or False
        )
        case.track_create(CaseTransaction.form_transaction(case, form))
        cases = [case]

    FormProcessorSQL.save_processed_models(ProcessedForms(form, None), cases)
    return CaseAccessorSQL.get_case(case_id)
Exemplo n.º 21
0
def _create_case(domain=None,
                 form_id=None,
                 case_type=None,
                 user_id=None,
                 closed=False,
                 case_id=None):
    """
    Create the models directly so that these tests aren't dependent on any
    other apps. Not testing form processing here anyway.
    :return: CommCareCaseSQL
    """
    domain = domain or DOMAIN
    form_id = form_id or uuid.uuid4().hex
    case_id = case_id or uuid.uuid4().hex
    user_id = user_id or 'user1'
    utcnow = datetime.utcnow()

    form = XFormInstanceSQL(
        form_id=form_id,
        xmlns='http://openrosa.org/formdesigner/form-processor',
        received_on=utcnow,
        user_id=user_id,
        domain=domain)

    case = CommCareCaseSQL(case_id=case_id,
                           domain=domain,
                           type=case_type or '',
                           owner_id=user_id,
                           opened_on=utcnow,
                           modified_on=utcnow,
                           modified_by=user_id,
                           server_modified_on=utcnow,
                           closed=closed or False)
    case.track_create(CaseTransaction.form_transaction(case, form, utcnow))
    cases = [case]

    FormProcessorSQL.save_processed_models(ProcessedForms(form, None), cases)
    return CaseAccessorSQL.get_case(case_id)
Exemplo n.º 22
0
    def test_ignores_before_rebuild_transaction(self):
        with freeze_time("2018-10-10"):
            case = self._create_case()

        with freeze_time("2018-10-11"):
            new_old_xform = self._create_form()
        with freeze_time("2018-10-08"):
            new_old_trans = self._create_case_transaction(case, new_old_xform)
        with freeze_time("2018-10-11"):
            case.track_create(new_old_trans)
            FormProcessorSQL.save_processed_models(ProcessedForms(new_old_xform, []), [case])

        self.assertFalse(case.check_transaction_order())

        with freeze_time("2018-10-13"):
            new_rebuild_xform = self._create_form()
            rebuild_detail = RebuildWithReason(reason="shadow's golden coin")
            rebuild_transaction = CaseTransaction.rebuild_transaction(case, rebuild_detail)
            case.track_create(rebuild_transaction)
            FormProcessorSQL.save_processed_models(ProcessedForms(new_rebuild_xform, []), [case])

        case = CaseAccessorSQL.get_case(case.case_id)
        update_strategy = SqlCaseUpdateStrategy(case)
        self.assertFalse(update_strategy.reconcile_transactions_if_necessary())
            relationship_id=CommCareCaseIndexSQL.CHILD
        ))
        case1.track_create(CaseAttachmentSQL(
            case=case1,
            attachment_id=uuid.uuid4().hex,
            name='pic.jpg',
            content_type='image/jpeg',
            blob_id='122',
            md5='123',
        ))
        CaseAccessorSQL.save_case(case1)

        num_deleted = CaseAccessorSQL.hard_delete_cases(DOMAIN, [case1.case_id, case2.case_id])
        self.assertEqual(1, num_deleted)
        with self.assertRaises(CaseNotFound):
            CaseAccessorSQL.get_case(case1.case_id)

        self.assertEqual([], CaseAccessorSQL.get_indices(case1.domain, case1.case_id))
        self.assertEqual([], CaseAccessorSQL.get_attachments(case1.case_id))
        self.assertEqual([], CaseAccessorSQL.get_transactions(case1.case_id))

    def test_get_attachment_by_name(self):
        case = _create_case()

        case.track_create(CaseAttachmentSQL(
            case=case,
            attachment_id=uuid.uuid4().hex,
            name='pic.jpg',
            content_type='image/jpeg',
            blob_id='123',
            md5='123'
 def test_get_case_by_id_missing(self):
     with self.assertRaises(CaseNotFound):
         CaseAccessorSQL.get_case('missing_case')
Exemplo n.º 25
0
 def test_get_case_by_id_missing(self):
     with self.assertRaises(CaseNotFound):
         CaseAccessorSQL.get_case('missing_case')
Exemplo n.º 26
0
def get_sql_case(case_id):
    return CaseAccessorSQL.get_case(case_id)
Exemplo n.º 27
0
 def hard_rebuild_case(domain, case_id, detail):
     try:
         case = CaseAccessorSQL.get_case(case_id)
         assert case.domain == domain
         found = True
Exemplo n.º 28
0
def _hard_delete_data(args_json):
    # TODO remove form and case diffs, if any, for hard-deleted items
    case_id, form_ids = args_json
    try:
        case = CaseAccessorSQL.get_case(case_id)
Exemplo n.º 29
0
 def get_obj_by_id(cls, case_id):
     from corehq.form_processor.backends.sql.dbaccessors import CaseAccessorSQL
     return CaseAccessorSQL.get_case(case_id)
Exemplo n.º 30
0
 def get_supply_point(supply_point_id):
     return CaseAccessorSQL.get_case(supply_point_id)
Exemplo n.º 31
0
 def get_supply_point(supply_point_id):
     return CaseAccessorSQL.get_case(supply_point_id)
Exemplo n.º 32
0
        xform_ids = CaseAccessorSQL.get_case_xform_ids(case_id)
        return FormAccessorSQL.get_forms_with_attachments_meta(xform_ids)

    @staticmethod
    def get_case_with_lock(case_id,
                           lock=False,
                           strip_history=False,
                           wrap=False):
        try:
            if lock:
                try:
                    return CommCareCaseSQL.get_locked_obj(_id=case_id)
                except redis.RedisError:
                    case = CaseAccessorSQL.get_case(case_id)
            else:
                case = CaseAccessorSQL.get_case(case_id)
        except CaseNotFound:
            return None, None

        return case, None

    @staticmethod
    def case_exists(case_id):
        return CaseAccessorSQL.case_exists(case_id)


def get_case_transactions(case_id, updated_xforms=None):
    """
    This fetches all the transactions required to rebuild the case along
    with all the forms for those transactions.
Exemplo n.º 33
0
 def get_obj_by_id(cls, case_id):
     from corehq.form_processor.backends.sql.dbaccessors import CaseAccessorSQL
     return CaseAccessorSQL.get_case(case_id)