Exemple #1
0
    def test_recent_counts_with_filter(self):
        """Verify that recent_asked_count and recent_unanswered_count
        respect filters passed."""

        now = datetime.now()
        question(created=now, locale='en-US', save=True)
        q = question(created=now, locale='en-US', save=True)
        answer(question=q, save=True)

        question(created=now, locale='pt-BR', save=True)
        question(created=now, locale='pt-BR', save=True)
        q = question(created=now, locale='pt-BR', save=True)
        answer(question=q, save=True)

        # 5 asked recently, 3 are unanswered
        eq_(5, Question.recent_asked_count())
        eq_(3, Question.recent_unanswered_count())

        # check english (2 asked, 1 unanswered)
        locale_filter = Q(locale='en-US')
        eq_(2, Question.recent_asked_count(locale_filter))
        eq_(1, Question.recent_unanswered_count(locale_filter))

        # check pt-BR (3 asked, 2 unanswered)
        locale_filter = Q(locale='pt-BR')
        eq_(3, Question.recent_asked_count(locale_filter))
        eq_(2, Question.recent_unanswered_count(locale_filter))
Exemple #2
0
    def test_created(self):
        """Basic functionality of created filter."""
        created_ds = datetime(2010, 6, 19, 12, 00)

        # on 6/19/2010
        q1 = question(title=u'q1 audio', created=created_ds, save=True)
        q1.tags.add(u'desktop')
        ans = answer(question=q1, save=True)
        answervote(answer=ans, helpful=True, save=True)

        # on 6/21/2010
        q2 = question(title=u'q2 audio',
                      created=(created_ds + timedelta(days=2)),
                      save=True)
        q2.tags.add(u'desktop')
        ans = answer(question=q2, save=True)
        answervote(answer=ans, helpful=True, save=True)

        self.refresh()

        qs = {'a': 1, 'w': 2, 'format': 'json',
              'sortby': 2, 'created_date': '06/20/2010'}

        qs['created'] = constants.INTERVAL_BEFORE
        response = self.client.get(reverse('search'), qs)
        results = json.loads(response.content)['results']
        eq_([q1.get_absolute_url()], [r['url'] for r in results])

        qs['created'] = constants.INTERVAL_AFTER
        response = self.client.get(reverse('search'), qs)
        results = json.loads(response.content)['results']
        eq_([q2.get_absolute_url()], [r['url'] for r in results])
Exemple #3
0
    def test_asker_replies_arent_a_contribution(self):
        """Verify that replies posted by the question creator aren't counted.

        If a user has 10 replies to their own question, they aren't counted as
        a contributor.
        """
        # A user with 10 answers to own question.
        q = question(save=True)
        u = q.creator
        for x in range(10):
            answer(creator=u, question=q, save=True)

        # Create metric kinds and update metrics for tomorrow (today's
        # activity shows up tomorrow).
        self._make_contributor_metric_kinds()
        update_contributor_metrics(day=date.today() + timedelta(days=1))

        r = self._get_api_result('kpi_active_contributors')
        eq_(r['objects'][0]['support_forum'], 0)

        # Change the question creator, now we should have 1 contributor.
        q.creator = user(save=True)
        q.save()
        cache.clear()  # We need to clear the cache for new results.

        Metric.objects.all().delete()
        update_contributor_metrics(day=date.today() + timedelta(days=1))

        r = self._get_api_result('kpi_active_contributors')
        eq_(r['objects'][0]['support_forum'], 1)
Exemple #4
0
    def test_asker_replies_arent_a_contribution(self):
        """Verify that replies posted by the question creator aren't counted.

        If a user has 10 replies to their own question, they aren't counted as
        a contributor.
        """
        # A user with 10 answers to own question.
        q = question(save=True)
        u = q.creator
        for x in range(10):
            answer(creator=u, question=q, save=True)

        # Create metric kinds and update metrics for tomorrow (today's
        # activity shows up tomorrow).
        self._make_contributor_metric_kinds()
        update_contributor_metrics(day=date.today() + timedelta(days=1))

        r = self._get_api_result('kpi_active_contributors')
        eq_(r['objects'][0]['support_forum'], 0)

        # Change the question creator, now we should have 1 contributor.
        q.creator = user(save=True)
        q.save()
        cache.clear()  # We need to clear the cache for new results.

        Metric.objects.all().delete()
        update_contributor_metrics(day=date.today() + timedelta(days=1))

        r = self._get_api_result('kpi_active_contributors')
        eq_(r['objects'][0]['support_forum'], 1)
Exemple #5
0
    def test_created(self):
        """Basic functionality of created filter."""
        created_ds = datetime(2010, 6, 19, 12, 00)

        # on 6/19/2010
        q1 = question(title=u"q1 audio", created=created_ds, save=True)
        q1.tags.add(u"desktop")
        ans = answer(question=q1, save=True)
        answervote(answer=ans, helpful=True, save=True)

        # on 6/21/2010
        q2 = question(title=u"q2 audio", created=(created_ds + timedelta(days=2)), save=True)
        q2.tags.add(u"desktop")
        ans = answer(question=q2, save=True)
        answervote(answer=ans, helpful=True, save=True)

        self.refresh()

        qs = {"a": 1, "w": 2, "format": "json", "sortby": 2, "created_date": "06/20/2010"}

        qs["created"] = constants.INTERVAL_BEFORE
        response = self.client.get(reverse("search"), qs)
        results = json.loads(response.content)["results"]
        eq_([q1.get_absolute_url()], [r["url"] for r in results])

        qs["created"] = constants.INTERVAL_AFTER
        response = self.client.get(reverse("search"), qs)
        results = json.loads(response.content)["results"]
        eq_([q2.get_absolute_url()], [r["url"] for r in results])
Exemple #6
0
    def test_created(self):
        """Basic functionality of created filter."""
        created_ds = datetime(2010, 6, 19, 12, 00)

        # on 6/19/2010
        q1 = question(title=u'q1 audio', created=created_ds, save=True)
        q1.tags.add(u'desktop')
        ans = answer(question=q1, save=True)
        answervote(answer=ans, helpful=True, save=True)

        # on 6/21/2010
        q2 = question(title=u'q2 audio',
                      created=(created_ds + timedelta(days=2)),
                      save=True)
        q2.tags.add(u'desktop')
        ans = answer(question=q2, save=True)
        answervote(answer=ans, helpful=True, save=True)

        self.refresh()

        qs = {'a': 1, 'w': 2, 'format': 'json',
              'sortby': 2, 'created_date': '06/20/2010'}

        qs['created'] = constants.INTERVAL_BEFORE
        response = self.client.get(reverse('search'), qs)
        results = json.loads(response.content)['results']
        eq_([q1.get_absolute_url()], [r['url'] for r in results])

        qs['created'] = constants.INTERVAL_AFTER
        response = self.client.get(reverse('search'), qs)
        results = json.loads(response.content)['results']
        eq_([q2.get_absolute_url()], [r['url'] for r in results])
Exemple #7
0
    def test_recent_counts_with_filter(self):
        """Verify that recent_asked_count and recent_unanswered_count
        respect filters passed."""

        now = datetime.now()
        question(created=now, locale='en-US', save=True)
        q = question(created=now, locale='en-US', save=True)
        answer(question=q, save=True)

        question(created=now, locale='pt-BR', save=True)
        question(created=now, locale='pt-BR', save=True)
        q = question(created=now, locale='pt-BR', save=True)
        answer(question=q, save=True)

        # 5 asked recently, 3 are unanswered
        eq_(5, Question.recent_asked_count())
        eq_(3, Question.recent_unanswered_count())

        # check english (2 asked, 1 unanswered)
        locale_filter = Q(locale='en-US')
        eq_(2, Question.recent_asked_count(locale_filter))
        eq_(1, Question.recent_unanswered_count(locale_filter))

        # check pt-BR (3 asked, 2 unanswered)
        locale_filter = Q(locale='pt-BR')
        eq_(3, Question.recent_asked_count(locale_filter))
        eq_(2, Question.recent_unanswered_count(locale_filter))
Exemple #8
0
    def test_user_num_answers(self):
        u = user(save=True)
        q = question(save=True)

        eq_(user_num_answers(u), 0)
        a1 = answer(creator=u, question=q, save=True)
        eq_(user_num_answers(u), 1)
        a2 = answer(creator=u, question=q, save=True)
        eq_(user_num_answers(u), 2)
        a1.delete()
        eq_(user_num_answers(u), 1)
        a2.delete()
        eq_(user_num_answers(u), 0)
    def test_user_num_answers(self):
        u = user(save=True)
        q = question(save=True)

        eq_(user_num_answers(u), 0)
        a1 = answer(creator=u, question=q, save=True)
        eq_(user_num_answers(u), 1)
        a2 = answer(creator=u, question=q, save=True)
        eq_(user_num_answers(u), 2)
        a1.delete()
        eq_(user_num_answers(u), 1)
        a2.delete()
        eq_(user_num_answers(u), 0)
Exemple #10
0
    def test_recent_counts(self):
        """Verify recent_asked_count and recent unanswered count."""
        # create a question for each of past 4 days
        now = datetime.now()
        question(created=now, save=True)
        question(created=now - timedelta(hours=12), save=True, is_locked=True)
        q = question(created=now - timedelta(hours=23), save=True)
        answer(question=q, save=True)
        # 25 hours instead of 24 to avoid random test fails.
        question(created=now - timedelta(hours=25), save=True)

        # Only 3 are recent from last 72 hours, 1 has an answer.
        eq_(3, Question.recent_asked_count())
        eq_(1, Question.recent_unanswered_count())
Exemple #11
0
    def test_recent_counts(self):
        """Verify recent_asked_count and recent unanswered count."""
        # create a question for each of past 4 days
        now = datetime.now()
        question(created=now, save=True)
        question(created=now - timedelta(hours=24), save=True, is_locked=True)
        q = question(created=now - timedelta(hours=48), save=True)
        answer(question=q, save=True)
        # 73 hours instead of 72 to avoid random test fails.
        question(created=now - timedelta(hours=73), save=True)

        # Only 3 are recent from last 72 hours, 1 has an answer.
        eq_(3, Question.recent_asked_count())
        eq_(1, Question.recent_unanswered_count())
Exemple #12
0
    def test_questions(self):
        """Test questions API call."""
        # A question with a solution:
        a = answer(save=True)
        a.question.solution = a
        a.question.save()
        # A question with an answer:
        answer(save=True)
        # A question without answers:
        question(save=True)

        r = self._get_api_result('kpi_questions')
        eq_(r['objects'][0]['solved'], 1)
        eq_(r['objects'][0]['responded'], 2)
        eq_(r['objects'][0]['questions'], 3)
Exemple #13
0
    def test_questions(self):
        """Test questions API call."""
        # A question with a solution:
        a = answer(save=True)
        a.question.solution = a
        a.question.save()
        # A question with an answer:
        answer(save=True)
        # A question without answers:
        question(save=True)

        r = self._get_api_result('kpi_questions')
        eq_(r['objects'][0]['solved'], 1)
        eq_(r['objects'][0]['responded'], 2)
        eq_(r['objects'][0]['questions'], 3)
Exemple #14
0
    def test_vote(self):
        """Test vote API call."""
        u = user(save=True)
        add_permission(u, Profile, 'view_kpi_dashboard')

        r = revision(save=True)
        helpful_vote(revision=r, save=True)
        helpful_vote(revision=r, save=True)
        helpful_vote(revision=r, helpful=True, save=True)

        a = answer(save=True)
        answer_vote(answer=a, save=True)
        answer_vote(answer=a, helpful=True, save=True)
        answer_vote(answer=a, helpful=True, save=True)

        url = reverse('api_dispatch_list',
                      kwargs={'resource_name': 'kpi_vote',
                              'api_name': 'v1'})
        self.client.login(username=u.username, password='******')
        response = self.client.get(url + '?format=json')
        eq_(200, response.status_code)
        r = json.loads(response.content)
        eq_(r['objects'][0]['kb_helpful'], 1)
        eq_(r['objects'][0]['kb_votes'], 3)
        eq_(r['objects'][0]['ans_helpful'], 2)
        eq_(r['objects'][0]['ans_votes'], 3)
Exemple #15
0
    def test_front_page_only_shows_wiki_and_questions(self):
        """Tests that the front page 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

        """
        ques = question(title=u"audio", save=True)
        ques.tags.add(u"desktop")
        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(product(slug=u"desktop", save=True))
        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_tags": "desktop", "product": "desktop", "q": "audio", "format": "json"}
        )

        eq_(200, response.status_code)

        content = json.loads(response.content)
        eq_(content["total"], 2)
Exemple #16
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
Exemple #17
0
    def test_added(self):
        search = QuestionMappingType.search()

        # Create a question--that adds one document to the index.
        q = question(title=u'Does this test work?', save=True)
        self.refresh()
        query = dict(('%s__text' % field, 'test')
                     for field in QuestionMappingType.get_query_fields())
        eq_(search.query(should=True, **query).count(), 1)

        # Create an answer for the question. It shouldn't be searchable
        # until the answer is saved.
        a = answer(content=u'There\'s only one way to find out!',
                   question=q)
        self.refresh()
        query = dict(('%s__text' % field, 'only')
                     for field in QuestionMappingType.get_query_fields())
        eq_(search.query(should=True, **query).count(), 0)

        a.save()
        self.refresh()
        query = dict(('%s__text' % field, 'only')
                     for field in QuestionMappingType.get_query_fields())
        eq_(search.query(should=True, **query).count(), 1)

        # Make sure that there's only one question document in the
        # index--creating an answer should have updated the existing
        # one.
        eq_(search.count(), 1)
Exemple #18
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]))
Exemple #19
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
Exemple #20
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]))
Exemple #21
0
    def test_asked_by(self):
        """Check several author values, including test for (anon)"""
        author_vals = (
            ('DoesNotExist', 0),
            ('jsocol', 2),
            ('pcraciunoiu', 2),
        )

        # Set up all the question data---creats users, creates the
        # questions, shove it all in the index, then query it and see
        # what happens.
        for name, number in author_vals:
            u = user(username=name, save=True)
            for i in range(number):
                ques = question(title=u'audio', creator=u, save=True)
                ques.tags.add(u'desktop')
                ans = answer(question=ques, save=True)
                answervote(answer=ans, helpful=True, save=True)

        self.refresh()

        qs = {'a': 1, 'w': 2, 'format': 'json'}

        for author, total in author_vals:
            qs.update({'asked_by': author})
            response = self.client.get(reverse('search'), qs)
            eq_(total, json.loads(response.content)['total'])
Exemple #22
0
    def test_added(self):
        # Create a question--that adds one document to the index.
        q = question(title=u'Does this test work?', save=True)
        self.refresh()
        eq_(
            Question.search().query(or_=dict(
                ('%s__text' % field, 'test')
                for field in Question.get_query_fields())).count(), 1)

        # Create an answer for the question. It shouldn't be searchable
        # until the answer is saved.
        a = answer(content=u'There\'s only one way to find out!', question=q)
        self.refresh()
        eq_(
            Question.search().query(or_=dict(
                ('%s__text' % field, 'only')
                for field in Question.get_query_fields())).count(), 0)

        a.save()
        self.refresh()
        eq_(
            Question.search().query(or_=dict(
                ('%s__text' % field, 'only')
                for field in Question.get_query_fields())).count(), 1)

        # Make sure that there's only one question document in the
        # index--creating an answer should have updated the existing
        # one.
        eq_(Question.search().count(), 1)
Exemple #23
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)
Exemple #24
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)
Exemple #25
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
Exemple #26
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)
Exemple #27
0
    def test_asked_by(self):
        """Check several author values, including test for (anon)"""
        author_vals = (
            ('DoesNotExist', 0),
            ('jsocol', 2),
            ('pcraciunoiu', 2),
        )

        # Set up all the question data---creats users, creates the
        # questions, shove it all in the index, then query it and see
        # what happens.
        for name, number in author_vals:
            u = user(username=name, save=True)
            for i in range(number):
                ques = question(title=u'audio', creator=u, save=True)
                ques.tags.add(u'desktop')
                ans = answer(question=ques, save=True)
                answervote(answer=ans, helpful=True, save=True)

        self.refresh()

        qs = {'a': 1, 'w': 2, 'format': 'json'}

        for author, total in author_vals:
            qs.update({'asked_by': author})
            response = self.client.get(reverse('search'), qs)
            eq_(total, json.loads(response.content)['total'])
Exemple #28
0
    def test_fast_response(self):
        """Test fast response API call."""
        a = answer(save=True)
        a.question.solution = a
        a.question.save()

        a = answer(save=True)
        a.question.save()

        url = reverse('api_dispatch_list',
                      kwargs={'resource_name': 'kpi_fast_response',
                              'api_name': 'v1'})
        response = self.client.get(url + '?format=json')
        eq_(200, response.status_code)
        r = json.loads(response.content)
        eq_(r['objects'][0]['responded'], 2)
        eq_(r['objects'][0]['questions'], 2)
Exemple #29
0
 def test_case_insensitive_search(self):
     """Ensure the default searcher is case insensitive."""
     answervote(
         answer=answer(question=question(title="lolrus", content="I am the lolrus.", save=True), save=True),
         helpful=True,
     ).save()
     self.refresh()
     result = Question.search().query("LOLRUS")
     assert len(result) > 0
Exemple #30
0
    def test_front_page_search_for_questions(self):
        """This tests whether doing a search from the front page returns
        question results.

        Bug #709202.

        """
        # Create a question with an answer with an answervote that
        # marks the answer as helpful.  The question should have the
        # "desktop" tag.
        ques = question(title=u'audio fails', content=u'my audio dont work.')
        ques.save()

        ques.tags.add(u'desktop')

        ans = answer(question=ques,
                     content=u'You need to turn your volume up.')
        ans.save()

        ansvote = answer_vote(answer=ans, helpful=True)
        ansvote.save()

        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.localizing_client.get(
            reverse('search'), {
                'q_tags': 'desktop',
                'product': 'desktop',
                'q': 'audio',
                'format': 'json'
            })

        eq_(200, response.status_code)

        content = json.loads(response.content)
        eq_(content['total'], 1)

        # This is another search that picks up results based on the
        # answer_content.  answer_content is in a string array, so
        # this makes sure that works.
        response = self.localizing_client.get(
            reverse('search'), {
                'q_tags': 'desktop',
                'product': 'desktop',
                'q': 'volume',
                'format': 'json'
            })

        eq_(200, response.status_code)

        content = json.loads(response.content)
        eq_(content['total'], 1)
Exemple #31
0
    def test_front_page_search_for_questions(self):
        """This tests whether doing a search from the front page returns
        question results.

        Bug #709202.

        """
        # Create a question with an answer with an answervote that
        # marks the answer as helpful.  The question should have the
        # "desktop" tag.
        ques = question(
            title=u'audio fails',
            content=u'my audio dont work.')
        ques.save()

        ques.tags.add(u'desktop')

        ans = answer(
            question=ques,
            content=u'You need to turn your volume up.')
        ans.save()

        ansvote = answer_vote(
            answer=ans,
            helpful=True)
        ansvote.save()

        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.localizing_client.get(reverse('search'), {
            'q_tags': 'desktop', 'product': 'desktop', 'q': 'audio',
            'format': 'json'
        })

        eq_(200, response.status_code)

        content = json.loads(response.content)
        eq_(content['total'], 1)

        # This is another search that picks up results based on the
        # answer_content.  answer_content is in a string array, so
        # this makes sure that works.
        response = self.localizing_client.get(reverse('search'), {
            'q_tags': 'desktop', 'product': 'desktop', 'q': 'volume',
            'format': 'json'
        })

        eq_(200, response.status_code)

        content = json.loads(response.content)
        eq_(content['total'], 1)
Exemple #32
0
    def setUp(self):
        super(FlaggedQueueTestCase, self).setUp()
        q = question(creator=user(save=True), save=True)
        self.answer = answer(question=q, creator=user(save=True), save=True)

        self.flagger = user(save=True)
        u = user(save=True)
        add_permission(u, FlaggedObject, 'can_moderate')

        self.client.login(username=u.username, password='******')
Exemple #33
0
    def test_user_num_solutions(self):
        u = user(save=True)
        q1 = question(save=True)
        q2 = question(save=True)
        a1 = answer(creator=u, question=q1, save=True)
        a2 = answer(creator=u, question=q2, save=True)

        eq_(user_num_solutions(u), 0)
        q1.solution = a1
        q1.save()
        eq_(user_num_solutions(u), 1)
        q2.solution = a2
        q2.save()
        eq_(user_num_solutions(u), 2)
        q1.solution = None
        q1.save()
        eq_(user_num_solutions(u), 1)
        a2.delete()
        eq_(user_num_solutions(u), 0)
Exemple #34
0
    def test_user_num_solutions(self):
        u = user(save=True)
        q1 = question(save=True)
        q2 = question(save=True)
        a1 = answer(creator=u, question=q1, save=True)
        a2 = answer(creator=u, question=q2, save=True)

        eq_(user_num_solutions(u), 0)
        q1.solution = a1
        q1.save()
        eq_(user_num_solutions(u), 1)
        q2.solution = a2
        q2.save()
        eq_(user_num_solutions(u), 2)
        q1.solution = None
        q1.save()
        eq_(user_num_solutions(u), 1)
        a2.delete()
        eq_(user_num_solutions(u), 0)
Exemple #35
0
 def test_case_insensitive_search(self):
     """Ensure the default searcher is case insensitive."""
     answer_vote(answer=answer(question=question(title='lolrus',
                                                 content='I am the lolrus.',
                                                 save=True),
                               save=True),
                 helpful=True).save()
     self.refresh()
     result = question_searcher(dummy_request).query('LOLRUS')
     assert len(result) > 0
Exemple #36
0
    def setUp(self):
        super(TestQuestionUpdates, self).setUp()
        self.u = user(is_superuser=True, save=True)
        self.client.login(username=self.u.username, password='******')

        self.q = question(updated=datetime(2012, 7, 9, 9, 0, 0), save=True)
        self.a = answer(question=self.q, save=True)

        # Get the question from the database so we have a consistent level of
        # precision during the test.
        self.q = Question.objects.get(pk=self.q.id)
Exemple #37
0
 def test_case_insensitive_search(self):
     """Ensure the default searcher is case insensitive."""
     answervote(answer=answer(question=question(title='lolrus',
                                                content='I am the lolrus.',
                                                save=True),
                              save=True),
                helpful=True).save()
     self.refresh()
     result = Question.search().query(question_title__text='LOLRUS',
                                      question_content__text='LOLRUS')
     assert result.count() > 0
Exemple #38
0
    def test_content_parsed_with_locale(self):
        """Make sure links to localized articles work."""
        rev = translated_revision(locale='es', is_approved=True, save=True)
        doc = rev.document
        doc.title = u'Un mejor título'
        doc.save()

        q = question(locale='es', save=True)
        a = answer(question=q, content='[[%s]]' % doc.title, save=True)

        assert 'es/kb/%s' % doc.slug in a.content_parsed
Exemple #39
0
    def setUp(self):
        super(TestQuestionUpdates, self).setUp()
        self.u = user(is_superuser=True, save=True)
        self.client.login(username=self.u.username, password='******')

        self.q = question(updated=datetime(2012, 7, 9, 9, 0, 0), save=True)
        self.a = answer(question=self.q, save=True)

        # Get the question from the database so we have a consistent level of
        # precision during the test.
        self.q = Question.objects.get(pk=self.q.id)
Exemple #40
0
 def test_case_insensitive_search(self):
     """Ensure the default searcher is case insensitive."""
     answervote(
         answer=answer(question=question(title='lolrus',
                                         content='I am the lolrus.',
                                         save=True),
                       save=True),
         helpful=True).save()
     self.refresh()
     result = Question.search().query('LOLRUS')
     assert result.count() > 0
Exemple #41
0
    def test_content_parsed_with_locale(self):
        """Make sure links to localized articles work."""
        rev = translated_revision(locale='es', is_approved=True, save=True)
        doc = rev.document
        doc.title = u'Un mejor título'
        doc.save()

        q = question(locale='es', save=True)
        a = answer(question=q, content='[[%s]]' % doc.title, save=True)

        assert 'es/kb/%s' % doc.slug in a.content_parsed
Exemple #42
0
    def test_fast_response(self):
        """Test fast response API call."""
        u = user(save=True)
        add_permission(u, Profile, 'view_kpi_dashboard')

        a = answer(save=True)
        a.question.solution = a
        a.question.save()

        a = answer(save=True)
        a.question.save()

        url = reverse('api_dispatch_list',
                      kwargs={'resource_name': 'kpi_fast_response',
                              'api_name': 'v1'})
        self.client.login(username=u.username, password='******')
        response = self.client.get(url + '?format=json')
        eq_(200, response.status_code)
        r = json.loads(response.content)
        eq_(r['objects'][0]['responded'], 2)
        eq_(r['objects'][0]['questions'], 2)
Exemple #43
0
    def test_empty_pages(self):
        """Tests requesting a page that has no results"""
        ques = question(title=u'audio', save=True)
        ques.tags.add(u'desktop')
        ans = answer(question=ques, content=u'volume', save=True)
        answervote(answer=ans, helpful=True, save=True)

        self.refresh()

        qs = {'q': 'audio', 'page': 81}
        response = self.client.get(reverse('search'), qs)
        eq_(200, response.status_code)
    def setUp(self):
        super(FlaggedQueueTestCase, self).setUp()
        q = question(creator=user(save=True), save=True)
        self.answer = answer(question=q,
                             creator=user(save=True),
                             save=True)

        self.flagger = user(save=True)
        u = user(save=True)
        add_permission(u, FlaggedObject, 'can_moderate')

        self.client.login(username=u.username, password='******')
Exemple #45
0
    def test_answer_vote_limit(self):
        """Test that an anonymous user's votes are ignored after 10
        answer votes."""
        q = question(save=True)
        answers = [answer(question=q, save=True) for _ in range(11)]

        # The rate limit is 10 per day. So make 10 requests. (0 through 9)
        for i in range(10):
            self._check_answer_vote(q, answers[i], False)

        # Now make another, it should fail.
        self._check_answer_vote(q, answers[10], True)
Exemple #46
0
    def test_answer_vote_limit(self):
        """Test that an anonymous user's votes are ignored after 10
        answer votes."""
        q = question(save=True)
        answers = [answer(question=q, save=True) for _ in range(11)]

        # The rate limit is 10 per day. So make 10 requests. (0 through 9)
        for i in range(10):
            self._check_answer_vote(q, answers[i], False)

        # Now make another, it should fail.
        self._check_answer_vote(q, answers[10], True)
Exemple #47
0
    def test_empty_pages(self):
        """Tests requesting a page that has no results"""
        ques = question(title=u'audio', save=True)
        ques.tags.add(u'desktop')
        ans = answer(question=ques, content=u'volume', save=True)
        answervote(answer=ans, helpful=True, save=True)

        self.refresh()

        qs = {'q': 'audio', 'page': 81}
        response = self.client.get(reverse('search'), qs)
        eq_(200, response.status_code)
Exemple #48
0
    def test_empty_pages(self):
        """Tests requesting a page that has no results"""
        ques = question(title=u"audio", save=True)
        ques.tags.add(u"desktop")
        ans = answer(question=ques, content=u"volume", save=True)
        answervote(answer=ans, helpful=True, save=True)

        self.refresh()

        qs = {"q": "audio", "page": 81}
        response = self.client.get(reverse("search"), qs)
        eq_(200, response.status_code)
Exemple #49
0
    def test_active_answerers(self):
        """Test active answerers API call."""
        # 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)

        # There should be only one active contributor.
        url = reverse('api_dispatch_list',
                      kwargs={'resource_name': 'kpi_active_answerers',
                              'api_name': 'v1'})

        response = self.client.get(url + '?format=json')
        eq_(200, response.status_code)
        r = json.loads(response.content)
        eq_(r['objects'][0]['contributors'], 1)
Exemple #50
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)
Exemple #51
0
    def test_clean_excerpt(self):
        """Ensure we clean html out of excerpts."""
        q = question(title='audio',
                     content='<script>alert("hacked");</script>',
                     save=True)
        a = answer(question=q, save=True)
        answervote(answer=a, helpful=True, save=True)

        self.refresh()

        response = self.client.get(reverse('search'), {'q': 'audio'})
        eq_(200, response.status_code)

        doc = pq(response.content)
        assert 'script' not in doc('div.result').text()
Exemple #52
0
    def test_created_default(self):
        """Questions older than 180 days aren't returned by default."""
        max_age_days = settings.SEARCH_DEFAULT_MAX_QUESTION_AGE / 60 / 60 / 24
        # Older than max_age_days:
        created = datetime.now() - timedelta(days=max_age_days + 1)
        q1 = question(title=u'q1 audio', created=created, save=True)
        q1.tags.add(u'desktop')
        ans = answer(question=q1, save=True)
        answervote(answer=ans, helpful=True, save=True)

        # Younger than max_age_days:
        created = datetime.now() - timedelta(days=max_age_days - 1)
        q2 = question(title=u'q2 audio', created=created, save=True)
        q2.tags.add(u'desktop')
        ans = answer(question=q2, save=True)
        answervote(answer=ans, helpful=True, save=True)

        self.refresh()

        qs = {'format': 'json', 'q': 'audio'}

        response = self.client.get(reverse('search'), qs)
        results = json.loads(response.content)['results']
        eq_([q2.get_absolute_url()], [r['url'] for r in results])
Exemple #53
0
    def test_vote(self):
        """Test vote API call."""
        r = revision(save=True)
        helpful_vote(revision=r, save=True)
        helpful_vote(revision=r, save=True)
        helpful_vote(revision=r, helpful=True, save=True)

        a = answer(save=True)
        answervote(answer=a, save=True)
        answervote(answer=a, helpful=True, save=True)
        answervote(answer=a, helpful=True, save=True)

        r = self._get_api_result('kpi_vote')
        eq_(r['objects'][0]['kb_helpful'], 1)
        eq_(r['objects'][0]['kb_votes'], 3)
        eq_(r['objects'][0]['ans_helpful'], 2)
        eq_(r['objects'][0]['ans_votes'], 3)
Exemple #54
0
    def test_default_search_for_questions(self):
        """This tests whether doing a default search returns
        question results.

        Bug #709202.

        """
        # Create a question with an answer with an answervote that
        # marks the answer as helpful.  The question should have the
        # "desktop" tag.
        p = product(title=u'firefox', 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)

        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)

        # This is another search that picks up results based on the
        # answer_content.  answer_content is in a string array, so
        # this makes sure that works.
        response = self.client.get(reverse('search'), {
            'q': 'volume',
            'format': 'json'
        })

        eq_(200, response.status_code)

        content = json.loads(response.content)
        eq_(content['total'], 1)
Exemple #55
0
    def test_category_invalid(self):
        """Tests passing an invalid category"""
        # wiki and questions
        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)

        d1 = document(title=u'd1 audio', locale=u'en-US', category=10,
                      is_archived=False, save=True)
        d1.tags.add(u'desktop')
        revision(document=d1, is_approved=True, save=True)

        self.refresh()

        qs = {'a': 1, 'w': 3, 'format': 'json', 'category': 'invalid'}
        response = self.client.get(reverse('search'), qs)
        eq_(2, json.loads(response.content)['total'])
Exemple #56
0
    def test_question_one_answer_deleted(self):
        eq_(elasticutils.S(Question).count(), 0)

        q = question(save=True)
        a = answer(question=q, save=True)
        self.refresh()

        # Question and its answers are a single document--so the
        # index count should be only 1.
        eq_(elasticutils.S(Question).count(), 1)

        a.delete()
        self.refresh()
        eq_(elasticutils.S(Question).count(), 1)

        q.delete()
        self.refresh()
        eq_(elasticutils.S(Question).count(), 0)
Exemple #57
0
    def test_question_one_answer_deleted(self):
        q = question(title=u'are model makers the new pink?', save=True)
        a = answer(content=u'yes.', question=q, save=True)
        self.refresh()

        # Question and its answers are a single document--so the
        # index count should be only 1.
        eq_(Question.search().query(question_title__text='pink').count(), 1)

        # After deleting the answer, the question document should
        # remain.
        a.delete()
        self.refresh()
        eq_(Question.search().query(question_title__text='pink').count(), 1)

        # Delete the question and it should be removed from the
        # index.
        q.delete()
        self.refresh()
        eq_(Question.search().query(question_title__text='pink').count(), 0)
Exemple #58
0
    def test_added(self):
        eq_(elasticutils.S(Question).count(), 0)

        q = question(save=True)
        self.refresh()
        eq_(elasticutils.S(Question).count(), 1)

        a = answer(question=q)
        self.refresh()
        eq_(elasticutils.S(Question).count(), 1)

        a.save()
        self.refresh()

        # Creating a new answer for a question doesn't create a new
        # document in the index.  Therefore, the count remains 1.
        #
        # TODO: This is ambiguous: it's not clear whether we correctly
        # updated the document in the index or whether the post_save
        # hook didn't kick off.  Need a better test.
        eq_(elasticutils.S(Question).count(), 1)
Exemple #59
0
    def test_user_api_last_activity(self, switch_is_active):
        """Verify the last activity field."""
        switch_is_active.return_value = True

        now = datetime.now()
        one_day = now - timedelta(days=1)
        two_days = now - timedelta(days=2)

        answer(creator=self.user1, created=now, save=True)
        answer(creator=self.user2, created=one_day, save=True)
        answer(creator=self.user3, created=two_days, save=True)

        url = reverse('karma.api.users')
        response = self.client.get(url)
        eq_(200, response.status_code)
        r = json.loads(response.content)
        days_since_last_activity = [u[2] for u in r['results']]
        eq_([1, 2, 0], days_since_last_activity)
Exemple #60
0
    def test_answer_vote_logged_in(self):
        """This exhausts the rate limit, then logs in, and exhausts it
        again."""
        q = question(save=True)
        answers = [answer(question=q, save=True) for _ in range(12)]
        u = user(password='******', save=True)

        # The rate limit is 10 per day. So make 10 requests. (0 through 9)
        for i in range(10):
            self._check_answer_vote(q, answers[i], False)
        # The ratelimit has been hit, so the next request will fail.
        self._check_answer_vote(q, answers[11], True)

        # Login.
        self.client.login(username=u.username, password='******')
        for i in range(10):
            self._check_answer_vote(q, answers[i], False)

        # Now the user has hit the rate limit too, so this should fail.
        self._check_answer_vote(q, answers[10], True)

        # Logging out out won't help
        self.client.logout()
        self._check_answer_vote(q, answers[11], True)