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 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
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'])
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 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
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 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)
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')
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'])
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())
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")
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')
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()))
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='******')
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_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')
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')
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)
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)
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())
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')
def test_delete_answer_removes_flag(self): """Deleting an answer also removes the flags on that answer.""" q = QuestionFactory(title='Test Question', content='Lorem Ipsum Dolor') a = AnswerFactory(question=q, content='Test Answer') u = UserFactory() FlaggedObject.objects.create(status=0, content_object=a, reason='language', creator_id=u.id) eq_(1, FlaggedObject.objects.count()) a.delete() eq_(0, FlaggedObject.objects.count())
def test_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")
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)
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)
def test_num_answers(self): u = UserFactory() q = QuestionFactory() eq_(num_answers(u), 0) a1 = AnswerFactory(creator=u, question=q) eq_(num_answers(u), 1) a2 = AnswerFactory(creator=u, question=q) eq_(num_answers(u), 2) a1.delete() eq_(num_answers(u), 1) a2.delete() eq_(num_answers(u), 0)
def 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())
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)
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.")
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")
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, }
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
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())
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, }
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")
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)
def setUp(self): super(UploadImageTestCase, self).setUp() self.user = UserFactory(username='******') self.question = QuestionFactory() self.client.login(username=self.user.username, password='******')
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()
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)
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'])
def setUp(self): self.user = UserFactory() self.client.login(username=self.user.username, password='******') super(ChangeEmailTestCase, self).setUp()
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"]')
def setUp(self): super(HelperTestCase, self).setUp() self.u = UserFactory()
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 })
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()
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"me@domain.c" u"om</span>", public_email("*****@*****.**"), ) eq_( u'<span class="email">' u"not.an.emai" u"l</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)
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='******')
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())
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'me@domain.c' u'om</span>', public_email('*****@*****.**')) eq_(u'<span class="email">' u'not.an.emai' u'l</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)
def setUp(self): super(LoginTests, self).setUp() self.u = UserFactory()
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"]')