diff --git a/cms/djangoapps/contentstore/features/common.py b/cms/djangoapps/contentstore/features/common.py index 42e3193cf3..c39e074d90 100644 --- a/cms/djangoapps/contentstore/features/common.py +++ b/cms/djangoapps/contentstore/features/common.py @@ -144,22 +144,10 @@ def log_into_studio( email='robot+studio@edx.org', 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('/') - 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(): course = world.CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course') @@ -176,7 +164,9 @@ def create_a_course(): group, __ = Group.objects.get_or_create(name=groupname) user.groups.add(group) user.save() - world.browser.reload() + + # Navigate to the studio dashboard + world.visit('/') course_link_css = 'a.course-link' world.css_click(course_link_css) course_title_css = 'span.course-title' diff --git a/cms/envs/acceptance.py b/cms/envs/acceptance.py index ecd22ed769..a1f5edb153 100644 --- a/cms/envs/acceptance.py +++ b/cms/envs/acceptance.py @@ -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 INSTALLED_APPS += ('lettuce.django',) LETTUCE_APPS = ('contentstore',) diff --git a/cms/urls.py b/cms/urls.py index 0beb21362e..8f396d3742 100644 --- a/cms/urls.py +++ b/cms/urls.py @@ -147,7 +147,7 @@ if settings.MITX_FEATURES.get('ENABLE_SERVICE_STATUS'): urlpatterns += (url(r'^admin/', include(admin.site.urls)),) # enable automatic login -if settings.MITX_FEATURES.get('AUTOMATIC_AUTH_FOR_LOAD_TESTING'): +if settings.MITX_FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING'): urlpatterns += ( url(r'^auto_auth$', 'student.views.auto_auth'), ) diff --git a/common/djangoapps/student/tests/test_auto_auth.py b/common/djangoapps/student/tests/test_auto_auth.py index dca2937b01..f9c4ae63de 100644 --- a/common/djangoapps/student/tests/test_auto_auth.py +++ b/common/djangoapps/student/tests/test_auto_auth.py @@ -11,9 +11,9 @@ class AutoAuthEnabledTestCase(UrlResetMixin, TestCase): 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): - # 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, # so we need to call super.setUp() which reloads urls.py (because # of the UrlResetMixin) @@ -37,6 +37,26 @@ class AutoAuthEnabledTestCase(UrlResetMixin, TestCase): user = qset[0] 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') def test_create_multiple_users(self, randint): """ @@ -50,8 +70,13 @@ class AutoAuthEnabledTestCase(UrlResetMixin, TestCase): 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) + 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}) def test_login_already_created_user(self): @@ -77,9 +102,9 @@ class AutoAuthDisabledTestCase(UrlResetMixin, TestCase): 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): - # 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, # so we need to call super.setUp() which reloads urls.py (because # of the UrlResetMixin) diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index bc6afdce0b..0b061f5a94 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -703,7 +703,7 @@ def create_account(request, post_override=None): 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 - if not (settings.MITX_FEATURES.get('AUTOMATIC_AUTH_FOR_LOAD_TESTING')): + if not (settings.MITX_FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING')): try: if settings.MITX_FEATURES.get('REROUTE_ACTIVATION_EMAIL'): dest_addr = settings.MITX_FEATURES['REROUTE_ACTIVATION_EMAIL'] @@ -942,31 +942,36 @@ def auto_auth(request): """ Automatically logs the user in with a generated random credentials 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 - of create_account, with specified username and password. + of create_account, with specified values. """ - return {'username': username, - 'email': username + "_dummy_test@mitx.mit.edu", + 'email': email, 'password': password, - 'name': username + " " + username, + 'name': name, 'honor_code': 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_' pass_base = 'PASS_' max_users = settings.MITX_FEATURES.get('MAX_AUTO_AUTH_USERS', 200) number = random.randint(1, max_users) - username = name_base + str(number) - password = pass_base + str(number) + # Get the params from the request to override default user attributes if specified + 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 try: @@ -976,7 +981,7 @@ def auto_auth(request): # else create and activate account info 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) request.user.is_active = True request.user.save() diff --git a/common/djangoapps/terrain/course_helpers.py b/common/djangoapps/terrain/course_helpers.py index 081e2a3bc2..afef8bf2e1 100644 --- a/common/djangoapps/terrain/course_helpers.py +++ b/common/djangoapps/terrain/course_helpers.py @@ -34,33 +34,17 @@ def create_user(uname, password): @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. - This will delete any existing cookies to ensure that the user - logs in to the correct session. + Use the auto_auth feature to programmatically log the user in """ + url = '/auto_auth?username=%s&password=%s&name=%s&email=%s' % (username, + password, name, email) + world.visit(url) - # Authenticate the user - world.scenario_dict['USER'] = authenticate(username=username, password=password) - assert(world.scenario_dict['USER'] is not None and world.scenario_dict['USER'].is_active) - - # 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) + # Save the user info in the world scenario_dict for use in the tests + user = User.objects.get(username=username) + world.scenario_dict['USER'] = user @world.absorb diff --git a/common/djangoapps/terrain/steps.py b/common/djangoapps/terrain/steps.py index 1c2e1e624c..9cf2aeda49 100644 --- a/common/djangoapps/terrain/steps.py +++ b/common/djangoapps/terrain/steps.py @@ -88,13 +88,13 @@ def the_page_title_should_contain(step, title): @step('I log in$') def i_log_in(step): - world.log_in('robot', 'test') + world.log_in(username='robot', password='test') @step('I am a logged in user$') def i_am_logged_in_user(step): world.create_user('robot', 'test') - world.log_in('robot', 'test') + world.log_in(username='robot', password='test') @step('I am not logged in$') @@ -147,7 +147,7 @@ def should_see_in_the_page(step, doesnt_appear, text): @step('I am logged in$') def i_am_logged_in(step): world.create_user('robot', 'test') - world.log_in('robot', 'test') + world.log_in(username='robot', password='test') world.browser.visit(django_url('/')) # You should not see the login link assert_equals(world.browser.find_by_css('a#login'), []) diff --git a/lms/djangoapps/courseware/features/common.py b/lms/djangoapps/courseware/features/common.py index 7632f22d6a..8b934e435d 100644 --- a/lms/djangoapps/courseware/features/common.py +++ b/lms/djangoapps/courseware/features/common.py @@ -55,7 +55,7 @@ def i_am_registered_for_the_course(step, course): # TODO: change to factory 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 "([^"]*)"$') diff --git a/lms/djangoapps/courseware/features/navigation.py b/lms/djangoapps/courseware/features/navigation.py index c87e6122a4..d4ac7060c4 100644 --- a/lms/djangoapps/courseware/features/navigation.py +++ b/lms/djangoapps/courseware/features/navigation.py @@ -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)) - world.log_in('robot', 'test') + world.log_in(username='robot', password='test') chapter_name = (TEST_SECTION_NAME + "1").replace(" ", "_") section_name = (TEST_SUBSECTION_NAME + "1").replace(" ", "_") url = django_url('/courses/edx/model_course/Test_Course/courseware/%s/%s' % diff --git a/lms/djangoapps/courseware/features/openended.py b/lms/djangoapps/courseware/features/openended.py index d848eb55d7..f7265be23c 100644 --- a/lms/djangoapps/courseware/features/openended.py +++ b/lms/djangoapps/courseware/features/openended.py @@ -11,7 +11,7 @@ logger = getLogger(__name__) @step('I navigate to an openended question$') def navigate_to_an_openended_question(step): 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/' world.browser.visit(django_url(problem)) tab_css = 'ol#sequence-list > li > a[data-element="5"]' @@ -21,7 +21,7 @@ def navigate_to_an_openended_question(step): @step('I navigate to an openended question as staff$') def navigate_to_an_openended_question_as_staff(step): 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/' world.browser.visit(django_url(problem)) tab_css = 'ol#sequence-list > li > a[data-element="5"]' diff --git a/lms/envs/acceptance.py b/lms/envs/acceptance.py index 5f8fd99c16..a58420ab1e 100644 --- a/lms/envs/acceptance.py +++ b/lms/envs/acceptance.py @@ -83,6 +83,9 @@ MITX_FEATURES['STUB_VIDEO_FOR_TESTING'] = True # per-test control for acceptance tests 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 INSTALLED_APPS += ('lettuce.django',) LETTUCE_APPS = ('courseware',) diff --git a/lms/envs/common.py b/lms/envs/common.py index 653040297c..0cbcbb774a 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -151,7 +151,7 @@ MITX_FEATURES = { 'ENABLE_HINTER_INSTRUCTOR_VIEW': False, # for load testing - 'AUTOMATIC_AUTH_FOR_LOAD_TESTING': False, + 'AUTOMATIC_AUTH_FOR_TESTING': False, # Toggle to enable chat availability (configured on a per-course # basis in Studio) diff --git a/lms/urls.py b/lms/urls.py index 380b5ea91d..b32c0263d0 100644 --- a/lms/urls.py +++ b/lms/urls.py @@ -439,7 +439,7 @@ if settings.MITX_FEATURES.get('ENABLE_HINTER_INSTRUCTOR_VIEW'): ) # enable automatic login -if settings.MITX_FEATURES.get('AUTOMATIC_AUTH_FOR_LOAD_TESTING'): +if settings.MITX_FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING'): urlpatterns += ( url(r'^auto_auth$', 'student.views.auto_auth'), )