问题
I'm trying to make a test for the email confirmation view with django-rest-auth. Here is what I have:
def test_verify_email(self):
# Verify email address
username = 'userTest'
payload = {
'email': 'test@example.com',
'password1': 'TestpassUltra1',
'password2': 'TestpassUltra1',
'username': username,
}
res = self.client.post(REGISTER_USER_URL, payload)
self.assertEqual(res.status_code, status.HTTP_201_CREATED)
user = get_user_model().objects.get(email='test@example.com')
# TODO retrieve the confirmation key from the user
resp = self.client.post(VERIFY_USER_URL, {'key': ''})
self.assertEqual(resp.status_code, status.HTTP_200_OK)
self.client.post(REGISTER_USER_URL, payload)
will send an email with the confirmation code in it and while I know I could retrieve that code with django.core.mail.outbox
in the code I rather not do that as I will have to parse the email content to look for the confirmation code (which can kill my test if the email changes). I couldn't find this code stored anywhere in the DB, it seems to really exist only inside the body of the email sent.
My question is: Is it possible to recover this verification code in my test without parsing the email? I just want to retrieve it to launch my self.client.post(VERIFY_USER_URL, {'key': ''})
with it.
Here is the example of the content of an email:
Hello from example.com!
You're receiving this e-mail from NomadSpeed because user detro1 has given yours as an e-mail address to connect their account.
To confirm this is correct, go to http://127.0.0.1:8000/registration/account-confirm-email/Mg:1hmqdS:J-2jGV028nd4qZQ3lPmFgXGFhsM/
Thank you from example.com!
example.com
What I need is Mg:1hmqdS:J-2jGV028nd4qZQ3lPmFgXGFhsM
.
Thank you.
回答1:
I think the best way to approach this is to use a regex to match the expected link, and parse the bits you want out of that. It's fair to worry that changes to the email might break the tests, but in this case you are testing that the link in the email is valid, and if this changes in some way, perhaps it should break your tests. If you change some of the other text, like the greeting, introduction, etc. it won't affect the regex for your link and token.
Anyway here is how I would structure that test:
import re
def test_verify_email(self):
# Verify email address
username = 'userTest'
payload = {
'email': 'test@example.com',
'password1': 'TestpassUltra1',
'password2': 'TestpassUltra1',
'username': username,
}
response = self.client.post(REGISTER_USER_URL, payload)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
user = get_user_model().objects.get(email='test@example.com')
# Get token from email
token_regex = r"registration\/account-confirm-email\/([A-Za-z0-9:\-]+)\/"
email_content = django.core.mail.outbox[0].body
match = re.search(token_regex, email_content)
assert match.groups(), "Could not find the token in the email" # You might want to use some other way to raise an error for this
token = match.group(1)
# Verify
response = self.client.post(VERIFY_USER_URL, {'key': token})
self.assertEqual(response.status_code, status.HTTP_200_OK)
You could perhaps even assert the correctness of the path of that link, so if someone changes that link you'll have a failing test to indicate that something may break.
来源:https://stackoverflow.com/questions/57032616/how-to-test-email-confirmation