Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions accounts/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
13 changes: 3 additions & 10 deletions accounts/forms.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
from django import forms

from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django import forms


class SignUpForm(UserCreationForm):
email = forms.CharField(max_length=254, required=True, widget=forms.EmailInput())

class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2')


class UserInformationUpdateForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = User
fields = ('first_name', 'last_name', 'email', )
fields = ('username','email','password1','password2')
Empty file added accounts/test/__init__.py
Empty file.
10 changes: 10 additions & 0 deletions accounts/test/test_form_signup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

from django.test import TestCase
from ..forms import SignUpForm

class SignUpFormTest(TestCase):
def test_form_has_fields(self):
form = SignUpForm()
expected = ['username', 'email', 'password1', 'password2',]
actual = list(form.fields)
self.assertSequenceEqual(expected, actual)
29 changes: 29 additions & 0 deletions accounts/test/test_mail_password_reset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

from django.core import mail
from django.contrib.auth.models import User
from django.urls import reverse
from django.test import TestCase

class PasswordResetMailTests(TestCase):
def setUp(self):
User.objects.create_user(username='john', email='[email protected]', password='123')
self.response = self.client.post(reverse('password_reset'), { 'email': '[email protected]' })
self.email = mail.outbox[0]

def test_email_subject(self):
self.assertEqual('[Django Boards] Please reset your password', self.email.subject)

def test_email_body(self):
context = self.response.context
token = context.get('token')
uid = context.get('uid')
password_reset_token_url = reverse('password_reset_confirm', kwargs={
'uidb64': uid,
'token': token
})
self.assertIn(password_reset_token_url, self.email.body)
self.assertIn('john', self.email.body)
self.assertIn('[email protected]', self.email.body)

def test_email_to(self):
self.assertEqual(['[email protected]',], self.email.to)
109 changes: 109 additions & 0 deletions accounts/test/test_view_password_change.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth.models import User
from django.contrib.auth import views as auth_views
from django.urls import resolve, reverse
from django.test import TestCase


class PasswordChangeTests(TestCase):
def setUp(self):
username = 'john'
password = 'secret123'
user = User.objects.create_user(username=username, email='[email protected]', password=password)
url = reverse('password_change')
self.client.login(username=username, password=password)
self.response = self.client.get(url)

def test_status_code(self):
self.assertEquals(self.response.status_code, 200)

def test_url_resolves_correct_view(self):
view = resolve('/settings/password/')
self.assertEquals(view.func.view_class, auth_views.PasswordChangeView)

def test_csrf(self):
self.assertContains(self.response, 'csrfmiddlewaretoken')

def test_contains_form(self):
form = self.response.context.get('form')
self.assertIsInstance(form, PasswordChangeForm)

def test_form_inputs(self):
'''
The view must contain four inputs: csrf, old_password, new_password1, new_password2
'''
self.assertContains(self.response, '<input', 4)
self.assertContains(self.response, 'type="password"', 3)


class LoginRequiredPasswordChangeTests(TestCase):
def test_redirection(self):
url = reverse('password_change')
login_url = reverse('login')
response = self.client.get(url)
#self.assertRedirects(response, f'{login_url}?next={url}')
self.assertRedirects(response,'{login_url}?next={url}'.format(login_url=login_url, url=url))


class PasswordChangeTestCase(TestCase):
'''
Base test case for form processing
accepts a `data` dict to POST to the view.
'''
def setUp(self, data={}):
self.user = User.objects.create_user(username='john', email='[email protected]', password='old_password')
self.url = reverse('password_change')
self.client.login(username='john', password='old_password')
self.response = self.client.post(self.url, data)


class SuccessfulPasswordChangeTests(PasswordChangeTestCase):
def setUp(self):
super().setUp({
'old_password': 'old_password',
'new_password1': 'new_password',
'new_password2': 'new_password',
})

def test_redirection(self):
'''
A valid form submission should redirect the user
'''
self.assertRedirects(self.response, reverse('password_change_done'))

def test_password_changed(self):
'''
refresh the user instance from database to get the new password
hash updated by the change password view.
'''
self.user.refresh_from_db()
self.assertTrue(self.user.check_password('new_password'))

def test_user_authentication(self):
'''
Create a new request to an arbitrary page.
The resulting response should now have an `user` to its context, after a successful sign up.
'''
response = self.client.get(reverse('home'))
user = response.context.get('user')
self.assertTrue(user.is_authenticated)


class InvalidPasswordChangeTests(PasswordChangeTestCase):
def test_status_code(self):
'''
An invalid form submission should return to the same page
'''
self.assertEquals(self.response.status_code, 200)

def test_form_errors(self):
form = self.response.context.get('form')
self.assertTrue(form.errors)

def test_didnt_change_password(self):
'''
refresh the user instance from the database to make
sure we have the latest data.
'''
self.user.refresh_from_db()
self.assertTrue(self.user.check_password('old_password'))
154 changes: 154 additions & 0 deletions accounts/test/test_view_password_reset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@

from django.contrib.auth import views as auth_views
from django.contrib.auth.forms import PasswordResetForm, SetPasswordForm
from django.contrib.auth.models import User
from django.core import mail
from django.urls import resolve,reverse
from django.test import TestCase

from django.contrib.auth.tokens import default_token_generator
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode

class PasswordResetTests(TestCase):
def setUp(self):
url = reverse('password_reset')
self.response = self.client.get(url)

def test_status_code(self):
self.assertEquals(self.response.status_code, 200)

def test_view_function(self):
view = resolve('/reset/')
self.assertEquals(view.func.view_class, auth_views.PasswordResetView)

def test_csrf(self):
self.assertContains(self.response, 'csrfmiddlewaretoken')

def test_contains_form(self):
form = self.response.context.get('form')
self.assertIsInstance(form, PasswordResetForm)

def test_form_inputs(self):
'''
The view must contain two inputs: csrf and email
'''
self.assertContains(self.response, '<input', 2)
self.assertContains(self.response, 'type="email"', 1)

class SuccessfulPasswordResetTests(TestCase):
def setUp(self):
email = '[email protected]'
User.objects.create_user(username='john', email=email, password='123abcdef')
url = reverse('password_reset')
self.response = self.client.post(url, {'email': email})

def test_redirection(self):
'''
A valid form submission should redirect the user to `password_reset_done` view
'''
url = reverse('password_reset_done')
self.assertRedirects(self.response, url)

def test_send_password_reset_email(self):
self.assertEqual(1, len(mail.outbox))

class InvalidPasswordResetTests(TestCase):
def setUp(self):
url = reverse('password_reset')
self.response = self.client.post(url, {'email': '[email protected]'})

def test_redirection(self):
'''
Even invalid emails in the database should
redirect the user to `password_reset_done` view
'''
url = reverse('password_reset_done')
self.assertRedirects(self.response, url)

def test_no_reset_email_sent(self):
self.assertEqual(0, len(mail.outbox))

class PasswordResetDoneTests(TestCase):
def setUp(self):
url = reverse('password_reset_done')
self.response = self.client.get(url)

def test_status_code(self):
self.assertEquals(self.response.status_code, 200)

def test_view_function(self):
view = resolve('/reset/done/')
self.assertEquals(view.func.view_class, auth_views.PasswordResetDoneView)


class PasswordResetConfirmTests(TestCase):
def setUp(self):
user = User.objects.create_user(username='john', email='[email protected]', password='123abcdef')

'''
create a valid password reset token
based on how django creates the token internally:
https://github.com/django/django/blob/1.11.5/django/contrib/auth/forms.py#L280
'''
self.uid = urlsafe_base64_encode(force_bytes(user.pk))
self.token = default_token_generator.make_token(user)

url = reverse('password_reset_confirm', kwargs={'uidb64': self.uid, 'token': self.token})
self.response = self.client.get(url, follow=True)

def test_status_code(self):
self.assertEquals(self.response.status_code, 200)

def test_view_function(self):
view = resolve('/reset/{uidb64}/{token}/'.format(uidb64=self.uid, token=self.token))
self.assertEquals(view.func.view_class, auth_views.PasswordResetConfirmView)

def test_csrf(self):
self.assertContains(self.response, 'csrfmiddlewaretoken')

def test_contains_form(self):
form = self.response.context.get('form')
self.assertIsInstance(form, SetPasswordForm)

def test_form_inputs(self):
'''
The view must contain two inputs: csrf and two password fields
'''
self.assertContains(self.response, '<input', 3)
self.assertContains(self.response, 'type="password"', 2)

class InvalidPasswordResetConfirmTests(TestCase):
def setUp(self):
user = User.objects.create_user(username='john', email='[email protected]', password='123abcdef')
uid = urlsafe_base64_encode(force_bytes(user.pk))
token = default_token_generator.make_token(user)

'''
invalidate the token by changing the password
'''
user.set_password('abcdef123')
user.save()

url = reverse('password_reset_confirm', kwargs={'uidb64': uid, 'token': token})
self.response = self.client.get(url)

def test_status_code(self):
self.assertEquals(self.response.status_code, 200)

def test_html(self):
password_reset_url = reverse('password_reset')
self.assertContains(self.response, 'invalid password reset link')
self.assertContains(self.response, 'href="{0}"'.format(password_reset_url))

class PasswordResetCompleteTests(TestCase):
def setUp(self):
url = reverse('password_reset_complete')
self.response = self.client.get(url)

def test_status_code(self):
self.assertEquals(self.response.status_code, 200)

def test_view_function(self):
view = resolve('/reset/complete/')
self.assertEquals(view.func.view_class, auth_views.PasswordResetCompleteView)
Loading