From c66b5dc3d49f6fbbc45d4d8ba6a0122d6934a870 Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 2 Oct 2013 17:09:06 -0400 Subject: [PATCH] Added acceptance tests for bulk email (through beta dashboard) --- common/djangoapps/terrain/course_helpers.py | 17 +- common/djangoapps/terrain/ui_helpers.py | 22 +-- .../instructor/features/bulk_email.feature | 16 ++ .../instructor/features/bulk_email.py | 165 ++++++++++++++++++ lms/envs/acceptance.py | 3 + .../instructor_dashboard_2/send_email.html | 2 +- 6 files changed, 213 insertions(+), 12 deletions(-) create mode 100644 lms/djangoapps/instructor/features/bulk_email.feature create mode 100644 lms/djangoapps/instructor/features/bulk_email.py diff --git a/common/djangoapps/terrain/course_helpers.py b/common/djangoapps/terrain/course_helpers.py index 1d41e880ea..0c95386445 100644 --- a/common/djangoapps/terrain/course_helpers.py +++ b/common/djangoapps/terrain/course_helpers.py @@ -2,7 +2,7 @@ # pylint: disable=W0621 from lettuce import world -from django.contrib.auth.models import User +from django.contrib.auth.models import User, Group from student.models import CourseEnrollment from xmodule.modulestore.django import editable_modulestore from xmodule.contentstore.django import contentstore @@ -41,6 +41,7 @@ def log_in(username='robot', password='test', email='robot@edx.org', name='Robot @world.absorb +<<<<<<< HEAD def register_by_course_id(course_id, username='robot', password='test', is_staff=False): create_user(username, password) user = User.objects.get(username=username) @@ -49,6 +50,20 @@ def register_by_course_id(course_id, username='robot', password='test', is_staff user.save() CourseEnrollment.enroll(user, course_id) +@world.absorb +def add_to_course_staff(username, course_num): + """ + Add the user with `username` to the course staff group + for `course_num`. + """ + # Based on code in lms/djangoapps/courseware/access.py + group_name = "instructor_{}".format(course_num) + group, _ = Group.objects.get_or_create(name=group_name) + group.save() + + user = User.objects.get(username=username) + user.groups.add(group) + @world.absorb def clear_courses(): diff --git a/common/djangoapps/terrain/ui_helpers.py b/common/djangoapps/terrain/ui_helpers.py index f973bcb4ac..3fdc14f544 100644 --- a/common/djangoapps/terrain/ui_helpers.py +++ b/common/djangoapps/terrain/ui_helpers.py @@ -228,20 +228,22 @@ def css_has_text(css_selector, text, index=0, strip=False): @world.absorb -def css_has_value(css_selector, value, index=0): +def css_has_text(css_selector, text, index=0, allow_blank=True): """ - Return a boolean indicating whether the element with - `css_selector` has the specified `value`. + Returns True only if the element with `css_selector` has + the specified `text`. - If there are multiple elements matching the css selector, - use `index` to indicate which one. + If there are multiple elements on the page, `index` specifies + which one to select. + + If `allow_blank` is False, wait for the element to have non-empty + text before making the assertion. This is useful for elements + that are populated by JavaScript after the page loads. """ - # If we're expecting a non-empty string, give the page - # a chance to fill in values - if value: - world.wait_for(lambda _: world.css_value(css_selector, index=index)) + if not allow_blank: + world.wait_for(lambda _: world.css_text(css_selector, index=index)) - return world.css_value(css_selector, index=index) == value + return world.css_text(css_selector, index=index) == text @world.absorb diff --git a/lms/djangoapps/instructor/features/bulk_email.feature b/lms/djangoapps/instructor/features/bulk_email.feature new file mode 100644 index 0000000000..7b46d1ec9b --- /dev/null +++ b/lms/djangoapps/instructor/features/bulk_email.feature @@ -0,0 +1,16 @@ +@shard_2 +Feature: Bulk Email + As an instructor, + In order to communicate with students and staff + I want to send email to staff and students in a course. + + Scenario: Send bulk email + Given I am an instructor for a course + When I send email to "" + Then Email is sent to "" + + Examples: + | Recipient | + | myself | + | course staff | + | students, staff, and instructors | diff --git a/lms/djangoapps/instructor/features/bulk_email.py b/lms/djangoapps/instructor/features/bulk_email.py new file mode 100644 index 0000000000..6706f0f430 --- /dev/null +++ b/lms/djangoapps/instructor/features/bulk_email.py @@ -0,0 +1,165 @@ +""" +Define steps for bulk email acceptance test. +""" + +from lettuce import world, step +from lettuce.django import mail +from nose.tools import assert_in, assert_true, assert_equal +from django.core.management import call_command + + +@step(u'I am an instructor for a course') +def i_am_an_instructor(step): + + # Clear existing courses to avoid conflicts + world.clear_courses() + + # Create a new course + course = world.CourseFactory.create( + org='edx', + number='999', + display_name='Test Course' + ) + + # Register the instructor as staff for the course + world.register_by_course_id( + 'edx/999/Test_Course', + username='instructor', + password='password', + is_staff=True + ) + world.add_to_course_staff('instructor', '999') + + # Register another staff member + world.register_by_course_id( + 'edx/999/Test_Course', + username='staff', + password='password', + is_staff=True + ) + world.add_to_course_staff('staff', '999') + + # Register a student + world.register_by_course_id( + 'edx/999/Test_Course', + username='student', + password='password', + is_staff=False + ) + + # Log in as the instructor for the course + world.log_in( + username='instructor', + password='password', + email="instructor@edx.org", + name="Instructor" + ) + + +# Dictionary mapping a description of the email recipient +# to the corresponding