def test_item_create_model(self): item = Item(collection=self.collection, name='item-1', properties_datetime=utc_aware(datetime.utcnow())) item.full_clean() item.save() self.assertEqual('item-1', item.name)
def test_item_create_model_none_geometry(self): # None geometry should not be allowed with self.assertRaises(ValidationError): item = Item(collection=self.collection, properties_datetime=utc_aware(datetime.utcnow()), name='item-empty', geometry=None) item.full_clean() item.save()
def test_item_create_model_valid_geometry(self): # a correct geometry should not pose any problems item = Item( collection=self.collection, properties_datetime=utc_aware(datetime.utcnow()), name='item-1', geometry=GEOSGeometry( 'SRID=4326;POLYGON ' '((5.96 45.82, 5.96 47.81, 10.49 47.81, 10.49 45.82, 5.96 45.82))' )) item.full_clean() item.save()
def test_item_create_model_invalid_geometry(self): # a geometry with self-intersection should not be allowed with self.assertRaises(ValidationError): item = Item( collection=self.collection, properties_datetime=utc_aware(datetime.utcnow()), name='item-1', geometry=GEOSGeometry( 'SRID=4326;POLYGON ' '((5.96 45.82, 5.96 47.81, 10.49 45.82, 10.49 47.81, 5.96 45.82))' )) item.full_clean() item.save()
def _create_model(self, attributes): attributes.pop('links', None) self.model_instance = Item(**attributes) self.model_instance.full_clean() self.model_instance.save()
class ItemSample(SampleData): '''Item Sample Data ''' model_class = Item sample_name = 'item' samples_dict = item_samples key_mapping = {'name': 'id'} optional_fields = ['properties_title', 'links'] read_only_fields = [ 'type', 'bbox', 'collection', 'assets', 'stac_extensions', 'stac_version', 'properties_created', 'properties_updated' ] def __init__(self, collection, sample='item-1', name=None, required_only=False, **kwargs): '''Create a item sample data Args: collection: Collection Collection DB object relations. sample: string Name of the sample based to use, see tests.sample_data.item_samples.items. name: string Overwrite the sample name. required_only: bool Return only attributes that are required (minimum sample data). **kwargs: Any parameter will overwrite existing attributes. ''' super().__init__(sample, collection=collection, name=name, required_only=required_only, **kwargs) if hasattr(self, 'attr_links'): self.attr_links = [ ItemLinkSample(**link) for link in self.attr_links ] self.model_links_instance = [] def get_attributes(self, remove_relations=True): '''Returns the sample data attributes as dictionary This can be used to create new DB object. Args: remove_relations: bool Remove relational attributes (links). Returns: Dictionary with the sample attributes to use to create a DB object. ''' attributes = super().get_attributes(remove_relations) links = attributes.pop('links', None) if not remove_relations and links: attributes['links'] = [link.attributes for link in links] return attributes def get_json(self, method='get', keep_read_only=False): '''Returns a json serializable representation of the sample data This json payload can then be used in the write API payload (with method='post', 'put' or 'patch') or to check the read API payload. It can also be directly used as the serializer data. Args: method: string Method for which the JSON would be used; 'get', 'post', 'put', 'patch', 'serialize', 'deserialize'. keep_read_only: bool keep read only fields in the json output. By default they are removed if the method is 'post', 'put' or 'patch'. Returns A dictionary with the sample data. ''' json_data = { key: value for key, value in super().get_json(method, keep_read_only).items() if not key.startswith('properties_') } if method in ['get', 'serialize']: collection = self.get('collection') json_data['collection'] = collection.name if 'geometry' in json_data and isinstance(json_data['geometry'], GEOSGeometry): json_data['geometry'] = json_data['geometry'].json if not 'properties' in json_data: json_data['properties'] = self._get_properties() links = json_data.pop('links', []) if links: json_data['links'] = [link.json for link in self.attr_links] return json_data def create(self): '''Create the sample in DB Returns: The DB sample (model object). ''' attributes = self.get_attributes(remove_relations=False) links = attributes.pop('links', []) self._create_model(attributes) if not self.model_links_instance and links: self._create_model_links(links) return self.model_instance @property def model_links(self): '''Returns a django DB model object of the links sample data If the data has not yet been created in DB, then it is created. Returns: List of link model instances. ''' if not self.model_links_instance: attributes = self.get_attributes(remove_relations=False) links = attributes.pop('links', []) if not self.model_instance: self._create_model(attributes) self._create_model_links(links) return self.model_links_instance def _get_properties(self): properties = {} for attribute in self.__dict__: if not attribute.startswith('attr_properties_'): continue key = attribute[16:] value = getattr(self, attribute) properties[key] = value if key.endswith('datetime') and isinstance(value, datetime): properties[key] = isoformat(value) return properties def _create_model(self, attributes): attributes.pop('links', None) self.model_instance = Item(**attributes) self.model_instance.full_clean() self.model_instance.save() def _create_model_links(self, links): for link in links: link_instance = ItemLink(item=self.model_instance, **link) link_instance.full_clean() link_instance.save() self.model_links_instance.append(link_instance)
def test_item_create_model_invalid_datetime(self): with self.assertRaises(ValidationError, msg="no datetime is invalid"): item = Item(collection=self.collection, name='item-1') item.full_clean() item.save() with self.assertRaises(ValidationError, msg="only start_datetime is invalid"): item = Item(collection=self.collection, name='item-2', properties_start_datetime=utc_aware(datetime.utcnow())) item.full_clean() item.save() with self.assertRaises(ValidationError, msg="only end_datetime is invalid"): item = Item(collection=self.collection, name='item-3', properties_end_datetime=utc_aware(datetime.utcnow())) item.full_clean() item.save() with self.assertRaises( ValidationError, msg="datetime is not allowed with start_datetime"): item = Item(collection=self.collection, name='item-4', properties_datetime=utc_aware(datetime.utcnow()), properties_start_datetime=utc_aware(datetime.utcnow()), properties_end_datetime=utc_aware(datetime.utcnow())) item.full_clean() item.save() with self.assertRaises(ValidationError): item = Item(collection=self.collection, name='item-1', properties_datetime='asd') item.full_clean() item.save() with self.assertRaises(ValidationError): item = Item(collection=self.collection, name='item-4', properties_start_datetime='asd') item.full_clean() item.save() with self.assertRaises(ValidationError): item = Item(collection=self.collection, name='item-1', properties_end_datetime='asd') item.full_clean() item.save() with self.assertRaises( ValidationError, msg="end_datetime must not be earlier than start_datetime"): today = datetime.utcnow() yesterday = today - timedelta(days=1) item = Item(collection=self.collection, name='item-5', properties_start_datetime=utc_aware(today), properties_end_datetime=utc_aware(yesterday)) item.full_clean() item.save()