Commit cd9d2085 by Jay Zoldak

Merge pull request #608 from edx/zoldak/auto-auth-acceptance

Auto auth can now accept parameters for user attributes.
parents 92f5246c 006b90af
...@@ -144,22 +144,10 @@ def log_into_studio( ...@@ -144,22 +144,10 @@ def log_into_studio(
email='robot+studio@edx.org', email='robot+studio@edx.org',
password='test'): password='test'):
world.browser.cookies.delete() world.log_in(username=uname, password=password, email=email, name='Robot Studio')
# Navigate to the studio dashboard
world.visit('/') world.visit('/')
signin_css = 'a.action-signin'
world.is_css_present(signin_css)
world.css_click(signin_css)
def fill_login_form():
login_form = world.browser.find_by_css('form#login_form')
login_form.find_by_name('email').fill(email)
login_form.find_by_name('password').fill(password)
login_form.find_by_name('submit').click()
world.retry_on_exception(fill_login_form)
assert_true(world.is_css_present('.new-course-button'))
world.scenario_dict['USER'] = get_user_by_email(email)
def create_a_course(): def create_a_course():
course = world.CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course') course = world.CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course')
...@@ -176,7 +164,9 @@ def create_a_course(): ...@@ -176,7 +164,9 @@ def create_a_course():
group, __ = Group.objects.get_or_create(name=groupname) group, __ = Group.objects.get_or_create(name=groupname)
user.groups.add(group) user.groups.add(group)
user.save() user.save()
world.browser.reload()
# Navigate to the studio dashboard
world.visit('/')
course_link_css = 'a.course-link' course_link_css = 'a.course-link'
world.css_click(course_link_css) world.css_click(course_link_css)
course_title_css = 'span.course-title' course_title_css = 'span.course-title'
......
...@@ -72,6 +72,9 @@ DATABASES = { ...@@ -72,6 +72,9 @@ DATABASES = {
} }
} }
# Use the auto_auth workflow for creating users and logging them in
MITX_FEATURES['AUTOMATIC_AUTH_FOR_TESTING'] = True
# Include the lettuce app for acceptance testing, including the 'harvest' django-admin command # Include the lettuce app for acceptance testing, including the 'harvest' django-admin command
INSTALLED_APPS += ('lettuce.django',) INSTALLED_APPS += ('lettuce.django',)
LETTUCE_APPS = ('contentstore',) LETTUCE_APPS = ('contentstore',)
......
...@@ -147,7 +147,7 @@ if settings.MITX_FEATURES.get('ENABLE_SERVICE_STATUS'): ...@@ -147,7 +147,7 @@ if settings.MITX_FEATURES.get('ENABLE_SERVICE_STATUS'):
urlpatterns += (url(r'^admin/', include(admin.site.urls)),) urlpatterns += (url(r'^admin/', include(admin.site.urls)),)
# enable automatic login # enable automatic login
if settings.MITX_FEATURES.get('AUTOMATIC_AUTH_FOR_LOAD_TESTING'): if settings.MITX_FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING'):
urlpatterns += ( urlpatterns += (
url(r'^auto_auth$', 'student.views.auto_auth'), url(r'^auto_auth$', 'student.views.auto_auth'),
) )
......
...@@ -11,9 +11,9 @@ class AutoAuthEnabledTestCase(UrlResetMixin, TestCase): ...@@ -11,9 +11,9 @@ class AutoAuthEnabledTestCase(UrlResetMixin, TestCase):
Tests for the Auto auth view that we have for load testing. Tests for the Auto auth view that we have for load testing.
""" """
@patch.dict("django.conf.settings.MITX_FEATURES", {"AUTOMATIC_AUTH_FOR_LOAD_TESTING": True}) @patch.dict("django.conf.settings.MITX_FEATURES", {"AUTOMATIC_AUTH_FOR_TESTING": True})
def setUp(self): def setUp(self):
# Patching the settings.MITX_FEATURES['AUTOMATIC_AUTH_FOR_LOAD_TESTING'] # Patching the settings.MITX_FEATURES['AUTOMATIC_AUTH_FOR_TESTING']
# value affects the contents of urls.py, # value affects the contents of urls.py,
# so we need to call super.setUp() which reloads urls.py (because # so we need to call super.setUp() which reloads urls.py (because
# of the UrlResetMixin) # of the UrlResetMixin)
...@@ -37,6 +37,26 @@ class AutoAuthEnabledTestCase(UrlResetMixin, TestCase): ...@@ -37,6 +37,26 @@ class AutoAuthEnabledTestCase(UrlResetMixin, TestCase):
user = qset[0] user = qset[0]
assert user.is_active assert user.is_active
def test_create_defined_user(self):
"""
Test that the user gets created with the correct attributes
when they are passed as parameters on the auto-auth page.
"""
self.client.get(
self.url,
{'username': 'robot', 'password': 'test', 'email': 'robot@edx.org'}
)
qset = User.objects.all()
# assert user was created with the correct username and password
self.assertEqual(qset.count(), 1)
user = qset[0]
self.assertEqual(user.username, 'robot')
self.assertTrue(user.check_password('test'))
self.assertEqual(user.email, 'robot@edx.org')
@patch('student.views.random.randint') @patch('student.views.random.randint')
def test_create_multiple_users(self, randint): def test_create_multiple_users(self, randint):
""" """
...@@ -50,8 +70,13 @@ class AutoAuthEnabledTestCase(UrlResetMixin, TestCase): ...@@ -50,8 +70,13 @@ class AutoAuthEnabledTestCase(UrlResetMixin, TestCase):
qset = User.objects.all() qset = User.objects.all()
# make sure that USER_1 and USER_2 were created # make sure that USER_1 and USER_2 were created correctly
self.assertEqual(qset.count(), 2) self.assertEqual(qset.count(), 2)
user1 = qset[0]
self.assertEqual(user1.username, 'USER_1')
self.assertTrue(user1.check_password('PASS_1'))
self.assertEqual(user1.email, 'USER_1_dummy_test@mitx.mit.edu')
self.assertEqual(qset[1].username, 'USER_2')
@patch.dict("django.conf.settings.MITX_FEATURES", {"MAX_AUTO_AUTH_USERS": 1}) @patch.dict("django.conf.settings.MITX_FEATURES", {"MAX_AUTO_AUTH_USERS": 1})
def test_login_already_created_user(self): def test_login_already_created_user(self):
...@@ -77,9 +102,9 @@ class AutoAuthDisabledTestCase(UrlResetMixin, TestCase): ...@@ -77,9 +102,9 @@ class AutoAuthDisabledTestCase(UrlResetMixin, TestCase):
Test that the page is inaccessible with default settings Test that the page is inaccessible with default settings
""" """
@patch.dict("django.conf.settings.MITX_FEATURES", {"AUTOMATIC_AUTH_FOR_LOAD_TESTING": False}) @patch.dict("django.conf.settings.MITX_FEATURES", {"AUTOMATIC_AUTH_FOR_TESTING": False})
def setUp(self): def setUp(self):
# Patching the settings.MITX_FEATURES['AUTOMATIC_AUTH_FOR_LOAD_TESTING'] # Patching the settings.MITX_FEATURES['AUTOMATIC_AUTH_FOR_TESTING']
# value affects the contents of urls.py, # value affects the contents of urls.py,
# so we need to call super.setUp() which reloads urls.py (because # so we need to call super.setUp() which reloads urls.py (because
# of the UrlResetMixin) # of the UrlResetMixin)
......
...@@ -703,7 +703,7 @@ def create_account(request, post_override=None): ...@@ -703,7 +703,7 @@ def create_account(request, post_override=None):
message = render_to_string('emails/activation_email.txt', d) message = render_to_string('emails/activation_email.txt', d)
# dont send email if we are doing load testing or random user generation for some reason # dont send email if we are doing load testing or random user generation for some reason
if not (settings.MITX_FEATURES.get('AUTOMATIC_AUTH_FOR_LOAD_TESTING')): if not (settings.MITX_FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING')):
try: try:
if settings.MITX_FEATURES.get('REROUTE_ACTIVATION_EMAIL'): if settings.MITX_FEATURES.get('REROUTE_ACTIVATION_EMAIL'):
dest_addr = settings.MITX_FEATURES['REROUTE_ACTIVATION_EMAIL'] dest_addr = settings.MITX_FEATURES['REROUTE_ACTIVATION_EMAIL']
...@@ -942,31 +942,36 @@ def auto_auth(request): ...@@ -942,31 +942,36 @@ def auto_auth(request):
""" """
Automatically logs the user in with a generated random credentials Automatically logs the user in with a generated random credentials
This view is only accessible when This view is only accessible when
settings.MITX_SETTINGS['AUTOMATIC_AUTH_FOR_LOAD_TESTING'] is true. settings.MITX_SETTINGS['AUTOMATIC_AUTH_FOR_TESTING'] is true.
""" """
def get_dummy_post_data(username, password): def get_dummy_post_data(username, password, email, name):
""" """
Return a dictionary suitable for passing to post_vars of _do_create_account or post_override Return a dictionary suitable for passing to post_vars of _do_create_account or post_override
of create_account, with specified username and password. of create_account, with specified values.
""" """
return {'username': username, return {'username': username,
'email': username + "_dummy_test@mitx.mit.edu", 'email': email,
'password': password, 'password': password,
'name': username + " " + username, 'name': name,
'honor_code': u'true', 'honor_code': u'true',
'terms_of_service': u'true', } 'terms_of_service': u'true', }
# generate random user ceredentials from a small name space (determined by settings) # generate random user credentials from a small name space (determined by settings)
name_base = 'USER_' name_base = 'USER_'
pass_base = 'PASS_' pass_base = 'PASS_'
max_users = settings.MITX_FEATURES.get('MAX_AUTO_AUTH_USERS', 200) max_users = settings.MITX_FEATURES.get('MAX_AUTO_AUTH_USERS', 200)
number = random.randint(1, max_users) number = random.randint(1, max_users)
username = name_base + str(number) # Get the params from the request to override default user attributes if specified
password = pass_base + str(number) qdict = request.GET
# Use the params from the request, otherwise use these defaults
username = qdict.get('username', name_base + str(number))
password = qdict.get('password', pass_base + str(number))
email = qdict.get('email', '%s_dummy_test@mitx.mit.edu' % username)
name = qdict.get('name', '%s Test' % username)
# if they already are a user, log in # if they already are a user, log in
try: try:
...@@ -976,7 +981,7 @@ def auto_auth(request): ...@@ -976,7 +981,7 @@ def auto_auth(request):
# else create and activate account info # else create and activate account info
except ObjectDoesNotExist: except ObjectDoesNotExist:
post_override = get_dummy_post_data(username, password) post_override = get_dummy_post_data(username, password, email, name)
create_account(request, post_override=post_override) create_account(request, post_override=post_override)
request.user.is_active = True request.user.is_active = True
request.user.save() request.user.save()
......
...@@ -34,33 +34,17 @@ def create_user(uname, password): ...@@ -34,33 +34,17 @@ def create_user(uname, password):
@world.absorb @world.absorb
def log_in(username, password): def log_in(username='robot', password='test', email='robot@edx.org', name='Robot'):
""" """
Log the user in programatically. Use the auto_auth feature to programmatically log the user in
This will delete any existing cookies to ensure that the user
logs in to the correct session.
""" """
url = '/auto_auth?username=%s&password=%s&name=%s&email=%s' % (username,
password, name, email)
world.visit(url)
# Authenticate the user # Save the user info in the world scenario_dict for use in the tests
world.scenario_dict['USER'] = authenticate(username=username, password=password) user = User.objects.get(username=username)
assert(world.scenario_dict['USER'] is not None and world.scenario_dict['USER'].is_active) world.scenario_dict['USER'] = user
# Send a fake HttpRequest to log the user in
# We need to process the request using
# Session middleware and Authentication middleware
# to ensure that session state can be stored
request = HttpRequest()
SessionMiddleware().process_request(request)
AuthenticationMiddleware().process_request(request)
login(request, world.scenario_dict['USER'])
# Save the session
request.session.save()
# Retrieve the sessionid and add it to the browser's cookies
cookie_dict = {settings.SESSION_COOKIE_NAME: request.session.session_key}
world.browser.cookies.delete()
world.browser.cookies.add(cookie_dict)
@world.absorb @world.absorb
......
...@@ -88,13 +88,13 @@ def the_page_title_should_contain(step, title): ...@@ -88,13 +88,13 @@ def the_page_title_should_contain(step, title):
@step('I log in$') @step('I log in$')
def i_log_in(step): def i_log_in(step):
world.log_in('robot', 'test') world.log_in(username='robot', password='test')
@step('I am a logged in user$') @step('I am a logged in user$')
def i_am_logged_in_user(step): def i_am_logged_in_user(step):
world.create_user('robot', 'test') world.create_user('robot', 'test')
world.log_in('robot', 'test') world.log_in(username='robot', password='test')
@step('I am not logged in$') @step('I am not logged in$')
...@@ -147,7 +147,7 @@ def should_see_in_the_page(step, doesnt_appear, text): ...@@ -147,7 +147,7 @@ def should_see_in_the_page(step, doesnt_appear, text):
@step('I am logged in$') @step('I am logged in$')
def i_am_logged_in(step): def i_am_logged_in(step):
world.create_user('robot', 'test') world.create_user('robot', 'test')
world.log_in('robot', 'test') world.log_in(username='robot', password='test')
world.browser.visit(django_url('/')) world.browser.visit(django_url('/'))
# You should not see the login link # You should not see the login link
assert_equals(world.browser.find_by_css('a#login'), []) assert_equals(world.browser.find_by_css('a#login'), [])
......
...@@ -55,7 +55,7 @@ def i_am_registered_for_the_course(step, course): ...@@ -55,7 +55,7 @@ def i_am_registered_for_the_course(step, course):
# TODO: change to factory # TODO: change to factory
CourseEnrollment.objects.get_or_create(user=u, course_id=course_id(course)) CourseEnrollment.objects.get_or_create(user=u, course_id=course_id(course))
world.log_in('robot', 'test') world.log_in(username='robot', password='test')
@step(u'The course "([^"]*)" has extra tab "([^"]*)"$') @step(u'The course "([^"]*)" has extra tab "([^"]*)"$')
......
...@@ -151,7 +151,7 @@ def create_user_and_visit_course(): ...@@ -151,7 +151,7 @@ def create_user_and_visit_course():
CourseEnrollment.objects.get_or_create(user=u, course_id=course_id(world.scenario_dict['COURSE'].number)) CourseEnrollment.objects.get_or_create(user=u, course_id=course_id(world.scenario_dict['COURSE'].number))
world.log_in('robot', 'test') world.log_in(username='robot', password='test')
chapter_name = (TEST_SECTION_NAME + "1").replace(" ", "_") chapter_name = (TEST_SECTION_NAME + "1").replace(" ", "_")
section_name = (TEST_SUBSECTION_NAME + "1").replace(" ", "_") section_name = (TEST_SUBSECTION_NAME + "1").replace(" ", "_")
url = django_url('/courses/edx/model_course/Test_Course/courseware/%s/%s' % url = django_url('/courses/edx/model_course/Test_Course/courseware/%s/%s' %
......
...@@ -11,7 +11,7 @@ logger = getLogger(__name__) ...@@ -11,7 +11,7 @@ logger = getLogger(__name__)
@step('I navigate to an openended question$') @step('I navigate to an openended question$')
def navigate_to_an_openended_question(step): def navigate_to_an_openended_question(step):
world.register_by_course_id('MITx/3.091x/2012_Fall') world.register_by_course_id('MITx/3.091x/2012_Fall')
world.log_in('robot@edx.org', 'test') world.log_in(email='robot@edx.org', password='test')
problem = '/courses/MITx/3.091x/2012_Fall/courseware/Week_10/Polymer_Synthesis/' problem = '/courses/MITx/3.091x/2012_Fall/courseware/Week_10/Polymer_Synthesis/'
world.browser.visit(django_url(problem)) world.browser.visit(django_url(problem))
tab_css = 'ol#sequence-list > li > a[data-element="5"]' tab_css = 'ol#sequence-list > li > a[data-element="5"]'
...@@ -21,7 +21,7 @@ def navigate_to_an_openended_question(step): ...@@ -21,7 +21,7 @@ def navigate_to_an_openended_question(step):
@step('I navigate to an openended question as staff$') @step('I navigate to an openended question as staff$')
def navigate_to_an_openended_question_as_staff(step): def navigate_to_an_openended_question_as_staff(step):
world.register_by_course_id('MITx/3.091x/2012_Fall', True) world.register_by_course_id('MITx/3.091x/2012_Fall', True)
world.log_in('robot@edx.org', 'test') world.log_in(email='robot@edx.org', password='test')
problem = '/courses/MITx/3.091x/2012_Fall/courseware/Week_10/Polymer_Synthesis/' problem = '/courses/MITx/3.091x/2012_Fall/courseware/Week_10/Polymer_Synthesis/'
world.browser.visit(django_url(problem)) world.browser.visit(django_url(problem))
tab_css = 'ol#sequence-list > li > a[data-element="5"]' tab_css = 'ol#sequence-list > li > a[data-element="5"]'
......
...@@ -83,6 +83,9 @@ MITX_FEATURES['STUB_VIDEO_FOR_TESTING'] = True ...@@ -83,6 +83,9 @@ MITX_FEATURES['STUB_VIDEO_FOR_TESTING'] = True
# per-test control for acceptance tests # per-test control for acceptance tests
MITX_FEATURES['ENABLE_DISCUSSION_SERVICE'] = True MITX_FEATURES['ENABLE_DISCUSSION_SERVICE'] = True
# Use the auto_auth workflow for creating users and logging them in
MITX_FEATURES['AUTOMATIC_AUTH_FOR_TESTING'] = True
# Include the lettuce app for acceptance testing, including the 'harvest' django-admin command # Include the lettuce app for acceptance testing, including the 'harvest' django-admin command
INSTALLED_APPS += ('lettuce.django',) INSTALLED_APPS += ('lettuce.django',)
LETTUCE_APPS = ('courseware',) LETTUCE_APPS = ('courseware',)
......
...@@ -151,7 +151,7 @@ MITX_FEATURES = { ...@@ -151,7 +151,7 @@ MITX_FEATURES = {
'ENABLE_HINTER_INSTRUCTOR_VIEW': False, 'ENABLE_HINTER_INSTRUCTOR_VIEW': False,
# for load testing # for load testing
'AUTOMATIC_AUTH_FOR_LOAD_TESTING': False, 'AUTOMATIC_AUTH_FOR_TESTING': False,
# Toggle to enable chat availability (configured on a per-course # Toggle to enable chat availability (configured on a per-course
# basis in Studio) # basis in Studio)
......
...@@ -439,7 +439,7 @@ if settings.MITX_FEATURES.get('ENABLE_HINTER_INSTRUCTOR_VIEW'): ...@@ -439,7 +439,7 @@ if settings.MITX_FEATURES.get('ENABLE_HINTER_INSTRUCTOR_VIEW'):
) )
# enable automatic login # enable automatic login
if settings.MITX_FEATURES.get('AUTOMATIC_AUTH_FOR_LOAD_TESTING'): if settings.MITX_FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING'):
urlpatterns += ( urlpatterns += (
url(r'^auto_auth$', 'student.views.auto_auth'), url(r'^auto_auth$', 'student.views.auto_auth'),
) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment