Esempio n. 1
0
    def form_valid(self, form):
        from tags.models import PageTagSet, Tag
        from tags.models import slugify as tag_slugify

        val = super(PageUpdateView, self).form_valid(form)

        if 'tag' in self.request.GET:
            # Add tag to page
            t = self.request.GET.get('tag')
            t = Tag.objects.get(slug=tag_slugify(t), region=self.object.region)
            if PageTagSet.objects.filter(page=self.object,
                                         region=self.object.region).exists():
                pts = self.object.pagetagset
            else:
                pts = PageTagSet(page=self.object, region=self.object.region)

            tag_name = Tag._meta.verbose_name.lower()
            pts.save(comment=_("added %(name)s %(added)s.") % {
                'name': tag_name,
                'added': t
            })

            pts.tags.add(t)

        return val
    def setUp(self):
        super(PageAPITests, self).setUp()

        # Create the edit user and add it to the authenticated group
        self.edit_user = User(username="******",
                              email="*****@*****.**",
                              password="******")
        self.edit_user.save()
        all_group, created = Group.objects.get_or_create(
            name=settings.USERS_DEFAULT_GROUP)
        self.edit_user.groups.add(all_group)
        self.edit_user.save()

        self.edit_user_2 = User(username="******",
                                email="*****@*****.**",
                                password="******")
        self.edit_user_2.save()
        all_group, created = Group.objects.get_or_create(
            name=settings.USERS_DEFAULT_GROUP)
        self.edit_user_2.groups.add(all_group)
        self.edit_user_2.save()

        self.sf_region = Region(full_name='San Francisco', slug='sf')
        self.sf_region.save()
        self.oak_region = Region(full_name='Oakland', slug='oak')
        self.oak_region.save()

        p = Page(region=self.oak_region)
        p.content = '<p>Lake Merritt here</p>'
        p.name = 'Lake Merritt'
        p.save()
        self.lake_merritt = p

        p = Page(region=self.sf_region)
        p.content = '<p>Dolores Park here</p>'
        p.name = 'Dolores Park'
        p.save()
        self.dolores_park = p

        p = Page(region=self.sf_region)
        p.content = '<p>Duboce Park here</p>'
        p.name = 'Duboce Park'
        p.save()
        self.duboce_park = p

        t1 = Tag(name='lake')
        t1.save()
        t2 = Tag(name='water')
        t2.save()
        pts = PageTagSet(page=p, region=self.sf_region)
        pts.save()
        pts.tags = [t1, t2]
    def setUp(self):
        super(PageAPITests, self).setUp()

        # Create the edit user and add it to the authenticated group
        self.edit_user = User(
            username="******", email="*****@*****.**", password="******")
        self.edit_user.save()
        all_group, created = Group.objects.get_or_create(name=settings.USERS_DEFAULT_GROUP)
        self.edit_user.groups.add(all_group)
        self.edit_user.save()

        self.edit_user_2 = User(
            username="******", email="*****@*****.**", password="******")
        self.edit_user_2.save()
        all_group, created = Group.objects.get_or_create(name=settings.USERS_DEFAULT_GROUP)
        self.edit_user_2.groups.add(all_group)
        self.edit_user_2.save()

        self.sf_region = Region(full_name='San Francisco', slug='sf')
        self.sf_region.save()
        self.oak_region = Region(full_name='Oakland', slug='oak')
        self.oak_region.save()

        p = Page(region=self.oak_region)
        p.content = '<p>Lake Merritt here</p>'
        p.name = 'Lake Merritt'
        p.save()
        self.lake_merritt = p

        p = Page(region=self.sf_region)
        p.content = '<p>Dolores Park here</p>'
        p.name = 'Dolores Park'
        p.save()
        self.dolores_park = p

        p = Page(region=self.sf_region)
        p.content = '<p>Duboce Park here</p>'
        p.name = 'Duboce Park'
        p.save()
        self.duboce_park = p

        t1 = Tag(name='lake')
        t1.save()
        t2 = Tag(name='water')
        t2.save()
        pts = PageTagSet(page=p, region=self.sf_region)
        pts.save()
        pts.tags = [t1, t2]
Esempio n. 4
0
 def get_object(self):
     page_slug = self.kwargs.get('slug')
     page = get_object_or_404(Page, slug=page_slug)
     try:
         return PageTagSet.objects.get(page=page)
     except PageTagSet.DoesNotExist:
         return PageTagSet(page=page)
Esempio n. 5
0
    def post_save(self, page, *args, **kwargs):
        if not hasattr(page, '_tags'):
            # Not providing any tag detail, so let's skip altering the tags.
            return

        if type(page._tags) is list:
            # If tags were provided in the request
            try:
                pts = PageTagSet.objects.get(page=page, region=page.region)
            except PageTagSet.DoesNotExist:
                pts = PageTagSet(page=page, region=page.region)
            pts.save()

            tags = []
            for word in page._tags:
                tags.append(get_or_create_tag(word, page.region))
            pts.tags = tags
Esempio n. 6
0
    def test_move_with_fks(self):
        ###########################################################
        # Moving should carry along files and FK'ed items that
        # point to it.
        ###########################################################

        p = Page(region=self.sf)
        p.content = "<p>A page with files and a map in SF.</p>"
        p.name = "Page With FKs"
        p.save()
        # Create a file that points at the page.
        pf = PageFile(file=ContentFile("foo"), name="file.txt", slug=p.slug, region=self.sf)
        pf.save()
        # Create a redirect that points at the page.
        redirect = Redirect(source="foobar", destination=p, region=self.sf)
        redirect.save()
        # Create a map that points at the page.
        points = GEOSGeometry("""MULTIPOINT (-122.4378964233400069 37.7971758820830033, -122.3929211425700032 37.7688207875790027, -122.3908612060599950 37.7883584775320003, -122.4056240844700056 37.8013807351830025, -122.4148937988299934 37.8002956347170027, -122.4183270263600036 37.8051784612779969)""")
        map = MapData(points=points, page=p, region=self.sf)
        map.save()
        # Add tags to page
        tagset = PageTagSet(page=p, region=self.sf)
        tagset.save()
        tag = Tag(name="tag1", region=self.sf)
        tag.save()
        tagset.tags.add(tag)

        move_to_region(self.oak, pages=[p])

        # Check to see that the related objects were moved.
        p = Page.objects.get(name="Page With FKs", region=self.oak)
        self.assertEqual(len(MapData.objects.filter(page=p, region=self.oak)), 1)
        self.assertEqual(len(p.pagetagset.tags.all()), 1)
        self.assertEqual(len(Redirect.objects.filter(destination=p, region=self.oak)), 1)
        self.assertEqual(len(PageFile.objects.filter(slug=p.slug, region=self.oak)), 1)

        # Check to see that version history was moved as well
        self.assertEquals(p.versions.all().count(), 1)
        self.assertEqual(len(MapData.versions.filter(page=p, region=self.oak)), 1)
        for pts in p.pagetagset.tags.all():
            self.assertEqual(pts.versions.all().count(), 1)
        self.assertEqual(len(Redirect.versions.filter(destination=p, region=self.oak)), 1)
        self.assertEqual(len(PageFile.versions.filter(slug=p.slug, region=self.oak)), 1)

        # ..and that the page is no longer in the SF region
        self.assertFalse(Page.objects.filter(region=self.sf, name="Page With FKs").exists())
Esempio n. 7
0
def page_tags_form(context, page):
    try:
        tags = page.pagetagset
    except PageTagSet.DoesNotExist:
        tags = PageTagSet(page=page)
    context.push()
    context['form'] = PageTagSetForm(instance=tags)
    rendered = render_to_string('tags/pagetagset_form_snippet.html', context)
    context.pop()
    return rendered
Esempio n. 8
0
    def form_valid(self, form):
        from tags.models import PageTagSet, Tag
        from tags.models import slugify as tag_slugify

        val = super(PageUpdateView, self).form_valid(form)

        if 'tag' in self.request.GET:
            # Add tag to page
            t = self.request.GET.get('tag')
            t = Tag.objects.get(slug=tag_slugify(t), region=self.object.region)
            if PageTagSet.objects.filter(page=self.object, region=self.object.region).exists():
                pts = self.object.pagetagset
            else:
                pts = PageTagSet(page=self.object, region=self.object.region)

            tag_name = Tag._meta.verbose_name.lower()
            pts.save(comment=_("added %(name)s %(added)s.") % {'name': tag_name, 'added': t})

            pts.tags.add(t)

        return val
    def setUp(self):
        from regions.models import Region
        from pages.models import Page
        from tags.models import Tag, PageTagSet

        self.factory = RequestFactory()

        # Create a new region and associate a domain with it
        self.sf = Region(full_name="San Francisco", slug="sf")
        self.sf.save()
        self.sf.regionsettings.domain = 'fakename.org'
        self.sf.regionsettings.save()

        self.user = User.objects.create_user(
            username='******', email='*****@*****.**', password='******')
        self.user.save()
       
        # Create a page in the SF region
        p = Page(name='Parks', content='<p>Hi</p>', region=self.sf)
        p.save(user=self.user)
        p.content += "!"
        p.save(user=self.user)

        # Add a tag to the page
        t = Tag(name='park', slug='park', region=self.sf)
        t.save(user=self.user)
        pts = PageTagSet(region=self.sf, page=p)
        pts.save(user=self.user)
        pts.tags.add(t)
        pts.save(user=self.user)
Esempio n. 10
0
    def test_fix_tags(self):
        """
        Test the `fix_tags` utility function.
        """
        from pages.models import Page
        from tags.tag_utils import fix_tags

        #########################
        # Create some test regions
        #########################
       
        sf = Region(full_name="San Francisco Test", slug='sftest')
        sf.save()

        mission = Region(full_name="Mission", slug="mission")
        mission.save()

        #########################
        # Create some test tags
        #########################

        park = Tag(name='park', region=sf)
        park.save()

        fun = Tag(name='fun', region=sf)
        fun.save()

        #########################
        # Add the tags to a test page
        #########################

        page = Page(name="Duboce Park", content="<p>Park.</p>", region=sf)
        page.save()

        pts = PageTagSet(
            page=page,
            region=sf
        )
        pts.save()
        pts.tags.add(park)
        pts.tags.add(fun)
        pts.save()

        # Now do something odd and make one of the referenced `Tag`s point
        # to a different region than the PageTagSet.
        fun.region = mission
        fun.save()

        self.assertTrue(pts.tags.filter(region=mission).exists())

        # Then attempt a fix:
        fix_tags(sf, PageTagSet.objects.filter(id=pts.id))

        pts = PageTagSet.objects.get(page=page, region=sf)
        self.assertFalse(pts.tags.filter(region=mission).exists())

        # Check that this is fixed in historical versions as well
        for pts_h in pts.versions.all():
            self.assertFalse(pts_h.tags.filter(region=mission).exists())
Esempio n. 11
0
    def test_page_rename(self):
        p = Page()
        p.content = "<p>The page content.</p>"
        p.name = "Original page"
        p.save()

        p.rename_to("New page")

        # Renamed-to page should exist.
        new_p = Page.objects.get(name="New page")
        # new_p should have the same content.
        self.assertEqual(new_p.content, p.content)

        # "Original page" should no longer exist.
        pgs = Page.objects.filter(name="Original page")
        self.assertEqual(len(pgs), 0)
        # and a redirect from "original page" to "New page" should exist.
        Redirect.objects.filter(source="original page", destination=new_p)

        ###########################################################
        # Renaming to a page that already exists should raise an
        # exception and not affect the original page.
        ###########################################################
        p = Page()
        p.content = "<p>Hello, world.</p>"
        p.name = "Page A"
        p.save()

        self.assertRaises(exceptions.PageExistsError, p.rename_to, "New page")
        # p should be unaffected.  No redirect should be created.
        p = Page.objects.get(name="Page A")
        self.assertEqual(p.content, "<p>Hello, world.</p>")
        self.assertEqual(len(Redirect.objects.filter(source="page a")), 0)

        ###########################################################
        # Renaming should carry along files and FK'ed items that
        # point to it.
        ###########################################################
        p = Page()
        p.content = "<p>A page with files and tags</p>"
        p.name = "Page With FKs"
        p.save()
        # Create a file that points at the page.
        pf = PageFile(file=ContentFile("foo"), name="file.txt", slug=p.slug)
        pf.save()
        # Create a redirect that points at the page.
        redirect = Redirect(source="foobar", destination=p)
        redirect.save()
        # Add tags to page
        tagset = PageTagSet(page=p)
        tagset.save()
        tag = Tag(name="tag1")
        tag.save()
        tagset.tags.add(tag)

        p.rename_to("New Page With FKs")

        new_p = Page.objects.get(name="New Page With FKs")
        self.assertEqual(len(new_p.pagetagset.tags.all()), 1)
        # Two redirects: one we created explicitly and one that was
        # created during rename_to()
        self.assertEqual(len(Redirect.objects.filter(destination=new_p)), 2)
        self.assertEqual(len(PageFile.objects.filter(slug=new_p.slug)), 1)

        # Renaming should keep slugs pointed at old page /and/ copy
        # them to the new page.
        self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 1)

        ###########################################################
        # Renaming with multiple files.
        ###########################################################
        p = Page()
        p.content = "<p>A new page with multiple files.</p>"
        p.name = "Page with multiple files"
        p.save()
        # Create a file that points at the page.
        pf = PageFile(file=ContentFile("foo"), name="file.txt", slug=p.slug)
        pf.save()
        pf = PageFile(file=ContentFile("foo2"), name="file2.txt", slug=p.slug)
        pf.save()
        pf = PageFile(file=ContentFile("foo3"), name="file3.txt", slug=p.slug)
        pf.save()
        p.rename_to("A page with multiple files 2")

        p = Page.objects.get(name="A page with multiple files 2")
        self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 3)

        ###########################################################
        # Reverting a renamed page should be possible and should
        # restore files and FK'ed items that were pointed at the
        # original page.  The renamed-to page should still exist
        # after the revert and should still have its own files and
        # FK'ed items pointed at it.
        ###########################################################
        p = Page(name="Page With FKs", slug="page with fks")
        # get the version right before it was deleted
        v_before_deleted = len(p.versions.all()) - 1
        p_h = p.versions.as_of(version=v_before_deleted)
        p_h.revert_to()
        p = Page.objects.get(name="Page With FKs")
        self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 1)

        p2 = Page.objects.get(name="New Page With FKs")
        self.assertEqual(len(PageFile.objects.filter(slug=p2.slug)), 1)

        self.assertEqual(len(Redirect.objects.filter(destination=p2)), 1)

        ###########################################################
        # Renaming a page and then renaming it back.
        ###########################################################
        # 1. Simple case
        p = Page(name="Page X", content="<p>Foobar</p>")
        p.save()
        p.rename_to("Page Y")
        self.assertEqual(len(Page.objects.filter(name="Page X")), 0)
        self.assertEqual(len(Page.objects.filter(name="Page Y")), 1)

        p_new = Page.objects.get(name="Page Y")
        p_new.rename_to("Page X")
        self.assertEqual(len(Page.objects.filter(name="Page X")), 1)
        self.assertEqual(len(Page.objects.filter(name="Page Y")), 0)

        # 2. If we have FKs pointed at the page this shouldn't be
        # totally f****d.
        p = Page(name="Page X2", content="<p>Foo X</p>")
        p.save()
        # Create a file that points at the page.
        pf = PageFile(file=ContentFile("foooo"), name="file_foo.txt", slug=p.slug)
        pf.save()

        p.rename_to("Page Y2")
        p_new = Page.objects.get(name="Page Y2")
        # FK points at the page we renamed to.
        self.assertEqual(len(PageFile.objects.filter(slug=p_new.slug)), 1)

        # Now rename it back.
        p_new.rename_to("Page X2")
        p = Page.objects.get(name="Page X2")
        # After rename-back-to, FK points to the renamed-back-to page.
        self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 1)

        ###########################################################
        # Renaming a page but keeping the same slug
        ###########################################################
        p = Page(name="Foo A", content="<p>Foo A</p>")
        p.save()
        p.rename_to("FOO A")

        # Name has changed.
        self.assertEqual(len(Page.objects.filter(name="FOO A")), 1)
        # Has the same history, with a new entry for the name change.
        p = Page.objects.get(name="FOO A")
        p1, p0 = p.versions.all()
        self.assertEqual(p1.name, 'FOO A')
        self.assertEqual(p0.name, 'Foo A')
        self.assertEqual(p0.content, p1.content)

        ###########################################################
        # Renaming a page twice (A -> B -> C) and then revert A to
        # an existing state.
        ###########################################################
        p = Page(name="Bar A", content="<p>Bar A</p>")
        p.save()
        p.rename_to("Bar B")
        p = Page.objects.get(name="Bar B")
        p.rename_to("Bar C")

        p = Page(name="Bar A", slug="bar a")
        p_h = p.versions.as_of(version=1)
        p_h.revert_to()

        ###########################################################
        # Renaming a page back and forth and reverting.
        ###########################################################
        p = Page(name="Zoo A", content="<p>Zoo A</p>")
        p.save()
        p.rename_to("Zoo B")
        p = Page.objects.get(name="Zoo B")
        p.rename_to("Zoo A")
        p = Page.objects.get(name="Zoo A")
        p.rename_to("Zoo B")

        p = Page(name="Zoo A", slug="zoo a")
        p_h = p.versions.as_of(version=1)
        p_h.revert_to()

        ###########################################################
        # page A, rename to B, then create new A, rename B to C,
        # rename C to B, then revert C to first version
        ###########################################################
        p = Page(name="Mike A", content="<p>A</p>")
        p.save()
        p.rename_to("Mike B")
        new_a = Page(name="Mike A", content="<p>A new</p>")
        new_a.save()
        p = Page.objects.get(name="Mike B")
        p.rename_to("Mike C")
        p = Page.objects.get(name="Mike C")
        p.rename_to("Mike B")

        p_c = Page(name="Mike C", slug="mike c")
        p_h = p_c.versions.as_of(version=1)
        p_h.revert_to()
Esempio n. 12
0
    def test_page_rename(self):
        p = Page()
        p.content = "<p>The page content.</p>"
        p.name = "Original page"
        p.save()

        p.rename_to("New page")

        # Renamed-to page should exist.
        new_p = Page.objects.get(name="New page")
        # new_p should have the same content.
        self.assertEqual(new_p.content, p.content)

        # "Original page" should no longer exist.
        pgs = Page.objects.filter(name="Original page")
        self.assertEqual(len(pgs), 0)
        # and a redirect from "original page" to "New page" should exist.
        Redirect.objects.filter(source="original page", destination=new_p)

        ###########################################################
        # Renaming to a page that already exists should raise an
        # exception and not affect the original page.
        ###########################################################
        p = Page()
        p.content = "<p>Hello, world.</p>"
        p.name = "Page A"
        p.save()

        self.assertRaises(exceptions.PageExistsError, p.rename_to, "New page")
        # p should be unaffected.  No redirect should be created.
        p = Page.objects.get(name="Page A")
        self.assertEqual(p.content, "<p>Hello, world.</p>")
        self.assertEqual(len(Redirect.objects.filter(source="page a")), 0)

        ###########################################################
        # Renaming should carry along files and FK'ed items that
        # point to it.
        ###########################################################
        p = Page()
        p.content = "<p>A page with files and a map.</p>"
        p.name = "Page With FKs"
        p.save()
        # Create a file that points at the page.
        pf = PageFile(file=ContentFile("foo"), name="file.txt", slug=p.slug)
        pf.save()
        # Create a redirect that points at the page.
        redirect = Redirect(source="foobar", destination=p)
        redirect.save()
        # Create a map that points at the page.
        points = GEOSGeometry("""MULTIPOINT (-122.4378964233400069 37.7971758820830033, -122.3929211425700032 37.7688207875790027, -122.3908612060599950 37.7883584775320003, -122.4056240844700056 37.8013807351830025, -122.4148937988299934 37.8002956347170027, -122.4183270263600036 37.8051784612779969)""")
        map = MapData(points=points, page=p)
        map.save()
        # Add tags to page
        tagset = PageTagSet(page=p)
        tagset.save()
        tag = Tag(name="tag1")
        tag.save()
        tagset.tags.add(tag)

        p.rename_to("New Page With FKs")

        new_p = Page.objects.get(name="New Page With FKs")
        self.assertEqual(len(MapData.objects.filter(page=new_p)), 1)
        self.assertEqual(len(new_p.pagetagset.tags.all()), 1)
        # Two redirects: one we created explicitly and one that was
        # created during rename_to()
        self.assertEqual(len(Redirect.objects.filter(destination=new_p)), 2)
        self.assertEqual(len(PageFile.objects.filter(slug=new_p.slug)), 1)

        # Renaming should keep slugs pointed at old page /and/ copy
        # them to the new page.
        self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 1)

        ###########################################################
        # Renaming with multiple files.
        ###########################################################
        p = Page()
        p.content = "<p>A new page with multiple files.</p>"
        p.name = "Page with multiple files"
        p.save()
        # Create a file that points at the page.
        pf = PageFile(file=ContentFile("foo"), name="file.txt", slug=p.slug)
        pf.save()
        pf = PageFile(file=ContentFile("foo2"), name="file2.txt", slug=p.slug)
        pf.save()
        pf = PageFile(file=ContentFile("foo3"), name="file3.txt", slug=p.slug)
        pf.save()
        p.rename_to("A page with multiple files 2")

        p = Page.objects.get(name="A page with multiple files 2")
        self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 3)

        ###########################################################
        # Reverting a renamed page should be possible and should
        # restore files and FK'ed items that were pointed at the
        # original page.  The renamed-to page should still exist
        # after the revert and should still have its own files and
        # FK'ed items pointed at it.
        ###########################################################
        p = Page(name="Page With FKs", slug="page with fks")
        # get the version right before it was deleted
        v_before_deleted = len(p.versions.all()) - 1
        p_h = p.versions.as_of(version=v_before_deleted)
        p_h.revert_to()
        p = Page.objects.get(name="Page With FKs")
        self.assertEqual(len(MapData.objects.filter(page=p)), 1)
        self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 1)

        p2 = Page.objects.get(name="New Page With FKs")
        self.assertEqual(len(MapData.objects.filter(page=p2)), 1)
        self.assertEqual(len(PageFile.objects.filter(slug=p2.slug)), 1)

        self.assertEqual(len(Redirect.objects.filter(destination=p2)), 1)

        ###########################################################
        # Renaming a page and then renaming it back.
        ###########################################################
        # 1. Simple case
        p = Page(name="Page X", content="<p>Foobar</p>")
        p.save()
        p.rename_to("Page Y")
        self.assertEqual(len(Page.objects.filter(name="Page X")), 0)
        self.assertEqual(len(Page.objects.filter(name="Page Y")), 1)

        p_new = Page.objects.get(name="Page Y")
        p_new.rename_to("Page X")
        self.assertEqual(len(Page.objects.filter(name="Page X")), 1)
        self.assertEqual(len(Page.objects.filter(name="Page Y")), 0)

        # 2. If we have FKs pointed at the page this shouldn't be
        # totally f****d.
        p = Page(name="Page X2", content="<p>Foo X</p>")
        p.save()
        points = GEOSGeometry("""MULTIPOINT (-122.4378964233400069 37.7971758820830033, -122.3929211425700032 37.7688207875790027, -122.3908612060599950 37.7883584775320003, -122.4056240844700056 37.8013807351830025, -122.4148937988299934 37.8002956347170027, -122.4183270263600036 37.8051784612779969)""")
        map = MapData(points=points, page=p)
        map.save()
        # Create a file that points at the page.
        pf = PageFile(file=ContentFile("foooo"), name="file_foo.txt", slug=p.slug)
        pf.save()

        p.rename_to("Page Y2")
        p_new = Page.objects.get(name="Page Y2")
        # FK points at the page we renamed to.
        self.assertEqual(len(MapData.objects.filter(page=p_new)), 1)
        self.assertEqual(len(PageFile.objects.filter(slug=p_new.slug)), 1)

        # Now rename it back.
        p_new.rename_to("Page X2")
        p = Page.objects.get(name="Page X2")
        # After rename-back-to, FK points to the renamed-back-to page.
        self.assertEqual(len(MapData.objects.filter(page=p)), 1)
        self.assertEqual(len(PageFile.objects.filter(slug=p.slug)), 1)

        ###########################################################
        # Renaming a page but keeping the same slug
        ###########################################################
        p = Page(name="Foo A", content="<p>Foo A</p>")
        p.save()
        p.rename_to("FOO A")

        # Name has changed.
        self.assertEqual(len(Page.objects.filter(name="FOO A")), 1)
        # Has the same history, with a new entry for the name change.
        p = Page.objects.get(name="FOO A")
        p1, p0 = p.versions.all()
        self.assertEqual(p1.name, 'FOO A')
        self.assertEqual(p0.name, 'Foo A')
        self.assertEqual(p0.content, p1.content)

        ###########################################################
        # Renaming a page twice (A -> B -> C) and then revert A to
        # an existing state.
        ###########################################################
        p = Page(name="Bar A", content="<p>Bar A</p>")
        p.save()
        p.rename_to("Bar B")
        p = Page.objects.get(name="Bar B")
        p.rename_to("Bar C")

        p = Page(name="Bar A", slug="bar a")
        p_h = p.versions.as_of(version=1)
        p_h.revert_to()

        ###########################################################
        # Renaming a page back and forth and reverting.
        ###########################################################
        p = Page(name="Zoo A", content="<p>Zoo A</p>")
        p.save()
        p.rename_to("Zoo B")
        p = Page.objects.get(name="Zoo B")
        p.rename_to("Zoo A")
        p = Page.objects.get(name="Zoo A")
        p.rename_to("Zoo B")

        p = Page(name="Zoo A", slug="zoo a")
        p_h = p.versions.as_of(version=1)
        p_h.revert_to()

        ###########################################################
        # page A, rename to B, then create new A, rename B to C,
        # rename C to B, then revert C to first version
        ###########################################################
        p = Page(name="Mike A", content="<p>A</p>")
        p.save()
        p.rename_to("Mike B")
        new_a = Page(name="Mike A", content="<p>A new</p>")
        new_a.save()
        p = Page.objects.get(name="Mike B")
        p.rename_to("Mike C")
        p = Page.objects.get(name="Mike C")
        p.rename_to("Mike B")

        p_c = Page(name="Mike C", slug="mike c")
        p_h = p_c.versions.as_of(version=1)
        p_h.revert_to()
    def test_page_rename(self):
        p = Page(region=self.region)
        p.content = "<p>The page content.</p>"
        p.name = "Original page"
        p.save()

        p.rename_to("New page")

        # Renamed-to page should exist.
        new_p = Page.objects.get(name="New page", region=self.region)
        # new_p should have the same content.
        self.assertEqual(new_p.content, p.content)

        # "Original page" should no longer exist.
        pgs = Page.objects.filter(name="Original page", region=self.region)
        self.assertEqual(len(pgs), 0)
        # and a redirect from "original page" to "New page" should exist.
        Redirect.objects.filter(source="original page", destination=new_p, region=self.region)

        ###########################################################
        # Renaming to a page that already exists should raise an
        # exception and not affect the original page.
        ###########################################################
        p = Page(region=self.region)
        p.content = "<p>Hello, world.</p>"
        p.name = "Page A"
        p.save()

        self.assertRaises(exceptions.PageExistsError, p.rename_to, "New page")
        # p should be unaffected.  No redirect should be created.
        p = Page.objects.get(name="Page A", region=self.region)
        self.assertEqual(p.content, "<p>Hello, world.</p>")
        self.assertEqual(len(Redirect.objects.filter(source="page a", region=self.region)), 0)

        ###########################################################
        # Renaming should carry along files and FK'ed items that
        # point to it.
        ###########################################################
        p = Page(region=self.region)
        p.content = "<p>A page with files and a map.</p>"
        p.name = "Page With FKs"
        p.save()
        # Create a file that points at the page.
        pf = PageFile(file=ContentFile("foo"), name="file.txt", slug=p.slug, region=self.region)
        pf.save()
        # Create a redirect that points at the page.
        redirect = Redirect(source="foobar", destination=p, region=self.region)
        redirect.save()
        # Create a map that points at the page.
        points = GEOSGeometry("""MULTIPOINT (-122.4378964233400069 37.7971758820830033, -122.3929211425700032 37.7688207875790027, -122.3908612060599950 37.7883584775320003, -122.4056240844700056 37.8013807351830025, -122.4148937988299934 37.8002956347170027, -122.4183270263600036 37.8051784612779969)""")
        map = MapData(points=points, page=p, region=self.region)
        map.save()
        # Add tags to page
        tagset = PageTagSet(page=p, region=self.region)
        tagset.save()
        tag = Tag(name="tag1", region=self.region)
        tag.save()
        tagset.tags.add(tag)

        p.rename_to("New Page With FKs")

        new_p = Page.objects.get(name="New Page With FKs", region=self.region)
        self.assertEqual(len(MapData.objects.filter(page=new_p, region=self.region)), 1)
        self.assertEqual(len(new_p.pagetagset.tags.all()), 1)
        # Two redirects: one we created explicitly and one that was
        # created during rename_to()
        self.assertEqual(len(Redirect.objects.filter(destination=new_p, region=self.region)), 2)
        self.assertEqual(len(PageFile.objects.filter(slug=new_p.slug, region=self.region)), 1)

        # Renaming should keep slugs pointed at old page /and/ copy
        # them to the new page.
        self.assertEqual(len(PageFile.objects.filter(slug=p.slug, region=self.region)), 1)

        ###########################################################
        # Renaming with multiple files.
        ###########################################################
        p = Page(region=self.region)
        p.content = "<p>A new page with multiple files.</p>"
        p.name = "Page with multiple files"
        p.save()
        # Create a file that points at the page.
        pf = PageFile(file=ContentFile("foo"), name="file.txt", slug=p.slug, region=self.region)
        pf.save()
        pf = PageFile(file=ContentFile("foo2"), name="file2.txt", slug=p.slug, region=self.region)
        pf.save()
        pf = PageFile(file=ContentFile("foo3"), name="file3.txt", slug=p.slug, region=self.region)
        pf.save()
        p.rename_to("A page with multiple files 2")

        p = Page.objects.get(name="A page with multiple files 2", region=self.region)
        self.assertEqual(len(PageFile.objects.filter(slug=p.slug, region=self.region)), 3)

        ###########################################################
        # Reverting a renamed page should be possible and should
        # restore files and FK'ed items that were pointed at the
        # original page.  The renamed-to page should still exist
        # after the revert and should still have its own files and
        # FK'ed items pointed at it.
        ###########################################################
        p = Page(name="Page With FKs", slug="page with fks", region=self.region)
        # get the version right before it was deleted
        v_before_deleted = len(p.versions.all()) - 1
        p_h = p.versions.as_of(version=v_before_deleted)
        p_h.revert_to()
        p = Page.objects.get(name="Page With FKs", region=self.region)
        self.assertEqual(len(MapData.objects.filter(page=p, region=self.region)), 1)
        self.assertEqual(len(PageFile.objects.filter(slug=p.slug, region=self.region)), 1)

        p2 = Page.objects.get(name="New Page With FKs")
        self.assertEqual(len(MapData.objects.filter(page=p2, region=self.region)), 1)
        self.assertEqual(len(PageFile.objects.filter(slug=p2.slug, region=self.region)), 1)

        self.assertEqual(len(Redirect.objects.filter(destination=p2, region=self.region)), 1)

        ###########################################################
        # Renaming a page and then renaming it back.
        ###########################################################
        # 1. Simple case
        p = Page(name="Page X", content="<p>Foobar</p>", region=self.region)
        p.save()
        p.rename_to("Page Y")
        self.assertEqual(len(Page.objects.filter(name="Page X", region=self.region)), 0)
        self.assertEqual(len(Page.objects.filter(name="Page Y", region=self.region)), 1)

        p_new = Page.objects.get(name="Page Y", region=self.region)
        p_new.rename_to("Page X")
        self.assertEqual(len(Page.objects.filter(name="Page X", region=self.region)), 1)
        self.assertEqual(len(Page.objects.filter(name="Page Y", region=self.region)), 0)

        # 2. If we have FKs pointed at the page this shouldn't be
        # totally f****d.
        p = Page(name="Page X2", content="<p>Foo X</p>", region=self.region)
        p.save()
        points = GEOSGeometry("""MULTIPOINT (-122.4378964233400069 37.7971758820830033, -122.3929211425700032 37.7688207875790027, -122.3908612060599950 37.7883584775320003, -122.4056240844700056 37.8013807351830025, -122.4148937988299934 37.8002956347170027, -122.4183270263600036 37.8051784612779969)""")
        map = MapData(points=points, page=p, region=self.region)
        map.save()
        # Create a file that points at the page.
        pf = PageFile(file=ContentFile("foooo"), name="file_foo.txt", slug=p.slug, region=self.region)
        pf.save()

        p.rename_to("Page Y2")
        p_new = Page.objects.get(name="Page Y2", region=self.region)
        # FK points at the page we renamed to.
        self.assertEqual(len(MapData.objects.filter(page=p_new, region=self.region)), 1)
        self.assertEqual(len(PageFile.objects.filter(slug=p_new.slug, region=self.region)), 1)

        # Now rename it back.
        p_new.rename_to("Page X2")
        p = Page.objects.get(name="Page X2", region=self.region)
        # After rename-back-to, FK points to the renamed-back-to page.
        self.assertEqual(len(MapData.objects.filter(page=p, region=self.region)), 1)
        self.assertEqual(len(PageFile.objects.filter(slug=p.slug, region=self.region)), 1)

        ###########################################################
        # Renaming a page but keeping the same slug
        ###########################################################
        p = Page(name="Foo A", content="<p>Foo A</p>", region=self.region)
        p.save()
        p.rename_to("FOO A")

        # Name has changed.
        self.assertEqual(len(Page.objects.filter(name="FOO A", region=self.region)), 1)
        # Has the same history, with a new entry for the name change.
        p = Page.objects.get(name="FOO A", region=self.region)
        p1, p0 = p.versions.all()
        self.assertEqual(p1.name, 'FOO A')
        self.assertEqual(p0.name, 'Foo A')
        self.assertEqual(p0.content, p1.content)

        ###########################################################
        # Renaming a page twice (A -> B -> C) and then revert A to
        # an existing state.
        ###########################################################
        p = Page(name="Bar A", content="<p>Bar A</p>", region=self.region)
        p.save()
        p.rename_to("Bar B")
        p = Page.objects.get(name="Bar B", region=self.region)
        p.rename_to("Bar C")

        p = Page(name="Bar A", slug="bar a", region=self.region)
        p_h = p.versions.as_of(version=1)
        p_h.revert_to()

        ###########################################################
        # Renaming a page back and forth and reverting.
        ###########################################################
        p = Page(name="Zoo A", content="<p>Zoo A</p>", region=self.region)
        p.save()
        p.rename_to("Zoo B")
        p = Page.objects.get(name="Zoo B", region=self.region)
        p.rename_to("Zoo A")
        p = Page.objects.get(name="Zoo A", region=self.region)
        p.rename_to("Zoo B")

        p = Page(name="Zoo A", slug="zoo a", region=self.region)
        p_h = p.versions.as_of(version=1)
        p_h.revert_to()

        ###########################################################
        # page A, rename to B, then create new A, rename B to C,
        # rename C to B, then revert C to first version
        ###########################################################
        p = Page(name="Mike A", content="<p>A</p>", region=self.region)
        p.save()
        p.rename_to("Mike B")
        new_a = Page(name="Mike A", content="<p>A new</p>", region=self.region)
        new_a.save()
        p = Page.objects.get(name="Mike B", region=self.region)
        p.rename_to("Mike C")
        p = Page.objects.get(name="Mike C", region=self.region)
        p.rename_to("Mike B")

        p_c = Page(name="Mike C", slug="mike c", region=self.region)
        p_h = p_c.versions.as_of(version=1)
        p_h.revert_to()

        ###########################################################
        # Page rename with links!
        ###########################################################
        from links.models import Link

        dogs_p = Page(name="Dogs", slug="dogs", region=self.region, content="<p>what</p>")
        dogs_p.save()

        p = Page(name="Places to have fun", content='<p><a href="Dogs">a link</a></p>', region=self.region)
        p.save()
        p.rename_to("Places to have the MOST fun")
       
        new_p = Page.objects.get(name="Places to have the MOST fun", region=self.region)
        self.assertEqual(new_p.links.all().count(), 1)
        self.assertEqual(new_p.links.all()[0].destination_name, 'Dogs')
        self.assertEqual(new_p.links.all()[0].destination, dogs_p)