tests/views: deprecate httmock (#85304)
This commit is contained in:
parent
fc5ec7d69e
commit
37c5ffb013
|
@ -20,12 +20,10 @@ from unittest import mock
|
|||
from urllib.parse import urlparse
|
||||
|
||||
import pytest
|
||||
import responses
|
||||
from django.urls import reverse
|
||||
from django.utils.html import escape
|
||||
from django.utils.timezone import now
|
||||
from httmock import HTTMock, remember_called
|
||||
from httmock import response as httmock_response
|
||||
from httmock import urlmatch
|
||||
|
||||
from authentic2.apps.authenticators.models import LoginPasswordAuthenticator
|
||||
from authentic2.custom_user.models import DeletedUser, User
|
||||
|
@ -38,18 +36,6 @@ from .utils import assert_event, get_link_from_mail, login, logout
|
|||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
@urlmatch(netloc='foo.whatever.none')
|
||||
@remember_called
|
||||
def sms_service_mock(url, request):
|
||||
return {
|
||||
'content': {},
|
||||
'headers': {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
'status_code': 200,
|
||||
}
|
||||
|
||||
|
||||
def test_profile(app, simple_user):
|
||||
page = login(app, simple_user, path=reverse('account_management'))
|
||||
assert simple_user.first_name in page
|
||||
|
@ -354,8 +340,10 @@ class TestDeleteAccountEmailNotVerified:
|
|||
assert urlparse(response.location).path == '/'
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_delete_account_phone_identifier(app, nomail_user, settings, phone_activated_authn):
|
||||
settings.SMS_URL = 'https://foo.whatever.none/'
|
||||
responses.post('https://foo.whatever.none/', status=200)
|
||||
|
||||
nomail_user.attributes.phone = '+33122446666'
|
||||
nomail_user.phone_verified_on = now()
|
||||
|
@ -366,8 +354,7 @@ def test_delete_account_phone_identifier(app, nomail_user, settings, phone_activ
|
|||
)
|
||||
resp = app.get('/accounts/delete/')
|
||||
assert 'A validation code will be sent to +33122446666' in resp.text
|
||||
with HTTMock(sms_service_mock):
|
||||
resp = resp.form.submit().follow()
|
||||
resp = resp.form.submit().follow()
|
||||
code = SMSCode.objects.get()
|
||||
assert not Token.objects.count()
|
||||
resp.form.set('sms_code', code.value)
|
||||
|
@ -377,8 +364,10 @@ def test_delete_account_phone_identifier(app, nomail_user, settings, phone_activ
|
|||
User.objects.get(id=nomail_user_id)
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_delete_account_phone_identifier_deactivated_user(app, nomail_user, settings, phone_activated_authn):
|
||||
settings.SMS_URL = 'https://foo.whatever.none/'
|
||||
responses.post('https://foo.whatever.none/', status=200)
|
||||
|
||||
nomail_user.attributes.phone = '+33122446666'
|
||||
nomail_user.phone_verified_on = now()
|
||||
|
@ -388,8 +377,7 @@ def test_delete_account_phone_identifier_deactivated_user(app, nomail_user, sett
|
|||
app, nomail_user, login=nomail_user.attributes.phone, path='/accounts/', password=nomail_user.username
|
||||
)
|
||||
resp = app.get('/accounts/delete/')
|
||||
with HTTMock(sms_service_mock):
|
||||
resp = resp.form.submit().follow()
|
||||
resp = resp.form.submit().follow()
|
||||
code = SMSCode.objects.get()
|
||||
resp.form.set('sms_code', code.value)
|
||||
nomail_user.is_active = False
|
||||
|
@ -419,10 +407,12 @@ def test_delete_account_phone_verified_yet_missing(app, nomail_user, settings, p
|
|||
assert '+33122446666' not in resp.html
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_delete_account_verified_email_precedence_over_verified_phone(
|
||||
app, simple_user, settings, phone_activated_authn
|
||||
):
|
||||
settings.SMS_URL = 'https://foo.whatever.none/'
|
||||
responses.post('https://foo.whatever.none/', status=200)
|
||||
|
||||
simple_user.attributes.phone = '+33122446666'
|
||||
simple_user.email_verified = True
|
||||
|
@ -434,15 +424,16 @@ def test_delete_account_verified_email_precedence_over_verified_phone(
|
|||
resp = app.get('/accounts/delete/')
|
||||
# email is verified and defaults as deletion code exchange means
|
||||
assert 'A validation message will be sent to user@example.net.' in resp.text
|
||||
with HTTMock(sms_service_mock):
|
||||
resp = resp.form.submit().follow()
|
||||
resp.form.submit().follow()
|
||||
assert not SMSCode.objects.count()
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_delete_account_verified_phone_precedence_over_unverified_email(
|
||||
app, simple_user, settings, phone_activated_authn
|
||||
):
|
||||
settings.SMS_URL = 'https://foo.whatever.none/'
|
||||
responses.post('https://foo.whatever.none/', status=200)
|
||||
|
||||
simple_user.attributes.phone = '+33122446666'
|
||||
simple_user.email_verified = False
|
||||
|
@ -455,15 +446,16 @@ def test_delete_account_verified_phone_precedence_over_unverified_email(
|
|||
# email is unverified and skipped as deletion code exchange means
|
||||
# fallback on phone
|
||||
assert 'A validation code will be sent to +33122446666' in resp.text
|
||||
with HTTMock(sms_service_mock):
|
||||
resp = resp.form.submit().follow()
|
||||
resp.form.submit().follow()
|
||||
assert SMSCode.objects.get()
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_delete_account_unverified_identifiers_direct_deletion(
|
||||
app, simple_user, settings, phone_activated_authn
|
||||
):
|
||||
settings.SMS_URL = 'https://foo.whatever.none/'
|
||||
responses.post('https://foo.whatever.none/', status=200)
|
||||
|
||||
simple_user.attributes.phone = '+33122446666'
|
||||
simple_user.email_verified = False
|
||||
|
@ -478,18 +470,19 @@ def test_delete_account_unverified_identifiers_direct_deletion(
|
|||
# deletion process is direct
|
||||
assert 'A validation message' not in resp.text
|
||||
assert 'A validation code' not in resp.text
|
||||
with HTTMock(sms_service_mock):
|
||||
resp.form.submit().follow()
|
||||
resp.form.submit().follow()
|
||||
assert not SMSCode.objects.count()
|
||||
assert not Token.objects.count()
|
||||
with pytest.raises(User.DoesNotExist):
|
||||
User.objects.get(id=simple_user_id)
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_delete_account_phone_identifier_changed_in_between(
|
||||
app, nomail_user, settings, phone_activated_authn
|
||||
):
|
||||
settings.SMS_URL = 'https://foo.whatever.none/'
|
||||
responses.post('https://foo.whatever.none/', status=200)
|
||||
|
||||
nomail_user.attributes.phone = '+33122446666'
|
||||
nomail_user.phone_verified_on = now()
|
||||
|
@ -500,8 +493,7 @@ def test_delete_account_phone_identifier_changed_in_between(
|
|||
)
|
||||
resp = app.get('/accounts/delete/')
|
||||
assert 'A validation code will be sent to +33122446666' in resp.text
|
||||
with HTTMock(sms_service_mock):
|
||||
resp = resp.form.submit().follow()
|
||||
resp = resp.form.submit().follow()
|
||||
code = SMSCode.objects.get()
|
||||
nomail_user.attributes.phone = '+33122446688'
|
||||
nomail_user.save()
|
||||
|
@ -525,73 +517,50 @@ def test_custom_account(settings, app, simple_user):
|
|||
|
||||
|
||||
@pytest.mark.parametrize('view_name', ['registration_register', 'password_reset', 'phone-change'])
|
||||
@responses.activate
|
||||
def test_views_sms_ratelimit(app, db, simple_user, settings, freezer, view_name, phone_activated_authn):
|
||||
freezer.move_to('2020-01-01')
|
||||
LoginPasswordAuthenticator.objects.update(sms_ip_ratelimit='10/h', sms_number_ratelimit='3/d')
|
||||
settings.SMS_SENDER = 'EO'
|
||||
settings.SMS_URL = 'https://www.example.com/send'
|
||||
responses.post('https://www.example.com/send', status=200)
|
||||
|
||||
@urlmatch(scheme='https', netloc='www.example.com', path='/send')
|
||||
def sms_endpoint_response(url, request):
|
||||
return httmock_response(200, {})
|
||||
|
||||
with HTTMock(sms_endpoint_response):
|
||||
if view_name in ('phone-change',):
|
||||
login(app, simple_user)
|
||||
if view_name in ('phone-change',):
|
||||
login(app, simple_user)
|
||||
response = app.get(reverse(view_name))
|
||||
response.form.set('phone_0', '33')
|
||||
response.form.set('phone_1', '0612345678')
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'try again later' not in response.text
|
||||
for _ in range(2):
|
||||
response = app.get(reverse(view_name))
|
||||
response.form.set('phone_0', '33')
|
||||
response.form.set('phone_1', '0612345678')
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'An SMS code has already been sent' in response.text
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'try again later' not in response.text
|
||||
for _ in range(2):
|
||||
response = app.get(reverse(view_name))
|
||||
response.form.set('phone_0', '33')
|
||||
response.form.set('phone_1', '0612345678')
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'An SMS code has already been sent' in response.text
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'try again later' not in response.text
|
||||
|
||||
response = app.get(reverse(view_name))
|
||||
response.form.set('phone_0', '33')
|
||||
response.form.set('phone_1', '0612345678')
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'try again later' in response.text
|
||||
response = app.get(reverse(view_name))
|
||||
response.form.set('phone_0', '33')
|
||||
response.form.set('phone_1', '0612345678')
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'try again later' in response.text
|
||||
|
||||
suffixes = iter(range(6000, 9999))
|
||||
# reach ip limit
|
||||
for _ in range(7):
|
||||
response = app.get(reverse(view_name))
|
||||
random_suffix = next(suffixes)
|
||||
response.form.set('phone_0', '33')
|
||||
response.form.set('phone_1', f'061234{random_suffix:04d}')
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'try again later' not in response.text
|
||||
|
||||
response = app.get(reverse(view_name))
|
||||
random_suffix = next(suffixes)
|
||||
response.form.set('phone_0', '33')
|
||||
response.form.set('phone_1', f'061234{random_suffix:04d}')
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'try again later' in response.text
|
||||
|
||||
# ip ratelimits are lifted after an hour
|
||||
freezer.tick(datetime.timedelta(hours=1))
|
||||
suffixes = iter(range(6000, 9999))
|
||||
# reach ip limit
|
||||
for _ in range(7):
|
||||
response = app.get(reverse(view_name))
|
||||
random_suffix = next(suffixes)
|
||||
response.form.set('phone_0', '33')
|
||||
|
@ -601,27 +570,47 @@ def test_views_sms_ratelimit(app, db, simple_user, settings, freezer, view_name,
|
|||
response = response.form.submit()
|
||||
assert 'try again later' not in response.text
|
||||
|
||||
# identifier ratelimits are lifted after a day
|
||||
response = app.get(reverse(view_name))
|
||||
response.form.set('phone_0', '33')
|
||||
response.form.set('phone_1', '0612345678')
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'Multiple SMSs have already been sent to this number.' in response.text
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'try again later' in response.text
|
||||
response = app.get(reverse(view_name))
|
||||
random_suffix = next(suffixes)
|
||||
response.form.set('phone_0', '33')
|
||||
response.form.set('phone_1', f'061234{random_suffix:04d}')
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'try again later' in response.text
|
||||
|
||||
freezer.tick(datetime.timedelta(days=1))
|
||||
response = app.get(reverse(view_name))
|
||||
response.form.set('phone_0', '33')
|
||||
response.form.set('phone_1', '0612345678')
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'try again later' not in response.text
|
||||
# ip ratelimits are lifted after an hour
|
||||
freezer.tick(datetime.timedelta(hours=1))
|
||||
response = app.get(reverse(view_name))
|
||||
random_suffix = next(suffixes)
|
||||
response.form.set('phone_0', '33')
|
||||
response.form.set('phone_1', f'061234{random_suffix:04d}')
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'try again later' not in response.text
|
||||
|
||||
# identifier ratelimits are lifted after a day
|
||||
response = app.get(reverse(view_name))
|
||||
response.form.set('phone_0', '33')
|
||||
response.form.set('phone_1', '0612345678')
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'Multiple SMSs have already been sent to this number.' in response.text
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'try again later' in response.text
|
||||
|
||||
freezer.tick(datetime.timedelta(days=1))
|
||||
response = app.get(reverse(view_name))
|
||||
response.form.set('phone_0', '33')
|
||||
response.form.set('phone_1', '0612345678')
|
||||
if view_name in ('phone-change',):
|
||||
response.form.set('password', simple_user.username)
|
||||
response = response.form.submit()
|
||||
assert 'try again later' not in response.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize('view_name', ['registration_register', 'password_reset'])
|
||||
|
|
Loading…
Reference in New Issue