Beispiel #1
0
    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)
Beispiel #4
0
    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()
Beispiel #5
0
    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)
Beispiel #6
0
    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)
Beispiel #10
0
    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())
Beispiel #11
0
    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)
Beispiel #12
0
    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)
Beispiel #13
0
 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'
Beispiel #14
0
 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
Beispiel #16
0
 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
Beispiel #17
0
    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
Beispiel #18
0
 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
Beispiel #19
0
 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"
Beispiel #22
0
 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'
Beispiel #23
0
 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)
Beispiel #24
0
 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
Beispiel #25
0
    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
Beispiel #27
0
 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
Beispiel #30
0
 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')
Beispiel #31
0
    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.')
Beispiel #32
0
    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.')
Beispiel #33
0
    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.')
Beispiel #34
0
    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.')
Beispiel #35
0
    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.')
Beispiel #36
0
    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.')
Beispiel #37
0
    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.')
Beispiel #38
0
    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])
Beispiel #39
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)
Beispiel #40
0
 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())
Beispiel #41
0
    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)
Beispiel #42
0
 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())
Beispiel #43
0
    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)
Beispiel #44
0
    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.')
Beispiel #45
0
    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.')
Beispiel #46
0
    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()
Beispiel #47
0
    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.')
Beispiel #48
0
    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())
Beispiel #49
0
    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)
Beispiel #50
0
 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())
Beispiel #51
0
    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])
Beispiel #52
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)
Beispiel #53
0
    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.
Beispiel #54
0
 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')
Beispiel #55
0
    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()
Beispiel #56
0
    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())
Beispiel #57
0
    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)
Beispiel #58
0
    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)
Beispiel #59
0
    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])
Beispiel #60
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])