def test_sync_to_couch(self): obj = SQLCustomDataFieldsDefinition( domain='botswana', field_type='UserFields', ) obj.save( sync_to_couch=False ) # need to save for set_fields to work, but don't want to sync couch obj.set_fields([ SQLField( slug='color', is_required=True, label='Color', choices=['red', 'orange', 'yellow'], regex='', regex_msg='', ), SQLField( slug='size', is_required=False, label='Size', choices=[], regex='^[0-9]+$', regex_msg='Εισαγάγετε', ), ]) obj.save() self.assertIsNone( Command.diff_couch_and_sql(self.db.get(obj.couch_id), obj)) obj.field_type = 'ProductFields' obj.save() self.assertEquals('ProductFields', self.db.get(obj.couch_id)['field_type'])
def test_validate_regex(self): field = SQLField( 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" )
def test_validate_choices(self): field = SQLField( 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." )
def setUpClass(cls): super(TestLocationsExport, cls).setUpClass() cls.loc_fields = SQLCustomDataFieldsDefinition.get_or_create( cls.domain, LocationFieldsView.field_type) cls.loc_fields.set_fields( [SQLField(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]
def test_download_reupload_no_changes(self): # Make sure there's a bunch of data loc_fields = SQLCustomDataFieldsDefinition.get_or_create( self.domain, 'LocationFields') loc_fields.set_fields([ SQLField(slug='favorite_color'), SQLField(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)
def test_validate_required(self): required_field = SQLField( 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 = SQLField( slug='fav_echinoderm', is_required=False, label='Favorite Echinoderm', ) self.assertIsNone(optional_field.validate_required('sea cucumber')) self.assertIsNone(optional_field.validate_required(None))
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 = SQLCustomDataFieldsDefinition.get_or_create(domain_link.linked_domain, field_type) model.set_fields([ SQLField( 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()
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([ SQLField( 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)
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))