Repository: GeotrekCE/Geotrek-admin

Issue:
Should not disable edit button if having bypass structure permission
Workaround: write url by hand (eg. "/trek/edit/1/").



Discussion:

Resolving patch:
diff --git a/geotrek/authent/decorators.py b/geotrek/authent/decorators.py
--- a/geotrek/authent/decorators.py
+++ b/geotrek/authent/decorators.py
@@ -18,16 +18,11 @@ def decorator(view_func):
         def _wrapped_view(self, request, *args, **kwargs):
             result = view_func(self, request, *args, **kwargs)
 
-            # Superuser is always allowed
-            if request.user.is_superuser:
-                return result
-
             if isinstance(result, HttpResponseRedirect):
                 return result
 
-            can_bypass_structure = request.user.has_perm('can_bypass_structure')
             obj = hasattr(self, 'get_object') and self.get_object() or getattr(self, 'object', None)
-            if can_bypass_structure or (obj and obj.same_structure(request.user)):
+            if obj.same_structure(request.user):
                 return result
             messages.warning(request, _(u'Access to the requested resource is restricted by structure. You have been redirected.'))
 
diff --git a/geotrek/authent/models.py b/geotrek/authent/models.py
--- a/geotrek/authent/models.py
+++ b/geotrek/authent/models.py
@@ -26,7 +26,7 @@ class Meta:
         verbose_name = _(u"Structure")
         verbose_name_plural = _(u"Structures")
         ordering = ['name']
-        permissions = (("can_bypass_structure", _("Can by structure")),)
+        permissions = (("can_bypass_structure", _("Can bypass structure")),)
 
 
 def default_structure():
@@ -69,8 +69,11 @@ def for_user(cls, user):
         return cls.in_structure.for_user(user)
 
     def same_structure(self, user):
-        """ Returns True if the user is in the same structure, False otherwise. """
-        return user.profile.structure == self.structure
+        """ Returns True if the user is in the same structure or has
+            bypass_structure permission, False otherwise. """
+        return (user.profile.structure == self.structure or
+                user.is_superuser or
+                user.has_perm('authent.can_bypass_structure'))
 
     class Meta:
         abstract = True


Test patch:
diff --git a/geotrek/trekking/tests/test_views.py b/geotrek/trekking/tests/test_views.py
--- a/geotrek/trekking/tests/test_views.py
+++ b/geotrek/trekking/tests/test_views.py
@@ -9,7 +9,7 @@
 
 from django.conf import settings
 from django.test import TestCase
-from django.contrib.auth.models import Group
+from django.contrib.auth.models import Group, Permission
 from django.contrib.gis.geos import LineString, MultiPoint, Point
 from django.core.urlresolvers import reverse
 from django.db import connection
@@ -801,14 +801,45 @@ def test_duration(self):
 class TrekViewsSameStructureTests(AuthentFixturesTest):
     def setUp(self):
         profile = UserProfileFactory.create(user__username='homer',
-                                            user__password='dooh')
-        user = profile.user
-        user.groups.add(Group.objects.get(name=u"Référents communication"))
-        self.client.login(username=user.username, password='dooh')
+                                            user__password='dooh',
+                                            language='en')
+        self.user = profile.user
+        self.user.groups.add(Group.objects.get(name=u"Référents communication"))
+        self.client.login(username='homer', password='dooh')
         self.content1 = TrekFactory.create()
         structure = StructureFactory.create()
         self.content2 = TrekFactory.create(structure=structure)
 
+    def add_bypass_perm(self):
+        perm = Permission.objects.get(codename='can_bypass_structure')
+        self.user.user_permissions.add(perm)
+
+    def test_edit_button_same_structure(self):
+        url = "/trek/{pk}/".format(pk=self.content1.pk)
+        response = self.client.get(url)
+        self.assertContains(response,
+                            '<a class="btn btn-primary pull-right" '
+                            'href="/trek/edit/{pk}/">'
+                            '<i class="icon-pencil icon-white"></i> '
+                            'Update</a>'.format(pk=self.content1.pk))
+
+    def test_edit_button_other_structure(self):
+        url = "/trek/{pk}/".format(pk=self.content2.pk)
+        response = self.client.get(url)
+        self.assertContains(response,
+                            '<span class="btn disabled pull-right" href="#">'
+                            '<i class="icon-pencil"></i> Update</span>')
+
+    def test_edit_button_bypass_structure(self):
+        self.add_bypass_perm()
+        url = "/trek/{pk}/".format(pk=self.content2.pk)
+        response = self.client.get(url)
+        self.assertContains(response,
+                            '<a class="btn btn-primary pull-right" '
+                            'href="/trek/edit/{pk}/">'
+                            '<i class="icon-pencil icon-white"></i> '
+                            'Update</a>'.format(pk=self.content2.pk))
+
     def test_can_edit_same_structure(self):
         url = "/trek/edit/{pk}/".format(pk=self.content1.pk)
         response = self.client.get(url)
@@ -819,6 +850,12 @@ def test_cannot_edit_other_structure(self):
         response = self.client.get(url)
         self.assertRedirects(response, "/trek/{pk}/".format(pk=self.content2.pk))
 
+    def test_can_edit_bypass_structure(self):
+        self.add_bypass_perm()
+        url = "/trek/edit/{pk}/".format(pk=self.content2.pk)
+        response = self.client.get(url)
+        self.assertEqual(response.status_code, 200)
+
     def test_can_delete_same_structure(self):
         url = "/trek/delete/{pk}/".format(pk=self.content1.pk)
         response = self.client.get(url)
@@ -829,6 +866,12 @@ def test_cannot_delete_other_structure(self):
         response = self.client.get(url)
         self.assertRedirects(response, "/trek/{pk}/".format(pk=self.content2.pk))
 
+    def test_can_delete_bypass_structure(self):
+        self.add_bypass_perm()
+        url = "/trek/delete/{pk}/".format(pk=self.content2.pk)
+        response = self.client.get(url)
+        self.assertEqual(response.status_code, 200)
+
 
 class POIViewsSameStructureTests(AuthentFixturesTest):
     def setUp(self):