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')))
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_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)
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
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)
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)
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_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)
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)
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)
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)
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)
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
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)
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')
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)
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]))
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)
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))
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)
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"])
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
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]))
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)
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)
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())
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)
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']
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)
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)
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)
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)
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])
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)
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)
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)
def test_creator_num_solutions(self): a = AnswerFactory() q = a.question q.solution = a q.save() eq_(a.creator_num_solutions, 1)
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
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)
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)
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
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)
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)
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)
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)
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)
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)
def setUp(self): u = UserFactory() self.client.login(username=u.username, password='******') self.question = QuestionFactory() self.answer = AnswerFactory(question=self.question)