Example #1
0
def rebuild_case_from_actions(case, actions):
    strategy = ActionsUpdateStrategy(case)
    strategy.reset_case_state()
    # in addition to resetting the state, also manually clear xform_ids and actions
    # since we're going to rebuild these from the forms
    case.xform_ids = []

    case.actions = actions
    # call "rebuild" on the case, which should populate xform_ids
    # and re-sort actions if necessary
    strategy.soft_rebuild_case(strict=False)
Example #2
0
    def testActionComparison(self):
        user_id = 'test-action-comparison-user'
        case_id = _post_util(create=True, property='a1 wins', user_id=user_id)
        _post_util(case_id=case_id, property='a2 wins', user_id=user_id)
        _post_util(case_id=case_id, property='a3 wins', user_id=user_id)

        # check initial state
        case = CommCareCase.get(case_id)
        create, a1, a2, a3 = deepcopy(list(case.actions))
        self.assertEqual('a3 wins', case.property)
        self.assertEqual(a1.updated_unknown_properties['property'], 'a1 wins')
        self.assertEqual(a2.updated_unknown_properties['property'], 'a2 wins')
        self.assertEqual(a3.updated_unknown_properties['property'], 'a3 wins')

        def _confirm_action_order(case, expected_actions):
            actual_actions = case.actions[1:]  # always assume create is first and removed
            for expected, actual in zip(expected_actions, actual_actions):
                self.assertEqual(expected.updated_unknown_properties['property'],
                                 actual.updated_unknown_properties['property'])

        _confirm_action_order(case, [a1, a2, a3])

        # test initial rebuild does nothing
        update_strategy = ActionsUpdateStrategy(case)
        update_strategy.soft_rebuild_case()
        _confirm_action_order(case, [a1, a2, a3])

        # test sorting by server date
        case.actions[2].server_date = case.actions[2].server_date + timedelta(days=1)
        update_strategy.soft_rebuild_case()
        _confirm_action_order(case, [a1, a3, a2])

        # test sorting by date within the same day
        case = CommCareCase.get(case_id)
        _confirm_action_order(case, [a1, a2, a3])
        case.actions[2].date = case.actions[3].date + timedelta(minutes=1)
        ActionsUpdateStrategy(case).soft_rebuild_case()
        _confirm_action_order(case, [a1, a3, a2])

        # test original form order
        case = CommCareCase.get(case_id)
        case.actions[3].server_date = case.actions[2].server_date
        case.actions[3].date = case.actions[2].date
        case.xform_ids = [a1.xform_id, a3.xform_id, a2.xform_id]
        ActionsUpdateStrategy(case).soft_rebuild_case()
        _confirm_action_order(case, [a1, a3, a2])

        # test create comes before update
        case = CommCareCase.get(case_id)
        case.actions = [a1, create, a2, a3]
        ActionsUpdateStrategy(case).soft_rebuild_case()
        _confirm_action_order(case, [a1, a2, a3])
Example #3
0
    def testReconcileActions(self):
        now = datetime.utcnow()
        # make sure we timestamp everything so they have the right order
        case_id = _post_util(create=True, form_extras={'received_on': now})
        _post_util(case_id=case_id, p1='p1-1', p2='p2-1', form_extras={'received_on': now + timedelta(seconds=1)})
        _post_util(case_id=case_id, p2='p2-2', p3='p3-2', form_extras={'received_on': now + timedelta(seconds=2)})
        case = CommCareCase.get(case_id)
        update_strategy = ActionsUpdateStrategy(case)

        original_actions = [deepcopy(a) for a in case.actions]
        original_form_ids = [id for id in case.xform_ids]
        self.assertEqual(3, len(original_actions))
        self.assertEqual(3, len(original_form_ids))
        self._assertListEqual(original_actions, case.actions)

        # test reordering
        case.actions = [case.actions[2], case.actions[1], case.actions[0]]
        self._assertListNotEqual(original_actions, case.actions)
        update_strategy.reconcile_actions()
        self._assertListEqual(original_actions, case.actions)

        # test duplication
        case.actions = case.actions * 3
        self.assertEqual(9, len(case.actions))
        self._assertListNotEqual(original_actions, case.actions)
        update_strategy.reconcile_actions()
        self._assertListEqual(original_actions, case.actions)

        # test duplication, even when dates are off
        case.actions = original_actions + [deepcopy(case.actions[2])]
        case.actions[-1].server_date = case.actions[-1].server_date + timedelta(seconds=1)
        self._assertListNotEqual(original_actions, case.actions)
        update_strategy.reconcile_actions()
        self._assertListEqual(original_actions, case.actions)

        # test duplication with different properties is actually
        # treated differently
        case.actions = original_actions + [deepcopy(case.actions[2])]
        case.actions[-1].updated_unknown_properties['new'] = 'mismatch'
        self.assertEqual(4, len(case.actions))
        self._assertListNotEqual(original_actions, case.actions)
        update_strategy.reconcile_actions()
        self._assertListNotEqual(original_actions, case.actions)

        # test clean slate rebuild
        case = rebuild_case_from_forms(case_id)
        self._assertListEqual(original_actions, primary_actions(case))
        self._assertListEqual(original_form_ids, case.xform_ids)
Example #4
0
def _get_or_update_model(case_update, xform, case_db):
    """
    Gets or updates an existing case, based on a block of data in a
    submitted form.  Doesn't save anything.
    """
    case = case_db.get(case_update.id)
    if case is None:
        case = ActionsUpdateStrategy.case_from_case_update(case_update, xform)
        case_db.set(case['_id'], case)
        return case
    else:
        ActionsUpdateStrategy(case).update_from_case_update(case_update, xform, case_db.get_cached_forms())
        return case