Exemple #1
0
 def test_delete_image_no_permission(self):
     """Can't delete an image without permission."""
     u = UserFactory(username='******')
     assert not u.has_perm('upload.delete_imageattachment')
     self.test_upload_image()
     im = ImageAttachment.objects.all()[0]
     self.client.login(username='******', password='******')
     r = self._make_post_request(args=[im.id])
     eq_(403, r.status_code)
     assert ImageAttachment.objects.exists()
Exemple #2
0
    def setUp(self):
        u = UserFactory()
        add_permission(u, Question, 'change_question')
        assert u.has_perm('questions.change_question')
        self.user = u

        p = ProductFactory()
        t = TopicFactory(product=p)

        q = QuestionFactory(product=p, topic=t)

        self.product = p
        self.topic = t
        self.question = q
Exemple #3
0
    def test_thread_is_reindexed_on_username_change(self):
        search = ThreadMappingType.search()

        u = UserFactory(username='******')
        ThreadFactory(creator=u, title=u'Hello')

        self.refresh()
        eq_(search.query(post_title='hello')[0]['post_author_ord'], [u'dexter'])

        # Change the username and verify the index.
        u.username = '******'
        u.save()
        self.refresh()
        eq_(search.query(post_title='hello')[0]['post_author_ord'], [u'walter'])
Exemple #4
0
 def setUp(self):
     super(PasswordResetTests, self).setUp()
     self.u = UserFactory(email="*****@*****.**")
     self.uidb36 = int_to_base36(self.u.id)
     self.token = default_token_generator.make_token(self.u)
     self.orig_debug = settings.DEBUG
     settings.DEBUG = True
Exemple #5
0
    def test_deactivate_button(self):
        """Check that the deactivate button is shown appropriately"""
        u = UserFactory()
        r = self.client.get(reverse('users.profile', args=[u.username]))
        assert 'Deactivate this user' not in r.content

        add_permission(self.u, Profile, 'deactivate_users')
        self.client.login(username=self.u.username, password='******')
        r = self.client.get(reverse('users.profile', args=[u.username]))
        assert 'Deactivate this user' in r.content

        u.is_active = False
        u.save()
        r = self.client.get(reverse('users.profile', args=[u.username]))
        assert 'This user has been deactivated.' in r.content

        r = self.client.get(reverse('users.profile', args=[self.u.username]))
        assert 'Deactivate this user' not in r.content
Exemple #6
0
    def setUp(self):
        super(TestQuestionUpdates, self).setUp()
        self.u = UserFactory(is_superuser=True)
        self.client.login(username=self.u.username, password='******')

        self.q = QuestionFactory(updated=datetime(2012, 7, 9, 9, 0, 0))
        self.a = AnswerFactory(question=self.q)

        # Get the question from the database so we have a consistent level of
        # precision during the test.
        self.q = Question.objects.get(pk=self.q.id)
Exemple #7
0
    def test_questions_inactive_user(self):
        """Verify questions from inactive users aren't counted."""
        # Two questions for an inactive user.
        # They shouldn't show up in the count.
        u = UserFactory(is_active=False)
        QuestionFactory(creator=u)
        QuestionFactory(creator=u)

        r = self._get_api_result('api.kpi.questions')
        eq_(len(r['objects']), 0)

        # Activate the user, now the questions should count.
        u.is_active = True
        u.save()
        cache.clear()  # We need to clear the cache for new results.

        url = reverse('api.kpi.questions')
        response = self.client.get(url + '?format=json')
        eq_(200, response.status_code)
        r = json.loads(response.content)
        eq_(r['objects'][0]['questions'], 2)
Exemple #8
0
    def test_aaq_new_question_inactive(self, get_current):
        """New question is posted through mobile."""
        get_current.return_value.domain = 'testserver'

        # Log in first.
        u = UserFactory()
        self.client.login(username=u.username, password='******')

        # Then become inactive.
        u.is_active = False
        u.save()

        # Set 'in-aaq' for the session. It isn't already set because this
        # test doesn't do a GET of the form first.
        s = self.client.session
        s['in-aaq'] = True
        s.save()

        response = self._new_question(post_it=True)
        eq_(200, response.status_code)
        assert template_used(response, 'questions/mobile/confirm_email.html')
Exemple #9
0
    def test_question_is_reindexed_on_username_change(self):
        search = QuestionMappingType.search()

        u = UserFactory(username='******')

        QuestionFactory(creator=u, title=u'Hello')
        AnswerFactory(creator=u, content=u'I love you')
        self.refresh()
        eq_(search.query(question_title__match='hello')[0]['question_creator'],
            u'dexter')
        query = search.query(question_answer_content__match='love')
        eq_(query[0]['question_answer_creator'],
            [u'dexter'])

        # Change the username and verify the index.
        u.username = '******'
        u.save()
        self.refresh()
        eq_(search.query(question_title__match='hello')[0]['question_creator'],
            u'walter')
        query = search.query(question_answer_content__match='love')
        eq_(query[0]['question_answer_creator'], [u'walter'])
Exemple #10
0
class PasswordChangeTests(TestCaseBase):

    def setUp(self):
        super(PasswordChangeTests, self).setUp()
        self.u = UserFactory()
        self.url = reverse('users.pw_change')
        self.new_pw = 'fjdka387fvstrongpassword!'
        self.client.login(username=self.u.username, password='******')

    def test_change_password(self):
        assert self.u.check_password(self.new_pw) is False

        r = self.client.post(self.url, {'old_password': '******',
                                        'new_password1': self.new_pw,
                                        'new_password2': self.new_pw})
        eq_(302, r.status_code)
        eq_('http://testserver/en-US/users/pwchangecomplete', r['location'])
        self.u = User.objects.get(username=self.u.username)
        assert self.u.check_password(self.new_pw)

    def test_bad_old_password(self):
        r = self.client.post(self.url, {'old_password': '******',
                                        'new_password1': self.new_pw,
                                        'new_password2': self.new_pw})
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_('Your old password was entered incorrectly. Please enter it '
            'again.', doc('ul.errorlist').text())

    def test_new_pw_doesnt_match(self):
        r = self.client.post(self.url, {'old_password': '******',
                                        'new_password1': self.new_pw,
                                        'new_password2': self.new_pw + '1'})
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_("The two password fields didn't match. Your old password was "
            "entered incorrectly. Please enter it again.",
            doc('ul.errorlist').text())
Exemple #11
0
    def test_youtube_in_post(self):
        """Verify youtube video embedding."""
        u = UserFactory()
        t = ThreadFactory()

        self.client.login(username=u.username, password="******")
        response = post(
            self.client,
            "forums.reply",
            {"content": "[[V:http://www.youtube.com/watch?v=oHg5SJYRHA0]]"},
            args=[t.forum.slug, t.id],
        )

        doc = pq(response.content)
        assert doc("iframe")[0].attrib["src"].startswith("//www.youtube.com/embed/oHg5SJYRHA0")
Exemple #12
0
    def test_watch_thread(self):
        """Watch and unwatch a thread."""
        u = UserFactory()
        self.client.login(username=u.username, password='******')

        t = ThreadFactory()
        response = post(self.client,
                        'wiki.discuss.watch_thread', {'watch': 'yes'},
                        args=[t.document.slug, t.id])
        self.assertContains(response, 'Stop')

        response = post(self.client,
                        'wiki.discuss.watch_thread', {'watch': 'no'},
                        args=[t.document.slug, t.id])
        self.assertNotContains(response, 'Stop')
Exemple #13
0
    def test_helpfulness(self):
        u = UserFactory()
        p = u.profile
        a1 = AnswerFactory(creator=u)
        a2 = AnswerFactory(creator=u)

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

        serializer = api.ProfileSerializer(instance=p)
        eq_(serializer.data['helpfulness'], 3)
    def test_edit_thread_template(self):
        """The edit-post template should render."""
        u = UserFactory()
        self.client.login(username=u.username, password="******")

        t = ThreadFactory(creator=u, is_locked=False)
        p = t.new_post(creator=u, content="foo")
        res = get(
            self.client,
            "wiki.discuss.edit_post",
            args=[p.thread.document.slug, p.thread.id, p.id],
        )

        doc = pq(res.content)
        eq_(len(doc("form.edit-post")), 1)
 def test_all_locale_discussions(self):
     """Start or stop watching all discussions in a locale."""
     u = UserFactory()
     self.client.login(username=u.username, password="******")
     next_url = reverse("wiki.locale_discussions")
     # Watch locale.
     response = post(
         self.client, "wiki.discuss.watch_locale", {"watch": "yes", "next": next_url}
     )
     self.assertContains(response, "Stop watching this locale")
     # Stop watching locale.
     response = post(
         self.client, "wiki.discuss.watch_locale", {"watch": "no", "next": next_url}
     )
     self.assertContains(response, "Watch this locale")
    def test_watch_forum(self):
        """Watch and unwatch a forum."""
        u = UserFactory()
        self.client.login(username=u.username, password="******")

        d = DocumentFactory()
        response = post(
            self.client, "wiki.discuss.watch_forum", {"watch": "yes"}, args=[d.slug]
        )
        self.assertContains(response, "Stop")

        response = post(
            self.client, "wiki.discuss.watch_forum", {"watch": "no"}, args=[d.slug]
        )
        self.assertNotContains(response, "Stop")
    def test_notify_arbitrary(self):
        """Test that arbitrary users are notified of new answers."""
        watcher = UserFactory()
        QuestionReplyEvent.notify(watcher, self.question)
        self.makeAnswer()

        # One for the asker's email, and one for the watcher's email.
        eq_(2, len(mail.outbox))
        notification = [m for m in mail.outbox if m.to == [watcher.email]][0]

        eq_([watcher.email], notification.to)
        eq_(u'Re: {0}'.format(self.question.title), notification.subject)

        body = re.sub(r'auth=[a-zA-Z0-9%_-]+', 'auth=AUTH', notification.body)
        starts_with(body, ANSWER_EMAIL.format(to_user=display_name(watcher), **self.format_args()))
Exemple #18
0
    def setUp(self):
        # Set up some ignored users
        self.ignored_usernames = ['deanj', 'r1cky', 'mythmon']
        for username in self.ignored_usernames:
            TwitterAccountFactory(username=username, ignored=True)

        # Now a few normal users
        self.normal_usernames = ['willkg', 'marcell', 'ian']
        for username in self.normal_usernames:
            TwitterAccountFactory(username=username, ignored=False)

        # Create a user with permissions to ignore
        u = UserFactory()
        add_permission(u, TwitterAccount, 'ignore_account')
        self.client.login(username=u.username, password='******')
Exemple #19
0
    def test_watch_forum(self):
        """Watch and unwatch a forum."""
        u = UserFactory()
        self.client.login(username=u.username, password='******')

        d = DocumentFactory()
        response = post(self.client,
                        'wiki.discuss.watch_forum', {'watch': 'yes'},
                        args=[d.slug])
        self.assertContains(response, 'Stop')

        response = post(self.client,
                        'wiki.discuss.watch_forum', {'watch': 'no'},
                        args=[d.slug])
        self.assertNotContains(response, 'Stop')
Exemple #20
0
    def test_youtube_in_post(self):
        """Verify youtube video embedding."""
        u = UserFactory()
        t = ThreadFactory()

        self.client.login(username=u.username, password='******')
        response = post(
            self.client,
            'forums.reply',
            {'content': '[[V:http://www.youtube.com/watch?v=oHg5SJYRHA0]]'},
            args=[t.forum.slug, t.id])

        doc = pq(response.content)
        assert doc('iframe')[0].attrib['src'].startswith(
            '//www.youtube.com/embed/oHg5SJYRHA0')
Exemple #21
0
    def test_restricted_hide_reply(self):
        """Reply fields don't show if user has no permission to post."""
        t = ThreadFactory()
        f = t.forum
        ct = ContentType.objects.get_for_model(f)
        # If the forum has the permission and the user isn't assigned said
        # permission, then they can't post.
        PermissionFactory(codename='forums_forum.post_in_forum',
                          content_type=ct,
                          object_id=f.id)
        u = UserFactory()

        self.client.login(username=u.username, password='******')
        response = get(self.client, 'forums.posts', args=[f.slug, t.pk])
        self.assertNotContains(response, 'thread-reply')
Exemple #22
0
    def test_following_target(self):
        follower = UserFactory()
        q = QuestionFactory()
        ans = AnswerFactory(question=q)
        # The above might make follows, which this test isn't about. Clear them out.
        Follow.objects.all().delete()
        follow(follower, q, actor_only=False)

        # Make a new action for the above. This should trigger notifications.
        action.send(ans.creator, verb="answered", action_object=ans, target=q)
        act = Action.objects.order_by("-id")[0]
        notification = Notification.objects.get(action=act)

        eq_(notification.owner, follower)
        eq_(notification.action, act)
Exemple #23
0
    def test_new_thread_without_post_permission(self):
        """Making a new thread without post permission should 403."""
        rforum = RestrictedForumFactory(
            permission_code='forums_forum.post_in_forum')
        u = UserFactory()

        self.client.login(username=u.username, password='******')
        with patch.object(Forum, 'allows_viewing_by', Mock(return_value=True)):
            response = post(self.client,
                            'forums.new_thread', {
                                'title': 'Blahs',
                                'content': 'Blahs'
                            },
                            args=[rforum.slug])
        eq_(403, response.status_code)
Exemple #24
0
    def test_add_tags(self):
        q = QuestionFactory()
        eq_(0, q.tags.count())

        u = UserFactory()
        add_permission(u, Tag, "add_tag")
        self.client.force_authenticate(user=u)

        res = self.client.post(
            reverse("question-add-tags", args=[q.id]),
            content_type="application/json",
            data=json.dumps({"tags": ["test", "more", "tags"]}),
        )
        eq_(res.status_code, 200)
        eq_(3, q.tags.count())
Exemple #25
0
    def test_restricted_hide_new_thread(self):
        """'Post new thread' doesn't show if user has no permission to post.
        """
        f = ForumFactory()
        ct = ContentType.objects.get_for_model(f)
        # If the forum has the permission and the user isn't assigned said
        # permission, then they can't post.
        PermissionFactory(codename='forums_forum.post_in_forum',
                          content_type=ct,
                          object_id=f.id)
        u = UserFactory()

        self.client.login(username=u.username, password='******')
        response = get(self.client, 'forums.threads', args=[f.slug])
        self.assertNotContains(response, 'Post a new thread')
Exemple #26
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())
Exemple #27
0
 def test_locale_discussions_ignores_sticky(self):
     """Sticky flag is ignored in locale discussions view"""
     u = UserFactory()
     d = DocumentFactory()
     t = ThreadFactory(title="Sticky Thread", is_sticky=True, document=d)
     t.new_post(creator=u, content="foo")
     t2 = ThreadFactory(title="A thread with a very very long", is_sticky=False, document=d)
     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(".threads .title a:first").text()
     assert title.startswith("A thread with a very very long")
Exemple #28
0
    def test_num_questions(self):
        """Answers are counted correctly on a user."""
        u = UserFactory()
        eq_(num_questions(u), 0)

        q1 = QuestionFactory(creator=u)
        eq_(num_questions(u), 1)

        q2 = QuestionFactory(creator=u)
        eq_(num_questions(u), 2)

        q1.delete()
        eq_(num_questions(u), 1)

        q2.delete()
        eq_(num_questions(u), 0)
Exemple #29
0
 def test_email_changed_in_FxA_match_by_uid(self, message_mock):
     """Test that the user email is updated successfully if it
     is changed in Firefox Accounts and we match users by uid.
     """
     user = UserFactory.create(profile__fxa_uid='my_unique_fxa_id',
                               email='*****@*****.**',
                               profile__is_fxa_migrated=True)
     claims = {'uid': 'my_unique_fxa_id', 'email': '*****@*****.**'}
     request_mock = Mock(spec=HttpRequest)
     request_mock.session = {}
     self.backend.claims = claims
     self.backend.request = request_mock
     self.backend.update_user(user, claims)
     user = User.objects.get(id=user.id)
     eq_(user.email, '*****@*****.**')
     ok_(not message_mock.info.called)
Exemple #30
0
    def test_num_answers(self):
        u = UserFactory()
        q = QuestionFactory()
        eq_(num_answers(u), 0)

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

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

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

        a2.delete()
        eq_(num_answers(u), 0)
Exemple #31
0
    def test_deactivate_and_flag_spam(self):
        self.client.login(username=self.user.username, password='******')
        add_permission(self.user, Profile, 'deactivate_users')

        # Verify content is flagged as spam when requested.
        u = UserFactory()
        AnswerFactory(creator=u)
        QuestionFactory(creator=u)
        url = reverse('users.deactivate-spam', locale='en-US')
        res = self.client.post(url, {'user_id': u.id})

        eq_(302, res.status_code)
        eq_(1, Question.objects.filter(creator=u, is_spam=True).count())
        eq_(0, Question.objects.filter(creator=u, is_spam=False).count())
        eq_(1, Answer.objects.filter(creator=u, is_spam=True).count())
        eq_(0, Answer.objects.filter(creator=u, is_spam=False).count())
Exemple #32
0
 def test_create(self):
     q = QuestionFactory()
     u = UserFactory()
     self.client.force_authenticate(user=u)
     data = {
         'question': q.id,
         'content': 'You just need to click the fox.',
     }
     eq_(Answer.objects.count(), 0)
     res = self.client.post(reverse('answer-list'), data)
     eq_(res.status_code, 201)
     eq_(Answer.objects.count(), 1)
     a = Answer.objects.all()[0]
     eq_(a.content, data['content'])
     eq_(a.content_parsed, res.data['content'])
     eq_(a.question, q)
Exemple #33
0
    def test_empty_thread_errors(self):
        """Posting an empty thread shows errors."""
        f = ForumFactory()
        u = UserFactory()

        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.")
Exemple #34
0
    def test_watch_forum(self):
        """Watch and unwatch a forum."""
        f = ForumFactory()
        u = UserFactory()

        self.client.login(username=u.username, password="******")

        response = post(
            self.client, "forums.watch_forum", {"watch": "yes"}, args=[f.slug]
        )
        self.assertContains(response, "Stop watching this forum")

        response = post(
            self.client, "forums.watch_forum", {"watch": "no"}, args=[f.slug]
        )
        self.assertNotContains(response, "Stop watching this forum")
Exemple #35
0
 def setUp(self):
     self.user = UserFactory()
     self.product = ProductFactory()
     self.topic = TopicFactory(product=self.product)
     self.request = mock.Mock()
     self.request.user = self.user
     self.context = {
         'request': self.request,
     }
     self.data = {
         'creator': self.user.profile,
         'title': 'How do I test programs?',
         'content': "Help, I don't know what to do.",
         'product': self.product.slug,
         'topic': self.topic.slug,
     }
Exemple #36
0
    def test_change_user_with_patch(self):
        user = UserFactory()
        new_display_name = user.profile.name.upper()
        data = {
            'display_name': new_display_name,
            'locale': 'en-US',
            'username': user.username,
            'password': '******',
        }
        url = reverse('user-detail', args=[user.username])
        self.client.force_authenticate(user=user)
        res = self.client.patch(url, data)
        eq_(res.status_code, 200)

        user = User.objects.get(id=user.id)
        eq_(user.profile.display_name, new_display_name)
 def test_fire_on_new_thread(self, fire):
     """The event fires when there is a new thread."""
     d = DocumentFactory()
     u = UserFactory()
     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
Exemple #38
0
    def test_preview_async(self):
        """Preview a reply."""
        u = UserFactory()
        self.client.login(username=u.username, password="******")

        d = DocumentFactory()
        content = "Full of awesome."
        response = post(
            self.client,
            "wiki.discuss.post_preview_async",
            {"content": content},
            args=[d.slug],
        )
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_(content, doc("div.content").text())
Exemple #39
0
 def setUp(self):
     self.user = UserFactory()
     self.product = ProductFactory()
     self.topic = TopicFactory(product=self.product)
     self.request = mock.Mock()
     self.request.user = self.user
     self.context = {
         "request": self.request,
     }
     self.data = {
         "creator": self.user.profile,
         "title": "How do I test programs?",
         "content": "Help, I don't know what to do.",
         "product": self.product.slug,
         "topic": self.topic.slug,
     }
Exemple #40
0
    def test_watch_locale(self):
        """Watch and unwatch a locale."""
        u = UserFactory()
        self.client.login(username=u.username, password="******")

        d = DocumentFactory()
        next_url = reverse("wiki.discuss.threads", args=[d.slug])
        response = post(
            self.client, "wiki.discuss.watch_locale", {"watch": "yes", "next": next_url}
        )
        self.assertContains(response, "Turn off emails")

        response = post(
            self.client, "wiki.discuss.watch_locale", {"watch": "no", "next": next_url}
        )
        self.assertContains(response, "Get emailed when there is new discussion")
Exemple #41
0
    def test_send_message(self):
        to = UserFactory.create_batch(2)
        sender = UserFactory()
        msg_text = "hi there!"
        send_message(to=to, text=msg_text, sender=sender)

        msgs_in = InboxMessage.objects.all()
        msgs_out = OutboxMessage.objects.all()
        eq_(1, msgs_out.count())
        msg_out = msgs_out[0]
        eq_(sender, msg_out.sender)
        eq_(msg_text, msg_out.message)
        for u in msg_out.to.all():
            assert u in to
        eq_(2, msgs_in.count())
        for message in msgs_in:
            eq_(sender, message.sender)
            assert message.to in to
            eq_(msg_text, message.message)
Exemple #42
0
 def setUp(self):
     super(UploadImageTestCase, self).setUp()
     self.user = UserFactory(username='******')
     self.question = QuestionFactory()
     self.client.login(username=self.user.username, password='******')
Exemple #43
0
 def setUp(self):
     self.user = UserFactory()
     self.profile = self.user.profile
     self.userrl = reverse('users.profile', args=[self.user.username], locale='en-US')
     super(UserProfileTests, self).setUp()
Exemple #44
0
class ChangeEmailTestCase(TestCase):
    client_class = LocalizingClient

    def setUp(self):
        self.user = UserFactory()
        self.client.login(username=self.user.username, password='******')
        super(ChangeEmailTestCase, self).setUp()

    def test_redirect(self):
        """Test our redirect from old url to new one."""
        response = self.client.get(reverse('users.old_change_email',
                                           locale='en-US'), follow=False)
        eq_(301, response.status_code)
        eq_('http://testserver/en-US/users/change_email', response['location'])

    @mock.patch.object(Site.objects, 'get_current')
    def test_user_change_email(self, get_current):
        """Send email to change user's email and then change it."""
        get_current.return_value.domain = 'su.mo.com'

        # Attempt to change email.
        response = self.client.post(reverse('users.change_email'),
                                    {'email': '*****@*****.**'},
                                    follow=True)
        eq_(200, response.status_code)

        # Be notified to click a confirmation link.
        eq_(1, len(mail.outbox))
        assert mail.outbox[0].subject.find('Please confirm your') == 0
        ec = EmailChange.objects.all()[0]
        assert ec.activation_key in mail.outbox[0].body
        eq_('*****@*****.**', ec.email)

        # Visit confirmation link to change email.
        response = self.client.get(reverse('users.confirm_email',
                                           args=[ec.activation_key]))
        eq_(200, response.status_code)
        u = User.objects.get(username=self.user.username)
        eq_('*****@*****.**', u.email)

    def test_user_change_email_same(self):
        """Changing to same email shows validation error."""
        self.user.email = '*****@*****.**'
        self.user.save()
        response = self.client.post(reverse('users.change_email'),
                                    {'email': self.user.email})
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_('This is your current email.', doc('ul.errorlist').text())

    def test_user_change_email_duplicate(self):
        """Changing to same email shows validation error."""
        u = UserFactory(email='*****@*****.**')
        response = self.client.post(reverse('users.change_email'),
                                    {'email': u.email})
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_('A user with that email address already exists.',
            doc('ul.errorlist').text())

    @mock.patch.object(Site.objects, 'get_current')
    def test_user_confirm_email_duplicate(self, get_current):
        """If we detect a duplicate email when confirming an email change,
        don't change it and notify the user."""
        get_current.return_value.domain = 'su.mo.com'
        old_email = self.user.email
        new_email = '*****@*****.**'
        response = self.client.post(reverse('users.change_email'),
                                    {'email': new_email})
        eq_(200, response.status_code)
        assert mail.outbox[0].subject.find('Please confirm your') == 0
        ec = EmailChange.objects.all()[0]

        # Before new email is confirmed, give the same email to a user
        u = UserFactory(email=new_email)

        # Visit confirmation link and verify email wasn't changed.
        response = self.client.get(reverse('users.confirm_email',
                                           args=[ec.activation_key]))
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_(u'Unable to change email for user %s' % self.user.username,
            doc('article h1').text())
        u = User.objects.get(username=self.user.username)
        eq_(old_email, u.email)
Exemple #45
0
class UploadImageTestCase(TestCase):
    client_class = LocalizingClient

    def setUp(self):
        super(UploadImageTestCase, self).setUp()
        self.user = UserFactory(username='******')
        self.question = QuestionFactory()
        self.client.login(username=self.user.username, password='******')

    def tearDown(self):
        ImageAttachment.objects.all().delete()
        super(UploadImageTestCase, self).tearDown()

    def test_model_not_whitelisted(self):
        """Specifying a model we don't allow returns 400."""
        r = self._make_post_request(image='', args=['wiki.Document', 123])

        eq_(400, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Model not allowed.', json_r['message'])

    def test_object_notexist(self):
        """Upload nothing returns 404 error and html content."""
        r = self._make_post_request(image='', args=['questions.Question', 123])

        eq_(404, r.status_code)
        json_r = json.loads(r.content)
        eq_('error', json_r['status'])
        eq_('Object does not exist.', json_r['message'])

    def test_empty_image(self):
        """Upload nothing returns 400 error and json content."""
        r = self._make_post_request(image='')

        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_('You have not selected an image to upload.',
            json_r['errors']['image'][0])

    def test_upload_image(self):
        """Uploading an image works."""
        with open('kitsune/upload/tests/media/test.jpg') as f:
            r = self._make_post_request(image=f)

        eq_(200, r.status_code)
        json_r = json.loads(r.content)
        eq_('success', json_r['status'])
        file = json_r['file']
        eq_('test.png', file['name'])
        eq_(90, file['width'])
        eq_(120, file['height'])
        name = '098f6b.png'
        message = 'Url "%s" does not contain "%s"' % (file['url'], name)
        assert (name in file['url']), message

        eq_(1, ImageAttachment.objects.count())
        image = ImageAttachment.objects.all()[0]
        eq_(self.user.username, image.creator.username)
        eq_(150, image.file.width)
        eq_(200, image.file.height)
        eq_('question', image.content_type.model)

    def test_upload_unicode_image(self):
        """Uploading an unicode image works."""
        with open(u'kitsune/upload/tests/media/123ascii\u6709\u52b9.jpg', 'rb') as f:
            r = self._make_post_request(image=f)

        eq_(200, r.status_code)
        json_r = json.loads(r.content)
        eq_('success', json_r['status'])

    def test_delete_image_logged_out(self):
        """Can't delete an image logged out."""
        # Upload the image first
        self.test_upload_image()
        im = ImageAttachment.objects.all()[0]
        self.client.logout()
        r = self._make_post_request(args=[im.id])
        eq_(403, r.status_code)
        assert ImageAttachment.objects.exists()

    def test_delete_image_no_permission(self):
        """Can't delete an image without permission."""
        u = UserFactory(username='******')
        assert not u.has_perm('upload.delete_imageattachment')
        self.test_upload_image()
        im = ImageAttachment.objects.all()[0]
        self.client.login(username='******', password='******')
        r = self._make_post_request(args=[im.id])
        eq_(403, r.status_code)
        assert ImageAttachment.objects.exists()

    def test_delete_image_owner(self):
        """Users can delete their own images."""
        self.test_upload_image()
        im = ImageAttachment.objects.all()[0]
        r = self._make_post_request(args=[im.id])
        eq_(200, r.status_code)
        json_r = json.loads(r.content)
        eq_('success', json_r['status'])
        assert not ImageAttachment.objects.exists()

    def test_delete_image_with_permission(self):
        """Users with permission can delete images."""
        ct = ContentType.objects.get_for_model(ImageAttachment)
        p = Permission.objects.get_or_create(
            codename='delete_imageattachment',
            content_type=ct)[0]
        self.user.user_permissions.add(p)
        assert self.user.has_perm('upload.delete_imageattachment')

        self.test_upload_image()
        im = ImageAttachment.objects.all()[0]
        r = self._make_post_request(args=[im.id])
        eq_(200, r.status_code)
        json_r = json.loads(r.content)
        eq_('success', json_r['status'])
        assert not ImageAttachment.objects.exists()

    def test_delete_no_image(self):
        """Trying to delete a non-existent image 404s."""
        r = self._make_post_request(args=[123])
        eq_(404, r.status_code)
        data = json.loads(r.content)
        eq_('error', data['status'])

    def test_invalid_image(self):
        """Make sure invalid files are not accepted as images."""
        with open('kitsune/upload/__init__.py', 'rb') as f:
            r = self._make_post_request(image=f)

        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_('The submitted file is empty.', json_r['errors']['image'][0])

    def test_invalid_image_extensions(self):
        """
        Make sure invalid extensions aren't accepted as images.
        """
        with open('kitsune/upload/tests/media/test_invalid.ext', 'rb') as f:
            r = self._make_post_request(image=f)

        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'])
        assert (
            json_r['errors']['image'][0] ==
            "File extension 'ext' is not allowed. Allowed extensions are: 'jpg, jpeg, png, gif'.")

    def test_unsupported_image_extensions(self):
        """
        Make sure valid image types that are not whitelisted aren't accepted as images.
        """
        with open('kitsune/upload/tests/media/test.tiff', 'rb') as f:
            r = self._make_post_request(image=f)

        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'])
        assert (
            json_r['errors']['image'][0] ==
            "File extension 'tiff' is not allowed. Allowed extensions are: 'jpg, jpeg, png, gif'.")

    def test_upload_long_filename(self):
        """Uploading an image with a filename that's too long fails."""
        # Windows has problems with large file names, so we create the
        # file in the test and if this fails, we assume we're on a
        # Windows file system and skip.
        #
        # FIXME: Is that an ok assumption to make?

        thisdir = os.path.dirname(__file__)
        path = os.path.join(thisdir, 'media', 'test.jpg')
        with open(path) as f:
            long_file_name = ('long_file_name' * 17) + '.jpg'
            image = SimpleUploadedFile(name=long_file_name, content=f.read(),
                                       content_type='image/jpg')
            r = self._make_post_request(image=image)

        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': 242,
                              'max': settings.MAX_FILENAME_LENGTH},
            json_r['errors']['image'][0])

    def _make_post_request(self, **kwargs):
        if 'args' not in kwargs:
            kwargs['args'] = ['questions.Question', self.question.pk]
        if 'image' in kwargs:
            image = {'image': kwargs['image']}
        else:
            image = {}
        if len(kwargs['args']) == 2:
            view = 'upload.up_image_async'
        elif len(kwargs['args']) == 1:
            view = 'upload.del_image_async'
        else:
            raise ValueError
        return post(self.client, view, image, args=kwargs['args'])
Exemple #46
0
 def setUp(self):
     self.user = UserFactory()
     self.client.login(username=self.user.username, password='******')
     super(ChangeEmailTestCase, self).setUp()
Exemple #47
0
class LoginTests(TestCaseBase):
    """Login tests."""

    def setUp(self):
        super(LoginTests, self).setUp()
        self.u = UserFactory()

    def test_login_bad_password(self):
        '''Test login with a good username and bad password.'''
        response = post(self.client, 'users.login',
                        {'username': self.u.username, 'password': '******'})
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_('Please enter a correct username and password. Note that both '
            'fields are case-sensitive.', doc('ul.errorlist li').text())

    def test_login_bad_username(self):
        '''Test login with a bad username.'''
        response = post(self.client, 'users.login',
                        {'username': '******', 'password': '******'})
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_('Please enter a correct username and password. Note that both '
            'fields are case-sensitive.', doc('ul.errorlist li').text())

    def test_login_password_disabled(self):
        """Test logging in as a user with PASSWORD_DISABLED doesn't 500."""
        self.u.set_unusable_password()
        self.u.save()
        response = self.client.post(reverse('users.login'),
                                    {'username': self.u.username,
                                     'password': '******'})
        eq_(200, response.status_code)

    def test_login(self):
        '''Test a valid login.'''
        response = self.client.post(reverse('users.login'),
                                    {'username': self.u.username,
                                     'password': '******'})
        eq_(302, response.status_code)
        eq_(reverse('home', locale=settings.LANGUAGE_CODE) + '?fpa=1',
            response['location'])

    def test_login_next_parameter(self):
        '''Test with a valid ?next=url parameter.'''
        next = '/kb/new'

        # Verify that next parameter is set in form hidden field.
        response = self.client.get(
            urlparams(reverse('users.login'), next=next), follow=True)
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_(next, doc('#login input[name="next"]')[0].attrib['value'])

        # Verify that it gets used on form POST.
        response = self.client.post(reverse('users.login'),
                                    {'username': self.u.username,
                                     'password': '******',
                                     'next': next})
        eq_(302, response.status_code)
        eq_(next + '?fpa=1', response['location'])

    def test_login_invalid_next_parameter(self):
        '''Test with an invalid ?next=http://example.com parameter.'''
        invalid_next = 'http://foobar.com/evil/'
        valid_next = reverse('home', locale=settings.LANGUAGE_CODE)

        # Verify that _valid_ next parameter is set in form hidden field.
        url = urlparams(reverse('users.login'), next=invalid_next)
        response = self.client.get(url, follow=True)
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_(valid_next, doc('#login input[name="next"]')[0].attrib['value'])

        # Verify that it gets used on form POST.
        response = self.client.post(reverse('users.login'),
                                    {'username': self.u.username,
                                     'password': '******',
                                     'next': invalid_next})
        eq_(302, response.status_code)
        eq_(valid_next + '?fpa=1', response['location'])

    def test_login_mobile_csrf(self):
        """The mobile login view should have a CSRF token."""
        response = self.client.get(reverse('users.login'), {'mobile': 1})
        eq_(200, response.status_code)
        doc = pq(response.content)
        assert doc('#content form input[name="csrfmiddlewaretoken"]')
Exemple #48
0
 def setUp(self):
     super(HelperTestCase, self).setUp()
     self.u = UserFactory()
Exemple #49
0
class TestQuestionUpdates(TestCaseBase):
    """Tests that questions are only updated in the right cases."""
    client_class = LocalizingClient

    date_format = '%Y%M%d%H%m%S'

    def setUp(self):
        super(TestQuestionUpdates, self).setUp()
        self.u = UserFactory(is_superuser=True)
        self.client.login(username=self.u.username, password='******')

        self.q = QuestionFactory(updated=datetime(2012, 7, 9, 9, 0, 0))
        self.a = AnswerFactory(question=self.q)

        # Get the question from the database so we have a consistent level of
        # precision during the test.
        self.q = Question.objects.get(pk=self.q.id)

    def tearDown(self):
        self.client.logout()
        self.u.delete()
        self.q.delete()

    def _request_and_no_update(self, url, req_type='POST', data={}):
        updated = self.q.updated

        if req_type == 'POST':
            self.client.post(url, data, follow=True)
        elif req_type == 'GET':
            self.client.get(url, data, follow=True)
        else:
            raise ValueError('req_type must be either "GET" or "POST"')

        self.q = Question.objects.get(pk=self.q.id)
        eq_(updated.strftime(self.date_format),
            self.q.updated.strftime(self.date_format))

    def test_no_update_edit(self):
        url = urlparams(reverse('questions.edit_question', args=[self.q.id]))
        self._request_and_no_update(url, req_type='POST', data={
            'title': 'A new title.',
            'content': 'Some new content.'
        })

    def test_no_update_solve(self):
        url = urlparams(reverse('questions.solve',
                        args=[self.q.id, self.a.id]))
        self._request_and_no_update(url)

    def test_no_update_unsolve(self):
        url = urlparams(reverse('questions.unsolve',
                                args=[self.q.id, self.a.id]))
        self._request_and_no_update(url)

    def test_no_update_vote(self):
        url = urlparams(reverse('questions.vote', args=[self.q.id]))
        self._request_and_no_update(url, req_type='POST')

    def test_no_update_lock(self):
        url = urlparams(reverse('questions.lock', args=[self.q.id]))
        self._request_and_no_update(url, req_type='POST')
        # Now unlock
        self._request_and_no_update(url, req_type='POST')

    def test_no_update_tagging(self):
        url = urlparams(reverse('questions.add_tag', args=[self.q.id]))
        self._request_and_no_update(url, req_type='POST', data={
            'tag-name': 'foo'
        })

        url = urlparams(reverse('questions.remove_tag', args=[self.q.id]))
        self._request_and_no_update(url, req_type='POST', data={
            'remove-tag-foo': 1
        })
Exemple #50
0
class PasswordResetTests(TestCaseBase):

    def setUp(self):
        super(PasswordResetTests, self).setUp()
        self.u = UserFactory(email="*****@*****.**")
        self.uidb36 = int_to_base36(self.u.id)
        self.token = default_token_generator.make_token(self.u)
        self.orig_debug = settings.DEBUG
        settings.DEBUG = True

    def tearDown(self):
        super(PasswordResetTests, self).tearDown()
        settings.DEBUG = self.orig_debug

    def test_bad_email(self):
        r = self.client.post(reverse('users.pw_reset'),
                             {'email': '*****@*****.**'})
        eq_(302, r.status_code)
        eq_('http://testserver/en-US/users/pwresetsent', r['location'])
        eq_(0, len(mail.outbox))

    @mock.patch.object(Site.objects, 'get_current')
    def test_success(self, get_current):
        get_current.return_value.domain = 'testserver.com'
        r = self.client.post(reverse('users.pw_reset'),
                             {'email': self.u.email})
        eq_(302, r.status_code)
        eq_('http://testserver/en-US/users/pwresetsent', r['location'])
        eq_(1, len(mail.outbox))
        assert mail.outbox[0].subject.find('Password reset') == 0
        assert mail.outbox[0].body.find('pwreset/%s' % self.uidb36) > 0

    @mock.patch.object(PasswordResetForm, 'save')
    def test_smtp_error(self, pwform_save):
        def raise_smtp(*a, **kw):
            raise SMTPRecipientsRefused(recipients=[self.u.email])
        pwform_save.side_effect = raise_smtp
        r = self.client.post(reverse('users.pw_reset'),
                             {'email': self.u.email})
        self.assertContains(r, unicode(ERROR_SEND_EMAIL))

    def _get_reset_url(self):
        return reverse('users.pw_reset_confirm',
                       args=[self.uidb36, self.token])

    def test_bad_reset_url(self):
        r = self.client.get('/users/pwreset/junk/', follow=True)
        eq_(r.status_code, 404)

        r = self.client.get(reverse('users.pw_reset_confirm',
                                    args=[self.uidb36, '12-345']))
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_('Password reset unsuccessful', doc('article h1').text())

    def test_reset_fail(self):
        url = self._get_reset_url()
        r = self.client.post(url, {'new_password1': '', 'new_password2': ''})
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_(1, len(doc('ul.errorlist')))

        r = self.client.post(url, {'new_password1': 'onetwo12',
                                   'new_password2': 'twotwo22'})
        eq_(200, r.status_code)
        doc = pq(r.content)
        eq_("The two password fields didn't match.",
            doc('ul.errorlist li').text())

    def test_reset_success(self):
        url = self._get_reset_url()
        new_pw = 'fjdka387fvstrongpassword!'
        assert self.u.check_password(new_pw) is False

        r = self.client.post(url, {'new_password1': new_pw,
                                   'new_password2': new_pw})
        eq_(302, r.status_code)
        eq_('http://testserver/en-US/users/pwresetcomplete', r['location'])
        self.u = User.objects.get(username=self.u.username)
        assert self.u.check_password(new_pw)

    def test_reset_user_with_unusable_password(self):
        """Verify that user's with unusable passwords can reset them."""
        self.u.set_unusable_password()
        self.u.save()
        self.test_success()
Exemple #51
0
class HelperTestCase(TestCase):
    def setUp(self):
        super(HelperTestCase, self).setUp()
        self.u = UserFactory()

    def test_profile_url(self):
        eq_(u"/user/%s" % self.u.username, profile_url(self.u))

    def test_profile_avatar_default(self):
        email_hash = hashlib.md5(self.u.email.lower()).hexdigest()
        gravatar_url = "https://secure.gravatar.com/avatar/%s?s=48" % (email_hash)
        assert profile_avatar(self.u).startswith(gravatar_url)

    def test_profile_avatar_anonymous(self):
        email_hash = "00000000000000000000000000000000"
        gravatar_url = "https://secure.gravatar.com/avatar/%s?s=48" % (email_hash)
        assert profile_avatar(AnonymousUser()).startswith(gravatar_url)

    def test_profile_avatar(self):
        self.u.profile.avatar = "images/foo.png"
        self.u.profile.save()
        email_hash = hashlib.md5(self.u.email.lower()).hexdigest()
        gravatar_url = "https://secure.gravatar.com/avatar/%s?s=48" % (email_hash)
        assert profile_avatar(self.u).startswith(gravatar_url)

    def test_profile_avatar_unicode(self):
        self.u.email = u"rá[email protected]"
        self.u.save()
        gravatar_url = "https://secure.gravatar.com/"
        assert profile_avatar(self.u).startswith(gravatar_url)

    def test_public_email(self):
        eq_(
            u'<span class="email">'
            u"&#109;&#101;&#64;&#100;&#111;&#109;&#97;&#105;&#110;&#46;&#99;"
            u"&#111;&#109;</span>",
            public_email("*****@*****.**"),
        )
        eq_(
            u'<span class="email">' u"&#110;&#111;&#116;&#46;&#97;&#110;&#46;&#101;&#109;&#97;&#105;" u"&#108;</span>",
            public_email("not.an.email"),
        )

    def test_display_name(self):
        eq_(self.u.profile.name, display_name(self.u))
        self.u.profile.name = u"Test User"
        self.u.profile.save()
        eq_(u"Test User", display_name(self.u))

    def test_display_name_anonymous(self):
        eq_(u"", display_name(AnonymousUser()))

    def test_user_list(self):
        UserFactory(username="******")
        UserFactory(username="******")
        users = User.objects.all()
        list = user_list(users)
        assert isinstance(list, Markup)
        fragment = pq(list)
        eq_(len(users), len(fragment("a")))
        a = fragment("a")[1]
        assert a.attrib["href"].endswith(str(users[1].username))
        eq_(users[1].username, a.text)
Exemple #52
0
 def setUp(self):
     super(PasswordChangeTests, self).setUp()
     self.u = UserFactory()
     self.url = reverse('users.pw_change')
     self.new_pw = 'fjdka387fvstrongpassword!'
     self.client.login(username=self.u.username, password='******')
Exemple #53
0
class UserProfileTests(TestCase):
    def setUp(self):
        self.user = UserFactory()
        self.profile = self.user.profile
        self.userrl = reverse('users.profile', args=[self.user.username], locale='en-US')
        super(UserProfileTests, self).setUp()

    def test_ProfileFactory(self):
        res = self.client.get(self.userrl)
        self.assertContains(res, self.user.username)

    def test_profile_redirect(self):
        """Ensure that old profile URL's get redirected."""
        res = self.client.get(reverse('users.profile', args=[self.user.pk],
                                      locale='en-US'))
        eq_(302, res.status_code)

    def test_profile_inactive(self):
        """Inactive users don't have a public profile."""
        self.user.is_active = False
        self.user.save()
        res = self.client.get(self.userrl)
        eq_(404, res.status_code)

    def test_profile_post(self):
        res = self.client.post(self.userrl)
        eq_(405, res.status_code)

    def test_profile_deactivate(self):
        """Test user deactivation"""
        p = UserFactory().profile

        self.client.login(username=self.user.username, password='******')
        res = self.client.post(reverse('users.deactivate', locale='en-US'), {'user_id': p.user.id})

        eq_(403, res.status_code)

        add_permission(self.user, Profile, 'deactivate_users')
        res = self.client.post(reverse('users.deactivate', locale='en-US'), {'user_id': p.user.id})

        eq_(302, res.status_code)

        log = Deactivation.objects.get(user_id=p.user_id)
        eq_(log.moderator_id, self.user.id)

        p = Profile.objects.get(user_id=p.user_id)
        assert not p.user.is_active

    def test_deactivate_and_flag_spam(self):
        self.client.login(username=self.user.username, password='******')
        add_permission(self.user, Profile, 'deactivate_users')

        # Verify content is flagged as spam when requested.
        u = UserFactory()
        AnswerFactory(creator=u)
        QuestionFactory(creator=u)
        url = reverse('users.deactivate-spam', locale='en-US')
        res = self.client.post(url, {'user_id': u.id})

        eq_(302, res.status_code)
        eq_(1, Question.objects.filter(creator=u, is_spam=True).count())
        eq_(0, Question.objects.filter(creator=u, is_spam=False).count())
        eq_(1, Answer.objects.filter(creator=u, is_spam=True).count())
        eq_(0, Answer.objects.filter(creator=u, is_spam=False).count())
Exemple #54
0
class HelperTestCase(TestCase):
    def setUp(self):
        super(HelperTestCase, self).setUp()
        self.u = UserFactory()

    def test_profile_url(self):
        eq_(u'/user/%s' % self.u.username, profile_url(self.u))

    def test_profile_avatar_default(self):
        email_hash = hashlib.md5(self.u.email.lower()).hexdigest()
        gravatar_url = 'https://secure.gravatar.com/avatar/%s?s=48' % (
            email_hash)
        assert profile_avatar(self.u).startswith(gravatar_url)

    def test_profile_avatar_anonymous(self):
        email_hash = '00000000000000000000000000000000'
        gravatar_url = 'https://secure.gravatar.com/avatar/%s?s=48' % (
            email_hash)
        assert profile_avatar(AnonymousUser()).startswith(gravatar_url)

    def test_profile_avatar(self):
        self.u.profile.avatar = 'images/foo.png'
        self.u.profile.save()
        email_hash = hashlib.md5(self.u.email.lower()).hexdigest()
        gravatar_url = 'https://secure.gravatar.com/avatar/%s?s=48' % (
            email_hash)
        assert profile_avatar(self.u).startswith(gravatar_url)

    def test_profile_avatar_unicode(self):
        self.u.email = u'rá[email protected]'
        self.u.save()
        gravatar_url = 'https://secure.gravatar.com/'
        assert profile_avatar(self.u).startswith(gravatar_url)

    def test_public_email(self):
        eq_(u'<span class="email">'
            u'&#109;&#101;&#64;&#100;&#111;&#109;&#97;&#105;&#110;&#46;&#99;'
            u'&#111;&#109;</span>', public_email('*****@*****.**'))
        eq_(u'<span class="email">'
            u'&#110;&#111;&#116;&#46;&#97;&#110;&#46;&#101;&#109;&#97;&#105;'
            u'&#108;</span>', public_email('not.an.email'))

    def test_display_name(self):
        eq_(self.u.profile.name, display_name(self.u))
        self.u.profile.name = u'Test User'
        self.u.profile.save()
        eq_(u'Test User', display_name(self.u))

    def test_display_name_anonymous(self):
        eq_(u'', display_name(AnonymousUser()))

    def test_user_list(self):
        UserFactory(username='******')
        UserFactory(username='******')
        users = User.objects.all()
        list = user_list(users)
        assert isinstance(list, Markup)
        fragment = pq(list)
        eq_(len(users), len(fragment('a')))
        a = fragment('a')[1]
        assert a.attrib['href'].endswith(str(users[1].username))
        eq_(users[1].username, a.text)
Exemple #55
0
 def setUp(self):
     super(LoginTests, self).setUp()
     self.u = UserFactory()
Exemple #56
0
class LoginTests(TestCaseBase):
    """Login tests."""

    def setUp(self):
        super(LoginTests, self).setUp()
        self.u = UserFactory()

    def test_login_bad_password(self):
        '''Test login with a good username and bad password.'''
        response = post(self.client, 'users.login',
                        {'username': self.u.username, 'password': '******'})
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_('Please enter a correct username and password. Note that both '
            'fields are case-sensitive.', doc('ul.errorlist li').text())

    def test_login_bad_username(self):
        '''Test login with a bad username.'''
        response = post(self.client, 'users.login',
                        {'username': '******', 'password': '******'})
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_('Please enter a correct username and password. Note that both '
            'fields are case-sensitive.', doc('ul.errorlist li').text())

    def test_login_password_disabled(self):
        """Test logging in as a user with PASSWORD_DISABLED doesn't 500."""
        self.u.set_unusable_password()
        self.u.save()
        response = self.client.post(reverse('users.login'),
                                    {'username': self.u.username,
                                     'password': '******'})
        eq_(200, response.status_code)

    def test_login(self):
        '''Test a valid login.'''
        response = self.client.post(reverse('users.login'),
                                    {'username': self.u.username,
                                     'password': '******'})
        eq_(302, response.status_code)
        eq_('http://testserver' +
            reverse('home', locale=settings.LANGUAGE_CODE) + '?fpa=1',
            response['location'])

    def test_login_next_parameter(self):
        '''Test with a valid ?next=url parameter.'''
        next = '/kb/new'

        # Verify that next parameter is set in form hidden field.
        response = self.client.get(
            urlparams(reverse('users.login'), next=next), follow=True)
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_(next, doc('#login input[name="next"]')[0].attrib['value'])

        # Verify that it gets used on form POST.
        response = self.client.post(reverse('users.login'),
                                    {'username': self.u.username,
                                     'password': '******',
                                     'next': next})
        eq_(302, response.status_code)
        eq_('http://testserver' + next + '?fpa=1', response['location'])

    @mock.patch.object(Site.objects, 'get_current')
    def test_login_invalid_next_parameter(self, get_current):
        '''Test with an invalid ?next=http://example.com parameter.'''
        get_current.return_value.domain = 'testserver.com'
        invalid_next = 'http://foobar.com/evil/'
        valid_next = reverse('home', locale=settings.LANGUAGE_CODE)

        # Verify that _valid_ next parameter is set in form hidden field.
        url = urlparams(reverse('users.login'), next=invalid_next)
        response = self.client.get(url, follow=True)
        eq_(200, response.status_code)
        doc = pq(response.content)
        eq_(valid_next, doc('#login input[name="next"]')[0].attrib['value'])

        # Verify that it gets used on form POST.
        response = self.client.post(reverse('users.login'),
                                    {'username': self.u.username,
                                     'password': '******',
                                     'next': invalid_next})
        eq_(302, response.status_code)
        eq_('http://testserver' + valid_next + '?fpa=1', response['location'])

    def test_ga_custom_variable_on_registered_login(self):
        """After logging in, there should be a ga-push data attr on body."""
        user_ = UserFactory()

        # User should be "Registered":
        response = self.client.post(reverse('users.login'),
                                    {'username': user_.username,
                                     'password': '******'},
                                    follow=True)
        eq_(200, response.status_code)
        doc = pq(response.content)
        assert '"Registered"' in doc('body').attr('data-ga-push')

    def test_ga_custom_variable_on_contributor_login(self):
        """After logging in, there should be a ga-push data attr on body."""
        user_ = UserFactory()

        # Add user to Contributors and so should be "Contributor":
        user_.groups.add(GroupFactory(name='Contributors'))
        response = self.client.post(reverse('users.login'),
                                    {'username': user_.username,
                                     'password': '******'},
                                    follow=True)
        eq_(200, response.status_code)
        doc = pq(response.content)
        assert '"Contributor"' in doc('body').attr('data-ga-push')

    def test_ga_custom_variable_on_admin_login(self):
        """After logging in, there should be a ga-push data attr on body."""
        user_ = UserFactory()

        # Add user to Administrators and so should be "Contributor - Admin":
        user_.groups.add(GroupFactory(name='Administrators'))
        response = self.client.post(reverse('users.login'),
                                    {'username': user_.username,
                                     'password': '******'},
                                    follow=True)
        eq_(200, response.status_code)
        doc = pq(response.content)
        assert '"Contributor - Admin"' in doc('body').attr('data-ga-push')

    def test_login_mobile_csrf(self):
        """The mobile login view should have a CSRF token."""
        response = self.client.get(reverse('users.login'), {'mobile': 1})
        eq_(200, response.status_code)
        doc = pq(response.content)
        assert doc('#content form input[name="csrfmiddlewaretoken"]')