From 1979d33314c39c9362dd293207589ef5ffd66a15 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Thu, 24 Sep 2020 14:15:42 +0200 Subject: [PATCH] Fully test registration app --- apps/api/tests.py | 16 +++++ apps/api/viewsets.py | 2 +- apps/registration/tests.py | 119 +++++++++++++++++++++++++++++++++++++ apps/registration/views.py | 11 ++-- corres2math/settings.py | 1 + corres2math/tokens.py | 3 +- 6 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 apps/api/tests.py diff --git a/apps/api/tests.py b/apps/api/tests.py new file mode 100644 index 0000000..f37cc5e --- /dev/null +++ b/apps/api/tests.py @@ -0,0 +1,16 @@ +from django.contrib.auth.models import User +from django.test import TestCase + + +class TestAPIPages(TestCase): + def setUp(self): + self.user = User.objects.create_superuser( + username="admin", + password="apitest", + email="", + ) + self.client.force_login(self.user) + + def test_user_page(self): + response = self.client.get("/api/user/") + self.assertEqual(response.status_code, 200) diff --git a/apps/api/viewsets.py b/apps/api/viewsets.py index ad6c669..757993d 100644 --- a/apps/api/viewsets.py +++ b/apps/api/viewsets.py @@ -10,7 +10,7 @@ class UserViewSet(ModelViewSet): """ Display list of users. """ - queryset = User.objects.all() + queryset = User.objects.order_by("id").all() serializer_class = UserSerializer filter_backends = [DjangoFilterBackend, SearchFilter] filterset_fields = ['id', 'first_name', 'last_name', 'email', 'is_superuser', 'is_staff', 'is_active', ] diff --git a/apps/registration/tests.py b/apps/registration/tests.py index e69de29..9c815f9 100644 --- a/apps/registration/tests.py +++ b/apps/registration/tests.py @@ -0,0 +1,119 @@ +from corres2math.tokens import email_validation_token +from django.contrib.auth.models import User +from django.test import TestCase +from django.urls import reverse +from django.utils.encoding import force_bytes +from django.utils.http import urlsafe_base64_encode + +from .models import CoachRegistration, Registration, StudentRegistration + + +class TestIndexPage(TestCase): + def test_index(self) -> None: + response = self.client.get(reverse("index")) + self.assertEqual(response.status_code, 200) + + +class TestRegistration(TestCase): + def setUp(self) -> None: + self.user = User.objects.create_superuser( + username="admin", + password="admin", + email="admin@example.com", + ) + self.client.force_login(self.user) + + def test_registration(self): + response = self.client.get(reverse("registration:signup")) + self.assertEqual(response.status_code, 200) + + # Incomplete form + response = self.client.post(reverse("registration:signup"), data=dict( + last_name="Toto", + first_name="Toto", + email="toto@example.com", + password1="azertyuiopazertyuiop", + password2="azertyuiopazertyuiop", + role="participant", + )) + self.assertEqual(response.status_code, 200) + + response = self.client.post(reverse("registration:signup"), data=dict( + last_name="Toto", + first_name="Toto", + email="toto@example.com", + password1="azertyuiopazertyuiop", + password2="azertyuiopazertyuiop", + role="participant", + student_class=12, + school="God", + give_contact_to_animath=False, + )) + self.assertRedirects(response, reverse("registration:email_validation_sent"), 302, 200) + self.assertTrue(User.objects.filter(email="toto@example.com").exists()) + + response = self.client.get(reverse("registration:email_validation_sent")) + self.assertEqual(response.status_code, 200) + + response = self.client.post(reverse("registration:signup"), data=dict( + last_name="Toto", + first_name="Coach", + email="coachtoto@example.com", + password1="azertyuiopazertyuiop", + password2="azertyuiopazertyuiop", + role="coach", + professional_activity="God", + give_contact_to_animath=True, + )) + self.assertRedirects(response, reverse("registration:email_validation_sent"), 302, 200) + self.assertTrue(User.objects.filter(email="coachtoto@example.com").exists()) + + user = User.objects.get(email="coachtoto@example.com") + token = email_validation_token.make_token(user) + uid = urlsafe_base64_encode(force_bytes(user.pk)) + response = self.client.get(reverse("registration:email_validation", kwargs=dict(uidb64=uid, token=token))) + self.assertEqual(response.status_code, 200) + user.registration.refresh_from_db() + self.assertTrue(user.registration.email_confirmed) + + # Token has expired + response = self.client.get(reverse("registration:email_validation", kwargs=dict(uidb64=uid, token=token))) + self.assertEqual(response.status_code, 400) + + # Uid does not exist + response = self.client.get(reverse("registration:email_validation", kwargs=dict(uidb64=0, token="toto"))) + self.assertEqual(response.status_code, 400) + + response = self.client.get(reverse("registration:email_validation_resend", args=(user.pk,))) + self.assertRedirects(response, reverse("registration:email_validation_sent"), 302, 200) + + def test_login(self): + response = self.client.get(reverse("login")) + self.assertEqual(response.status_code, 200) + + self.client.logout() + + response = self.client.post(reverse("login"), data=dict( + username="admin", + password="toto", + )) + self.assertEqual(response.status_code, 200) + + response = self.client.post(reverse("login"), data=dict( + username="admin@example.com", + password="admin", + )) + self.assertRedirects(response, reverse("index"), 302, 200) + + def test_change_email(self): + self.user.email = "newaddressmail@example.com" + self.user.save() + self.assertEqual(self.user.email, self.user.username) + + def test_string_render(self): + # TODO These string field tests will be removed when used in a template + str(self.user.registration) + self.assertRaises(NotImplementedError, lambda: Registration().type) + str(StudentRegistration().type) + str(CoachRegistration().type) + str(self.user.registration.type) # AdminRegistration diff --git a/apps/registration/views.py b/apps/registration/views.py index c8fa805..a9a21ba 100644 --- a/apps/registration/views.py +++ b/apps/registration/views.py @@ -45,7 +45,7 @@ class SignupView(CreateView): return ret def get_success_url(self): - return reverse_lazy("index") + return reverse_lazy("registration:email_validation_sent") class UserValidateView(TemplateView): @@ -70,7 +70,7 @@ class UserValidateView(TemplateView): if user is not None and email_validation_token.check_token(user, token): self.validlink = True user.registration.email_confirmed = True - user.save() + user.registration.save() return self.render_to_response(self.get_context_data(), status=200 if self.validlink else 400) def get_user(self, uidb64): @@ -116,8 +116,5 @@ class UserResendValidationEmailView(LoginRequiredMixin, DetailView): def get(self, request, *args, **kwargs): user = self.get_object() - - user.profile.send_email_validation_link() - - # TODO Change URL - return redirect('index') + user.registration.send_email_validation_link() + return redirect('registration:email_validation_sent') diff --git a/corres2math/settings.py b/corres2math/settings.py index 0adc198..230321f 100644 --- a/corres2math/settings.py +++ b/corres2math/settings.py @@ -60,6 +60,7 @@ INSTALLED_APPS = [ 'rest_framework', 'rest_framework.authtoken', + 'api', 'eastereggs', 'registration', 'participation', diff --git a/corres2math/tokens.py b/corres2math/tokens.py index c194980..a945253 100644 --- a/corres2math/tokens.py +++ b/corres2math/tokens.py @@ -20,7 +20,8 @@ class AccountActivationTokenGenerator(PasswordResetTokenGenerator): # Truncate microseconds so that tokens are consistent even if the # database doesn't support microseconds. login_timestamp = '' if user.last_login is None else user.last_login.replace(microsecond=0, tzinfo=None) - return str(user.pk) + str(user.email) + str(login_timestamp) + str(timestamp) + return str(user.pk) + str(user.email) + str(user.registration.email_confirmed)\ + + str(login_timestamp) + str(timestamp) email_validation_token = AccountActivationTokenGenerator()