Ejemplo n.º 1
0
    def test_cron_updates_counts(self):
        q = QuestionFactory()
        self.refresh()

        eq_(q.num_votes_past_week, 0)
        # NB: Need to call .values_dict() here and later otherwise we
        # get a Question object which has data from the database and
        # not the index.
        document = (QuestionMappingType.search()
                    .filter(id=q.id))[0]

        eq_(document['question_num_votes_past_week'], 0)

        QuestionVoteFactory(question=q, anonymous_id='abc123')
        q.num_votes_past_week = 0
        q.save()

        update_weekly_votes()
        self.refresh()

        q = Question.objects.get(pk=q.pk)
        eq_(1, q.num_votes_past_week)

        document = (QuestionMappingType.search()
                    .filter(id=q.id))[0]

        eq_(document['question_num_votes_past_week'], 1)
Ejemplo n.º 2
0
    def test_cron_updates_counts(self):
        q = QuestionFactory()
        self.refresh()

        eq_(q.num_votes_past_week, 0)
        # NB: Need to call .values_dict() here and later otherwise we
        # get a Question object which has data from the database and
        # not the index.
        document = (QuestionMappingType.search().filter(id=q.id))[0]

        eq_(document['question_num_votes_past_week'], 0)

        QuestionVoteFactory(question=q, anonymous_id='abc123')
        q.num_votes_past_week = 0
        q.save()

        update_weekly_votes()
        self.refresh()

        q = Question.objects.get(pk=q.pk)
        eq_(1, q.num_votes_past_week)

        document = (QuestionMappingType.search().filter(id=q.id))[0]

        eq_(document['question_num_votes_past_week'], 1)
Ejemplo n.º 3
0
    def test_responded(self):
        """Verify the responded queryset."""
        # Create a question, there shouldn't be any responded yet.
        q = QuestionFactory()
        eq_(0, Question.objects.responded().count())

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

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

        # Add another answer, there should be one responded.
        a = AnswerFactory(question=q)
        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())
Ejemplo n.º 4
0
    def test_data_in_index(self):
        """Verify the data we are indexing."""
        p = ProductFactory()
        q = QuestionFactory(locale='pt-BR', product=p)
        a = AnswerFactory(question=q)

        self.refresh()

        eq_(AnswerMetricsMappingType.search().count(), 1)
        data = AnswerMetricsMappingType.search()[0]
        eq_(data['locale'], q.locale)
        eq_(data['product'], [p.slug])
        eq_(data['creator_id'], a.creator_id)
        eq_(data['is_solution'], False)
        eq_(data['by_asker'], False)

        # Mark as solution and verify
        q.solution = a
        q.save()

        self.refresh()
        data = AnswerMetricsMappingType.search()[0]
        eq_(data['is_solution'], True)

        # Make the answer creator to be the question creator and verify.
        a.creator = q.creator
        a.save()

        self.refresh()
        data = AnswerMetricsMappingType.search()[0]
        eq_(data['by_asker'], True)
Ejemplo 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 = QuestionFactory()
        u = q.creator
        AnswerFactory.create_batch(10, creator=u, question=q)

        # 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('api.kpi.contributors')
        eq_(r['objects'][0]['support_forum'], 0)

        # Change the question creator, now we should have 1 contributor.
        q.creator = UserFactory()
        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('api.kpi.contributors')
        eq_(r['objects'][0]['support_forum'], 1)
Ejemplo n.º 6
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?
                """,
        }
        defaults.update(kwargs)
        q = QuestionFactory(**defaults)
        if solved:
            a = AnswerFactory(question=q)
            q.solution = a
        # Trigger a reindex for the question.
        q.save()
        return q
Ejemplo n.º 7
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 = QuestionFactory()
        u = q.creator
        AnswerFactory.create_batch(10, creator=u, question=q)

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

        r = self._get_api_result('api.kpi.contributors')
        eq_(r['objects'][0]['support_forum'], 0)

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

        Metric.objects.all().delete()
        call_command('update_contributor_metrics',
                     str(date.today() + timedelta(days=1)))

        r = self._get_api_result('api.kpi.contributors')
        eq_(r['objects'][0]['support_forum'], 1)
Ejemplo n.º 8
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?
                """,
        }
        defaults.update(kwargs)
        q = QuestionFactory(**defaults)
        if solved:
            a = AnswerFactory(question=q)
            q.solution = a
        # Trigger a reindex for the question.
        q.save()
        return q
Ejemplo n.º 9
0
    def test_data_in_index(self):
        """Verify the data we are indexing."""
        p = ProductFactory()
        q = QuestionFactory(locale='pt-BR', product=p)
        a = AnswerFactory(question=q)

        self.refresh()

        eq_(AnswerMetricsMappingType.search().count(), 1)
        data = AnswerMetricsMappingType.search()[0]
        eq_(data['locale'], q.locale)
        eq_(data['product'], [p.slug])
        eq_(data['creator_id'], a.creator_id)
        eq_(data['is_solution'], False)
        eq_(data['by_asker'], False)

        # Mark as solution and verify
        q.solution = a
        q.save()

        self.refresh()
        data = AnswerMetricsMappingType.search()[0]
        eq_(data['is_solution'], True)

        # Make the answer creator to be the question creator and verify.
        a.creator = q.creator
        a.save()

        self.refresh()
        data = AnswerMetricsMappingType.search()[0]
        eq_(data['by_asker'], True)
Ejemplo n.º 10
0
    def test_responded(self):
        """Verify the responded queryset."""
        # Create a question, there shouldn't be any responded yet.
        q = QuestionFactory()
        eq_(0, Question.objects.responded().count())

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

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

        # Add another answer, there should be one responded.
        a = AnswerFactory(question=q)
        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())
Ejemplo n.º 11
0
    def test_no_notification_on_update(self):
        """Saving an existing question does not watch it."""

        q = QuestionFactory()
        QuestionReplyEvent.stop_notifying(q.creator, q)
        assert not QuestionReplyEvent.is_notifying(q.creator, q)

        q.save()
        assert not QuestionReplyEvent.is_notifying(q.creator, q)
Ejemplo n.º 12
0
    def test_no_notification_on_update(self):
        """Saving an existing question does not watch it."""

        q = QuestionFactory()
        QuestionReplyEvent.stop_notifying(q.creator, q)
        assert not QuestionReplyEvent.is_notifying(q.creator, q)

        q.save()
        assert not QuestionReplyEvent.is_notifying(q.creator, q)
Ejemplo n.º 13
0
    def test_tasks(self, index_fun):
        """Tests to make sure tasks are added and run"""
        q = QuestionFactory()
        # Don't call self.refresh here since that calls generate_tasks().

        eq_(index_fun.call_count, 0)

        q.save()
        generate_tasks()

        eq_(index_fun.call_count, 1)
Ejemplo n.º 14
0
    def test_question_spam_is_unindexed(self):
        search = QuestionMappingType.search()

        q = QuestionFactory(title=u'I am spam')
        self.refresh()
        eq_(search.query(question_title__match='spam').count(), 1)

        q.is_spam = True
        q.save()
        self.refresh()
        eq_(search.query(question_title__match='spam').count(), 0)
Ejemplo n.º 15
0
    def test_tasks(self, index_fun):
        """Tests to make sure tasks are added and run"""
        q = QuestionFactory()
        # Don't call self.refresh here since that calls generate_tasks().

        eq_(index_fun.call_count, 0)

        q.save()
        generate_tasks()

        eq_(index_fun.call_count, 1)
Ejemplo n.º 16
0
    def test_question_spam_is_unindexed(self):
        search = QuestionMappingType.search()

        q = QuestionFactory(title='I am spam')
        self.refresh()
        eq_(search.query(question_title__match='spam').count(), 1)

        q.is_spam = True
        q.save()
        self.refresh()
        eq_(search.query(question_title__match='spam').count(), 0)
Ejemplo n.º 17
0
class TestVoteQuestions(TestCaseBase):
    def setUp(self):
        u = UserFactory()
        self.client.login(username=u.username, password="******")
        self.question = QuestionFactory()

    def test_cannot_vote_on_spam_question(self):
        self.question.is_spam = True
        self.question.save()

        res = self.client.post(reverse("questions.vote", args=[self.question.id]))
        eq_(res.status_code, 404)
Ejemplo n.º 18
0
    def test_filter_is_solved(self):
        q1 = QuestionFactory()
        a1 = AnswerFactory(question=q1)
        q1.solution = a1
        q1.save()
        q2 = QuestionFactory()

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

        qs = self.filter_instance.filter_is_solved(self.queryset, False)
        eq_(list(qs), [q2])
Ejemplo n.º 19
0
    def test_counts(self):
        u = UserFactory()
        p = u.profile
        q = QuestionFactory(creator=u)
        AnswerFactory(creator=u)
        q.solution = AnswerFactory(question=q, creator=u)
        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)
Ejemplo n.º 20
0
    def test_counts(self):
        u = UserFactory()
        p = u.profile
        q = QuestionFactory(creator=u)
        AnswerFactory(creator=u)
        q.solution = AnswerFactory(question=q, creator=u)
        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)
Ejemplo n.º 21
0
    def test_only_show_wiki_and_questions(self):
        """Tests that the simple 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 = ProductFactory(slug=u'desktop')
        ques = QuestionFactory(title=u'audio', product=p)
        ans = AnswerFactory(question=ques, content=u'volume')
        AnswerVoteFactory(answer=ans, helpful=True)

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

        thread1 = ThreadFactory(title=u'audio')
        PostFactory(thread=thread1)

        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 simple 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)
Ejemplo n.º 22
0
    def test_cron_updates_counts(self):
        q = QuestionFactory()
        eq_(0, q.num_votes_past_week)

        QuestionVoteFactory(question=q, anonymous_id='abc123')

        q.num_votes_past_week = 0
        q.save()

        update_weekly_votes()

        q = Question.objects.get(pk=q.pk)
        eq_(1, q.num_votes_past_week)
Ejemplo n.º 23
0
class TestVoteQuestions(TestCaseBase):
    def setUp(self):
        u = UserFactory()
        self.client.login(username=u.username, password='******')
        self.question = QuestionFactory()

    def test_cannot_vote_on_spam_question(self):
        self.question.is_spam = True
        self.question.save()

        res = self.client.post(
            reverse('questions.vote', args=[self.question.id]))
        eq_(res.status_code, 404)
Ejemplo n.º 24
0
    def test_cron_updates_counts(self):
        q = QuestionFactory()
        eq_(0, q.num_votes_past_week)

        QuestionVoteFactory(question=q, anonymous_id='abc123')

        q.num_votes_past_week = 0
        q.save()

        update_weekly_votes()

        q = Question.objects.get(pk=q.pk)
        eq_(1, q.num_votes_past_week)
Ejemplo n.º 25
0
    def test_is_taken(self):
        q = QuestionFactory()
        u = UserFactory()
        eq_(q.is_taken, False)

        q.taken_by = u
        q.taken_until = datetime.now() + timedelta(seconds=600)
        q.save()
        eq_(q.is_taken, True)

        q.taken_by = None
        q.taken_until = None
        q.save()
        eq_(q.is_taken, False)
Ejemplo n.º 26
0
    def test_is_taken(self):
        q = QuestionFactory()
        u = UserFactory()
        eq_(q.is_taken, False)

        q.taken_by = u
        q.taken_until = datetime.now() + timedelta(seconds=600)
        q.save()
        eq_(q.is_taken, True)

        q.taken_by = None
        q.taken_until = None
        q.save()
        eq_(q.is_taken, False)
Ejemplo n.º 27
0
    def test_only_show_wiki_and_questions(self):
        """Tests that the simple 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 = ProductFactory(slug=u'desktop')
        ques = QuestionFactory(title=u'audio', product=p)
        ans = AnswerFactory(question=ques, content=u'volume')
        AnswerVoteFactory(answer=ans, helpful=True)

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

        thread1 = ThreadFactory(title=u'audio')
        PostFactory(thread=thread1)

        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 simple 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)
Ejemplo n.º 28
0
    def test_bleaching(self):
        """Tests whether summaries are bleached"""
        ProductFactory(slug=u'firefox')
        q = QuestionFactory(
            title=u'cupcakes',
            content=u'<unbleached>Cupcakes are the best</unbleached')
        q.tags.add(u'desktop')
        q.save()
        self.refresh()

        url = urlparams(reverse('questions.aaq_step4', args=['desktop', 'd1']),
                        search='cupcakes')

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

        assert '<unbleached>' not in response.content
Ejemplo n.º 29
0
    def test_filter_solved_by(self):
        q1 = QuestionFactory()
        a1 = AnswerFactory(question=q1)
        q1.solution = a1
        q1.save()
        q2 = QuestionFactory()
        AnswerFactory(question=q2, creator=a1.creator)
        q3 = QuestionFactory()
        a3 = AnswerFactory(question=q3)
        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])
Ejemplo n.º 30
0
class TestQuestionDetails(TestCaseBase):
    def setUp(self):
        self.question = QuestionFactory()

    def test_mods_can_see_spam_details(self):
        self.question.is_spam = True
        self.question.save()

        res = get(self.client, 'questions.details', args=[self.question.id])
        eq_(404, res.status_code)

        u = UserFactory()
        add_permission(u, FlaggedObject, 'can_moderate')
        self.client.login(username=u.username, password='******')

        res = get(self.client, 'questions.details', args=[self.question.id])
        eq_(200, res.status_code)
Ejemplo n.º 31
0
class TestQuestionReply(TestCaseBase):
    def setUp(self):
        u = UserFactory()
        self.client.login(username=u.username, password="******")
        self.question = QuestionFactory()

    def test_reply_to_spam_question(self):
        self.question.is_spam = True
        self.question.save()

        res = self.client.post(
            reverse("questions.reply", args=[self.question.id]),
            {"content": "The best reply evar!"},
        )
        eq_(res.status_code, 404)

    def test_needs_info(self):
        eq_(self.question.needs_info, False)

        res = self.client.post(
            reverse("questions.reply", args=[self.question.id]),
            {
                "content": "More info please",
                "needsinfo": ""
            },
        )
        eq_(res.status_code, 302)

        q = Question.objects.get(id=self.question.id)
        eq_(q.needs_info, True)

    def test_clear_needs_info(self):
        self.question.set_needs_info()
        eq_(self.question.needs_info, True)

        res = self.client.post(
            reverse("questions.reply", args=[self.question.id]),
            {
                "content": "More info please",
                "clear_needsinfo": ""
            },
        )
        eq_(res.status_code, 302)

        q = Question.objects.get(id=self.question.id)
        eq_(q.needs_info, False)
Ejemplo n.º 32
0
class TestQuestionDetails(TestCaseBase):
    def setUp(self):
        self.question = QuestionFactory()

    def test_mods_can_see_spam_details(self):
        self.question.is_spam = True
        self.question.save()

        res = get(self.client, "questions.details", args=[self.question.id])
        eq_(404, res.status_code)

        u = UserFactory()
        add_permission(u, FlaggedObject, "can_moderate")
        self.client.login(username=u.username, password="******")

        res = get(self.client, "questions.details", args=[self.question.id])
        eq_(200, res.status_code)
Ejemplo n.º 33
0
    def test_bleaching(self):
        """Tests whether summaries are bleached"""
        ProductFactory(slug=u'firefox')
        q = QuestionFactory(
            title=u'cupcakes',
            content=u'<unbleached>Cupcakes are the best</unbleached')
        q.tags.add(u'desktop')
        q.save()
        self.refresh()

        url = urlparams(
            reverse('questions.aaq_step4', args=['desktop', 'd1']),
            search='cupcakes')

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

        assert '<unbleached>' not in response.content
Ejemplo n.º 34
0
    def test_done(self):
        """Verify the done queryset."""
        # Create a question, there shouldn't be any done yet.
        q = QuestionFactory()
        eq_(0, Question.objects.done().count())

        # Add an answer, there shouldn't be any done yet.
        a = AnswerFactory(question=q)
        eq_(0, Question.objects.done().count())

        # Make it the solution, there should be one done.
        q.solution = a
        q.save()
        eq_(1, Question.objects.done().count())

        # Create a locked questions, there should be two done.
        QuestionFactory(is_locked=True)
        eq_(2, Question.objects.done().count())
Ejemplo n.º 35
0
    def test_tagged_feed(self):
        """Test the tagged feed."""
        t = TagFactory(name='green', slug='green')
        q = QuestionFactory()
        q.tags.add('green')
        items = TaggedQuestionsFeed().items(t)
        eq_(1, len(items))
        eq_(q.id, items[0].id)

        cache.clear()

        q = QuestionFactory()
        q.tags.add('green')
        q.updated = datetime.now() + timedelta(days=1)
        q.save()
        items = TaggedQuestionsFeed().items(t)
        eq_(2, len(items))
        eq_(q.id, items[0].id)
Ejemplo n.º 36
0
    def test_tagged_feed(self):
        """Test the tagged feed."""
        t = TagFactory(name="green", slug="green")
        q = QuestionFactory()
        q.tags.add("green")
        items = TaggedQuestionsFeed().items(t)
        eq_(1, len(items))
        eq_(q.id, items[0].id)

        cache.clear()

        q = QuestionFactory()
        q.tags.add("green")
        q.updated = datetime.now() + timedelta(days=1)
        q.save()
        items = TaggedQuestionsFeed().items(t)
        eq_(2, len(items))
        eq_(q.id, items[0].id)
Ejemplo n.º 37
0
    def test_done(self):
        """Verify the done queryset."""
        # Create a question, there shouldn't be any done yet.
        q = QuestionFactory()
        eq_(0, Question.objects.done().count())

        # Add an answer, there shouldn't be any done yet.
        a = AnswerFactory(question=q)
        eq_(0, Question.objects.done().count())

        # Make it the solution, there should be one done.
        q.solution = a
        q.save()
        eq_(1, Question.objects.done().count())

        # Create a locked questions, there should be two done.
        QuestionFactory(is_locked=True)
        eq_(2, Question.objects.done().count())
Ejemplo n.º 38
0
class TestMarkingSolved(TestCaseBase):
    def setUp(self):
        u = UserFactory()
        self.client.login(username=u.username, password="******")
        self.question = QuestionFactory(creator=u)
        self.answer = AnswerFactory(question=self.question)

    def test_cannot_mark_spam_answer(self):
        self.answer.is_spam = True
        self.answer.save()

        res = self.client.get(reverse("questions.solve", args=[self.question.id, self.answer.id]))
        eq_(res.status_code, 404)

    def test_cannot_mark_answers_on_spam_question(self):
        self.question.is_spam = True
        self.question.save()

        res = self.client.get(reverse("questions.solve", args=[self.question.id, self.answer.id]))
        eq_(res.status_code, 404)
Ejemplo n.º 39
0
    def test_questions_by_product(self):
        """Test product filtering of questions API call."""
        firefox_os = ProductFactory(slug='firefox-os')
        firefox = ProductFactory(slug='firefox')

        # A Firefox OS question with a solution:
        q = QuestionFactory(product=firefox_os)
        a = AnswerFactory(question=q)
        q.solution = a
        q.save()

        # A Firefox OS question with an answer:
        q = QuestionFactory(product=firefox_os)
        AnswerFactory(question=q)

        # A Firefox OS question without answers:
        q = QuestionFactory(product=firefox_os)

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

        # 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]
Ejemplo n.º 40
0
    def test_questions_by_product(self):
        """Test product filtering of questions API call."""
        firefox_os = ProductFactory(slug='firefox-os')
        firefox = ProductFactory(slug='firefox')

        # A Firefox OS question with a solution:
        q = QuestionFactory(product=firefox_os)
        a = AnswerFactory(question=q)
        q.solution = a
        q.save()

        # A Firefox OS question with an answer:
        q = QuestionFactory(product=firefox_os)
        AnswerFactory(question=q)

        # A Firefox OS question without answers:
        q = QuestionFactory(product=firefox_os)

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

        # 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]
Ejemplo n.º 41
0
    def test_questions_by_product(self):
        """Test product filtering of questions API call."""
        firefox_os = ProductFactory(slug="firefox-os")
        firefox = ProductFactory(slug="firefox")

        # A Firefox OS question with a solution:
        q = QuestionFactory(product=firefox_os)
        a = AnswerFactory(question=q)
        q.solution = a
        q.save()

        # A Firefox OS question with an answer:
        q = QuestionFactory(product=firefox_os)
        AnswerFactory(question=q)

        # A Firefox OS question without answers:
        q = QuestionFactory(product=firefox_os)

        # A Firefox question without answers:
        q = QuestionFactory(product=firefox, locale="pt-BR")

        # 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]
Ejemplo n.º 42
0
class TestQuestionReply(TestCaseBase):
    def setUp(self):
        u = UserFactory()
        self.client.login(username=u.username, password='******')
        self.question = QuestionFactory()

    def test_reply_to_spam_question(self):
        self.question.is_spam = True
        self.question.save()

        res = self.client.post(
            reverse('questions.reply', args=[self.question.id]),
            {'content': 'The best reply evar!'})
        eq_(res.status_code, 404)

    def test_needs_info(self):
        eq_(self.question.needs_info, False)

        res = self.client.post(
            reverse('questions.reply', args=[self.question.id]), {
                'content': 'More info please',
                'needsinfo': ''
            })
        eq_(res.status_code, 302)

        q = Question.objects.get(id=self.question.id)
        eq_(q.needs_info, True)

    def test_clear_needs_info(self):
        self.question.set_needs_info()
        eq_(self.question.needs_info, True)

        res = self.client.post(
            reverse('questions.reply', args=[self.question.id]), {
                'content': 'More info please',
                'clear_needsinfo': ''
            })
        eq_(res.status_code, 302)

        q = Question.objects.get(id=self.question.id)
        eq_(q.needs_info, False)
Ejemplo n.º 43
0
    def test_search_suggestions_questions(self):
        """Verifies the view doesn't kick up an HTTP 500"""
        p = ProductFactory(slug=u"firefox")
        locale = QuestionLocale.objects.get(locale=settings.LANGUAGE_CODE)
        p.questions_locales.add(locale)
        TopicFactory(title="Fix problems", slug="fix-problems", product=p)
        q = QuestionFactory(product=p, title=u"CupcakesQuestion cupcakes")

        d = DocumentFactory(title=u"CupcakesKB cupcakes", category=10)
        d.products.add(p)

        RevisionFactory(document=d, is_approved=True)

        self.refresh()

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

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

        assert "CupcakesQuestion" in response.content
        assert "CupcakesKB" in response.content

        # Verify that archived articles and questions aren't shown...
        # Archive both and they shouldn't appear anymore.
        q.is_archived = True
        q.save()
        d.is_archived = True
        d.save()

        self.refresh()

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

        assert "CupcakesQuestion" not in response.content
        assert "CupcakesKB" not in response.content
Ejemplo n.º 44
0
    def test_update_question_vote_chunk(self):
        # Reset the num_votes_past_week counts, I suspect the data gets
        # loaded before I disconnect the signal and they get zeroed out.
        q1 = QuestionFactory()
        QuestionVoteFactory(question=q1)
        q1.num_votes_past_week = 1
        q1.save()

        q2 = QuestionFactory()

        # Actually test the task.
        qs = Question.objects.all().order_by('-num_votes_past_week')
        eq_(q1.pk, qs[0].pk)

        QuestionVoteFactory(question=q2)
        QuestionVoteFactory(question=q2)
        qs = Question.objects.all().order_by('-num_votes_past_week')
        eq_(q1.pk, qs[0].pk)

        update_question_vote_chunk([q.pk for q in qs])
        qs = Question.objects.all().order_by('-num_votes_past_week')
        eq_(q2.pk, qs[0].pk)
Ejemplo n.º 45
0
    def test_search_suggestions_questions(self):
        """Verifies the view doesn't kick up an HTTP 500"""
        p = ProductFactory(slug=u'firefox')
        l = QuestionLocale.objects.get(locale=settings.LANGUAGE_CODE)
        p.questions_locales.add(l)
        TopicFactory(title='Fix problems', slug='fix-problems', product=p)
        q = QuestionFactory(product=p, title=u'CupcakesQuestion cupcakes')

        d = DocumentFactory(title=u'CupcakesKB cupcakes', category=10)
        d.products.add(p)

        RevisionFactory(document=d, is_approved=True)

        self.refresh()

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

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

        assert 'CupcakesQuestion' in response.content
        assert 'CupcakesKB' in response.content

        # Verify that archived articles and questions aren't shown...
        # Archive both and they shouldn't appear anymore.
        q.is_archived = True
        q.save()
        d.is_archived = True
        d.save()

        self.refresh()

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

        assert 'CupcakesQuestion' not in response.content
        assert 'CupcakesKB' not in response.content
Ejemplo n.º 46
0
    def test_update_question_vote_chunk(self):
        # Reset the num_votes_past_week counts, I suspect the data gets
        # loaded before I disconnect the signal and they get zeroed out.
        q1 = QuestionFactory()
        QuestionVoteFactory(question=q1)
        q1.num_votes_past_week = 1
        q1.save()

        q2 = QuestionFactory()

        # Actually test the task.
        qs = Question.objects.all().order_by('-num_votes_past_week')
        eq_(q1.pk, qs[0].pk)

        QuestionVoteFactory(question=q2)
        QuestionVoteFactory(question=q2)
        qs = Question.objects.all().order_by('-num_votes_past_week')
        eq_(q1.pk, qs[0].pk)

        update_question_vote_chunk([q.pk for q in qs])
        qs = Question.objects.all().order_by('-num_votes_past_week')
        eq_(q2.pk, qs[0].pk)
Ejemplo n.º 47
0
class TestQuestionReply(TestCaseBase):
    def setUp(self):
        u = UserFactory()
        self.client.login(username=u.username, password='******')
        self.question = QuestionFactory()

    def test_reply_to_spam_question(self):
        self.question.is_spam = True
        self.question.save()

        res = self.client.post(
            reverse('questions.reply', args=[self.question.id]),
            {'content': 'The best reply evar!'})
        eq_(res.status_code, 404)

    def test_needs_info(self):
        eq_(self.question.needs_info, False)

        res = self.client.post(
            reverse('questions.reply', args=[self.question.id]),
            {'content': 'More info please', 'needsinfo': ''})
        eq_(res.status_code, 302)

        q = Question.objects.get(id=self.question.id)
        eq_(q.needs_info, True)

    def test_clear_needs_info(self):
        self.question.set_needs_info()
        eq_(self.question.needs_info, True)

        res = self.client.post(
            reverse('questions.reply', args=[self.question.id]),
            {'content': 'More info please', 'clear_needsinfo': ''})
        eq_(res.status_code, 302)

        q = Question.objects.get(id=self.question.id)
        eq_(q.needs_info, False)
Ejemplo n.º 48
0
    def test_questions_by_locale(self):
        """Test locale filtering of questions API call."""
        # An en-US question with a solution:
        q = QuestionFactory(locale='en-US')
        a = AnswerFactory(question=q)
        q.solution = a
        q.save()
        # An en-US question with an answer:
        q = QuestionFactory(locale='en-US')
        AnswerFactory(question=q)
        # An en-US question without answers:
        QuestionFactory(locale='en-US')

        # A pt-BR question without answers:
        QuestionFactory(locale='pt-BR')

        # Verify no locale 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 locale=en-US
        r = self._get_api_result('api.kpi.questions', locale='en-US')
        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 locale=pt-BR
        r = self._get_api_result('api.kpi.questions', locale='pt-BR')
        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]
Ejemplo n.º 49
0
    def test_questions_by_locale(self):
        """Test locale filtering of questions API call."""
        # An en-US question with a solution:
        q = QuestionFactory(locale='en-US')
        a = AnswerFactory(question=q)
        q.solution = a
        q.save()
        # An en-US question with an answer:
        q = QuestionFactory(locale='en-US')
        AnswerFactory(question=q)
        # An en-US question without answers:
        QuestionFactory(locale='en-US')

        # A pt-BR question without answers:
        QuestionFactory(locale='pt-BR')

        # Verify no locale 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 locale=en-US
        r = self._get_api_result('api.kpi.questions', locale='en-US')
        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 locale=pt-BR
        r = self._get_api_result('api.kpi.questions', locale='pt-BR')
        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]
Ejemplo n.º 50
0
class TestVoteAnswers(TestCaseBase):
    def setUp(self):
        u = UserFactory()
        self.client.login(username=u.username, password='******')
        self.question = QuestionFactory()
        self.answer = AnswerFactory(question=self.question)

    def test_cannot_vote_for_answers_on_spam_question(self):
        self.question.is_spam = True
        self.question.save()

        res = self.client.post(
            reverse('questions.answer_vote',
                    args=[self.question.id, self.answer.id]))
        eq_(res.status_code, 404)

    def test_cannot_vote_for_answers_marked_spam(self):
        self.answer.is_spam = True
        self.answer.save()

        res = self.client.post(
            reverse('questions.answer_vote',
                    args=[self.question.id, self.answer.id]))
        eq_(res.status_code, 404)
Ejemplo n.º 51
0
    def test_questions_by_locale(self):
        """Test locale filtering of questions API call."""
        # An en-US question with a solution:
        q = QuestionFactory(locale="en-US")
        a = AnswerFactory(question=q)
        q.solution = a
        q.save()
        # An en-US question with an answer:
        q = QuestionFactory(locale="en-US")
        AnswerFactory(question=q)
        # An en-US question without answers:
        QuestionFactory(locale="en-US")

        # A pt-BR question without answers:
        QuestionFactory(locale="pt-BR")

        # Verify no locale 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 locale=en-US
        r = self._get_api_result("api.kpi.questions", locale="en-US")
        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 locale=pt-BR
        r = self._get_api_result("api.kpi.questions", locale="pt-BR")
        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]
Ejemplo n.º 52
0
class TestMarkingSolved(TestCaseBase):
    def setUp(self):
        u = UserFactory()
        self.client.login(username=u.username, password='******')
        self.question = QuestionFactory(creator=u)
        self.answer = AnswerFactory(question=self.question)

    def test_cannot_mark_spam_answer(self):
        self.answer.is_spam = True
        self.answer.save()

        res = self.client.get(
            reverse('questions.solve',
                    args=[self.question.id, self.answer.id]))
        eq_(res.status_code, 404)

    def test_cannot_mark_answers_on_spam_question(self):
        self.question.is_spam = True
        self.question.save()

        res = self.client.get(
            reverse('questions.solve',
                    args=[self.question.id, self.answer.id]))
        eq_(res.status_code, 404)
Ejemplo n.º 53
0
    def test_num_solutions(self):
        u = UserFactory()
        q1 = QuestionFactory()
        q2 = QuestionFactory()
        a1 = AnswerFactory(creator=u, question=q1)
        a2 = AnswerFactory(creator=u, question=q2)
        eq_(num_solutions(u), 0)

        q1.solution = a1
        q1.save()
        eq_(num_solutions(u), 1)

        q2.solution = a2
        q2.save()
        eq_(num_solutions(u), 2)

        q1.solution = None
        q1.save()
        eq_(num_solutions(u), 1)

        a2.delete()
        eq_(num_solutions(u), 0)
Ejemplo n.º 54
0
    def test_num_solutions(self):
        u = UserFactory()
        q1 = QuestionFactory()
        q2 = QuestionFactory()
        a1 = AnswerFactory(creator=u, question=q1)
        a2 = AnswerFactory(creator=u, question=q2)
        eq_(num_solutions(u), 0)

        q1.solution = a1
        q1.save()
        eq_(num_solutions(u), 1)

        q2.solution = a2
        q2.save()
        eq_(num_solutions(u), 2)

        q1.solution = None
        q1.save()
        eq_(num_solutions(u), 1)

        a2.delete()
        eq_(num_solutions(u), 0)
Ejemplo n.º 55
0
 def test_answer_change_no_action(self):
     """When an answer is changed, no Action should be created."""
     q = QuestionFactory()
     Action.objects.all().delete()
     q.save()  # trigger another post_save hook
     eq_(Action.objects.count(), 0)
Ejemplo n.º 56
0
class TestQuestionSerializerSerialization(TestCase):

    def setUp(self):
        self.asker = UserFactory()
        self.helper1 = UserFactory()
        self.helper2 = UserFactory()
        self.question = QuestionFactory(creator=self.asker)

    def _names(self, *users):
        return sorted(
            {
                'username': u.username,
                'display_name': Profile.objects.get(user=u).name,
                'avatar': profile_avatar(u),
            }
            for u in users)

    def _answer(self, user):
        return AnswerFactory(question=self.question, creator=user)

    def test_no_votes(self):
        serializer = api.QuestionSerializer(instance=self.question)
        eq_(serializer.data['num_votes'], 0)

    def test_with_votes(self):
        QuestionVoteFactory(question=self.question)
        QuestionVoteFactory(question=self.question)
        QuestionVoteFactory()
        serializer = api.QuestionSerializer(instance=self.question)
        eq_(serializer.data['num_votes'], 2)

    def test_just_asker(self):
        serializer = api.QuestionSerializer(instance=self.question)
        eq_(serializer.data['involved'], self._names(self.asker))

    def test_one_answer(self):
        self._answer(self.helper1)

        serializer = api.QuestionSerializer(instance=self.question)
        eq_(sorted(serializer.data['involved']), self._names(self.asker, self.helper1))

    def test_asker_and_response(self):
        self._answer(self.helper1)
        self._answer(self.asker)

        serializer = api.QuestionSerializer(instance=self.question)
        eq_(sorted(serializer.data['involved']), self._names(self.asker, self.helper1))

    def test_asker_and_two_answers(self):
        self._answer(self.helper1)
        self._answer(self.asker)
        self._answer(self.helper2)

        serializer = api.QuestionSerializer(instance=self.question)
        eq_(sorted(serializer.data['involved']),
            self._names(self.asker, self.helper1, self.helper2))

    def test_solution_is_id(self):
        a = self._answer(self.helper1)
        self.question.solution = a
        self.question.save()

        serializer = api.QuestionSerializer(instance=self.question)
        eq_(serializer.data['solution'], a.id)

    def test_creator_is_object(self):
        serializer = api.QuestionSerializer(instance=self.question)
        eq_(serializer.data['creator'], {
            'username': self.question.creator.username,
            'display_name': Profile.objects.get(user=self.question.creator).display_name,
            'avatar': profile_avatar(self.question.creator),
        })
Ejemplo n.º 57
0
 def test_save_no_update(self):
     """Saving without the `update` option shouldn't update `updated`."""
     q = QuestionFactory()
     updated = q.updated
     q.save()
     eq_(updated, q.updated)
Ejemplo n.º 58
0
 def test_save_updated(self):
     """Saving with the `update` option should update `updated`."""
     q = QuestionFactory()
     updated = q.updated
     q.save(update=True)
     self.assertNotEqual(updated, q.updated)