How to test email confirmation?

你离开我真会死。 提交于 2020-12-15 08:41:30

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!