コード例 #1
0
    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])
コード例 #2
0
ファイル: info.py プロジェクト: plone/plone.app.linkintegrity
    def check_object(self, obj, excluded_path=None):
        """Check one object for breaches.

        Breaches originating from excluded_path are ignored.
        """
        breaches = {}
        direct_links = getIncomingLinks(obj)
        has_breaches = False
        for direct_link in direct_links:
            source_path = direct_link.from_path
            if not source_path:
                # link is broken
                continue
            if excluded_path and source_path.startswith(excluded_path):
                # source is in excluded_path
                continue
            source = direct_link.from_object
            if not breaches.get('sources'):
                breaches['sources'] = []
            breaches['sources'].append({
                'uid': IUUID(source),
                'title': source.Title(),
                'url': source.absolute_url(),
                'accessible': self.is_accessible(source),
            })
            has_breaches = True
        if has_breaches:
            breaches['target'] = {
                'uid': IUUID(obj),
                'title': obj.Title(),
                'url': obj.absolute_url(),
                'portal_type': obj.portal_type,
                'type_title': self.get_portal_type_title(obj),
            }
            return breaches
コード例 #3
0
    def check_object(self, obj, excluded_path=None):
        """Check one object for breaches.

        Breaches originating from excluded_path are ignored.
        """
        breaches = {}
        direct_links = getIncomingLinks(obj)
        has_breaches = False
        for direct_link in direct_links:
            source_path = direct_link.from_path
            if not source_path:
                # link is broken
                continue
            if excluded_path and source_path.startswith(excluded_path):
                # source is in excluded_path
                continue
            source = direct_link.from_object
            if not breaches.get('sources'):
                breaches['sources'] = []
            breaches['sources'].append({
                'uid': IUUID(source),
                'title': source.Title(),
                'url': source.absolute_url(),
                'accessible': self.is_accessible(source),
            })
            has_breaches = True
        if has_breaches:
            breaches['target'] = {
                'uid': IUUID(obj),
                'title': obj.Title(),
                'url': obj.absolute_url(),
                'portal_type': obj.portal_type,
                'type_title': self.get_portal_type_title(obj),
            }
            return breaches
コード例 #4
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, ])
コード例 #5
0
    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, ])
コード例 #6
0
    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, ])
コード例 #7
0
    def test_renaming_referenced_item(self):
        doc1 = self.portal.doc1
        doc2 = self.portal.doc2

        # This tests makes sure items that are linked to can still be
        # renamed (see the related bug report in #6608).  First we need
        # to create the necessary links:
        self._set_text(doc1, '<a href="doc2">doc2</a>')
        self.assertEqual([i.from_object for i in getIncomingLinks(doc2)],
                         [doc1])

        # Make changes visible to testbrowseropen
        transaction.commit()

        # Then we use a browser to rename the referenced image:
        self.browser.handleErrors = True
        self.browser.open('{0:s}/object_rename?_authenticator={1:s}'.format(
            doc1.absolute_url(), self._get_token(doc1)))

        self.browser.getControl(name='form.widgets.new_id').value = 'nuname'
        self.browser.getControl(name='form.buttons.Rename').click()
        self.assertIn("Renamed 'doc1' to 'nuname'.", self.browser.contents)
        transaction.commit()

        self.assertNotIn('doc1', self.portal.objectIds())
        self.assertIn('nuname', self.portal.objectIds())
        self.assertIn(doc1, [i.from_object for i in getIncomingLinks(doc2)])

        # We simply use a browser to try to delete a content item.
        self.browser.open(doc2.absolute_url())
        self.browser.getLink('Delete').click()
        self.assertIn('Do you really want to delete this item?',
                      self.browser.contents)
        self.assertIn('nuname', self.portal.objectIds())
        # Link breakabe page should be shown
        self.assertIn('Potential link breakage', self.browser.contents)
        self.assertIn('<a href="http://nohost/plone/nuname">Test Page 1</a>',
                      self.browser.contents)
        self.browser.getControl(name='form.buttons.Delete').click()
        self.assertNotIn('doc2', self.portal.objectIds())
コード例 #8
0
    def test_renaming_referenced_item(self):
        doc1 = self.portal.doc1
        doc2 = self.portal.doc2

        # This tests makes sure items that are linked to can still be
        # renamed (see the related bug report in #6608).  First we need
        # to create the necessary links:
        self._set_text(doc1, '<a href="doc2">doc2</a>')
        self.assertEqual(
            [i.from_object for i in getIncomingLinks(doc2)], [doc1])

        # Make changes visible to testbrowseropen
        transaction.commit()

        # Then we use a browser to rename the referenced image:
        self.browser.handleErrors = True
        self.browser.open('{0:s}/object_rename?_authenticator={1:s}'.format(
            doc1.absolute_url(), self._get_token(doc1)))

        self.browser.getControl(name='form.widgets.new_id').value = 'nuname'
        self.browser.getControl(name='form.buttons.Rename').click()
        self.assertIn("Renamed 'doc1' to 'nuname'.", self.browser.contents)
        transaction.commit()

        self.assertNotIn('doc1', self.portal.objectIds())
        self.assertIn('nuname', self.portal.objectIds())
        self.assertIn(doc1, [i.from_object for i in getIncomingLinks(doc2)])

        # We simply use a browser to try to delete a content item.
        self.browser.open(doc2.absolute_url())
        self.browser.getLink('Delete').click()
        self.assertIn(
            'Do you really want to delete this item?', self.browser.contents)
        self.assertIn('nuname', self.portal.objectIds())
        # Link breakabe page should be shown
        self.assertIn('Potential link breakage', self.browser.contents)
        self.assertIn('<a href="http://nohost/plone/nuname">Test Page 1</a>',
                      self.browser.contents)
        self.browser.getControl(name='form.buttons.Delete').click()
        self.assertNotIn('doc2', self.portal.objectIds())
コード例 #9
0
def checkSnippetReferences(obj):
    """
    Checks if this content is a snippet on any other content.
    If it is, make sure the header setting is not ruined
    """
    registry = getUtility(IRegistry)
    evaluator = ExpressionEvaluator()
    expression = Expression(
        registry.get('uwosh.snippets.render_expression',
                     'context/text/output|context/getText|nothing'))
    obj_headers = []
    html = evaluator.evaluate(expression, obj)
    if not html:
        return

    dom = fromstring(html)
    for el in dom.cssselect('h1,h2,h3,h4,h5,h6'):
        if el.text_content():
            obj_headers.append(el.text_content().strip())

    broken = []
    for link in getIncomingLinks(obj):
        if not link.from_object:
            continue
        for text in findTextAreas(link.from_object):
            if not text or not link.from_object:
                continue

            dom = fromstring(text)
            for el in dom.cssselect('[data-snippet-id="{}"]'.format(
                    IUUID(obj))):
                header = el.attrib.get('data-header')
                if not header:
                    continue
                if header not in obj_headers:
                    # broken reference
                    broken.append({'header': header, 'link': link.from_object})

    if len(broken) > 0:
        # show status message warning
        names = set()
        for b in broken:
            names.add('{}:{}'.format(b['link'].absolute_url(), b['header']))
        message = 'Broken snippet references: {}'.format(', '.join(names))
        api.portal.show_message(message=message,
                                request=getRequest(),
                                type='error')
コード例 #10
0
def checkSnippetReferences(obj):
    """
    Checks if this content is a snippet on any other content.
    If it is, make sure the header setting is not ruined
    """
    registry = getUtility(IRegistry)
    evaluator = ExpressionEvaluator()
    expression = Expression(registry.get('uwosh.snippets.render_expression',
                                         'context/text/output|context/getText|nothing'))
    obj_headers = []
    html = evaluator.evaluate(expression, obj)
    if not html:
        return

    dom = fromstring(html)
    for el in dom.cssselect('h1,h2,h3,h4,h5,h6'):
        if el.text_content():
            obj_headers.append(el.text_content().strip())

    broken = []
    for link in getIncomingLinks(obj):
        for text in findTextAreas(link.from_object):
            if not text:
                continue

            dom = fromstring(text)
            for el in dom.cssselect('[data-snippet-id="{}"]'.format(IUUID(obj))):
                header = el.attrib.get('data-header')
                if not header:
                    continue
                if header not in obj_headers:
                    # broken reference
                    broken.append({
                        'header': header,
                        'link': link.from_object
                    })

    if len(broken) > 0:
        # show status message warning
        names = set()
        for b in broken:
            names.add('{}:{}'.format(b['link'].absolute_url(), b['header']))
        message = 'Broken snippet references: {}'.format(
            ', '.join(names)
        )
        api.portal.show_message(message=message, request=getRequest(), type='error')
コード例 #11
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,
        ])
コード例 #12
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)))
コード例 #13
0
ファイル: info.py プロジェクト: FHNW/plone.app.linkintegrity
 def get_qch_warnings(self, items=None):
     if items is None:
         items = [self.context]
     qch_warnings = []
     catalog = getToolByName(self.context, 'portal_catalog')
     for to_del_object in items:
         temp = to_del_object.getPhysicalPath()
         obj_path = '/'.join(to_del_object.getPhysicalPath())+'/'
         subobjects = catalog.searchResults(path={'query': obj_path})
         for subobject in subobjects:
             links = getIncomingLinks(subobject.getObject())
             link_list = []
             for link in links:
                 #link_list.append(link.from_object.absolute_url())
                 add_to_list = True
                 for to_del in items:
                     to_del_path = to_del.absolute_url()+'/' #'/'.join(to_del.getPhysicalPath())+'/'
                     if to_del_path in link.from_object.absolute_url()+'/':
                         add_to_list = False
                 if add_to_list:
                     link_list.append(link.from_object.absolute_url())
             if len(link_list) > 0:
                 qch_warnings.append({'subobject': subobject.getURL(), 'subobjectPath': str(subobject.getPath()), 'links': link_list})
     return qch_warnings