Skip to content

Commit

Permalink
Layer: ensure area can be only Polygon or Point #181
Browse files Browse the repository at this point in the history
  • Loading branch information
nemesifier committed Oct 2, 2014
1 parent 55bad26 commit 97f2139
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 28 deletions.
9 changes: 8 additions & 1 deletion nodeshot/core/layers/models/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError, ObjectDoesNotExist
from django.contrib.gis.measure import D
from django.contrib.gis.geos import Polygon
from django.contrib.gis.geos import Polygon, Point

from django_hstore.fields import DictionaryField

Expand Down Expand Up @@ -96,6 +96,13 @@ def save(self, *args, **kwargs):
# update _current_is_published
self._current_is_published = self.is_published

def clean(self):
"""
Ensure area is either a Point or a Polygon
"""
if not isinstance(self.area, (Polygon, Point)):
raise ValidationError('area can be only of type Polygon or Point')

def update_nodes_published(self):
""" publish or unpublish nodes of current layer """
if self.pk:
Expand Down
71 changes: 44 additions & 27 deletions nodeshot/core/layers/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,32 +109,6 @@ def test_layer_nodes_minimum_distance(self):

self.assertTrue(False, 'validation not working as expected')

def test_layer_area_validation(self):
""" ensure area validation works as expected """
layer = Layer.objects.get(slug='rome')
layer.area = GEOSGeometry('POLYGON ((12.19 41.92, 12.58 42.17, 12.82 41.86, 12.43 41.64, 12.43 41.65, 12.19 41.92))')
layer.save()

# creating node with same coordinates should not be an issue
new_node = Node(**{
'name': 'new_node',
'slug': 'new_node',
'layer': layer,
'geometry': 'POINT (50.0 50.0)'
})

try:
new_node.full_clean()
except ValidationError as e:
self.assertIn(_('Node must be inside layer area'), e.messages)
else:
self.fail('validation not working as expected')

# if area is a point the contains check won't be done
layer.area = GEOSGeometry('POINT (30.0 30.0)')
layer.save()
new_node.full_clean()

def test_layers_api(self,*args,**kwargs):
"""
Layers endpoint should be reachable and return 404 if layer is not found.
Expand Down Expand Up @@ -201,7 +175,6 @@ def test_layers_api_results(self,*args,**kwargs):

def test_layers_api_post(self):
layer_count = Layer.objects.all().count()

# POST to create, 400
self.client.login(username='registered', password='tester')
data = {
Expand All @@ -224,16 +197,59 @@ def test_layers_api_post(self):
def test_unpublish_layer_should_unpublish_nodes(self):
layer = Layer.objects.first()
layer.is_published = False
layer.full_clean()
layer.save()
for node in layer.node_set.all():
self.assertFalse(node.is_published)

layer = Layer.objects.first()
layer.is_published = True
layer.full_clean()
layer.save()
for node in layer.node_set.all():
self.assertTrue(node.is_published)

def test_layer_area_point_or_polygon(self):
layer = Layer.objects.get(slug='rome')
layer.area = GEOSGeometry('LINESTRING (12.19 41.92, 12.58 42.17)')
try:
layer.full_clean()
except ValidationError as e:
self.assertIn('Polygon', str(e))
self.assertIn('Point', str(e))
else:
self.fail('ValidationError not raised (Polygon/Point area check)')
layer.area = GEOSGeometry('POINT (12.19 41.92)')
layer.full_clean()

def test_layer_area_contains_node_validation(self):
""" ensure area validation works as expected """
layer = Layer.objects.get(slug='rome')
layer.area = GEOSGeometry('POLYGON ((12.19 41.92, 12.58 42.17, 12.82 41.86, 12.43 41.64, 12.43 41.65, 12.19 41.92))')
layer.full_clean()
layer.save()

# creating node with same coordinates should not be an issue
new_node = Node(**{
'name': 'new_node',
'slug': 'new_node',
'layer': layer,
'geometry': 'POINT (50.0 50.0)'
})

try:
new_node.full_clean()
except ValidationError as e:
self.assertIn(_('Node must be inside layer area'), e.messages)
else:
self.fail('validation not working as expected')

# if area is a point the contains check won't be done
layer.area = GEOSGeometry('POINT (30.0 30.0)')
layer.full_clean()
layer.save()
new_node.full_clean()

def test_node_geometry_distance_and_area(self):
""" test minimum distance check between nodes """
self.client.login(username='admin', password='tester')
Expand All @@ -250,6 +266,7 @@ def test_node_geometry_distance_and_area(self):
}
layer = Layer.objects.get(pk=1)
layer.nodes_minimum_distance = 100
layer.full_clean()
layer.save()

# Node coordinates don't respect minimum distance. Insert should fail because coords are near to already existing PoI ( fusolab )
Expand Down

0 comments on commit 97f2139

Please sign in to comment.