def testUserRestoreWithCase(self):
        file_path = os.path.join(os.path.dirname(__file__),
                                 "data", "create_short.xml")
        with open(file_path, "rb") as f:
            xml_data = f.read()

        # implicit length assertion
        _, _, [newcase] = submit_form_locally(xml_data, domain=self.project.name)

        expected_case_block = """
        <case>
            <case_id>asdf</case_id>
            <date_modified>2010-06-29T13:42:50.000000Z</date_modified>
            <create>
                <case_type_id>test_case_type</case_type_id>
                <user_id>foo</user_id>
                <case_name>test case name</case_name>
                <external_id>someexternal</external_id>
            </create>
        </case>"""
        check_xml_line_by_line(self, expected_case_block, xml.get_case_xml(newcase, [case_const.CASE_ACTION_CREATE,
                                                                                     case_const.CASE_ACTION_UPDATE]))

        # check v2
        expected_v2_case_block = """
        <case case_id="asdf" date_modified="2010-06-29T13:42:50.000000Z" user_id="foo" xmlns="http://commcarehq.org/case/transaction/v2" >
            <create>
                <case_type>test_case_type</case_type>
                <case_name>test case name</case_name>
                <owner_id>foo</owner_id>
            </create>
            <update>
                <external_id>someexternal</external_id>
            </update>
        </case>"""
        check_xml_line_by_line(
            self,
            expected_v2_case_block,
            xml.get_case_xml(
                newcase,
                [case_const.CASE_ACTION_CREATE, case_const.CASE_ACTION_UPDATE],
                version="2.0",
            ),
        )

        restore_payload = generate_restore_payload(
            project=self.project,
            user=dummy_user(),
            items=True,
        )
        sync_log_id = SyncLog.view(
            "phone/sync_logs_by_user",
            include_docs=True,
            reduce=False,
        ).one().get_id
        check_xml_line_by_line(
            self,
            dummy_restore_xml(sync_log_id, expected_case_block, items=4),
            restore_payload
        )
Exemple #2
0
def explode_cases(request, domain, template="hqcase/explode_cases.html"):
    if request.method == 'POST':
        user_id = request.POST['user_id']
        user = CommCareUser.get_by_user_id(user_id, domain)
        factor = request.POST.get('factor', '2')
        try:
            factor = int(factor)
        except ValueError:
            messages.error(request, 'factor must be an int; was: %s' % factor)
        else:
            keys = [[domain, owner_id, False] for owner_id in user.get_owner_ids()]
            for case in CommCareCase.view('hqcase/by_owner',
                keys=keys,
                include_docs=True,
                reduce=False
            ):
                # we'll be screwing with this guy, so make him unsaveable
                case.save = None
                for i in range(factor - 1):

                    case._id = uuid.uuid4().hex
                    case_block = get_case_xml(case, (const.CASE_ACTION_CREATE, const.CASE_ACTION_UPDATE), version='2.0')
                    submit_case_blocks(case_block, domain)
            messages.success(request, "All of %s's cases were exploded by a factor of %d" % (user.raw_username, factor))

    return render(request, template, {
        'domain': domain,
        'users': CommCareUser.by_domain(domain),
    })
Exemple #3
0
def xml_for_case(request, case_id, version="1.0"):
    """
    Test view to get the xml for a particular case
    """
    case = CommCareCase.get(case_id)
    return HttpResponse(xml.get_case_xml(case, [const.CASE_ACTION_CREATE,
                                                const.CASE_ACTION_UPDATE],
                                         version), mimetype="text/xml")
    
Exemple #4
0
def make_creating_casexml(case, new_case_id):
    old_case_id = case._id
    case._id = new_case_id
    try:
        case_block = get_case_xml(case, (const.CASE_ACTION_CREATE, const.CASE_ACTION_UPDATE), version='2.0')
        case_block, attachments = _process_case_block(case_block, case.case_attachments, old_case_id)
    finally:
        case._id = old_case_id
    return case_block, attachments
 def get_xml(self):
     updates = self._case._updates
     case_block = get_case_xml(self._case, updates, version='2.0')
     diff_block = get_diff_block(self._case)
     return render_to_string('hqcase/xml/case_block.xml', {
         'xmlns': self.xmlns,
         'case_block': case_block.decode('utf-8') + diff_block,
         'time': json_format_datetime(self.received_on),
         'uid': self.form_id,
         'username': "",
         'user_id': self.user_id or "",
         'device_id': self.device_id,
     })
    def testParseWithIndices(self):
        self._test_parse_create()

        user_id = "bar-user-id"
        for prereq in ["some_referenced_id", "some_other_referenced_id"]:
            post_case_blocks([
                CaseBlock(
                    create=True, case_id=prereq,
                    user_id=user_id
                ).as_xml()
            ])

        file_path = os.path.join(os.path.dirname(__file__), "data", "v2", "index_update.xml")
        with open(file_path, "rb") as f:
            xml_data = f.read()

        case = submit_form_locally(xml_data, 'test-domain').case
        self.assertEqual(2, len(case.indices))
        self.assertTrue(case.has_index("foo_ref"))
        self.assertTrue(case.has_index("baz_ref"))
        self.assertEqual("bar", case.get_index("foo_ref").referenced_type)
        self.assertEqual("some_referenced_id", case.get_index("foo_ref").referenced_id)
        self.assertEqual("bop", case.get_index("baz_ref").referenced_type)
        self.assertEqual("some_other_referenced_id", case.get_index("baz_ref").referenced_id)

        if not getattr(settings, 'TESTS_SHOULD_USE_SQL_BACKEND', False):
            # check the action
            self.assertEqual(2, len(case.actions))
            [_, index_action] = case.actions
            self.assertEqual(const.CASE_ACTION_INDEX, index_action.action_type)
            self.assertEqual(2, len(index_action.indices))

        # quick test for ota restore
        v2response = xml.get_case_xml(case, [const.CASE_ACTION_CREATE, const.CASE_ACTION_UPDATE], V2)
        expected_v2_response = """
        <case case_id="foo-case-id" date_modified="2011-12-07T13:42:50.000000Z" user_id="bar-user-id" xmlns="http://commcarehq.org/case/transaction/v2">
                <create>
                    <case_type>v2_case_type</case_type>
                    <case_name>test case name</case_name>
                    <owner_id>bar-user-id</owner_id>
                </create>
                <update>
                    <date_opened>2011-12-06</date_opened>
                </update>
                <index>
                    <baz_ref case_type="bop">some_other_referenced_id</baz_ref>
                    <foo_ref case_type="bar">some_referenced_id</foo_ref>
                </index>
            </case>"""
        check_xml_line_by_line(self, expected_v2_response, v2response)
Exemple #7
0
    def testParseWithIndices(self):
        self.testParseCreate()

        user_id = "bar-user-id"
        for prereq in ["some_referenced_id", "some_other_referenced_id"]:
            post_case_blocks([
                CaseBlock(
                    create=True, case_id=prereq,
                    user_id=user_id, version=V2
                ).as_xml()
            ])

        file_path = os.path.join(os.path.dirname(__file__), "data", "v2", "index_update.xml")
        with open(file_path, "rb") as f:
            xml_data = f.read()

        form = post_xform_to_couch(xml_data)
        process_cases(form)
        case = CommCareCase.get("foo-case-id")
        self.assertEqual(2, len(case.indices))
        self.assertTrue(case.has_index("foo_ref"))
        self.assertTrue(case.has_index("baz_ref"))
        self.assertEqual("bar", case.get_index("foo_ref").referenced_type)
        self.assertEqual("some_referenced_id", case.get_index("foo_ref").referenced_id)
        self.assertEqual("bop", case.get_index("baz_ref").referenced_type)
        self.assertEqual("some_other_referenced_id", case.get_index("baz_ref").referenced_id)

        # check the action
        self.assertEqual(2, len(case.actions))
        [_, index_action] = case.actions
        self.assertEqual(const.CASE_ACTION_INDEX, index_action.action_type)
        self.assertEqual(2, len(index_action.indices))


        # quick test for ota restore
        v2response = xml.get_case_xml(case, [const.CASE_ACTION_CREATE, const.CASE_ACTION_UPDATE], V2)
        expected_v2_response = """
        <case case_id="foo-case-id" date_modified="2011-12-07T13:42:50.000000Z" user_id="bar-user-id" xmlns="http://commcarehq.org/case/transaction/v2">
                <create>
                    <case_type>v2_case_type</case_type>
                    <case_name>test case name</case_name>
                    <owner_id>bar-user-id</owner_id>
                </create>
                <index>
                    <baz_ref case_type="bop">some_other_referenced_id</baz_ref>
                    <foo_ref case_type="bar">some_referenced_id</foo_ref>
                </index>
            </case>"""
        check_xml_line_by_line(self, expected_v2_response, v2response)
 def testUserRestoreWithCase(self):
     file_path = os.path.join(os.path.dirname(__file__), "data", "create_short.xml")
     with open(file_path, "rb") as f:
         xml_data = f.read()
     form = post_xform_to_couch(xml_data)
     process_cases(sender="testharness", xform=form)
     user = dummy_user()
     
     # implicit length assertion
     [newcase] = CommCareCase.view("case/by_user", reduce=False, include_docs=True).all()
     self.assertEqual(1, len(user.get_case_updates(None).actual_cases_to_sync))
     expected_case_block = """
     <case>
         <case_id>asdf</case_id> 
         <date_modified>2010-06-29</date_modified>
         <create>
             <case_type_id>test_case_type</case_type_id> 
             <user_id>foo</user_id> 
             <case_name>test case name</case_name> 
             <external_id>someexternal</external_id>
         </create>
     </case>"""
     check_xml_line_by_line(self, expected_case_block, xml.get_case_xml(newcase, [case_const.CASE_ACTION_CREATE,
                                                                                  case_const.CASE_ACTION_UPDATE]))
     
     # check v2
     expected_v2_case_block = """
     <case case_id="asdf" date_modified="2010-06-29" user_id="foo" xmlns="http://commcarehq.org/case/transaction/v2" >
         <create>
             <case_type>test_case_type</case_type> 
             <case_name>test case name</case_name>
             <owner_id>foo</owner_id>
         </create>
         <update>
             <external_id>someexternal</external_id>
         </update>
     </case>"""
     check_xml_line_by_line(self, expected_v2_case_block, xml.get_case_xml\
                            (newcase, [case_const.CASE_ACTION_CREATE,
                                       case_const.CASE_ACTION_UPDATE],
                             version="2.0"))
     
     
     restore_payload = generate_restore_payload(dummy_user())
     # implicit length assertion
     [sync_log] = SyncLog.view("phone/sync_logs_by_user", include_docs=True, reduce=False).all()
     check_xml_line_by_line(self, dummy_restore_xml(sync_log.get_id, expected_case_block), 
                            restore_payload)
Exemple #9
0
def make_creating_casexml(domain, case, new_case_id, new_parent_ids=None):
    new_parent_ids = new_parent_ids or {}
    old_case_id = case.case_id
    case.case_id = new_case_id
    local_move_back = {}
    for index in case.indices:
        new = new_parent_ids[index.referenced_id]
        old = index.referenced_id
        local_move_back[new] = old
        index.referenced_id = new
    try:
        case_block = get_case_xml(case, (const.CASE_ACTION_CREATE, const.CASE_ACTION_UPDATE), version='2.0')
        case_block, attachments = _process_case_block(domain, case_block, case.case_attachments, old_case_id)
    finally:
        case.case_id = old_case_id
        for index in case.indices:
            index.referenced_id = local_move_back[index.referenced_id]
    return case_block, attachments
Exemple #10
0
    def testUserRestoreWithCase(self):
        file_path = os.path.join(os.path.dirname(__file__),
                                 "data", "create_short.xml")
        with open(file_path, "rb") as f:
            xml_data = f.read()
        form = post_xform_to_couch(xml_data, domain=self.project.name)
        # implicit length assertion
        [newcase] = process_cases(form)
        user = dummy_user()

        self.assertEqual(1, len(list(
            BatchedCaseSyncOperation(RestoreState(self.project, user, RestoreParams())).get_all_case_updates()
        )))
        expected_case_block = """
        <case>
            <case_id>asdf</case_id>
            <date_modified>2010-06-29T13:42:50.000000Z</date_modified>
            <create>
                <case_type_id>test_case_type</case_type_id>
                <user_id>foo</user_id>
                <case_name>test case name</case_name>
                <external_id>someexternal</external_id>
            </create>
        </case>"""
        check_xml_line_by_line(self, expected_case_block, xml.get_case_xml(newcase, [case_const.CASE_ACTION_CREATE,
                                                                                     case_const.CASE_ACTION_UPDATE]))

        # check v2
        expected_v2_case_block = """
        <case case_id="asdf" date_modified="2010-06-29T13:42:50.000000Z" user_id="foo" xmlns="http://commcarehq.org/case/transaction/v2" >
            <create>
                <case_type>test_case_type</case_type>
                <case_name>test case name</case_name>
                <owner_id>foo</owner_id>
            </create>
            <update>
                <external_id>someexternal</external_id>
            </update>
        </case>"""
        check_xml_line_by_line(
            self,
            expected_v2_case_block,
            xml.get_case_xml(
                newcase,
                [case_const.CASE_ACTION_CREATE, case_const.CASE_ACTION_UPDATE],
                version="2.0",
            ),
        )

        restore_payload = generate_restore_payload(
            project=self.project,
            user=dummy_user(),
            items=True,
        )
        sync_log_id = SyncLog.view(
            "phone/sync_logs_by_user",
            include_docs=True,
            reduce=False,
        ).one().get_id
        check_xml_line_by_line(
            self,
            dummy_restore_xml(sync_log_id, expected_case_block, items=4),
            restore_payload
        )
    def testUserRestoreWithCase(self):
        xml_data = self.get_xml('create_short')
        xml_data = xml_data.format(user_id=self.restore_user.user_id)

        # implicit length assertion
        _, _, [newcase] = submit_form_locally(xml_data,
                                              domain=self.project.name)

        expected_case_block = """
        <case>
            <case_id>asdf</case_id>
            <date_modified>2010-06-29T13:42:50.000000Z</date_modified>
            <create>
                <case_type_id>test_case_type</case_type_id>
                <user_id>{user_id}</user_id>
                <case_name>test case name</case_name>
                <external_id>someexternal</external_id>
            </create>
            <update>
                <date_opened>2010-06-29</date_opened>
            </update>
        </case>""".format(user_id=self.restore_user.user_id)
        check_xml_line_by_line(
            self, expected_case_block,
            xml.get_case_xml(
                newcase,
                [case_const.CASE_ACTION_CREATE, case_const.CASE_ACTION_UPDATE
                 ]))

        # check v2
        expected_v2_case_block = """
        <case case_id="asdf" date_modified="2010-06-29T13:42:50.000000Z" user_id="{user_id}" xmlns="http://commcarehq.org/case/transaction/v2" >
            <create>
                <case_type>test_case_type</case_type>
                <case_name>test case name</case_name>
                <owner_id>{user_id}</owner_id>
            </create>
            <update>
                <external_id>someexternal</external_id>
                <date_opened>2010-06-29</date_opened>
            </update>
        </case>""".format(user_id=self.restore_user.user_id)
        check_xml_line_by_line(
            self,
            expected_v2_case_block,
            xml.get_case_xml(
                newcase,
                [case_const.CASE_ACTION_CREATE, case_const.CASE_ACTION_UPDATE],
                version="2.0",
            ),
        )

        restore_payload = generate_restore_payload(
            project=self.project,
            user=self.restore_user,
            items=True,
        )
        sync_log_id = SyncLog.view(
            "phone/sync_logs_by_user",
            include_docs=True,
            reduce=False,
        ).one().get_id
        check_xml_line_by_line(
            self,
            dummy_restore_xml(sync_log_id,
                              expected_case_block,
                              items=4,
                              user=self.restore_user), restore_payload)
Exemple #12
0
def excel_commit(request, domain):
    named_columns = request.POST['named_columns']
    uses_headers = named_columns == 'yes'
    case_type = request.POST['case_type']
    search_column = request.POST['search_column']
    search_field = request.POST['search_field']
    key_column = request.POST['key_column']
    value_column = request.POST['value_column']

    # TODO musn't be able to select an excel_field twice (in html)
    excel_fields = request.POST.getlist('excel_field[]')
    case_fields = request.POST.getlist('case_field[]')
    custom_fields = request.POST.getlist('custom_field[]')
    date_yesno = request.POST.getlist('date_yesno[]')

    # turn all the select boxes into a useful struct
    field_map = {}
    for i, field in enumerate(excel_fields):
        if field and (case_fields[i] or custom_fields[i]):
            field_map[field] = {'case': case_fields[i], 'custom': custom_fields[i], 'date': int(date_yesno[i])}

    download_ref = DownloadBase.get(request.session.get(EXCEL_SESSION_ID))
    spreadsheet = _get_spreadsheet(download_ref, uses_headers)
    if not spreadsheet:
        return _spreadsheet_expired(request, domain)

    if spreadsheet.has_errors:
        messages.error(request, _('The session containing the file you '
                                  'uploaded has expired - please upload '
                                  'a new one.'))
        return HttpResponseRedirect(base.ImportCases.get_url(domain=domain) + "?error=cache")

    columns = spreadsheet.get_header_columns()

    # find indexes of user selected columns
    search_column_index = columns.index(search_column)

    try:
        key_column_index = columns.index(key_column)
    except ValueError:
        key_column_index = False

    try:
        value_column_index = columns.index(value_column)
    except ValueError:
        value_column_index = False

    no_match_count = 0
    match_count = 0
    too_many_matches = 0

    cases = {}

    # start looping through all the rows
    for i in range(spreadsheet.get_num_rows()):
        # skip first row if it is a header field
        if i == 0 and named_columns:
            continue

        row = spreadsheet.get_row(i)
        found = False

        search_id = row[search_column_index]

        # see what has come out of the spreadsheet
        try:
            float(search_id)
            # no error, so something that looks like a number came out of the cell
            # in which case we should remove any decimal places
            search_id = int(search_id)
        except ValueError:
            # error, so probably a string
            pass

        # couchdb wants a string
        search_id = str(search_id)

        if search_field == 'case_id':
            try:
                case = CommCareCase.get(search_id)
                if case.domain == domain:
                    found = True
            except Exception:
                pass
        elif search_field == 'external_id':
            try:
                case = CommCareCase.view('hqcase/by_domain_external_id',
                                         key=[domain, search_id],
                                         reduce=False,
                                         include_docs=True).one()
                found = True if case else False
            except NoResultFound:
                pass
            except MultipleResultsFound:
                too_many_matches += 1

        if found:
            match_count += 1
        else:
            no_match_count += 1
            continue

        # here be monsters
        fields_to_update = {}

        for key in field_map:
            update_value = False

            if key_column_index and key == row[key_column_index]:
                update_value = row[value_column_index]
            else:
                # nothing was set so maybe it is a regular column
                try:
                    update_value = row[columns.index(key)]
                except Exception:
                    pass

            if update_value:
                # case field to update
                if field_map[key]['custom']:
                    # custom (new) field was entered
                    update_field_name = field_map[key]['custom']
                else:
                    # existing case field was chosen
                    update_field_name = field_map[key]['case']

                if field_map[key]['date'] == 1:
                    update_value = date(*xldate_as_tuple(update_value, 0)[:3])

                fields_to_update[update_field_name] = update_value

        if case.type == case_type:
            if cases.has_key(search_id):
                cases[search_id]['fields'].update(fields_to_update)
            else:
                cases[search_id] = {'obj': case, 'fields': fields_to_update}

    # run updates
    for id, case in cases.iteritems():
        for name, value in case['fields'].iteritems():
            case['obj'].set_case_property(name, value)

        case['obj'].modified_on = datetime.utcnow()

        # spoof case update xform submission
        case_block = get_case_xml(case['obj'], (const.CASE_ACTION_UPDATE,), version='2.0')
        submit_case_blocks(case_block, domain)

    # unset filename session var
    try:
        del request.session[EXCEL_SESSION_ID]
    except KeyError:
        pass

    return render(request, "importer/excel_commit.html", {
                                'match_count': match_count,
                                'no_match_count': no_match_count,
                                'too_many_matches': too_many_matches,
                                'domain': domain,
                                'report': {
                                    'name': 'Import: Completed'
                                 },
                                'slug': base.ImportCases.slug})
Exemple #13
0
 def iter_xml_blocks(self):
     yield get_case_xml(self, self._updates, version='2.0')
     yield from self._ledger_blocks()
     yield get_diff_block(self).encode('utf-8')
    def testUserRestoreWithCase(self):
        xml_data = self.get_xml('create_short').decode('utf-8')
        xml_data = xml_data.format(user_id=self.restore_user.user_id)

        # implicit length assertion
        result = submit_form_locally(xml_data, domain=self.project.name)

        expected_case_block = """
        <case>
            <case_id>asdf</case_id>
            <date_modified>2010-06-29T13:42:50.000000Z</date_modified>
            <create>
                <case_type_id>test_case_type</case_type_id>
                <user_id>{user_id}</user_id>
                <case_name>test case name</case_name>
                <external_id>someexternal</external_id>
            </create>
            <update>
                <date_opened>2010-06-29</date_opened>
            </update>
        </case>""".format(user_id=self.restore_user.user_id)
        check_xml_line_by_line(
            self,
            expected_case_block,
            xml.get_case_xml(
                result.case,
                [case_const.CASE_ACTION_CREATE, case_const.CASE_ACTION_UPDATE]
            )
        )

        # check v2
        expected_v2_case_block = """
        <case case_id="asdf" date_modified="2010-06-29T13:42:50.000000Z" user_id="{user_id}" xmlns="http://commcarehq.org/case/transaction/v2" >
            <create>
                <case_type>test_case_type</case_type>
                <case_name>test case name</case_name>
                <owner_id>{user_id}</owner_id>
            </create>
            <update>
                <external_id>someexternal</external_id>
                <date_opened>2010-06-29</date_opened>
            </update>
        </case>""".format(user_id=self.restore_user.user_id)
        check_xml_line_by_line(
            self,
            expected_v2_case_block,
            xml.get_case_xml(
                result.case,
                [case_const.CASE_ACTION_CREATE, case_const.CASE_ACTION_UPDATE],
                version="2.0",
            ),
        )

        restore_payload = deprecated_generate_restore_payload(
            project=self.project,
            user=self.restore_user,
            items=True,
        )
        sync_log_id = self._get_the_first_synclog().get_id
        check_xml_line_by_line(
            self,
            dummy_restore_xml(sync_log_id, expected_case_block, items=4, user=self.restore_user),
            restore_payload
        )