Merge pull request #21841 from edx/bom/student-python-3

student app: python-3 upgrade
This commit is contained in:
Nimisha Asthagiri
2019-09-30 09:24:25 -04:00
committed by GitHub
7 changed files with 73 additions and 58 deletions

View File

@@ -32,7 +32,7 @@ class Command(BaseCommand):
def handle(self, *args, **options):
csv_path = options['csv_path']
with open(csv_path) as csvfile:
with open(csv_path, 'rb') as csvfile:
reader = unicodecsv.DictReader(csvfile)
for row in reader:
username = row['username']

View File

@@ -1,5 +1,6 @@
from __future__ import absolute_import
import six
import unittest
from tempfile import NamedTemporaryFile
@@ -43,10 +44,11 @@ class BulkChangeEnrollmentCSVTests(SharedModuleStoreTestCase):
self.courses.append(course)
self.enrollments.append(CourseEnrollment.enroll(user, course.id, mode=CourseMode.AUDIT))
def _write_test_csv(self, csv, lines=None):
def _write_test_csv(self, csv, lines):
"""Write a test csv file with the lines provided"""
csv.write("course_id,user,mode,\n")
csv.writelines(lines)
csv.write(b"course_id,user,mode,\n")
for line in lines:
csv.write(six.b(line))
csv.seek(0)
return csv
@@ -54,7 +56,7 @@ class BulkChangeEnrollmentCSVTests(SharedModuleStoreTestCase):
def test_user_not_exist(self):
"""Verify that warning is logged for non existing user."""
with NamedTemporaryFile() as csv:
csv = self._write_test_csv(csv, lines="course-v1:edX+DemoX+Demo_Course,user,audit\n")
csv = self._write_test_csv(csv, lines=["course-v1:edX+DemoX+Demo_Course,user,audit\n"])
with LogCapture(LOGGER_NAME) as log:
call_command("bulk_change_enrollment_csv", "--csv_file_path={}".format(csv.name))
@@ -70,7 +72,7 @@ class BulkChangeEnrollmentCSVTests(SharedModuleStoreTestCase):
def test_invalid_course_key(self):
"""Verify in case of invalid course key warning is logged."""
with NamedTemporaryFile() as csv:
csv = self._write_test_csv(csv, lines="Demo_Course,river,audit\n")
csv = self._write_test_csv(csv, lines=["Demo_Course,river,audit\n"])
with LogCapture(LOGGER_NAME) as log:
call_command("bulk_change_enrollment_csv", "--csv_file_path={}".format(csv.name))
@@ -86,7 +88,7 @@ class BulkChangeEnrollmentCSVTests(SharedModuleStoreTestCase):
def test_already_enrolled_student(self):
""" Verify in case if a user is already enrolled warning is logged."""
with NamedTemporaryFile() as csv:
csv = self._write_test_csv(csv, lines=str(self.courses[0].id) + ",amy,audit\n")
csv = self._write_test_csv(csv, lines=[str(self.courses[0].id) + ",amy,audit\n"])
with LogCapture(LOGGER_NAME) as log:
call_command("bulk_change_enrollment_csv", "--csv_file_path={}".format(csv.name))
@@ -105,8 +107,10 @@ class BulkChangeEnrollmentCSVTests(SharedModuleStoreTestCase):
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_bulk_enrollment(self):
""" Test all users are enrolled using the command."""
lines = (str(enrollment.course.id) + "," + str(enrollment.user.username) + ",verified\n"
for enrollment in self.enrollments)
lines = [
str(enrollment.course.id) + "," + str(enrollment.user.username) + ",verified\n"
for enrollment in self.enrollments
]
with NamedTemporaryFile() as csv:
csv = self._write_test_csv(csv, lines=lines)

View File

@@ -1,5 +1,6 @@
from __future__ import absolute_import
import six
from tempfile import NamedTemporaryFile
from django.core.management import call_command
@@ -38,17 +39,18 @@ class BulkUnenrollTests(SharedModuleStoreTestCase):
self.users.append(user)
self.enrollments.append(CourseEnrollment.enroll(user, self.course.id, mode='audit'))
def _write_test_csv(self, csv, lines=None):
"""Write a test csv file with the lines procided"""
csv.write("user_id,username,email,course_id\n")
csv.writelines(lines)
def _write_test_csv(self, csv, lines):
"""Write a test csv file with the lines provided"""
csv.write(b"user_id,username,email,course_id\n")
for line in lines:
csv.write(six.b(line))
csv.seek(0)
return csv
def test_user_not_exist(self):
"""Verify that warning user not exist is logged for non existing user."""
with NamedTemporaryFile() as csv:
csv = self._write_test_csv(csv, lines="111,test,test@example.com,course-v1:edX+DemoX+Demo_Course\n")
csv = self._write_test_csv(csv, lines=["111,test,test@example.com,course-v1:edX+DemoX+Demo_Course\n"])
with LogCapture(LOGGER_NAME) as log:
call_command("bulk_unenroll", "--csv_path={}".format(csv.name))
@@ -63,7 +65,7 @@ class BulkUnenrollTests(SharedModuleStoreTestCase):
def test_invalid_course_key(self):
"""Verify in case of invalid course key warning is logged."""
with NamedTemporaryFile() as csv:
csv = self._write_test_csv(csv, lines="111,amy,amy@pond.com,test_course\n")
csv = self._write_test_csv(csv, lines=["111,amy,amy@pond.com,test_course\n"])
with LogCapture(LOGGER_NAME) as log:
call_command("bulk_unenroll", "--csv_path={}".format(csv.name))
@@ -79,7 +81,7 @@ class BulkUnenrollTests(SharedModuleStoreTestCase):
def test_user_not_enrolled(self):
"""Verify in case of user not enrolled in course warning is logged."""
with NamedTemporaryFile() as csv:
csv = self._write_test_csv(csv, lines="111,amy,amy@pond.com,course-v1:edX+DemoX+Demo_Course\n")
csv = self._write_test_csv(csv, lines=["111,amy,amy@pond.com,course-v1:edX+DemoX+Demo_Course\n"])
with LogCapture(LOGGER_NAME) as log:
call_command("bulk_unenroll", "--csv_path={}".format(csv.name))
@@ -94,11 +96,13 @@ class BulkUnenrollTests(SharedModuleStoreTestCase):
def test_bulk_un_enroll(self):
"""Verify users are unenrolled using the command."""
lines = (str(enrollment.user.id) + "," + enrollment.user.username + "," +
enrollment.user.email + "," + str(enrollment.course.id) + "\n"
for enrollment in self.enrollments)
lines = [
str(enrollment.user.id) + "," + enrollment.user.username + "," +
enrollment.user.email + "," + str(enrollment.course.id) + "\n"
for enrollment in self.enrollments
]
with NamedTemporaryFile() as csv:
csv = self._write_test_csv(csv, lines=lines)\
csv = self._write_test_csv(csv, lines=lines)
call_command("bulk_unenroll", "--csv_path={}".format(csv.name))
for enrollment in CourseEnrollment.objects.all():

View File

@@ -58,13 +58,13 @@ class TestStudentDashboardEmailView(SharedModuleStoreTestCase):
BulkEmailFlag.objects.create(enabled=True, require_course_email_auth=False)
# Assert that the URL for the email view is in the response
response = self.client.get(self.url)
self.assertIn(self.email_modal_link, response.content)
self.assertContains(response, self.email_modal_link)
def test_email_flag_false(self):
BulkEmailFlag.objects.create(enabled=False)
# Assert that the URL for the email view is not in the response
response = self.client.get(self.url)
self.assertNotIn(self.email_modal_link, response.content)
self.assertNotContains(response, self.email_modal_link)
def test_email_unauthorized(self):
BulkEmailFlag.objects.create(enabled=True, require_course_email_auth=True)
@@ -73,7 +73,7 @@ class TestStudentDashboardEmailView(SharedModuleStoreTestCase):
# Assert that the URL for the email view is not in the response
# if this course isn't authorized
response = self.client.get(self.url)
self.assertNotIn(self.email_modal_link, response.content)
self.assertNotContains(response, self.email_modal_link)
def test_email_authorized(self):
BulkEmailFlag.objects.create(enabled=True, require_course_email_auth=True)
@@ -85,4 +85,4 @@ class TestStudentDashboardEmailView(SharedModuleStoreTestCase):
# Assert that the URL for the email view is not in the response
# if this course isn't authorized
response = self.client.get(self.url)
self.assertIn(self.email_modal_link, response.content)
self.assertContains(response, self.email_modal_link)

View File

@@ -299,7 +299,7 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
self._assert_course_verification_status(VERIFY_STATUS_APPROVED)
response2 = self.client.get(self.dashboard_url)
self.assertContains(response2, attempt2.expiration_datetime.strftime("%m/%d/%Y"))
self.assertEqual(response2.content.count(attempt2.expiration_datetime.strftime("%m/%d/%Y")), 2)
self.assertContains(response2, attempt2.expiration_datetime.strftime("%m/%d/%Y"), count=2)
def _setup_mode_and_enrollment(self, deadline, enrollment_mode):
"""Create a course mode and enrollment.
@@ -383,7 +383,7 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
# and fail if none of these are found.
found_msg = False
for message in self.NOTIFICATION_MESSAGES[status]:
if message in response.content:
if six.b(message) in response.content:
found_msg = True
break

View File

@@ -263,11 +263,11 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
set_prerequisite_courses(self.course.id, [six.text_type(self.pre_requisite_course.id)])
response = self.client.get(reverse('dashboard'))
self.assertIn('<div class="prerequisites">', response.content)
self.assertContains(response, '<div class="prerequisites">')
remove_prerequisite_course(self.course.id, get_course_milestones(self.course.id)[0])
response = self.client.get(reverse('dashboard'))
self.assertNotIn('<div class="prerequisites">', response.content)
self.assertNotContains(response, '<div class="prerequisites">')
@patch('openedx.core.djangoapps.programs.utils.get_programs')
@patch('student.views.dashboard.get_visible_sessions_for_entitlement')
@@ -301,10 +301,10 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
'type': 'verified'
}
response = self.client.get(self.path)
self.assertIn('class="course-target-link enter-course hidden"', response.content)
self.assertIn('You must select a session to access the course.', response.content)
self.assertIn('<div class="course-entitlement-selection-container ">', response.content)
self.assertIn('Related Programs:', response.content)
self.assertContains(response, 'class="course-target-link enter-course hidden"')
self.assertContains(response, 'You must select a session to access the course.')
self.assertContains(response, '<div class="course-entitlement-selection-container ">')
self.assertContains(response, 'Related Programs:')
# If an entitlement has already been redeemed by the user for a course run, do not let the run be selectable
enrollment = CourseEnrollmentFactory(
@@ -326,9 +326,9 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
response = self.client.get(self.path)
# There should be two entitlements on the course page, one prompting for a mandatory session, but no
# select option for the courses as there is only the single course run which has already been redeemed
self.assertEqual(response.content.count('<li class="course-item">'), 2)
self.assertIn('You must select a session to access the course.', response.content)
self.assertNotIn('To access the course, select a session.', response.content)
self.assertContains(response, '<li class="course-item">', count=2)
self.assertContains(response, 'You must select a session to access the course.')
self.assertNotContains(response, 'To access the course, select a session.')
@patch('student.views.dashboard.get_visible_sessions_for_entitlement')
@patch.object(CourseOverview, 'get_from_id')
@@ -354,7 +354,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
}
]
response = self.client.get(self.path)
self.assertEqual(response.content.count('<li class="course-item">'), 0)
self.assertNotContains(response, '<li class="course-item">')
@patch('entitlements.api.v1.views.get_course_runs_for_course')
@patch.object(CourseOverview, 'get_from_id')
@@ -454,9 +454,9 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
program['courses'][0]['uuid'] = entitlement.course_uuid
mock_get_programs.return_value = [program]
response = self.client.get(self.path)
self.assertEqual(response.content.count('<li class="course-item">'), 1)
self.assertIn('<button class="change-session btn-link "', response.content)
self.assertIn('Related Programs:', response.content)
self.assertContains(response, '<li class="course-item">', count=1)
self.assertContains(response, '<button class="change-session btn-link "')
self.assertContains(response, 'Related Programs:')
@patch('openedx.core.djangoapps.programs.utils.get_programs')
@patch('student.views.dashboard.get_visible_sessions_for_entitlement')
@@ -489,9 +489,9 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
program['courses'][0]['uuid'] = entitlement.course_uuid
mock_get_programs.return_value = [program]
response = self.client.get(self.path)
self.assertEqual(response.content.count('<li class="course-item">'), 1)
self.assertIn('You can no longer change sessions.', response.content)
self.assertIn('Related Programs:', response.content)
self.assertContains(response, '<li class="course-item">', count=1)
self.assertContains(response, 'You can no longer change sessions.')
self.assertContains(response, 'Related Programs:')
@patch('openedx.core.djangoapps.catalog.utils.get_course_runs_for_course')
@patch('student.views.dashboard.is_bulk_email_feature_enabled')
@@ -535,13 +535,13 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
# Ensure active users see the course list
self.assertTrue(self.user.is_active)
response = self.client.get(reverse('dashboard'))
self.assertIn('You are not enrolled in any courses yet.', response.content)
self.assertContains(response, 'You are not enrolled in any courses yet.')
# Ensure inactive users don't see the course list
self.user.is_active = False
self.user.save()
response = self.client.get(reverse('dashboard'))
self.assertNotIn('You are not enrolled in any courses yet.', response.content)
self.assertNotContains(response, 'You are not enrolled in any courses yet.')
def test_show_empty_dashboard_message(self):
"""
@@ -550,15 +550,15 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
"""
empty_dashboard_message = "Check out our lovely <i>free</i> courses!"
response = self.client.get(reverse('dashboard'))
self.assertIn('You are not enrolled in any courses yet.', response.content)
self.assertNotIn(empty_dashboard_message, response.content)
self.assertContains(response, 'You are not enrolled in any courses yet.')
self.assertNotContains(response, empty_dashboard_message)
with with_site_configuration_context(configuration={
"EMPTY_DASHBOARD_MESSAGE": empty_dashboard_message,
}):
response = self.client.get(reverse('dashboard'))
self.assertIn('You are not enrolled in any courses yet.', response.content)
self.assertIn(empty_dashboard_message, response.content)
self.assertContains(response, 'You are not enrolled in any courses yet.')
self.assertContains(response, empty_dashboard_message)
@patch('django.conf.settings.DASHBOARD_COURSE_LIMIT', 1)
def test_course_limit_on_dashboard(self):
@@ -575,12 +575,16 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
)
response = self.client.get(reverse('dashboard'))
self.assertIn('1 results successfully populated', response.content)
self.assertContains(response, '1 results successfully populated')
@staticmethod
def _remove_whitespace_from_html_string(html):
return ''.join(html.split())
@staticmethod
def _remove_whitespace_from_response(response):
return ''.join(response.content.decode('utf-8').split())
@staticmethod
def _pull_course_run_from_course_key(course_key_string):
search_results = re.search(r'Run_[0-9]+$', course_key_string)
@@ -665,7 +669,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
view_button_html = self._remove_whitespace_from_html_string(view_button_html)
resume_button_html = self._remove_whitespace_from_html_string(resume_button_html)
dashboard_html = self._remove_whitespace_from_html_string(response.content)
dashboard_html = self._remove_whitespace_from_response(response)
self.assertIn(
view_button_html,
@@ -719,7 +723,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
view_button_html = self._remove_whitespace_from_html_string(view_button_html)
resume_button_html = self._remove_whitespace_from_html_string(resume_button_html)
dashboard_html = self._remove_whitespace_from_html_string(response.content)
dashboard_html = self._remove_whitespace_from_response(response)
self.assertIn(
resume_button_html,
@@ -749,7 +753,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
schedule = ScheduleFactory(start=self.THREE_YEARS_AGO + timedelta(days=1), enrollment=enrollment)
response = self.client.get(reverse('dashboard'))
dashboard_html = self._remove_whitespace_from_html_string(response.content.decode('utf-8'))
dashboard_html = self._remove_whitespace_from_response(response)
access_expired_substring = 'Accessexpired'
course_link_class = 'course-target-link'
@@ -848,7 +852,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
for button in html_for_entitlement
]
dashboard_html = self._remove_whitespace_from_html_string(response.content)
dashboard_html = self._remove_whitespace_from_response(response)
for i in range(num_course_cards):
expected_button = None

View File

@@ -433,13 +433,13 @@ class DashboardTest(ModuleStoreTestCase):
response = self.client.get(redeem_url)
self.assertEquals(response.status_code, 200)
# check button text
self.assertIn('Activate Course Enrollment', response.content)
self.assertContains(response, 'Activate Course Enrollment')
#now activate the user by enrolling him/her to the course
response = self.client.post(redeem_url)
self.assertEquals(response.status_code, 200)
response = self.client.get(reverse('dashboard'))
self.assertIn('You can no longer access this course because payment has not yet been received', response.content)
self.assertContains(response, 'You can no longer access this course because payment has not yet been received')
optout_object = Optout.objects.filter(user=self.user, course_id=self.course.id)
self.assertEqual(len(optout_object), 1)
@@ -457,7 +457,10 @@ class DashboardTest(ModuleStoreTestCase):
invoice.save()
response = self.client.get(reverse('dashboard'))
self.assertNotIn('You can no longer access this course because payment has not yet been received', response.content)
self.assertNotContains(
response,
'You can no longer access this course because payment has not yet been received',
)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_linked_in_add_to_profile_btn_not_appearing_without_config(self):
@@ -490,7 +493,7 @@ class DashboardTest(ModuleStoreTestCase):
response = self.client.get(reverse('dashboard'))
self.assertEquals(response.status_code, 200)
self.assertNotIn('Add Certificate to LinkedIn', response.content)
self.assertNotContains(response, 'Add Certificate to LinkedIn')
response_url = 'http://www.linkedin.com/profile/add?_ed='
self.assertNotContains(response, escape(response_url))
@@ -534,7 +537,7 @@ class DashboardTest(ModuleStoreTestCase):
response = self.client.get(reverse('dashboard'))
self.assertEquals(response.status_code, 200)
self.assertIn('Add Certificate to LinkedIn', response.content)
self.assertContains(response, 'Add Certificate to LinkedIn')
expected_url = (
u'http://www.linkedin.com/profile/add'