Skip to content
Snippets Groups Projects
Commit 82535f3b authored by Will Daly's avatar Will Daly Committed by Will Daly
Browse files

Enable and update bulk email acceptance test

parent ccd692dd
No related merge requests found
......@@ -197,7 +197,7 @@ def screenshot_on_error(scenario):
LOGGER.error('Could not capture a screenshot')
@after.all
@after.harvest
def teardown_browser(total):
"""
Quit the browser after executing the tests.
......
@shard_2
Feature: Bulk Email
Feature: LMS.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.
......@@ -17,4 +17,3 @@ Feature: Bulk Email
| staff | myself |
| staff | course staff |
| staff | students, staff, and instructors |
......@@ -12,12 +12,22 @@ 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
@step(u'Given I am "([^"]*)" for a course')
def i_am_an_instructor(step, role): # pylint: disable=W0613
# Store the role
assert_in(role, ['instructor', 'staff'])
# 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',
......@@ -44,14 +54,22 @@ def i_am_an_instructor(step): # pylint: disable=W0613
is_staff=False
)
# Log in as the instructor for the course
# Log in as the an instructor or staff for the course
world.log_in(
username='instructor',
username=role,
password='password',
email="instructor@edx.org",
name="Instructor"
)
# Store the expected recipients
# given each "send to" option
world.expected_addresses = {
'myself': [role + '@edx.org'],
'course staff': ['instructor@edx.org', 'staff@edx.org'],
'students, staff, and instructors': ['instructor@edx.org', 'staff@edx.org', 'student@edx.org']
}
# Dictionary mapping a description of the email recipient
# to the corresponding <option> value in the UI.
......@@ -63,7 +81,7 @@ SEND_TO_OPTIONS = {
@step(u'I send email to "([^"]*)"')
def when_i_send_an_email(recipient):
def when_i_send_an_email(step, recipient):
# Check that the recipient is valid
assert_in(
......@@ -71,6 +89,10 @@ def when_i_send_an_email(recipient):
msg="Invalid recipient: {}".format(recipient)
)
# Clear the queue of existing emails
while not mail.queue.empty(): # pylint: disable=E1101
mail.queue.get() # pylint: disable=E1101
# Because we flush the database before each run,
# we need to ensure that the email template fixture
# is re-loaded into the database
......@@ -95,27 +117,23 @@ def when_i_send_an_email(recipient):
# Click send
world.css_click('input[name="send"]')
# Confirm the alert
world.browser.get_alert().accept()
# Expect to see a message that the email was sent
expected_msg = "Your email was successfully queued for sending."
assert_true(
world.css_has_text('div.request-response', expected_msg, '#request-response', allow_blank=False),
world.wait_for_visible('#request-response')
assert_in(
expected_msg, world.css_text('#request-response'),
msg="Could not find email success message."
)
# Dictionaries mapping description of email recipient
# to the expected recipient email addresses
EXPECTED_ADDRESSES = {
'myself': ['instructor@edx.org'],
'course staff': ['instructor@edx.org', 'staff@edx.org'],
'students, staff, and instructors': ['instructor@edx.org', 'staff@edx.org', 'student@edx.org']
}
UNSUBSCRIBE_MSG = 'To stop receiving email like this'
@step(u'Email is sent to "([^"]*)"')
def then_the_email_is_sent(recipient):
def then_the_email_is_sent(step, recipient):
# Check that the recipient is valid
assert_in(
......@@ -131,9 +149,9 @@ def then_the_email_is_sent(recipient):
# Check that we got the right number of messages
assert_equal(
len(messages), len(EXPECTED_ADDRESSES[recipient]),
len(messages), len(world.expected_addresses[recipient]),
msg="Received {0} instead of {1} messages for {2}".format(
len(messages), len(EXPECTED_ADDRESSES[recipient]), recipient
len(messages), len(world.expected_addresses[recipient]), recipient
)
)
......@@ -141,7 +159,7 @@ def then_the_email_is_sent(recipient):
recipients = []
for msg in messages:
assert_in('Hello', msg.subject)
assert_in(settings.DEFAULT_BULK_FROM_EMAIL, msg.from_email)
assert_in(settings.BULK_EMAIL_DEFAULT_FROM_EMAIL, msg.from_email)
# Message body should have the message we sent
# and an unsubscribe message
......@@ -150,7 +168,8 @@ def then_the_email_is_sent(recipient):
# Should have alternative HTML form
assert_equal(len(msg.alternatives), 1)
content = msg.alternatives[0]
content, mime_type = msg.alternatives[0]
assert_equal(mime_type, 'text/html')
assert_in('test message', content)
assert_in(UNSUBSCRIBE_MSG, content)
......@@ -158,5 +177,8 @@ def then_the_email_is_sent(recipient):
recipients.extend(msg.recipients())
# Check that the messages were sent to the right people
for addr in EXPECTED_ADDRESSES[recipient]:
# Because "myself" can vary based on who sent the message,
# we use the world.expected_addresses dict we configured
# in an earlier step.
for addr in world.expected_addresses[recipient]:
assert_in(addr, recipients)
......@@ -80,7 +80,7 @@ TRACKING_BACKENDS.update({
}
})
DEFAULT_BULK_FROM_EMAIL = "test@test.org"
BULK_EMAIL_DEFAULT_FROM_EMAIL = "test@test.org"
# Forums are disabled in test.py to speed up unit tests, but we do not have
# per-test control for acceptance tests
......@@ -98,6 +98,8 @@ MITX_FEATURES['ENABLE_PAYMENT_FAKE'] = True
# Enable email on the instructor dash
MITX_FEATURES['ENABLE_INSTRUCTOR_EMAIL'] = True
MITX_FEATURES['REQUIRE_COURSE_EMAIL_AUTH'] = False
# Configure the payment processor to use the fake processing page
# Since both the fake payment page and the shoppingcart app are using
......@@ -123,7 +125,15 @@ FEEDBACK_SUBMISSION_EMAIL = 'dummy@example.com'
# Include the lettuce app for acceptance testing, including the 'harvest' django-admin command
INSTALLED_APPS += ('lettuce.django',)
LETTUCE_APPS = ('courseware',)
LETTUCE_APPS = ('courseware', 'instructor',)
# Lettuce appears to have a bug that causes it to search
# `instructor_task` when we specify the `instructor` app.
# This causes some pretty cryptic errors as lettuce tries
# to parse files in `instructor_task` as features.
# As a quick workaround, explicitly exclude the `instructor_task` app.
LETTUCE_AVOID_APPS = ('instructor_task',)
LETTUCE_BROWSER = os.environ.get('LETTUCE_BROWSER', 'chrome')
# Where to run: local, saucelabs, or grid
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment