diff --git a/AUTHORS b/AUTHORS index 94963e4630..2f4d7efead 100644 --- a/AUTHORS +++ b/AUTHORS @@ -89,3 +89,4 @@ Akshay Jagadeesh Nick Parlante Marko Seric Felipe Montoya +Julia Hansbrough diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b05af2a0fd..0b424adbfc 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,6 +7,8 @@ the top. Include a label indicating the component affected. LMS: Disable data download buttons on the instructor dashboard for large courses +LMS: Ported bulk emailing to the beta instructor dashboard. + LMS: Refactor and clean student dashboard templates. LMS: Fix issue with CourseMode expiration dates diff --git a/common/djangoapps/terrain/course_helpers.py b/common/djangoapps/terrain/course_helpers.py index 1d41e880ea..40c89b1087 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 @@ -50,6 +50,21 @@ def register_by_course_id(course_id, username='robot', password='test', is_staff 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(): # Flush and initialize the module store diff --git a/lms/djangoapps/instructor/features/bulk_email.feature b/lms/djangoapps/instructor/features/bulk_email.feature new file mode 100644 index 0000000000..8d3784c1ea --- /dev/null +++ b/lms/djangoapps/instructor/features/bulk_email.feature @@ -0,0 +1,20 @@ +@shard_2 +Feature: Bulk Email + As an instructor or course staff, + 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 "" for a course + When I send email to "" + Then Email is sent to "" + + Examples: + | Role | Recipient | + | instructor | myself | + | instructor | course staff | + | instructor | students, staff, and instructors | + | staff | myself | + | staff | course staff | + | 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..220ab9ecee --- /dev/null +++ b/lms/djangoapps/instructor/features/bulk_email.py @@ -0,0 +1,162 @@ +""" +Define steps for bulk email acceptance test. +""" + +#pylint: disable=C0111 +#pylint: disable=W0621 + +from lettuce import world, step +from lettuce.django import mail +from nose.tools import assert_in, assert_true, assert_equal # pylint: disable=E0611 +from django.core.management import call_command +from django.conf import settings + + +@step(u'I am an instructor for a course') +def i_am_an_instructor(step): # pylint: disable=W0613 + + # Clear existing courses to avoid conflicts + world.clear_courses() + + # 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