API - refactor imports
This commit is contained in:
0
fittrackee/tests/emails/__init__.py
Normal file
0
fittrackee/tests/emails/__init__.py
Normal file
@ -0,0 +1,174 @@
|
||||
# flake8: noqa
|
||||
|
||||
expected_en_text_body = """Hi test,
|
||||
|
||||
You recently requested to reset your password for your FitTrackee account. Use the button below to reset it. This password reset link is only valid for 3 seconds.
|
||||
|
||||
Reset your password ( http://localhost/password-reset?token=xxx )
|
||||
|
||||
For security, this request was received from a Linux device using Firefox. If you did not request a password reset, please ignore this email.
|
||||
|
||||
Thanks,
|
||||
The FitTrackee Team"""
|
||||
|
||||
expected_fr_text_body = """Bonjour test,
|
||||
|
||||
Vous avez récemment demander la réinitilisation du mot de passe de votre compte sur FitTrackee.
|
||||
Cliquez sur le lien ci-dessous pour le réinitialiser. Ce lien n'est valide que pendant 3 secondes.
|
||||
|
||||
Réinitialiser le mot de passe: ( http://localhost/password-reset?token=xxx )
|
||||
|
||||
Pour vérification, cette demande a été reçue à partir d'un appareil sous Linux, utilisant le navigateur Firefox.
|
||||
Si vous n'avez pas demandé de réinitalisation, vous pouvez ignorer cet e-mail.
|
||||
|
||||
Merci,
|
||||
L'équipe FitTrackee"""
|
||||
|
||||
expected_en_html_body = """ <body>
|
||||
<span class="preheader">Use this link to reset your password. The link is only valid for 3 seconds.</span>
|
||||
<table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<table class="email-content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td class="email-masthead">
|
||||
<a href="https://example.com" class="f-fallback email-masthead-name">
|
||||
FitTrackee
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="email-body" width="100%" cellpadding="0" cellspacing="0">
|
||||
<table class="email-body-inner" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td class="content-cell">
|
||||
<div class="f-fallback">
|
||||
<h1>Hi test,</h1>
|
||||
<p>You recently requested to reset your password for your account. Use the button below to reset it.
|
||||
<strong>This password reset link is only valid for 3 seconds.</strong>
|
||||
</p>
|
||||
<table class="body-action" align="center" width="100%" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0" role="presentation">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="http://localhost/password-reset?token=xxx" class="f-fallback button button--green" target="_blank">Reset your password</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
For security, this request was received from a Linux device using Firefox.
|
||||
If you did not request a password reset, please ignore this email.
|
||||
</p>
|
||||
<p>Thanks,
|
||||
<br>The FitTrackee Team</p>
|
||||
<table class="body-sub" role="presentation">
|
||||
<tr>
|
||||
<td>
|
||||
<p class="f-fallback sub">If you’re having trouble with the button above, copy and paste the URL below into your web browser.</p>
|
||||
<p class="f-fallback sub">http://localhost/password-reset?token=xxx</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="email-footer" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td class="content-cell" align="center">
|
||||
<p class="f-fallback sub align-center">© FitTrackee.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
expected_fr_html_body = """ <body>
|
||||
<span class="preheader">Utiliser ce lien pour réinitialiser le mot de passe. Ce lien n'est valide que pendant 3 secondes.</span>
|
||||
<table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<table class="email-content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td class="email-masthead">
|
||||
<a href="https://example.com" class="f-fallback email-masthead-name">
|
||||
FitTrackee
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="email-body" width="100%" cellpadding="0" cellspacing="0">
|
||||
<table class="email-body-inner" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td class="content-cell">
|
||||
<div class="f-fallback">
|
||||
<h1>Bonjour test,</h1>
|
||||
<p>Vous avez récemment demander la réinitilisation du mot de passe de votre compte sur FitTrackee.
|
||||
Cliquez sur le bouton ci-dessous pour le réinitialiser.
|
||||
<strong>Cette réinitialisation n'est valide que pendant 3 secondes.</strong>
|
||||
</p>
|
||||
<table class="body-action" align="center" width="100%" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0" role="presentation">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="http://localhost/password-reset?token=xxx" class="f-fallback button button--green" target="_blank">Réinitialiser le mot de passe</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
Pour vérification, cette demande a été reçue à partir d'un appareil sous Linux, utilisant le navigateur Firefox.
|
||||
Si vous n'avez pas demandé de réinitalisation, vous pouvez ignorer cet e-mail.
|
||||
</p>
|
||||
<p>Merci,
|
||||
<br>L'équipe FitTrackee</p>
|
||||
<table class="body-sub" role="presentation">
|
||||
<tr>
|
||||
<td>
|
||||
<p class="f-fallback sub">Si vous avez des problèmes avec le bouton, vous pouvez copier et coller le lien suivant dans votre navigateur</p>
|
||||
<p class="f-fallback sub">http://localhost/password-reset?token=xxx</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="email-footer" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
|
||||
<tr>
|
||||
<td class="content-cell" align="center">
|
||||
<p class="f-fallback sub align-center">© FitTrackee.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>"""
|
107
fittrackee/tests/emails/test_email.py
Normal file
107
fittrackee/tests/emails/test_email.py
Normal file
@ -0,0 +1,107 @@
|
||||
from typing import Any
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from flask import Flask
|
||||
|
||||
from fittrackee import email_service
|
||||
from fittrackee.emails.email import EmailMessage
|
||||
|
||||
from .template_results.password_reset_request import expected_en_text_body
|
||||
|
||||
|
||||
class TestEmailMessage:
|
||||
def test_it_generate_email_data(self) -> None:
|
||||
message = EmailMessage(
|
||||
sender='fittrackee@example.com',
|
||||
recipient='test@test.com',
|
||||
subject='Fittrackee - test email',
|
||||
html="""\
|
||||
<html>
|
||||
<body>
|
||||
<p>Hello !</p>
|
||||
</body>
|
||||
</html>
|
||||
""",
|
||||
text='Hello !',
|
||||
)
|
||||
message_data = message.generate_message()
|
||||
assert message_data.get('From') == 'fittrackee@example.com'
|
||||
assert message_data.get('To') == 'test@test.com'
|
||||
assert message_data.get('Subject') == 'Fittrackee - test email'
|
||||
message_string = message_data.as_string()
|
||||
assert 'Hello !' in message_string
|
||||
|
||||
|
||||
class TestEmailSending:
|
||||
|
||||
email_data = {
|
||||
'expiration_delay': '3 seconds',
|
||||
'username': 'test',
|
||||
'password_reset_url': 'http://localhost/password-reset?token=xxx',
|
||||
'operating_system': 'Linux',
|
||||
'browser_name': 'Firefox',
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def get_args(call_args: Any) -> Any:
|
||||
if len(call_args) == 2:
|
||||
args, _ = call_args
|
||||
else:
|
||||
_, args, _ = call_args
|
||||
return args
|
||||
|
||||
def assert_smtp(self, smtp: Mock) -> None:
|
||||
assert smtp.sendmail.call_count == 1
|
||||
call_args = self.get_args(smtp.sendmail.call_args)
|
||||
assert call_args[0] == 'fittrackee@example.com'
|
||||
assert call_args[1] == 'test@test.com'
|
||||
assert expected_en_text_body in call_args[2]
|
||||
|
||||
@patch('smtplib.SMTP_SSL')
|
||||
@patch('smtplib.SMTP')
|
||||
def test_it_sends_message(
|
||||
self, mock_smtp: Mock, mock_smtp_ssl: Mock, app: Flask
|
||||
) -> None:
|
||||
|
||||
email_service.send(
|
||||
template='password_reset_request',
|
||||
lang='en',
|
||||
recipient='test@test.com',
|
||||
data=self.email_data,
|
||||
)
|
||||
|
||||
smtp = mock_smtp.return_value.__enter__.return_value
|
||||
assert smtp.starttls.not_called
|
||||
self.assert_smtp(smtp)
|
||||
|
||||
@patch('smtplib.SMTP_SSL')
|
||||
@patch('smtplib.SMTP')
|
||||
def test_it_sends_message_with_ssl(
|
||||
self, mock_smtp: Mock, mock_smtp_ssl: Mock, app_ssl: Flask
|
||||
) -> None:
|
||||
email_service.send(
|
||||
template='password_reset_request',
|
||||
lang='en',
|
||||
recipient='test@test.com',
|
||||
data=self.email_data,
|
||||
)
|
||||
|
||||
smtp = mock_smtp_ssl.return_value.__enter__.return_value
|
||||
assert smtp.starttls.not_called
|
||||
self.assert_smtp(smtp)
|
||||
|
||||
@patch('smtplib.SMTP_SSL')
|
||||
@patch('smtplib.SMTP')
|
||||
def test_it_sends_message_with_tls(
|
||||
self, mock_smtp: Mock, mock_smtp_ssl: Mock, app_tls: Flask
|
||||
) -> None:
|
||||
email_service.send(
|
||||
template='password_reset_request',
|
||||
lang='en',
|
||||
recipient='test@test.com',
|
||||
data=self.email_data,
|
||||
)
|
||||
|
||||
smtp = mock_smtp.return_value.__enter__.return_value
|
||||
assert smtp.starttls.call_count == 1
|
||||
self.assert_smtp(smtp)
|
@ -0,0 +1,85 @@
|
||||
import pytest
|
||||
from flask import Flask
|
||||
|
||||
from fittrackee.emails.email import EmailTemplate
|
||||
|
||||
from .template_results.password_reset_request import (
|
||||
expected_en_html_body,
|
||||
expected_en_text_body,
|
||||
expected_fr_html_body,
|
||||
expected_fr_text_body,
|
||||
)
|
||||
|
||||
|
||||
class TestEmailTemplateForPasswordRequest:
|
||||
@pytest.mark.parametrize(
|
||||
'lang, expected_subject',
|
||||
[
|
||||
('en', 'FitTrackee - Password reset request'),
|
||||
('fr', 'FitTrackee - Réinitialiser votre mot de passe'),
|
||||
],
|
||||
)
|
||||
def test_it_gets_subject(
|
||||
self, app: Flask, lang: str, expected_subject: str
|
||||
) -> None:
|
||||
email_template = EmailTemplate(app.config['TEMPLATES_FOLDER'])
|
||||
|
||||
subject = email_template.get_content(
|
||||
'password_reset_request', lang, 'subject.txt', {}
|
||||
)
|
||||
|
||||
assert subject == expected_subject
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'lang, expected_text_body',
|
||||
[('en', expected_en_text_body), ('fr', expected_fr_text_body)],
|
||||
)
|
||||
def test_it_gets_text_body(
|
||||
self, app: Flask, lang: str, expected_text_body: str
|
||||
) -> None:
|
||||
email_template = EmailTemplate(app.config['TEMPLATES_FOLDER'])
|
||||
email_data = {
|
||||
'expiration_delay': '3 seconds' if lang == 'en' else '3 secondes',
|
||||
'username': 'test',
|
||||
'password_reset_url': 'http://localhost/password-reset?token=xxx',
|
||||
'operating_system': 'Linux',
|
||||
'browser_name': 'Firefox',
|
||||
}
|
||||
|
||||
text_body = email_template.get_content(
|
||||
'password_reset_request', lang, 'body.txt', email_data
|
||||
)
|
||||
|
||||
assert text_body == expected_text_body
|
||||
|
||||
def test_it_gets_en_html_body(self, app: Flask) -> None:
|
||||
email_template = EmailTemplate(app.config['TEMPLATES_FOLDER'])
|
||||
email_data = {
|
||||
'expiration_delay': '3 seconds',
|
||||
'username': 'test',
|
||||
'password_reset_url': 'http://localhost/password-reset?token=xxx',
|
||||
'operating_system': 'Linux',
|
||||
'browser_name': 'Firefox',
|
||||
}
|
||||
|
||||
text_body = email_template.get_content(
|
||||
'password_reset_request', 'en', 'body.html', email_data
|
||||
)
|
||||
|
||||
assert expected_en_html_body in text_body
|
||||
|
||||
def test_it_gets_fr_html_body(self, app: Flask) -> None:
|
||||
email_template = EmailTemplate(app.config['TEMPLATES_FOLDER'])
|
||||
email_data = {
|
||||
'expiration_delay': '3 secondes',
|
||||
'username': 'test',
|
||||
'password_reset_url': 'http://localhost/password-reset?token=xxx',
|
||||
'operating_system': 'Linux',
|
||||
'browser_name': 'Firefox',
|
||||
}
|
||||
|
||||
text_body = email_template.get_content(
|
||||
'password_reset_request', 'fr', 'body.html', email_data
|
||||
)
|
||||
|
||||
assert expected_fr_html_body in text_body
|
43
fittrackee/tests/emails/test_email_utils.py
Normal file
43
fittrackee/tests/emails/test_email_utils.py
Normal file
@ -0,0 +1,43 @@
|
||||
import pytest
|
||||
|
||||
from fittrackee.emails.utils_email import (
|
||||
InvalidEmailUrlScheme,
|
||||
parse_email_url,
|
||||
)
|
||||
|
||||
|
||||
class TestEmailUrlParser:
|
||||
def test_it_raises_error_if_url_scheme_is_invalid(self) -> None:
|
||||
url = 'stmp://username:password@localhost:587'
|
||||
with pytest.raises(InvalidEmailUrlScheme):
|
||||
parse_email_url(url)
|
||||
|
||||
def test_it_parses_email_url(self) -> None:
|
||||
url = 'smtp://test@example.com:12345678@localhost:25'
|
||||
parsed_email = parse_email_url(url)
|
||||
assert parsed_email['username'] == 'test@example.com'
|
||||
assert parsed_email['password'] == '12345678'
|
||||
assert parsed_email['host'] == 'localhost'
|
||||
assert parsed_email['port'] == 25
|
||||
assert parsed_email['use_tls'] is False
|
||||
assert parsed_email['use_ssl'] is False
|
||||
|
||||
def test_it_parses_email_url_with_tls(self) -> None:
|
||||
url = 'smtp://test@example.com:12345678@localhost:587?tls=True'
|
||||
parsed_email = parse_email_url(url)
|
||||
assert parsed_email['username'] == 'test@example.com'
|
||||
assert parsed_email['password'] == '12345678'
|
||||
assert parsed_email['host'] == 'localhost'
|
||||
assert parsed_email['port'] == 587
|
||||
assert parsed_email['use_tls'] is True
|
||||
assert parsed_email['use_ssl'] is False
|
||||
|
||||
def test_it_parses_email_url_with_ssl(self) -> None:
|
||||
url = 'smtp://test@example.com:12345678@localhost:465?ssl=True'
|
||||
parsed_email = parse_email_url(url)
|
||||
assert parsed_email['username'] == 'test@example.com'
|
||||
assert parsed_email['password'] == '12345678'
|
||||
assert parsed_email['host'] == 'localhost'
|
||||
assert parsed_email['port'] == 465
|
||||
assert parsed_email['use_tls'] is False
|
||||
assert parsed_email['use_ssl'] is True
|
Reference in New Issue
Block a user