이메일 인증과 비밀번호 초기화 관련 테스트 코드를 작성해봤다.
이것저것 import
해와서 쓰는게 많아서 좀 버벅였다...
from django.urls import reverse
from django.core import mail
from django.utils.http import urlsafe_base64_encode
from django.utils.encoding import force_bytes
from rest_framework.test import APITestCase
from users.models import User, UserInfo
from .customtoken import user_email_verify_token
class UserBaseTestCase(APITestCase):
@classmethod
def setUpTestData(cls) -> None:
cls.user_signup_data = {
"username": "signupuser",
"password": "qhdks111!",
"email": "signupuser@gmail.com",
}
cls.set_up_user = User.objects.create_user(
email="testuser@gmail.com",
password="qhdks111!",
)
cls.set_up_userinfo = UserInfo.objects.create(player=cls.set_up_user)
cls.password_reset_data = {"email": "testuser@gmail.com"}
cls.user_edit_data = {"username": "testuser"}
cls.user_login_data = {"email": "testuser@gmail.com", "password": "qhdks111!"}
def setUp(self) -> None:
login_user = self.client.post(reverse("login"), self.user_login_data).data
self.access = login_user["access"]
self.refresh = login_user["refresh"]
self.token = user_email_verify_token.make_token(self.set_up_user)
self.uidb64 = urlsafe_base64_encode(force_bytes(self.set_up_user.pk))
class UserSignUpTestCase(UserBaseTestCase):
def test_signup(self):
url = reverse("signup")
data = self.user_signup_data
response = self.client.post(
path=url,
data=data,
)
self.assertEqual(response.status_code, 201)
self.assertEqual(response.data, {"message": "유저 인증 이메일을 전송했습니다."})
user = User.objects.get(email=data["email"])
self.assertTrue(user)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].to, [user.email])
self.assertEqual(mail.outbox[0].subject, f"<한> {user.username}님의 계정 인증")
class UserEmailTestCase(UserBaseTestCase):
def test_email_verify(self):
url = reverse(
"email_verify_view", kwargs={"uidb64": self.uidb64, "token": self.token}
)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
# 바뀐 적용사항 확인을 위해 DB refresh 해주기
self.set_up_user.refresh_from_db()
self.assertTrue(self.set_up_user.is_active)
def test_password_reset(self):
reset_response = self.client.put(
path=reverse("password_reset_view"),
data=self.password_reset_data,
)
self.assertEqual(reset_response.status_code, 200)
reset_password = mail.outbox[0].body.split(" ")[4][:6]
self.password_reset_data["password"] = reset_password
login_response = self.client.post(reverse("login"), self.password_reset_data)
self.assertEqual(login_response.status_code, 200)
class UserSignUpTestCase(UserBaseTestCase):
def test_signup(self):
...
user = User.objects.get(email=data["email"])
...
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].to, [user.email])
self.assertEqual(mail.outbox[0].subject, f"<한> {user.username}님의 계정 인증")
회원가입 이후 추가 인증이 필요없던 기존의 코드와 다르게,
이메일 인증의 경우
이메일이 잘 전송됐는지, 받는 이메일 주소가 올바른지, 제목은 제대로 갔는지를 확인해줘야 한다.
확인을 위해 django.core
에서 mail
을 import
해온다.
우리는 .send()
메소드를 실행했을 때 저장되는 Django의 내장 메일 메시지를 보관하는 리스트 outbox
를 사용해 줄 것이다.
메일이 잘 전송됐는지 길이를 체크해준다.
그러고 받는 이메일 주소가 맞는지와 제목을 체크해준다.
class UserEmailTestCase(UserBaseTestCase):
def test_email_verify(self):
url = reverse(
"email_verify_view", kwargs={"uidb64": self.uidb64, "token": self.token}
)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.set_up_user.refresh_from_db()
self.assertTrue(self.set_up_user.is_active)
먼저 setUp
에서 저장해준 uidb64
랑 token
값을 들고온 뒤, reverse
메소드를 통해 url
주소를 지정해준다.
그런 뒤 요청을 보내고, status code
가 올바른지 확인한다.
refresh_from_db()
로 DB 상태를 refresh
해준 뒤
assertTrue
로 is_active
가 변경되었는지 확인해준다.
class UserEmailTestCase(UserBaseTestCase):
def test_password_reset(self):
reset_response = self.client.put(
path=reverse("password_reset_view"),
data=self.password_reset_data,
)
self.assertEqual(reset_response.status_code, 200)
reset_password = mail.outbox[0].body.split(" ")[4][:6]
self.password_reset_data["password"] = reset_password
login_response = self.client.post(reverse("login"), self.password_reset_data)
self.assertEqual(login_response.status_code, 200)
먼저, put
요청으로 비밀번호를 초기화 시켜주고 status code
를 확인한다.
그런 뒤, outbox
에서 메일을 찾아 본문의 비밀번호 부분만 쪼갠다.
그리고, 그 비밀번호로 다시 login post
요청을 보내 잘 로그인이 되는지 확인해준다.