launch tests with Django 1.11 (fixes #27095)
This commit is contained in:
parent
7b2f4f2f9a
commit
460def09da
|
@ -25,9 +25,13 @@ pipeline {
|
||||||
utils.mail_notify(currentBuild, env, 'admin+jenkins-authentic2-auth-fc@entrouvert.com')
|
utils.mail_notify(currentBuild, env, 'admin+jenkins-authentic2-auth-fc@entrouvert.com')
|
||||||
utils.publish_coverage('coverage-*.xml')
|
utils.publish_coverage('coverage-*.xml')
|
||||||
utils.publish_coverage_native(
|
utils.publish_coverage_native(
|
||||||
'index.html', 'htmlcov-coverage-dj18-pg', 'Coverage a2-auth-fc PG')
|
'index.html', 'htmlcov-coverage-dj18-pg', 'Coverage a2-auth-fc dj18 PG')
|
||||||
utils.publish_coverage_native(
|
utils.publish_coverage_native(
|
||||||
'index.html', 'htmlcov-coverage-dj18-sqlite', 'Coverage a2-auth-fc SQLITE')
|
'index.html', 'htmlcov-coverage-dj18-sqlite', 'Coverage a2-auth-fc dj18 SQLITE')
|
||||||
|
utils.publish_coverage_native(
|
||||||
|
'index.html', 'htmlcov-coverage-dj111-pg', 'Coverage a2-auth-fc dj111 PG')
|
||||||
|
utils.publish_coverage_native(
|
||||||
|
'index.html', 'htmlcov-coverage-dj111-sqlite', 'Coverage a2-auth-fc dj111 SQLITE')
|
||||||
utils.publish_pylint('pylint.out')
|
utils.publish_pylint('pylint.out')
|
||||||
}
|
}
|
||||||
junit 'junit-*.xml'
|
junit 'junit-*.xml'
|
||||||
|
|
|
@ -8,6 +8,7 @@ import requests
|
||||||
from requests_oauthlib import OAuth2Session
|
from requests_oauthlib import OAuth2Session
|
||||||
|
|
||||||
|
|
||||||
|
import django
|
||||||
from django.views.generic import View, FormView
|
from django.views.generic import View, FormView
|
||||||
from django.views.generic.detail import SingleObjectMixin
|
from django.views.generic.detail import SingleObjectMixin
|
||||||
from django.http import HttpResponseRedirect, Http404
|
from django.http import HttpResponseRedirect, Http404
|
||||||
|
@ -22,6 +23,10 @@ from django.core.cache import InvalidCacheBackendError, caches
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.forms import Form
|
from django.forms import Form
|
||||||
|
try:
|
||||||
|
from django.contrib.auth.views import update_session_auth_hash
|
||||||
|
except ImportError:
|
||||||
|
update_session_auth_hash = None
|
||||||
|
|
||||||
from authentic2 import app_settings as a2_app_settings
|
from authentic2 import app_settings as a2_app_settings
|
||||||
from authentic2 import utils as a2_utils, hooks, constants
|
from authentic2 import utils as a2_utils, hooks, constants
|
||||||
|
@ -150,7 +155,11 @@ class FcOAuthSessionViewMixin(LoggerMixin):
|
||||||
else:
|
else:
|
||||||
redirect_to = request.GET.get(self.redirect_field_name, '')
|
redirect_to = request.GET.get(self.redirect_field_name, '')
|
||||||
|
|
||||||
if not is_safe_url(url=redirect_to, host=request.get_host()):
|
if django.VERSION < (1, 11):
|
||||||
|
safe = is_safe_url(url=redirect_to, host=request.get_host())
|
||||||
|
else:
|
||||||
|
safe = is_safe_url(url=redirect_to, allowed_hosts=[request.get_host()])
|
||||||
|
if not safe:
|
||||||
redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)
|
redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)
|
||||||
return redirect_to
|
return redirect_to
|
||||||
|
|
||||||
|
@ -523,6 +532,7 @@ class UnlinkView(LoggerMixin, FormView):
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
if self.must_set_password():
|
if self.must_set_password():
|
||||||
form.save()
|
form.save()
|
||||||
|
update_session_auth_hash(self.request, self.request.user)
|
||||||
self.logger.info(u'user %s has set a password', self.request.user)
|
self.logger.info(u'user %s has set a password', self.request.user)
|
||||||
links = models.FcAccount.objects.filter(user=self.request.user)
|
links = models.FcAccount.objects.filter(user=self.request.user)
|
||||||
for link in links:
|
for link in links:
|
||||||
|
|
|
@ -24,6 +24,15 @@ from authentic2_auth_fc.utils import requests_retry_session
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
|
def path(url):
|
||||||
|
return urlparse.urlparse(url).path
|
||||||
|
|
||||||
|
|
||||||
|
def path_and_query(url):
|
||||||
|
parsed = urlparse.urlparse(url)
|
||||||
|
return parsed.path + '?' + parsed.query
|
||||||
|
|
||||||
|
|
||||||
def get_links_from_mail(mail):
|
def get_links_from_mail(mail):
|
||||||
'''Extract links from mail sent by Django'''
|
'''Extract links from mail sent by Django'''
|
||||||
return re.findall('https?://[^ \n]*', mail.body)
|
return re.findall('https?://[^ \n]*', mail.body)
|
||||||
|
@ -113,7 +122,7 @@ def test_login_simple(app, fc_settings, caplog, hooks, exp):
|
||||||
else:
|
else:
|
||||||
assert User.objects.count() == 1
|
assert User.objects.count() == 1
|
||||||
if User.objects.count():
|
if User.objects.count():
|
||||||
assert response['Location'] == 'http://testserver/idp/'
|
assert path(response['Location']) == '/idp/'
|
||||||
assert hooks.event[1]['kwargs']['name'] == 'login'
|
assert hooks.event[1]['kwargs']['name'] == 'login'
|
||||||
assert hooks.event[1]['kwargs']['service'] == 'portail'
|
assert hooks.event[1]['kwargs']['service'] == 'portail'
|
||||||
# we must be connected
|
# we must be connected
|
||||||
|
@ -130,7 +139,7 @@ def test_login_simple(app, fc_settings, caplog, hooks, exp):
|
||||||
state = urlparse.parse_qs(urlparse.urlparse(continue_url).query)['state'][0]
|
state = urlparse.parse_qs(urlparse.urlparse(continue_url).query)['state'][0]
|
||||||
assert app.session['fc_states'][state]['next'] == '/accounts/'
|
assert app.session['fc_states'][state]['next'] == '/accounts/'
|
||||||
response = app.get(reverse('fc-logout') + '?state=' + state)
|
response = app.get(reverse('fc-logout') + '?state=' + state)
|
||||||
assert response['Location'] == 'http://testserver/accounts/'
|
assert path(response['Location']) == '/accounts/'
|
||||||
|
|
||||||
|
|
||||||
def test_login_email_is_unique(app, fc_settings, caplog):
|
def test_login_email_is_unique(app, fc_settings, caplog):
|
||||||
|
@ -327,7 +336,7 @@ def test_registration1(app, fc_settings, caplog, hooks):
|
||||||
with httmock.HTTMock(access_token_response, user_info_response):
|
with httmock.HTTMock(access_token_response, user_info_response):
|
||||||
response = app.get(callback + '&code=zzz&state=%s' % state, status=302)
|
response = app.get(callback + '&code=zzz&state=%s' % state, status=302)
|
||||||
assert User.objects.count() == 0
|
assert User.objects.count() == 0
|
||||||
assert response['Location'].startswith('http://testserver/login/')
|
assert path(response['Location']) == '/login/'
|
||||||
response = response.follow()
|
response = response.follow()
|
||||||
response = response.click('Create your account with FranceConnect')
|
response = response.click('Create your account with FranceConnect')
|
||||||
location = response['Location']
|
location = response['Location']
|
||||||
|
@ -336,7 +345,7 @@ def test_registration1(app, fc_settings, caplog, hooks):
|
||||||
assert hooks.calls['event'][0]['kwargs']['service'] == 'portail'
|
assert hooks.calls['event'][0]['kwargs']['service'] == 'portail'
|
||||||
# we must be connected
|
# we must be connected
|
||||||
assert app.session['_auth_user_id']
|
assert app.session['_auth_user_id']
|
||||||
assert response['Location'].startswith(callback)
|
assert path_and_query(response['Location']) == path_and_query(callback)
|
||||||
response = response.follow()
|
response = response.follow()
|
||||||
location = response['Location']
|
location = response['Location']
|
||||||
state = check_authorization_url(location)
|
state = check_authorization_url(location)
|
||||||
|
@ -354,7 +363,7 @@ def test_registration1(app, fc_settings, caplog, hooks):
|
||||||
state = urlparse.parse_qs(urlparse.urlparse(continue_url).query)['state'][0]
|
state = urlparse.parse_qs(urlparse.urlparse(continue_url).query)['state'][0]
|
||||||
assert app.session['fc_states'][state]['next'] == '/accounts/'
|
assert app.session['fc_states'][state]['next'] == '/accounts/'
|
||||||
response = app.get(reverse('fc-logout') + '?state=' + state)
|
response = app.get(reverse('fc-logout') + '?state=' + state)
|
||||||
assert response['Location'] == 'http://testserver/accounts/'
|
assert path(response['Location']) == '/accounts/'
|
||||||
|
|
||||||
|
|
||||||
def test_registration2(app, fc_settings, caplog, hooks):
|
def test_registration2(app, fc_settings, caplog, hooks):
|
||||||
|
@ -406,7 +415,7 @@ def test_registration2(app, fc_settings, caplog, hooks):
|
||||||
with httmock.HTTMock(access_token_response, user_info_response):
|
with httmock.HTTMock(access_token_response, user_info_response):
|
||||||
response = app.get(callback + '&code=zzz&state=%s' % state, status=302)
|
response = app.get(callback + '&code=zzz&state=%s' % state, status=302)
|
||||||
assert User.objects.count() == 0
|
assert User.objects.count() == 0
|
||||||
assert response['Location'].startswith('http://testserver/accounts/fc/register/')
|
assert path(response['Location']) == '/accounts/fc/register/'
|
||||||
response = response.follow()
|
response = response.follow()
|
||||||
location = response['Location']
|
location = response['Location']
|
||||||
location.startswith('http://testserver/accounts/activate/')
|
location.startswith('http://testserver/accounts/activate/')
|
||||||
|
@ -419,7 +428,7 @@ def test_registration2(app, fc_settings, caplog, hooks):
|
||||||
callback = callback.replace('®istration=', '')
|
callback = callback.replace('®istration=', '')
|
||||||
callback = callback.replace('?registration=', '?')
|
callback = callback.replace('?registration=', '?')
|
||||||
callback = callback.replace('?&', '?')
|
callback = callback.replace('?&', '?')
|
||||||
assert response['Location'].startswith(callback)
|
assert path_and_query(response['Location']) == path_and_query(callback)
|
||||||
response = response.follow()
|
response = response.follow()
|
||||||
location = response['Location']
|
location = response['Location']
|
||||||
state = check_authorization_url(location)
|
state = check_authorization_url(location)
|
||||||
|
@ -437,4 +446,4 @@ def test_registration2(app, fc_settings, caplog, hooks):
|
||||||
state = urlparse.parse_qs(urlparse.urlparse(continue_url).query)['state'][0]
|
state = urlparse.parse_qs(urlparse.urlparse(continue_url).query)['state'][0]
|
||||||
assert app.session['fc_states'][state]['next'] == '/accounts/'
|
assert app.session['fc_states'][state]['next'] == '/accounts/'
|
||||||
response = app.get(reverse('fc-logout') + '?state=' + state)
|
response = app.get(reverse('fc-logout') + '?state=' + state)
|
||||||
assert response['Location'] == 'http://testserver/accounts/'
|
assert path(response['Location']) == '/accounts/'
|
||||||
|
|
6
tox.ini
6
tox.ini
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
[tox]
|
[tox]
|
||||||
toxworkdir = {env:TMPDIR:/tmp}/tox-{env:USER}/authentic2-auth-fc/
|
toxworkdir = {env:TMPDIR:/tmp}/tox-{env:USER}/authentic2-auth-fc/
|
||||||
envlist = coverage-dj18-{pg,sqlite}
|
envlist = coverage-{dj18,dj111}-{pg,sqlite}
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
whitelist_externals =
|
whitelist_externals =
|
||||||
|
@ -24,6 +24,8 @@ usedevelop =
|
||||||
deps =
|
deps =
|
||||||
dj18: django>1.8,<1.9
|
dj18: django>1.8,<1.9
|
||||||
dj18: django-tables2<1.1
|
dj18: django-tables2<1.1
|
||||||
|
dj111: django<2.0
|
||||||
|
dj111: django-tables<2.0
|
||||||
pg: psycopg2
|
pg: psycopg2
|
||||||
coverage
|
coverage
|
||||||
pytest-cov
|
pytest-cov
|
||||||
|
@ -34,7 +36,7 @@ deps =
|
||||||
cssselect
|
cssselect
|
||||||
pylint
|
pylint
|
||||||
pylint-django
|
pylint-django
|
||||||
django-webtest
|
django-webtest<1.9.3
|
||||||
WebTest
|
WebTest
|
||||||
pyquery
|
pyquery
|
||||||
httmock
|
httmock
|
||||||
|
|
Reference in New Issue