Esempio n. 1
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])
Esempio n. 2
0
    def test_reindex_users_that_contributed_yesterday(self):
        yesterday = datetime.now() - timedelta(days=1)

        # Verify for answers.
        u = user(username='******', save=True)
        profile(user=u)
        answer(creator=u, created=yesterday, save=True)

        reindex_users_that_contributed_yesterday()
        self.refresh()

        data = UserMappingType.search().query(username__match='answerer')[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())

        # Verify for edits.
        u = user(username='******', save=True)
        profile(user=u)
        revision(creator=u, created=yesterday, save=True)

        reindex_users_that_contributed_yesterday()
        self.refresh()

        data = UserMappingType.search().query(username__match='editor')[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())

        # Verify for reviews.
        u = user(username='******', save=True)
        profile(user=u)
        revision(reviewer=u, reviewed=yesterday, save=True)

        reindex_users_that_contributed_yesterday()
        self.refresh()

        data = UserMappingType.search().query(username__match='reviewer')[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())
Esempio n. 3
0
    def test_responded(self):
        """Verify the responded queryset."""
        # Create a question, there shouldn't be any responded yet.
        q = question(save=True)
        eq_(0, Question.objects.responded().count())

        # Add an answer, there should be one responded.
        a = answer(question=q, save=True)
        eq_(1, Question.objects.responded().count())

        # Add an answer by the creator, there should be none responded.
        a = answer(creator=q.creator, question=q, save=True)
        eq_(0, Question.objects.responded().count())

        # Add another answer, there should be one responded.
        a = answer(question=q, save=True)
        eq_(1, Question.objects.responded().count())

        # Lock it, there should be none responded.
        q.is_locked = True
        q.save()
        eq_(0, Question.objects.responded().count())

        # Unlock it and mark solved, there should be none responded.
        q.is_locked = False
        q.solution = a
        q.save()
        eq_(0, Question.objects.responded().count())
Esempio n. 4
0
    def test_answer_badge(self):
        """Verify the Support Forum Badge is awarded properly."""
        # Create the user and badge.
        year = date.today().year
        u = profile().user
        badge_template = QUESTIONS_BADGES['answer-badge']
        b = badge(
            slug=badge_template['slug'].format(year=year),
            title=badge_template['title'].format(year=year),
            description=badge_template['description'].format(year=year),
            save=True)

        # Create 29 answers.
        q = question(save=True)
        answers = []
        for i in range(28):
            answers.append(answer(question=q, creator=u))
        Answer.objects.bulk_create(answers)

        # Create the 29th answer separately so the signals are triggered.
        answer(creator=u, save=True)

        # User should NOT have the badge yet.
        assert not b.is_awarded_to(u)

        # Create 1 more answer.
        answer(creator=u, save=True)

        # User should have the badge now.
        assert b.is_awarded_to(u)
Esempio n. 5
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)
Esempio n. 6
0
    def test_creator_num_answers(self):
        a = answer(save=True)

        eq_(a.creator_num_answers, 1)

        answer(creator=a.creator, save=True)
        eq_(a.creator_num_answers, 2)
Esempio n. 7
0
    def test_last_answer_date(self):
        p = profile()
        u = p.user
        answer(creator=u, save=True)

        serializer = api.ProfileSerializer(instance=p)
        eq_(serializer.data['last_answer_date'], u.answers.last().created)
Esempio n. 8
0
    def test_it_works(self):
        u1 = profile().user
        u2 = profile().user

        a1 = answer(creator=u1, save=True)  # noqa
        a2 = answer(creator=u1, save=True)
        a3 = answer(creator=u2, save=True)

        a1.question.solution = a1
        a1.question.save()
        answervote(answer=a3, helpful=True, save=True)

        self.refresh()

        req = self.factory.get('/')
        data = self.api.get_data(req)

        eq_(data['count'], 2)

        eq_(data['results'][0]['user']['username'], u1.username)
        eq_(data['results'][0]['rank'], 1)
        eq_(data['results'][0]['answer_count'], 2)
        eq_(data['results'][0]['solution_count'], 1)
        eq_(data['results'][0]['helpful_vote_count'], 0)
        eq_(data['results'][0]['last_contribution_date'], a2.created.replace(microsecond=0))

        eq_(data['results'][1]['user']['username'], u2.username)
        eq_(data['results'][1]['rank'], 2)
        eq_(data['results'][1]['answer_count'], 1)
        eq_(data['results'][1]['solution_count'], 0)
        eq_(data['results'][1]['helpful_vote_count'], 1)
        eq_(data['results'][1]['last_contribution_date'], a3.created.replace(microsecond=0))
Esempio n. 9
0
    def test_top_contributors_questions(self):
        firefox = product(slug='firefox', save=True)
        fxos = product(slug='firefox-os', save=True)
        a1 = answer(save=True)
        a1.question.products.add(firefox)
        a1.question.products.add(fxos)
        a2 = answer(creator=a1.creator, save=True)
        a3 = answer(save=True)
        a3.question.products.add(fxos)
        a4 = answer(created=datetime.now()-timedelta(days=91),
                    save=True)

        self.refresh()

        # By default, we should only get 2 top contributors back.
        top = top_contributors_questions()
        eq_(2, len(top))
        assert a4.creator_id not in [u['term'] for u in top]
        eq_(a1.creator_id, top[0]['term'])

        # Verify, filtering of Firefox questions only.
        top = top_contributors_questions(product=firefox.slug)
        eq_(1, len(top))
        eq_(a1.creator_id, top[0]['term'])
        top = top_contributors_questions(product=fxos.slug)
        eq_(2, len(top))
Esempio n. 10
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])
Esempio n. 11
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))
Esempio n. 12
0
 def test_delete_updates_pages(self):
     a1 = answer(save=True)
     a2 = answer(question=a1.question, save=True)
     answer(question=a1.question, save=True)
     a1.page = 7
     a1.save()
     a2.delete()
     a3 = Answer.objects.filter(question=a1.question)[0]
     assert a3.page == 1, "Page was %s" % a3.page
Esempio n. 13
0
    def test_last_contribution_date(self):
        """Verify the last_contribution_date field works properly."""
        u = user(username='******', save=True)
        p = profile(user=u)

        self.refresh()

        data = UserMappingType.search().query(
            username__match='satdav').values_dict()[0]
        assert not data['last_contribution_date']

        # Add a AoA reply. It should be the last contribution.
        d = datetime(2014, 1, 1)
        reply(user=u, created=d, save=True)

        p.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(
            username__match='satdav').values_dict()[0]
        eq_(data['last_contribution_date'], d)

        # Add a Support Forum answer. It should be the last contribution.
        d = datetime(2014, 1, 2)
        answer(creator=u, created=d, save=True)

        p.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(
            username__match='satdav').values_dict()[0]
        eq_(data['last_contribution_date'], d)

        # Add a Revision edit. It should be the last contribution.
        d = datetime(2014, 1, 3)
        revision(creator=u, created=d, save=True)

        p.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(
            username__match='satdav').values_dict()[0]
        eq_(data['last_contribution_date'], d)

        # Add a Revision review. It should be the last contribution.
        d = datetime(2014, 1, 4)
        revision(reviewer=u, reviewed=d, save=True)

        p.save()  # we need to resave the profile to force a reindex
        self.refresh()

        data = UserMappingType.search().query(
            username__match='satdav').values_dict()[0]
        eq_(data['last_contribution_date'], d)
Esempio n. 14
0
    def test_counts(self):
        p = profile()
        u = p.user
        q = question(creator=u, save=True)
        answer(creator=u, save=True)
        q.solution = answer(question=q, creator=u, save=True)
        q.save()

        serializer = api.ProfileSerializer(instance=p)
        eq_(serializer.data['question_count'], 1)
        eq_(serializer.data['answer_count'], 2)
        eq_(serializer.data['solution_count'], 1)
Esempio n. 15
0
    def test_top_questions(self):
        a1 = answer(save=True)
        a2 = answer(save=True)

        self.refresh()

        response = self.client.get(urlparams(
            reverse('community.top_contributors', args=['questions'])))
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_(2, len(doc('li.results-user')))
        assert a1.creator.username in response.content
        assert a2.creator.username in response.content
Esempio n. 16
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)
Esempio n. 17
0
    def test_top_contributors_questions(self):
        a1 = answer(save=True)
        a2 = answer(creator=a1.creator, save=True)
        a3 = answer(save=True)
        a4 = answer(created=datetime.now()-timedelta(days=91),
                    save=True)

        self.refresh()

        # By default, we should only get 2 top contributors back.
        top = top_contributors_questions()
        eq_(2, len(top))
        assert a4.creator_id not in [u['term'] for u in top]
        eq_(a1.creator_id, top[0]['term'])
Esempio n. 18
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())
Esempio n. 19
0
    def test_ordering(self):
        a1 = answer(save=True)
        a2 = answer(save=True)

        res = self.client.get(reverse('answer-list'))
        eq_(res.data['results'][0]['id'], a2.id)
        eq_(res.data['results'][1]['id'], a1.id)

        res = self.client.get(reverse('answer-list') + '?ordering=id')
        eq_(res.data['results'][0]['id'], a1.id)
        eq_(res.data['results'][1]['id'], a2.id)

        res = self.client.get(reverse('answer-list') + '?ordering=-id')
        eq_(res.data['results'][0]['id'], a2.id)
        eq_(res.data['results'][1]['id'], a1.id)
Esempio n. 20
0
    def test_helpfulness(self):
        p = profile()
        u = p.user
        a1 = answer(creator=u, save=True)
        a2 = answer(creator=u, save=True)

        answervote(answer=a1, helpful=True, save=True)
        answervote(answer=a2, helpful=True, save=True)
        answervote(answer=a2, helpful=True, save=True)
        # Some red herrings.
        answervote(creator=u, save=True)
        answervote(answer=a1, helpful=False, save=True)

        serializer = api.ProfileSerializer(instance=p)
        eq_(serializer.data['helpfulness'], 3)
Esempio n. 21
0
    def test_deactivate_and_flag_spam(self):
        self.client.login(username=self.u.username, password='******')
        add_permission(self.u, Profile, 'deactivate_users')

        # Verify content is flagged as spam when requested.
        p = profile()
        answer(creator=p.user, save=True)
        question(creator=p.user, save=True)
        url = reverse('users.deactivate-spam', locale='en-US')
        res = self.client.post(url, {'user_id': p.user.id})

        eq_(302, res.status_code)
        eq_(1, Question.objects.filter(creator=p.user, is_spam=True).count())
        eq_(0, Question.objects.filter(creator=p.user, is_spam=False).count())
        eq_(1, Answer.objects.filter(creator=p.user, is_spam=True).count())
        eq_(0, Answer.objects.filter(creator=p.user, is_spam=False).count())
Esempio n. 22
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'])
Esempio n. 23
0
    def test_solution_notification_deleted(self, get_current):
        """Calling QuestionSolvedEvent.fire() should not query the
        questions_question table.

        This test attempts to simulate the replication lag presumed to cause
        bug 585029.

        """
        get_current.return_value.domain = 'testserver'

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

        a_user = a.creator
        QuestionSolvedEvent.notify(a_user, q)
        event = QuestionSolvedEvent(a)

        # Delete the question, pretend it hasn't been replicated yet
        Question.objects.get(pk=q.pk).delete()

        event.fire(exclude=q.creator)

        # There should be a reply notification and a solved notification.
        eq_(2, len(mail.outbox))
        eq_('Solution found to Firefox Help question', mail.outbox[1].subject)
Esempio n. 24
0
 def test_is_solved_property(self):
     a = answer(save=True)
     q = a.question
     assert not q.is_solved
     q.solution = a
     q.save()
     assert q.is_solved
Esempio n. 25
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]))
Esempio n. 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)
Esempio n. 27
0
 def test_solution_is_readonly(self):
     q = question(save=True)
     a = answer(question=q, save=True)
     self.data['solution'] = a.id
     serializer = api.QuestionSerializer(context=self.context, data=self.data, instance=q)
     serializer.save()
     eq_(q.solution, None)
Esempio n. 28
0
 def test_bleaching(self):
     """Tests whether answer content is bleached."""
     a = answer(content=u'<unbleached>Cupcakes are the best</unbleached>', save=True)
     url = reverse('answer-detail', args=[a.id])
     res = self.client.get(url)
     eq_(res.status_code, 200)
     assert '<unbleached>' not in res.data['content']
Esempio n. 29
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
Esempio n. 30
0
    def _make_question(self, solved=True, **kwargs):
        defaults = {
            'title': 'Login to website comments disabled ' + str(time.time()),
            'content': """
                readersupportednews.org, sends me emails with a list of
                articles to read.

                The links to the articles work as normal, except that I
                cannot login from the linked article - as required - to
                send my comments.

                I see a javascript activity statement at the bottom left
                corner of my screen while the left button is depressed
                on the Login button. it is gone when I release the left
                button, but no results.

                I have the latest (7) version of java enabled, on an XP
                box.

                Why this inability to login to this website commentary?
                """,
            'save': True,
        }
        defaults.update(kwargs)
        q = question(**defaults)
        if solved:
            a = answer(question=q, save=True)
            q.solution = a
        # Trigger a reindex for the question.
        q.save()
        return q
Esempio n. 31
0
    def test_delete_last_answer_of_question(self):
        """Deleting the last_answer of a Question should update the question.
        """
        yesterday = datetime.now() - timedelta(days=1)
        q = answer(created=yesterday, save=True).question
        last_answer = q.last_answer

        # add a new answer and verify last_answer updated
        a = answer(question=q, content='Test Answer', save=True)
        q = Question.objects.get(pk=q.id)

        eq_(q.last_answer.id, a.id)

        # delete the answer and last_answer should go back to previous value
        a.delete()
        q = Question.objects.get(pk=q.id)
        eq_(q.last_answer.id, last_answer.id)
        eq_(Answer.objects.filter(pk=a.id).count(), 0)
Esempio n. 32
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)
        # A locked question that shouldn't be counted for anything
        question(is_locked=True, save=True)

        r = self._get_api_result('api.kpi.questions')
        eq_(r['objects'][0]['solved'], 1)
        eq_(r['objects'][0]['responded_24'], 2)
        eq_(r['objects'][0]['responded_72'], 2)
        eq_(r['objects'][0]['questions'], 3)
Esempio n. 33
0
    def test_fire_on_solution(self, fire):
        """The event also fires when an answer is marked as a solution."""
        a = answer(save=True)
        q = a.question

        self.client.login(username=q.creator, password='******')
        post(self.client, 'questions.solve', args=[q.id, a.id])

        assert fire.called
Esempio n. 34
0
 def test_update_page_task(self):
     a = answer(save=True)
     a.page = 4
     a.save()
     a = Answer.objects.get(pk=a.id)
     assert a.page == 4
     update_answer_pages(a.question)
     a = Answer.objects.get(pk=a.id)
     assert a.page == 1
Esempio n. 35
0
 def test_follow(self):
     a = answer(save=True)
     u = profile().user
     self.client.force_authenticate(user=u)
     eq_(Follow.objects.filter(user=u).count(), 0)  # pre-condition
     res = self.client.post(reverse('answer-follow', args=[a.id]))
     eq_(res.status_code, 204)
     f = Follow.objects.get(user=u)
     eq_(f.follow_object, a)
     eq_(f.actor_only, False)
Esempio n. 36
0
 def test_solution_is_readonly(self):
     q = question(save=True)
     a = answer(question=q, save=True)
     self.data['solution'] = a.id
     serializer = api.QuestionSerializer(context=self.context,
                                         data=self.data,
                                         instance=q)
     serializer.is_valid(raise_exception=True)
     serializer.save()
     eq_(q.solution, None)
Esempio n. 37
0
    def test_filter_solved_by(self):
        q1 = question(save=True)
        a1 = answer(question=q1, save=True)
        q1.solution = a1
        q1.save()
        q2 = question(save=True)
        answer(question=q2, creator=a1.creator, save=True)
        q3 = question(save=True)
        a3 = answer(question=q3, save=True)
        q3.solution = a3
        q3.save()

        qs = self.filter_instance.filter_solved_by(self.queryset,
                                                   a1.creator.username)
        eq_(list(qs), [q1])

        qs = self.filter_instance.filter_solved_by(self.queryset,
                                                   a3.creator.username)
        eq_(list(qs), [q3])
Esempio n. 38
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='******')
Esempio n. 39
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)
Esempio n. 40
0
    def test_question_solved_makes_action(self):
        """When an answer is marked as the solution to a question, an Action should be created."""
        ans = answer(save=True)
        Action.objects.all().delete()
        ans.question.set_solution(ans, ans.question.creator)

        act = Action.objects.action_object(ans).get()
        eq_(act.actor, ans.question.creator)
        eq_(act.verb, 'marked as a solution')
        eq_(act.target, ans.question)
Esempio n. 41
0
 def test_helpful_double_vote(self):
     a = answer(save=True)
     u = profile().user
     answervote(answer=a, creator=u, save=True)
     self.client.force_authenticate(user=u)
     res = self.client.post(reverse('answer-helpful', args=[a.id]))
     eq_(res.status_code, 409)
     # It's 1, not 0, because one was created above. The failure cause is
     # if the number of votes is 2, one from above and one from the api call.
     eq_(Answer.objects.get(id=a.id).num_votes, 1)
Esempio n. 42
0
    def test_with_votes(self):
        a = answer(save=True)
        answervote(answer=a, helpful=True, save=True)
        answervote(answer=a, helpful=True, save=True)
        answervote(answer=a, helpful=False, save=True)
        answervote(save=True)

        serializer = api.AnswerSerializer(instance=a)
        eq_(serializer.data['num_helpful_votes'], 2)
        eq_(serializer.data['num_unhelpful_votes'], 1)
Esempio n. 43
0
    def test_solve(self):
        q = question(save=True)
        a = answer(question=q, save=True)

        self.client.force_authenticate(user=q.creator)
        res = self.client.post(reverse('question-solve', args=[q.id]),
                               data={'answer': a.id})
        eq_(res.status_code, 204)
        q = Question.objects.get(id=q.id)
        eq_(q.solution, a)
Esempio n. 44
0
    def test_page_size(self):
        u1 = profile().user
        u2 = profile().user

        q1 = question(save=True)
        answer(question=q1, creator=u1, save=True)
        q2 = question(save=True)
        answer(question=q2, creator=u2, save=True)

        self.refresh()

        req = self.factory.get('/', {'page_size': 2})
        data = self.api.get_data(req)
        eq_(data['count'], 2)
        eq_(len(data['results']), 2)

        req = self.factory.get('/', {'page_size': 1})
        data = self.api.get_data(req)
        eq_(data['count'], 2)
        eq_(len(data['results']), 1)
Esempio n. 45
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 = QuestionMappingType.search().query(
         question_title__match='LOLRUS', question_content__match='LOLRUS')
     assert result.count() > 0
Esempio n. 46
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)
Esempio n. 47
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
Esempio n. 48
0
    def test_answer_spam_is_unindexed(self):
        search = QuestionMappingType.search()

        a = answer(content=u'I am spam', save=True)
        self.refresh()
        eq_(search.query(question_answer_content__match='spam').count(), 1)

        a.is_spam = True
        a.save()
        self.refresh()
        eq_(search.query(question_answer_content__match='spam').count(), 0)
Esempio n. 49
0
    def test_questions_by_product(self):
        """Test product filtering of questions API call."""
        firefox_os = product(slug='firefox-os', save=True)
        firefox = product(slug='firefox', save=True)

        # A Firefox OS question with a solution:
        q = question(product=firefox_os, save=True)
        a = answer(question=q, save=True)
        q.solution = a
        q.save()

        # A Firefox OS question with an answer:
        q = question(product=firefox_os, save=True)
        answer(question=q, save=True)

        # A Firefox OS question without answers:
        q = question(product=firefox_os, save=True)

        # A Firefox question without answers:
        q = question(product=firefox, locale='pt-BR', save=True)

        # Verify no product filtering:
        r = self._get_api_result('api.kpi.questions')
        eq_(r['objects'][0]['solved'], 1)
        eq_(r['objects'][0]['responded_24'], 2)
        eq_(r['objects'][0]['responded_72'], 2)
        eq_(r['objects'][0]['questions'], 4)

        # Verify product=firefox-os
        r = self._get_api_result('api.kpi.questions', product='firefox-os')
        eq_(r['objects'][0]['solved'], 1)
        eq_(r['objects'][0]['responded_24'], 2)
        eq_(r['objects'][0]['responded_72'], 2)
        eq_(r['objects'][0]['questions'], 3)

        # Verify product=firefox
        r = self._get_api_result('api.kpi.questions', product='firefox')
        eq_(r['objects'][0]['questions'], 1)
        assert 'solved' not in r['objects'][0]
        assert 'responded_24' not in r['objects'][0]
        assert 'responded_72' not in r['objects'][0]
Esempio n. 50
0
    def test_add_and_delete(self):
        """Adding an answer should add it to the index.

        Deleting should delete it.
        """
        a = answer(save=True)
        self.refresh()
        eq_(AnswerMetricsMappingType.search().count(), 1)

        a.delete()
        self.refresh()
        eq_(AnswerMetricsMappingType.search().count(), 0)
Esempio n. 51
0
    def test_filter_is_solved(self):
        q1 = question(save=True)
        a1 = answer(question=q1, save=True)
        q1.solution = a1
        q1.save()
        q2 = question(save=True)

        res = self.filter_instance.filter_is_solved(self.queryset, True)
        eq_(list(res), [q1])

        res = self.filter_instance.filter_is_solved(self.queryset, False)
        eq_(list(res), [q2])
Esempio n. 52
0
    def test_filter_involved(self):
        q1 = question(save=True)
        a1 = answer(question=q1, save=True)
        q2 = question(creator=a1.creator, save=True)

        res = self.filter_instance.filter_involved(self.queryset, q1.creator.username)
        eq_(list(res), [q1])

        res = self.filter_instance.filter_involved(self.queryset, q2.creator.username)
        # The filter does not have a strong order.
        res = sorted(res, key=lambda q: q.id)
        eq_(res, [q1, q2])
Esempio n. 53
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)
Esempio n. 54
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)

        # Archive the article and question. They should no longer appear
        # in default search results.
        ques.is_archived = True
        ques.save()
        doc.is_archived = True
        doc.save()

        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'], 0)
Esempio n. 55
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)
Esempio n. 56
0
    def test_top_contributors(self):
        """Verify the top contributors appear."""
        d = document(locale='en-US', save=True)
        revision(document=d, save=True)
        d = document(locale='es', save=True)
        revision(document=d, save=True)
        revision(document=d, save=True)
        answer(save=True)
        answer(save=True)
        answer(save=True)
        reply(user=user(save=True), save=True)
        reply(user=user(save=True), save=True)
        reply(user=user(save=True), save=True)
        reply(user=user(save=True), save=True)

        for u in User.objects.all():
            profile(user=u)

        self.refresh()

        response = self.client.get(urlparams(reverse('community.home')))
        eq_(response.status_code, 200)
        doc = pq(response.content)
        eq_(1, len(doc('ul.kb > li')))
        eq_(2, len(doc('ul.l10n > li')))
        eq_(3, len(doc('ul.questions > li')))
        eq_(4, len(doc('ul.army-of-awesome > li')))
Esempio n. 57
0
    def test_delete_solution_of_question(self):
        """Deleting the solution of a Question should update the question.
        """
        # set a solution to the question
        q = answer(save=True).question
        solution = q.last_answer
        q.solution = solution
        q.save()

        # delete the solution and question.solution should go back to None
        solution.delete()
        q = Question.objects.get(pk=q.id)
        eq_(q.solution, None)
Esempio n. 58
0
    def test_reindex_users_that_contributed_yesterday(self):
        yesterday = datetime.now() - timedelta(days=1)

        # Verify for answers.
        u = user(username='******', save=True)
        p = profile(user=u)
        answer(creator=u, created=yesterday, save=True)

        reindex_users_that_contributed_yesterday()
        self.refresh()

        data = UserMappingType.search().query(
            username__match='answerer').values_dict()[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())

        # Verify for edits.
        u = user(username='******', save=True)
        p = profile(user=u)
        revision(creator=u, created=yesterday, save=True)

        reindex_users_that_contributed_yesterday()
        self.refresh()

        data = UserMappingType.search().query(
            username__match='editor').values_dict()[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())

        # Verify for reviews.
        u = user(username='******', save=True)
        p = profile(user=u)
        revision(reviewer=u, reviewed=yesterday, save=True)

        reindex_users_that_contributed_yesterday()
        self.refresh()

        data = UserMappingType.search().query(
            username__match='reviewer').values_dict()[0]
        eq_(data['last_contribution_date'].date(), yesterday.date())
Esempio n. 59
0
    def test_question_is_reindexed_on_username_change(self):
        search = QuestionMappingType.search()

        u = user(username='******', save=True)

        question(creator=u, title=u'Hello', save=True)
        answer(creator=u, content=u'I love you', save=True)
        self.refresh()
        eq_(
            search.query(question_title__match='hello')[0]['question_creator'],
            u'dexter')
        query = search.query(question_answer_content__match='love')
        eq_(query[0]['question_answer_creator'], [u'dexter'])

        # Change the username and verify the index.
        u.username = '******'
        u.save()
        self.refresh()
        eq_(
            search.query(question_title__match='hello')[0]['question_creator'],
            u'walter')
        query = search.query(question_answer_content__match='love')
        eq_(query[0]['question_answer_creator'], [u'walter'])
Esempio n. 60
0
    def test_delete_answer_removes_flag(self):
        """Deleting an answer also removes the flags on that answer."""
        q = question(title='Test Question', content='Lorem Ipsum Dolor',
                     save=True)

        a = answer(question=q, content='Test Answer', save=True)

        u = user(save=True)
        FlaggedObject.objects.create(
            status=0, content_object=a, reason='language', creator_id=u.id)
        eq_(1, FlaggedObject.objects.count())

        a.delete()
        eq_(0, FlaggedObject.objects.count())