Пример #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)
Пример #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)
Пример #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)
Пример #4
0
    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])
Пример #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
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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())
Пример #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)
Пример #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
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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])
Пример #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)
Пример #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)
Пример #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())
Пример #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())
Пример #25
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)
Пример #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)
Пример #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)
Пример #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
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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
Пример #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())
Пример #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)
Пример #36
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)
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #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())
Пример #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)
Пример #46
0
    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)
Пример #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)
Пример #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())
Пример #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())
Пример #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)
Пример #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)
Пример #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)
Пример #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)
Пример #54
0
    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)
Пример #55
0
    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])
Пример #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?")
Пример #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)
Пример #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
Пример #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)
Пример #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'], '*')