Ejemplo n.º 1
0
 def test_redirect_suppression(self):
     """The document view shouldn't redirect when passed redirect=no."""
     redirect, _ = doc_rev('REDIRECT [[http://smoo/]]')
     response = self.client.get(
                    redirect.get_absolute_url() + '?redirect=no',
                    follow=True)
     self.assertContains(response, 'REDIRECT ')
Ejemplo n.º 2
0
    def test_form_save_section(self):
        d, r = doc_rev(
            """
            <h1 id="s1">s1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">s2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">s3</h1>
            <p>test</p>
            <p>test</p>
        """
        )
        replace_content = """
            <h1 id="s2">New stuff</h1>
            <p>new stuff</p>
        """
        expected = """
            <h1 id="s1">s1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">New stuff</h1>
            <p>new stuff</p>

            <h1 id="s3">s3</h1>
            <p>test</p>
            <p>test</p>
        """
        rev_form = RevisionForm({"content": replace_content}, instance=r, section_id="s2")
        new_rev = rev_form.save(r.creator, d)
        eq_(normalize_html(expected), normalize_html(new_rev.content))
Ejemplo n.º 3
0
    def test_raw_section_source(self):
        """The raw source for a document section can be requested"""
        client = LocalizingClient()
        client.login(username='******', password='******')
        d, r = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        expected = """
            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>
        """
        response = client.get('%s?section=s2&raw=true' %
                              reverse('wiki.document', args=[d.slug]))
        eq_(normalize_html(expected), 
            normalize_html(response.content))
Ejemplo n.º 4
0
    def test_form_loaded_with_section(self):
        """RevisionForm given section_id should load initial content for only
        one section"""
        d, r = doc_rev(
            """
            <h1 id="s1">s1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">s2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">s3</h1>
            <p>test</p>
            <p>test</p>
        """
        )
        expected = """
            <h1 id="s2">s2</h1>
            <p>test</p>
            <p>test</p>
        """
        rev_form = RevisionForm(instance=r, section_id="s2")
        eq_(normalize_html(expected), normalize_html(rev_form.initial["content"]))
Ejemplo n.º 5
0
    def test_raw_with_editing_links_source(self):
        """The raw source for a document can be requested, with section editing
        links"""
        client = LocalizingClient()
        client.login(username='******', password='******')
        d, r = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        expected = """
            <h1 id="s1"><a class="edit-section" data-section-id="s1" data-section-src-url="/en-US/docs/%(slug)s?raw=true&amp;section=s1" href="/en-US/docs/%(slug)s$edit?section=s1&amp;edit_links=true" title="Edit section">Edit</a>Head 1</h1>
            <p>test</p>
            <p>test</p>
            <h1 id="s2"><a class="edit-section" data-section-id="s2" data-section-src-url="/en-US/docs/%(slug)s?raw=true&amp;section=s2" href="/en-US/docs/%(slug)s$edit?section=s2&amp;edit_links=true" title="Edit section">Edit</a>Head 2</h1>
            <p>test</p>
            <p>test</p>
            <h1 id="s3"><a class="edit-section" data-section-id="s3" data-section-src-url="/en-US/docs/%(slug)s?raw=true&amp;section=s3" href="/en-US/docs/%(slug)s$edit?section=s3&amp;edit_links=true" title="Edit section">Edit</a>Head 3</h1>
            <p>test</p>
            <p>test</p>
        """ % {'slug': d.slug}
        response = client.get('%s?raw=true&edit_links=true' %
                              reverse('wiki.document', args=[d.slug]))
        eq_(normalize_html(expected), 
            normalize_html(response.content))
Ejemplo n.º 6
0
 def setUp(self):
     super(DeferredRenderingTests, self).setUp()
     self.rendered_content = 'THIS IS RENDERED'
     self.raw_content = 'THIS IS NOT RENDERED CONTENT'
     self.d1, self.r1 = doc_rev('Doc 1')
     constance.config.KUMA_DOCUMENT_RENDER_TIMEOUT = 600.0
     constance.config.KUMA_DOCUMENT_FORCE_DEFERRED_TIMEOUT = 7.0
Ejemplo n.º 7
0
 def test_form_onload_attr_filter(self):
     """RevisionForm should strip out any harmful onload attributes from
     input markup"""
     d, r = doc_rev("""
         <svg><circle onload=confirm(3)>
     """)
     rev_form = RevisionForm(instance=r)
     ok_('onload' not in rev_form.initial['content'])
Ejemplo n.º 8
0
    def test_unapproved_revision_not_updates_html(self):
        """Creating an unapproved revision does not update document.html"""
        d, _ = doc_rev('Here to stay')

        assert 'Here to stay' in d.html, '"Here to stay" not in %s' % d.html

        # Creating another approved revision keeps initial content
        r = revision(document=d, content='Fail to replace html')
        r.save()

        assert 'Here to stay' in d.html, '"Here to stay" not in %s' % d.html
Ejemplo n.º 9
0
    def test_approved_revision_updates_html(self):
        """Creating an approved revision updates document.html"""
        d, _ = doc_rev("Replace document html")

        assert "Replace document html" in d.html, '"Replace document html" not in %s' % d.html

        # Creating another approved revision replaces it again
        r = revision(document=d, content="Replace html again", is_approved=True)
        r.save()

        assert "Replace html again" in d.html, '"Replace html again" not in %s' % d.html
Ejemplo n.º 10
0
 def test_retitling(self):
     """When the title of an article is edited, a redirect is made."""
     # Not testing slug changes separately; the model tests cover those plus
     # slug+title changes. If title changes work in the view, the rest
     # should also.
     new_title = "Some New Title"
     d, r = doc_rev()
     old_title = d.title
     data = new_document_data()
     data.update({"title": new_title, "slug": d.slug, "form": "doc"})
     self.client.post(reverse("wiki.edit_document", args=[d.slug]), data)
     eq_(new_title, Document.uncached.get(slug=d.slug).title)
     assert Document.uncached.get(title=old_title).redirect_url()
Ejemplo n.º 11
0
 def test_changing_products(self):
     """Changing products works as expected."""
     d, r = doc_rev()
     data = new_document_data()
     data.update({'products': ['desktop', 'sync'],
                  'form': 'doc'})
     self.client.post(reverse('wiki.edit_document', args=[d.slug]), data)
     tags_eq(d, ['desktop', 'sync'])
     data.update({'products': ['mobile'],
                  'form': 'doc'})
     self.client.post(reverse('wiki.edit_document', args=[data['slug']]),
                      data)
     tags_eq(d, ['mobile'])
Ejemplo n.º 12
0
 def test_changing_products(self):
     """Changing products works as expected."""
     client = LocalizingClient()
     client.login(username='******', password='******')
     d, r = doc_rev()
     data = new_document_data()
     data.update({'products': ['desktop', 'sync'],
                  'form': 'doc'})
     client.post(reverse('wiki.edit_document', args=[d.slug]), data)
     tags_eq(d, ['desktop', 'sync'])
     data.update({'products': ['mobile'],
                  'form': 'doc'})
     client.post(reverse('wiki.edit_document', args=[data['slug']]), data)
     tags_eq(d, ['mobile'])
Ejemplo n.º 13
0
 def test_retitling_ignored_for_iframe(self):
     """When the title of an article is edited in an iframe, the change is
     ignored."""
     client = LocalizingClient()
     client.login(username='******', password='******')
     new_title = 'Some New Title'
     d, r = doc_rev()
     old_title = d.title
     data = new_document_data()
     data.update({'title': new_title,
                  'slug': d.slug,
                  'form': 'rev'})
     client.post('%s?iframe=1' % reverse('wiki.edit_document', args=[d.slug]), data)
     eq_(old_title, Document.uncached.get(slug=d.slug).title)
     assert "REDIRECT" not in Document.uncached.get(title=old_title).html
Ejemplo n.º 14
0
    def test_raw_section_edit(self):
        client = LocalizingClient()
        client.login(username='******', password='******')
        d, r = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        replace = """
            <h1 id="s2">Replace</h1>
            <p>replace</p>
        """
        expected = """
            <h1 id="s2">Replace</h1>
            <p>replace</p>
        """
        response = client.post('%s?section=s2&raw=true' %
                               reverse('wiki.edit_document', args=[d.slug]),
                               {"form": "rev",
                                "content": replace},
                               follow=True)
        eq_(normalize_html(expected), 
            normalize_html(response.content))

        expected = """
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Replace</h1>
            <p>replace</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """
        response = client.get('%s?raw=true' %
                               reverse('wiki.document', args=[d.slug]))
        eq_(normalize_html(expected), 
            normalize_html(response.content))
Ejemplo n.º 15
0
    def test_show_toc(self):
        """Setting show_toc appropriately affects the Document's
        show_toc property."""
        d, r = doc_rev('Toggle table of contents.')
        assert r.show_toc
        assert d.show_toc

        r = revision(document=d, content=r.content, show_toc=False,
                     is_approved=True)
        r.save()
        assert not d.show_toc

        r = revision(document=d, content=r.content, show_toc=True,
                     is_approved=True)
        r.save()
        assert d.show_toc
Ejemplo n.º 16
0
 def test_retitling(self):
     """When the title of an article is edited, a redirect is made."""
     # Not testing slug changes separately; the model tests cover those plus
     # slug+title changes. If title changes work in the view, the rest
     # should also.
     client = LocalizingClient()
     client.login(username='******', password='******')
     new_title = 'Some New Title'
     d, r = doc_rev()
     old_title = d.title
     data = new_document_data()
     data.update({'title': new_title,
                  'slug': d.slug,
                  'form': 'doc'})
     client.post(reverse('wiki.edit_document', args=[d.slug]), data)
     eq_(new_title, Document.uncached.get(slug=d.slug).title)
     assert Document.uncached.get(title=old_title).redirect_url()
Ejemplo n.º 17
0
 def test_changing_metadata(self):
     """Changing metadata works as expected."""
     client = LocalizingClient()
     client.login(username='******', password='******')
     d, r = doc_rev()
     data = new_document_data()
     data.update({'firefox_versions': [1, 2, 3],
                  'operating_systems': [1, 3],
                  'form': 'doc'})
     client.post(reverse('wiki.edit_document', args=[d.slug]), data)
     eq_(3, d.firefox_versions.count())
     eq_(2, d.operating_systems.count())
     data.update({'firefox_versions': [1, 2],
                  'operating_systems': [2],
                  'form': 'doc'})
     client.post(reverse('wiki.edit_document', args=[data['slug']]), data)
     eq_(2, d.firefox_versions.count())
     eq_(1, d.operating_systems.count())
Ejemplo n.º 18
0
    def test_revert(self):
        """Reverting to a specific revision."""
        d, r = doc_rev('Test reverting')
        old_id = r.id

        time.sleep(1)

        r2 = revision(document=d, title='Test reverting',
                      content='An edit to revert',
                      comment='This edit gets reverted',
                      is_approved=True)
        r.save()

        time.sleep(1)

        reverted = d.revert(r, r.creator)
        ok_('Revert to' in reverted.comment)
        ok_('Test reverting' == reverted.content)
        ok_(old_id != reverted.id)
Ejemplo n.º 19
0
    def test_revision_tags(self):
        """Change tags on Document by creating Revisions"""
        d, _ = doc_rev('Sample document')

        eq_(0, Document.objects.filter(tags__name='foo').count())
        eq_(0, Document.objects.filter(tags__name='alpha').count())

        r = revision(document=d, content='Update to document',
                     is_approved=True, tags="foo, bar, baz")
        r.save()

        eq_(1, Document.objects.filter(tags__name='foo').count())
        eq_(0, Document.objects.filter(tags__name='alpha').count())

        r = revision(document=d, content='Another update',
                     is_approved=True, tags="alpha, beta, gamma")
        r.save()

        eq_(0, Document.objects.filter(tags__name='foo').count())
        eq_(1, Document.objects.filter(tags__name='alpha').count())
Ejemplo n.º 20
0
    def test_changing_products(self):
        """Changing products works as expected."""
        d, r = doc_rev()
        prod_desktop = product(title=u"desktop", save=True)
        prod_mobile = product(title=u"mobile", save=True)

        data = new_document_data()
        data.update({"products": [prod_desktop.id, prod_mobile.id], "title": d.title, "slug": d.slug, "form": "doc"})
        self.client.post(reverse("wiki.edit_document", args=[d.slug]), data)

        eq_(
            sorted(Document.uncached.get(slug=d.slug).products.values_list("id", flat=True)),
            sorted([prod.id for prod in [prod_desktop, prod_mobile]]),
        )

        data.update({"products": [prod_desktop.id], "form": "doc"})
        self.client.post(reverse("wiki.edit_document", args=[data["slug"]]), data)
        eq_(
            sorted(Document.uncached.get(slug=d.slug).products.values_list("id", flat=True)),
            sorted([prod.id for prod in [prod_desktop]]),
        )
Ejemplo n.º 21
0
    def test_trans_lock_workflow(self):
        """End to end test of locking on a translated document."""
        doc, _ = doc_rev()
        u = user(save=True, password='******')

        # Create a new translation of doc() using the translation view
        self.client.login(username=u.username, password='******')
        trans_url = reverse('wiki.translate', locale='es', args=[doc.slug])
        data = {
            'title': 'Un Test Articulo',
            'slug': 'un-test-articulo',
            'keywords': 'keyUno, keyDos, keyTres',
            'summary': 'lipsumo',
            'content': 'loremo ipsumo doloro sito ameto'}
        r = self.client.post(trans_url, data)
        eq_(r.status_code, 302)

        # Now run the test.
        edit_url = reverse('wiki.edit_document', locale='es', args=[data['slug']])
        es_doc = Document.objects.get(slug=data['slug'])
        eq_(es_doc.locale, 'es')
        self._lock_workflow(es_doc, edit_url)
Ejemplo n.º 22
0
    def test_trans_lock_workflow(self):
        """End to end test of locking on a translated document."""
        doc, _ = doc_rev()
        u = user(save=True, password="******")

        # Create a new translation of doc() using the translation view
        self.client.login(username=u.username, password="******")
        trans_url = reverse("wiki.translate", locale="es", args=[doc.slug])
        data = {
            "title": "Un Test Articulo",
            "slug": "un-test-articulo",
            "keywords": "keyUno, keyDos, keyTres",
            "summary": "lipsumo",
            "content": "loremo ipsumo doloro sito ameto",
        }
        r = self.client.post(trans_url, data)
        eq_(r.status_code, 302)

        # Now run the test.
        edit_url = reverse("wiki.edit_document", locale="es", args=[data["slug"]])
        es_doc = Document.objects.get(slug=data["slug"])
        eq_(es_doc.locale, "es")
        self._lock_workflow(es_doc, edit_url)
Ejemplo n.º 23
0
    def test_changing_products(self):
        """Changing products works as expected."""
        d, r = doc_rev()
        prod_desktop = product(title=u'desktop', save=True)
        prod_mobile = product(title=u'mobile', save=True)

        data = new_document_data()
        data.update({'products': [prod_desktop.id, prod_mobile.id],
                     'title': d.title,
                     'slug': d.slug,
                     'form': 'doc'})
        self.client.post(reverse('wiki.edit_document', args=[d.slug]), data)

        eq_(sorted(Document.uncached.get(slug=d.slug).products.values_list(
                    'id', flat=True)),
            sorted([prod.id for prod in [prod_desktop, prod_mobile]]))

        data.update({'products': [prod_desktop.id],
                     'form': 'doc'})
        self.client.post(reverse('wiki.edit_document', args=[data['slug']]),
                         data)
        eq_(sorted(Document.uncached.get(slug=d.slug).products.values_list(
                    'id', flat=True)),
            sorted([prod.id for prod in [prod_desktop]]))
Ejemplo n.º 24
0
 def test_revision_unicode(self):
     """Revision containing unicode characters is saved successfully."""
     str = u'Firefox informa\xe7\xf5es \u30d8\u30eb'
     _, r = doc_rev(str)
     eq_(str, r.content)
Ejemplo n.º 25
0
 def setUp(self):
     self.d, self.r = doc_rev()
     self.old_title = self.d.title
     self.old_slug = self.d.slug
Ejemplo n.º 26
0
    def test_link_annotation(self):
        d, r = doc_rev("This document exists")
        d.save()
        r.save()

        d2 = document(title=u"Héritée", locale=u"fr", slug=u"CSS/Héritage", save=True)

        base_url = u"http://testserver/"
        vars = dict(
            base_url=base_url,
            exist_url=d.get_absolute_url(),
            exist_url_with_base=urljoin(base_url, d.get_absolute_url()),
            uilocale_url=u"/en-US/docs/%s/%s" % (d.locale, d.slug),
            noexist_url=u"/en-US/docs/no-such-doc",
            noexist_url_with_base=urljoin(base_url, u"/en-US/docs/no-such-doc"),
            noexist_uilocale_url=u"/en-US/docs/en-US/blah-blah-blah",
            nonen_slug="/fr/docs/CSS/H%c3%a9ritage",
            tag_url="/en-US/docs/tag/foo",
            feed_url="/en-US/docs/feeds/atom/all",
            templates_url="/en-US/docs/templates",
        )
        doc_src = (
            u"""
                <li><a href="%(nonen_slug)s">Héritée</a></li>
                <li><a href="%(exist_url)s">This doc should exist</a></li>
                <li><a href="%(exist_url)s#withanchor">This doc should exist</a></li>
                <li><a href="%(exist_url_with_base)s">This doc should exist</a></li>
                <li><a href="%(exist_url_with_base)s#withanchor">This doc should exist</a></li>
                <li><a href="%(uilocale_url)s">This doc should exist</a></li>
                <li><a class="foobar" href="%(exist_url)s">This doc should exist, and its class should be left alone.</a></li>
                <li><a href="%(noexist_url)s#withanchor">This doc should NOT exist</a></li>
                <li><a href="%(noexist_url)s">This doc should NOT exist</a></li>
                <li><a href="%(noexist_url_with_base)s">This doc should NOT exist</a></li>
                <li><a href="%(noexist_url_with_base)s#withanchor">This doc should NOT exist</a></li>
                <li><a href="%(noexist_uilocale_url)s">This doc should NOT exist</a></li>
                <li><a class="foobar" href="%(noexist_url)s">This doc should NOT exist, and its class should be altered</a></li>
                <li><a href="http://mozilla.org/">This is an external link</a></li>
                <li><a class="foobar" name="quux">A lack of href should not cause a problem.</a></li>
                <li><a>In fact, a "link" with no attributes should be no problem as well.</a></li>
                <a href="%(tag_url)s">Tag link</a>
                <a href="%(feed_url)s">Feed link</a>
                <a href="%(templates_url)s">Templates link</a>
        """
            % vars
        )
        expected = (
            u"""
                <li><a href="%(nonen_slug)s">Héritée</a></li>
                <li><a href="%(exist_url)s">This doc should exist</a></li>
                <li><a href="%(exist_url)s#withanchor">This doc should exist</a></li>
                <li><a href="%(exist_url_with_base)s">This doc should exist</a></li>
                <li><a href="%(exist_url_with_base)s#withanchor">This doc should exist</a></li>
                <li><a href="%(uilocale_url)s">This doc should exist</a></li>
                <li><a class="foobar" href="%(exist_url)s">This doc should exist, and its class should be left alone.</a></li>
                <li><a class="new" href="%(noexist_url)s#withanchor">This doc should NOT exist</a></li>
                <li><a class="new" href="%(noexist_url)s">This doc should NOT exist</a></li>
                <li><a class="new" href="%(noexist_url_with_base)s">This doc should NOT exist</a></li>
                <li><a class="new" href="%(noexist_url_with_base)s#withanchor">This doc should NOT exist</a></li>
                <li><a class="new" href="%(noexist_uilocale_url)s">This doc should NOT exist</a></li>
                <li><a class="foobar new" href="%(noexist_url)s">This doc should NOT exist, and its class should be altered</a></li>
                <li><a class="external" href="http://mozilla.org/">This is an external link</a></li>
                <li><a class="foobar" name="quux">A lack of href should not cause a problem.</a></li>
                <li><a>In fact, a "link" with no attributes should be no problem as well.</a></li>
                <a href="%(tag_url)s">Tag link</a>
                <a href="%(feed_url)s">Feed link</a>
                <a href="%(templates_url)s">Templates link</a>
        """
            % vars
        )

        # Split the markup into lines, to better see failures
        doc_lines = doc_src.strip().split("\n")
        expected_lines = expected.strip().split("\n")
        for idx in range(0, len(doc_lines)):
            doc_line = doc_lines[idx]
            expected_line = expected_lines[idx]
            result_line = wiki.content.parse(doc_line).annotateLinks(base_url=vars["base_url"]).serialize()
            eq_(normalize_html(expected_line), normalize_html(result_line))
Ejemplo n.º 27
0
    def test_link_annotation(self):
        d, r = doc_rev("This document exists")
        d.save()
        r.save()

        d2 = document(title=u'Héritée',
                      locale=u'fr',
                      slug=u'CSS/Héritage',
                      save=True)

        base_url = u'http://testserver/'
        vars = dict(
            base_url=base_url,
            exist_url=d.get_absolute_url(),
            exist_url_with_base=urljoin(base_url, d.get_absolute_url()),
            uilocale_url=u'/en-US/docs/%s/%s' % (d.locale, d.slug),
            noexist_url=u'/en-US/docs/no-such-doc',
            noexist_url_with_base=urljoin(base_url,
                                          u'/en-US/docs/no-such-doc'),
            noexist_uilocale_url=u'/en-US/docs/en-US/blah-blah-blah',
            nonen_slug='/fr/docs/CSS/H%c3%a9ritage',
        )
        doc_src = u"""
                <li><a href="%(nonen_slug)s">Héritée</a></li>
                <li><a href="%(exist_url)s">This doc should exist</a></li>
                <li><a href="%(exist_url)s#withanchor">This doc should exist</a></li>
                <li><a href="%(exist_url_with_base)s">This doc should exist</a></li>
                <li><a href="%(exist_url_with_base)s#withanchor">This doc should exist</a></li>
                <li><a href="%(uilocale_url)s">This doc should exist</a></li>
                <li><a class="foobar" href="%(exist_url)s">This doc should exist, and its class should be left alone.</a></li>
                <li><a href="%(noexist_url)s#withanchor">This doc should NOT exist</a></li>
                <li><a href="%(noexist_url)s">This doc should NOT exist</a></li>
                <li><a href="%(noexist_url_with_base)s">This doc should NOT exist</a></li>
                <li><a href="%(noexist_url_with_base)s#withanchor">This doc should NOT exist</a></li>
                <li><a href="%(noexist_uilocale_url)s">This doc should NOT exist</a></li>
                <li><a class="foobar" href="%(noexist_url)s">This doc should NOT exist, and its class should be altered</a></li>
                <li><a href="http://mozilla.org/">This is an external link</a></li>
                <li><a class="foobar" name="quux">A lack of href should not cause a problem.</a></li>
                <li><a>In fact, a "link" with no attributes should be no problem as well.</a></li>
        """ % vars
        expected = u"""
                <li><a href="%(nonen_slug)s">Héritée</a></li>
                <li><a href="%(exist_url)s">This doc should exist</a></li>
                <li><a href="%(exist_url)s#withanchor">This doc should exist</a></li>
                <li><a href="%(exist_url_with_base)s">This doc should exist</a></li>
                <li><a href="%(exist_url_with_base)s#withanchor">This doc should exist</a></li>
                <li><a href="%(uilocale_url)s">This doc should exist</a></li>
                <li><a class="foobar" href="%(exist_url)s">This doc should exist, and its class should be left alone.</a></li>
                <li><a class="new" href="%(noexist_url)s#withanchor">This doc should NOT exist</a></li>
                <li><a class="new" href="%(noexist_url)s">This doc should NOT exist</a></li>
                <li><a class="new" href="%(noexist_url_with_base)s">This doc should NOT exist</a></li>
                <li><a class="new" href="%(noexist_url_with_base)s#withanchor">This doc should NOT exist</a></li>
                <li><a class="new" href="%(noexist_uilocale_url)s">This doc should NOT exist</a></li>
                <li><a class="foobar new" href="%(noexist_url)s">This doc should NOT exist, and its class should be altered</a></li>
                <li><a class="external" href="http://mozilla.org/">This is an external link</a></li>
                <li><a class="foobar" name="quux">A lack of href should not cause a problem.</a></li>
                <li><a>In fact, a "link" with no attributes should be no problem as well.</a></li>
        """ % vars

        # Split the markup into lines, to better see failures
        doc_lines = doc_src.strip().split("\n")
        expected_lines = expected.strip().split("\n")
        for idx in range(0, len(doc_lines)):
            doc_line = doc_lines[idx]
            expected_line = expected_lines[idx]
            result_line = (wiki.content.parse(doc_line).annotateLinks(
                base_url=vars['base_url']).serialize())
            eq_(normalize_html(expected_line), normalize_html(result_line))
Ejemplo n.º 28
0
 def setUp(self):
     self.d, self.r = doc_rev()
     self.old_title = self.d.title
     self.old_slug = self.d.slug
Ejemplo n.º 29
0
 def test_revision_unicode(self):
     """Revision containing unicode characters is saved successfully."""
     str = u' \r\nFirefox informa\xe7\xf5es \u30d8\u30eb'
     _, r = doc_rev(str)
     eq_(str, r.content)
Ejemplo n.º 30
0
    def test_midair_section_merge(self):
        """If a page was changed while someone was editing, but the changes
        didn't affect the specific section being edited, then ignore the midair
        warning"""
        client = LocalizingClient()
        client.login(username='******', password='******')

        doc, rev = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        replace_1 = """
            <h1 id="s1">replace</h1>
            <p>replace</p>
        """
        replace_2 = """
            <h1 id="s2">replace</h1>
            <p>replace</p>
        """
        expected = """
            <h1 id="s1">replace</h1>
            <p>replace</p>

            <h1 id="s2">replace</h1>
            <p>replace</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """
        data = {'form': 'rev', 'content': rev.content}

        # Edit #1 starts...
        resp = client.get('%s?section=s1' %
                          reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id1 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 starts...
        resp = client.get('%s?section=s2' %
                          reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id2 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 submits successfully
        data.update({
            'form': 'rev',
            'content': replace_2,
            'current_rev': rev_id2
        })
        resp = client.post(
            '%s?section=s2&raw=true' %
            reverse('wiki.edit_document', args=[doc.slug]), data)
        eq_(302, resp.status_code)

        # Edit #1 submits, but since it's a different section, there's no
        # mid-air collision
        data.update({
            'form': 'rev',
            'content': replace_1,
            'current_rev': rev_id1
        })
        resp = client.post(
            '%s?section=s1&raw=true' %
            reverse('wiki.edit_document', args=[doc.slug]), data)
        # No conflict, but we should get a 205 Reset as an indication that the
        # page needs a refresh.
        eq_(205, resp.status_code)

        # Finally, make sure that all the edits landed
        response = client.get('%s?raw=true' %
                              reverse('wiki.document', args=[doc.slug]))
        eq_(normalize_html(expected), normalize_html(response.content))

        # Also, ensure that the revision is slipped into the headers
        eq_(unicode(Document.uncached.get(slug=doc.slug).current_revision.id),
            unicode(response['x-kuma-revision']))
Ejemplo n.º 31
0
    def test_roundtrip(self):
        # Create some documents and revisions here, rather than use a fixture
        d1, r1 = doc_rev('Doc 1')
        d2, r2 = doc_rev('Doc 2')
        d3, r3 = doc_rev('Doc 3')
        d4, r4 = doc_rev('Doc 4')
        d5, r5 = doc_rev('Doc 5')

        # Since this happens in dev sometimes, break a doc by deleting its
        # current revision and leaving it with none.
        d5.current_revision = None
        d5.save()
        r5.delete()

        # The same creator will be used for all the revs, so let's also get a
        # non-creator user for the upload.
        creator = r1.creator
        uploader = User.objects.exclude(pk=creator.id).all()[0]

        # Count docs (with revisions) and revisions in DB
        doc_cnt_db = (Document.objects
                      .filter(current_revision__isnull=False)
                      .count())
        rev_cnt_db = (Revision.objects.count())

        # Do the dump, capture it, parse the JSON
        fin = StringIO()
        Document.objects.dump_json(Document.objects.all(), fin)
        data_json = fin.getvalue()
        data = json.loads(data_json)

        # No objects should come with non-null primary keys
        for x in data:
            ok_(not x['pk'])

        # Count the documents in JSON vs the DB
        doc_cnt_json = len([x for x in data if x['model'] == 'wiki.document'])
        eq_(doc_cnt_db, doc_cnt_json,
            "DB and JSON document counts should match")

        # Count the revisions in JSON vs the DB
        rev_cnt_json = len([x for x in data if x['model'] == 'wiki.revision'])
        eq_(rev_cnt_db, rev_cnt_json,
            "DB and JSON revision counts should match")

        # For good measure, ensure no documents missing revisions in the dump.
        doc_no_rev = (Document.objects
                      .filter(current_revision__isnull=True))[0]
        no_rev_cnt = len([x for x in data
                          if x['model'] == 'wiki.document' and
                             x['fields']['slug'] == doc_no_rev.slug and
                             x['fields']['locale'] == doc_no_rev.locale])
        eq_(0, no_rev_cnt,
            "There should be no document exported without revision")

        # Upload the data as JSON, assert that all objects were loaded
        loaded_cnt = Document.objects.load_json(uploader, StringIO(data_json))
        eq_(len(data), loaded_cnt)

        # Ensure the current revisions of the documents have changed, and that
        # the creator matches the uploader.
        for d_orig in (d1, d2, d3, d4):
            d_curr = Document.uncached.get(pk=d_orig.pk)
            eq_(2, d_curr.revisions.count())
            ok_(d_orig.current_revision.id != d_curr.current_revision.id)
            ok_(d_orig.current_revision.creator_id !=
                d_curr.current_revision.creator_id)
            eq_(uploader.id, d_curr.current_revision.creator_id)

        # Everyone out of the pool!
        Document.objects.all().delete()
        Revision.objects.all().delete()

        # Try reloading the data on an empty DB
        loaded_cnt = Document.objects.load_json(uploader, StringIO(data_json))
        eq_(len(data), loaded_cnt)

        # Count docs (with revisions) and revisions in DB. The imported objects
        # should have beeen doc/rev pairs.
        eq_(loaded_cnt / 2, Document.objects.count())
        eq_(loaded_cnt / 2, Revision.objects.count())

        # The originals should be gone, now.
        for d_orig in (d1, d2, d3, d4):

            # The original primary key should have gone away.
            try:
                d_curr = Document.uncached.get(pk=d_orig.pk)
                ok_(False, "This should have been an error")
            except Document.DoesNotExist:
                pass

            # Should be able to fetch document with the original natural key
            key = d_orig.natural_key()
            d_curr = Document.objects.get_by_natural_key(*key)
            eq_(1, d_curr.revisions.count())
            eq_(uploader.id, d_curr.current_revision.creator_id)
Ejemplo n.º 32
0
    def test_midair_section_collision(self):
        """If both a revision and the edited section has changed, then a
        section edit is a collision."""
        client = LocalizingClient()
        client.login(username='******', password='******')

        doc, rev = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        replace_1 = """
            <h1 id="s2">replace</h1>
            <p>replace</p>
        """
        replace_2 = """
            <h1 id="s2">first replace</h1>
            <p>first replace</p>
        """
        data = {
            'form': 'rev',
            'content': rev.content
        }

        # Edit #1 starts...
        resp = client.get('%s?section=s2' % 
                          reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id1 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 starts...
        resp = client.get('%s?section=s2' % 
                          reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id2 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 submits successfully
        data.update({
            'form': 'rev',
            'content': replace_2,
            'current_rev': rev_id2
        })
        resp = client.post('%s?section=s2&raw=true' %
                            reverse('wiki.edit_document', args=[doc.slug]),
                            data)
        eq_(302, resp.status_code)

        # Edit #1 submits, but since it's the same section, there's a collision
        data.update({
            'form': 'rev',
            'content': replace_1,
            'current_rev': rev_id1
        })
        resp = client.post('%s?section=s2&raw=true' %
                           reverse('wiki.edit_document', args=[doc.slug]),
                           data)
        # With the raw API, we should get a 409 Conflict on collision.
        eq_(409, resp.status_code)
Ejemplo n.º 33
0
 def test_doc_lock_workflow(self):
     """End to end test of locking on an english document."""
     doc, rev = doc_rev()
     url = reverse('wiki.edit_document', args=[doc.slug], locale='en-US')
     self._lock_workflow(doc, url)
Ejemplo n.º 34
0
    def test_midair_section_collision(self):
        """If both a revision and the edited section has changed, then a
        section edit is a collision."""
        client = LocalizingClient()
        client.login(username='******', password='******')

        doc, rev = doc_rev("""
            <h1 id="s1">Head 1</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s2">Head 2</h1>
            <p>test</p>
            <p>test</p>

            <h1 id="s3">Head 3</h1>
            <p>test</p>
            <p>test</p>
        """)
        replace_1 = """
            <h1 id="s2">replace</h1>
            <p>replace</p>
        """
        replace_2 = """
            <h1 id="s2">first replace</h1>
            <p>first replace</p>
        """
        data = {'form': 'rev', 'content': rev.content}

        # Edit #1 starts...
        resp = client.get('%s?section=s2' %
                          reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id1 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 starts...
        resp = client.get('%s?section=s2' %
                          reverse('wiki.edit_document', args=[doc.slug]))
        page = pq(resp.content)
        rev_id2 = page.find('input[name="current_rev"]').attr('value')

        # Edit #2 submits successfully
        data.update({
            'form': 'rev',
            'content': replace_2,
            'current_rev': rev_id2
        })
        resp = client.post(
            '%s?section=s2&raw=true' %
            reverse('wiki.edit_document', args=[doc.slug]), data)
        eq_(302, resp.status_code)

        # Edit #1 submits, but since it's the same section, there's a collision
        data.update({
            'form': 'rev',
            'content': replace_1,
            'current_rev': rev_id1
        })
        resp = client.post(
            '%s?section=s2&raw=true' %
            reverse('wiki.edit_document', args=[doc.slug]), data)
        # With the raw API, we should get a 409 Conflict on collision.
        eq_(409, resp.status_code)
Ejemplo n.º 35
0
 def test_doc_lock_workflow(self):
     """End to end test of locking on an english document."""
     doc, rev = doc_rev()
     url = reverse('wiki.edit_document', args=[doc.slug], locale='en-US')
     self._lock_workflow(doc, url)
Ejemplo n.º 36
0
    def test_link_annotation(self):
        d, r = doc_rev("This document exists")
        d.save()
        r.save()

        document(title=u'Héritée', locale=u'fr', slug=u'CSS/Héritage',
                 save=True)
        document(title=u'DOM/StyleSheet', locale=u'en-US',
                 slug=u'DOM/StyleSheet', save=True)

        base_url = u'http://testserver/'
        vars = dict(
            base_url=base_url,
            exist_url=d.get_absolute_url(),
            exist_url_with_base=urljoin(base_url, d.get_absolute_url()),
            uilocale_url=u'/en-US/docs/%s/%s' % (d.locale, d.slug),
            noexist_url=u'/en-US/docs/no-such-doc',
            noexist_url_with_base=urljoin(base_url,
                                          u'/en-US/docs/no-such-doc'),
            noexist_uilocale_url=u'/en-US/docs/en-US/blah-blah-blah',
            nonen_slug='/fr/docs/CSS/H%c3%a9ritage',
            tag_url='/en-US/docs/tag/foo',
            feed_url='/en-US/docs/feeds/atom/all',
            templates_url='/en-US/docs/templates',
        )
        doc_src = u"""
                <li><a href="%(nonen_slug)s">Héritée</a></li>
                <li><a href="%(exist_url)s">This doc should exist</a></li>
                <li><a href="%(exist_url)s#withanchor">This doc should exist</a></li>
                <li><a href="%(exist_url_with_base)s">This doc should exist</a></li>
                <li><a href="%(exist_url_with_base)s#withanchor">This doc should exist</a></li>
                <li><a href="%(uilocale_url)s">This doc should exist</a></li>
                <li><a class="foobar" href="%(exist_url)s">This doc should exist, and its class should be left alone.</a></li>
                <li><a href="%(noexist_url)s#withanchor">This doc should NOT exist</a></li>
                <li><a href="%(noexist_url)s">This doc should NOT exist</a></li>
                <li><a href="%(noexist_url_with_base)s">This doc should NOT exist</a></li>
                <li><a href="%(noexist_url_with_base)s#withanchor">This doc should NOT exist</a></li>
                <li><a href="%(noexist_uilocale_url)s">This doc should NOT exist</a></li>
                <li><a class="foobar" href="%(noexist_url)s">This doc should NOT exist, and its class should be altered</a></li>
                <li><a href="http://mozilla.org/">This is an external link</a></li>
                <li><a class="foobar" name="quux">A lack of href should not cause a problem.</a></li>
                <li><a>In fact, a "link" with no attributes should be no problem as well.</a></li>
                <a href="%(tag_url)s">Tag link</a>
                <a href="%(feed_url)s">Feed link</a>
                <a href="%(templates_url)s">Templates link</a>
                <a href="/en-US/docs/DOM/stylesheet">Case sensitive 1</a>
                <a href="/en-US/docs/DOM/Stylesheet">Case sensitive 1</a>
                <a href="/en-US/docs/DOM/StyleSheet">Case sensitive 1</a>
                <a href="/en-us/docs/dom/StyleSheet">Case sensitive 1</a>
                <a href="/en-US/docs/dom/Styles">For good measure</a>
        """ % vars
        expected = u"""
                <li><a href="%(nonen_slug)s">Héritée</a></li>
                <li><a href="%(exist_url)s">This doc should exist</a></li>
                <li><a href="%(exist_url)s#withanchor">This doc should exist</a></li>
                <li><a href="%(exist_url_with_base)s">This doc should exist</a></li>
                <li><a href="%(exist_url_with_base)s#withanchor">This doc should exist</a></li>
                <li><a href="%(uilocale_url)s">This doc should exist</a></li>
                <li><a class="foobar" href="%(exist_url)s">This doc should exist, and its class should be left alone.</a></li>
                <li><a class="new" href="%(noexist_url)s#withanchor">This doc should NOT exist</a></li>
                <li><a class="new" href="%(noexist_url)s">This doc should NOT exist</a></li>
                <li><a class="new" href="%(noexist_url_with_base)s">This doc should NOT exist</a></li>
                <li><a class="new" href="%(noexist_url_with_base)s#withanchor">This doc should NOT exist</a></li>
                <li><a class="new" href="%(noexist_uilocale_url)s">This doc should NOT exist</a></li>
                <li><a class="foobar new" href="%(noexist_url)s">This doc should NOT exist, and its class should be altered</a></li>
                <li><a class="external" href="http://mozilla.org/">This is an external link</a></li>
                <li><a class="foobar" name="quux">A lack of href should not cause a problem.</a></li>
                <li><a>In fact, a "link" with no attributes should be no problem as well.</a></li>
                <a href="%(tag_url)s">Tag link</a>
                <a href="%(feed_url)s">Feed link</a>
                <a href="%(templates_url)s">Templates link</a>
                <a href="/en-US/docs/DOM/stylesheet">Case sensitive 1</a>
                <a href="/en-US/docs/DOM/Stylesheet">Case sensitive 1</a>
                <a href="/en-US/docs/DOM/StyleSheet">Case sensitive 1</a>
                <a href="/en-us/docs/dom/StyleSheet">Case sensitive 1</a>
                <a class="new" href="/en-US/docs/dom/Styles">For good measure</a>
        """ % vars

        # Split the markup into lines, to better see failures
        doc_lines = doc_src.strip().split("\n")
        expected_lines = expected.strip().split("\n")
        for idx in range(0, len(doc_lines)):
            doc_line = doc_lines[idx]
            expected_line = expected_lines[idx]
            result_line = (wiki.content.parse(doc_line)
                          .annotateLinks(base_url=vars['base_url'])
                          .serialize())
            eq_(normalize_html(expected_line), normalize_html(result_line))
Ejemplo n.º 37
0
    def test_roundtrip(self):
        # Create some documents and revisions here, rather than use a fixture
        d1, r1 = doc_rev('Doc 1')
        d2, r2 = doc_rev('Doc 2')
        d3, r3 = doc_rev('Doc 3')
        d4, r4 = doc_rev('Doc 4')
        d5, r5 = doc_rev('Doc 5')

        # Since this happens in dev sometimes, break a doc by deleting its
        # current revision and leaving it with none.
        d5.current_revision = None
        d5.save()
        r5.delete()

        # The same creator will be used for all the revs, so let's also get a
        # non-creator user for the upload.
        creator = r1.creator
        uploader = User.objects.exclude(pk=creator.id).all()[0]

        # Count docs (with revisions) and revisions in DB
        doc_cnt_db = (Document.objects.filter(
            current_revision__isnull=False).count())
        rev_cnt_db = (Revision.objects.count())

        # Do the dump, capture it, parse the JSON
        fin = StringIO()
        Document.objects.dump_json(Document.objects.all(), fin)
        data_json = fin.getvalue()
        data = json.loads(data_json)

        # No objects should come with non-null primary keys
        for x in data:
            ok_(not x['pk'])

        # Count the documents in JSON vs the DB
        doc_cnt_json = len([x for x in data if x['model'] == 'wiki.document'])
        eq_(doc_cnt_db, doc_cnt_json,
            "DB and JSON document counts should match")

        # Count the revisions in JSON vs the DB
        rev_cnt_json = len([x for x in data if x['model'] == 'wiki.revision'])
        eq_(rev_cnt_db, rev_cnt_json,
            "DB and JSON revision counts should match")

        # For good measure, ensure no documents missing revisions in the dump.
        doc_no_rev = (Document.objects.filter(
            current_revision__isnull=True))[0]
        no_rev_cnt = len([
            x for x in data
            if x['model'] == 'wiki.document' and x['fields']['slug'] ==
            doc_no_rev.slug and x['fields']['locale'] == doc_no_rev.locale
        ])
        eq_(0, no_rev_cnt,
            "There should be no document exported without revision")

        # Upload the data as JSON, assert that all objects were loaded
        loaded_cnt = Document.objects.load_json(uploader, StringIO(data_json))
        eq_(len(data), loaded_cnt)

        # Ensure the current revisions of the documents have changed, and that
        # the creator matches the uploader.
        for d_orig in (d1, d2, d3, d4):
            d_curr = Document.uncached.get(pk=d_orig.pk)
            eq_(2, d_curr.revisions.count())
            ok_(d_orig.current_revision.id != d_curr.current_revision.id)
            ok_(d_orig.current_revision.creator_id !=
                d_curr.current_revision.creator_id)
            eq_(uploader.id, d_curr.current_revision.creator_id)

        # Everyone out of the pool!
        Document.objects.all().delete()
        Revision.objects.all().delete()

        # Try reloading the data on an empty DB
        loaded_cnt = Document.objects.load_json(uploader, StringIO(data_json))
        eq_(len(data), loaded_cnt)

        # Count docs (with revisions) and revisions in DB. The imported objects
        # should have beeen doc/rev pairs.
        eq_(loaded_cnt / 2, Document.objects.count())
        eq_(loaded_cnt / 2, Revision.objects.count())

        # The originals should be gone, now.
        for d_orig in (d1, d2, d3, d4):

            # The original primary key should have gone away.
            try:
                d_curr = Document.uncached.get(pk=d_orig.pk)
                ok_(False, "This should have been an error")
            except Document.DoesNotExist:
                pass

            # Should be able to fetch document with the original natural key
            key = d_orig.natural_key()
            d_curr = Document.objects.get_by_natural_key(*key)
            eq_(1, d_curr.revisions.count())
            eq_(uploader.id, d_curr.current_revision.creator_id)