From 118b98cfb6bbb2a4d9a048e45ff915cb161c9afe Mon Sep 17 00:00:00 2001 From: gustavomm19 Date: Wed, 5 Feb 2025 14:59:50 +0000 Subject: [PATCH 1/3] add endpoint to verify if email is validated --- breathecode/authenticate/urls/v1.py | 2 ++ breathecode/authenticate/views.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/breathecode/authenticate/urls/v1.py b/breathecode/authenticate/urls/v1.py index 2e0b7d8a9..0f6edc019 100644 --- a/breathecode/authenticate/urls/v1.py +++ b/breathecode/authenticate/urls/v1.py @@ -51,6 +51,7 @@ UserMeView, UserSettingsView, WaitingListView, + EmailConfirmation, get_facebook_token, get_github_token, get_google_token, @@ -89,6 +90,7 @@ app_name = "authenticate" urlpatterns = [ + path("emailverification/", EmailConfirmation.as_view(), name="email_confirmation"), path("confirmation/", ConfirmEmailView.as_view(), name="confirmation_token"), path("invite/resend/", ResendInviteView.as_view(), name="invite_resend_id"), path("member/invite/resend/", AcademyInviteView.as_view(), name="member_invite_resend_id"), diff --git a/breathecode/authenticate/views.py b/breathecode/authenticate/views.py index 39b714274..c9f513bae 100644 --- a/breathecode/authenticate/views.py +++ b/breathecode/authenticate/views.py @@ -530,6 +530,35 @@ def put(self, request, profile_academy_id=None, new_status=None): return Response(serializer.data) +class EmailConfirmation(APIView): + permission_classes = [AllowAny] + + def get(self, request, email=None): + get_user_language(request) + + invite = UserInvite.objects.filter(email=email).first() + user = User.objects.filter(email=email).first() + if user is None and invite is None: + raise ValidationException( + translation( + en="We could not find an account with this email", + es="No pudimos encontrar una dirección con este email", + ), + slug="email-not-found", + ) + + if invite is not None and not invite.is_email_validated: + raise ValidationException( + translation( + en="You need to validate your email first", + es="Debes validar tu email primero", + ), + slug="email-not-validated", + ) + + return Response(None, status=status.HTTP_204_NO_CONTENT) + + class ConfirmEmailView(APIView): permission_classes = [AllowAny] From 490ac35d17388f54b01cb4ee274730f55c6f32b5 Mon Sep 17 00:00:00 2001 From: gustavomm19 Date: Thu, 6 Feb 2025 11:15:56 +0000 Subject: [PATCH 2/3] add tests --- .../tests/urls/v1/tests_email_verification.py | 64 +++++++++++++++++++ breathecode/authenticate/urls/v1.py | 4 +- breathecode/authenticate/views.py | 2 +- 3 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 breathecode/authenticate/tests/urls/v1/tests_email_verification.py diff --git a/breathecode/authenticate/tests/urls/v1/tests_email_verification.py b/breathecode/authenticate/tests/urls/v1/tests_email_verification.py new file mode 100644 index 000000000..c911dd466 --- /dev/null +++ b/breathecode/authenticate/tests/urls/v1/tests_email_verification.py @@ -0,0 +1,64 @@ +""" +Test cases for /emailvalidation +""" + +import re +import urllib +from unittest import mock + +import capyc.pytest as capy +import pytest +from django.urls.base import reverse_lazy +from rest_framework import status +from rest_framework.test import APIClient +from linked_services.django.actions import reset_app_cache + +import staging.pytest as staging +from breathecode.authenticate.tests.mocks.mocks import FakeResponse +from breathecode.tests.mixins.breathecode_mixin.breathecode import Breathecode + +from ...mocks import GithubRequestsMock + + +@pytest.fixture(autouse=True) +def setup(db): + reset_app_cache() + yield + + +def test_email_verification_no_user(bc: Breathecode, client: APIClient): + email = "thanos@4geeks.com" + + url = reverse_lazy("authenticate:email_verification", kwargs={"email": email}) + response = client.get(url) + + json = response.json() + expected = {"detail": "email-not-found", "status_code": 400} + + assert json == expected + assert response.status_code == status.HTTP_400_BAD_REQUEST + + +def test_email_verification_not_validated(bc: Breathecode, client: APIClient): + email = "thanos@4geeks.com" + + model = bc.database.create(user={"email": email}, user_invite={"email": email, "is_email_validated": False}) + + url = reverse_lazy("authenticate:email_verification", kwargs={"email": email}) + response = client.get(url) + + json = response.json() + expected = {"detail": "email-not-validated", "status_code": 400} + + assert json == expected + assert response.status_code == status.HTTP_400_BAD_REQUEST + + +def test_email_verification(bc: Breathecode, client: APIClient): + email = "thanos@4geeks.com" + model = bc.database.create(user={"email": email}) + + url = reverse_lazy("authenticate:email_verification", kwargs={"email": email}) + response = client.get(url) + + assert response.status_code == status.HTTP_204_NO_CONTENT diff --git a/breathecode/authenticate/urls/v1.py b/breathecode/authenticate/urls/v1.py index 0f6edc019..e97b9052e 100644 --- a/breathecode/authenticate/urls/v1.py +++ b/breathecode/authenticate/urls/v1.py @@ -51,7 +51,7 @@ UserMeView, UserSettingsView, WaitingListView, - EmailConfirmation, + EmailVerification, get_facebook_token, get_github_token, get_google_token, @@ -90,7 +90,7 @@ app_name = "authenticate" urlpatterns = [ - path("emailverification/", EmailConfirmation.as_view(), name="email_confirmation"), + path("emailverification/", EmailVerification.as_view(), name="email_verification"), path("confirmation/", ConfirmEmailView.as_view(), name="confirmation_token"), path("invite/resend/", ResendInviteView.as_view(), name="invite_resend_id"), path("member/invite/resend/", AcademyInviteView.as_view(), name="member_invite_resend_id"), diff --git a/breathecode/authenticate/views.py b/breathecode/authenticate/views.py index c9f513bae..ceadbcd10 100644 --- a/breathecode/authenticate/views.py +++ b/breathecode/authenticate/views.py @@ -530,7 +530,7 @@ def put(self, request, profile_academy_id=None, new_status=None): return Response(serializer.data) -class EmailConfirmation(APIView): +class EmailVerification(APIView): permission_classes = [AllowAny] def get(self, request, email=None): From 90b424a5281621136d2601585fa06a632ecc4933 Mon Sep 17 00:00:00 2001 From: gustavomm19 Date: Thu, 6 Feb 2025 11:22:16 +0000 Subject: [PATCH 3/3] remove unused imports --- .../tests/urls/v1/tests_email_verification.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/breathecode/authenticate/tests/urls/v1/tests_email_verification.py b/breathecode/authenticate/tests/urls/v1/tests_email_verification.py index c911dd466..583ff2e89 100644 --- a/breathecode/authenticate/tests/urls/v1/tests_email_verification.py +++ b/breathecode/authenticate/tests/urls/v1/tests_email_verification.py @@ -2,23 +2,14 @@ Test cases for /emailvalidation """ -import re -import urllib -from unittest import mock - -import capyc.pytest as capy import pytest from django.urls.base import reverse_lazy from rest_framework import status from rest_framework.test import APIClient from linked_services.django.actions import reset_app_cache -import staging.pytest as staging -from breathecode.authenticate.tests.mocks.mocks import FakeResponse from breathecode.tests.mixins.breathecode_mixin.breathecode import Breathecode -from ...mocks import GithubRequestsMock - @pytest.fixture(autouse=True) def setup(db):