test_legacy_enrollment.py 14.9 KB
Newer Older
1
"""
dcadams committed
2
Unit tests for enrollment methods in views.py
3

4
"""
5

6
import ddt
7
from mock import patch
8
from nose.plugins.attrib import attr
9

10
from django.contrib.auth.models import User
11
from django.core.urlresolvers import reverse
12
from courseware.tests.helpers import LoginEnrollmentTestCase
13 14
from xmodule.modulestore.tests.factories import CourseFactory
from student.tests.factories import UserFactory, CourseEnrollmentFactory, AdminFactory
15
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
16
from student.models import CourseEnrollment, CourseEnrollmentAllowed
17
from instructor.views.legacy import get_and_clean_student_list, send_mail_to_student
18
from django.core import mail
19

20
USER_COUNT = 4
21

22

23
@attr('shard_1')
24
@ddt.ddt
25
class TestInstructorEnrollsStudent(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
26 27 28
    """
    Check Enrollment/Unenrollment with/without auto-enrollment on activation and with/without email notification
    """
29 30 31 32
    @classmethod
    def setUpClass(cls):
        super(TestInstructorEnrollsStudent, cls).setUpClass()
        cls.course = CourseFactory.create()
33 34

    def setUp(self):
35
        super(TestInstructorEnrollsStudent, self).setUp()
36

37 38
        instructor = AdminFactory.create()
        self.client.login(username=instructor.username, password='test')
39

40 41 42 43
        self.users = [
            UserFactory.create(username="student%d" % i, email="student%d@test.com" % i)
            for i in xrange(USER_COUNT)
        ]
44

45 46
        for user in self.users:
            CourseEnrollmentFactory.create(user=user, course_id=self.course.id)
dcadams committed
47

48 49
        # Empty the test outbox
        mail.outbox = []
dcadams committed
50

51 52 53 54
    def test_unenrollment_email_off(self):
        """
        Do un-enrollment email off test
        """
55

56
        course = self.course
57

58
        # Run the Un-enroll students command
Calen Pennington committed
59
        url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id.to_deprecated_string()})
60 61 62 63 64 65 66
        response = self.client.post(
            url,
            {
                'action': 'Unenroll multiple students',
                'multiple_students': 'student0@test.com student1@test.com'
            }
        )
dcadams committed
67

68
        # Check the page output
69
        self.assertContains(response, '<td>student0@test.com</td>')
70 71
        self.assertContains(response, '<td>student1@test.com</td>')
        self.assertContains(response, '<td>un-enrolled</td>')
dcadams committed
72

73
        # Check the enrollment table
74
        user = User.objects.get(email='student0@test.com')
75
        self.assertFalse(CourseEnrollment.is_enrolled(user, course.id))
dcadams committed
76

77
        user = User.objects.get(email='student1@test.com')
78
        self.assertFalse(CourseEnrollment.is_enrolled(user, course.id))
79

80
        # Check the outbox
81 82 83 84 85 86 87 88
        self.assertEqual(len(mail.outbox), 0)

    def test_enrollment_new_student_autoenroll_on_email_off(self):
        """
        Do auto-enroll on, email off test
        """

        course = self.course
dcadams committed
89

90
        # Run the Enroll students command
Calen Pennington committed
91
        url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id.to_deprecated_string()})
92
        response = self.client.post(url, {'action': 'Enroll multiple students', 'multiple_students': 'student1_1@test.com, student1_2@test.com', 'auto_enroll': 'on'})
dcadams committed
93

94
        # Check the page output
95 96
        self.assertContains(response, '<td>student1_1@test.com</td>')
        self.assertContains(response, '<td>student1_2@test.com</td>')
97
        self.assertContains(response, '<td>user does not exist, enrollment allowed, pending with auto enrollment on</td>')
dcadams committed
98

99
        # Check the outbox
100 101
        self.assertEqual(len(mail.outbox), 0)

102
        # Check the enrollmentallowed db entries
103
        cea = CourseEnrollmentAllowed.objects.filter(email='student1_1@test.com', course_id=course.id)
104
        self.assertEqual(1, cea[0].auto_enroll)
105
        cea = CourseEnrollmentAllowed.objects.filter(email='student1_2@test.com', course_id=course.id)
106
        self.assertEqual(1, cea[0].auto_enroll)
dcadams committed
107

108
        # Check there is no enrollment db entry other than for the other students
109
        ce = CourseEnrollment.objects.filter(course_id=course.id, is_active=1)
110
        self.assertEqual(4, len(ce))
dcadams committed
111

112
        # Create and activate student accounts with same email
113
        self.student1 = 'student1_1@test.com'
114 115 116
        self.password = 'bar'
        self.create_account('s1_1', self.student1, self.password)
        self.activate_user(self.student1)
dcadams committed
117

118
        self.student2 = 'student1_2@test.com'
119 120
        self.create_account('s1_2', self.student2, self.password)
        self.activate_user(self.student2)
dcadams committed
121

122
        # Check students are enrolled
123
        user = User.objects.get(email='student1_1@test.com')
124
        self.assertTrue(CourseEnrollment.is_enrolled(user, course.id))
dcadams committed
125

126
        user = User.objects.get(email='student1_2@test.com')
127
        self.assertTrue(CourseEnrollment.is_enrolled(user, course.id))
128

129 130 131 132 133 134 135
    def test_repeat_enroll(self):
        """
        Try to enroll an already enrolled student
        """

        course = self.course

Calen Pennington committed
136
        url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id.to_deprecated_string()})
137 138 139 140 141 142 143 144 145 146
        response = self.client.post(url, {'action': 'Enroll multiple students', 'multiple_students': 'student0@test.com', 'auto_enroll': 'on'})
        self.assertContains(response, '<td>student0@test.com</td>')
        self.assertContains(response, '<td>already enrolled</td>')

    def test_enrollmemt_new_student_autoenroll_off_email_off(self):
        """
        Do auto-enroll off, email off test
        """

        course = self.course
dcadams committed
147

148
        # Run the Enroll students command
Calen Pennington committed
149
        url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id.to_deprecated_string()})
150
        response = self.client.post(url, {'action': 'Enroll multiple students', 'multiple_students': 'student2_1@test.com, student2_2@test.com'})
dcadams committed
151

152
        # Check the page output
153 154
        self.assertContains(response, '<td>student2_1@test.com</td>')
        self.assertContains(response, '<td>student2_2@test.com</td>')
155
        self.assertContains(response, '<td>user does not exist, enrollment allowed, pending with auto enrollment off</td>')
dcadams committed
156

157
        # Check the outbox
158 159
        self.assertEqual(len(mail.outbox), 0)

160
        # Check the enrollmentallowed db entries
161
        cea = CourseEnrollmentAllowed.objects.filter(email='student2_1@test.com', course_id=course.id)
162
        self.assertEqual(0, cea[0].auto_enroll)
163
        cea = CourseEnrollmentAllowed.objects.filter(email='student2_2@test.com', course_id=course.id)
164
        self.assertEqual(0, cea[0].auto_enroll)
dcadams committed
165

166
        # Check there is no enrollment db entry other than for the setup instructor and students
167
        ce = CourseEnrollment.objects.filter(course_id=course.id, is_active=1)
168
        self.assertEqual(4, len(ce))
dcadams committed
169

170
        # Create and activate student accounts with same email
171
        self.student = 'student2_1@test.com'
172 173 174
        self.password = 'bar'
        self.create_account('s2_1', self.student, self.password)
        self.activate_user(self.student)
dcadams committed
175

176
        self.student = 'student2_2@test.com'
177
        self.create_account('s2_2', self.student, self.password)
dcadams committed
178 179
        self.activate_user(self.student)

180
        # Check students are not enrolled
181
        user = User.objects.get(email='student2_1@test.com')
182 183
        self.assertFalse(CourseEnrollment.is_enrolled(user, course.id))

184
        user = User.objects.get(email='student2_2@test.com')
185
        self.assertFalse(CourseEnrollment.is_enrolled(user, course.id))
186 187

    def test_get_and_clean_student_list(self):
188
        """
189
        Clean user input test
190
        """
191

192
        string = "abc@test.com, def@test.com ghi@test.com \n \n jkl@test.com   \n mno@test.com   "
stv committed
193
        cleaned_string, _cleaned_string_lc = get_and_clean_student_list(string)
194 195
        self.assertEqual(cleaned_string, ['abc@test.com', 'def@test.com', 'ghi@test.com', 'jkl@test.com', 'mno@test.com'])

196 197
    @ddt.data('http', 'https')
    def test_enrollment_email_on(self, protocol):
198 199 200 201 202 203
        """
        Do email on enroll test
        """

        course = self.course

204
        # Create activated, but not enrolled, user
205
        UserFactory.create(username="student3_0", email="student3_0@test.com", first_name='Autoenrolled')
206

Calen Pennington committed
207
        url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id.to_deprecated_string()})
208 209 210
        params = {'action': 'Enroll multiple students', 'multiple_students': 'student3_0@test.com, student3_1@test.com, student3_2@test.com', 'auto_enroll': 'on', 'email_students': 'on'}
        environ = {'wsgi.url_scheme': protocol}
        response = self.client.post(url, params, **environ)
211

212
        # Check the page output
213 214 215 216 217 218
        self.assertContains(response, '<td>student3_0@test.com</td>')
        self.assertContains(response, '<td>student3_1@test.com</td>')
        self.assertContains(response, '<td>student3_2@test.com</td>')
        self.assertContains(response, '<td>added, email sent</td>')
        self.assertContains(response, '<td>user does not exist, enrollment allowed, pending with auto enrollment on, email sent</td>')

219
        # Check the outbox
220
        self.assertEqual(len(mail.outbox), 3)
Adam Palay committed
221 222
        self.assertEqual(
            mail.outbox[0].subject,
Don Mitchell committed
223
            'You have been enrolled in {}'.format(course.display_name)
Adam Palay committed
224 225 226
        )
        self.assertEqual(
            mail.outbox[0].body,
Don Mitchell committed
227
            "Dear Autoenrolled Test\n\nYou have been enrolled in {} "
Adam Palay committed
228 229 230
            "at edx.org by a member of the course staff. "
            "The course should now appear on your edx.org dashboard.\n\n"
            "To start accessing course materials, please visit "
Don Mitchell committed
231 232 233 234
            "{}://edx.org/courses/{}/\n\n"
            "----\nThis email was automatically sent from edx.org to Autoenrolled Test".format(
                course.display_name, protocol, unicode(course.id)
            )
Adam Palay committed
235 236 237 238
        )

        self.assertEqual(
            mail.outbox[1].subject,
Don Mitchell committed
239
            'You have been invited to register for {}'.format(course.display_name)
Adam Palay committed
240 241 242 243
        )
        self.assertEqual(
            mail.outbox[1].body,
            "Dear student,\n\nYou have been invited to join "
Don Mitchell committed
244
            "{display_name} at edx.org by a member of the "
Adam Palay committed
245 246
            "course staff.\n\n"
            "To finish your registration, please visit "
247
            "{}://edx.org/register and fill out the registration form "
Adam Palay committed
248 249
            "making sure to use student3_1@test.com in the E-mail field.\n"
            "Once you have registered and activated your account, you will "
Don Mitchell committed
250
            "see {display_name} listed on your dashboard.\n\n"
Adam Palay committed
251
            "----\nThis email was automatically sent from edx.org to "
Don Mitchell committed
252
            "student3_1@test.com".format(protocol, display_name=course.display_name)
Adam Palay committed
253
        )
254 255 256 257 258 259 260 261

    def test_unenrollment_email_on(self):
        """
        Do email on unenroll test
        """

        course = self.course

262
        # Create invited, but not registered, user
263 264 265
        cea = CourseEnrollmentAllowed(email='student4_0@test.com', course_id=course.id)
        cea.save()

Calen Pennington committed
266
        url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id.to_deprecated_string()})
267 268
        response = self.client.post(url, {'action': 'Unenroll multiple students', 'multiple_students': 'student4_0@test.com, student2@test.com, student3@test.com', 'email_students': 'on'})

269
        # Check the page output
270 271 272 273
        self.assertContains(response, '<td>student2@test.com</td>')
        self.assertContains(response, '<td>student3@test.com</td>')
        self.assertContains(response, '<td>un-enrolled, email sent</td>')

274
        # Check the outbox
275
        self.assertEqual(len(mail.outbox), 3)
Adam Palay committed
276 277
        self.assertEqual(
            mail.outbox[0].subject,
Don Mitchell committed
278
            'You have been un-enrolled from {}'.format(course.display_name)
Adam Palay committed
279 280 281 282
        )
        self.assertEqual(
            mail.outbox[0].body,
            "Dear Student,\n\nYou have been un-enrolled from course "
Don Mitchell committed
283
            "{} by a member of the course staff. "
Adam Palay committed
284 285
            "Please disregard the invitation previously sent.\n\n"
            "----\nThis email was automatically sent from edx.org "
Don Mitchell committed
286
            "to student4_0@test.com".format(course.display_name)
Adam Palay committed
287 288 289
        )
        self.assertEqual(
            mail.outbox[1].subject,
Don Mitchell committed
290
            'You have been un-enrolled from {}'.format(course.display_name)
Adam Palay committed
291 292
        )

293 294 295 296 297 298 299 300 301
    def test_send_mail_to_student(self):
        """
        Do invalid mail template test
        """

        d = {'message': 'message_type_that_doesn\'t_exist'}

        send_mail_ret = send_mail_to_student('student0@test.com', d)
        self.assertFalse(send_mail_ret)
302

303
    @ddt.data('http', 'https')
304
    @patch('instructor.views.legacy.uses_shib')
305
    def test_enrollment_email_on_shib_on(self, protocol, mock_uses_shib):
306 307 308 309 310 311 312 313
        # Do email on enroll, shibboleth on test

        course = self.course
        mock_uses_shib.return_value = True

        # Create activated, but not enrolled, user
        UserFactory.create(username="student5_0", email="student5_0@test.com", first_name="ShibTest", last_name="Enrolled")

Calen Pennington committed
314
        url = reverse('instructor_dashboard_legacy', kwargs={'course_id': course.id.to_deprecated_string()})
315 316 317
        params = {'action': 'Enroll multiple students', 'multiple_students': 'student5_0@test.com, student5_1@test.com', 'auto_enroll': 'on', 'email_students': 'on'}
        environ = {'wsgi.url_scheme': protocol}
        response = self.client.post(url, params, **environ)
318 319 320 321 322 323 324 325 326 327 328

        # Check the page output
        self.assertContains(response, '<td>student5_0@test.com</td>')
        self.assertContains(response, '<td>student5_1@test.com</td>')
        self.assertContains(response, '<td>added, email sent</td>')
        self.assertContains(response, '<td>user does not exist, enrollment allowed, pending with auto enrollment on, email sent</td>')

        # Check the outbox
        self.assertEqual(len(mail.outbox), 2)
        self.assertEqual(
            mail.outbox[0].subject,
Don Mitchell committed
329
            'You have been enrolled in {}'.format(course.display_name)
330 331 332
        )
        self.assertEqual(
            mail.outbox[0].body,
Don Mitchell committed
333
            "Dear ShibTest Enrolled\n\nYou have been enrolled in {} "
334 335 336
            "at edx.org by a member of the course staff. "
            "The course should now appear on your edx.org dashboard.\n\n"
            "To start accessing course materials, please visit "
Don Mitchell committed
337 338 339 340
            "{}://edx.org/courses/{}/\n\n"
            "----\nThis email was automatically sent from edx.org to ShibTest Enrolled".format(
                course.display_name, protocol, unicode(course.id)
            )
341 342 343 344
        )

        self.assertEqual(
            mail.outbox[1].subject,
Don Mitchell committed
345
            'You have been invited to register for {}'.format(course.display_name)
346 347 348 349
        )
        self.assertEqual(
            mail.outbox[1].body,
            "Dear student,\n\nYou have been invited to join "
Don Mitchell committed
350
            "{} at edx.org by a member of the "
351
            "course staff.\n\n"
Don Mitchell committed
352
            "To access the course visit {}://edx.org/courses/{}/ and login.\n\n"
353
            "----\nThis email was automatically sent from edx.org to "
Don Mitchell committed
354 355 356
            "student5_1@test.com".format(
                course.display_name, protocol, course.id
            )
357
        )