Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
 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()
Ejemplo n.º 3
0
 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()
Ejemplo n.º 4
0
 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()
Ejemplo n.º 5
0
 def _create_model(self, attributes):
     attributes.pop('links', None)
     self.model_instance = Item(**attributes)
     self.model_instance.full_clean()
     self.model_instance.save()
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
    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()