コード例 #1
0
 def test_metadata(self):
     location_type = self.location_types['state']
     location = SQLLocation(
         id="854208",
         domain="test-domain",
         name="Braavos",
         location_type=location_type,
         metadata={
             'best_swordsman': "Sylvio Forel",
             'in_westeros': "false",
             'appeared_in_num_episodes': 3,
         },
     )
     location_db = LocationSet([location])
     data_fields = [
         Field(slug='best_swordsman'),
         Field(slug='in_westeros'),
         Field(slug='appeared_in_num_episodes'),
     ]
     fixture = _location_to_fixture(location_db, location, location_type,
                                    data_fields)
     location_data = {e.tag: e.text for e in fixture.find('location_data')}
     self.assertEqual(location_data,
                      {k: str(v)
                       for k, v in location.metadata.items()})
コード例 #2
0
 def setUpClass(cls):
     super(LocationFixturesDataTest, cls).setUpClass()
     cls.user = create_restore_user(cls.domain, 'user', '123')
     cls.loc_fields = CustomDataFieldsDefinition.get_or_create(cls.domain, LocationFieldsView.field_type)
     cls.loc_fields.set_fields([
         Field(slug='baseball_team'),
         Field(slug='favorite_pastime'),
     ])
     cls.loc_fields.save()
     cls.field_slugs = [f.slug for f in cls.loc_fields.get_fields()]
コード例 #3
0
    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
            },
        )
コード例 #4
0
 def test_validate_regex(self):
     field = Field(
         slug='s_word',
         label='Word starting with the letter S',
         regex='^[Ss]',
         regex_msg='That does not start with S',
     )
     self.assertIsNone(field.validate_regex('sibilant'))
     self.assertEqual(
         field.validate_regex('whisper'),
         "'whisper' is not a valid match for Word starting with the letter S"
     )
コード例 #5
0
 def test_validate_choices(self):
     field = Field(
         slug='warm_color',
         label='Warm Color',
         choices=[
             'red',
             'orange',
             'yellow',
         ],
     )
     self.assertIsNone(field.validate_choices('orange'))
     self.assertEqual(
         field.validate_choices('squishy'),
         "'squishy' is not a valid choice for Warm Color. The available options are: red, orange, yellow."
     )
コード例 #6
0
ファイル: test_export.py プロジェクト: soitun/commcare-hq
    def setUpClass(cls):
        super(TestLocationsExport, cls).setUpClass()

        cls.loc_fields = CustomDataFieldsDefinition.get_or_create(cls.domain, LocationFieldsView.field_type)
        cls.loc_fields.set_fields([
            Field(slug=slug) for slug in cls.custom_fields
        ])
        cls.loc_fields.save()

        cls.boston = cls.locations['Boston']
        cls.boston.metadata = {
            field: '{}-试验'.format(field) for field in cls.custom_fields + ['不知道']
        }
        cls.boston.external_id = 'external_id'
        cls.boston.latitude = Decimal('42.36')
        cls.boston.longitude = Decimal('71.06')
        cls.boston.save()

        exporter = LocationExporter(cls.domain)
        writer = MockExportWriter()
        exporter.write_data(writer)

        cls.headers = dict(exporter.get_headers())
        cls.city_headers = cls.headers['city'][0]
        cls.boston_data = [row for row in writer.data['city'] if row[0] == cls.boston.location_id][0]
コード例 #7
0
    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()
コード例 #8
0
    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()
コード例 #9
0
ファイル: updates.py プロジェクト: mxdxlx/commcare-hq
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()
コード例 #10
0
ファイル: test_session.py プロジェクト: soitun/commcare-hq
 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'])
コード例 #11
0
ファイル: test_profiles.py プロジェクト: solleks/commcare-hq
    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()
コード例 #12
0
ファイル: test_importer.py プロジェクト: solleks/commcare-hq
    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()
コード例 #13
0
    def test_download_reupload_no_changes(self):
        # Make sure there's a bunch of data
        loc_fields = CustomDataFieldsDefinition.get_or_create(self.domain, 'LocationFields')
        loc_fields.set_fields([
            Field(slug='favorite_color'),
            Field(slug='language'),
        ])
        loc_fields.save()

        self.locations['City111'].latitude = Decimal('42.36')
        self.locations['City111'].longitude = Decimal('71.06')
        self.locations['City111'].external_id = '123'
        self.locations['County11'].metadata = {'favorite_color': 'purple',
                                               'language': 'en'}
        self.locations['City111'].save()

        self.locations['County11'].external_id = '321'
        self.locations['County11'].metadata = {'favorite_color': 'blue'}
        self.locations['County11'].save()

        # Export locations
        exporter = LocationExporter(self.domain)
        writer = MockExportWriter()
        exporter.write_data(writer)

        # Re-upload that export
        worksheets = []
        for sheet_title, headers in exporter.get_headers():
            rows = [[val if val is not None else '' for val in row]
                    for row in writer.data[sheet_title]]
            sheet = IteratorJSONReader(headers + rows)
            sheet.title = sheet_title
            worksheets.append(sheet)
        mock_importer = Mock()
        mock_importer.worksheets = worksheets
        with patch('corehq.apps.locations.models.SQLLocation.save') as save_location, \
             patch('corehq.apps.locations.models.LocationType.save') as save_type:
            result = new_locations_import(self.domain, mock_importer, self.user)

        # The upload should succeed and not perform any updates
        assert_errors(result, [])
        self.assertFalse(save_location.called)
        self.assertFalse(save_type.called)
コード例 #14
0
    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()
コード例 #15
0
    def test_validate_required(self):
        required_field = Field(
            slug='favorite_chordata',
            is_required=True,
            label='Favorite Chordata',
        )
        self.assertIsNone(required_field.validate_required('sea lamprey'))
        self.assertEqual(required_field.validate_required(None), 'Favorite Chordata is required.')

        optional_field = Field(
            slug='fav_echinoderm',
            is_required=False,
            label='Favorite Echinoderm',
        )
        self.assertIsNone(optional_field.validate_required('sea cucumber'))
        self.assertIsNone(optional_field.validate_required(None))
コード例 #16
0
 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
コード例 #17
0
 def update_or_create_sql_object(self, doc):
     model, created = self.sql_class().objects.update_or_create(
         couch_id=doc['_id'],
         defaults={
             "domain": doc['domain'],
             "field_type": doc['field_type'],
         },
     )
     model.set_fields([
         Field(
             slug=field['slug'],
             is_required=field.get('is_required', False),
             label=field.get('label', ''),
             choices=field.get('choices', []),
             regex=field.get('regex', ''),
             regex_msg=field.get('regex_msg', ''),
         ) for field in doc['fields']
     ])
     model.save()
     return (model, created)
コード例 #18
0
ファイル: user_resources.py プロジェクト: solleks/commcare-hq
 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()
コード例 #19
0
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, field_definitions in master_results.items():
        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()
コード例 #20
0
ファイル: user_resources.py プロジェクト: soitun/commcare-hq
    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()
コード例 #21
0
    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())
コード例 #22
0
    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)
コード例 #23
0
    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',
        )