Form expected test redirect urls properly.

This commit is contained in:
John Eskew
2017-12-27 17:24:12 -05:00
parent e67171b880
commit 1504c098a9
5 changed files with 42 additions and 24 deletions

View File

@@ -6,6 +6,7 @@ import json
import mock
from contextlib import contextmanager
import django
from django import test
from django.contrib import auth
from django.contrib.auth import models as auth_models
@@ -20,6 +21,7 @@ from social_django import views as social_views
from lms.djangoapps.commerce.tests import TEST_API_URL
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory
from openedx.tests.util import expected_redirect_url
from student import models as student_models
from student import views as student_views
from student.tests.factories import UserFactory
@@ -64,7 +66,7 @@ class IntegrationTestMixin(object):
provider_response = self.do_provider_login(try_login_response['Location'])
# We should be redirected to the register screen since this account is not linked to an edX account:
self.assertEqual(provider_response.status_code, 302)
self.assertEqual(provider_response['Location'], self.url_prefix + self.register_page_url)
self.assertEqual(provider_response['Location'], expected_redirect_url(self.register_page_url, hostname=self.hostname))
register_response = self.client.get(self.register_page_url)
tpa_context = register_response.context["data"]["third_party_auth"]
self.assertEqual(tpa_context["errorMessage"], None)
@@ -94,7 +96,7 @@ class IntegrationTestMixin(object):
continue_response = self.client.get(tpa_context["finishAuthUrl"])
# And we should be redirected to the dashboard:
self.assertEqual(continue_response.status_code, 302)
self.assertEqual(continue_response['Location'], self.url_prefix + reverse('dashboard'))
self.assertEqual(continue_response['Location'], expected_redirect_url(reverse('dashboard'), hostname=self.hostname))
# Now check that we can login again, whether or not we have yet verified the account:
self.client.logout()
@@ -115,7 +117,7 @@ class IntegrationTestMixin(object):
complete_response = self.do_provider_login(try_login_response['Location'])
# We should be redirected to the login screen since this account is not linked to an edX account:
self.assertEqual(complete_response.status_code, 302)
self.assertEqual(complete_response['Location'], self.url_prefix + self.login_page_url)
self.assertEqual(complete_response['Location'], expected_redirect_url(self.login_page_url, hostname=self.hostname))
login_response = self.client.get(self.login_page_url)
tpa_context = login_response.context["data"]["third_party_auth"]
self.assertEqual(tpa_context["errorMessage"], None)
@@ -132,7 +134,7 @@ class IntegrationTestMixin(object):
continue_response = self.client.get(tpa_context["finishAuthUrl"])
# And we should be redirected to the dashboard:
self.assertEqual(continue_response.status_code, 302)
self.assertEqual(continue_response['Location'], self.url_prefix + reverse('dashboard'))
self.assertEqual(continue_response['Location'], expected_redirect_url(reverse('dashboard'), hostname=self.hostname))
# Now check that we can login again:
self.client.logout()
@@ -161,7 +163,12 @@ class IntegrationTestMixin(object):
# required to set the login cookie (it sticks around if the main session times out):
if not previous_session_timed_out:
self.assertEqual(login_response.status_code, 302)
self.assertEqual(login_response['Location'], self.url_prefix + self.complete_url)
expected_url = expected_redirect_url(self.complete_url, hostname=self.hostname)
# TODO: Remove Django 1.11 upgrade shim
# SHIM: Get rid of this logic post-upgrade
if django.VERSION >= (1, 9):
expected_url = "{}?".format(expected_url)
self.assertEqual(login_response['Location'], expected_url)
# And then we should be redirected to the dashboard:
login_response = self.client.get(login_response['Location'])
self.assertEqual(login_response.status_code, 302)
@@ -169,7 +176,7 @@ class IntegrationTestMixin(object):
url_expected = reverse('dashboard')
else:
url_expected = reverse('third_party_inactive_redirect') + '?next=' + reverse('dashboard')
self.assertEqual(login_response['Location'], self.url_prefix + url_expected)
self.assertEqual(login_response['Location'], expected_redirect_url(url_expected, hostname=self.hostname))
# Now we are logged in:
dashboard_response = self.client.get(reverse('dashboard'))
self.assertEqual(dashboard_response.status_code, 200)

View File

@@ -6,6 +6,7 @@ from django.conf import settings
from django.core.urlresolvers import reverse
import json
from mock import patch
from openedx.tests.util import expected_redirect_url
from social_core.exceptions import AuthException
from student.tests.factories import UserFactory
from third_party_auth import pipeline
@@ -72,7 +73,7 @@ class GoogleOauth2IntegrationTest(base.Oauth2IntegrationTest):
response = self.client.get(complete_url)
# This should redirect to the custom login/register form:
self.assertEqual(response.status_code, 302)
self.assertEqual(response['Location'], 'http://example.none/auth/custom_auth_entry')
self.assertEqual(response['Location'], expected_redirect_url('/auth/custom_auth_entry', hostname='example.none'))
response = self.client.get(response['Location'])
self.assertEqual(response.status_code, 200)
@@ -106,7 +107,7 @@ class GoogleOauth2IntegrationTest(base.Oauth2IntegrationTest):
# Now our custom login/registration page must resume the pipeline:
response = self.client.get(complete_url)
self.assertEqual(response.status_code, 302)
self.assertEqual(response['Location'], 'http://example.none/misc/final-destination')
self.assertEqual(response['Location'], expected_redirect_url('/misc/final-destination', hostname='example.none'))
_, strategy = self.get_request_and_strategy()
self.assert_social_auth_exists_for_user(created_user, strategy)
@@ -133,4 +134,4 @@ class GoogleOauth2IntegrationTest(base.Oauth2IntegrationTest):
response = self.client.get(complete_url)
# This should redirect to the custom error URL
self.assertEqual(response.status_code, 302)
self.assertEqual(response['Location'], 'http://example.none/misc/my-custom-sso-error-page')
self.assertEqual(response['Location'], expected_redirect_url('/misc/my-custom-sso-error-page', hostname='example.none'))

View File

@@ -2,18 +2,20 @@
Integration tests for third_party_auth LTI auth providers
"""
import unittest
import django
from django.conf import settings
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from oauthlib.oauth1.rfc5849 import Client, SIGNATURE_TYPE_BODY
from openedx.tests.util import expected_redirect_url
from third_party_auth.tests import testutil
FORM_ENCODED = 'application/x-www-form-urlencoded'
LTI_CONSUMER_KEY = 'consumer'
LTI_CONSUMER_SECRET = 'secret'
LTI_TPA_LOGIN_URL = 'http://testserver/auth/login/lti/'
LTI_TPA_COMPLETE_URL = 'http://testserver/auth/complete/lti/'
LTI_TPA_LOGIN_URL = '/auth/login/lti/'
LTI_TPA_COMPLETE_URL = '/auth/complete/lti/'
OTHER_LTI_CONSUMER_KEY = 'settings-consumer'
OTHER_LTI_CONSUMER_SECRET = 'secret2'
LTI_USER_ID = 'lti_user_id'
@@ -29,8 +31,9 @@ class IntegrationTestLTI(testutil.TestCase):
def setUp(self):
super(IntegrationTestLTI, self).setUp()
self.client.defaults['SERVER_NAME'] = 'testserver'
self.url_prefix = 'http://testserver'
self.hostname = 'testserver'
self.client.defaults['SERVER_NAME'] = self.hostname
self.url_prefix = 'http://{}'.format(self.hostname)
self.configure_lti_provider(
name='Other Tool Consumer 1', enabled=True,
lti_consumer_key='other1',
@@ -58,7 +61,7 @@ class IntegrationTestLTI(testutil.TestCase):
def test_lti_login(self):
# The user initiates a login from an external site
(uri, _headers, body) = self.lti.sign(
uri=LTI_TPA_LOGIN_URL, http_method='POST',
uri=self.url_prefix + LTI_TPA_LOGIN_URL, http_method='POST',
headers={'Content-Type': FORM_ENCODED},
body={
'user_id': LTI_USER_ID,
@@ -85,27 +88,32 @@ class IntegrationTestLTI(testutil.TestCase):
}
)
self.assertEqual(ajax_register_response.status_code, 200)
continue_response = self.client.get(LTI_TPA_COMPLETE_URL)
continue_response = self.client.get(self.url_prefix + LTI_TPA_COMPLETE_URL)
# The user should be redirected to the finish_auth view which will enroll them.
# FinishAuthView.js reads the URL parameters directly from $.url
self.assertEqual(continue_response.status_code, 302)
self.assertEqual(
continue_response['Location'],
'http://testserver/account/finish_auth/?course_id=my_course_id&enrollment_action=enroll'
expected_redirect_url('/account/finish_auth/?course_id=my_course_id&enrollment_action=enroll')
)
# Now check that we can login again
self.client.logout()
self.verify_user_email(EMAIL)
(uri, _headers, body) = self.lti.sign(
uri=LTI_TPA_LOGIN_URL, http_method='POST',
uri=self.url_prefix + LTI_TPA_LOGIN_URL, http_method='POST',
headers={'Content-Type': FORM_ENCODED},
body={'user_id': LTI_USER_ID}
)
login_2_response = self.client.post(path=uri, content_type=FORM_ENCODED, data=body)
# The user should be redirected to the dashboard
self.assertEqual(login_2_response.status_code, 302)
self.assertEqual(login_2_response['Location'], LTI_TPA_COMPLETE_URL)
expected_url = expected_redirect_url(LTI_TPA_COMPLETE_URL)
# TODO: Remove Django 1.11 upgrade shim
# SHIM: Get rid of this logic post-upgrade
if django.VERSION >= (1, 9):
expected_url = "{}?".format(expected_url)
self.assertEqual(login_2_response['Location'], expected_url)
continue_2_response = self.client.get(login_2_response['Location'])
self.assertEqual(continue_2_response.status_code, 302)
self.assertTrue(continue_2_response['Location'].endswith(reverse('dashboard')))
@@ -115,12 +123,12 @@ class IntegrationTestLTI(testutil.TestCase):
self.assertEqual(user.username, EDX_USER_ID)
def test_reject_initiating_login(self):
response = self.client.get(LTI_TPA_LOGIN_URL)
response = self.client.get(self.url_prefix + LTI_TPA_LOGIN_URL)
self.assertEqual(response.status_code, 405) # Not Allowed
def test_reject_bad_login(self):
login_response = self.client.post(
path=LTI_TPA_LOGIN_URL, content_type=FORM_ENCODED,
path=self.url_prefix + LTI_TPA_LOGIN_URL, content_type=FORM_ENCODED,
data="invalid=login",
)
# The user should be redirected to the login page with an error message
@@ -140,7 +148,7 @@ class IntegrationTestLTI(testutil.TestCase):
signature_type=SIGNATURE_TYPE_BODY,
)
(uri, _headers, body) = lti.sign(
uri=LTI_TPA_LOGIN_URL, http_method='POST',
uri=self.url_prefix + LTI_TPA_LOGIN_URL, http_method='POST',
headers={'Content-Type': FORM_ENCODED},
body={
'user_id': LTI_USER_ID,

View File

@@ -13,6 +13,7 @@ from social_django.models import UserSocialAuth
from testfixtures import LogCapture
from unittest import skip
from openedx.tests.util import expected_redirect_url
from third_party_auth.saml import log as saml_log, SapSuccessFactorsIdentityProvider
from third_party_auth.tasks import fetch_saml_metadata
from third_party_auth.tests import testutil
@@ -135,7 +136,7 @@ class TestShibIntegrationTest(SamlIntegrationTestUtilities, IntegrationTestMixin
try_login_response = self.client.get(testshib_login_url)
# The user should be redirected to back to the login page:
self.assertEqual(try_login_response.status_code, 302)
self.assertEqual(try_login_response['Location'], self.url_prefix + self.login_page_url)
self.assertEqual(try_login_response['Location'], expected_redirect_url(self.login_page_url, hostname=self.hostname))
# When loading the login page, the user will see an error message:
response = self.client.get(self.login_page_url)
self.assertEqual(response.status_code, 200)

View File

@@ -187,8 +187,9 @@ class TestCase(ThirdPartyAuthTestMixin, django.test.TestCase):
super(TestCase, self).setUp()
# Explicitly set a server name that is compatible with all our providers:
# (The SAML lib we use doesn't like the default 'testserver' as a domain)
self.client.defaults['SERVER_NAME'] = 'example.none'
self.url_prefix = 'http://example.none'
self.hostname = 'example.none'
self.client.defaults['SERVER_NAME'] = self.hostname
self.url_prefix = 'http://{}'.format(self.hostname)
class SAMLTestCase(TestCase):