Example #1
0
    def test_update_l10n_metric_cron(self):
        """Verify the cron job creates the correct metric."""
        l10n_kind = metric_kind(code=L10N_METRIC_CODE, save=True)

        # Create the en-US document with an approved revision.
        doc = document(save=True)
        rev = revision(
            document=doc,
            is_approved=True,
            save=True)

        time.sleep(1)

        # Create an es translation
        es_doc = document(parent=doc, locale='es', save=True)
        revision(
            document=es_doc,
            is_approved=True,
            based_on=rev,
            save=True)

        # Run it and verify results.
        # Value should be 100%
        update_l10n_metric()
        metrics = Metric.objects.filter(kind=l10n_kind)
        eq_(1, len(metrics))
        eq_(100, metrics[0].value)

        # Update the en-US document
        rev2 = revision(
            document=doc,
            is_approved=True,
            save=True)

        # Run it and verify results.
        # Value should be 0%
        update_l10n_metric()
        metrics = Metric.objects.filter(kind=l10n_kind)
        eq_(1, len(metrics))
        eq_(0, metrics[0].value)

        time.sleep(1)

        # Create a pt-BR translation
        ptBR_doc = document(parent=doc, locale='pt-BR', save=True)
        revision(
            document=ptBR_doc,
            is_approved=True,
            based_on=rev,
            save=True)

        # Run it and verify results.
        # Value should be 50%
        update_l10n_metric()
        metrics = Metric.objects.filter(kind=l10n_kind)
        eq_(1, len(metrics))
        eq_(50, metrics[0].value)
Example #2
0
    def test_feed_locale_filter(self):
        """Documents and Revisions in feeds should be filtered by locale"""
        d1 = document(title="Doc1", locale='en-US', save=True)
        r1 = revision(document=d1, save=True)
        r1.review_tags.set('editorial')
        d1.tags.set('foobar')

        d2 = document(title="TransDoc1", locale='de', parent=d1, save=True)
        r2 = revision(document=d2, save=True)
        r2.review_tags.set('editorial')
        d2.tags.set('foobar')

        d3 = document(title="TransDoc1", locale='fr', parent=d1, save=True)
        r3 = revision(document=d3, save=True)
        r3.review_tags.set('editorial')
        d3.tags.set('foobar')

        show_alls = (False, True)
        locales = ('en-US', 'de', 'fr')
        for show_all in show_alls:
            for locale in locales:
                feed_urls = (
                    reverse('wiki.feeds.recent_revisions',
                            locale=locale,
                            args=(),
                            kwargs={'format': 'json'}),
                    reverse('wiki.feeds.recent_documents',
                            locale=locale,
                            args=(),
                            kwargs={'format': 'json'}),
                    reverse('wiki.feeds.recent_documents',
                            locale=locale,
                            args=(),
                            kwargs={
                                'format': 'json',
                                'tag': 'foobar'
                            }),
                    reverse('wiki.feeds.list_review',
                            locale=locale,
                            args=('json', )),
                    reverse('wiki.feeds.list_review_tag',
                            locale=locale,
                            args=(
                                'json',
                                'editorial',
                            )),
                )
                for feed_url in feed_urls:
                    if show_all:
                        feed_url = '%s?all_locales' % feed_url
                    resp = self.client.get(feed_url)
                    data = json.loads(resp.content)
                    if show_all:
                        eq_(3, len(data))
                    else:
                        eq_(1, len(data))
Example #3
0
    def test_update_l10n_metric_cron(self):
        """Verify the cron job creates the correct metric."""
        l10n_kind = metric_kind(code=L10N_METRIC_CODE, save=True)

        # Create the en-US document with an approved revision.
        doc = document(save=True)
        rev = revision(
            document=doc,
            is_approved=True,
            save=True)

        time.sleep(1)

        # Create an es translation
        es_doc = document(parent=doc, locale='es', save=True)
        revision(
            document=es_doc,
            is_approved=True,
            based_on=rev,
            save=True)

        # Run it and verify results.
        # Value should be 100%
        update_l10n_metric()
        metrics = Metric.objects.filter(kind=l10n_kind)
        eq_(1, len(metrics))
        eq_(100, metrics[0].value)

        # Update the en-US document
        revision(document=doc, is_approved=True, save=True)

        # Run it and verify results.
        # Value should be 0%
        update_l10n_metric()
        metrics = Metric.objects.filter(kind=l10n_kind)
        eq_(1, len(metrics))
        eq_(0, metrics[0].value)

        time.sleep(1)

        # Create a pt-BR translation
        ptBR_doc = document(parent=doc, locale='pt-BR', save=True)
        revision(
            document=ptBR_doc,
            is_approved=True,
            based_on=rev,
            save=True)

        # Run it and verify results.
        # Value should be 50%
        update_l10n_metric()
        metrics = Metric.objects.filter(kind=l10n_kind)
        eq_(1, len(metrics))
        eq_(50, metrics[0].value)
Example #4
0
    def test_feed_unchanged_after_render(self):
        """Rendering a document shouldn't affect feed contents, unless the
        document content has actually been changed."""
        d1 = document(title="FeedDoc1", locale='en-US', save=True)
        revision(document=d1, save=True)

        time.sleep(1)  # Let timestamps tick over.
        d2 = document(title="FeedDoc2", locale='en-US', save=True)
        revision(document=d2, save=True)

        time.sleep(1)  # Let timestamps tick over.
        d3 = document(title="FeedDoc3", locale='en-US', save=True)
        revision(document=d3, save=True)

        time.sleep(1)  # Let timestamps tick over.
        d4 = document(title="FeedDoc4", locale='en-US', save=True)
        # No r4, so we can trigger the no-current-rev edge case

        feed_url = reverse('wiki.feeds.recent_documents',
                           locale='en-US',
                           args=(),
                           kwargs={'format': 'rss'})

        # Force a render, hash the feed
        for d in (d1, d2, d3, d4):
            d.render(cache_control="no-cache")
        resp = self.client.get(feed_url)
        feed_hash_1 = hashlib.md5(resp.content).hexdigest()

        # Force another render, hash the feed
        time.sleep(1)  # Let timestamps tick over.
        for d in (d1, d2, d3, d4):
            d.render(cache_control="no-cache")
        resp = self.client.get(feed_url)
        feed_hash_2 = hashlib.md5(resp.content).hexdigest()

        # The hashes should match
        eq_(feed_hash_1, feed_hash_2)

        # Make a real edit.
        time.sleep(1)  # Let timestamps tick over.
        revision(document=d2, content="Hah! An edit!", save=True)
        for d in (d1, d2, d3, d4):
            d.render(cache_control="no-cache")

        # This time, the hashes should *not* match
        resp = self.client.get(feed_url)
        feed_hash_3 = hashlib.md5(resp.content).hexdigest()
        ok_(feed_hash_2 != feed_hash_3)
Example #5
0
 def test_watch_includes_csrf(self):
     """The watch/unwatch forms should include the csrf tag."""
     self.client.login(username="******", password="******")
     d = document(save=True)
     resp = self.client.get(d.get_absolute_url())
     doc = pq(resp.content)
     assert doc(".page-watch input[type=hidden]")
Example #6
0
    def test_intermediate(self):
        """
        Test that the intermediate DocumentAttachment gets created
        correctly when adding an Attachment with a document_id.

        """
        doc = document(locale="en-US",
                       slug="attachment-test-intermediate",
                       save=True)
        revision(document=doc, is_approved=True, save=True)

        file_for_upload = make_test_file(
            content="A file for testing intermediate attachment model.")

        post_data = {
            "title": "Intermediate test file",
            "description": "Intermediate test file",
            "comment": "Initial upload",
            "file": file_for_upload,
        }
        files_url = reverse("attachments.edit_attachment",
                            kwargs={"document_path": doc.slug})
        response = self.client.post(files_url,
                                    data=post_data,
                                    HTTP_HOST=settings.WIKI_HOST)
        assert response.status_code == 302
        assert_no_cache_header(response)

        assert doc.files.count() == 1
        intermediates = DocumentAttachment.objects.filter(document__pk=doc.id)
        assert intermediates.count() == 1

        intermediate = intermediates[0]
        assert intermediate.attached_by.username == "admin"
        assert intermediate.name == file_for_upload.name.split("/")[-1]
Example #7
0
    def test_intermediate(self):
        """
        Test that the intermediate DocumentAttachment gets created
        correctly when adding an Attachment with a document_id.

        """
        doc = document(locale='en', slug='attachment-test-intermediate')
        doc.save()
        rev = revision(document=doc, is_approved=True)
        rev.save()

        file_for_upload = make_test_file(
            content='A file for testing intermediate attachment model.')

        post_data = {
            'title': 'Intermediate test file',
            'description': 'Intermediate test file',
            'comment': 'Initial upload',
            'file': file_for_upload,
        }

        add_url = urlparams(reverse('attachments.new_attachment'),
                            document_id=doc.id)
        resp = self.client.post(add_url, data=post_data)
        eq_(302, resp.status_code)

        eq_(1, doc.files.count())

        intermediates = DocumentAttachment.objects.filter(document__pk=doc.id)
        eq_(1, intermediates.count())

        intermediate = intermediates[0]
        eq_('admin', intermediate.attached_by.username)
        eq_(file_for_upload.name.split('/')[-1], intermediate.name)
Example #8
0
    def test_intermediate(self):
        """
        Test that the intermediate DocumentAttachment gets created
        correctly when adding an Attachment with a document_id.

        """
        doc = document(locale='en-US',
                       slug='attachment-test-intermediate',
                       save=True)
        revision(document=doc, is_approved=True, save=True)

        file_for_upload = make_test_file(
            content='A file for testing intermediate attachment model.')

        post_data = {
            'title': 'Intermediate test file',
            'description': 'Intermediate test file',
            'comment': 'Initial upload',
            'file': file_for_upload,
        }
        files_url = reverse('attachments.edit_attachment',
                            kwargs={'document_path': doc.slug},
                            locale='en-US')
        response = self.client.post(files_url, data=post_data)
        self.assertEqual(response.status_code, 302)

        self.assertEqual(doc.files.count(), 1)
        intermediates = DocumentAttachment.objects.filter(document__pk=doc.id)
        self.assertEqual(intermediates.count(), 1)

        intermediate = intermediates[0]
        self.assertEqual(intermediate.attached_by.username, 'admin')
        self.assertEqual(intermediate.name,
                         file_for_upload.name.split('/')[-1])
Example #9
0
    def test_revisions_feed_diffs(self):
        d = document(title='HTML9')
        d.save()
        revision(save=True,
                 document=d,
                 title='HTML9',
                 comment='Revision 1',
                 content="First Content",
                 is_approved=True,
                 created=datetime.datetime.now())
        r = revision(save=True,
                     document=d,
                     title='HTML9',
                     comment='Revision 2',
                     content="First Content",
                     is_approved=True,
                     created=(datetime.datetime.now() +
                              datetime.timedelta(seconds=1)),
                     tags='"some", "more", "tags"')
        r.review_tags.set(*[u'editorial'])

        resp = self.client.get(reverse('wiki.feeds.recent_revisions',
                                       args=(), kwargs={'format': 'rss'}))
        eq_(200, resp.status_code)
        feed = pq(resp.content)
        for i, item in enumerate(feed.find('item')):
            desc_text = pq(item).find('description').text()
            if "Edited" in desc_text:
                ok_('<h3>Tag changes:</h3>' in desc_text)
                ok_('<span class="diff_add" style="background-color: #afa; '
                    'text-decoration: none;">"more"<br />&nbsp;</span>'
                    in desc_text)
                ok_('<h3>Review changes:</h3>' in desc_text)
                ok_('<span class="diff_add" style="background-color: #afa; '
                    'text-decoration: none;">editorial</span>' in desc_text)
Example #10
0
    def test_intermediate(self):
        """
        Test that the intermediate DocumentAttachment gets created
        correctly when adding an Attachment with a document_id.

        """
        doc = document(locale="en", slug="attachment-test-intermediate")
        doc.save()
        rev = revision(document=doc, is_approved=True)
        rev.save()

        file_for_upload = make_test_file(content="A file for testing intermediate attachment model.")

        post_data = {
            "title": "Intermediate test file",
            "description": "Intermediate test file",
            "comment": "Initial upload",
            "file": file_for_upload,
        }

        add_url = urlparams(reverse("attachments.new_attachment"), document_id=doc.id)
        resp = self.client.post(add_url, data=post_data)
        eq_(302, resp.status_code)

        eq_(1, doc.files.count())

        intermediates = DocumentAttachment.objects.filter(document__pk=doc.id)
        eq_(1, intermediates.count())

        intermediate = intermediates[0]
        eq_("admin", intermediate.attached_by.username)
        eq_(file_for_upload.name.split("/")[-1], intermediate.name)
Example #11
0
    def test_bug869301_revisions_feed_locale(self):
        """Links to documents in revisions feed with ?all_locales should
        reflect proper document locale, regardless of requestor's locale"""
        d = document(title='HTML9', locale="fr")
        d.save()
        now = datetime.datetime.now()
        for i in xrange(1, 6):
            created = now + datetime.timedelta(seconds=5 * i)
            revision(save=True,
                     document=d,
                     title='HTML9',
                     comment='Revision %s' % i,
                     content="Some Content %s" % i,
                     is_approved=True,
                     created=created)

        resp = self.client.get('%s?all_locales' %
                               reverse('wiki.feeds.recent_revisions',
                                       args=(),
                                       kwargs={'format': 'rss'},
                                       locale='en-US'))
        eq_(200, resp.status_code)
        feed = pq(resp.content)
        eq_(5, len(feed.find('item')))
        for i, item in enumerate(feed.find('item')):
            href = pq(item).find('link').text()
            ok_('/fr/' in href)
Example #12
0
    def test_intermediate(self):
        """
        Test that the intermediate DocumentAttachment gets created
        correctly when adding an Attachment with a document_id.

        """
        doc = document(locale='en-US',
                       slug='attachment-test-intermediate',
                       save=True)
        revision(document=doc, is_approved=True, save=True)

        file_for_upload = make_test_file(
            content='A file for testing intermediate attachment model.')

        post_data = {
            'title': 'Intermediate test file',
            'description': 'Intermediate test file',
            'comment': 'Initial upload',
            'file': file_for_upload,
        }
        files_url = reverse('attachments.edit_attachment',
                            kwargs={'document_path': doc.slug},
                            locale='en-US')
        response = self.client.post(files_url, data=post_data)
        self.assertEqual(response.status_code, 302)

        self.assertEqual(doc.files.count(), 1)
        intermediates = DocumentAttachment.objects.filter(document__pk=doc.id)
        self.assertEqual(intermediates.count(), 1)

        intermediate = intermediates[0]
        self.assertEqual(intermediate.attached_by.username, 'admin')
        self.assertEqual(intermediate.name,
                         file_for_upload.name.split('/')[-1])
Example #13
0
    def test_feed_unchanged_after_render(self):
        """Rendering a document shouldn't affect feed contents, unless the
        document content has actually been changed."""
        d1 = document(title="FeedDoc1", locale='en-US', save=True)
        revision(document=d1, save=True)

        time.sleep(1)  # Let timestamps tick over.
        d2 = document(title="FeedDoc2", locale='en-US', save=True)
        revision(document=d2, save=True)

        time.sleep(1)  # Let timestamps tick over.
        d3 = document(title="FeedDoc3", locale='en-US', save=True)
        revision(document=d3, save=True)

        time.sleep(1)  # Let timestamps tick over.
        d4 = document(title="FeedDoc4", locale='en-US', save=True)
        # No r4, so we can trigger the no-current-rev edge case

        feed_url = reverse('wiki.feeds.recent_documents', locale='en-US',
                           args=(), kwargs={'format': 'rss'})

        # Force a render, hash the feed
        for d in (d1, d2, d3, d4):
            d.render(cache_control="no-cache")
        resp = self.client.get(feed_url)
        feed_hash_1 = hashlib.md5(resp.content).hexdigest()

        # Force another render, hash the feed
        time.sleep(1)  # Let timestamps tick over.
        for d in (d1, d2, d3, d4):
            d.render(cache_control="no-cache")
        resp = self.client.get(feed_url)
        feed_hash_2 = hashlib.md5(resp.content).hexdigest()

        # The hashes should match
        eq_(feed_hash_1, feed_hash_2)

        # Make a real edit.
        time.sleep(1)  # Let timestamps tick over.
        revision(document=d2, content="Hah! An edit!", save=True)
        for d in (d1, d2, d3, d4):
            d.render(cache_control="no-cache")

        # This time, the hashes should *not* match
        resp = self.client.get(feed_url)
        feed_hash_3 = hashlib.md5(resp.content).hexdigest()
        ok_(feed_hash_2 != feed_hash_3)
Example #14
0
 def test_doc_short_short_slug_and_title(self):
     slug = 'NotSpam'
     html = '<p>This page is not spam.</p>'
     doc = document(title='blah', slug=slug, html=html, save=True)
     revision(document=doc, content=html, is_approved=True, save=True)
     dsa = DocumentSpamAttempt(slug=slug, document=doc)
     assert self.admin.doc_short(dsa) == u'/en-US/docs/NotSpam (blah)'
     assert self.admin.doc_short(dsa) == str(doc)
Example #15
0
 def test_doc_short_short_slug_and_title(self):
     slug = 'NotSpam'
     html = '<p>This page is not spam.</p>'
     doc = document(title='blah', slug=slug, html=html, save=True)
     revision(document=doc, content=html, is_approved=True, save=True)
     dsa = DocumentSpamAttempt(slug=slug, document=doc)
     assert self.admin.doc_short(dsa) == u'/en-US/docs/NotSpam (blah)'
     assert self.admin.doc_short(dsa) == str(doc)
Example #16
0
 def test_section_pars_for_empty_docs(self):
     doc = document(title='Doc',
                    locale=u'fr',
                    slug=u'doc',
                    save=True,
                    html='<!-- -->')
     res = get_content_sections(doc.html)
     eq_(type(res).__name__, 'list')
Example #17
0
 def setUp(self):
     super(AttachmentTemplatesTests, self).setUp()
     self.old_allowed_types = config.WIKI_ATTACHMENT_ALLOWED_TYPES
     config.WIKI_ATTACHMENT_ALLOWED_TYPES = 'text/plain'
     self.client.login(username='******', password='******')
     self.document = document(save=True)
     self.files_url = reverse('attachments.edit_attachment',
                              kwargs={'document_path': self.document.slug},
                              locale='en-US')
 def setUp(self):
     super(AttachmentTemplatesTests, self).setUp()
     self.old_allowed_types = config.WIKI_ATTACHMENT_ALLOWED_TYPES
     config.WIKI_ATTACHMENT_ALLOWED_TYPES = 'text/plain'
     self.client.login(username='******', password='******')
     self.document = document(save=True)
     self.files_url = reverse('attachments.edit_attachment',
                              kwargs={'document_path': self.document.slug},
                              locale='en-US')
Example #19
0
    def test_redirect(self):
        """Make sure documents with REDIRECT directives redirect properly.

        Also check the backlink to the redirect page.
        """
        Flag.objects.create(name="redirect_messages", everyone=True)
        target = document(save=True)
        target_url = target.get_absolute_url()

        # Ordinarily, a document with no approved revisions cannot have HTML,
        # but we shove it in manually here as a shortcut:
        redirect_html = REDIRECT_CONTENT % dict(title="Boo", href=target_url)
        redirect = document(html=redirect_html)
        redirect.save()
        redirect_url = redirect.get_absolute_url()
        response = self.client.get(redirect_url)
        response = self.client.get(redirect_url, follow=True)
        self.assertRedirects(response, urlparams(target_url), status_code=301)
        self.assertContains(response, redirect_url)
Example #20
0
    def test_feed_locale_filter(self):
        """Documents and Revisions in feeds should be filtered by locale"""
        d1 = document(title="Doc1", locale='en-US', save=True)
        r1 = revision(document=d1, save=True)
        r1.review_tags.set('editorial')
        d1.tags.set('foobar')

        d2 = document(title="TransDoc1", locale='de', parent=d1, save=True)
        r2 = revision(document=d2, save=True)
        r2.review_tags.set('editorial')
        d2.tags.set('foobar')

        d3 = document(title="TransDoc1", locale='fr', parent=d1, save=True)
        r3 = revision(document=d3, save=True)
        r3.review_tags.set('editorial')
        d3.tags.set('foobar')

        show_alls = (False, True)
        locales = ('en-US', 'de', 'fr')
        for show_all in show_alls:
            for locale in locales:
                feed_urls = (
                    reverse('wiki.feeds.recent_revisions', locale=locale,
                            args=(), kwargs={'format': 'json'}),
                    reverse('wiki.feeds.recent_documents', locale=locale,
                            args=(), kwargs={'format': 'json'}),
                    reverse('wiki.feeds.recent_documents', locale=locale,
                            args=(), kwargs={'format': 'json',
                                             'tag': 'foobar'}),
                    reverse('wiki.feeds.list_review', locale=locale,
                            args=('json',)),
                    reverse('wiki.feeds.list_review_tag', locale=locale,
                            args=('json', 'editorial',)),
                )
                for feed_url in feed_urls:
                    if show_all:
                        feed_url = '%s?all_locales' % feed_url
                    resp = self.client.get(feed_url)
                    data = json.loads(resp.content)
                    if show_all:
                        eq_(3, len(data))
                    else:
                        eq_(1, len(data))
Example #21
0
 def test_doc_short_long_unicode(self):
     slug = u'Web/Guide/HTML/HTML5_ডকুমেন্টের_সেকশন_এবং_আউটলাইন'
     title = u'HTML5 ডকুমেন্টের সেকশন এবং আউটলাইন'
     html = '<p>This Bengali page is not spam.</p>'
     doc = document(title=title, slug=slug, html=html, save=True,
                    locale='bn-BD')
     revision(document=doc, content=html, is_approved=True, save=True)
     dsa = DocumentSpamAttempt(slug=slug, document=doc)
     expected = u'/bn-BD/docs/Web/Guide/HT… (HTML5 ডকুমেন্টের সেকশন এব…)'
     assert self.admin.doc_short(dsa) == expected
Example #22
0
 def test_doc_short_long_slug_and_title(self):
     slug = 'Web/Guide/HTML/Sections_and_Outlines_of_an_HTML5_document'
     title = 'Sections and Outlines of an HTML5 Document'
     html = '<p>This German page is not spam.</p>'
     doc = document(title=title, slug=slug, html=html, save=True,
                    locale='de')
     revision(document=doc, content=html, is_approved=True, save=True)
     dsa = DocumentSpamAttempt(slug=slug, document=doc)
     expected = u'/de/docs/Web/Guide/HTML/… (Sections and Outlines of…)'
     assert self.admin.doc_short(dsa) == expected
Example #23
0
 def test_show_toc_hidden_input_for_templates(self):
     """Toggling show_toc on/off through the toc_depth field should
     cause table of contents to appear/disappear."""
     doc_content = """w00t"""
     doc = document(slug="Template:w00t", save=True)
     r = revision(document=doc, save=True, content=doc_content, is_approved=True)
     response = self.client.get(r.document.get_absolute_url())
     eq_(200, response.status_code)
     soup = BeautifulSoup(response.content)
     hidden_inputs = soup.findAll("input", type="hidden")
     for input in hidden_inputs:
         if input["name"] == "toc_depth":
             eq_(0, input["value"])
Example #24
0
 def test_doc_short_long_unicode(self):
     slug = u'Web/Guide/HTML/HTML5_ডকুমেন্টের_সেকশন_এবং_আউটলাইন'
     title = u'HTML5 ডকুমেন্টের সেকশন এবং আউটলাইন'
     html = '<p>This Bengali page is not spam.</p>'
     doc = document(title=title,
                    slug=slug,
                    html=html,
                    save=True,
                    locale='bn-BD')
     revision(document=doc, content=html, is_approved=True, save=True)
     dsa = DocumentSpamAttempt(slug=slug, document=doc)
     expected = u'/bn-BD/docs/Web/Guide/HT… (HTML5 ডকুমেন্টের সেকশন এব…)'
     assert self.admin.doc_short(dsa) == expected
Example #25
0
 def test_doc_short_long_slug_and_title(self):
     slug = 'Web/Guide/HTML/Sections_and_Outlines_of_an_HTML5_document'
     title = 'Sections and Outlines of an HTML5 Document'
     html = '<p>This German page is not spam.</p>'
     doc = document(title=title,
                    slug=slug,
                    html=html,
                    save=True,
                    locale='de')
     revision(document=doc, content=html, is_approved=True, save=True)
     dsa = DocumentSpamAttempt(slug=slug, document=doc)
     expected = u'/de/docs/Web/Guide/HTML/… (Sections and Outlines of…)'
     assert self.admin.doc_short(dsa) == expected
Example #26
0
    def test_revisions_feed(self):
        d = document(title='HTML9')
        d.save()
        now = datetime.datetime.now()
        for i in xrange(1, 6):
            created = now + datetime.timedelta(seconds=5 * i)
            revision(save=True,
                     document=d,
                     title='HTML9',
                     comment='Revision %s' % i,
                     content="Some Content %s" % i,
                     is_approved=True,
                     created=created)

        resp = self.client.get(
            reverse('wiki.feeds.recent_revisions',
                    args=(),
                    kwargs={'format': 'rss'}))
        eq_(200, resp.status_code)
        feed = pq(resp.content)
        eq_(5, len(feed.find('item')))
        for i, item in enumerate(feed.find('item')):
            desc_text = pq(item).find('description').text()
            ok_('by:</h3><p>testuser</p>' in desc_text)
            ok_('<h3>Comment:</h3><p>Revision' in desc_text)
            if "Edited" in desc_text:
                ok_('$compare?to' in desc_text)
                ok_('diff_chg' in desc_text)
            ok_('$edit' in desc_text)
            ok_('$history' in desc_text)

        resp = self.client.get(
            reverse('wiki.feeds.recent_revisions',
                    args=(),
                    kwargs={'format': 'rss'}) + '?limit=2')
        feed = pq(resp.content)
        eq_(2, len(feed.find('item')))

        resp = self.client.get(
            reverse('wiki.feeds.recent_revisions',
                    args=(),
                    kwargs={'format': 'rss'}) + '?limit=2&page=1')
        ok_('Revision 5' in resp.content)
        ok_('Revision 4' in resp.content)

        resp = self.client.get(
            reverse('wiki.feeds.recent_revisions',
                    args=(),
                    kwargs={'format': 'rss'}) + '?limit=2&page=2')
        ok_('Revision 3' in resp.content)
        ok_('Revision 2' in resp.content)
Example #27
0
    def test_non_localizable_translate_disabled(self):
        """Non localizable document doesn't show tab for 'Localize'."""
        self.client.login(username="******", password="******")
        d = document(is_localizable=True, save=True)
        resp = self.client.get(d.get_absolute_url())
        doc = pq(resp.content)
        assert "Add a translation" in doc(".page-buttons #translations li").text()

        # Make it non-localizable
        d.is_localizable = False
        d.save()
        resp = self.client.get(d.get_absolute_url())
        doc = pq(resp.content)
        assert "Add a translation" not in doc(".page-buttons #translations li").text()
Example #28
0
 def test_translation_document_no_approved_content(self):
     """Load a non-English document with no approved content, with a parent
     with no approved content either."""
     r = revision(save=True, content="Some text.", is_approved=False)
     d2 = document(parent=r.document, locale="fr", slug="french", save=True)
     revision(document=d2, save=True, content="Moartext", is_approved=False)
     response = self.client.get(d2.get_absolute_url())
     eq_(200, response.status_code)
     doc = pq(response.content)
     eq_(d2.title, doc("main#content div.document-head h1").text())
     # HACK: fr doc has different message if locale/ is updated
     ok_(
         ("This article doesn't have approved content yet." in doc("article#wikiArticle").text())
         or ("Cet article n'a pas encore de contenu" in doc("article#wikiArticle").text())
     )
Example #29
0
def _create_document(title="Test Document", parent=None, locale=settings.WIKI_DEFAULT_LANGUAGE):
    d = document(
        title=title, html="<div>Lorem Ipsum</div>", category=10, locale=locale, parent=parent, is_localizable=True
    )
    d.save()
    r = Revision(
        document=d,
        keywords="key1, key2",
        summary="lipsum",
        content="<div>Lorem Ipsum</div>",
        creator_id=8,
        is_approved=True,
        comment="Good job!",
    )
    r.save()
    return d
Example #30
0
    def test_files_dict(self):
        doc = document(locale='en', slug='attachment-test-files-dict')
        doc.save()
        rev = revision(document=doc, is_approved=True)
        rev.save()

        test_file_1 = make_test_file(
            content='A file for testing the files dict')

        post_data = {
            'title': 'Files dict test file',
            'description': 'Files dict test file',
            'comment': 'Initial upload',
            'file': test_file_1,
        }

        add_url = urlparams(reverse('attachments.new_attachment'),
                            document_id=doc.id)
        self.client.post(add_url, data=post_data)

        test_file_2 = make_test_file(
            content='Another file for testing the files dict')

        post_data = {
            'title': 'Files dict test file 2',
            'description': 'Files dict test file 2',
            'comment': 'Initial upload',
            'file': test_file_2,
        }

        self.client.post(add_url, data=post_data)

        doc = Document.objects.get(pk=doc.id)

        files_dict = doc.files_dict()

        file1 = files_dict[test_file_1.name.split('/')[-1]]
        eq_('admin', file1['attached_by'])
        eq_('Files dict test file', file1['description'])
        eq_('text/plain', file1['mime_type'])
        ok_(test_file_1.name.split('/')[-1] in file1['url'])

        file2 = files_dict[test_file_2.name.split('/')[-1]]
        eq_('admin', file2['attached_by'])
        eq_('Files dict test file 2', file2['description'])
        eq_('text/plain', file2['mime_type'])
        ok_(test_file_2.name.split('/')[-1] in file2['url'])
Example #31
0
    def test_revisions_feed(self):
        d = document(title='HTML9')
        d.save()
        now = datetime.datetime.now()
        for i in xrange(1, 6):
            created = now + datetime.timedelta(seconds=5 * i)
            revision(save=True,
                     document=d,
                     title='HTML9',
                     comment='Revision %s' % i,
                     content="Some Content %s" % i,
                     is_approved=True,
                     created=created)

        resp = self.client.get(reverse('wiki.feeds.recent_revisions',
                                       args=(), kwargs={'format': 'rss'}))
        eq_(200, resp.status_code)
        feed = pq(resp.content)
        eq_(5, len(feed.find('item')))
        for i, item in enumerate(feed.find('item')):
            desc_text = pq(item).find('description').text()
            ok_('by:</h3><p>testuser</p>' in desc_text)
            ok_('<h3>Comment:</h3><p>Revision' in desc_text)
            if "Edited" in desc_text:
                ok_('$compare?to' in desc_text)
                ok_('diff_chg' in desc_text)
            ok_('$edit' in desc_text)
            ok_('$history' in desc_text)

        resp = self.client.get(reverse('wiki.feeds.recent_revisions',
                                       args=(), kwargs={'format': 'rss'}) +
                               '?limit=2')
        feed = pq(resp.content)
        eq_(2, len(feed.find('item')))

        resp = self.client.get(reverse('wiki.feeds.recent_revisions',
                                       args=(), kwargs={'format': 'rss'}) +
                               '?limit=2&page=1')
        ok_('Revision 5' in resp.content)
        ok_('Revision 4' in resp.content)

        resp = self.client.get(reverse('wiki.feeds.recent_revisions',
                                       args=(), kwargs={'format': 'rss'}) +
                               '?limit=2&page=2')
        ok_('Revision 3' in resp.content)
        ok_('Revision 2' in resp.content)
Example #32
0
    def test_files_dict(self):
        doc = document(locale="en", slug="attachment-test-files-dict")
        doc.save()
        rev = revision(document=doc, is_approved=True)
        rev.save()

        test_file_1 = make_test_file(content="A file for testing the files dict")

        post_data = {
            "title": "Files dict test file",
            "description": "Files dict test file",
            "comment": "Initial upload",
            "file": test_file_1,
        }

        add_url = urlparams(reverse("attachments.new_attachment"), document_id=doc.id)
        self.client.post(add_url, data=post_data)

        test_file_2 = make_test_file(content="Another file for testing the files dict")

        post_data = {
            "title": "Files dict test file 2",
            "description": "Files dict test file 2",
            "comment": "Initial upload",
            "file": test_file_2,
        }

        self.client.post(add_url, data=post_data)

        doc = Document.objects.get(pk=doc.id)

        files_dict = doc.files_dict()

        file1 = files_dict[test_file_1.name.split("/")[-1]]
        eq_("admin", file1["attached_by"])
        eq_("Files dict test file", file1["description"])
        eq_("text/plain", file1["mime_type"])
        ok_(test_file_1.name.split("/")[-1] in file1["url"])

        file2 = files_dict[test_file_2.name.split("/")[-1]]
        eq_("admin", file2["attached_by"])
        eq_("Files dict test file 2", file2["description"])
        eq_("text/plain", file2["mime_type"])
        ok_(test_file_2.name.split("/")[-1] in file2["url"])
Example #33
0
    def test_document_fallback_with_translation(self):
        """The document template falls back to English if translation exists
        but it has no approved revisions."""
        r = revision(save=True, content="Test", is_approved=True)
        d2 = document(parent=r.document, locale="fr", slug="french", save=True)
        revision(document=d2, is_approved=False, save=True)
        url = reverse("wiki.document", args=[d2.slug], locale="fr")
        response = self.client.get(url)
        doc = pq(response.content)
        eq_(d2.title, doc("main#content div.document-head h1").text())

        # Fallback message is shown.
        eq_(1, len(doc("#doc-pending-fallback")))
        ok_("$translate" in doc("#edit-button").attr("href"))
        # Removing this as it shows up in text(), and we don't want to depend
        # on its localization.
        doc("#doc-pending-fallback").remove()
        # Included content is English.
        eq_(pq(r.document.html).text(), doc("article#wikiArticle").text())
Example #34
0
    def test_document_attachment(self):
        doc = document(save=True)
        self.assertEqual(DocumentAttachment.objects.count(), 0)

        document_attachment1 = self.attachment.attach(
            doc, self.test_user, self.revision)
        self.assertEqual(DocumentAttachment.objects.count(), 1)
        self.assertEqual(document_attachment1.file, self.attachment)
        self.assertTrue(document_attachment1.is_original)
        self.assertEqual(document_attachment1.name, self.revision.filename)
        self.assertEqual(document_attachment1.attached_by, self.test_user)

        document_attachment2 = self.attachment.attach(
            doc, self.test_user, self.revision2)
        self.assertEqual(DocumentAttachment.objects.count(), 1)
        self.assertEqual(document_attachment2.file, self.attachment)
        self.assertTrue(document_attachment2.is_original)
        self.assertEqual(document_attachment2.name, self.revision2.filename)
        self.assertEqual(document_attachment2.attached_by, self.test_user)
        self.assertEqual(document_attachment1.pk, document_attachment2.pk)
Example #35
0
    def test_document_attachment(self):
        doc = document(save=True)
        self.assertEqual(DocumentAttachment.objects.count(), 0)

        document_attachment1 = self.attachment.attach(doc, self.test_user,
                                                      self.revision)
        self.assertEqual(DocumentAttachment.objects.count(), 1)
        self.assertEqual(document_attachment1.file, self.attachment)
        self.assertTrue(document_attachment1.is_original)
        self.assertEqual(document_attachment1.name, self.revision.filename)
        self.assertEqual(document_attachment1.attached_by, self.test_user)

        document_attachment2 = self.attachment.attach(doc, self.test_user,
                                                      self.revision2)
        self.assertEqual(DocumentAttachment.objects.count(), 1)
        self.assertEqual(document_attachment2.file, self.attachment)
        self.assertTrue(document_attachment2.is_original)
        self.assertEqual(document_attachment2.name, self.revision2.filename)
        self.assertEqual(document_attachment2.attached_by, self.test_user)
        self.assertEqual(document_attachment1.pk, document_attachment2.pk)
Example #36
0
    def test_intermediate(self):
        """
        Test that the intermediate DocumentAttachment gets created
        correctly when adding an Attachment with a document_id.

        """
        doc = document(locale='en-US',
                       slug='attachment-test-intermediate',
                       save=True)
        revision(document=doc, is_approved=True, save=True)

        file_for_upload = make_test_file(
            content='A file for testing intermediate attachment model.')

        post_data = {
            'title': 'Intermediate test file',
            'description': 'Intermediate test file',
            'comment': 'Initial upload',
            'file': file_for_upload,
        }
        files_url = reverse('attachments.edit_attachment',
                            kwargs={'document_path': doc.slug},
                            locale='en-US')
        response = self.client.post(files_url, data=post_data)
        assert response.status_code == 302
        assert 'max-age=0' in response['Cache-Control']
        assert 'no-cache' in response['Cache-Control']
        assert 'no-store' in response['Cache-Control']
        assert 'must-revalidate' in response['Cache-Control']

        assert doc.files.count() == 1
        intermediates = DocumentAttachment.objects.filter(document__pk=doc.id)
        assert intermediates.count() == 1

        intermediate = intermediates[0]
        assert intermediate.attached_by.username == 'admin'
        assert intermediate.name == file_for_upload.name.split('/')[-1]
Example #37
0
    def test_intermediate(self):
        """
        Test that the intermediate DocumentAttachment gets created
        correctly when adding an Attachment with a document_id.

        """
        doc = document(locale='en-US',
                       slug='attachment-test-intermediate',
                       save=True)
        revision(document=doc, is_approved=True, save=True)

        file_for_upload = make_test_file(
            content='A file for testing intermediate attachment model.')

        post_data = {
            'title': 'Intermediate test file',
            'description': 'Intermediate test file',
            'comment': 'Initial upload',
            'file': file_for_upload,
        }
        files_url = reverse('attachments.edit_attachment',
                            kwargs={'document_path': doc.slug},
                            locale='en-US')
        response = self.client.post(files_url, data=post_data)
        assert response.status_code == 302
        assert 'max-age=0' in response['Cache-Control']
        assert 'no-cache' in response['Cache-Control']
        assert 'no-store' in response['Cache-Control']
        assert 'must-revalidate' in response['Cache-Control']

        assert doc.files.count() == 1
        intermediates = DocumentAttachment.objects.filter(document__pk=doc.id)
        assert intermediates.count() == 1

        intermediate = intermediates[0]
        assert intermediate.attached_by.username == 'admin'
        assert intermediate.name == file_for_upload.name.split('/')[-1]
Example #38
0
 def test_redirect_from_nonexistent(self):
     """The template shouldn't crash or print a backlink if the "from" page
     doesn't exist."""
     d = document(save=True)
     response = self.client.get(urlparams(d.get_absolute_url()))
     self.assertNotContains(response, "Redirected from ")
Example #39
0
 def test_section_pars_for_empty_docs(self):
     doc = document(title='Doc', locale=u'fr', slug=u'doc', save=True,
                    html='<!-- -->')
     res = get_content_sections(doc.html)
     eq_(type(res).__name__, 'list')
Example #40
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'https://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 = (kuma.wiki.content.parse(doc_line)
                          .annotateLinks(base_url=vars['base_url'])
                          .serialize())
            eq_(normalize_html(expected_line), normalize_html(result_line))
Example #41
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'https://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 = (kuma.wiki.content.parse(doc_line)
                          .annotateLinks(base_url=vars['base_url'])
                          .serialize())
            eq_(normalize_html(expected_line), normalize_html(result_line))