def test_user_data_profile(self): definition = CustomDataFieldsDefinition( domain='cloudcare-tests', field_type=UserFieldsView.field_type) definition.save() definition.set_fields([ Field(slug='word', label='A Word'), ]) definition.save() self.addCleanup(definition.delete) profile = CustomDataFieldsProfile(name='prof', fields={'word': 'supernova'}, definition=definition) profile.save() user = CommCareUser.create( 'cloudcare-tests', '*****@*****.**', 'do you want to know a secret', None, None, uuid=uuid.uuid4().hex, metadata={PROFILE_SLUG: profile.id}, ) self.addCleanup(user.delete, None, None) user_data = get_user_contributions_to_touchforms_session( 'cloudcare-tests', user)['user_data'] self.assertEqual(profile.id, user_data[PROFILE_SLUG]) self.assertEqual('supernova', user_data['word'])
def test_sync_custom_user_data(self): definition = CustomDataFieldsDefinition( domain=TEST_DOMAIN, field_type=UserFieldsView.field_type) definition.save() definition.set_fields([ Field(slug='from_profile', label='From Profile'), ]) definition.save() profile = CustomDataFieldsProfile( name='callcenter_profile', fields={'from_profile': 'yes'}, definition=definition, ) profile.save() self.user.update_metadata({ '': 'blank_key', 'blank_val': '', 'ok': 'good', 'name with spaces': 'ok', '8starts_with_a_number': '0', 'xml_starts_with_xml': '0', '._starts_with_punctuation': '0', PROFILE_SLUG: profile.id, }) sync_call_center_user_case(self.user) case = self._get_user_case() self.assertIsNotNone(case) self.assertEqual(case.get_case_property('blank_val'), '') self.assertEqual(case.get_case_property('ok'), 'good') self.assertEqual(case.get_case_property(PROFILE_SLUG), str(profile.id)) self.assertEqual(case.get_case_property('from_profile'), 'yes') self.user.pop_metadata(PROFILE_SLUG) definition.delete()
def setUpClass(cls): super().setUpClass() cls.domain = 'user-esaccessors-test' cls.definition = CustomDataFieldsDefinition(domain=cls.domain, field_type=UserFieldsView.field_type) cls.definition.save() cls.definition.set_fields([ Field(slug='job', label='Job'), ]) cls.definition.save() cls.profile = CustomDataFieldsProfile( name='daily_planet_staff', fields={'job': 'reporter'}, definition=cls.definition, ) cls.profile.save() cls.user = CommCareUser.create( cls.domain, 'superman', 'secret agent man', None, None, first_name='clark', last_name='kent', is_active=True, metadata={PROFILE_SLUG: cls.profile.id, 'office': 'phone_booth'}, ) cls.user.save()
def update_custom_data_models(domain_link, limit_types=None): if domain_link.is_remote: master_results = remote_custom_data_models(domain_link, limit_types) else: master_results = local_custom_data_models(domain_link.master_domain, limit_types) for field_type, data in master_results.items(): field_definitions = data.get('fields', []) model = CustomDataFieldsDefinition.get_or_create(domain_link.linked_domain, field_type) model.set_fields([ Field( slug=field_def['slug'], is_required=field_def['is_required'], label=field_def['label'], choices=field_def['choices'], regex=field_def['regex'], regex_msg=field_def['regex_msg'], ) for field_def in field_definitions ]) model.save() old_profiles = {profile.name: profile for profile in model.get_profiles()} for profile in data.get('profiles'): old_profile = old_profiles.get(profile['name'], None) if old_profile: old_profile.fields = profile['fields'] old_profile.save() else: CustomDataFieldsProfile( name=profile['name'], definition=model, fields=profile['fields'], ).save()
def test_update(self): # Initial update of linked domain update_custom_data_models(self.domain_link, limit_types=[UserFieldsView.field_type]) model = CustomDataFieldsDefinition.objects.get( domain=self.linked_domain, field_type=UserFieldsView.field_type) fields = model.get_fields() self.assertEqual(fields[0].slug, "has_legs") self.assertEqual(fields[0].label, "Has legs") self.assertEqual(fields[0].choices, ["yes", "no"]) self.assertEqual(fields[1].slug, "can_swim") self.assertEqual(fields[2].slug, "color") profiles_by_name = {p.name: p for p in model.get_profiles()} self.assertEqual(profiles_by_name[self.coral_profile.name].fields, self.coral_profile.fields) self.assertEqual(profiles_by_name[self.fish_profile.name].fields, self.fish_profile.fields) # Add, update, and remove a profile lamprey_profile = CustomDataFieldsProfile( name='Lamprey', fields={ 'has_legs': 'no', 'can_swim': 'yes' }, definition=self.definition, ) lamprey_profile.save() self.fish_profile.fields = { 'has_legs': 'no', 'can_swim': 'no', } self.fish_profile.save() self.coral_profile.delete() update_custom_data_models(self.domain_link, limit_types=[UserFieldsView.field_type]) model = CustomDataFieldsDefinition.objects.get( domain=self.linked_domain, field_type=UserFieldsView.field_type) profiles_by_name = {p.name: p for p in model.get_profiles()} self.assertTrue(bool(profiles_by_name[ self.coral_profile.name])) # updating doesn't delete profiles self.assertEqual(profiles_by_name[self.fish_profile.name].fields, self.fish_profile.fields) self.assertEqual(profiles_by_name[lamprey_profile.name].fields, lamprey_profile.fields)
def setUpClass(cls): super().setUpClass() cls.domain = 'a-domain' cls.definition = CustomDataFieldsDefinition( domain=cls.domain, field_type=UserFieldsView.field_type) cls.definition.save() cls.definition.set_fields([ Field( slug='corners', is_required=True, label='Number of corners', regex='^[0-9]+$', regex_msg='This should be a number', ), Field( slug='prefix', is_required=False, label='Prefix', choices=['tri', 'tetra', 'penta'], ), Field( slug='color', is_required=False, label='Color', ), ]) cls.definition.save() cls.profile3 = CustomDataFieldsProfile( name='three', fields={ 'corners': 3, 'prefix': 'tri' }, definition=cls.definition, ) cls.profile3.save() cls.profile5 = CustomDataFieldsProfile( name='five', fields={ 'corners': 5, 'prefix': 'penta' }, definition=cls.definition, ) cls.profile5.save()
def _setup_profile(self): definition = CustomDataFieldsDefinition( domain=self.domain, field_type=UserFieldsView.field_type) definition.save() definition.set_fields([ Field( slug='conflicting_field', label='Conflicting Field', choices=['yes', 'no'], ), ]) definition.save() profile = CustomDataFieldsProfile( name='character', fields={'conflicting_field': 'yes'}, definition=definition, ) profile.save() return profile.id
def setUpClass(cls): super().setUpClass() cls.definition = CustomDataFieldsDefinition( domain=cls.domain, field_type=UserFieldsView.field_type) cls.definition.save() cls.definition.set_fields([ Field( slug='has_legs', label='Has legs', choices=['yes', 'no'], ), Field( slug='can_swim', label='Can swim', choices=['yes', 'no'], ), Field( slug='color', label='Color', ), ]) cls.definition.save() cls.coral_profile = CustomDataFieldsProfile( name='Coral', fields={ 'has_legs': 'no', 'can_swim': 'no' }, definition=cls.definition, ) cls.coral_profile.save() cls.fish_profile = CustomDataFieldsProfile( name='Fish', fields={ 'has_legs': 'no', 'can_swim': 'yes' }, definition=cls.definition, ) cls.fish_profile.save()
def setUpClass(cls): super().setUpClass() cls.domain_obj = create_domain(cls.domain) # APP_USER_PROFILES is on ENTERPRISE and above cls.setup_subscription(cls.domain, SoftwarePlanEdition.ENTERPRISE) cls.group_memoizer = GroupMemoizer(domain=cls.domain_obj.name) cls.group_memoizer.load_all() cls.definition = CustomDataFieldsDefinition( domain=cls.domain_obj.name, field_type=UserFieldsView.field_type) cls.definition.save() cls.definition.set_fields([ Field( slug='born', label='Year of Birth', ), Field( slug='_type', label='Type', choices=['fiction', 'non-fiction'], ), ]) cls.definition.save() cls.profile = CustomDataFieldsProfile( name='Novelist', fields={'_type': 'fiction'}, definition=cls.definition, ) cls.profile.save() cls.user1 = CommCareUser.create(cls.domain_obj.name, 'edith', 'badpassword', None, None, first_name='Edith', last_name='Wharton', metadata={'born': 1862}) cls.user2 = CommCareUser.create( cls.domain_obj.name, 'george', 'anotherbadpassword', None, None, first_name='George', last_name='Eliot', metadata={ 'born': 1849, PROFILE_SLUG: cls.profile.id }, )
def setUpClass(cls): super().setUpClass() delete_all_users() cls.domain_name = 'mydomain' cls.domain = Domain.get_or_create_with_name(name=cls.domain_name) cls.other_domain = Domain.get_or_create_with_name(name='other-domain') cls.uploading_user = WebUser.create(cls.domain_name, "*****@*****.**", 'password', None, None, is_superuser=True) permissions = Permissions(edit_apps=True, view_apps=True, view_reports=True) cls.role = UserRole.get_or_create_with_permissions( cls.domain.name, permissions, 'edit-apps') cls.other_role = UserRole.get_or_create_with_permissions( cls.domain.name, permissions, 'admin') cls.patcher = patch('corehq.apps.user_importer.tasks.UserUploadRecord') cls.patcher.start() cls.definition = CustomDataFieldsDefinition( domain=cls.domain_name, field_type=UserFieldsView.field_type) cls.definition.save() cls.definition.set_fields([ Field( slug='key', is_required=False, label='Key', regex='^[A-G]', regex_msg='Starts with A-G', ), Field(slug='mode', is_required=False, label='Mode', choices=['major', 'minor']), ]) cls.definition.save() cls.profile = CustomDataFieldsProfile( name='melancholy', fields={'mode': 'minor'}, definition=cls.definition, ) cls.profile.save()
def setUpClass(cls): reset_es_index(USER_INDEX_INFO) super().setUpClass() cls.definition = CustomDataFieldsDefinition( domain=cls.domain.name, field_type=UserFieldsView.field_type) cls.definition.save() cls.definition.set_fields([ Field( slug='imaginary', label='Imaginary Person', choices=['yes', 'no'], ), ]) cls.definition.save() cls.profile = CustomDataFieldsProfile( name='character', fields={'imaginary': 'yes'}, definition=cls.definition, ) cls.profile.save()
def setUpClass(cls): super().setUpClass() cls.domain = 'test-domain' cls.domain_obj = create_domain(cls.domain) cls.addClassCleanup(cls.domain_obj.delete) cls.definition = CustomDataFieldsDefinition( domain=cls.domain, field_type=UserFieldsView.field_type) cls.definition.save() cls.definition.set_fields([ Field( slug='conflicting_field', label='Conflicting Field', choices=['yes', 'no'], ), ]) cls.definition.save() cls.profile = CustomDataFieldsProfile( name='character', fields={'conflicting_field': 'yes'}, definition=cls.definition, ) cls.profile.save()
def test_metadata_with_profile(self): definition = CustomDataFieldsDefinition( domain='my-domain', field_type=UserFieldsView.field_type) definition.save() definition.set_fields([Field(slug='start')]) definition.save() profile = CustomDataFieldsProfile( name='low', fields={'start': 'sometimes'}, definition=definition, ) profile.save() conflict_message = "metadata properties conflict with profile: start" # Custom user data profiles get their data added to metadata automatically for mobile users self.user.update_metadata({PROFILE_SLUG: profile.id}) self.assertEqual( self.user.metadata, { 'commcare_project': 'my-domain', PROFILE_SLUG: profile.id, 'start': 'sometimes', }) # Remove profile should remove it and related fields self.user.pop_metadata(PROFILE_SLUG) self.assertEqual(self.user.metadata, { 'commcare_project': 'my-domain', }) # Can't add profile that conflicts with existing data self.user.update_metadata({ 'start': 'never', 'end': 'yesterday', }) with self.assertRaisesMessage(ValueError, conflict_message): self.user.update_metadata({ PROFILE_SLUG: profile.id, }) # Can't add data that conflicts with existing profile self.user.pop_metadata('start') self.user.update_metadata({PROFILE_SLUG: profile.id}) with self.assertRaisesMessage(ValueError, conflict_message): self.user.update_metadata({'start': 'never'}) # Can't add both a profile and conflicting data self.user.pop_metadata(PROFILE_SLUG) with self.assertRaisesMessage(ValueError, conflict_message): self.user.update_metadata({ PROFILE_SLUG: profile.id, 'start': 'never', }) # Custom user data profiles don't get populated for web users web_user = WebUser.create(None, "imogen", "*****", None, None) self.assertEqual(web_user.metadata, { 'commcare_project': None, }) web_user.update_metadata({PROFILE_SLUG: profile.id}) self.assertEqual(web_user.metadata, { 'commcare_project': None, PROFILE_SLUG: profile.id, }) definition.delete() web_user.delete(self.domain, deleted_by=None)
def setUpClass(cls): super().setUpClass() cls.domain = 'bookshelf' cls.other_domain = 'book' cls.domain_obj = create_domain(cls.domain) cls.other_domain_obj = create_domain(cls.other_domain) cls.definition = CustomDataFieldsDefinition( domain=cls.domain_obj.name, field_type=UserFieldsView.field_type) cls.definition.save() cls.definition.set_fields([ Field( slug='born', label='Year of Birth', ), Field( slug='_type', label='Type', choices=['fiction', 'non-fiction'], ), ]) cls.definition.save() cls.profile = CustomDataFieldsProfile( name='Novelist', fields={'_type': 'fiction'}, definition=cls.definition, ) cls.profile.save() cls.user1 = CommCareUser.create(cls.domain_obj.name, 'edith', 'badpassword', None, None, first_name='Edith', last_name='Wharton', metadata={'born': 1862}) cls.user2 = CommCareUser.create( cls.domain_obj.name, 'george', 'anotherbadpassword', None, None, first_name='George', last_name='Eliot', metadata={ 'born': 1849, PROFILE_SLUG: cls.profile.id }, ) cls.user3 = CommCareUser.create( cls.other_domain_obj.name, 'emily', 'anothersuperbadpassword', None, None, first_name='Emily', last_name='Bronte', )
def setUpClass(cls): super(SchedulingRecipientTest, cls).setUpClass() cls.domain_obj = create_domain(cls.domain) cls.location_types = setup_location_types(cls.domain, ['country', 'state', 'city']) cls.country_location = make_loc('usa', domain=cls.domain, type='country') cls.state_location = make_loc('ma', domain=cls.domain, type='state', parent=cls.country_location) cls.city_location = make_loc('boston', domain=cls.domain, type='city', parent=cls.state_location) cls.mobile_user = CommCareUser.create(cls.domain, 'mobile', 'abc', None, None) cls.mobile_user.set_location(cls.city_location) cls.mobile_user2 = CommCareUser.create(cls.domain, 'mobile2', 'abc', None, None) cls.mobile_user2.set_location(cls.state_location) cls.mobile_user3 = CommCareUser.create(cls.domain, 'mobile3', 'abc', None, None, metadata={ 'role': 'pharmacist', }) cls.mobile_user3.save() cls.mobile_user4 = CommCareUser.create(cls.domain, 'mobile4', 'abc', None, None, metadata={ 'role': 'nurse', }) cls.mobile_user4.save() cls.mobile_user5 = CommCareUser.create(cls.domain, 'mobile5', 'abc', None, None, metadata={ 'role': ['nurse', 'pharmacist'], }) cls.mobile_user5.save() full_username = normalize_username('mobile', cls.domain) cls.full_mobile_user = CommCareUser.create(cls.domain, full_username, 'abc', None, None) cls.definition = CustomDataFieldsDefinition( domain=cls.domain, field_type=UserFieldsView.field_type) cls.definition.save() cls.definition.set_fields([ Field( slug='role', label='Role', ), ]) cls.definition.save() cls.profile = CustomDataFieldsProfile( name='nurse_profile', fields={'role': ['nurse']}, definition=cls.definition, ) cls.profile.save() cls.mobile_user6 = CommCareUser.create(cls.domain, 'mobile6', 'abc', None, None, metadata={ PROFILE_SLUG: cls.profile.id, }) cls.mobile_user5.save() cls.web_user = WebUser.create(cls.domain, 'web', 'abc', None, None) cls.web_user2 = WebUser.create(cls.domain, 'web2', 'abc', None, None, metadata={ 'role': 'nurse', }) cls.web_user2.save() cls.group = Group(domain=cls.domain, users=[cls.mobile_user.get_id]) cls.group.save() cls.group2 = Group(domain=cls.domain, users=[ cls.mobile_user.get_id, cls.mobile_user3.get_id, cls.mobile_user4.get_id, cls.mobile_user5.get_id, cls.mobile_user6.get_id, ]) cls.group2.save() cls.case_group = CommCareCaseGroup(domain=cls.domain) cls.case_group.save() cls.process_pillow_changes = process_pillow_changes( 'DefaultChangeFeedPillow') cls.process_pillow_changes.add_pillow(get_case_messaging_sync_pillow())