Repository: django-cms/django-cms

Issue:
One the clean method in PageForm does not play well with permod
I can't save the same page several time in a raw with the moderator. 
The form has a validation error telling me: "Page with redirect url u'uk' already exist"



Discussion:

Resolving patch:
diff --git a/cms/admin/forms.py b/cms/admin/forms.py
--- a/cms/admin/forms.py
+++ b/cms/admin/forms.py
@@ -177,7 +177,9 @@ def clean_overwrite_url(self):
                 if not any_path_re.match(url):
                     raise forms.ValidationError(_('Invalid URL, use /my/url format.'))
                 page = get_page_from_path(url.strip('/'))
-                if page and page.pk != self.instance.pk:
+                if (page and
+                    page.pk not in [self.instance.pk,
+                                    self.instance.publisher_public_id]):
                     raise forms.ValidationError(_('Page with redirect url %r already exist') % url)
         return url
 


Test patch:
diff --git a/cms/tests/forms.py b/cms/tests/forms.py
--- a/cms/tests/forms.py
+++ b/cms/tests/forms.py
@@ -130,3 +130,5 @@ def test_page_user_form_initial(self):
                  'can_change_pagepermission', 'can_delete_pagepermission']
         for name in names:
             self.assertTrue(puf.initial.get(name, False))
+
+
diff --git a/cms/tests/page.py b/cms/tests/page.py
--- a/cms/tests/page.py
+++ b/cms/tests/page.py
@@ -8,7 +8,6 @@
 from cms.plugins.link.cms_plugins import LinkPlugin
 from cms.plugins.text.cms_plugins import TextPlugin
 from cms.plugins.text.models import Text
-from cms.plugins.link.models import Link
 from cms.sitemaps import CMSSitemap
 from cms.templatetags.cms_tags import get_placeholder_content
 from cms.test_utils.testcases import (CMSTestCase, URL_CMS_PAGE,
@@ -168,7 +167,34 @@ def test_edit_page(self):
             response = self.client.post('/admin/cms/page/%s/' %page.id, page_data)
             self.assertRedirects(response, URL_CMS_PAGE)
             self.assertEqual(page.get_title(), 'changed title')
-    
+
+    def test_moderator_edit_page_redirect(self):
+        """
+        Test that a page can be edited multiple times with moderator
+        """
+        superuser = self.get_superuser()
+        with self.login_user_context(superuser):
+            with SettingsOverride(CMS_MODERATOR=True):
+                page_data = self.get_new_page_data()
+                response = self.client.post(URL_CMS_PAGE_ADD, page_data)
+                self.assertEquals(response.status_code, 302)
+                page =  Page.objects.get(title_set__slug=page_data['slug'])
+                response = self.client.get('/en/admin/cms/page/%s/' %page.id)
+                self.assertEqual(response.status_code, 200)
+                page_data['overwrite_url'] = '/hello/'
+                page_data['has_url_overwrite'] = True
+                response = self.client.post('/en/admin/cms/page/%s/' %page.id, page_data)
+                self.assertRedirects(response, URL_CMS_PAGE)
+                self.assertEqual(page.get_absolute_url(), '/hello/')
+                title = Title.objects.all()[0]
+                page.publish()
+                page_data['title'] = 'new title'
+                response = self.client.post('/en/admin/cms/page/%s/' %page.id, page_data)
+                page =  Page.objects.get(title_set__slug=page_data['slug'], publisher_is_draft=True)
+                self.assertRedirects(response, URL_CMS_PAGE)
+                self.assertEqual(page.get_title(), 'new title')
+
+
     def test_meta_description_and_keywords_fields_from_admin(self):
         """
         Test that description and keywords tags can be set via the admin
diff --git a/cms/tests/publisher.py b/cms/tests/publisher.py
--- a/cms/tests/publisher.py
+++ b/cms/tests/publisher.py
@@ -220,3 +220,4 @@ def test_publish_works_with_descendants(self):
                 self.assertTrue(draft.parent in draft.get_ancestors())
                 self.assertTrue(draft in draft.parent.get_descendants())
                 self.assertTrue(draft in draft.parent.get_children())
+