def test_flat_sync_format(self, uses_locations): with flag_enabled('SYNC_ALL_LOCATIONS'): with flag_enabled('FLAT_LOCATION_FIXTURE'): self._assert_fixture_has_locations( 'expand_from_root_flat', ['Massachusetts', 'Suffolk', 'Middlesex', 'Boston', 'Revere', 'Cambridge', 'Somerville', 'New York', 'New York City', 'Manhattan', 'Queens', 'Brooklyn'], flat=True, )
def test_should_sync_flat_format_disabled_toggle(self): location_settings = LocationFixtureConfiguration.objects.create( domain='some-domain', sync_flat_fixture=False ) self.addCleanup(location_settings.delete) with flag_enabled('FLAT_LOCATION_FIXTURE'): self.assertEqual(False, should_sync_flat_fixture('some-domain'))
def test_location_instances(self): self.form.form_filter = "instance('locations')/locations/" with flag_enabled('FLAT_LOCATION_FIXTURE'): self.assertXmlPartialEqual( u""" <partial> <instance id='locations' src='jr://fixture/locations' /> </partial> """, self.factory.app.create_suite(), "entry/instance") self.assertXmlPartialEqual( u""" <partial> <instance id='locations' src='jr://fixture/commtrack:locations' /> </partial> """, self.factory.app.create_suite(), "entry/instance" ) self.form.form_filter = "instance('commtrack:locations')/locations/" self.assertXmlPartialEqual( u""" <partial> <instance id='commtrack:locations' src='jr://fixture/commtrack:locations' /> </partial> """, self.factory.app.create_suite(), "entry/instance" )
def test_all_locations_flag_returns_all_locations(self): with flag_enabled('SYNC_ALL_LOCATIONS'): self._assert_fixture_matches_file( 'expand_from_root', ['Massachusetts', 'Suffolk', 'Middlesex', 'Boston', 'Revere', 'Cambridge', 'Somerville', 'New York', 'New York City', 'Manhattan', 'Queens', 'Brooklyn'] )
def test_opened_on(self): case = self.factory.create_case() new_date = '2015-04-30T14:41:53.000000Z' with flag_enabled('BULK_UPLOAD_DATE_OPENED'): self.import_mock_file([ ['case_id', 'date_opened'], [case.case_id, new_date] ]) case = CaseAccessors(self.domain).get_case(case.case_id) self.assertEqual(case.opened_on, PhoneTime(parse_datetime(new_date)).done())
def test_use_default_media(self): self.module.use_default_image_for_all = True self.module.use_default_audio_for_all = True self.module.set_icon('en', self.image_path) self.module.set_audio('en', self.audio_path) self.module.set_icon('hin', 'jr://file/commcare/case_list_image_hin.jpg') self.module.set_audio('hin', 'jr://file/commcare/case_list_audio_hin.mp3') with flag_enabled('LANGUAGE_LINKED_MULTIMEDIA'): en_app_strings = commcare_translations.loads(self.app.create_app_strings('en')) hin_app_strings = commcare_translations.loads(self.app.create_app_strings('hin')) self.assertEqual(en_app_strings['modules.m0.icon'], hin_app_strings['modules.m0.icon']) self.assertEqual(en_app_strings['modules.m0.audio'], hin_app_strings['modules.m0.audio'])
def test_should_sync_hierarchical_format_disabled(self): domain = uuid.uuid4().hex project = Domain(name=domain) project.save() location_type = LocationType.objects.create(domain=domain, name='test-type') location_settings = LocationFixtureConfiguration.objects.create( domain=domain, sync_hierarchical_fixture=False ) self.assertEqual(False, should_sync_hierarchical_fixture(project)) with flag_enabled('FLAT_LOCATION_FIXTURE'): self.assertEqual(False, should_sync_hierarchical_fixture(project)) self.addCleanup(project.delete) self.addCleanup(location_type.delete) self.addCleanup(location_settings.delete)
def _do_submit(self, xml_data, dict_attachments, sync_token=None, date=None): """ RequestFactory submitter - simulates direct submission to server directly (no need to call process case after fact) """ with flag_enabled('MM_CASE_PROPERTIES'): result = submit_form_locally( xml_data, TEST_DOMAIN_NAME, attachments=dict_attachments, last_sync_token=sync_token, received_on=date ) attachments = result.xform.attachments self.assertEqual(set(dict_attachments.keys()), set(attachments.keys())) self.assertEqual(result.case.case_id, TEST_CASE_ID) return result.response, result.xform, result.cases
def test_case_detail_tabs_with_nodesets(self): with flag_enabled('DISPLAY_CONDITION_ON_TABS'): self._test_generic_suite("app_case_detail_tabs_with_nodesets", 'suite-case-detail-tabs-with-nodesets')
def test_contractor(): user = CouchUser(username="******") with flag_enabled('IS_CONTRACTOR'): assert_true(is_superuser_or_contractor(user))
class ImporterTest(TestCase): def setUp(self): super(ImporterTest, self).setUp() self.domain_obj = create_domain("importer-test") self.domain = self.domain_obj.name self.default_case_type = 'importer-test-casetype' self.couch_user = WebUser.create(None, "test", "foobar") self.couch_user.add_domain_membership(self.domain, is_admin=True) self.couch_user.save() self.accessor = CaseAccessors(self.domain) self.factory = CaseFactory(domain=self.domain, case_defaults={ 'case_type': self.default_case_type, }) delete_all_cases() def tearDown(self): self.couch_user.delete() self.domain_obj.delete() super(ImporterTest, self).tearDown() def _config(self, col_names, search_column=None, case_type=None, search_field='case_id', create_new_cases=True): return ImporterConfig( couch_user_id=self.couch_user._id, case_type=case_type or self.default_case_type, excel_fields=col_names, case_fields=[''] * len(col_names), custom_fields=col_names, search_column=search_column or col_names[0], search_field=search_field, create_new_cases=create_new_cases, ) @run_with_all_backends @patch('corehq.apps.case_importer.tasks.bulk_import_async.update_state') def testImportNone(self, update_state): res = bulk_import_async.delay(self._config(['anything']), self.domain, None) self.assertIsInstance(res.result, Ignore) update_state.assert_called_with( state=states.FAILURE, meta={'errors': 'Sorry, your session has expired. Please start over and try again.'}) self.assertEqual(0, len(get_case_ids_in_domain(self.domain))) @run_with_all_backends def testImportBasic(self): config = self._config(['case_id', 'age', 'sex', 'location']) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], ['case_id-0', 'age-0', 'sex-0', 'location-0'], ['case_id-1', 'age-1', 'sex-1', 'location-1'], ['case_id-2', 'age-2', 'sex-2', 'location-2'], ['case_id-3', 'age-3', 'sex-3', 'location-3'], ['case_id-4', 'age-4', 'sex-4', 'location-4'], ) res = do_import(file, config, self.domain) self.assertEqual(5, res['created_count']) self.assertEqual(0, res['match_count']) self.assertFalse(res['errors']) self.assertEqual(1, res['num_chunks']) case_ids = self.accessor.get_case_ids_in_domain() cases = list(self.accessor.get_cases(case_ids)) self.assertEqual(5, len(cases)) properties_seen = set() for case in cases: self.assertEqual(self.couch_user._id, case.user_id) self.assertEqual(self.couch_user._id, case.owner_id) self.assertEqual(self.default_case_type, case.type) for prop in ['age', 'sex', 'location']: self.assertTrue(prop in case.get_case_property(prop)) self.assertFalse(case.get_case_property(prop) in properties_seen) properties_seen.add(case.get_case_property(prop)) @run_with_all_backends def testImportNamedColumns(self): config = self._config(['case_id', 'age', 'sex', 'location']) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], ['case_id-0', 'age-0', 'sex-0', 'location-0'], ['case_id-1', 'age-1', 'sex-1', 'location-1'], ['case_id-2', 'age-2', 'sex-2', 'location-2'], ['case_id-3', 'age-3', 'sex-3', 'location-3'], ) res = do_import(file, config, self.domain) self.assertEqual(4, res['created_count']) self.assertEqual(4, len(self.accessor.get_case_ids_in_domain())) @run_with_all_backends def testImportTrailingWhitespace(self): cols = ['case_id', 'age', 'sex\xa0', 'location'] config = self._config(cols) file = make_worksheet_wrapper( ['case_id', 'age', 'sex\xa0', 'location'], ['case_id-0', 'age-0', 'sex\xa0-0', 'location-0'], ) res = do_import(file, config, self.domain) self.assertEqual(1, res['created_count']) case_ids = self.accessor.get_case_ids_in_domain() self.assertEqual(1, len(case_ids)) case = self.accessor.get_case(case_ids[0]) self.assertTrue(bool(case.get_case_property('sex'))) # make sure the value also got properly set @run_with_all_backends def testCaseIdMatching(self): # bootstrap a stub case [case] = self.factory.create_or_update_case(CaseStructure(attrs={ 'create': True, 'update': {'importer_test_prop': 'foo'}, })) self.assertEqual(1, len(self.accessor.get_case_ids_in_domain())) config = self._config(['case_id', 'age', 'sex', 'location']) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], [case.case_id, 'age-0', 'sex-0', 'location-0'], [case.case_id, 'age-1', 'sex-1', 'location-1'], [case.case_id, 'age-2', 'sex-2', 'location-2'], ) res = do_import(file, config, self.domain) self.assertEqual(0, res['created_count']) self.assertEqual(3, res['match_count']) self.assertFalse(res['errors']) # shouldn't create any more cases, just the one case_ids = self.accessor.get_case_ids_in_domain() self.assertEqual(1, len(case_ids)) [case] = self.accessor.get_cases(case_ids) for prop in ['age', 'sex', 'location']: self.assertTrue(prop in case.get_case_property(prop)) # shouldn't touch existing properties self.assertEqual('foo', case.get_case_property('importer_test_prop')) @run_with_all_backends def testCaseLookupTypeCheck(self): [case] = self.factory.create_or_update_case(CaseStructure(attrs={ 'create': True, 'case_type': 'nonmatch-type', })) self.assertEqual(1, len(self.accessor.get_case_ids_in_domain())) config = self._config(['case_id', 'age', 'sex', 'location']) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], [case.case_id, 'age-0', 'sex-0', 'location-0'], [case.case_id, 'age-1', 'sex-1', 'location-1'], [case.case_id, 'age-2', 'sex-2', 'location-2'], ) res = do_import(file, config, self.domain) # because the type is wrong these shouldn't match self.assertEqual(3, res['created_count']) self.assertEqual(0, res['match_count']) self.assertEqual(4, len(self.accessor.get_case_ids_in_domain())) @run_with_all_backends def testCaseLookupDomainCheck(self): self.factory.domain = 'wrong-domain' [case] = self.factory.create_or_update_case(CaseStructure(attrs={ 'create': True, })) self.assertEqual(0, len(self.accessor.get_case_ids_in_domain())) config = self._config(['case_id', 'age', 'sex', 'location']) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], [case.case_id, 'age-0', 'sex-0', 'location-0'], [case.case_id, 'age-1', 'sex-1', 'location-1'], [case.case_id, 'age-2', 'sex-2', 'location-2'], ) res = do_import(file, config, self.domain) # because the domain is wrong these shouldn't match self.assertEqual(3, res['created_count']) self.assertEqual(0, res['match_count']) self.assertEqual(3, len(self.accessor.get_case_ids_in_domain())) @run_with_all_backends def testExternalIdMatching(self): # bootstrap a stub case external_id = 'importer-test-external-id' [case] = self.factory.create_or_update_case(CaseStructure( attrs={ 'create': True, 'external_id': external_id, } )) self.assertEqual(1, len(self.accessor.get_case_ids_in_domain())) headers = ['external_id', 'age', 'sex', 'location'] config = self._config(headers, search_field='external_id') file = make_worksheet_wrapper( ['external_id', 'age', 'sex', 'location'], ['importer-test-external-id', 'age-0', 'sex-0', 'location-0'], ['importer-test-external-id', 'age-1', 'sex-1', 'location-1'], ['importer-test-external-id', 'age-2', 'sex-2', 'location-2'], ) res = do_import(file, config, self.domain) self.assertEqual(0, res['created_count']) self.assertEqual(3, res['match_count']) self.assertFalse(res['errors']) # shouldn't create any more cases, just the one self.assertEqual(1, len(self.accessor.get_case_ids_in_domain())) @run_with_all_backends def test_external_id_matching_on_create_with_custom_column_name(self): headers = ['id_column', 'age', 'sex', 'location'] external_id = 'external-id-test' config = self._config(headers[1:], search_column='id_column', search_field='external_id') file = make_worksheet_wrapper( ['id_column', 'age', 'sex', 'location'], ['external-id-test', 'age-0', 'sex-0', 'location-0'], ['external-id-test', 'age-1', 'sex-1', 'location-1'], ) res = do_import(file, config, self.domain) self.assertFalse(res['errors']) self.assertEqual(1, res['created_count']) self.assertEqual(1, res['match_count']) case_ids = self.accessor.get_case_ids_in_domain() self.assertEqual(1, len(case_ids)) case = self.accessor.get_case(case_ids[0]) self.assertEqual(external_id, case.external_id) def testNoCreateNew(self): config = self._config(['case_id', 'age', 'sex', 'location'], create_new_cases=False) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], ['case_id-0', 'age-0', 'sex-0', 'location-0'], ['case_id-1', 'age-1', 'sex-1', 'location-1'], ['case_id-2', 'age-2', 'sex-2', 'location-2'], ['case_id-3', 'age-3', 'sex-3', 'location-3'], ['case_id-4', 'age-4', 'sex-4', 'location-4'], ) res = do_import(file, config, self.domain) # no matching and no create new set - should do nothing self.assertEqual(0, res['created_count']) self.assertEqual(0, res['match_count']) self.assertEqual(0, len(get_case_ids_in_domain(self.domain))) def testBlankRows(self): # don't create new cases for rows left blank config = self._config(['case_id', 'age', 'sex', 'location'], create_new_cases=True) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], [None, None, None, None], ['', '', '', ''], ) res = do_import(file, config, self.domain) # no matching and no create new set - should do nothing self.assertEqual(0, res['created_count']) self.assertEqual(0, res['match_count']) self.assertEqual(0, len(get_case_ids_in_domain(self.domain))) @patch('corehq.apps.case_importer.do_import.CASEBLOCK_CHUNKSIZE', 2) def testBasicChunking(self): config = self._config(['case_id', 'age', 'sex', 'location']) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], ['case_id-0', 'age-0', 'sex-0', 'location-0'], ['case_id-1', 'age-1', 'sex-1', 'location-1'], ['case_id-2', 'age-2', 'sex-2', 'location-2'], ['case_id-3', 'age-3', 'sex-3', 'location-3'], ['case_id-4', 'age-4', 'sex-4', 'location-4'], ) res = do_import(file, config, self.domain) # 5 cases in chunks of 2 = 3 chunks self.assertEqual(3, res['num_chunks']) self.assertEqual(5, res['created_count']) self.assertEqual(5, len(get_case_ids_in_domain(self.domain))) @run_with_all_backends def testExternalIdChunking(self): # bootstrap a stub case external_id = 'importer-test-external-id' headers = ['external_id', 'age', 'sex', 'location'] config = self._config(headers, search_field='external_id') file = make_worksheet_wrapper( ['external_id', 'age', 'sex', 'location'], ['importer-test-external-id', 'age-0', 'sex-0', 'location-0'], ['importer-test-external-id', 'age-1', 'sex-1', 'location-1'], ['importer-test-external-id', 'age-2', 'sex-2', 'location-2'], ) # the first one should create the case, and the remaining two should update it res = do_import(file, config, self.domain) self.assertEqual(1, res['created_count']) self.assertEqual(2, res['match_count']) self.assertFalse(res['errors']) self.assertEqual(2, res['num_chunks']) # the lookup causes an extra chunk # should just create the one case case_ids = self.accessor.get_case_ids_in_domain() self.assertEqual(1, len(case_ids)) [case] = self.accessor.get_cases(case_ids) self.assertEqual(external_id, case.external_id) for prop in ['age', 'sex', 'location']: self.assertTrue(prop in case.get_case_property(prop)) @run_with_all_backends def testParentCase(self): headers = ['parent_id', 'name', 'case_id'] config = self._config(headers, create_new_cases=True, search_column='case_id') rows = 3 [parent_case] = self.factory.create_or_update_case(CaseStructure(attrs={'create': True})) self.assertEqual(1, len(self.accessor.get_case_ids_in_domain())) file = make_worksheet_wrapper( ['parent_id', 'name', 'case_id'], [parent_case.case_id, 'name-0', 'case_id-0'], [parent_case.case_id, 'name-1', 'case_id-1'], [parent_case.case_id, 'name-2', 'case_id-2'], ) file_missing = make_worksheet_wrapper( ['parent_id', 'name', 'case_id'], ['parent_id-0', 'name-0', 'case_id-0'], ['parent_id-1', 'name-1', 'case_id-1'], ['parent_id-2', 'name-2', 'case_id-2'], ) # Should successfully match on `rows` cases res = do_import(file, config, self.domain) self.assertEqual(rows, res['created_count']) # Should be unable to find parent case on `rows` cases res = do_import(file_missing, config, self.domain) error_column_name = 'parent_id' self.assertEqual(rows, len(res['errors'][exceptions.InvalidParentId.title][error_column_name]['rows']), "All cases should have missing parent") def import_mock_file(self, rows): config = self._config(rows[0]) xls_file = make_worksheet_wrapper(*rows) return do_import(xls_file, config, self.domain) @run_with_all_backends def testLocationOwner(self): # This is actually testing several different things, but I figure it's # worth it, as each of these tests takes a non-trivial amount of time. non_case_sharing = LocationType.objects.create( domain=self.domain, name='lt1', shares_cases=False ) case_sharing = LocationType.objects.create( domain=self.domain, name='lt2', shares_cases=True ) location = make_loc('loc-1', 'Loc 1', self.domain, case_sharing.code) make_loc('loc-2', 'Loc 2', self.domain, case_sharing.code) duplicate_loc = make_loc('loc-3', 'Loc 2', self.domain, case_sharing.code) improper_loc = make_loc('loc-4', 'Loc 4', self.domain, non_case_sharing.code) res = self.import_mock_file([ ['case_id', 'name', 'owner_id', 'owner_name'], ['', 'location-owner-id', location.group_id, ''], ['', 'location-owner-code', '', location.site_code], ['', 'location-owner-name', '', location.name], ['', 'duplicate-location-name', '', duplicate_loc.name], ['', 'non-case-owning-name', '', improper_loc.name], ]) case_ids = self.accessor.get_case_ids_in_domain() cases = {c.name: c for c in list(self.accessor.get_cases(case_ids))} self.assertEqual(cases['location-owner-id'].owner_id, location.group_id) self.assertEqual(cases['location-owner-code'].owner_id, location.group_id) self.assertEqual(cases['location-owner-name'].owner_id, location.group_id) error_message = exceptions.DuplicateLocationName.title error_column_name = None self.assertIn(error_message, res['errors']) self.assertEqual(res['errors'][error_message][error_column_name]['rows'], [5]) error_message = exceptions.InvalidOwnerId.title self.assertIn(error_message, res['errors']) error_column_name = 'owner_id' self.assertEqual(res['errors'][error_message][error_column_name]['rows'], [6]) @run_with_all_backends def test_opened_on(self): case = self.factory.create_case() new_date = '2015-04-30T14:41:53.000000Z' with flag_enabled('BULK_UPLOAD_DATE_OPENED'): self.import_mock_file([ ['case_id', 'date_opened'], [case.case_id, new_date] ]) case = CaseAccessors(self.domain).get_case(case.case_id) self.assertEqual(case.opened_on, PhoneTime(parse_datetime(new_date)).done())
def test_should_sync_flat_format_default_toggle(self): with flag_enabled('FLAT_LOCATION_FIXTURE'): self.assertEqual(True, should_sync_flat_fixture('some-domain'))
def test_wrong_password(self): wrong_credentials = self._get_basic_credentials(self.web_user.username, 'wrong_password') with flag_enabled('ODATA'): response = self._execute_query(wrong_credentials) self.assertEqual(response.status_code, 401)
class ImporterTest(TestCase): def setUp(self): super(ImporterTest, self).setUp() self.domain_obj = create_domain("importer-test") self.domain = self.domain_obj.name self.default_case_type = 'importer-test-casetype' self.couch_user = WebUser.create(None, "test", "foobar", None, None) self.couch_user.add_domain_membership(self.domain, is_admin=True) self.couch_user.save() self.accessor = CaseAccessors(self.domain) self.factory = CaseFactory(domain=self.domain, case_defaults={ 'case_type': self.default_case_type, }) delete_all_cases() def tearDown(self): self.couch_user.delete(deleted_by=None) self.domain_obj.delete() super(ImporterTest, self).tearDown() def _config(self, col_names, search_column=None, case_type=None, search_field='case_id', create_new_cases=True): return ImporterConfig( couch_user_id=self.couch_user._id, case_type=case_type or self.default_case_type, excel_fields=col_names, case_fields=[''] * len(col_names), custom_fields=col_names, search_column=search_column or col_names[0], search_field=search_field, create_new_cases=create_new_cases, ) @run_with_all_backends @patch('corehq.apps.case_importer.tasks.bulk_import_async.update_state') def testImportFileMissing(self, update_state): # by using a made up upload_id, we ensure it's not referencing any real file case_upload = CaseUploadRecord(upload_id=str(uuid.uuid4()), task_id=str(uuid.uuid4())) case_upload.save() res = bulk_import_async.delay(self._config(['anything']), self.domain, case_upload.upload_id) self.assertIsInstance(res.result, Ignore) update_state.assert_called_with( state=states.FAILURE, meta=get_interned_exception( 'Sorry, your session has expired. Please start over and try again.' )) self.assertEqual(0, len(get_case_ids_in_domain(self.domain))) @run_with_all_backends def testImportBasic(self): config = self._config(['case_id', 'age', 'sex', 'location']) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], ['case_id-0', 'age-0', 'sex-0', 'location-0'], ['case_id-1', 'age-1', 'sex-1', 'location-1'], ['case_id-2', 'age-2', 'sex-2', 'location-2'], ['case_id-3', 'age-3', 'sex-3', 'location-3'], ['case_id-4', 'age-4', 'sex-4', 'location-4'], ) res = do_import(file, config, self.domain) self.assertEqual(5, res['created_count']) self.assertEqual(0, res['match_count']) self.assertFalse(res['errors']) self.assertEqual(1, res['num_chunks']) case_ids = self.accessor.get_case_ids_in_domain() cases = list(self.accessor.get_cases(case_ids)) self.assertEqual(5, len(cases)) properties_seen = set() for case in cases: self.assertEqual(self.couch_user._id, case.user_id) self.assertEqual(self.couch_user._id, case.owner_id) self.assertEqual(self.default_case_type, case.type) for prop in ['age', 'sex', 'location']: self.assertTrue(prop in case.get_case_property(prop)) self.assertFalse( case.get_case_property(prop) in properties_seen) properties_seen.add(case.get_case_property(prop)) @run_with_all_backends def testCreateCasesWithDuplicateExternalIds(self): config = self._config( ['case_id', 'age', 'sex', 'location', 'external_id']) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location', 'external_id'], ['case_id-0', 'age-0', 'sex-0', 'location-0', 'external_id-0'], ['case_id-1', 'age-1', 'sex-1', 'location-1', 'external_id-0'], ['case_id-2', 'age-2', 'sex-2', 'location-2', 'external_id-1'], ) res = do_import(file, config, self.domain) self.assertEqual(3, res['created_count']) self.assertEqual(0, res['match_count']) self.assertFalse(res['errors']) case_ids = self.accessor.get_case_ids_in_domain() self.assertItemsEqual( [case.external_id for case in self.accessor.get_cases(case_ids)], ['external_id-0', 'external_id-0', 'external_id-1']) @run_with_all_backends def testImportNamedColumns(self): config = self._config(['case_id', 'age', 'sex', 'location']) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], ['case_id-0', 'age-0', 'sex-0', 'location-0'], ['case_id-1', 'age-1', 'sex-1', 'location-1'], ['case_id-2', 'age-2', 'sex-2', 'location-2'], ['case_id-3', 'age-3', 'sex-3', 'location-3'], ) res = do_import(file, config, self.domain) self.assertEqual(4, res['created_count']) self.assertEqual(4, len(self.accessor.get_case_ids_in_domain())) @run_with_all_backends def testImportTrailingWhitespace(self): cols = ['case_id', 'age', 'sex\xa0', 'location'] config = self._config(cols) file = make_worksheet_wrapper( ['case_id', 'age', 'sex\xa0', 'location'], ['case_id-0', 'age-0', 'sex\xa0-0', 'location-0'], ) res = do_import(file, config, self.domain) self.assertEqual(1, res['created_count']) case_ids = self.accessor.get_case_ids_in_domain() self.assertEqual(1, len(case_ids)) case = self.accessor.get_case(case_ids[0]) self.assertTrue(bool(case.get_case_property( 'sex'))) # make sure the value also got properly set @run_with_all_backends def testCaseIdMatching(self): # bootstrap a stub case [case] = self.factory.create_or_update_case( CaseStructure(attrs={ 'create': True, 'update': { 'importer_test_prop': 'foo' }, })) self.assertEqual(1, len(self.accessor.get_case_ids_in_domain())) config = self._config(['case_id', 'age', 'sex', 'location']) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], [case.case_id, 'age-0', 'sex-0', 'location-0'], [case.case_id, 'age-1', 'sex-1', 'location-1'], [case.case_id, 'age-2', 'sex-2', 'location-2'], ) res = do_import(file, config, self.domain) self.assertEqual(0, res['created_count']) self.assertEqual(3, res['match_count']) self.assertFalse(res['errors']) # shouldn't create any more cases, just the one case_ids = self.accessor.get_case_ids_in_domain() self.assertEqual(1, len(case_ids)) [case] = self.accessor.get_cases(case_ids) for prop in ['age', 'sex', 'location']: self.assertTrue(prop in case.get_case_property(prop)) # shouldn't touch existing properties self.assertEqual('foo', case.get_case_property('importer_test_prop')) @run_with_all_backends def testCaseLookupTypeCheck(self): [case] = self.factory.create_or_update_case( CaseStructure(attrs={ 'create': True, 'case_type': 'nonmatch-type', })) self.assertEqual(1, len(self.accessor.get_case_ids_in_domain())) config = self._config(['case_id', 'age', 'sex', 'location']) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], [case.case_id, 'age-0', 'sex-0', 'location-0'], [case.case_id, 'age-1', 'sex-1', 'location-1'], [case.case_id, 'age-2', 'sex-2', 'location-2'], ) res = do_import(file, config, self.domain) # because the type is wrong these shouldn't match self.assertEqual(3, res['created_count']) self.assertEqual(0, res['match_count']) self.assertEqual(4, len(self.accessor.get_case_ids_in_domain())) @run_with_all_backends def testCaseLookupDomainCheck(self): self.factory.domain = 'wrong-domain' [case] = self.factory.create_or_update_case( CaseStructure(attrs={ 'create': True, })) self.assertEqual(0, len(self.accessor.get_case_ids_in_domain())) config = self._config(['case_id', 'age', 'sex', 'location']) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], [case.case_id, 'age-0', 'sex-0', 'location-0'], [case.case_id, 'age-1', 'sex-1', 'location-1'], [case.case_id, 'age-2', 'sex-2', 'location-2'], ) res = do_import(file, config, self.domain) # because the domain is wrong these shouldn't match self.assertEqual(3, res['created_count']) self.assertEqual(0, res['match_count']) self.assertEqual(3, len(self.accessor.get_case_ids_in_domain())) @run_with_all_backends def testExternalIdMatching(self): # bootstrap a stub case external_id = 'importer-test-external-id' [case] = self.factory.create_or_update_case( CaseStructure(attrs={ 'create': True, 'external_id': external_id, })) self.assertEqual(1, len(self.accessor.get_case_ids_in_domain())) headers = ['external_id', 'age', 'sex', 'location'] config = self._config(headers, search_field='external_id') file = make_worksheet_wrapper( ['external_id', 'age', 'sex', 'location'], ['importer-test-external-id', 'age-0', 'sex-0', 'location-0'], ['importer-test-external-id', 'age-1', 'sex-1', 'location-1'], ['importer-test-external-id', 'age-2', 'sex-2', 'location-2'], ) res = do_import(file, config, self.domain) self.assertEqual(0, res['created_count']) self.assertEqual(3, res['match_count']) self.assertFalse(res['errors']) # shouldn't create any more cases, just the one self.assertEqual(1, len(self.accessor.get_case_ids_in_domain())) @run_with_all_backends def test_external_id_matching_on_create_with_custom_column_name(self): headers = ['id_column', 'age', 'sex', 'location'] external_id = 'external-id-test' config = self._config(headers[1:], search_column='id_column', search_field='external_id') file = make_worksheet_wrapper( ['id_column', 'age', 'sex', 'location'], ['external-id-test', 'age-0', 'sex-0', 'location-0'], ['external-id-test', 'age-1', 'sex-1', 'location-1'], ) res = do_import(file, config, self.domain) self.assertFalse(res['errors']) self.assertEqual(1, res['created_count']) self.assertEqual(1, res['match_count']) case_ids = self.accessor.get_case_ids_in_domain() self.assertEqual(1, len(case_ids)) case = self.accessor.get_case(case_ids[0]) self.assertEqual(external_id, case.external_id) def testNoCreateNew(self): config = self._config(['case_id', 'age', 'sex', 'location'], create_new_cases=False) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], ['case_id-0', 'age-0', 'sex-0', 'location-0'], ['case_id-1', 'age-1', 'sex-1', 'location-1'], ['case_id-2', 'age-2', 'sex-2', 'location-2'], ['case_id-3', 'age-3', 'sex-3', 'location-3'], ['case_id-4', 'age-4', 'sex-4', 'location-4'], ) res = do_import(file, config, self.domain) # no matching and no create new set - should do nothing self.assertEqual(0, res['created_count']) self.assertEqual(0, res['match_count']) self.assertEqual(0, len(get_case_ids_in_domain(self.domain))) def testBlankRows(self): # don't create new cases for rows left blank config = self._config(['case_id', 'age', 'sex', 'location'], create_new_cases=True) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], [None, None, None, None], ['', '', '', ''], ) res = do_import(file, config, self.domain) # no matching and no create new set - should do nothing self.assertEqual(0, res['created_count']) self.assertEqual(0, res['match_count']) self.assertEqual(0, len(get_case_ids_in_domain(self.domain))) @patch('corehq.apps.case_importer.do_import.CASEBLOCK_CHUNKSIZE', 2) def testBasicChunking(self): config = self._config(['case_id', 'age', 'sex', 'location']) file = make_worksheet_wrapper( ['case_id', 'age', 'sex', 'location'], ['case_id-0', 'age-0', 'sex-0', 'location-0'], ['case_id-1', 'age-1', 'sex-1', 'location-1'], ['case_id-2', 'age-2', 'sex-2', 'location-2'], ['case_id-3', 'age-3', 'sex-3', 'location-3'], ['case_id-4', 'age-4', 'sex-4', 'location-4'], ) res = do_import(file, config, self.domain) # 5 cases in chunks of 2 = 3 chunks self.assertEqual(3, res['num_chunks']) self.assertEqual(5, res['created_count']) self.assertEqual(5, len(get_case_ids_in_domain(self.domain))) @run_with_all_backends def testExternalIdChunking(self): # bootstrap a stub case external_id = 'importer-test-external-id' headers = ['external_id', 'age', 'sex', 'location'] config = self._config(headers, search_field='external_id') file = make_worksheet_wrapper( ['external_id', 'age', 'sex', 'location'], ['importer-test-external-id', 'age-0', 'sex-0', 'location-0'], ['importer-test-external-id', 'age-1', 'sex-1', 'location-1'], ['importer-test-external-id', 'age-2', 'sex-2', 'location-2'], ) # the first one should create the case, and the remaining two should update it res = do_import(file, config, self.domain) self.assertEqual(1, res['created_count']) self.assertEqual(2, res['match_count']) self.assertFalse(res['errors']) self.assertEqual(2, res['num_chunks']) # the lookup causes an extra chunk # should just create the one case case_ids = self.accessor.get_case_ids_in_domain() self.assertEqual(1, len(case_ids)) [case] = self.accessor.get_cases(case_ids) self.assertEqual(external_id, case.external_id) for prop in ['age', 'sex', 'location']: self.assertTrue(prop in case.get_case_property(prop)) @run_with_all_backends def testParentCase(self): headers = ['parent_id', 'name', 'case_id'] config = self._config(headers, create_new_cases=True, search_column='case_id') rows = 3 [parent_case] = self.factory.create_or_update_case( CaseStructure(attrs={'create': True})) self.assertEqual(1, len(self.accessor.get_case_ids_in_domain())) file = make_worksheet_wrapper( ['parent_id', 'name', 'case_id'], [parent_case.case_id, 'name-0', 'case_id-0'], [parent_case.case_id, 'name-1', 'case_id-1'], [parent_case.case_id, 'name-2', 'case_id-2'], ) # Should successfully match on `rows` cases res = do_import(file, config, self.domain) self.assertEqual(rows, res['created_count']) # Should create child cases self.assertEqual( len(self.accessor.get_reverse_indexed_cases([parent_case.case_id ])), 3) self.assertEqual( self.accessor.get_extension_case_ids([parent_case.case_id]), []) file_missing = make_worksheet_wrapper( ['parent_id', 'name', 'case_id'], ['parent_id-0', 'name-0', 'case_id-0'], ['parent_id-1', 'name-1', 'case_id-1'], ['parent_id-2', 'name-2', 'case_id-2'], ) # Should be unable to find parent case on `rows` cases res = do_import(file_missing, config, self.domain) error_column_name = 'parent_id' self.assertEqual( rows, len(res['errors'][exceptions.InvalidParentId.title] [error_column_name]['rows']), "All cases should have missing parent") @run_with_all_backends def testExtensionCase(self): headers = [ 'parent_id', 'name', 'case_id', 'parent_relationship_type', 'parent_identifier' ] config = self._config(headers, create_new_cases=True, search_column='case_id') [parent_case] = self.factory.create_or_update_case( CaseStructure(attrs={'create': True})) self.assertEqual(1, len(self.accessor.get_case_ids_in_domain())) file = make_worksheet_wrapper( headers, [parent_case.case_id, 'name-0', 'case_id-0', 'extension', 'host'], [ parent_case.case_id, 'name-1', 'case_id-1', 'extension', 'mother' ], [parent_case.case_id, 'name-2', 'case_id-2', 'child', 'parent'], ) # Should successfully match on `rows` cases res = do_import(file, config, self.domain) self.assertEqual(res['created_count'], 3) # Of the 3, 2 should be extension cases extension_case_ids = self.accessor.get_extension_case_ids( [parent_case.case_id]) self.assertEqual(len(extension_case_ids), 2) extension_cases = self.accessor.get_cases(extension_case_ids) # Check that identifier is set correctly self.assertEqual({'host', 'mother'}, {c.indices[0].identifier for c in extension_cases}) # This test will only run on SQL backend because of a bug in couch backend # that overrides current domain with the 'domain' column value from excel @override_settings(TESTS_SHOULD_USE_SQL_BACKEND=True) @flag_enabled('DOMAIN_PERMISSIONS_MIRROR') def test_multiple_domain_case_import(self): mirror_domain1 = DomainPermissionsMirror(source=self.domain, mirror='mirrordomain1') mirror_domain2 = DomainPermissionsMirror(source=self.domain, mirror='mirrordomain2') mirror_domain1.save() mirror_domain2.save() headers_with_domain = ['case_id', 'name', 'artist', 'domain'] config_1 = self._config(headers_with_domain, create_new_cases=True, search_column='case_id') case_with_domain_file = make_worksheet_wrapper( ['case_id', 'name', 'artist', 'domain'], ['', 'name-0', 'artist-0', self.domain], ['', 'name-1', 'artist-1', mirror_domain1.mirror], ['', 'name-2', 'artist-2', mirror_domain2.mirror], ['', 'name-3', 'artist-3', self.domain], ['', 'name-4', 'artist-4', self.domain], ['', 'name-5', 'artist-5', 'not-existing-domain']) res = do_import(case_with_domain_file, config_1, self.domain) self.assertEqual(5, res['created_count']) self.assertEqual(0, res['match_count']) self.assertEqual(1, res['failed_count']) # Asserting current domain cur_case_ids = self.accessor.get_case_ids_in_domain() cur_cases = list(self.accessor.get_cases(cur_case_ids)) self.assertEqual(3, len(cur_cases)) #Asserting current domain case property cases = {c.name: c for c in cur_cases} self.assertEqual(cases['name-0'].get_case_property('artist'), 'artist-0') # Asserting mirror domain 1 md1_case_ids = CaseAccessors( mirror_domain1.mirror).get_case_ids_in_domain() md1_cases = list(self.accessor.get_cases(md1_case_ids)) self.assertEqual(1, len(md1_cases)) # Asserting mirror domain 1 case property md1_cases_pro = {c.name: c for c in md1_cases} self.assertEqual(md1_cases_pro['name-1'].get_case_property('artist'), 'artist-1') # Asserting mirror domain 2 md2_case_ids = CaseAccessors( mirror_domain2.mirror).get_case_ids_in_domain() md2_cases = list(self.accessor.get_cases(md2_case_ids)) self.assertEqual(1, len(md2_cases)) # Asserting mirror domain 2 case propperty md2_cases_pro = {c.name: c for c in md2_cases} self.assertEqual(md2_cases_pro['name-2'].get_case_property('artist'), 'artist-2') # This test will only run on SQL backend because of a bug in couch backend # that overrides current domain with the 'domain' column value from excel @override_settings(TESTS_SHOULD_USE_SQL_BACKEND=True) @flag_disabled('DOMAIN_PERMISSIONS_MIRROR') def test_multiple_domain_case_import_mirror_domain_disabled(self): headers_with_domain = ['case_id', 'name', 'artist', 'domain'] config_1 = self._config(headers_with_domain, create_new_cases=True, search_column='case_id') case_with_domain_file = make_worksheet_wrapper( ['case_id', 'name', 'artist', 'domain'], ['', 'name-0', 'artist-0', self.domain], ['', 'name-1', 'artist-1', 'domain-1'], ['', 'name-2', 'artist-2', 'domain-2'], ['', 'name-3', 'artist-3', self.domain], ['', 'name-4', 'artist-4', self.domain], ['', 'name-5', 'artist-5', 'not-existing-domain']) res = do_import(case_with_domain_file, config_1, self.domain) self.assertEqual(6, res['created_count']) self.assertEqual(0, res['match_count']) self.assertEqual(0, res['failed_count']) case_ids = self.accessor.get_case_ids_in_domain() # Asserting current domain cur_cases = list(self.accessor.get_cases(case_ids)) self.assertEqual(6, len(cur_cases)) #Asserting domain case property cases = {c.name: c for c in cur_cases} self.assertEqual(cases['name-0'].get_case_property('domain'), self.domain) def import_mock_file(self, rows): config = self._config(rows[0]) xls_file = make_worksheet_wrapper(*rows) return do_import(xls_file, config, self.domain) @run_with_all_backends def testLocationOwner(self): # This is actually testing several different things, but I figure it's # worth it, as each of these tests takes a non-trivial amount of time. non_case_sharing = LocationType.objects.create(domain=self.domain, name='lt1', shares_cases=False) case_sharing = LocationType.objects.create(domain=self.domain, name='lt2', shares_cases=True) location = make_loc('loc-1', 'Loc 1', self.domain, case_sharing.code) make_loc('loc-2', 'Loc 2', self.domain, case_sharing.code) duplicate_loc = make_loc('loc-3', 'Loc 2', self.domain, case_sharing.code) improper_loc = make_loc('loc-4', 'Loc 4', self.domain, non_case_sharing.code) res = self.import_mock_file([ ['case_id', 'name', 'owner_id', 'owner_name'], ['', 'location-owner-id', location.location_id, ''], ['', 'location-owner-code', '', location.site_code], ['', 'location-owner-name', '', location.name], ['', 'duplicate-location-name', '', duplicate_loc.name], ['', 'non-case-owning-name', '', improper_loc.name], ]) case_ids = self.accessor.get_case_ids_in_domain() cases = {c.name: c for c in list(self.accessor.get_cases(case_ids))} self.assertEqual(cases['location-owner-id'].owner_id, location.location_id) self.assertEqual(cases['location-owner-code'].owner_id, location.location_id) self.assertEqual(cases['location-owner-name'].owner_id, location.location_id) error_message = exceptions.DuplicateLocationName.title error_column_name = None self.assertIn(error_message, res['errors']) self.assertEqual( res['errors'][error_message][error_column_name]['rows'], [5]) error_message = exceptions.InvalidOwner.title self.assertIn(error_message, res['errors']) error_column_name = 'owner_name' self.assertEqual( res['errors'][error_message][error_column_name]['rows'], [6]) @run_with_all_backends def test_opened_on(self): case = self.factory.create_case() new_date = '2015-04-30T14:41:53.000000Z' with flag_enabled('BULK_UPLOAD_DATE_OPENED'): self.import_mock_file([['case_id', 'date_opened'], [case.case_id, new_date]]) case = CaseAccessors(self.domain).get_case(case.case_id) self.assertEqual(case.opened_on, PhoneTime(parse_datetime(new_date)).done())
class APIResourceTest(TestCase, metaclass=PatchMeta): """ Base class for shared API tests. Sets up a domain and user and provides some helper methods and properties for accessing the API """ patch = flag_enabled('API_THROTTLE_WHITELIST') resource = None # must be set by subclasses api_name = 'v0.4' # can be overridden by subclasses maxDiff = None @classmethod def setUpClass(cls): super(APIResourceTest, cls).setUpClass() Role.get_cache().clear() cls.domain = Domain.get_or_create_with_name('qwerty', is_active=True) cls.list_endpoint = cls._get_list_endpoint() cls.username = '******' cls.password = '******' cls.user = WebUser.create(cls.domain.name, cls.username, cls.password, None, None) cls.user.set_role(cls.domain.name, 'admin') cls.user.save() cls.account = BillingAccount.get_or_create_account_by_domain( cls.domain.name, created_by="automated-test")[0] plan = DefaultProductPlan.get_default_plan_version( edition=SoftwarePlanEdition.ADVANCED) cls.subscription = Subscription.new_domain_subscription( cls.account, cls.domain.name, plan) cls.subscription.is_active = True cls.subscription.save() cls.api_key, _ = HQApiKey.objects.get_or_create( user=WebUser.get_django_user(cls.user)) @classmethod def _get_list_endpoint(cls): return reverse('api_dispatch_list', kwargs=dict( domain=cls.domain.name, api_name=cls.api_name, resource_name=cls.resource._meta.resource_name)) @classmethod def tearDownClass(cls): cls.api_key.delete() cls.user.delete(deleted_by=None) for domain in Domain.get_all(): Subscription._get_active_subscription_by_domain.clear( Subscription, domain.name) domain.delete() super(APIResourceTest, cls).tearDownClass() def single_endpoint(self, id): return reverse('api_dispatch_detail', kwargs=dict( domain=self.domain.name, api_name=self.api_name, resource_name=self.resource._meta.resource_name, pk=id)) def _api_url(self, url, username=None): if 'api_key' in url: return url username = username or self.username api_key = self.api_key.key if username != self.username: web_user = WebUser.get_by_username(username) api_key, _ = HQApiKey.objects.get_or_create( user=WebUser.get_django_user(web_user)) api_key = api_key.key api_params = urlencode({'username': username, 'api_key': api_key}) if "?" in url: api_url = "%s&%s" % (url, api_params) else: api_url = "%s?%s" % (url, api_params) return api_url def _assert_auth_get_resource(self, url, username=None, password=None, failure_code=401, headers=None): """ This tests that the given URL fails when accessed via sessions and returns the response obtained via using API auth. It's callers' responsibility to test resource specific logic using response returned. The user authentication is attempted via default self.username creds, other creds can be passed via username and password kwargs """ username = username or self.username password = password or self.password headers = headers or {} # session based auth should fail self.client.login(username=username, password=password) response = self.client.get(url, **headers) self.assertEqual(response.status_code, failure_code) # api_key auth should succeed, caller can check for expected code api_url = self._api_url(url, username) response = self.client.get(api_url, **headers) return response def _assert_auth_post_resource(self, url, post_data, content_type='application/json', method="POST", failure_code=401): """ See docstring for _assert_auth_get_resource() """ # session based auth should fail self.client.login(username=self.username, password=self.password) if method == "POST": response = self.client.post(url, post_data, content_type=content_type) elif method == "PUT": response = self.client.put(url, post_data, content_type=content_type) elif method == "DELETE": response = self.client.delete(url, post_data, content_type=content_type) self.assertEqual(response.status_code, failure_code) # api_key auth should succeed, caller should check expected response status and content api_url = self._api_url(url) if method == "POST": response = self.client.post(api_url, post_data, content_type=content_type) elif method == "PUT": response = self.client.put(api_url, post_data, content_type=content_type) elif method == "DELETE": response = self.client.delete(api_url, post_data, content_type=content_type) return response
def test_no_credentials(self): with flag_enabled('ODATA'): response = self.client.get(self.view_url) self.assertEqual(response.status_code, 401)
def test_success_with_two_factor_api_key(self): with flag_enabled('TWO_FACTOR_SUPERUSER_ROLLOUT'): self.test_success_with_api_key()
def test_should_sync_flat_format_disabled_toggle(self): location_settings = LocationFixtureConfiguration.objects.create( domain='some-domain', sync_flat_fixture=False) self.addCleanup(location_settings.delete) with flag_enabled('FLAT_LOCATION_FIXTURE'): self.assertEqual(False, should_sync_flat_fixture('some-domain'))
def test_case_list_form_followup_form(self, *args): # * Register house (case type = house, basic) # * Register house form # * Register person (case type = person, parent select = 'Register house', advanced) # * Register person form # * Manager person (case type = person, case list form = 'Register person form', basic) # * Manage person form factory = AppFactory(build_version='2.9.0') register_house_module, register_house_form = factory.new_basic_module( 'register_house', 'house') factory.form_opens_case(register_house_form) register_person_module, register_person_form = factory.new_advanced_module( 'register_person', 'person') factory.form_requires_case(register_person_form, 'house') factory.form_opens_case(register_person_form, 'person', is_subcase=True) house_module, update_house_form = factory.new_advanced_module( 'update_house', 'house', ) factory.form_requires_case(update_house_form) person_module, update_person_form = factory.new_basic_module( 'update_person', 'person', case_list_form=update_house_form) factory.form_requires_case(update_person_form) def _assert_app_build_error(error): errors = factory.app.validate_app() self.assertIn( (error, person_module.unique_id), [(e["type"], e.get("module", {}).get("unique_id", {})) for e in errors]) self.assertXmlPartialEqual("<partial></partial>", factory.app.create_suite(), "./detail[@id='m3_case_short']/action") # should fail since feature flag isn't enabled _assert_app_build_error('case list form not registration') with flag_enabled('FOLLOWUP_FORMS_AS_CASE_LIST_FORM'): # should fail since module doesn't have active parent_select _assert_app_build_error("invalid case list followup form") person_module.parent_select.active = True person_module.parent_select.module_id = register_house_module.unique_id person_module.case_list_form.relevancy_expression = "count(instance('casedb')/casedb/case) != 0" errors = factory.app.validate_app() self.assertNotIn( ('case list form not registration', person_module.unique_id), [(e["type"], e.get("module", {}).get("unique_id", {})) for e in errors]) xml = """ <partial> <action relevant="count(instance('casedb')/casedb/case) != 0"> <display> <text><locale id="case_list_form.m3"/></text> </display> <stack> <push> <command value="'m2-f0'"/> <datum id="case_id_load_house_0" value="instance('commcaresession')/session/data/parent_id"/> <datum id="return_to" value="'m3'"/> </push> </stack> </action> </partial> """ self.assertXmlPartialEqual(xml, factory.app.create_suite(), "./detail[@id='m3_case_short']/action") person_module.parent_select.active = False
def test_request_succeeded(self): correct_credentials = self._get_correct_credentials() with flag_enabled('ODATA'): response = self._execute_query(correct_credentials) self.assertEqual(response.status_code, 200)
def test_modules_case_search_app_strings(self): factory = AppFactory(build_version='2.40.0') factory.app.langs = ['en', 'es'] factory.app.build_profiles = OrderedDict({ 'en': BuildProfile(langs=['en'], name='en-profile'), 'es': BuildProfile(langs=['es'], name='es-profile'), }) module, form = factory.new_basic_module('my_module', 'cases') module.search_config = CaseSearch( search_label=CaseSearchLabel( label={ 'en': 'Get them', 'es': 'Conseguirlos' }, media_image={ 'en': "jr://file/commcare/image/1.png", 'es': "jr://file/commcare/image/1_es.png" }, media_audio={'en': "jr://file/commcare/image/2.mp3"}), search_again_label=CaseSearchAgainLabel( label={'en': 'Get them all'}), properties=[CaseSearchProperty(name="name", label={'en': 'Name'})]) # wrap to have assign_references called app = Application.wrap(factory.app.to_json()) with flag_disabled('USH_CASE_CLAIM_UPDATES'): # default language self.assertEqual(app.default_language, 'en') en_app_strings = self._generate_app_strings(app, 'default', build_profile_id='en') self.assertEqual(en_app_strings['case_search.m0'], 'Search All Cases') self.assertEqual(en_app_strings['case_search.m0.again'], 'Search Again') self.assertFalse('case_search.m0.icon' in en_app_strings) self.assertFalse('case_search.m0.audio' in en_app_strings) # non-default language es_app_strings = self._generate_app_strings(app, 'es', build_profile_id='es') self.assertEqual(es_app_strings['case_search.m0'], 'Search All Cases') self.assertEqual(es_app_strings['case_search.m0.again'], 'Search Again') with flag_enabled('USH_CASE_CLAIM_UPDATES'): # default language en_app_strings = self._generate_app_strings(app, 'default', build_profile_id='en') self.assertEqual(en_app_strings['case_search.m0'], 'Get them') self.assertEqual(en_app_strings['case_search.m0.icon'], 'jr://file/commcare/image/1.png') self.assertEqual(en_app_strings['case_search.m0.audio'], 'jr://file/commcare/image/2.mp3') self.assertEqual(en_app_strings['case_search.m0.again'], 'Get them all') # non-default language es_app_strings = self._generate_app_strings(app, 'es', build_profile_id='es') self.assertEqual(es_app_strings['case_search.m0'], 'Conseguirlos') self.assertEqual(es_app_strings['case_search.m0.icon'], 'jr://file/commcare/image/1_es.png') self.assertEqual(es_app_strings['case_search.m0.again'], 'Get them all')
def contractor(): with domain_admin(), flag_enabled('IS_CONTRACTOR'): yield