def test_update(self):
        doc1 = self.portal.doc1
        doc2 = self.portal.doc2
        doc4 = self.portal.folder1.doc4

        # This tests updating link integrity information for all site content,
        # i.e. after migrating from a previous version.
        self._set_text(doc1, '<a href="doc2">a document</a>')
        self._set_text(doc2, '<a href="folder1/doc4">a document</a>')

        catalog = getUtility(ICatalog)
        rels = [i for i in catalog.findRelations()]
        for rel in rels:
            catalog.unindex(rel)

        # Just to make sure, we check that there are no references from or to
        # these documents at this point:
        self.assertEqual([i.to_object for i in getOutgoingLinks(doc1)], [])
        self.assertEqual([i.to_object for i in getOutgoingLinks(doc2)], [])

        # An update of link integrity information for all content is triggered
        # by browsing a specific url:
        transaction.commit()
        self.browser.open('{0:s}/updateLinkIntegrityInformation'.format(
            self.portal.absolute_url()))
        self.browser.getControl('Update').click()
        self.assertIn('Link integrity information updated for',
                      self.browser.contents)

        # Now the linking documents should hold the correct link integrity
        # references:
        self.assertEqual([i.to_object for i in getOutgoingLinks(doc1)], [doc2, ])
        self.assertEqual([i.to_object for i in getOutgoingLinks(doc2)], [doc4, ])
    def test_reference_orthogonality(self):
        doc = self.portal.doc1
        img = self.portal.image1
        tag = img.restrictedTraverse('@@images').tag()

        # This tests the behavior when other references already exist.
        self.assertEqual([l for l in getOutgoingLinks(doc)], [])
        self.assertEqual([l for l in getIncomingLinks(doc)], [])
        self.assertEqual([l for l in getOutgoingLinks(img)], [])
        self.assertEqual([l for l in getOutgoingLinks(img)], [])

        # Then establish a reference between the document and image as
        # a related item:
        self._set_related_items(doc, [img, ])
        self.assertEqual(self._get_related_items(doc), [img, ])

        # Next edit the document body and insert a link to the image,
        # which should trigger the creation of a link integrity reference:
        self._set_text(doc, tag)

        self.assertEqual([l.to_object for l in getOutgoingLinks(doc)], [img])

        # And the related item reference remains in place:
        self.assertEqual(self._get_related_items(doc), [img, ])

        # Finally, edit the document body again, this time removing the
        # link to the image, which should trigger the removal of the
        # link integrity reference:
        self._set_text(doc, 'where did my link go?')
        self.assertEqual([l.to_object for l in getOutgoingLinks(doc)], [])

        # And again the related item reference remains in place:
        self.assertEqual(self._get_related_items(doc), [img, ])
 def test_relative_upwards_link_generates_matching_reference(self):
     doc1 = self.portal.doc1
     doc3 = self.portal.folder1.doc3
     self._set_text(doc3, '<a href="../doc1">go!</a>')
     self.assertEqual(len(list(getOutgoingLinks(doc1))), 0)
     self.assertEqual([l.to_object for l in getOutgoingLinks(doc3)],
                      [doc1])
Example #4
0
    def test_internal_breaches_are_dropped(self):
        folder1 = self.portal.folder1
        create(folder1, 'Document', id='doc5', title='Test Page 5')
        doc1 = self.portal.doc1
        doc4 = self.portal.folder1.doc4
        doc5 = self.portal.folder1.doc5
        self._set_text(doc1, '<a href="folder1">f1</a>')
        self._set_text(doc4, '<a href="doc5">d5</a><a href="../doc1">d1</a>')
        self._set_text(doc5, '<a href="../folder1">f1</a>')

        doc4_breaches = set([r.to_object for r in getOutgoingLinks(doc4)])
        # the order of breaches is non-deterministic
        self.assertEqual(set([doc1, doc5]), doc4_breaches)
        self.assertEqual([r.to_object for r in getOutgoingLinks(doc5)],
                         [folder1])
        self.assertEqual([r.to_object for r in getOutgoingLinks(doc1)],
                         [folder1])
        view = DeleteConfirmationInfo(self.portal, self.request)
        self.assertEqual(len(view.get_breaches([doc4])), 0)
        self.assertEqual(len(view.get_breaches([doc5])), 1)
        self.assertEqual(len(view.get_breaches([doc4, doc5])), 0)
        self.assertEqual(len(view.get_breaches([folder1])), 1)
        self.assertEqual(len(view.get_breaches([doc1])), 1)
        self.assertEqual(len(view.get_breaches([doc1, folder1])), 0)

        view = folder1.restrictedTraverse('delete_confirmation')
        self.assertIn('Potential link breakage', view())
        view = folder1.restrictedTraverse('delete_confirmation_info')
        self.assertIn('Potential link breakage', view())
        view = doc4.restrictedTraverse('delete_confirmation')
        self.assertNotIn('Potential link breakage', view())
        view = doc4.restrictedTraverse('delete_confirmation_info')
        self.assertNotIn('Potential link breakage', view())
    def test_internal_breaches_are_dropped(self):
        folder1 = self.portal.folder1
        create(folder1, 'Document', id='doc5', title='Test Page 5')
        doc1 = self.portal.doc1
        doc4 = self.portal.folder1.doc4
        doc5 = self.portal.folder1.doc5
        self._set_text(doc1, '<a href="folder1">f1</a>')
        self._set_text(doc4, '<a href="doc5">d5</a><a href="../doc1">d1</a>')
        self._set_text(doc5, '<a href="../folder1">f1</a>')

        doc4_breaches = set([r.to_object for r in getOutgoingLinks(doc4)])
        # the order of breaches is non-deterministic
        self.assertEqual(set([doc1, doc5]), doc4_breaches)
        self.assertEqual(
            [r.to_object for r in getOutgoingLinks(doc5)], [folder1])
        self.assertEqual(
            [r.to_object for r in getOutgoingLinks(doc1)], [folder1])
        view = DeleteConfirmationInfo(self.portal, self.request)
        self.assertEqual(len(view.get_breaches([doc4])), 0)
        self.assertEqual(len(view.get_breaches([doc5])), 1)
        self.assertEqual(len(view.get_breaches([doc4, doc5])), 0)
        self.assertEqual(len(view.get_breaches([folder1])), 1)
        self.assertEqual(len(view.get_breaches([doc1])), 1)
        self.assertEqual(len(view.get_breaches([doc1, folder1])), 0)

        view = folder1.restrictedTraverse('delete_confirmation')
        self.assertIn('Potential link breakage', view())
        view = folder1.restrictedTraverse('delete_confirmation_info')
        self.assertIn('Potential link breakage', view())
        view = doc4.restrictedTraverse('delete_confirmation')
        self.assertNotIn('Potential link breakage', view())
        view = doc4.restrictedTraverse('delete_confirmation_info')
        self.assertNotIn('Potential link breakage', view())
    def test_image_tag_reference_creation(self):
        doc1 = self.portal.doc1
        img1 = self.portal.image1

        # This tests the correct creation of references used for
        # ensuring link integrity. Any archetype-based content object
        # which refers to other (local) objects by `<img>` or `<a>` tags
        # should create references between those objects on save.
        self._set_text(doc1, img1.restrictedTraverse('@@images').tag())

        self.assertEqual([r.to_object for r in getOutgoingLinks(doc1)], [img1, ])
        self.assertEqual([r.to_object for r in getIncomingLinks(doc1)], [])
        self.assertEqual([r.to_object for r in getOutgoingLinks(img1)], [])
        self.assertEqual([r.from_object for r in getIncomingLinks(img1)], [doc1])
    def test_broken_references(self):
        # create a temporary document to test with
        doc1a = testing.create(self.portal, 'Document', id='doc1a')
        doc1 = self.portal.doc1

        self.assertEqual(len(list(getOutgoingLinks(doc1))), 0)
        self._set_text(doc1, '<a href="doc1a">Doc 1a</a>')
        self.assertEqual(len(list(getOutgoingLinks(doc1))), 1)
        self.assertEqual([l.to_object for l in getOutgoingLinks(doc1)],
                         [self.portal.doc1a])

        # Now delete the target item, suppress events and test again,
        # the reference should be gone now.
        self.portal._delObject(doc1a.id, suppress_events=True)
        self.assertEqual([l.to_object for l in getOutgoingLinks(doc1)], [None])
Example #8
0
    def test_broken_references(self):
        # create a temporary document to test with
        doc1a = testing.create(self.portal, 'Document', id='doc1a')
        doc1 = self.portal.doc1

        self.assertEqual(len(list(getOutgoingLinks(doc1))), 0)
        self._set_text(doc1, '<a href="doc1a">Doc 1a</a>')
        self.assertEqual(len(list(getOutgoingLinks(doc1))), 1)
        self.assertEqual([l.to_object for l in getOutgoingLinks(doc1)],
                         [self.portal.doc1a])

        # Now delete the target item, suppress events and test again,
        # the reference should be gone now.
        self.portal._delObject(doc1a.id, suppress_events=True)
        self.assertEqual([l.to_object for l in getOutgoingLinks(doc1)], [None])
    def test_files_with_spaces_removal(self):
        doc1 = self.portal.doc1

        # This tests the behaviour when removing a referenced file that has
        # spaces in its id.  First we need to rename the existing file:
        self.portal.invokeFactory(
            'Document', id='some spaces.doc', title='A spaces doc')

        self.assertIn('some spaces.doc', self.portal.objectIds())
        spaces1 = self.portal['some spaces.doc']

        self._set_text(doc1, '<a href="some spaces.doc">a document</a>')

        # The document should now have a reference to the file:
        self.assertEqual(
            [i.to_object for i in getOutgoingLinks(doc1)], [spaces1])
        transaction.commit()

        # Then we use a browser to try to delete the referenced file.
        # Before we can do this we need to prevent the test framework
        # from choking on the exception we intentionally throw.
        self.browser.handleErrors = True

        self.browser.open('{0:s}/delete_confirmation?_authenticator={1:s}'.format(
            spaces1.absolute_url(), self._get_token(spaces1)))
        self.assertIn('Potential link breakage', self.browser.contents)
        self.assertIn(
            '<a href="http://nohost/plone/doc1">Test Page 1</a>',
            self.browser.contents
        )
        self.browser.getControl(name='form.buttons.Delete').click()
        self.assertNotIn('some spaces.doc', self.portal.objectIds())
Example #10
0
    def test_files_with_spaces_removal(self):
        doc1 = self.portal.doc1

        # This tests the behaviour when removing a referenced file that has
        # spaces in its id.  First we need to rename the existing file:
        self.portal.invokeFactory('Document',
                                  id='some spaces.doc',
                                  title='A spaces doc')

        self.assertIn('some spaces.doc', self.portal.objectIds())
        spaces1 = self.portal['some spaces.doc']

        self._set_text(doc1, '<a href="some spaces.doc">a document</a>')

        # The document should now have a reference to the file:
        self.assertEqual([i.to_object for i in getOutgoingLinks(doc1)],
                         [spaces1])
        transaction.commit()

        # Then we use a browser to try to delete the referenced file.
        # Before we can do this we need to prevent the test framework
        # from choking on the exception we intentionally throw.
        self.browser.handleErrors = True

        self.browser.open(
            '{0:s}/delete_confirmation?_authenticator={1:s}'.format(
                spaces1.absolute_url(), self._get_token(spaces1)))
        self.assertIn('Potential link breakage', self.browser.contents)
        self.assertIn('<a href="http://nohost/plone/doc1">Test Page 1</a>',
                      self.browser.contents)
        self.browser.getControl(name='form.buttons.Delete').click()
        self.assertNotIn('some spaces.doc', self.portal.objectIds())
    def test_unicode_links(self):
        doc1 = self.portal.doc1

        # This tests checks that hasIncomingLinks can now be used safely as it
        # eventually plays well with transaction machinery.
        # Add bad link, should not raise exception and there should not
        # be any references added.
        self._set_text(doc1, unicode('<a href="ö?foo=bar&baz=bam">bug</a>', 'utf-8'))
        self.assertEqual([l for l in getOutgoingLinks(doc1)], [])
    def test_image_scale_reference_creation(self):
        doc1 = self.portal.doc1
        img1 = self.portal.image1

        # Linking image scales should also work:
        self._set_text(
            doc1, '<a href="image1/@@images/image_thumb">an image</a>')
        self.assertEqual([r.to_object for r in getOutgoingLinks(doc1)], [img1, ])
        self.assertEqual([r.from_object for r in getIncomingLinks(img1)], [doc1, ])
    def test_image_resolveuid_reference_creation(self):
        doc1 = self.portal.doc1
        img1 = self.portal.image1

        # Linking via the "resolveuid/UID" method should also work:
        self._set_text(doc1, '<a href="resolveuid/{0:s}">an image</a>'.format(
            IUUID(img1)))
        self.assertEqual([r.to_object for r in getOutgoingLinks(doc1)], [img1, ])
        self.assertEqual([r.from_object for r in getIncomingLinks(img1)], [doc1, ])
 def test_get_ref_form_snippet(self):
     page1 = self._create_page(_id='test1')
     page2 = self._create_page(
         text='<div data-type="snippet_tag" data-snippet-id="{}"</div>'.
         format(IUUID(page1)))
     refs = getSnippetRefs(page2)
     self.assertEqual([i for i in refs][0].to_object.getId(), 'test1')
     # should also have stored these refs for object
     links = getOutgoingLinks(page2)
     self.assertEqual([l for l in links][0].to_object.getId(), 'test1')
    def test_unicode_links(self):
        doc1 = self.portal.doc1

        # This tests checks that hasIncomingLinks can now be used safely as it
        # eventually plays well with transaction machinery.
        # Add bad link, should not raise exception and there should not
        # be any references added.
        self._set_text(doc1,
                       unicode('<a href="ö?foo=bar&baz=bam">bug</a>', 'utf-8'))
        self.assertEqual([l for l in getOutgoingLinks(doc1)], [])
Example #16
0
    def test_update(self):
        doc1 = self.portal.doc1
        doc2 = self.portal.doc2
        doc4 = self.portal.folder1.doc4

        # This tests updating link integrity information for all site content,
        # i.e. after migrating from a previous version.
        self._set_text(doc1, '<a href="doc2">a document</a>')
        self._set_text(doc2, '<a href="folder1/doc4">a document</a>')

        catalog = getUtility(ICatalog)
        rels = [i for i in catalog.findRelations()]
        for rel in rels:
            catalog.unindex(rel)

        # Just to make sure, we check that there are no references from or to
        # these documents at this point:
        self.assertEqual([i.to_object for i in getOutgoingLinks(doc1)], [])
        self.assertEqual([i.to_object for i in getOutgoingLinks(doc2)], [])

        # An update of link integrity information for all content is triggered
        # by browsing a specific url:
        transaction.commit()
        self.browser.open('{0:s}/updateLinkIntegrityInformation'.format(
            self.portal.absolute_url()))
        self.browser.getControl('Update').click()
        self.assertIn('Link integrity information updated for',
                      self.browser.contents)

        # Now the linking documents should hold the correct link integrity
        # references:
        self.assertEqual(
            [i.to_object for i in getOutgoingLinks(doc1)],
            [
                doc2,
            ],
        )
        self.assertEqual(
            [i.to_object for i in getOutgoingLinks(doc2)],
            [
                doc4,
            ],
        )
Example #17
0
    def test_reference_orthogonality(self):
        doc = self.portal.doc1
        img = self.portal.image1
        tag = img.restrictedTraverse('@@images').tag()

        # This tests the behavior when other references already exist.
        self.assertEqual([l for l in getOutgoingLinks(doc)], [])
        self.assertEqual([l for l in getIncomingLinks(doc)], [])
        self.assertEqual([l for l in getOutgoingLinks(img)], [])
        self.assertEqual([l for l in getOutgoingLinks(img)], [])

        # Then establish a reference between the document and image as
        # a related item:
        self._set_related_items(doc, [
            img,
        ])
        self.assertEqual(self._get_related_items(doc), [
            img,
        ])

        # Next edit the document body and insert a link to the image,
        # which should trigger the creation of a link integrity reference:
        self._set_text(doc, tag)

        self.assertEqual([l.to_object for l in getOutgoingLinks(doc)], [img])

        # And the related item reference remains in place:
        self.assertEqual(self._get_related_items(doc), [
            img,
        ])

        # Finally, edit the document body again, this time removing the
        # link to the image, which should trigger the removal of the
        # link integrity reference:
        self._set_text(doc, 'where did my link go?')
        self.assertEqual([l.to_object for l in getOutgoingLinks(doc)], [])

        # And again the related item reference remains in place:
        self.assertEqual(self._get_related_items(doc), [
            img,
        ])
    def test_circular_reference_subfolder_deletion(self):
        doc1 = self.portal.doc1
        doc2 = self.portal.doc2
        doc3 = self.portal.doc3
        doc4 = self.portal.folder1.doc4
        folder1 = self.portal.folder1

        # This tests the behaviour when removing objects
        # referencing each other in a circle.
        self._set_text(doc1, '<a href="doc2">documents...</a>')
        self._set_text(doc2, '<a href="doc3">go round...</a>')
        self._set_text(doc3, '<a href="folder1/doc4">and round.</a>')
        self._set_text(doc4, '<a href="../doc1">in circles.</a>')

        self.assertEqual([r.to_object for r in getOutgoingLinks(doc1)], [doc2])
        self.assertEqual([r.to_object for r in getOutgoingLinks(doc2)], [doc3])
        self.assertEqual([r.to_object for r in getOutgoingLinks(doc3)], [doc4])
        self.assertEqual([r.to_object for r in getOutgoingLinks(doc4)], [doc1])

        view = DeleteConfirmationInfo(self.portal, self.request)
        self.assertEqual(len(view.get_breaches([folder1])), 1)
        self.assertEqual(
            len(view.get_breaches([doc1, doc2, doc3, folder1])), 0)
        self.assertEqual(len(view.get_breaches([doc2, folder1])), 2)
Example #19
0
    def test_circular_reference_subfolder_deletion(self):
        doc1 = self.portal.doc1
        doc2 = self.portal.doc2
        doc3 = self.portal.doc3
        doc4 = self.portal.folder1.doc4
        folder1 = self.portal.folder1

        # This tests the behaviour when removing objects
        # referencing each other in a circle.
        self._set_text(doc1, '<a href="doc2">documents...</a>')
        self._set_text(doc2, '<a href="doc3">go round...</a>')
        self._set_text(doc3, '<a href="folder1/doc4">and round.</a>')
        self._set_text(doc4, '<a href="../doc1">in circles.</a>')

        self.assertEqual([r.to_object for r in getOutgoingLinks(doc1)], [doc2])
        self.assertEqual([r.to_object for r in getOutgoingLinks(doc2)], [doc3])
        self.assertEqual([r.to_object for r in getOutgoingLinks(doc3)], [doc4])
        self.assertEqual([r.to_object for r in getOutgoingLinks(doc4)], [doc1])

        view = DeleteConfirmationInfo(self.portal, self.request)
        self.assertEqual(len(view.get_breaches([folder1])), 1)
        self.assertEqual(len(view.get_breaches([doc1, doc2, doc3, folder1])),
                         0)
        self.assertEqual(len(view.get_breaches([doc2, folder1])), 2)
Example #20
0
    def __call__(self):

        valid = True
        for link in getOutgoingLinks(self.context):
            state = api.content.get_state(obj=link.to_object, default='published')
            if state != 'published':
                valid = False
                break

        headers_ordered = True

        try:
            feed = SearchFeed(api.portal.get())
            adapter = queryMultiAdapter((self.context, feed), IFeedItem)
            html = adapter.render_content_core().strip()
        except Exception:
            html = ''

        if html:
            dom = fromstring(html)
            last = 1
            for el in dom.cssselect('h1,h2,h3,h4,h5,h6'):
                idx = int(el.tag[-1])
                if idx - last > 1:
                    # means they skipped from say h1 -> h5
                    # h1 -> h2 is allowed
                    headers_ordered = False
                    break
                last = idx

        is_template = False
        if ITemplate.providedBy(self.context):
            is_template = True

        self.request.response.setHeader('Content-type', 'application/json')
        return json.dumps({
            'title': self.context.Title(),
            'id': self.context.getId(),
            'description': self.context.Description(),
            'linksValid': valid,
            'headersOrdered': headers_ordered,
            'html': html_parser.unescape(html),
            'template': is_template
        })
    def test_removal_via_zmi(self):
        """Delete via ZMI is no longer protedted!"""
        doc1 = self.portal.doc1
        doc2 = self.portal.doc2

        # This tests ensuring link integrity when removing an object via
        # the ZMI.
        self._set_text(doc1, '<a href="doc2">a document</a>')
        self.assertEqual([i.to_object for i in getOutgoingLinks(doc1)], [doc2])

        transaction.commit()
        # Then we use a browser to try to delete the referenced
        # document. Before we can do this we need to prevent the test
        # framework from choking on the exception we intentionally throw.
        self.browser.handleErrors = True

        self.browser.open('http://nohost/plone/manage_main')
        self.browser\
            .getControl(name='ids:list')\
            .getControl(value='doc2').selected = True

        self.browser.getControl('Delete').click()
        self.assertNotIn('doc2', self.portal.objectIds())
Example #22
0
    def test_removal_via_zmi(self):
        """Delete via ZMI is no longer protedted!"""
        doc1 = self.portal.doc1
        doc2 = self.portal.doc2

        # This tests ensuring link integrity when removing an object via
        # the ZMI.
        self._set_text(doc1, '<a href="doc2">a document</a>')
        self.assertEqual([i.to_object for i in getOutgoingLinks(doc1)], [doc2])

        transaction.commit()
        # Then we use a browser to try to delete the referenced
        # document. Before we can do this we need to prevent the test
        # framework from choking on the exception we intentionally throw.
        self.browser.handleErrors = True

        self.browser.open('http://nohost/plone/manage_main')
        self.browser\
            .getControl(name='ids:list')\
            .getControl(value='doc2').selected = True

        self.browser.getControl('Delete').click()
        self.assertNotIn('doc2', self.portal.objectIds())
Example #23
0
    def test_breaking_header_links(self):
        page = self._create_page(_id='test1', text='''
<h1>Foobar 1</h1>
<p>foobar 1</p>
<h1>Foobar 2</h1>
<p>foobar 2</p>
<h2>Foobar 3</h2>
<p>foobar 3</p>
<h1>Foobar 4</h1>
<p>foobar 4</p>
''')
        page2 = self._create_page(_id='test2', text='''
<div data-type="snippet_tag"
     data-snippet-id="{}"
     data-header="Foobar 2"></div>'''.format(IUUID(page)))

        links = getOutgoingLinks(page2)  # should add link
        self.assertEqual([l for l in links][0].to_object.getId(), 'test1')
        links = getIncomingLinks(page)  # should add link
        self.assertEqual([l for l in links][0].from_object.getId(), 'test2')

        # now, remove the header...
        page.text = RichTextValue('''
<h1>Foobar 1</h1>
<p>foobar 1</p>
<h2>Foobar 3</h2>
<p>foobar 3</p>
<h1>Foobar 4</h1>
<p>foobar 4</p>
''', 'text/html', 'text/html')

        status_annotations = IAnnotations(self.request)
        self.assertFalse(bool(status_annotations.get(STATUSMESSAGEKEY)))

        checkSnippetReferences(page)

        self.assertTrue(bool(status_annotations.get(STATUSMESSAGEKEY)))
Example #24
0
 def test_relative_upwards_link_generates_matching_reference(self):
     doc1 = self.portal.doc1
     doc3 = self.portal.folder1.doc3
     self._set_text(doc3, '<a href="../doc1">go!</a>')
     self.assertEqual(len(list(getOutgoingLinks(doc1))), 0)
     self.assertEqual([l.to_object for l in getOutgoingLinks(doc3)], [doc1])