Exemple #1
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)
Exemple #2
0
 def test_take_twice_forced(self):
     u1 = UserFactory()
     u2 = UserFactory()
     q = QuestionFactory()
     q.take(u1)
     q.take(u2, force=True)
     eq_(q.taken_by, u2)
Exemple #3
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)
    def test_created(self):
        """Basic functionality of created filter."""
        created_ds = datetime(2010, 6, 19, 12, 00)

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

        # on 6/21/2010
        q2 = QuestionFactory(title=u"q2 audio", created=(created_ds + timedelta(days=2)), tags=[u"desktop"])
        ans = AnswerFactory(question=q2)
        AnswerVoteFactory(answer=ans, helpful=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.advanced"), 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.advanced"), qs)
        results = json.loads(response.content)["results"]
        eq_([q2.get_absolute_url()], [r["url"] for r in results])
Exemple #5
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
Exemple #6
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)
Exemple #7
0
 def test_is_taken(self):
     q = QuestionFactory()
     u = UserFactory()
     q.take(u)
     url = reverse('question-detail', args=[q.id])
     res = self.client.get(url)
     eq_(res.status_code, 200)
     eq_(res.data['taken_by']['username'], u.username)
Exemple #8
0
    def test_weird_list_troubleshooting_info(self):
        """Test the corner case in which 'modifiedPReferences' is in a
        list in troubleshooting data. This is weird, but caused a bug."""
        q = QuestionFactory()
        q.add_metadata(troubleshooting='["modifiedPreferences"]')

        # This case should not raise an error.
        response = get(self.client, 'questions.details', args=[q.id])
        eq_(200, response.status_code)
Exemple #9
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)
Exemple #10
0
    def test_question_no_answers_deleted(self):
        search = QuestionMappingType.search()

        q = QuestionFactory(title=u'Does this work?')
        self.refresh()
        eq_(search.query(question_title__match='work').count(), 1)

        q.delete()
        self.refresh()
        eq_(search.query(question_title__match='work').count(), 0)
Exemple #11
0
    def test_delete_question_removes_flag(self):
        """Deleting a question also removes the flags on that question."""
        q = QuestionFactory(title='Test Question', content='Lorem Ipsum Dolor')

        u = UserFactory()
        FlaggedObject.objects.create(
            status=0, content_object=q, reason='language', creator_id=u.id)
        eq_(1, FlaggedObject.objects.count())

        q.delete()
        eq_(0, FlaggedObject.objects.count())
Exemple #12
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)
Exemple #13
0
 def test_editable(self):
     q = QuestionFactory()
     assert q.editable  # unlocked/unarchived
     q.is_archived = True
     assert not q.editable  # unlocked/archived
     q.is_locked = True
     assert not q.editable  # locked/archived
     q.is_archived = False
     assert not q.editable  # locked/unarchived
     q.is_locked = False
     assert q.editable  # unlocked/unarchived
Exemple #14
0
    def test_filter_is_taken_false(self):
        q1 = QuestionFactory()
        q2 = QuestionFactory()
        q2.take(q1.creator)

        url = reverse('question-list') + '?is_taken=0'
        res = self.client.get(url)

        eq_(res.status_code, 200)
        eq_(res.data['count'], 1)
        eq_(res.data['results'][0]['id'], q1.id)
Exemple #15
0
    def test_filter_is_taken_expired(self):
        q = QuestionFactory()
        # "take" the question, but with an expired timer.
        q.taken_by = UserFactory()
        q.taken_until = datetime.now() - timedelta(seconds=60)

        url = reverse('question-list') + '?is_taken=1'
        res = self.client.get(url)

        eq_(res.status_code, 200)
        eq_(res.data['count'], 0)
Exemple #16
0
    def test_filter_taken_by_username(self):
        q1 = QuestionFactory()
        q2 = QuestionFactory()
        q2.take(q1.creator)

        url = reverse('question-list') + '?taken_by=' + q1.creator.username
        res = self.client.get(url)

        eq_(res.status_code, 200)
        eq_(res.data['count'], 1)
        eq_(res.data['results'][0]['id'], q2.id)
Exemple #17
0
    def test_empty_troubleshooting_info(self):
        """Test a troubleshooting value that is valid JSON, but junk.
        This should trigger the parser to return None, which should not
        cause a 500.
        """
        q = QuestionFactory()
        q.add_metadata(troubleshooting='{"foo": "bar"}')

        # This case should not raise an error.
        response = get(self.client, 'questions.details', args=[q.id])
        eq_(200, response.status_code)
Exemple #18
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)
Exemple #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)
Exemple #20
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])
Exemple #21
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)
Exemple #22
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)
Exemple #23
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())
Exemple #24
0
    def test_needs_info(self):
        """Verify the needs_info queryset."""
        q = QuestionFactory()

        # There should be no needs_info questions yet.
        eq_(0, Question.objects.needs_info().count())

        # Tag a question and there should be one needs_info question.
        q.set_needs_info()
        eq_(1, Question.objects.needs_info().count())

        # Remove tag and there shouldn't be any anymore.
        q.unset_needs_info()
        eq_(0, Question.objects.needs_info().count())
    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)
Exemple #26
0
class FlagTestCase(TestCaseBase):
    """Test the flag view."""
    def setUp(self):
        super(FlagTestCase, self).setUp()
        self.user = UserFactory()
        self.question = QuestionFactory(creator=self.user)

        self.client.login(username=self.user.username, password='******')

    def tearDown(self):
        super(FlagTestCase, self).tearDown()
        self.client.logout()

    def test_flag(self):
        """Flag a question."""
        d = {'content_type': ContentType.objects.get_for_model(Question).id,
             'object_id': self.question.id,
             'reason': 'spam',
             'next': self.question.get_absolute_url()}
        post(self.client, 'flagit.flag', d)
        eq_(1, FlaggedObject.objects.count())

        flag = FlaggedObject.objects.all()[0]
        eq_(self.user.username, flag.creator.username)
        eq_('spam', flag.reason)
        eq_(self.question, flag.content_object)
Exemple #27
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)
Exemple #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
Exemple #29
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)
Exemple #30
0
    def test_questions(self):
        """Test questions API call."""
        # A question with a solution:
        a = AnswerFactory()
        a.question.solution = a
        a.question.save()
        # A question with an answer:
        AnswerFactory()
        # A question without answers:
        QuestionFactory()
        # A locked question that shouldn't be counted for anything
        QuestionFactory(is_locked=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)
Exemple #31
0
 def test_is_taken_clears(self):
     u = UserFactory()
     taken_until = datetime.now() - timedelta(seconds=30)
     q = QuestionFactory(taken_by=u, taken_until=taken_until)
     # Testin q.is_taken should clear out ``taken_by`` and ``taken_until``,
     # since taken_until is in the past.
     eq_(q.is_taken, False)
     eq_(q.taken_by, None)
     eq_(q.taken_until, None)
Exemple #32
0
    def test_filter_involved(self):
        q1 = QuestionFactory()
        a1 = AnswerFactory(question=q1)
        q2 = QuestionFactory(creator=a1.creator)

        querystring = "?involved={0}".format(q1.creator.username)
        res = self.client.get(reverse("question-list") + querystring)
        eq_(res.status_code, 200)
        eq_(len(res.data["results"]), 1)
        eq_(res.data["results"][0]["id"], q1.id)

        querystring = "?involved={0}".format(q2.creator.username)
        res = self.client.get(reverse("question-list") + querystring)
        eq_(res.status_code, 200)
        eq_(len(res.data["results"]), 2)
        # The API has a default sort, so ordering will be consistent.
        eq_(res.data["results"][0]["id"], q2.id)
        eq_(res.data["results"][1]["id"], q1.id)
Exemple #33
0
 def test_case_insensitive_search(self):
     """Ensure the default searcher is case insensitive."""
     q = QuestionFactory(title='lolrus', content='I am the lolrus.')
     AnswerVoteFactory(answer__question=q)
     self.refresh()
     # This is an AND operation
     result = QuestionMappingType.search().query(
         question_title__match='LOLRUS', question_content__match='LOLRUS')
     assert result.count() > 0
Exemple #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())
Exemple #35
0
    def test_question_one_answer_deleted(self):
        search = QuestionMappingType.search()

        q = QuestionFactory(title='are model makers the new pink?')
        a = AnswerFactory(content='yes.', question=q)
        self.refresh()

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

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

        # Delete the question and it should be removed from the index.
        q.delete()
        self.refresh()
        eq_(search.query(question_title__match='pink').count(), 0)
    def test_num_votes_none(self):
        """Tests num_voted filtering where num_votes is ''"""
        q = QuestionFactory()
        QuestionVoteFactory(question=q)

        self.refresh()

        qs = {'q': '', 'w': 2, 'a': 1, 'num_voted': 2, 'num_votes': ''}
        response = self.client.get(reverse('search.advanced'), qs)
        eq_(200, response.status_code)
Exemple #37
0
 def test_take_conflict(self):
     u1 = UserFactory()
     u2 = UserFactory()
     taken_until = datetime.now() + timedelta(seconds=30)
     q = QuestionFactory(taken_until=taken_until, taken_by=u1)
     self.client.force_authenticate(user=u2)
     res = self.client.post(reverse('question-take', args=[q.id]))
     eq_(res.status_code, 409)
     q = Question.objects.get(id=q.id)
     eq_(q.taken_by, u1)
Exemple #38
0
 def test_helpful_double_vote(self):
     q = QuestionFactory()
     u = UserFactory()
     QuestionVoteFactory(question=q, creator=u)
     self.client.force_authenticate(user=u)
     res = self.client.post(reverse('question-helpful', args=[q.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_(Question.objects.get(id=q.id).num_votes, 1)
Exemple #39
0
    def test_num_votes_none(self):
        """Tests num_voted filtering where num_votes is ''"""
        q = QuestionFactory()
        QuestionVoteFactory(question=q)

        self.refresh()

        qs = {"q": "", "w": 2, "a": 1, "num_voted": 2, "num_votes": ""}
        response = self.client.get(reverse("search.advanced"), qs)
        eq_(200, response.status_code)
Exemple #40
0
    def test_solve(self):
        q = QuestionFactory()
        a = AnswerFactory(question=q)

        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)
Exemple #41
0
 def test_solution_is_readonly(self):
     q = QuestionFactory()
     a = AnswerFactory(question=q)
     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)
Exemple #42
0
    def test_question_is_unindexed_on_creator_delete(self):
        search = QuestionMappingType.search()

        q = QuestionFactory(title='Does this work?')
        self.refresh()
        eq_(search.query(question_title__match='work').count(), 1)

        q.creator.delete()
        self.refresh()
        eq_(search.query(question_title__match='work').count(), 0)
Exemple #43
0
    def test_question_vote_limit(self):
        """Test that an anonymous user's votes are ignored after 10
        question votes."""
        questions = [QuestionFactory() 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_question_vote(questions[i], False)

        # Now make another, it should fail.
        self._check_question_vote(questions[10], True)
Exemple #44
0
    def test_not_by_asker(self):
        """Verify that only answers by users other than the original asker are returned"""
        q = QuestionFactory()

        # Add an answer by the original asker
        AnswerFactory(question=q, creator=q.creator)
        eq_(0, Answer.objects.not_by_asker().count())

        # Add an answer by someone else
        AnswerFactory(question=q)
        eq_(1, Answer.objects.not_by_asker().count())
Exemple #45
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)
    def test_annotation_has_correct_counts(self):
        question = QuestionFactory()
        [f(question=question) for f in [QuestionVoteFactory] * 4]

        document = QuestionDocument.prepare(question)
        self.assertEqual(document.question_num_votes, 4)

        annotated_question = QuestionDocument.get_queryset().get(id=question.id)

        document = QuestionDocument.prepare(annotated_question)
        self.assertEqual(document.question_num_votes, 4)
Exemple #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)
Exemple #48
0
    def test_escalated(self):
        """Verify the escalated queryset."""
        t = TagFactory(name=config.ESCALATE_TAG_NAME,
                       slug=config.ESCALATE_TAG_NAME)
        q = QuestionFactory()

        # There should be no escalated questions yet.
        eq_(0, Question.objects.escalated().count())

        # Tag a question and there should be one escalated question.
        q.tags.add(t)
        eq_(1, Question.objects.escalated().count())
Exemple #49
0
    def test_flag_content_as_spam(self):
        # Create some questions and answers by the user.
        u = UserFactory()
        QuestionFactory(creator=u)
        QuestionFactory(creator=u)
        AnswerFactory(creator=u)
        AnswerFactory(creator=u)
        AnswerFactory(creator=u)

        # Verify they are not marked as spam yet.
        eq_(2, Question.objects.filter(is_spam=False, creator=u).count())
        eq_(0, Question.objects.filter(is_spam=True, creator=u).count())
        eq_(3, Answer.objects.filter(is_spam=False, creator=u).count())
        eq_(0, Answer.objects.filter(is_spam=True, creator=u).count())

        # Flag content as spam and verify it is updated.
        mark_content_as_spam(u, UserFactory())
        eq_(0, Question.objects.filter(is_spam=False, creator=u).count())
        eq_(2, Question.objects.filter(is_spam=True, creator=u).count())
        eq_(0, Answer.objects.filter(is_spam=False, creator=u).count())
        eq_(3, Answer.objects.filter(is_spam=True, creator=u).count())
Exemple #50
0
    def test_empty_pages(self):
        """Tests requesting a page that has no results"""
        ques = QuestionFactory(title="audio")
        ques.tags.add("desktop")
        ans = AnswerFactory(question=ques, content="volume")
        AnswerVoteFactory(answer=ans, helpful=True)

        self.refresh()

        qs = {"q": "audio", "page": 81}
        response = self.client.get(reverse("search"), qs)
        eq_(200, response.status_code)
Exemple #51
0
    def test_no_action_for_self(self):
        """Test that a notification is not sent for actions the user took."""
        follower = UserFactory()
        q = QuestionFactory(creator=follower)
        # The above might make follows, which this test isn't about. Clear them out.
        Follow.objects.all().delete()
        follow(follower, q, actor_only=False)

        # Make a new action for the above. This should not trigger notifications.
        action.send(q.creator, verb='edited', action_object=q)
        act = Action.objects.order_by('-id')[0]
        eq_(Notification.objects.filter(action=act).count(), 0)
Exemple #52
0
    def test_answer_vote_limit(self):
        """Test that an anonymous user's votes are ignored after 10
        answer votes."""
        q = QuestionFactory()
        answers = AnswerFactory.create_batch(11, question=q)

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

        # Now make another, it should fail.
        self._check_answer_vote(q, answers[10], True)
Exemple #53
0
    def test_questions_inactive_user(self):
        """Verify questions from inactive users aren't counted."""
        # Two questions for an inactive user.
        # They shouldn't show up in the count.
        u = UserFactory(is_active=False)
        QuestionFactory(creator=u)
        QuestionFactory(creator=u)

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

        # Activate the user, now the questions should count.
        u.is_active = True
        u.save()
        cache.clear()  # We need to clear the cache for new results.

        url = reverse('api.kpi.questions')
        response = self.client.get(url + '?format=json')
        eq_(200, response.status_code)
        r = json.loads(response.content)
        eq_(r['objects'][0]['questions'], 2)
    def test_empty_pages(self):
        """Tests requesting a page that has no results"""
        ques = QuestionFactory(title=u'audio')
        ques.tags.add(u'desktop')
        ans = AnswerFactory(question=ques, content=u'volume')
        AnswerVoteFactory(answer=ans, helpful=True)

        self.refresh()

        qs = {'q': 'audio', 'page': 81}
        response = self.client.get(reverse('search'), qs)
        eq_(200, response.status_code)
    def test_created(self):
        """Basic functionality of created filter."""
        created_ds = datetime(2010, 6, 19, 12, 00)

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

        # on 6/21/2010
        q2 = QuestionFactory(
            title=u'q2 audio',
            created=(created_ds + timedelta(days=2)),
            tags=[u'desktop'])
        ans = AnswerFactory(question=q2)
        AnswerVoteFactory(answer=ans, helpful=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.advanced'), 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.advanced'), qs)
        results = json.loads(response.content)['results']
        eq_([q2.get_absolute_url()], [r['url'] for r in results])
Exemple #56
0
    def test_search_suggestion_questions_locale(self):
        """Verifies the right languages show up in search suggestions."""
        QuestionLocaleFactory(locale="de")

        p = ProductFactory(slug=u"firefox")

        for l in QuestionLocale.objects.all():
            p.questions_locales.add(l)

        TopicFactory(title="Fix problems", slug="fix-problems", product=p)

        QuestionFactory(title="question cupcakes?", product=p, locale="en-US")
        QuestionFactory(title="question donuts?", product=p, locale="en-US")
        QuestionFactory(title="question pies?", product=p, locale="pt-BR")
        QuestionFactory(title="question pastries?", product=p, locale="de")

        self.refresh()

        def sub_test(locale, *titles):
            url = urlparams(
                reverse(
                    "questions.aaq_step4",
                    args=["desktop", "fix-problems"],
                    locale=locale,
                ),
                search="question",
            )
            response = self.client.get(url, follow=True)
            doc = pq(response.content)
            eq_msg(
                len(doc(".result.question")),
                len(titles),
                "Wrong number of results for {0}".format(locale),
            )
            for substr in titles:
                assert substr in doc(".result.question h3 a").text()

        sub_test("en-US", "cupcakes?", "donuts?")
        sub_test("pt-BR", "cupcakes?", "donuts?", "pies?")
        sub_test("de", "cupcakes?", "donuts?", "pastries?")
Exemple #57
0
 def test_take_twice_forced(self):
     u1 = UserFactory()
     u2 = UserFactory()
     q = QuestionFactory()
     q.take(u1)
     q.take(u2, force=True)
     eq_(q.taken_by, u2)
Exemple #58
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
Exemple #59
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)
Exemple #60
0
 def test_is_cors(self, requests):
     u = UserFactory()
     q = QuestionFactory()
     self.client.force_authenticate(user=u)
     url = reverse('realtimeregistration-list')
     data = {
         'content_type': 'question',
         'object_id': q.id,
         'endpoint': 'http://example.com',
     }
     res = self.client.post(url, data, HTTP_ORIGIN='http://example.com')
     eq_(res.status_code, 201)
     eq_(res['Access-Control-Allow-Origin'], '*')