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 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 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_migration(self): doc = CustomDataFieldsDefinition( domain='botswana', field_type='UserFields', fields=[ CustomDataField( slug='color', is_required=True, label='Color', choices=['red', 'orange', 'yellow'], ), ], ) doc.save(sync_to_sql=False) call_command('populate_custom_data_fields') self.assertIsNone( Command.diff_couch_and_sql( doc.to_json(), SQLCustomDataFieldsDefinition.objects.get( couch_id=doc.get_id))) # Additional call should apply any updates doc = CustomDataFieldsDefinition.get(doc.get_id) doc.field_type = 'LocationFields' doc.save(sync_to_sql=False) call_command('populate_custom_data_fields') self.assertIsNone( Command.diff_couch_and_sql( doc.to_json(), SQLCustomDataFieldsDefinition.objects.get( couch_id=doc.get_id)))
def test_sync_to_sql(self): doc = CustomDataFieldsDefinition( domain='botswana', field_type='UserFields', fields=[ CustomDataField( slug='color', is_required=True, label='Color', choices=['red', 'orange', 'yellow'], ), CustomDataField( slug='size', is_required=False, label='Size', regex='^[0-9]+$', regex_msg='Εισαγάγετε', ), ], ) doc.save() self.assertIsNone( Command.diff_couch_and_sql( doc.to_json(), SQLCustomDataFieldsDefinition.objects.get( couch_id=doc.get_id))) doc.fields[0].label = 'Hue' doc.save() self.assertEquals( 'Hue', SQLCustomDataFieldsDefinition.objects.get( couch_id=doc.get_id).get_fields()[0].label)
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() 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 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 _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): 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())
def test_diff(self): # Start with identical data def_args = {'domain': 'some-domain', 'field_type': 'ProductFields'} field1_args = { 'slug': 'texture', 'is_required': True, 'label': 'Texture', 'choices': ['soft', 'spiky'] } obj = SQLCustomDataFieldsDefinition(**def_args) obj.save() obj.set_fields([SQLField(**field1_args)]) doc = CustomDataFieldsDefinition( fields=[CustomDataField(**field1_args)], **def_args, ).to_json() self.assertIsNone(Command.diff_couch_and_sql(doc, obj)) # Difference in top-level attribute doc['domain'] = 'other-domain' self.assertEqual( Command.diff_couch_and_sql(doc, obj), "domain: couch value 'other-domain' != sql value 'some-domain'") # Difference in numer of sub-models doc['domain'] = 'some-domain' field2_args = { 'slug': 'temp', 'is_required': False, 'label': 'F', 'choices': ['32', '212'] } doc['fields'] = [ CustomDataField(**field1_args).to_json(), CustomDataField(**field2_args).to_json() ] self.assertEqual(Command.diff_couch_and_sql(doc, obj), "fields: 2 in couch != 1 in sql") # Different in sub-model attribute field2_args['label'] = 'C' obj.set_fields([SQLField(**field1_args), SQLField(**field2_args)]) self.assertEqual(Command.diff_couch_and_sql(doc, obj), "label: couch value 'F' != sql value 'C'") # Difference in sub-model ordering field2_args['label'] = 'F' obj.set_fields([SQLField(**field2_args), SQLField(**field1_args)]) self.assertEqual( Command.diff_couch_and_sql(doc, obj).split("\n"), [ "slug: couch value 'texture' != sql value 'temp'", "is_required: couch value 'True' != sql value 'False'", "label: couch value 'Texture' != sql value 'F'", "choices: couch value '['soft', 'spiky']' != sql value '['32', '212']'", "slug: couch value 'temp' != sql value 'texture'", "is_required: couch value 'False' != sql value 'True'", "label: couch value 'F' != sql value 'Texture'", "choices: couch value '['32', '212']' != sql value '['soft', 'spiky']'", ]) # Identical data obj.set_fields([SQLField(**field1_args), SQLField(**field2_args)]) self.assertIsNone(Command.diff_couch_and_sql(doc, obj))