Example #1
0
    def test_delete(self):
        """Make sure deleting the latest localizable revision doesn't delete
        the document but instead sets its latest localizable revision to the
        previous one.

        Making sure current_revision does the same is covered in the
        test_delete_current_revision template test.

        """
        r1 = revision(is_approved=True,
                      is_ready_for_localization=True,
                      save=True)
        d = r1.document
        r2 = revision(document=d,
                      is_approved=True,
                      is_ready_for_localization=True,
                      save=True)

        # Deleting r2 should make the latest fall back to r1:
        r2.delete()
        eq_(r1, Document.objects.get(pk=d.pk).latest_localizable_revision)

        # And deleting r1 should fall back to None:
        r1.delete()
        eq_(None, Document.objects.get(pk=d.pk).latest_localizable_revision)
Example #2
0
 def test_no_approved_revs(self):
     """Articles with no approved revisions should not appear."""
     revision(is_approved=False,
              is_ready_for_localization=False,
              significance=MAJOR_SIGNIFICANCE,
              save=True)
     eq_([], self.titles())
Example #3
0
    def test_revisions_feed(self):
        d = document(title='HTML9')
        d.save()
        for i in xrange(1, 6):
            revision(save=True, document=d,
                         title='HTML9', comment='Revision %s' % i,
                         content="Some Content %s" % i,
                         is_approved=True,
                         created=datetime.datetime.now()\
                         + datetime.timedelta(seconds=5 * i))

        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)
Example #4
0
    def test_render(self):
        """Assert the main dash and all the readouts render and don't crash."""
        # Put some stuff in the DB so at least one row renders for each
        # readout:
        untranslated = revision(is_approved=True)
        untranslated.save()

        unreviewed = translated_revision()
        unreviewed.save()

        out_of_date = translated_revision(is_approved=True)
        out_of_date.save()
        major_update = revision(document=out_of_date.document.parent,
                                significance=MAJOR_SIGNIFICANCE,
                                is_approved=True)
        major_update.save()

        needing_updates = translated_revision(is_approved=True)
        needing_updates.save()
        medium_update = revision(document=needing_updates.document.parent,
                                significance=MEDIUM_SIGNIFICANCE)
        medium_update.save()

        response = self.client.get(reverse('dashboards.localization',
                                           locale='de'),
                                   follow=False)
        eq_(200, response.status_code)
        doc = pq(response.content)
        self._assert_readout_contains(doc, 'untranslated',
                                      untranslated.document.title)
        self._assert_readout_contains(doc, 'unreviewed',
                                      unreviewed.document.title)
Example #5
0
 def test_latest_rejected(self):
     """Return latest rejected revision when no current exists."""
     r1 = revision(is_approved=False, reviewed=None, save=True,
                   created=datetime.now() - timedelta(days=1))
     r2 = revision(is_approved=False, save=True, document=r1.document)
     eq_(r2, get_current_or_latest_revision(r1.document,
                                            reviewed_only=False))
Example #6
0
    def test_by_product(self):
        """Test the product filtering of the readout."""
        p = product(title="Firefox", slug="firefox", save=True)
        translation = translated_revision(is_approved=True, save=True)
        revision(
            document=translation.document.parent,
            is_approved=True,
            is_ready_for_localization=False,  # should still count
            significance=MAJOR_SIGNIFICANCE,
            save=True,
        )
        revision(
            document=translation.document.parent,
            is_approved=True,
            is_ready_for_localization=True,
            significance=MEDIUM_SIGNIFICANCE,
            save=True,
        )

        # There shouldn't be any rows yet.
        eq_(0, len(self.rows(product=p)))

        # Add the product to the document, and verify it shows up.
        translation.document.parent.products.add(p)
        eq_(self.row(product=p)["title"], translation.document.title)
Example #7
0
    def test_not_counting_outdated(self):
        """Out-of-date translations shouldn't count as "done".

        "Out-of-date" can mean either moderately or majorly out of date. The
        only thing we don't care about is typo-level outdatedness.

        """
        t = translated_revision(is_approved=True, save=True)
        overview = overview_rows('de')
        eq_(1, overview['most-visited']['numerator'])
        eq_(1, overview['all']['numerator'])

        # Update the parent with a typo-level revision:
        revision(document=t.document.parent,
                 significance=TYPO_SIGNIFICANCE,
                 is_approved=True,
                 is_ready_for_localization=True,
                 save=True)
        # Assert it still shows up in the numerators:
        overview = overview_rows('de')
        eq_(1, overview['most-visited']['numerator'])
        eq_(1, overview['all']['numerator'])

        # Update the parent with a medium-level revision:
        revision(document=t.document.parent,
                 significance=MEDIUM_SIGNIFICANCE,
                 is_approved=True,
                 is_ready_for_localization=True,
                 save=True)
        # Assert it no longer shows up in the numerators:
        overview = overview_rows('de')
        eq_(0, overview['all']['numerator'])
        eq_(0, overview['most-visited']['numerator'])
Example #8
0
 def test_unlocalizable(self):
     """Unlocalizable docs shouldn't show up in the list."""
     revision(
         document=document(is_localizable=False, save=True),
         is_approved=True,
         save=True)
     self.assertRaises(IndexError, self.row)
Example #9
0
 def test_correct_based_on_to_none(self):
     """Assure Revision.clean() changes a bad based_on value to None when
     there is no current_revision of the English document."""
     r = revision()
     r.based_on = revision()  # Revision of some other unrelated Document
     self.assertRaises(ValidationError, r.clean)
     eq_(None, r.based_on)
Example #10
0
    def test_front_page_search_paging(self):
        # Create 30 documents
        for i in range(30):
            doc = document(
                title=u'How to fix your audio %d' % i,
                locale=u'en-US',
                category=10,
                save=True)
            doc.tags.add(u'desktop')
            revision(document=doc, is_approved=True, save=True)

        # Create 20 questions
        for i in range(20):
            ques = question(title=u'audio',  content=u'audio bad.', save=True)
            ques.tags.add(u'desktop')
            ans = answer(question=ques, save=True)
            answervote(answer=ans, helpful=True, save=True)

        self.refresh()

        response = self.client.get(reverse('search'), {
            'q_tags': 'desktop', 'product': 'desktop', 'q': 'audio',
            'format': 'json'
        })
        eq_(200, response.status_code)
        content = json.loads(response.content)

        # Make sure there are 20 results.
        eq_(content['total'], 20)

        # Make sure only 10 of them are kb.
        docs = [mem for mem in content['results']
                if mem['type'] == 'document']
        eq_(len(docs), 10)
Example #11
0
    def test_default_search_for_wiki(self):
        """This tests whether doing a default search returns wiki document
        results.

        Bug #709202.

        """
        doc = document(title=u'audio', locale=u'en-US', category=10, save=True)
        doc.products.add(product(title=u'firefox', slug=u'desktop', save=True))
        revision(document=doc, is_approved=True, save=True)

        self.refresh()

        # This is the search that you get when you start on the sumo
        # homepage and do a search from the box with two differences:
        # first, we do it in json since it's easier to deal with
        # testing-wise and second, we search for 'audio' since we have
        # data for that.
        response = self.client.get(reverse('search'), {
            'q': 'audio', 'format': 'json'})

        eq_(200, response.status_code)

        content = json.loads(response.content)
        eq_(content['total'], 1)
Example #12
0
    def test_default_only_shows_wiki_and_questions(self):
        """Tests that the default search doesn't show forums

        This verifies that we're only showing documents of the type
        that should be shown and that the filters on model are working
        correctly.

        Bug #767394

        """
        p = product(slug=u'desktop', save=True)
        ques = question(title=u'audio', save=True)
        ques.products.add(p)
        ans = answer(question=ques, content=u'volume', save=True)
        answervote(answer=ans, helpful=True, save=True)

        doc = document(title=u'audio', locale=u'en-US', category=10, save=True)
        doc.products.add(p)
        revision(document=doc, is_approved=True, save=True)

        thread1 = thread(title=u'audio', save=True)
        post(thread=thread1, save=True)

        self.refresh()

        response = self.client.get(reverse('search'), {
            'q': 'audio', 'format': 'json'})

        eq_(200, response.status_code)

        content = json.loads(response.content)
        eq_(content['total'], 2)
Example #13
0
    def test_document_listing(self, flag_is_active):
        """Verify /products/<product slug>/<topic slug> renders articles."""
        flag_is_active.return_value = True

        # Create a topic and product.
        t1 = topic(save=True)
        p = product(save=True)

        # Create 3 documents with the topic and product and one without.
        for i in range(3):
            doc = revision(is_approved=True, save=True).document
            doc.topics.add(t1)
            doc.products.add(p)

        doc = revision(is_approved=True, save=True).document

        self.refresh()

        # GET the page and verify the content.
        url = reverse('products.documents', args=[p.slug, t1.slug])
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(3, len(doc('#document-list > ul > li')))
        eq_(p.slug, doc('#support-search input[name=product]').attr['value'])
Example #14
0
    def test_hot_topics(self, flag_is_active):
        """Verifies the hot topics section."""
        flag_is_active.return_value = True

        # Create a product and the hot topics topic.
        p = product(save=True)
        hot = topic(slug=HOT_TOPIC_SLUG, save=True)

        # Create 7 hot documents.
        for i in range(7):
            doc = revision(is_approved=True, save=True).document
            doc.products.add(p)
            doc.topics.add(hot)

        # Create a not hot document.
        doc = revision(is_approved=True, save=True).document
        doc.products.add(p)

        self.refresh()

        # GET the product landing page and verify the content.
        url = reverse('products.product', args=[p.slug])
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(7, len(doc('#hot-topics li')))
Example #15
0
    def test_majorly_outdated_with_unapproved_parents(self):
        """Migrations might introduce translated revisions without based_on
        set. Tolerate these.

        If based_on of a translation's current_revision is None, the
        translation should be considered out of date iff any
        major-significance, approved revision to the English article exists.

        """
        # Create a parent doc with only an unapproved revision...
        parent_rev = revision()
        parent_rev.save()
        # ...and a translation with a revision based on nothing.
        trans = document(parent=parent_rev.document, locale='de')
        trans.save()
        trans_rev = revision(document=trans, is_approved=True)
        trans_rev.save()

        assert trans_rev.based_on is None, \
            ('based_on defaulted to something non-None, which this test '
             "wasn't expecting.")

        assert not trans.is_majorly_outdated(), \
            ('A translation was considered majorly out of date even though '
             'the English document has never had an approved revision of '
             'major significance.')

        major_parent_rev = revision(document=parent_rev.document,
                                    significance=MAJOR_SIGNIFICANCE,
                                    is_approved=True)
        major_parent_rev.save()

        assert trans.is_majorly_outdated(), \
            ('A translation was not considered majorly outdated when its '
             "current revision's based_on value was None.")
Example #16
0
    def setUp(self):
        super(TestFacetHelpers, self).setUp()

        # Create topics
        self.general = topic(slug='general', save=True)
        self.bookmarks = topic(slug='bookmarks', save=True)
        self.sync = topic(slug='sync', save=True)

        # Create products
        self.desktop = product(slug='firefox', save=True)
        self.mobile = product(slug='mobile', save=True)

        # Set up documents.
        doc1 = revision(is_approved=True, save=True).document
        doc1.topics.add(self.general)
        doc1.topics.add(self.bookmarks)
        doc1.products.add(self.desktop)

        doc2 = revision(is_approved=True, save=True).document
        doc2.topics.add(self.bookmarks)
        doc2.topics.add(self.sync)
        doc2.products.add(self.desktop)
        doc2.products.add(self.mobile)

        self.refresh()
Example #17
0
    def test_product_facets(self):
        """Verify the facet counts on the results page."""
        # Create products, questions and documents.
        p1 = product(title="Firefox", slug="firefox", save=True)
        p2 = product(title="Firefox for mobile", slug="mobile", save=True)

        ques = question(title=u"audio", save=True)
        ques.products.add(p1)
        ans = answer(question=ques, content=u"volume", save=True)
        answervote(answer=ans, helpful=True, save=True)

        doc = document(title=u"audio", locale=u"en-US", category=10, save=True)
        doc.products.add(p1)
        doc.products.add(p2)
        revision(document=doc, is_approved=True, save=True)

        self.refresh()

        # There should be 2 total results, 2 "firefox" results and
        # 1 "mobile" result.
        response = self.client.get(reverse("search"), {"q": "audio"})
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_("Found 2 results for audio in English", doc("h2").text())
        facet_text = doc("#product-filter").text()
        assert "Firefox (2)" in facet_text
        assert "Firefox for mobile (1)" in facet_text
Example #18
0
    def test_product_facets(self):
        """Verify the facet counts on the results page."""
        # Create products, questions and documents.
        p1 = product(title='Firefox', slug='firefox', save=True)
        p2 = product(title='Firefox for mobile', slug='mobile', save=True)

        ques = question(title=u'audio', save=True)
        ques.products.add(p1)
        ans = answer(question=ques, content=u'volume', save=True)
        answervote(answer=ans, helpful=True, save=True)

        doc = document(title=u'audio', locale=u'en-US', category=10, save=True)
        doc.products.add(p1)
        doc.products.add(p2)
        revision(document=doc, is_approved=True, save=True)

        self.refresh()

        # There should be 2 total results, 2 "firefox" results and
        # 1 "mobile" result.
        response = self.client.get(reverse('search'), {'q': 'audio'})
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_('Found 2 results for audio in English', doc('h2').text())
        facet_text = doc('#product-filter').text()
        assert 'Firefox (2)' in facet_text
        assert 'Firefox for mobile (1)' in facet_text
Example #19
0
    def test_ready_for_l10n_updates_doc(self):
        """Approving and marking ready a rev should update the doc's ref."""
        # Ready a rev in a new doc:
        ready_1 = revision(is_approved=True,
                           is_ready_for_localization=True,
                           save=True)
        eq_(ready_1, ready_1.document.latest_localizable_revision)

        # Add an unready revision that we can ready later:
        unready = revision(document=ready_1.document,
                           is_approved=False,
                           is_ready_for_localization=False,
                           save=True)

        # Ready a rev in a doc that already has a ready revision:
        ready_2 = revision(document=ready_1.document,
                           is_approved=True,
                           is_ready_for_localization=True,
                           save=True)
        eq_(ready_2, ready_2.document.latest_localizable_revision)

        # Ready the older rev. It should not become the latest_localizable.
        unready.is_ready_for_localization = True
        unready.is_approved = True
        unready.save()
        eq_(ready_2, ready_2.document.latest_localizable_revision)
Example #20
0
 def test_non_localizable(self):
     """When document isn't localizable, ignore is_ready_for_l10n."""
     r1 = revision(is_approved=True, is_ready_for_localization=True, save=True)
     r2 = revision(document=r1.document, is_approved=True, is_ready_for_localization=False, save=True)
     r1.document.is_localizable = False
     r1.document.save()
     eq_(r2, r2.document.localizable_or_latest_revision())
Example #21
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 #22
0
    def test_document_listing(self, flag_is_active):
        """Verify /products/<product slug>/<topic slug> renders articles."""
        flag_is_active.return_value = True

        # Create a topic and product.
        t1 = topic(save=True)
        t2 = topic(save=True)
        p = product(save=True)

        # Create 3 documents with the topic and product and one without.
        for i in range(3):
            doc = revision(is_approved=True, save=True).document
            doc.topics.add(t1)
            doc.products.add(p)
            if i == 1:  # Only one document with t2
                doc.topics.add(t2)

        doc = revision(is_approved=True, save=True).document

        self.refresh()

        # GET the page and verify the content.
        url = reverse('products.documents', args=[p.slug, t1.slug])
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(3, len(doc('#document-list > ul > li')))

        # GET the page with refine topic and verify the content.
        url = reverse('products.documents', args=[p.slug, t1.slug])
        url = urlparams(url, refine=t2.slug)
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(1, len(doc('#document-list > ul > li')))
Example #23
0
    def test_previous(self):
        r1 = revision(is_approved=True, save=True)
        d = r1.document
        r2 = revision(document=d, is_approved=True, save=True)

        eq_(r1.previous, None)
        eq_(r2.previous.id, r1.id)
Example #24
0
    def test_advanced_search_sortby_documents_helpful(self):
        """Tests advanced search with a sortby_documents by helpful"""
        r1 = revision(is_approved=True, save=True)
        r2 = revision(is_approved=True, save=True)
        helpful_vote(revision=r2, helpful=True, save=True)

        # Note: We have to wipe and rebuild the index because new
        # helpful_votes don't update the index data.
        self.setup_indexes()
        self.reindex_and_refresh()

        # r2.document should come first with 1 vote.
        response = self.client.get(reverse('search'), {
            'w': '1', 'a': '1', 'sortby_documents': 'helpful',
            'format': 'json'})
        eq_(200, response.status_code)

        content = json.loads(response.content)
        eq_(r2.document.title, content['results'][0]['title'])

        # Vote twice on r1, now it should come first.
        helpful_vote(revision=r1, helpful=True, save=True)
        helpful_vote(revision=r1, helpful=True, save=True)

        self.setup_indexes()
        self.reindex_and_refresh()

        response = self.client.get(reverse('search'), {
            'w': '1', 'a': '1', 'sortby_documents': 'helpful',
            'format': 'json'})
        eq_(200, response.status_code)

        content = json.loads(response.content)
        eq_(r1.document.title, content['results'][0]['title'])
Example #25
0
 def test_approved_over_unreviewed(self):
     """Favor an approved revision over a more recent unreviewed one."""
     approved = revision(is_approved=True, is_ready_for_localization=False, save=True)
     revision(
         document=approved.document, is_ready_for_localization=False, is_approved=False, reviewed=None, save=True
     )
     eq_(approved, approved.document.localizable_or_latest_revision())
Example #26
0
    def test_deferred_translation(self):
        """Verify a translation with only a deferred revision appears."""
        d = document(title='Foo', save=True)
        untranslated = revision(is_approved=True,
                                is_ready_for_localization=True,
                                document=d,
                                save=True)

        # There should be 1.
        eq_(1, len(self.titles(locale='es')))

        translation = document(
            parent=untranslated.document, locale='es', save=True)
        deferred = revision(is_approved=False,
                            reviewed=datetime.now(),
                            document=translation,
                            save=True)

        # There should still be 1.
        eq_(1, len(self.titles(locale='es')))

        # Mark that rev as approved and there should then be 0.
        deferred.is_approved = True
        deferred.save()
        eq_(0, len(self.titles(locale='es')))
Example #27
0
    def test_suggestions(self, get_current):
        """Suggestions API is well-formatted."""
        get_current.return_value.domain = 'testserver'

        doc = document(title=u'doc1 audio', locale=u'en-US',
                       is_archived=False, save=True)
        revision(document=doc, summary=u'audio', content=u'audio',
                 is_approved=True, save=True)

        ques = question(title=u'q1 audio', save=True)
        ques.tags.add(u'desktop')
        ans = answer(question=ques, save=True)
        answervote(answer=ans, helpful=True, save=True)

        self.refresh()

        response = self.client.get(reverse('search.suggestions',
                                           locale='en-US'),
                                   {'q': 'audio'})
        eq_(200, response.status_code)
        eq_('application/x-suggestions+json', response['content-type'])
        results = json.loads(response.content)

        eq_('audio', results[0])
        eq_(2, len(results[1]))
        eq_(0, len(results[2]))
        eq_(2, len(results[3]))
Example #28
0
    def test_wiki_topics(self):
        """Search wiki for topics, includes multiple."""
        t1 = topic(slug='doesnotexist', save=True)
        t2 = topic(slug='extant', save=True)
        t3 = topic(slug='tagged', save=True)

        doc = document(locale=u'en-US', category=10, save=True)
        doc.topics.add(t2)
        revision(document=doc, is_approved=True, save=True)

        doc = document(locale=u'en-US', category=10, save=True)
        doc.topics.add(t2)
        doc.topics.add(t3)
        revision(document=doc, is_approved=True, save=True)

        self.refresh()

        topic_vals = (
            (t1.slug, 0),
            (t2.slug, 2),
            (t3.slug, 1),
            ([t2.slug, t3.slug], 1),
        )

        qs = {'a': 1, 'w': 1, 'format': 'json'}
        for topics, number in topic_vals:
            qs.update({'topics': topics})
            response = self.client.get(reverse('search'), qs)
            eq_(number, json.loads(response.content)['total'])
Example #29
0
    def test_search_suggestions_archived_articles(self):
        """Verifies that archived articles aren't shown."""
        topic(title='Fix problems', slug='fix-problems', save=True)
        p = product(slug=u'firefox', save=True)

        d1 = document(title=u'document donut', category=10, save=True)
        d1.products.add(p)
        revision(document=d1, is_approved=True, save=True)

        d2 = document(title=u'document cupcake', category=10, is_archived=True,
                      save=True)
        d2.products.add(p)
        revision(document=d1, is_approved=True, save=True)

        self.refresh()

        url = urlparams(
            reverse('questions.aaq_step4', args=['desktop', 'fix-problems']),
            search='document')

        response = self.client.get(url, follow=True)
        eq_(200, response.status_code)

        doc = pq(response.content)
        eq_(len(doc('.result.document')), 1)
        assert 'donut' in doc('.result.document h3 a').text()
        assert 'cupcake' not in doc('.result.document h3 a').text()
Example #30
0
    def test_active_contributors(self):
        """Test active contributors API call."""
        # 2 en-US revisions by 2 contributors:
        r1 = revision(creator=user(save=True), save=True)
        r2 = revision(creator=user(save=True), save=True)
        # A translation with 2 contributors (translator + reviewer):
        d = document(parent=r1.document, locale='es', save=True)
        revision(document=d, reviewed=datetime.now(),
                 reviewer=r1.creator, creator=r2.creator, save=True)
        # 1 active support forum contributor:
        # A user with 10 answers
        u1 = user(save=True)
        for x in range(10):
            answer(save=True, creator=u1)
        # A user with 9 answers
        u2 = user(save=True)
        for x in range(9):
            answer(save=True, creator=u2)
        # A user with 1 answer
        u3 = user(save=True)
        answer(save=True, creator=u3)

        # An AoA reply (1 contributor):
        reply(save=True)

        r = self._get_api_result('kpi_active_contributors')
        eq_(r['objects'][0]['en_us'], 2)
        eq_(r['objects'][0]['non_en_us'], 2)
        eq_(r['objects'][0]['support_forum'], 1)
        eq_(r['objects'][0]['aoa'], 1)
Example #31
0
    def setUp(self):
        super(DocumentZoneTests, self).setUp()

        self.root_links_content = """
            <p>Links content</p>
        """
        self.root_content = """
            <h4 id="links">Links</h4>
            %s
        """ % (self.root_links_content)

        root_rev = revision(title='ZoneRoot', slug='ZoneRoot',
                            content=self.root_content,
                            is_approved=True, save=True)
        self.root_doc = root_rev.document
        self.root_doc.rendered_html = self.root_content
        self.root_doc.save()

        self.root_zone = DocumentZone(document=self.root_doc)
        self.root_zone.save()

        sub_rev = revision(title='SubPage', slug='SubPage',
                           content='This is a subpage',
                           is_approved=True, save=True)
        self.sub_doc = sub_rev.document
        self.sub_doc.parent_topic = self.root_doc
        self.sub_doc.rendered_html = sub_rev.content
        self.sub_doc.save()

        self.sub_sub_links_content = """
            <p>Sub-page links content</p>
        """
        self.sub_sub_content = """
            <h4 id="links">Links</h4>
            %s
        """ % (self.sub_sub_links_content)

        sub_sub_rev = revision(title='SubSubPage', slug='SubSubPage',
                           content='This is a subpage',
                           is_approved=True, save=True)
        self.sub_sub_doc = sub_sub_rev.document
        self.sub_sub_doc.parent_topic = self.sub_doc
        self.sub_sub_doc.rendered_html = self.sub_sub_content
        self.sub_sub_doc.save()

        other_rev = revision(title='otherPage', slug='otherPage',
                            content='This is an other page',
                            is_approved=True, save=True)
        self.other_doc = other_rev.document
        self.other_doc.save()
Example #32
0
    def test_search(self, _out):
        """Test that es_search command doesn't fail"""
        call_command('essearch', 'cupcakes')

        doc = document(title=u'cupcakes rock',
                       locale=u'en-US',
                       category=10,
                       save=True)
        doc.products.add(product(title=u'firefox', slug=u'desktop', save=True))
        revision(document=doc, is_approved=True, save=True)

        self.refresh()

        call_command('essearch', 'cupcakes')
Example #33
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)
        r1 = revision(document=d1, save=True)

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

        time.sleep(1)  # Let timestamps tick over.
        d3 = document(title="FeedDoc3", locale='en-US', save=True)
        r3 = 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.
        r2a = 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 #34
0
 def test_indirect_recursion(self):
     """Make sure indirect recursion is caught."""
     boo = document(title='Template:Boo')
     boo.save()
     yah = document(title='Template:Yah')
     yah.save()
     revision(document=boo,
              content='Paper [[Template:Yah]] Cups',
              is_approved=True).save()
     revision(document=yah,
              content='Wooden [[Template:Boo]] Bats',
              is_approved=True).save()
     recursion_message = RECURSION_MESSAGE % 'Template:Boo'
     eq_('<p>Paper Wooden %s Bats\n Cups\n</p>' % recursion_message,
         boo.content_parsed)
Example #35
0
    def test_wiki_keywords(self):
        """Make sure updating keywords updates the index."""
        # Create a document with a revision with no keywords. It
        # shouldn't show up with a document_keywords term query for
        # 'wool' since it has no keywords.
        doc = document(title=u'wool hats')
        doc.save()
        revision(document=doc, is_approved=True, save=True)
        self.refresh()
        eq_(Document.search().query(document_keywords='wool').count(), 0)

        revision(document=doc, is_approved=True, keywords='wool', save=True)
        self.refresh()

        eq_(Document.search().query(document_keywords='wool').count(), 1)
Example #36
0
    def test_redirect(self):
        """Assert get_object_fallback follows wiki redirects."""
        target_rev = revision(document=document(title='target', save=True),
                              is_approved=True,
                              save=True)
        translated_target_rev = revision(document=document(
            parent=target_rev.document, locale='de', save=True),
                                         is_approved=True,
                                         save=True)
        revision(document=document(title='redirect', save=True),
                 content='REDIRECT [[target]]',
                 is_approved=True).save()

        eq_(translated_target_rev.document,
            get_object_fallback(Document, 'redirect', 'de'))
Example #37
0
    def test_reindex(self, _out):
        doc = document(title=u'cupcakes rock',
                       locale=u'en-US',
                       category=10,
                       save=True)
        doc.products.add(product(title=u'firefox', slug=u'desktop', save=True))
        revision(document=doc, is_approved=True, save=True)

        self.refresh()

        call_command('esreindex')
        call_command('esreindex', '--percent=50')
        call_command('esreindex', '--criticalmass')
        call_command('esreindex', '--mapping_types=wiki_documents')
        call_command('esreindex', '--delete')
Example #38
0
    def test_wiki_products_inherit(self):
        """Translations inherit products from their parents."""
        doc = document(locale=u'en-US', category=10, save=True)
        p = product(title=u'Firefox', slug=u'desktop', save=True)
        doc.products.add(p)
        revision(document=doc, is_approved=True, save=True)

        translated = document(locale=u'fr', parent=doc, category=10, save=True)
        revision(document=translated, is_approved=True, save=True)

        self.refresh()

        qs = {'a': 1, 'w': 1, 'format': 'json', 'product': p.slug}
        response = self.client.get(reverse('search', locale='fr'), qs)
        eq_(1, json.loads(response.content)['total'])
Example #39
0
    def test_wiki_topics_inherit(self):
        """Translations inherit topics from their parents."""
        doc = document(locale=u'en-US', category=10, save=True)
        doc.topics.add(topic(slug='extant', save=True))
        revision(document=doc, is_approved=True, save=True)

        translated = document(locale=u'es', parent=doc, category=10,
                              save=True)
        revision(document=translated, is_approved=True, save=True)

        self.refresh()

        qs = {'a': 1, 'w': 1, 'format': 'json', 'topics': 'extant'}
        response = self.client.get(reverse('search', locale='es'), qs)
        eq_(1, json.loads(response.content)['total'])
Example #40
0
    def test_unready_for_l10n(self):
        """Test status for article that is not ready for l10n"""
        locale = settings.WIKI_DEFAULT_LANGUAGE
        d = document(title='Template:test', save=True)
        revision(document=d, is_ready_for_localization=True, save=True)
        revision(document=d,
                 is_ready_for_localization=False,
                 is_approved=True,
                 significance=MAJOR_SIGNIFICANCE,
                 save=True)

        row = self.row(locale=locale)

        eq_(row['title'], d.title)
        eq_(unicode(row['status']), u'Changes Not Ready For Localization')
Example #41
0
    def test_revisions_feed(self):
        d = document(title='HTML9')
        d.save()
        for i in xrange(1, 6):
            revision(save=True, document=d,
                         title='HTML9', comment='Revision %s' % i,
                         content="Some Content %s" % i,
                         is_approved=True,
                         created=datetime.datetime.now()\
                         + datetime.timedelta(seconds=5 * i))

        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 #42
0
 def test_external(self):
     """Make sure rebuild_kb doesn't delete redirects to external URLs."""
     doc_pk = revision(content='REDIRECT [http://www.example.com/]',
                       is_approved=True,
                       save=True).document.pk
     rebuild_kb()
     assert Document.uncached.filter(pk=doc_pk).exists()
Example #43
0
    def test_product_landing(self, flag_is_active):
        """Verify that /products/<slug> page renders topics."""
        flag_is_active.return_value = True

        # Create a product.
        p = product(save=True)

        # Create some topics.
        topic(slug=HOT_TOPIC_SLUG, save=True)
        topics = []
        for i in range(11):
            topics.append(topic(save=True))

        # Create a document and assign the product and 10 topics.
        doc = revision(is_approved=True, save=True).document
        doc.products.add(p)
        for i in range(10):
            doc.topics.add(topics[i])

        self.refresh()

        # GET the product landing page and verify the content.
        url = reverse('products.product', args=[p.slug])
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(10, len(doc('#help-topics li')))
Example #44
0
    def test_subtopics(self):
        """Verifies subtopics appear on document listing page."""
        # Create a topic and product.
        t = topic(save=True)
        p = product(save=True)

        # Create a documents with the topic and product
        doc = revision(is_approved=True, save=True).document
        doc.topics.add(t)
        doc.products.add(p)

        self.refresh()

        # GET the page and verify no subtopics yet.
        url = reverse('products.documents', args=[p.slug, t.slug])
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(0, len(doc('ul.subtopics')))

        # Create a subtopic and verify it is listed
        topic(parent=t, save=True)
        url = reverse('products.documents', args=[p.slug, t.slug])
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(1, len(doc('ul.subtopics')))
Example #45
0
 def test_from_revision_none(self):
     rev = revision()
     try:
         diff = revisions_unified_diff(None, rev)
     except AttributeError:
         self.fail("Should not throw AttributeError")
     eq_("Diff is unavailable.", diff)
Example #46
0
 def test_context_dict_no_previous_revision(self):
     rev = revision()
     try:
         cd = context_dict(rev)
     except AttributeError:
         self.fail("Should not throw AttributeError")
     eq_(cd, cd)
Example #47
0
 def test_redirect_document_nonexistent(self):
     """Assert redirects to non-existent pages return None."""
     eq_(
         None,
         revision(content='REDIRECT [[kersmoo]]',
                  is_approved=True,
                  save=True).document.redirect_document())
Example #48
0
 def test_redirect_document_external_redirect(self):
     """Assert redirects to external pages return None."""
     eq_(
         None,
         revision(content='REDIRECT [http://example.com]',
                  is_approved=True,
                  save=True).document.redirect_document())
Example #49
0
    def test_recent_helpful_votes(self):
        """Recent helpful votes are indexed properly."""
        # Create a document and verify it doesn't show up in a
        # query for recent_helpful_votes__gt=0.
        r = revision(is_approved=True, save=True)
        self.refresh()
        eq_(
            Document.search().filter(
                document_recent_helpful_votes__gt=0).count(), 0)

        # Add an unhelpful vote, it still shouldn't show up.
        helpful_vote(revision=r, helpful=False, save=True)
        r.document.save()  # Votes don't trigger a reindex.
        self.refresh()
        eq_(
            Document.search().filter(
                document_recent_helpful_votes__gt=0).count(), 0)

        # Add an helpful vote created 31 days ago, it still shouldn't show up.
        created = datetime.now() - timedelta(days=31)
        helpful_vote(revision=r, helpful=True, created=created, save=True)
        r.document.save()  # Votes don't trigger a reindex.
        self.refresh()
        eq_(
            Document.search().filter(
                document_recent_helpful_votes__gt=0).count(), 0)

        # Add an helpful vote created 29 days ago, it should show up now.
        created = datetime.now() - timedelta(days=29)
        helpful_vote(revision=r, helpful=True, created=created, save=True)
        r.document.save()  # Votes don't trigger a reindex.
        self.refresh()
        eq_(
            Document.search().filter(
                document_recent_helpful_votes__gt=0).count(), 1)
Example #50
0
def doc_rev_parser(content, title='Installing Firefox', parser_cls=WikiParser):
    p = parser_cls()
    d = document(title=title)
    d.save()
    r = revision(document=d, content=content, is_approved=True)
    r.save()
    return (d, r, p)
Example #51
0
    def test_topic_select_product(self, flag_is_active):
        """Verify that /topics/<slug>?selectproduct=1 renders products."""
        flag_is_active.return_value = True

        # Create a topic
        t = topic(save=True)

        # Create 3 products
        prods = []
        for i in range(3):
            prods.append(product(save=True))

        # Create a document and assign the topic and two products.
        doc = revision(is_approved=True, save=True).document
        doc.topics.add(t)
        doc.products.add(prods[0])
        doc.products.add(prods[1])

        self.refresh()

        # GET the topic page and verify the content
        url = reverse('topics.topic', args=[t.slug])
        url = urlparams(url, selectproduct=1)
        r = self.client.get(url, follow=True)
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(2, len(doc('#products-and-services li')))
Example #52
0
    def test_needs_change(self):
        """Test setting and unsetting the needs change flag"""
        # Create a new document and edit it, setting needs_change.
        comment = 'Please update for Firefix.next'
        doc = revision(save=True).document
        data = new_document_data()
        data.update({
            'needs_change': True,
            'needs_change_comment': comment,
            'form': 'doc'
        })

        # Verify that needs_change can't be set if the user doesn't have
        # the permission.
        self.client.post(reverse('wiki.edit_document', args=[doc.slug]), data)
        doc = Document.uncached.get(pk=doc.pk)
        assert not doc.needs_change
        assert not doc.needs_change_comment

        # Give the user permission, now it should work.
        add_permission(self.u, Document, 'edit_needs_change')
        self.client.post(reverse('wiki.edit_document', args=[doc.slug]), data)
        doc = Document.uncached.get(pk=doc.pk)
        assert doc.needs_change
        eq_(comment, doc.needs_change_comment)

        # Clear out needs_change.
        data.update({'needs_change': False, 'needs_change_comment': comment})
        self.client.post(reverse('wiki.edit_document', args=[doc.slug]), data)
        doc = Document.uncached.get(pk=doc.pk)
        assert not doc.needs_change
        eq_('', doc.needs_change_comment)
Example #53
0
 def test_consider_max_significance(self):
     """When determining how significantly an article has changed since
     translation, use the max significance of the approved revisions, not
     just that of the latest ready-to-localize one."""
     translation = translated_revision(is_approved=True, save=True)
     revision(document=translation.document.parent,
              is_approved=True,
              is_ready_for_localization=False,  # should still count
              significance=MAJOR_SIGNIFICANCE,
              save=True)
     revision(document=translation.document.parent,
              is_approved=True,
              is_ready_for_localization=True,
              significance=MEDIUM_SIGNIFICANCE,
              save=True)
     eq_([translation.document.title], self.titles())
Example #54
0
 def test_bad_visit_count(self):
     """Skip URLs whose visit counts aren't ints."""
     d = revision(is_approved=True, save=True).document
     eq_({}, WikiDocumentVisits._visit_counts('{"data": {"12/01/2010-12/07/'
         '2010": {"SubRows":{"http://support.mozilla.com/%s/kb/%s":{'
         '"measures":{"Visits":"non-integer"}}}}}}'
         % (settings.LANGUAGE_CODE, d.slug)))
Example #55
0
    def test_correct_based_on_to_current_revision(self):
        """Assure Revision.clean() defaults based_on value to the English
        doc's current_revision when there is one."""
        # Make English rev:
        en_rev = revision(is_approved=True)
        en_rev.save()

        # Make Deutsch translation:
        de_doc = document(parent=en_rev.document, locale='de')
        de_doc.save()
        de_rev = revision(document=de_doc)

        # Set based_on to a de rev to simulate fixing broken translation source
        de_rev.based_on = de_rev
        de_rev.clean()
        eq_(en_rev.document.current_revision, de_rev.based_on)
Example #56
0
 def test_vote_on_template(self):
     """Throw helpful_vote a document that is a template and see if it 400s."""
     d = document(save=True, slug="somedoc", category=TEMPLATES_CATEGORY)
     r = revision(save=True, document=d)
     response = self.client.post(reverse('wiki.document_vote', args=['hi']),
                                 {'revision_id': r.id})
     eq_(400, response.status_code)
Example #57
0
 def test_untranslated(self):
     """Assert untranslated templates are labeled as such."""
     d = document(title='Template:test', save=True)
     untranslated = revision(is_approved=True, document=d, save=True)
     row = self.row()
     eq_(row['title'], untranslated.document.title)
     eq_(unicode(row['status']), 'Translation Needed')
Example #58
0
    def facets_setUp(self):
        # Create topics
        self.general = topic(slug='general', save=True)
        self.bookmarks = topic(slug='bookmarks', save=True)
        self.sync = topic(slug='sync', save=True)

        # Create products
        self.desktop = product(slug='firefox', save=True)
        self.mobile = product(slug='mobile', save=True)

        # Set up documents.
        doc1 = revision(is_approved=True, save=True).document
        doc1.topics.add(self.general)
        doc1.topics.add(self.bookmarks)
        doc1.products.add(self.desktop)

        doc2 = revision(is_approved=True, save=True).document
        doc2.topics.add(self.bookmarks)
        doc2.topics.add(self.sync)
        doc2.products.add(self.desktop)
        doc2.products.add(self.mobile)

        # An archived article shouldn't show up
        doc3 = revision(is_approved=True, save=True).document
        doc3.is_archived = True
        doc3.save()
        doc3.topics.add(self.general)
        doc3.topics.add(self.bookmarks)
        doc3.products.add(self.desktop)

        # A template article shouldn't show up either
        doc4 = revision(is_approved=True, save=True).document
        doc4.category = 60
        doc4.title = 'Template: Test'
        doc4.save()
        doc4.topics.add(self.general)
        doc4.topics.add(self.bookmarks)
        doc4.products.add(self.desktop)

        # An article without current revision should be "invisible"
        # to everything.
        doc5 = revision(is_approved=False, save=True).document
        doc5.topics.add(self.general)
        doc5.topics.add(self.bookmarks)
        doc5.topics.add(self.sync)
        doc5.products.add(self.desktop)
        doc5.products.add(self.mobile)
Example #59
0
 def test_bad_page_info(self):
     """Skip URLs whose page info is unsubscriptable."""
     d = revision(is_approved=True, save=True).document
     eq_({},
         WikiDocumentVisits._visit_counts(
             '{"data": {"12/01/2010-12/07/'
             '2010": {"SubRows":{"http://support.mozilla.com/%s/kb/%s":8}}}}'
             % (settings.LANGUAGE_CODE, d.slug)))
Example #60
0
    def test_indirect_recursion(self):
        """Make sure indirect recursion is caught."""
        boo = document(title='Boo')
        boo.save()
        yah = document(title='Yah')
        yah.save()
        revision(document=boo, content='Paper [[Include:Yah]] Cups',
                 is_approved=True).save()
        revision(document=yah, content='Wooden [[Include:Boo]] Bats',
                 is_approved=True).save()
        recursion_message = RECURSION_MESSAGE % 'Boo'

        # boo.content_parsed is something like <p>Paper </p><p>Wooden
        # [Recursive inclusion of "Boo"] Bats\n</p> Cups\n<p></p>.
        eq_('Paper Wooden %s Bats Cups' % recursion_message,
            boo.content_parsed.replace('</p>', '').replace('<p>',
            '').replace('\n', ''))