Example #1
0
    def test_top_contributors(self):
        # There should be no top contributors since there are no answers.
        response = self.client.get(reverse('questions.list', args=['all']))
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_(0, len(doc('#top-contributors ol li')))

        # Add an answer, we now have a top conributor.
        a = AnswerFactory()
        self.refresh()
        response = self.client.get(reverse('questions.list', args=['all']))
        eq_(200, response.status_code)
        doc = pq(response.content)
        lis = doc('#top-contributors ol li')
        eq_(1, len(lis))
        eq_(Profile.objects.get(user=a.creator).display_name, lis[0].text)

        # Make answer 91 days old. There should no be top contributors.
        a.created = datetime.now() - timedelta(days=91)
        a.save()
        self.refresh()
        response = self.client.get(reverse('questions.list', args=['all']))
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_(0, len(doc('#top-contributors ol li')))
Example #2
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)
Example #3
0
    def test_asker_replies_arent_a_contribution(self):
        """Verify that replies posted by the question creator aren't counted.

        If a user has 10 replies to their own question, they aren't counted as
        a contributor.
        """
        # A user with 10 answers to own question.
        q = 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)
Example #4
0
 def test_update_page_task(self):
     a = AnswerFactory()
     a.page = 4
     a.save()
     a = Answer.objects.get(pk=a.id)
     assert a.page == 4
     update_answer_pages(a.question)
     a = Answer.objects.get(pk=a.id)
     assert a.page == 1
Example #5
0
    def test_answer_spam_is_unindexed(self):
        search = QuestionMappingType.search()

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

        a.is_spam = True
        a.save()
        self.refresh()
        eq_(search.query(question_answer_content__match='spam').count(), 0)
Example #6
0
    def test_add_and_delete(self):
        """Adding an answer should add it to the index.

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

        a.delete()
        self.refresh()
        eq_(AnswerMetricsMappingType.search().count(), 0)
Example #7
0
    def test_delete_answer_removes_flag(self):
        """Deleting an answer also removes the flags on that answer."""
        q = QuestionFactory(title='Test Question', content='Lorem Ipsum Dolor')

        a = AnswerFactory(question=q, content='Test Answer')

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

        a.delete()
        eq_(0, FlaggedObject.objects.count())
Example #8
0
    def test_delete_solution_of_question(self):
        """Deleting the solution of a Question should update the question.
        """
        # set a solution to the question
        q = AnswerFactory().question
        solution = q.last_answer
        q.solution = solution
        q.save()

        # delete the solution and question.solution should go back to None
        solution.delete()
        q = Question.objects.get(pk=q.id)
        eq_(q.solution, None)
Example #9
0
    def test_ordering(self):
        a1 = AnswerFactory()
        a2 = AnswerFactory()

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

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

        res = self.client.get(reverse('answer-list') + '?ordering=-id')
        eq_(res.data['results'][0]['id'], a2.id)
        eq_(res.data['results'][1]['id'], a1.id)
Example #10
0
    def test_helpfulness(self):
        u = UserFactory()
        p = u.profile
        a1 = AnswerFactory(creator=u)
        a2 = AnswerFactory(creator=u)

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

        serializer = api.ProfileSerializer(instance=p)
        eq_(serializer.data["helpfulness"], 3)
Example #11
0
    def test_ordering(self):
        a1 = AnswerFactory()
        a2 = AnswerFactory()

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

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

        res = self.client.get(reverse("answer-list") + "?ordering=-id")
        eq_(res.data["results"][0]["id"], a2.id)
        eq_(res.data["results"][1]["id"], a1.id)
Example #12
0
    def test_delete_answer_removes_flag(self):
        """Deleting an answer also removes the flags on that answer."""
        q = QuestionFactory(title='Test Question', content='Lorem Ipsum Dolor')

        a = AnswerFactory(question=q, content='Test Answer')

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

        a.delete()
        eq_(0, FlaggedObject.objects.count())
    def test_filter_by_doctype(self):
        desktop = ProductFactory(slug=u'desktop')
        ques = QuestionFactory(title=u'audio', product=desktop)
        ans = AnswerFactory(question=ques, content=u'volume')
        AnswerVoteFactory(answer=ans, helpful=True)

        doc = DocumentFactory(title=u'audio', locale=u'en-US', category=10, products=[desktop])
        RevisionFactory(document=doc, is_approved=True)

        doc = DocumentFactory(title=u'audio too', locale=u'en-US', category=10, products=[desktop])
        RevisionFactory(document=doc, is_approved=True)

        self.refresh()

        # There should be 2 results for kb (w=1) and 1 for questions (w=2).
        response = self.client.get(reverse('search'), {
            'q': 'audio', 'format': 'json', 'w': '1'})
        eq_(200, response.status_code)
        content = json.loads(response.content)
        eq_(content['total'], 2)

        response = self.client.get(reverse('search'), {
            'q': 'audio', 'format': 'json', 'w': '2'})
        eq_(200, response.status_code)
        content = json.loads(response.content)
        eq_(content['total'], 1)
Example #14
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
Example #15
0
    def test_last_contribution_date(self):
        """Verify the last_contribution_date field works properly."""
        u = UserFactory(username="******")
        self.refresh()

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

        # Add a Support Forum answer. It should be the last contribution.
        d = datetime(2014, 1, 2)
        AnswerFactory(creator=u, created=d)
        u.profile.save()  # we need to resave the profile to force a reindex
        self.refresh()

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

        # Add a Revision edit. It should be the last contribution.
        d = datetime(2014, 1, 3)
        RevisionFactory(created=d, creator=u)
        u.profile.save()  # we need to resave the profile to force a reindex
        self.refresh()

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

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

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

        data = UserMappingType.search().query(username__match="satdav")[0]
        eq_(data["last_contribution_date"], d)
Example #16
0
    def setUp(self):
        today = datetime.today()
        self.start_of_first_week = today - timedelta(days=today.weekday(), weeks=12)

        revisions = ApprovedRevisionFactory.create_batch(3, created=self.start_of_first_week)

        reviewer = UserFactory()
        ApprovedRevisionFactory(reviewer=reviewer, created=self.start_of_first_week)

        ApprovedRevisionFactory(creator=revisions[1].creator, reviewer=reviewer,
                                created=self.start_of_first_week + timedelta(weeks=1, days=2))
        ApprovedRevisionFactory(created=self.start_of_first_week + timedelta(weeks=1, days=1))

        for r in revisions:
            lr = ApprovedRevisionFactory(created=self.start_of_first_week + timedelta(days=1),
                                         document__locale='es')
            ApprovedRevisionFactory(created=self.start_of_first_week + timedelta(weeks=2, days=1),
                                    creator=lr.creator, document__locale='es')

        answers = AnswerFactory.create_batch(
            7, created=self.start_of_first_week + timedelta(weeks=1, days=2))

        AnswerFactory(question=answers[2].question, creator=answers[2].question.creator,
                      created=self.start_of_first_week + timedelta(weeks=1, days=2))

        for a in answers[:2]:
            AnswerFactory(creator=a.creator,
                          created=self.start_of_first_week + timedelta(weeks=2, days=5))

        replies = ReplyFactory.create_batch(2, created=self.start_of_first_week)

        for r in replies:
            ReplyFactory(user=r.user, created=self.start_of_first_week + timedelta(weeks=2))

        call_command('cohort_analysis')
Example #17
0
    def test_solution_notification_deleted(self, get_current):
        """Calling QuestionSolvedEvent.fire() should not query the
        questions_question table.

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

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

        a = AnswerFactory()
        q = a.question
        q.solution = a
        q.save()

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

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

        event.fire(exclude=q.creator)

        # There should be a reply notification and a solved notification.
        eq_(2, len(mail.outbox))
        eq_('Solution found to Firefox Help question', mail.outbox[1].subject)
Example #18
0
    def test_suggestions(self, get_current):
        """Suggestions API is well-formatted."""
        get_current.return_value.domain = 'testserver'

        doc = DocumentFactory(title='doc1 audio', locale='en-US', is_archived=False)
        ApprovedRevisionFactory(document=doc, summary='audio', content='audio')

        ques = QuestionFactory(title='q1 audio', tags=['desktop'])
        # ques.tags.add(u'desktop')
        ans = AnswerFactory(question=ques)
        AnswerVoteFactory(answer=ans, helpful=True)

        self.refresh()

        response = self.client.get(reverse('search.suggestions',
                                           locale='en-US'),
                                   {'q': 'audio'})
        eq_(200, response.status_code)
        eq_('application/x-suggestions+json', response['content-type'])
        results = json.loads(response.content)

        eq_('audio', results[0])
        eq_(2, len(results[1]))
        eq_(0, len(results[2]))
        eq_(2, len(results[3]))
Example #19
0
    def test_filter_by_product(self):
        desktop = ProductFactory(slug="desktop")
        mobile = ProductFactory(slug="mobile")
        ques = QuestionFactory(title="audio", product=desktop)
        ans = AnswerFactory(question=ques, content="volume")
        AnswerVoteFactory(answer=ans, helpful=True)

        doc = DocumentFactory(title="audio", locale="en-US", category=10)
        doc.products.add(desktop)
        doc.products.add(mobile)
        RevisionFactory(document=doc, is_approved=True)

        self.refresh()

        # There should be 2 results for desktop and 1 for mobile.
        response = self.client.get(
            reverse("search"), {"q": "audio", "format": "json", "product": "desktop"}
        )
        eq_(200, response.status_code)
        content = json.loads(response.content)
        eq_(content["total"], 2)

        response = self.client.get(
            reverse("search"), {"q": "audio", "format": "json", "product": "mobile"}
        )
        eq_(200, response.status_code)
        content = json.loads(response.content)
        eq_(content["total"], 1)
Example #20
0
    def test_weekly_solutions(self):
        eight_days_ago = datetime.now() - timedelta(days=8)
        # First one is a solution, but it is too old.
        # second answer is not a solution.
        SolutionAnswerFactory(created=eight_days_ago)
        AnswerFactory()
        res = self.client.get(reverse('user-weekly-solutions'))
        eq_(res.status_code, 200)
        eq_(len(res.data), 0)

        # Check that the data about the contributors is showing currectly
        user_info_list = [
        ]  # Info list with username and their number of solutions
        top_answer_number = 15
        for i in range(12):
            user = UserFactory()
            SolutionAnswerFactory.create_batch(top_answer_number, creator=user)
            user_info_list.append((user.username, top_answer_number))
            top_answer_number -= 1

        res = self.client.get(reverse('user-weekly-solutions'))
        eq_(res.status_code, 200)
        # Check only 10 users information is present there
        eq_(len(res.data), 10)
        # Create a list of the data with only the ``username`` and ``weekly_solutions``
        data_list = [(data['username'], data['weekly_solutions'])
                     for data in res.data]

        # Check only top 10 contributor information is in the API
        top_ten = user_info_list[:10]
        eq_(sorted(top_ten), sorted(data_list))
Example #21
0
    def test_new_answer_updates_question(self):
        """Test saving a new answer updates the corresponding question.
        Specifically, last_post and num_replies should update."""
        q = QuestionFactory(title="Test Question", content="Lorem Ipsum Dolor")
        updated = q.updated

        eq_(0, q.num_answers)
        eq_(None, q.last_answer)

        a = AnswerFactory(question=q, content="Test Answer")
        a.save()

        q = Question.objects.get(pk=q.id)
        eq_(1, q.num_answers)
        eq_(a, q.last_answer)
        self.assertNotEqual(updated, q.updated)
Example #22
0
    def test_asked_by(self):
        """Check several author values, including test for (anon)"""
        author_vals = (
            ("DoesNotExist", 0),
            ("jsocol", 2),
            ("pcraciunoiu", 2),
        )

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

        self.refresh()

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

        for author, total in author_vals:
            qs.update({"asked_by": author})
            response = self.client.get(reverse("search.advanced"), qs)
            eq_(total, json.loads(response.content)["total"])
Example #23
0
 def test_is_solved_property(self):
     a = AnswerFactory()
     q = a.question
     assert not q.is_solved
     q.solution = a
     q.save()
     assert q.is_solved
Example #24
0
    def test_suggestions(self, get_current):
        """Suggestions API is well-formatted."""
        get_current.return_value.domain = "testserver"

        doc = DocumentFactory(title="doc1 audio",
                              locale="en-US",
                              is_archived=False)
        ApprovedRevisionFactory(document=doc, summary="audio", content="audio")

        ques = QuestionFactory(title="q1 audio", tags=["desktop"])
        # ques.tags.add(u'desktop')
        ans = AnswerFactory(question=ques)
        AnswerVoteFactory(answer=ans, helpful=True)

        self.refresh()

        response = self.client.get(
            reverse("search.suggestions", locale="en-US"), {"q": "audio"})
        eq_(200, response.status_code)
        eq_("application/x-suggestions+json", response["content-type"])
        results = json.loads(response.content)

        eq_("audio", results[0])
        eq_(2, len(results[1]))
        eq_(0, len(results[2]))
        eq_(2, len(results[3]))
Example #25
0
    def test_updates_subview(self, requests):
        requests.put.return_value.status_code = 200

        u = UserFactory()
        q = QuestionFactory(content='asdf')
        ct = ContentType.objects.get_for_model(q)
        rt = RealtimeRegistration.objects.create(
            creator=u,
            content_type=ct,
            object_id=q.id,
            endpoint='http://example.com/')
        # Some of the above may have created actions, which we don't care about.
        Action.objects.all().delete()
        # This should create an action that will trigger the above.
        a = AnswerFactory(question=q, content='asdf')

        self.client.force_authenticate(user=u)
        url = reverse('realtimeregistration-updates', args=[rt.id])
        res = self.client.get(url)
        eq_(res.status_code, 200)

        eq_(len(res.data), 1)
        act = res.data[0]
        eq_(act['actor']['username'], a.creator.username)
        eq_(act['target']['content'], q.content_parsed)
        eq_(act['action_object']['content'], a.content_parsed)
Example #26
0
    def test_last_answer_date(self):
        p = ProfileFactory()
        u = p.user
        AnswerFactory(creator=u)

        serializer = api.ProfileSerializer(instance=p)
        eq_(serializer.data['last_answer_date'], u.answers.last().created)
Example #27
0
    def test_reindex_users_that_contributed_yesterday(self):
        yesterday = datetime.now() - timedelta(days=1)

        # Verify for answers.
        u = UserFactory(username="******")
        AnswerFactory(creator=u, created=yesterday)

        call_command("reindex_users_that_contributed_yesterday")
        self.refresh()

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

        # Verify for edits.
        u = UserFactory(username="******")
        RevisionFactory(creator=u, created=yesterday)

        call_command("reindex_users_that_contributed_yesterday")
        self.refresh()

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

        # Verify for reviews.
        u = UserFactory(username="******")
        RevisionFactory(reviewer=u, reviewed=yesterday)

        call_command("reindex_users_that_contributed_yesterday")
        self.refresh()

        data = UserMappingType.search().query(username__match="reviewer")[0]
        eq_(data["last_contribution_date"].date(), yesterday.date())
Example #28
0
    def test_new_answer_updates_question(self):
        """Test saving a new answer updates the corresponding question.
        Specifically, last_post and num_replies should update."""
        q = QuestionFactory(title='Test Question', content='Lorem Ipsum Dolor')
        updated = q.updated

        eq_(0, q.num_answers)
        eq_(None, q.last_answer)

        a = AnswerFactory(question=q, content='Test Answer')
        a.save()

        q = Question.objects.get(pk=q.id)
        eq_(1, q.num_answers)
        eq_(a, q.last_answer)
        self.assertNotEqual(updated, q.updated)
Example #29
0
 def test_bleaching(self):
     """Tests whether answer content is bleached."""
     a = AnswerFactory(content=u'<unbleached>Cupcakes are the best</unbleached>')
     url = reverse('answer-detail', args=[a.id])
     res = self.client.get(url)
     eq_(res.status_code, 200)
     assert '<unbleached>' not in res.data['content']
Example #30
0
    def test_asked_by(self):
        """Check several author values, including test for (anon)"""
        author_vals = (
            ('DoesNotExist', 0),
            ('jsocol', 2),
            ('pcraciunoiu', 2),
        )

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

        self.refresh()

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

        for author, total in author_vals:
            qs.update({'asked_by': author})
            response = self.client.get(reverse('search.advanced'), qs)
            eq_(total, json.loads(response.content)['total'])
    def test_filter_by_product(self):
        desktop = ProductFactory(slug=u'desktop')
        mobile = ProductFactory(slug=u'mobile')
        ques = QuestionFactory(title=u'audio', product=desktop)
        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(desktop)
        doc.products.add(mobile)
        RevisionFactory(document=doc, is_approved=True)

        self.refresh()

        # There should be 2 results for desktop and 1 for mobile.
        response = self.client.get(reverse('search'), {
            'q': 'audio',
            'format': 'json',
            'product': 'desktop'
        })
        eq_(200, response.status_code)
        content = json.loads(response.content)
        eq_(content['total'], 2)

        response = self.client.get(reverse('search'), {
            'q': 'audio',
            'format': 'json',
            'product': 'mobile'
        })
        eq_(200, response.status_code)
        content = json.loads(response.content)
        eq_(content['total'], 1)
Example #32
0
 def test_helpful_answer_not_editable(self):
     q = QuestionFactory(is_locked=True)
     a = AnswerFactory(question=q)
     u = UserFactory()
     self.client.force_authenticate(user=u)
     res = self.client.post(reverse('answer-helpful', args=[a.id]))
     eq_(res.status_code, 403)
     eq_(Answer.objects.get(id=a.id).num_votes, 0)
Example #33
0
    def test_weekly_solutions(self):
        eight_days_ago = datetime.now() - timedelta(days=8)
        # ``a1`` is a solution in the right range.
        # ``a2`` is a solution, but it is too old.
        # The third answer is not a solution.
        a1 = AnswerFactory()
        a1.question.solution = a1
        a1.question.save()
        a2 = AnswerFactory(created=eight_days_ago)
        a2.question.solution = a2
        a2.question.save()
        AnswerFactory()

        res = self.client.get(reverse('user-weekly-solutions'))
        eq_(res.status_code, 200)
        eq_(len(res.data), 1)
        eq_(res.data[0]['username'], a1.creator.username)
Example #34
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)
Example #35
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])
Example #36
0
 def test_answer_create_action(self):
     """When an answer is created, an Action is created too."""
     q = QuestionFactory()
     ans = AnswerFactory(question=q)
     act = Action.objects.action_object(ans).get()
     eq_(act.actor, ans.creator)
     eq_(act.verb, "answered")
     eq_(act.target, q)
Example #37
0
    def test_delete_last_answer_of_question(self):
        """Deleting the last_answer of a Question should update the question."""
        yesterday = datetime.now() - timedelta(days=1)
        q = AnswerFactory(created=yesterday).question
        last_answer = q.last_answer

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

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

        # delete the answer and last_answer should go back to previous value
        a.delete()
        q = Question.objects.get(pk=q.id)
        eq_(q.last_answer.id, last_answer.id)
        eq_(Answer.objects.filter(pk=a.id).count(), 0)
Example #38
0
 def test_helpful(self):
     a = AnswerFactory()
     u = UserFactory()
     self.client.force_authenticate(user=u)
     res = self.client.post(reverse('answer-helpful', args=[a.id]))
     eq_(res.status_code, 200)
     eq_(res.data, {'num_helpful_votes': 1, 'num_unhelpful_votes': 0})
     eq_(Answer.objects.get(id=a.id).num_votes, 1)
Example #39
0
    def test_creator_num_solutions(self):
        a = AnswerFactory()
        q = a.question

        q.solution = a
        q.save()

        eq_(a.creator_num_solutions, 1)
Example #40
0
    def test_fire_on_solution(self, fire):
        """The event also fires when an answer is marked as a solution."""
        a = AnswerFactory()
        q = a.question

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

        assert fire.called
Example #41
0
    def test_delete_last_answer_of_question(self):
        """Deleting the last_answer of a Question should update the question.
        """
        yesterday = datetime.now() - timedelta(days=1)
        q = AnswerFactory(created=yesterday).question
        last_answer = q.last_answer

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

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

        # delete the answer and last_answer should go back to previous value
        a.delete()
        q = Question.objects.get(pk=q.id)
        eq_(q.last_answer.id, last_answer.id)
        eq_(Answer.objects.filter(pk=a.id).count(), 0)
Example #42
0
    def test_question_one_answer_deleted(self):
        search = QuestionMappingType.search()

        q = QuestionFactory(title=u'are model makers the new pink?')
        a = AnswerFactory(content=u'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)
Example #43
0
 def test_delete_updates_pages(self):
     a1 = AnswerFactory()
     a2 = AnswerFactory(question=a1.question)
     AnswerFactory(question=a1.question)
     a1.page = 7
     a1.save()
     a2.delete()
     a3 = Answer.objects.filter(question=a1.question)[0]
     assert a3.page == 1, "Page was %s" % a3.page
Example #44
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)
Example #45
0
    def test_answer_badge(self):
        """Verify the Support Forum Badge is awarded properly."""
        # Create the user and badge.
        year = date.today().year
        u = UserFactory()
        badge_template = QUESTIONS_BADGES['answer-badge']
        b = BadgeFactory(
            slug=badge_template['slug'].format(year=year),
            title=badge_template['title'].format(year=year),
            description=badge_template['description'].format(year=year))

        # Create one less answer than reqiured to earn badge
        AnswerFactory.create_batch(settings.BADGE_LIMIT_SUPPORT_FORUM - 1, creator=u)

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

        # Create 1 more answer.
        AnswerFactory(creator=u)

        # User should have the badge now.
        assert b.is_awarded_to(u)
Example #46
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)
Example #47
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)
Example #48
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)
Example #49
0
    def test_num_answers(self):
        u = UserFactory()
        q = QuestionFactory()
        eq_(num_answers(u), 0)

        a1 = AnswerFactory(creator=u, question=q)
        eq_(num_answers(u), 1)

        a2 = AnswerFactory(creator=u, question=q)
        eq_(num_answers(u), 2)

        a1.delete()
        eq_(num_answers(u), 1)

        a2.delete()
        eq_(num_answers(u), 0)
Example #50
0
 def setUp(self):
     u = UserFactory()
     self.client.login(username=u.username, password='******')
     self.question = QuestionFactory()
     self.answer = AnswerFactory(question=self.question)