def common_answer_vote(self): """Helper method for answer vote tests.""" # Check that there are no votes and vote form renders response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_(1, len(doc('form.helpful input[name="helpful"]'))) # Vote ua = 'Mozilla/5.0 (DjangoTestClient)' self.client.post(reverse('questions.answer_vote', args=[self.question.id, self.answer.id]), {'helpful': 'y'}, HTTP_USER_AGENT=ua) # Check that there is 1 vote and vote form doesn't render response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_('1 out of 1 person found this reply helpful', doc('#answer-1 span.helpful')[0].text.strip()) eq_(0, len(doc('form.helpful input[name="helpful"]'))) # Verify user agent vote_meta = VoteMetadata.objects.all()[0] eq_('ua', vote_meta.key) eq_(ua, vote_meta.value) # Voting again (same user) should not increment vote count post(self.client, 'questions.answer_vote', {'helpful': 'y'}, args=[self.question.id, self.answer.id]) doc = pq(response.content) eq_('1 out of 1 person found this reply helpful', doc('#answer-1 span.helpful')[0].text.strip())
def test_autowatch_reply(self, get_current): """Replying to a thread creates a watch.""" get_current.return_value.domain = 'testserver' u = user(save=True) t1 = thread(save=True) t2 = thread(save=True) assert not NewPostEvent.is_notifying(u, t1) assert not NewPostEvent.is_notifying(u, t2) self.client.login(username=u.username, password='******') # If the poster has the forums_watch_after_reply setting set to True, # they will start watching threads they reply to. s = Setting.objects.create(user=u, name='forums_watch_after_reply', value='True') data = {'content': 'some content'} post(self.client, 'forums.reply', data, args=[t1.forum.slug, t1.pk]) assert NewPostEvent.is_notifying(u, t1) # Setting forums_watch_after_reply back to False, now they shouldn't # start watching threads they reply to. s.value = 'False' s.save() post(self.client, 'forums.reply', data, args=[t2.forum.slug, t2.pk]) assert not NewPostEvent.is_notifying(u, t2)
def test_watch_both_then_new_post(self, get_current): """Watching both forum and thread. Replying to a thread should send ONE email.""" get_current.return_value.domain = 'testserver' t = thread(save=True) f = t.forum forum_post(thread=t, save=True) poster = user(save=True) watcher = user(save=True) self._toggle_watch_forum_as(f, watcher, turn_on=True) self._toggle_watch_thread_as(t, watcher, turn_on=True) self.client.login(username=poster.username, password='******') post(self.client, 'forums.reply', {'content': 'a post'}, args=[f.slug, t.id]) eq_(1, len(mail.outbox)) p = Post.objects.all().order_by('-id')[0] attrs_eq(mail.outbox[0], to=[watcher.email], subject='Re: {f} - {t}'.format(f=f, t=t)) body = REPLY_EMAIL.format( username=poster.username, forum_slug=f.slug, thread_title=t.title, thread_id=t.id, post_id=p.id) starts_with(mail.outbox[0].body, body)
def test_answer_upload(self): """Posting answer attaches an existing uploaded image to the answer.""" f = open('apps/upload/tests/media/test.jpg') post(self.client, 'upload.up_image_async', {'image': f}, args=['questions.Question', self.question.id]) f.close() content = 'lorem ipsum dolor sit amet' response = post(self.client, 'questions.reply', {'content': content}, args=[self.question.id]) eq_(200, response.status_code) new_answer = self.question.answers.order_by('-created')[0] eq_(1, new_answer.images.count()) image = new_answer.images.all()[0] name = '098f6b.jpg' message = 'File name "%s" does not contain "%s"' % ( image.file.name, name) assert name in image.file.name, message eq_('jsocol', image.creator.username) # Clean up ImageAttachment.objects.all().delete()
def test_answer_creator_can_edit(self): """The creator of an answer can edit his/her answer.""" self.client.login(username='******', password='******') # Initially there should be no edit links response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_(0, len(doc('ol.answers a.edit'))) # Add an answer and verify the edit link shows up content = 'lorem ipsum dolor sit amet' response = post(self.client, 'questions.reply', {'content': content}, args=[self.question.id]) doc = pq(response.content) eq_(1, len(doc('ol.answers a.edit'))) new_answer = self.question.answers.order_by('-created')[0] eq_(1, len(doc('#answer-%s a.edit' % new_answer.id))) # Make sure it can be edited content = 'New content for answer' response = post(self.client, 'questions.edit_answer', {'content': content}, args=[self.question.id, new_answer.id]) eq_(200, response.status_code) # Now lock it and make sure it can't be edited self.question.is_locked = True self.question.save() response = post(self.client, 'questions.edit_answer', {'content': content}, args=[self.question.id, new_answer.id]) eq_(403, response.status_code)
def common_vote(self): """Helper method for question vote tests.""" # Check that there are no votes and vote form renders response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_('0 people', doc('div.have-problem mark')[0].text) eq_(1, len(doc('div.me-too form'))) # Vote ua = 'Mozilla/5.0 (DjangoTestClient)' self.client.post(reverse('questions.vote', args=[self.question.id]), {}, HTTP_USER_AGENT=ua) # Check that there is 1 vote and vote form doesn't render response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_('1 person', doc('div.have-problem mark')[0].text) eq_(0, len(doc('div.me-too form'))) # Verify user agent vote_meta = VoteMetadata.objects.all()[0] eq_('ua', vote_meta.key) eq_(ua, vote_meta.value) # Voting again (same user) should not increment vote count post(self.client, 'questions.vote', args=[self.question.id]) response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_('1 person', doc('div.have-problem mark')[0].text)
def _toggle_watch_question(self, event_type, turn_on=True): """Helper to watch/unwatch a question. Fails if called twice with the same turn_on value.""" question = Question.objects.all()[0] self.client.login(username='******', password='******') user = User.objects.get(username='******') event_cls = (QuestionReplyEvent if event_type == 'reply' else QuestionSolvedEvent) # Make sure 'before' values are the reverse. if turn_on: assert not event_cls.is_notifying(user, question), ( '%s should not be notifying.' % event_cls.__name__) else: assert event_cls.is_notifying(user, question), ( '%s should be notifying.' % event_cls.__name__) url = 'questions.watch' if turn_on else 'questions.unwatch' data = {'event_type': event_type} if turn_on else {} post(self.client, url, data, args=[question.id]) if turn_on: assert event_cls.is_notifying(user, question), ( '%s should be notifying.' % event_cls.__name__) else: assert not event_cls.is_notifying(user, question), ( '%s should not be notifying.' % event_cls.__name__) return question
def test_solution_notification(self, get_current): """Assert that hitting the watch toggle toggles and that proper mails are sent to anonymous and registered watchers.""" # TODO: Too monolithic. Split this test into several. get_current.return_value.domain = 'testserver' question = self._toggle_watch_question('solution', turn_on=True) QuestionSolvedEvent.notify('*****@*****.**', question) answer = question.answers.all()[0] # Post a reply self.client.login(username='******', password='******') post(self.client, 'questions.solution', args=[question.id, answer.id]) # Order of emails is not important. attrs_eq(mail.outbox[0], to=['user47963@nowhere'], subject='Solution found to Firefox Help question') starts_with(mail.outbox[0].body, SOLUTION_EMAIL % answer.id) attrs_eq(mail.outbox[1], to=['*****@*****.**'], subject='Solution found to Firefox Help question') starts_with(mail.outbox[1].body, SOLUTION_EMAIL_TO_ANONYMOUS % answer.id) self._toggle_watch_question('solution', turn_on=False)
def test_answer_creator_can_edit(self): """The creator of an answer can edit his/her answer.""" self.client.login(username="******", password="******") # Initially there should be no edit links response = get(self.client, "questions.answers", args=[self.question.id]) doc = pq(response.content) eq_(0, len(doc("ol.answers li.edit"))) # Add an answer and verify the edit link shows up content = "lorem ipsum dolor sit amet" response = post(self.client, "questions.reply", {"content": content}, args=[self.question.id]) doc = pq(response.content) eq_(1, len(doc("ol.answers li.edit"))) new_answer = self.question.answers.order_by("-created")[0] eq_(1, len(doc("#answer-%s li.edit" % new_answer.id))) # Make sure it can be edited content = "New content for answer" response = post( self.client, "questions.edit_answer", {"content": content}, args=[self.question.id, new_answer.id] ) eq_(200, response.status_code) # Now lock it and make sure it can't be edited self.question.is_locked = True self.question.save() response = post( self.client, "questions.edit_answer", {"content": content}, args=[self.question.id, new_answer.id] ) eq_(403, response.status_code)
def test_post_ratelimit(self): """Verify that rate limiting kicks in after 4 threads or replies.""" d = document(save=True) u = user(save=True) self.client.login(username=u.username, password='******') # Create 2 threads: for i in range(2): response = post(self.client, 'wiki.discuss.new_thread', {'title': 'Topic', 'content': 'hellooo'}, args=[d.slug]) eq_(200, response.status_code) # Now 3 replies (only 2 should save): t = Thread.objects.all()[0] for i in range(3): response = post(self.client, 'wiki.discuss.reply', {'content': 'hellooo'}, args=[d.slug, t.id]) eq_(200, response.status_code) # And another thread that shouldn't save: response = post(self.client, 'wiki.discuss.new_thread', {'title': 'Topic', 'content': 'hellooo'}, args=[d.slug]) # We should only have 4 posts (each thread and reply creates a post). eq_(4, Post.objects.count())
def common_vote(self): """Helper method for question vote tests.""" # Check that there are no votes and vote form renders response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_('0 people', doc('div.have-problem mark')[0].text) eq_(1, len(doc('div.me-too form'))) # Vote post(self.client, 'questions.vote', args=[self.question.id]) # Check that there is 1 vote and vote form doesn't render response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_('1 person', doc('div.have-problem mark')[0].text) eq_(0, len(doc('div.me-too form'))) # Voting again (same user) should not increment vote count post(self.client, 'questions.vote', args=[self.question.id]) response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_('1 person', doc('div.have-problem mark')[0].text)
def common_answer_vote(self): """Helper method for answer vote tests.""" # Check that there are no votes and vote form renders response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_(1, len(doc('form.helpful input[name="helpful"]'))) # Vote post(self.client, 'questions.answer_vote', {'helpful': 'y'}, args=[self.question.id, self.answer.id]) # Check that there is 1 vote and vote form doesn't render response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_('1 out of 1 person', doc('#answer-1 div.helpful mark')[0].text) eq_(0, len(doc('form.helpful input[name="helpful"]'))) # Voting again (same user) should not increment vote count post(self.client, 'questions.answer_vote', {'helpful': 'y'}, args=[self.question.id, self.answer.id]) doc = pq(response.content) eq_('1 out of 1 person', doc('#answer-1 div.helpful mark')[0].text)
def test_watch_solution(self): """Watch a question for solution.""" self.client.logout() post(self.client, 'questions.watch', {'email': '*****@*****.**', 'event_type': 'solution'}, args=[self.question.id]) assert check_watch(Question, self.question.id, '*****@*****.**', 'solution'), 'Watch was not created'
def test_unwatch(self): """Unwatch a question.""" self.client.login(username='******', password='******') user = User.objects.get(username='******') create_watch(Question, self.question.id, user.email, 'solution') post(self.client, 'questions.unwatch', args=[self.question.id]) assert not check_watch(Question, self.question.id, user.email, 'solution'), 'Watch was not destroyed'
def test_fire_on_reply(self, fire): """The event fires when there is a reply.""" t = Thread.objects.get(pk=2) self.client.login(username='******', password='******') post(self.client, 'forums.reply', {'content': 'a post'}, args=[t.forum.slug, t.id]) # NewPostEvent.fire() is called. assert fire.called
def test_unsolve(self, delete): answer = Answer.objects.get(pk=1) question = answer.question self.client.login(username='******', password='******') question.solution = answer question.save() post(self.client, 'questions.unsolve', args=[question.id, answer.id]) assert delete.called
def test_fire_on_solution(self, fire): """The event also fires when an answer is marked as a solution.""" answer = Answer.objects.get(pk=1) question = answer.question self.client.login(username='******', password='******') post(self.client, 'questions.solution', args=[question.id, answer.id]) assert fire.called
def test_fire_on_reply(self, fire): """The event fires when there is a reply.""" t = thread(save=True) u = user(save=True) self.client.login(username=u.username, password='******') post(self.client, 'wiki.discuss.reply', {'content': 'a post'}, args=[t.document.slug, t.id]) # NewPostEvent.fire() is called. assert fire.called
def test_watch_replies_logged_in(self): """Watch a question for replies (logged in).""" self.client.login(username='******', password='******') user = User.objects.get(username='******') post(self.client, 'questions.watch', {'event_type': 'reply'}, args=[self.question.id]) assert QuestionReplyEvent.is_notifying(user, self.question), ( 'Watch was not created')
def test_fire_on_new_thread(self, fire): """The event fires when there is a new thread.""" f = Forum.objects.get(pk=1) self.client.login(username='******', password='******') post(self.client, 'forums.new_thread', {'title': 'a title', 'content': 'a post'}, args=[f.slug]) # NewThreadEvent.fire() is called. assert fire.called
def test_unwatch(self): """Unwatch a question.""" # First watch question. self.test_watch_replies_logged_in() # Then unwatch it. self.client.login(username="******", password="******") user = User.objects.get(username="******") post(self.client, "questions.unwatch", args=[self.question.id]) assert not QuestionReplyEvent.is_notifying(user, self.question), "Watch was not destroyed"
def test_watch_replies_logged_in(self): """Watch a question for replies (logged in).""" self.client.login(username='******', password='******') user = User.objects.get(username='******') post(self.client, 'questions.watch', {'email': '*****@*****.**', 'event_type': 'reply'}, args=[self.question.id]) assert check_watch(Question, self.question.id, user.email, 'reply'), 'Watch was not created'
def test_solution_with_perm(self): """Test marking a solution with 'change_solution' permission.""" u = user(save=True) add_permission(u, Question, 'change_solution') self.client.login(username=u.username, password='******') answer = self.question.answers.all()[0] post(self.client, 'questions.solution', args=[self.question.id, answer.id]) q = Question.uncached.get(pk=self.question.id) eq_(q.solution, answer)
def test_fire_on_new_thread(self, fire): """The event fires when there is a new thread.""" d = document(save=True) u = user(save=True) self.client.login(username=u.username, password='******') post(self.client, 'wiki.discuss.new_thread', {'title': 'a title', 'content': 'a post'}, args=[d.slug]) # NewThreadEvent.fire() is called. assert fire.called
def test_edit_thread_creator(self): """Changing thread title as the thread creator works.""" t = forum_post(save=True).thread u = t.creator self.client.login(username=u.username, password='******') post(self.client, 'forums.edit_thread', {'title': 'A new title'}, args=[t.forum.slug, t.id]) edited_t = Thread.uncached.get(id=t.id) eq_('A new title', edited_t.title)
def test_watch_other_thread_then_reply(self): """Watching a different thread than the one we're replying to shouldn't notify.""" t = self._toggle_watch_thread_as('pcraciunoiu', turn_on=True) t2 = Thread.objects.exclude(pk=t.pk)[0] self.client.login(username='******', password='******') post(self.client, 'forums.reply', {'content': 'a post'}, args=[t2.forum.slug, t2.id]) assert not mail.outbox
def test_upload_video_ogv_flv(self): """Upload the same video, in ogv and flv formats""" ogv = open(TEST_VID["ogv"]) flv = open(TEST_VID["flv"]) post(self.client, "gallery.upload_async", {"ogv": ogv, "flv": flv}, args=["video"]) ogv.close() flv.close() vid = Video.objects.all()[0] assert vid.ogv.url.endswith("098f6b.ogv") assert vid.flv.url.endswith("098f6b.flv")
def test_watch_forum_then_new_thread_as_self(self, get_current): """Watching a forum and creating a new thread as myself should not send email.""" get_current.return_value.domain = 'testserver' f = self._toggle_watch_forum_as('pcraciunoiu', turn_on=True) self.client.login(username='******', password='******') post(self.client, 'forums.new_thread', {'title': 'a title', 'content': 'a post'}, args=[f.slug]) # Assert no email is sent. assert not mail.outbox
def test_watch_forum_then_new_post_as_self(self, get_current): """Watching a forum and replying as myself should not send email.""" get_current.return_value.domain = 'testserver' f = self._toggle_watch_forum_as('pcraciunoiu', turn_on=True) t = f.thread_set.all()[0] self.client.login(username='******', password='******') post(self.client, 'forums.reply', {'content': 'a post'}, args=[f.slug, t.id]) # Assert no email is sent. assert not mail.outbox
def test_upload_video_ogv_flv(self): """Upload the same video, in ogv and flv formats""" ogv = open(TEST_VID['ogv']) flv = open(TEST_VID['flv']) post(self.client, 'gallery.upload_async', {'ogv': ogv, 'flv': flv}, args=['video']) ogv.close() flv.close() vid = Video.objects.all()[0] assert vid.ogv.url.endswith('098f6b.ogv') assert vid.flv.url.endswith('098f6b.flv')
def test_edit_thread_errors(self): """Editing thread with too short of a title shows errors.""" self.client.login(username='******', password='******') d = Document.objects.all()[0] t_creator = User.objects.get(username='******') t = d.thread_set.filter(creator=t_creator)[0] response = post(self.client, 'wiki.discuss.edit_thread', {'title': 'wha?'}, args=[d.slug, t.id]) doc = pq(response.content) errors = doc('ul.errorlist li a') eq_( errors[0].text, 'Your title is too short (4 characters). ' + 'It must be at least 5 characters.')
def test_new_short_thread_errors(self): """Posting a short new thread shows errors.""" self.client.login(username='******', password='******') d = Document.objects.all()[0] response = post(self.client, 'wiki.discuss.new_thread', {'title': 'wha?', 'content': 'wha?'}, args=[d.slug]) doc = pq(response.content) errors = doc('ul.errorlist li a') eq_(errors[0].text, 'Your title is too short (4 characters). ' + 'It must be at least 5 characters.') eq_(errors[1].text, 'Your message is too short (4 characters). ' + 'It must be at least 5 characters.')
def test_edit_post_errors(self): """Changing post content works.""" u = user(save=True) self.client.login(username=u.username, password='******') t = thread(creator=u, is_locked=False, save=True) p = t.new_post(creator=u, content='foo') response = post(self.client, 'wiki.discuss.edit_post', {'content': 'wha?'}, args=[t.document.slug, t.id, p.id]) doc = pq(response.content) errors = doc('ul.errorlist li a') eq_( errors[0].text, 'Your message is too short (4 characters). ' + 'It must be at least 5 characters.')
def test_edit_thread_errors(self): """Editing thread with too short of a title shows errors.""" u = user(save=True) self.client.login(username=u.username, password='******') d = document(save=True) t = thread(document=d, creator=u, save=True) response = post(self.client, 'wiki.discuss.edit_thread', {'title': 'wha?'}, args=[d.slug, t.id]) doc = pq(response.content) errors = doc('ul.errorlist li a') eq_( errors[0].text, 'Your title is too short (4 characters). ' + 'It must be at least 5 characters.')
def test_empty_thread_errors(self): """Posting an empty thread shows errors.""" self.client.login(username='******', password='******') d = Document.objects.all()[0] response = post(self.client, 'wiki.discuss.new_thread', { 'title': '', 'content': '' }, args=[d.slug]) doc = pq(response.content) errors = doc('ul.errorlist li a') eq_(errors[0].text, 'Please provide a title.') eq_(errors[1].text, 'Please provide a message.')
def test_edit_post_errors(self): """Changing post content works.""" p = forum_post(save=True) t = p.thread u = p.author self.client.login(username=u.username, password='******') response = post(self.client, 'forums.edit_post', {'content': 'wha?'}, args=[t.forum.slug, t.id, p.id]) doc = pq(response.content) errors = doc('ul.errorlist li a') eq_( errors[0].text, 'Your message is too short (4 characters). ' + 'It must be at least 5 characters.')
def test_empty_thread_errors(self): """Posting an empty thread shows errors.""" f = forum(save=True) u = user(save=True) self.client.login(username=u.username, password='******') response = post(self.client, 'forums.new_thread', { 'title': '', 'content': '' }, args=[f.slug]) doc = pq(response.content) errors = doc('ul.errorlist li a') eq_(errors[0].text, 'Please provide a title.') eq_(errors[1].text, 'Please provide a message.')
def test_delete_question_logged_out(self): """Deleting a question while logged out redirects to login.""" self.client.logout() response = get(self.client, 'questions.delete', args=[self.question.id]) redirect = response.redirect_chain[0] eq_(302, redirect[1]) eq_('http://testserver/%s%s?next=/en-US/questions/1/delete' % (settings.LANGUAGE_CODE, settings.LOGIN_URL), redirect[0]) response = post(self.client, 'questions.delete', args=[self.question.id]) redirect = response.redirect_chain[0] eq_(302, redirect[1]) eq_('http://testserver/%s%s?next=/en-US/questions/1/delete' % (settings.LANGUAGE_CODE, settings.LOGIN_URL), redirect[0])
def test_edit_post_moderator(self): """Editing post as a moderator works.""" u = user(save=True) add_permission(u, Post, 'change_post') self.client.login(username=u.username, password='******') p = post_(save=True) t = p.thread d = t.document r = post(self.client, 'wiki.discuss.edit_post', {'content': 'More new content'}, args=[d.slug, t.id, p.id]) eq_(200, r.status_code) edited_p = Post.uncached.get(pk=p.pk) eq_('More new content', edited_p.content)
def test_preview(self): """Preview the thread post.""" self.client.login(username='******', password='******') f = Forum.objects.filter()[0] num_threads = f.thread_set.count() content = 'Full of awesome.' response = post(self.client, 'forums.new_thread', { 'title': 'Topic', 'content': content, 'preview': 'any string' }, args=[f.slug]) eq_(200, response.status_code) doc = pq(response.content) eq_(content, doc('#post-preview div.content').text()) eq_(num_threads, f.thread_set.count())
def test_edit_thread_moderator(self): """Editing post as a moderator works.""" t = forum_post(save=True).thread f = t.forum u = user(save=True) g = group(save=True) ct = ContentType.objects.get_for_model(f) permission(codename='forums_forum.thread_edit_forum', content_type=ct, object_id=f.id, group=g, save=True) g.user_set.add(u) self.client.login(username=u.username, password='******') r = post(self.client, 'forums.edit_thread', {'title': 'new title'}, args=[f.slug, t.id]) eq_(200, r.status_code) edited_t = Thread.uncached.get(id=t.id) eq_('new title', edited_t.title)
def test_preview_reply(self): """Preview a reply.""" self.client.login(username='******', password='******') f = Forum.objects.filter()[0] t = f.thread_set.all()[0] num_posts = t.post_set.count() content = 'Full of awesome.' response = post(self.client, 'forums.reply', { 'content': content, 'preview': 'any string' }, args=[f.slug, t.id]) eq_(200, response.status_code) doc = pq(response.content) eq_(content, doc('#post-preview div.content').text()) eq_(num_posts, t.post_set.count())
def test_edit_thread_moderator(self): """Editing post as a moderator works.""" u = user(save=True) add_permission(u, Thread, 'change_thread') t = thread(title='Sticky Thread', save=True) d = t.document self.client.login(username=u.username, password='******') eq_('Sticky Thread', t.title) r = post(self.client, 'wiki.discuss.edit_thread', {'title': 'new title'}, args=[d.slug, t.id]) eq_(200, r.status_code) edited_t = Thread.uncached.get(pk=t.id) eq_('new title', edited_t.title)
def test_new_short_thread_errors(self): """Posting a short new thread shows errors.""" f = forum(save=True) u = user(save=True) self.client.login(username=u.username, password='******') response = post(self.client, 'forums.new_thread', {'title': 'wha?', 'content': 'wha?'}, args=[f.slug]) doc = pq(response.content) errors = doc('ul.errorlist li a') eq_(errors[0].text, 'Your title is too short (4 characters). ' + 'It must be at least 5 characters.') eq_(errors[1].text, 'Your message is too short (4 characters). ' + 'It must be at least 5 characters.')
def test_edit_post_errors(self): """Changing post content works.""" self.client.login(username='******', password='******') f = Forum.objects.filter()[0] t = f.thread_set.all()[0] p_author = User.objects.get(username='******') p = t.post_set.filter(author=p_author)[0] response = post(self.client, 'forums.edit_post', {'content': 'wha?'}, args=[f.slug, t.id, p.id]) doc = pq(response.content) errors = doc('ul.errorlist li a') eq_( errors[0].text, 'Your message is too short (4 characters). ' + 'It must be at least 5 characters.')
def test_solution(self): """Test accepting a solution.""" response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_(0, len(doc('div.solution'))) answer = self.question.answers.all()[0] response = post(self.client, 'questions.solution', args=[self.question.id, answer.id]) doc = pq(response.content) eq_(1, len(doc('div.solution'))) li = doc('span.solved')[0].getparent().getparent().getparent() eq_('answer-%s' % answer.id, li.attrib['id']) self.question.solution = None self.question.save()
def test_long_answer(self): """Post a long answer shows error.""" # Set up content length to 10,001 characters content = '' for i in range(1000): content += '1234567890' content += '1' response = post(self.client, 'questions.reply', {'content': content}, args=[self.question.id]) doc = pq(response.content) error_msg = doc('ul.errorlist li a')[0] eq_(error_msg.text, 'Please keep the length of your content to ' + '10,000 characters or less. It is currently ' + '10,001 characters.')
def test_preview_reply(self): """Preview a reply.""" t = forum_post(save=True).thread u = t.creator content = 'Full of awesome.' self.client.login(username=u.username, password='******') response = post(self.client, 'forums.reply', { 'content': content, 'preview': 'any string' }, args=[t.forum.slug, t.id]) eq_(200, response.status_code) doc = pq(response.content) eq_(content, doc('#post-preview div.content').text()) eq_(1, t.post_set.count())
def test_only_owner_can_accept_solution(self): """Make sure non-owner can't mark solution.""" response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_(1, len(doc('input[name="solution"]'))) self.client.logout() self.client.login(username='******', password='******') response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_(0, len(doc('input[name="solution"]'))) answer = self.question.answers.all()[0] response = post(self.client, 'questions.solution', args=[self.question.id, answer.id]) eq_(403, response.status_code)
def test_preview(self): """Preview the thread post.""" u = user(save=True) self.client.login(username=u.username, password='******') d = document(save=True) num_threads = d.thread_set.count() content = 'Full of awesome.' response = post(self.client, 'wiki.discuss.new_thread', { 'title': 'Topic', 'content': content, 'preview': 'any string' }, args=[d.slug]) eq_(200, response.status_code) doc = pq(response.content) eq_(content, doc('#post-preview div.content').text()) eq_(num_threads, d.thread_set.count())
def test_upload_image_long_filename(self): """Uploading an image with a filename that's too long fails.""" with open('apps/upload/tests/media/a_really_long_filename_worth_' 'more_than_250_characters__a_really_long_filename_worth_' 'more_than_250_characters__a_really_long_filename_worth_' 'more_than_250_characters__a_really_long_filename_worth_' 'more_than_250_characters__a_really_long_filename_yes_.jpg')\ as f: r = post(self.client, 'gallery.upload_async', {'file': f}, args=['image']) eq_(400, r.status_code) json_r = json.loads(r.content) eq_('error', json_r['status']) eq_('Could not upload your image.', json_r['message']) eq_(forms.MSG_IMAGE_LONG % {'length': 251, 'max': settings.MAX_FILENAME_LENGTH}, json_r['errors']['file'][0])
def test_submit_ticket_anon(self, submit_ticket): """Verify form post from unauth'd user.""" email = '*****@*****.**' subject = 'A new ticket' body = 'Lorem ipsum dolor sit amet' cat = 'account' self.client.logout() response = post(self.client, 'questions.marketplace_aaq_category', { 'subject': subject, 'body': body, 'category': cat, 'email': email }, args=['account']) eq_(200, response.status_code) submit_ticket.assert_called_with(email, cat, subject, body)
def test_preview(self): """Preview the thread post.""" f = forum(save=True) u = user(save=True) self.client.login(username=u.username, password='******') content = 'Full of awesome.' response = post(self.client, 'forums.new_thread', { 'title': 'Topic', 'content': content, 'preview': 'any string' }, args=[f.slug]) eq_(200, response.status_code) doc = pq(response.content) eq_(content, doc('#post-preview div.content').text()) eq_(0, f.thread_set.count()) # No thread was created.
def test_locale_discussions_ignores_sticky(self): """Sticky flag is ignored in locale discussions view""" u = user(save=True) d = document(save=True) t = thread(title='Sticky Thread', is_sticky=True, document=d, save=True) t.new_post(creator=u, content='foo') t2 = thread(title='A thread with a very very long', is_sticky=False, document=d, save=True) t2.new_post(creator=u, content='bar') time.sleep(1) t2.new_post(creator=u, content='last') self.client.login(username=u.username, password='******') response = post(self.client, 'wiki.locale_discussions') eq_(200, response.status_code) doc = pq(response.content) title = doc('ol.threads li div.title a:first').text() assert title.startswith('A thread with a very very long')
def test_delete_image_with_permission(self): """Users with permission can delete images.""" u = User.objects.get(username='******') ct = ContentType.objects.get_for_model(ImageAttachment) p = Permission.objects.get_or_create(codename='delete_imageattachment', content_type=ct)[0] u.user_permissions.add(p) assert u.has_perm('upload.delete_imageattachment') self.test_upload_image() im = ImageAttachment.objects.all()[0] self.client.login(username='******', password='******') r = post(self.client, 'upload.del_image_async', args=[im.id]) eq_(200, r.status_code) json_r = json.loads(r.content) eq_('success', json_r['status']) assert not ImageAttachment.uncached.exists()
def test_preview_reply(self): """Preview a reply.""" u = user(save=True) self.client.login(username=u.username, password='******') d = document(save=True) t = thread(document=d, save=True) num_posts = t.post_set.count() content = 'Full of awesome.' response = post(self.client, 'wiki.discuss.reply', { 'content': content, 'preview': 'any string' }, args=[d.slug, t.id]) eq_(200, response.status_code) doc = pq(response.content) eq_(content, doc('#post-preview div.content').text()) eq_(num_posts, t.post_set.count())
def test_upload_draft_image(self): """Uploading draft image works, sets locale too.""" u = User.objects.get(username='******') img = image(creator=u, title=get_draft_title(u)) # No thumbnail yet. eq_(None, img.thumbnail) r = post(self.client, 'gallery.upload', {'locale': 'de', 'title': 'Hasta la vista', 'description': 'Auf wiedersehen!'}, args=['image']) eq_(200, r.status_code) img = Image.objects.all()[0] eq_('de', img.locale) eq_('Hasta la vista', img.title) eq_('Auf wiedersehen!', img.description) # Thumbnail generated after form is saved. eq_(90, img.thumbnail.width)
def test_edit_answer_without_permission(self): """Editing an answer without permissions returns a 403. The edit link shouldn't show up on the Answers page.""" response = get(self.client, 'questions.answers', args=[self.question.id]) doc = pq(response.content) eq_(0, len(doc('ol.answers li.edit'))) answer = self.question.last_answer response = get(self.client, 'questions.edit_answer', args=[self.question.id, answer.id]) eq_(403, response.status_code) content = 'New content for answer' response = post(self.client, 'questions.edit_answer', {'content': content}, args=[self.question.id, answer.id]) eq_(403, response.status_code)
def test_upload_video_long_filename(self): """Uploading a video with a filename that's too long fails.""" for k in ('flv', 'ogv', 'webm'): with open('apps/upload/tests/media/a_really_long_filename_worth_' 'more_than_250_characters__a_really_long_filename_worth_' 'more_than_250_characters__a_really_long_filename_worth_' 'more_than_250_characters__a_really_long_filename_worth_' 'more_than_250_characters__a_really_long_filename_yes_' '.jpg')\ as f: r = post(self.client, 'gallery.upload_async', {k: f}, args=['video']) eq_(400, r.status_code) json_r = json.loads(r.content) eq_('error', json_r['status']) eq_('Could not upload your video.', json_r['message']) message = getattr(forms, 'MSG_' + k.upper() + '_LONG') eq_(message % {'length': 251, 'max': settings.MAX_FILENAME_LENGTH}, json_r['errors'][k][0])
def test_upload_long_filename(self): """Uploading an image with a filename that's too long fails.""" with open('apps/upload/tests/media/a_really_long_filename_worth_' 'more_than_250_characters__a_really_long_filename_worth_' 'more_than_250_characters__a_really_long_filename_worth_' 'more_than_250_characters__a_really_long_filename_worth_' 'more_than_250_characters__a_really_long_filename_yes_.jpg')\ as f: r = post(self.client, 'upload.up_image_async', {'image': f}, args=['questions.Question', 1]) eq_(400, r.status_code) json_r = json.loads(r.content) eq_('error', json_r['status']) eq_('Invalid or no image received.', json_r['message']) eq_( MSG_IMAGE_LONG % { 'length': 251, 'max': settings.MAX_FILENAME_LENGTH }, json_r['errors']['image'][0])