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) def test_bad_email(self): r = self.client.post(reverse('users.pw_reset'), {'email': '*****@*****.**'}) eq_(302, r.status_code) eq_('/en-US/users/pwresetsent', r['location']) eq_(0, len(mail.outbox)) def test_success(self): r = self.client.post(reverse('users.pw_reset'), {'email': self.u.email}) eq_(302, r.status_code) eq_('/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_('/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 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"]')
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"]')
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 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"]')
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"]')
class LoginTests(TestCaseBase): """Login tests.""" def setUp(self): super(LoginTests, self).setUp() self.u = UserFactory() self.profile_url = reverse('users.profile', args=[self.u.username], locale=settings.LANGUAGE_CODE) + '?fpa=1' 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_(self.profile_url, response['location']) def test_login_next_parameter(self): '''Test with a valid ?next=url parameter.''' next = self.profile_url # 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, 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_(self.profile_url, response['location']) def test_fxa_deprecation_warning(self): """ Test that a SUMO login shows FXA deprecation warning """ response = self.client.post(reverse('users.login'), { 'username': self.u.username, 'password': '******' }, follow=True) doc = pq(response.content) eq_(1, len(doc('#fxa-notification-deprecated')))