def setUpClass(cls): super(CourseImportViewTest, cls).setUpClass() cls.course = CourseFactory.create(display_name='test course', run="Testing_course") cls.course_key = cls.course.id cls.restricted_course = CourseFactory.create(display_name='restricted test course', run="Restricted_course") cls.restricted_course_key = cls.restricted_course.id cls.password = '******' cls.student = UserFactory(username='******', password=cls.password) cls.staff = StaffFactory(course_key=cls.course.id, password=cls.password) cls.restricted_staff = StaffFactory(course_key=cls.restricted_course.id, password=cls.password) cls.content_dir = path(tempfile.mkdtemp()) # Create tar test files ----------------------------------------------- # OK course: good_dir = tempfile.mkdtemp(dir=cls.content_dir) # test course being deeper down than top of tar file embedded_dir = os.path.join(good_dir, "grandparent", "parent") os.makedirs(os.path.join(embedded_dir, "course")) with open(os.path.join(embedded_dir, "course.xml"), "w+") as f: f.write('<course url_name="2013_Spring" org="EDx" course="0.00x"/>') with open(os.path.join(embedded_dir, "course", "2013_Spring.xml"), "w+") as f: f.write('<course></course>') cls.good_tar_filename = "good.tar.gz" cls.good_tar_fullpath = os.path.join(cls.content_dir, cls.good_tar_filename) with tarfile.open(cls.good_tar_fullpath, "w:gz") as gtar: gtar.add(good_dir)
def test_courseware_page_unfulfilled_prereqs(self): """ Test courseware access when a course has pre-requisite course yet to be completed """ seed_milestone_relationship_types() pre_requisite_course = CourseFactory.create(org="edX", course="900", run="test_run") pre_requisite_courses = [unicode(pre_requisite_course.id)] course = CourseFactory.create( org="edX", course="1000", run="test_run", pre_requisite_courses=pre_requisite_courses ) set_prerequisite_courses(course.id, pre_requisite_courses) test_password = "******" user = UserFactory.create() user.set_password(test_password) user.save() self.login(user.email, test_password) CourseEnrollmentFactory(user=user, course_id=course.id) url = reverse("courseware", args=[unicode(course.id)]) response = self.client.get(url) self.assertRedirects(response, reverse("dashboard")) self.assertEqual(response.status_code, 302) fulfill_course_milestone(pre_requisite_course.id, user) response = self.client.get(url) self.assertEqual(response.status_code, 200)
def setUp(self): patcher = patch('student.models.tracker') self.mock_tracker = patcher.start() self.user = UserFactory.create() self.user.set_password('password') self.user.save() self.instructor = AdminFactory.create() self.cost = 40 self.coupon_code = 'abcde' self.reg_code = 'qwerty' self.percentage_discount = 10 self.course = CourseFactory.create(org='MITx', number='999', display_name='Robot Super Course') self.course_key = self.course.id self.course_mode = CourseMode(course_id=self.course_key, mode_slug="honor", mode_display_name="honor cert", min_price=self.cost) self.course_mode.save() #Saving another testing course mode self.testing_cost = 20 self.testing_course = CourseFactory.create(org='edX', number='888', display_name='Testing Super Course') self.testing_course_mode = CourseMode(course_id=self.testing_course.id, mode_slug="honor", mode_display_name="testing honor cert", min_price=self.testing_cost) self.testing_course_mode.save() verified_course = CourseFactory.create(org='org', number='test', display_name='Test Course') self.verified_course_key = verified_course.id self.cart = Order.get_cart_for_user(self.user) self.addCleanup(patcher.stop)
def setUp(self): self.user = UserFactory.create() course = CourseFactory.create(org='org', number='test', display_name='Test Course') self.course_key = course.id for i in xrange(1, 5): CourseFactory.create(org='org', number='test', display_name='Test Course {0}'.format(i)) self.cost = 40
def test_access_on_course_with_pre_requisites(self): """ Test course access when a course has pre-requisite course yet to be completed """ seed_milestone_relationship_types() user = UserFactory.create() pre_requisite_course = CourseFactory.create(org="test_org", number="788", run="test_run") pre_requisite_courses = [unicode(pre_requisite_course.id)] course = CourseFactory.create( org="test_org", number="786", run="test_run", pre_requisite_courses=pre_requisite_courses ) set_prerequisite_courses(course.id, pre_requisite_courses) # user should not be able to load course even if enrolled CourseEnrollmentFactory(user=user, course_id=course.id) response = access._has_access_course_desc(user, "view_courseware_with_prerequisites", course) self.assertFalse(response) self.assertIsInstance(response, access_response.MilestoneError) # Staff can always access course staff = StaffFactory.create(course_key=course.id) self.assertTrue(access._has_access_course_desc(staff, "view_courseware_with_prerequisites", course)) # User should be able access after completing required course fulfill_course_milestone(pre_requisite_course.id, user) self.assertTrue(access._has_access_course_desc(user, "view_courseware_with_prerequisites", course))
def setUp(self): self.course = CourseFactory.create(number='999', display_name='Robot_Super_Course') self.overview_chapter = ItemFactory.create(display_name='Overview') self.courseware_chapter = ItemFactory.create(display_name='courseware') self.test_course = CourseFactory.create(number='666', display_name='Robot_Sub_Course') self.other_org_course = CourseFactory.create(org='Other_Org_Course') self.sub_courseware_chapter = ItemFactory.create( parent_location=self.test_course.location, display_name='courseware' ) self.sub_overview_chapter = ItemFactory.create( parent_location=self.sub_courseware_chapter.location, display_name='Overview' ) self.welcome_section = ItemFactory.create( parent_location=self.overview_chapter.location, display_name='Welcome' ) self.global_staff_user = GlobalStaffFactory() self.unenrolled_user = UserFactory(last_name="Unenrolled") self.enrolled_user = UserFactory(last_name="Enrolled") CourseEnrollmentFactory(user=self.enrolled_user, course_id=self.course.id) CourseEnrollmentFactory(user=self.enrolled_user, course_id=self.test_course.id) self.staff_user = StaffFactory(course=self.course.location) self.instructor_user = InstructorFactory( course=self.course.location) self.org_staff_user = OrgStaffFactory(course=self.course.location) self.org_instructor_user = OrgInstructorFactory( course=self.course.location)
def setUp(self): """ Set up tests """ super(TestInstructorDashboard, self).setUp() self.course = CourseFactory.create( grading_policy={"GRADE_CUTOFFS": {"A": 0.75, "B": 0.63, "C": 0.57, "D": 0.5}}, display_name='<script>alert("XSS")</script>' ) self.course_mode = CourseMode( course_id=self.course.id, mode_slug=CourseMode.DEFAULT_MODE_SLUG, mode_display_name=CourseMode.DEFAULT_MODE.name, min_price=40 ) self.course_info = CourseFactory.create( org="ACME", number="001", run="2017", name="How to defeat the Road Runner" ) self.course_mode.save() # Create instructor account self.instructor = AdminFactory.create() self.client.login(username=self.instructor.username, password="******") # URL for instructor dash self.url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.course.id)})
def test_courseware_access(self): self.login() course_with_prereq = CourseFactory.create(start=self.LAST_WEEK, mobile_available=True) prerequisite_course = CourseFactory.create() set_prerequisite_courses(course_with_prereq.id, [unicode(prerequisite_course.id)]) # Create list of courses with various expected courseware_access responses and corresponding expected codes courses = [ course_with_prereq, CourseFactory.create(start=self.NEXT_WEEK, mobile_available=True), CourseFactory.create(visible_to_staff_only=True, mobile_available=True), CourseFactory.create(start=self.LAST_WEEK, mobile_available=True, visible_to_staff_only=False), ] expected_error_codes = [ MilestoneAccessError().error_code, # 'unfulfilled_milestones' StartDateError(self.NEXT_WEEK).error_code, # 'course_not_started' VisibilityError().error_code, # 'not_visible_to_user' None, ] # Enroll in all the courses for course in courses: self.enroll(course.id) # Verify courses have the correct response through error code. Last enrolled course is first course in response response = self.api_response() for course_index in range(len(courses)): result = response.data[course_index]['course']['courseware_access'] self.assertEqual(result['error_code'], expected_error_codes[::-1][course_index]) if result['error_code'] is not None: self.assertFalse(result['has_access'])
def setUpClass(cls): super(CertificateGetTests, cls).setUpClass() cls.student = UserFactory() cls.student_no_cert = UserFactory() cls.course_1 = CourseFactory.create( org='edx', number='verified_1', display_name='Verified Course 1' ) cls.course_2 = CourseFactory.create( org='edx', number='verified_2', display_name='Verified Course 2' ) # certificate for the first course GeneratedCertificateFactory.create( user=cls.student, course_id=cls.course_1.id, status=CertificateStatuses.downloadable, mode='verified', download_url='www.google.com', grade="0.88", ) # certificate for the second course GeneratedCertificateFactory.create( user=cls.student, course_id=cls.course_2.id, status=CertificateStatuses.downloadable, mode='honor', download_url='www.gmail.com', grade="0.99", )
def test_get_from_ids_if_exists(self): course_with_overview_1 = CourseFactory.create(emit_signals=True) course_with_overview_2 = CourseFactory.create(emit_signals=True) course_without_overview = CourseFactory.create(emit_signals=False) courses = [course_with_overview_1, course_with_overview_2, course_without_overview] course_ids_to_overviews = CourseOverview.get_from_ids_if_exists( course.id for course in courses ) # We should see the ones that have published CourseOverviews # (when the signals were emitted), but not the one that didn't issue # a publish signal. self.assertEqual(len(course_ids_to_overviews), 2) self.assertIn(course_with_overview_1.id, course_ids_to_overviews) self.assertIn(course_with_overview_2.id, course_ids_to_overviews) self.assertNotIn(course_without_overview.id, course_ids_to_overviews) # But if we set a CourseOverview to be an old version, it shouldn't be # returned by get_from_ids_if_exists() overview_2 = course_ids_to_overviews[course_with_overview_2.id] overview_2.version = CourseOverview.VERSION - 1 overview_2.save() course_ids_to_overviews = CourseOverview.get_from_ids_if_exists( course.id for course in courses ) self.assertEqual(len(course_ids_to_overviews), 1) self.assertIn(course_with_overview_1.id, course_ids_to_overviews)
def test_course_listing_org_permissions(self, role): """ Create multiple courses within the same org. Verify that someone with org-wide permissions can access all of them. """ org_course_one = SlashSeparatedCourseKey('AwesomeOrg', 'Course1', 'RunBabyRun') CourseFactory.create( org=org_course_one.org, number=org_course_one.course, run=org_course_one.run ) org_course_two = SlashSeparatedCourseKey('AwesomeOrg', 'Course2', 'RunRunRun') CourseFactory.create( org=org_course_two.org, number=org_course_two.course, run=org_course_two.run ) # Two types of org-wide roles have edit permissions: staff and instructor. We test both role.add_users(self.user) with self.assertRaises(AccessListFallback): _accessible_courses_list_from_groups(self.request) courses_list = _accessible_courses_list(self.request) self.assertEqual(len(courses_list), 2)
def setUpClass(cls): super(TestSites, cls).setUpClass() cls.course = CourseFactory.create( display_name='Robot_Super_Course', org='TestSiteX', emit_signals=True, ) cls.chapter0 = ItemFactory.create(parent_location=cls.course.location, display_name='Overview') cls.chapter9 = ItemFactory.create(parent_location=cls.course.location, display_name='factory_chapter') cls.section0 = ItemFactory.create(parent_location=cls.chapter0.location, display_name='Welcome') cls.section9 = ItemFactory.create(parent_location=cls.chapter9.location, display_name='factory_section') cls.course_outside_site = CourseFactory.create( display_name='Robot_Course_Outside_Site', org='FooX', emit_signals=True, ) # have a course which explicitly sets visibility in catalog to False cls.course_hidden_visibility = CourseFactory.create( display_name='Hidden_course', org='TestSiteX', catalog_visibility=CATALOG_VISIBILITY_NONE, emit_signals=True, ) # have a course which explicitly sets visibility in catalog and about to true cls.course_with_visibility = CourseFactory.create( display_name='visible_course', org='TestSiteX', course="foo", catalog_visibility=CATALOG_VISIBILITY_CATALOG_AND_ABOUT, emit_signals=True, )
def test_pre_requisite_course_update_and_fetch(self): seed_milestone_relationship_types() url = get_url(self.course.id) resp = self.client.get_json(url) course_detail_json = json.loads(resp.content) # assert pre_requisite_courses is initialized self.assertEqual([], course_detail_json['pre_requisite_courses']) # update pre requisite courses with a new course keys pre_requisite_course = CourseFactory.create(org='edX', course='900', run='test_run') pre_requisite_course2 = CourseFactory.create(org='edX', course='902', run='test_run') pre_requisite_course_keys = [unicode(pre_requisite_course.id), unicode(pre_requisite_course2.id)] course_detail_json['pre_requisite_courses'] = pre_requisite_course_keys self.client.ajax_post(url, course_detail_json) # fetch updated course to assert pre_requisite_courses has new values resp = self.client.get_json(url) course_detail_json = json.loads(resp.content) self.assertEqual(pre_requisite_course_keys, course_detail_json['pre_requisite_courses']) # remove pre requisite course course_detail_json['pre_requisite_courses'] = [] self.client.ajax_post(url, course_detail_json) resp = self.client.get_json(url) course_detail_json = json.loads(resp.content) self.assertEqual([], course_detail_json['pre_requisite_courses'])
def test_course_index_view_with_course(self): """Test viewing the index page with an existing course""" CourseFactory.create(display_name="Robot Super Educational Course") resp = self.client.get(reverse("index")) self.assertContains( resp, '<span class="class-name">Robot Super Educational Course</span>', status_code=200, html=True )
def setUp(self): super(IndexPageCourseCardsSortingTests, self).setUp() self.starting_later = CourseFactory.create( org='MITx', number='1000', display_name='Starting later, Announced later', metadata={ 'start': datetime.datetime.now(UTC) + datetime.timedelta(days=4), 'announcement': datetime.datetime.now(UTC) + datetime.timedelta(days=3), } ) self.starting_earlier = CourseFactory.create( org='MITx', number='1001', display_name='Starting earlier, Announced earlier', metadata={ 'start': datetime.datetime.now(UTC) + datetime.timedelta(days=2), 'announcement': datetime.datetime.now(UTC) + datetime.timedelta(days=1), } ) self.course_with_default_start_date = CourseFactory.create( org='MITx', number='1002', display_name='Tech Beta Course', ) self.factory = RequestFactory()
def setUp(self): """ Set up courses and enrollments. """ super(TestStudentDashboardWithCCX, self).setUp() # Create a Draft Mongo and a Split Mongo course and enroll a student user in them. self.student_password = "******" self.student = UserFactory.create(username="******", password=self.student_password, is_staff=False) self.draft_course = CourseFactory.create(default_store=ModuleStoreEnum.Type.mongo) self.split_course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split) CourseEnrollment.enroll(self.student, self.draft_course.id) CourseEnrollment.enroll(self.student, self.split_course.id) # Create a CCX coach. self.coach = AdminFactory.create() role = CourseCcxCoachRole(self.split_course.id) role.add_users(self.coach) # Create a CCX course and enroll the user in it. self.ccx = CcxFactory(course_id=self.split_course.id, coach=self.coach) last_week = datetime.datetime.now(UTC()) - datetime.timedelta(days=7) override_field_for_ccx(self.ccx, self.split_course, 'start', last_week) # Required by self.ccx.has_started(). course_key = CCXLocator.from_course_locator(self.split_course.id, self.ccx.id) CourseEnrollment.enroll(self.student, course_key)
def setUp(self): super(ExternalAuthShibTest, self).setUp() self.course = CourseFactory.create( org='Stanford', number='456', display_name='NO SHIB', user_id=self.user.id, ) self.shib_course = CourseFactory.create( org='Stanford', number='123', display_name='Shib Only', enrollment_domain='shib:https://idp.stanford.edu/', user_id=self.user.id, ) self.user_w_map = UserFactory.create(email='*****@*****.**') self.extauth = ExternalAuthMap(external_id='*****@*****.**', external_email='*****@*****.**', external_domain='shib:https://idp.stanford.edu/', external_credentials="", user=self.user_w_map) self.user_w_map.save() self.extauth.save() self.user_wo_map = UserFactory.create(email='*****@*****.**') self.user_wo_map.save()
def setUp(self): super(TestNavigation, self).setUp() self.test_course = CourseFactory.create() self.course = CourseFactory.create() self.chapter0 = ItemFactory.create(parent=self.course, display_name="Overview") self.chapter9 = ItemFactory.create(parent=self.course, display_name="factory_chapter") self.section0 = ItemFactory.create(parent=self.chapter0, display_name="Welcome") self.section9 = ItemFactory.create(parent=self.chapter9, display_name="factory_section") self.unit0 = ItemFactory.create(parent=self.section0, display_name="New Unit") self.chapterchrome = ItemFactory.create(parent=self.course, display_name="Chrome") self.chromelesssection = ItemFactory.create(parent=self.chapterchrome, display_name="chromeless", chrome="none") self.accordionsection = ItemFactory.create( parent=self.chapterchrome, display_name="accordion", chrome="accordion" ) self.tabssection = ItemFactory.create(parent=self.chapterchrome, display_name="tabs", chrome="tabs") self.defaultchromesection = ItemFactory.create(parent=self.chapterchrome, display_name="defaultchrome") self.fullchromesection = ItemFactory.create( parent=self.chapterchrome, display_name="fullchrome", chrome="accordion,tabs" ) self.tabtest = ItemFactory.create( parent=self.chapterchrome, display_name="progress_tab", default_tab="progress" ) # Create student accounts and activate them. for i in range(len(self.STUDENT_INFO)): email, password = self.STUDENT_INFO[i] username = "******".format(i) self.create_account(username, email, password) self.activate_user(email) self.staff_user = GlobalStaffFactory()
def test_course_listing_org_permissions(self, role): """ Create multiple courses within the same org. Verify that someone with org-wide permissions can access all of them. """ org_course_one = self.store.make_course_key('AwesomeOrg', 'Course1', 'RunBabyRun') CourseFactory.create( org=org_course_one.org, number=org_course_one.course, run=org_course_one.run ) org_course_two = self.store.make_course_key('AwesomeOrg', 'Course2', 'RunBabyRun') CourseFactory.create( org=org_course_two.org, number=org_course_two.course, run=org_course_two.run ) # Two types of org-wide roles have edit permissions: staff and instructor. We test both role.add_users(self.user) with self.assertRaises(AccessListFallback): _accessible_courses_list_from_groups(self.request) courses_list, __ = get_courses_accessible_to_user(self.request) # Verify fetched accessible courses list is a list of CourseSummery instances and test expacted # course count is returned self.assertEqual(len(courses_list), 2) self.assertTrue(all(isinstance(course, CourseSummary) for course in courses_list))
def setUp(self): self.user = UserFactory.create() self.course_id = "org/test/Test_Course" CourseFactory.create(org='org', number='test', display_name='Test Course') for i in xrange(1, 5): CourseFactory.create(org='org', number='test', display_name='Test Course {0}'.format(i)) self.cost = 40
def test_course_ids_with_certs_for_user(self): # Create one user with certs and one without student_no_certs = UserFactory() student_with_certs = UserFactory() student_with_certs.profile.allow_certificate = True student_with_certs.profile.save() # Set up a couple of courses course_1 = CourseFactory.create() course_2 = CourseFactory.create() # Generate certificates GeneratedCertificateFactory.create( user=student_with_certs, course_id=course_1.id, status=CertificateStatuses.downloadable, mode='honor' ) GeneratedCertificateFactory.create( user=student_with_certs, course_id=course_2.id, status=CertificateStatuses.downloadable, mode='honor' ) # User with no certs should return an empty set. self.assertSetEqual( GeneratedCertificate.course_ids_with_certs_for_user(student_no_certs), set() ) # User with certs should return a set with the two course_ids self.assertSetEqual( GeneratedCertificate.course_ids_with_certs_for_user(student_with_certs), {course_1.id, course_2.id} )
def build_courses(self): """ Build up a course tree with multiple test courses """ self.courses = [ CourseFactory.create( org='ElasticsearchFiltering', course='ES101F', run='test_run', display_name='Elasticsearch Filtering test course', ), CourseFactory.create( org='FilterTest', course='FT101', run='test_run', display_name='FilterTest test course', ) ] self.chapter = ItemFactory.create( parent_location=self.courses[0].location, category='chapter', display_name="Week 1", publish_item=True, ) self.chapter2 = ItemFactory.create( parent_location=self.courses[1].location, category='chapter', display_name="Week 1", publish_item=True, )
def setUp(self): super(ParamValidatorTest, self).setUp() self.draft_course = CourseFactory.create( start=NEXT_WEEK, enrollment_start=NEXT_WEEK, end=NEXT_WEEK, enrollment_end=NEXT_WEEK, ) self.upcoming_course = CourseFactory.create( start=NEXT_WEEK, enrollment_start=YESTERDAY, end=NEXT_MONTH, enrollment_end=NEXT_WEEK, ) self.current_course = CourseFactory.create( start=PAST_WEEK, enrollment_start=PAST_WEEK, end=NEXT_MONTH, enrollment_end=NEXT_WEEK, ) self.closed_course = CourseFactory.create( start=PAST_WEEK, enrollment_start=PAST_WEEK, end=YESTERDAY, enrollment_end=YESTERDAY, )
def setUpClass(cls): """ Creates two courses; one that's just a course module, and one that looks like: course | chapter | sequential | vertical / | \ \ / | \ ---------- / | \ \ / | --- \ / | \ \ html -> problem -> video -> video2 The side-pointing arrows (->) are PRECEDES relationships; the more vertical lines are PARENT_OF relationships. """ super(TestDumpToNeo4jCommandBase, cls).setUpClass() cls.course = CourseFactory.create() cls.chapter = ItemFactory.create(parent=cls.course, category='chapter') cls.sequential = ItemFactory.create(parent=cls.chapter, category='sequential') cls.vertical = ItemFactory.create(parent=cls.sequential, category='vertical') cls.html = ItemFactory.create(parent=cls.vertical, category='html') cls.problem = ItemFactory.create(parent=cls.vertical, category='problem') cls.video = ItemFactory.create(parent=cls.vertical, category='video') cls.video2 = ItemFactory.create(parent=cls.vertical, category='video') cls.course2 = CourseFactory.create() cls.course_strings = [six.text_type(cls.course.id), six.text_type(cls.course2.id)]
def test_course_with_prereq(self): """ Simulate having a course which has closed enrollments that has a pre-req course """ pre_requisite_course = CourseFactory.create( org='edX', course='900', display_name='pre requisite course', ) pre_requisite_courses = [unicode(pre_requisite_course.id)] # for this failure to occur, the enrollment window needs to be in the past course = CourseFactory.create( org='edX', course='1000', display_name='course that has pre requisite', # closed enrollment enrollment_start=datetime.datetime(2013, 1, 1), enrollment_end=datetime.datetime(2014, 1, 1), start=datetime.datetime(2013, 1, 1), end=datetime.datetime(2030, 1, 1), pre_requisite_courses=pre_requisite_courses, ) set_prerequisite_courses(course.id, pre_requisite_courses) resp = self.client.get('/') self.assertEqual(resp.status_code, 200) # make sure both courses are visible in the catalog self.assertIn('pre requisite course', resp.content) self.assertIn('course that has pre requisite', resp.content)
def test_eligibility_email_with_providers(self, providers_list, providers_email_message, expected_subject): """ Test the credit requirements, eligibility notification, email for different providers combinations. """ # Configure a course with two credit requirements self.add_credit_course() CourseFactory.create(org='edX', number='DemoX', display_name='Demo_Course') requirements = [ { "namespace": "grade", "name": "grade", "display_name": "Grade", "criteria": { "min_grade": 0.8 }, }, { "namespace": "reverification", "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid", "display_name": "Assessment 1", "criteria": {}, } ] api.set_credit_requirements(self.course_key, requirements) user = UserFactory.create(username=self.USER_INFO['username'], password=self.USER_INFO['password']) # Satisfy one of the requirements, but not the other api.set_credit_requirement_status( user.username, self.course_key, requirements[0]["namespace"], requirements[0]["name"] ) # Satisfy the other requirement. And mocked the api to return different kind of data. with mock.patch('openedx.core.djangoapps.credit.email_utils.get_credit_provider_display_names') as mock_method: mock_method.return_value = providers_list api.set_credit_requirement_status( "bob", self.course_key, requirements[1]["namespace"], requirements[1]["name"] ) # Now the user should be eligible self.assertTrue(api.is_user_eligible_for_credit("bob", self.course_key)) # Credit eligibility email should be sent self.assertEqual(len(mail.outbox), 1) # Verify the email subject self.assertEqual(mail.outbox[0].subject, expected_subject) # Now verify them email content email_payload_first = mail.outbox[0].attachments[0]._payload # pylint: disable=protected-access html_content_first = email_payload_first[0]._payload[1]._payload # pylint: disable=protected-access self.assertIn(providers_email_message, html_content_first) # test text email text_content_first = email_payload_first[0]._payload[0]._payload # pylint: disable=protected-access self.assertIn(providers_email_message, text_content_first)
def test_factories(self): test_course = CourseFactory.create( org='testx', course='course', run='2014', display_name='fun test course', user_id='testbot' ) self.assertIsInstance(test_course, CourseDescriptor) self.assertEqual(test_course.display_name, 'fun test course') course_from_store = self.store.get_course(test_course.id) self.assertEqual(course_from_store.id.org, 'testx') self.assertEqual(course_from_store.id.course, 'course') self.assertEqual(course_from_store.id.run, '2014') test_chapter = ItemFactory.create( parent_location=test_course.location, category='chapter', display_name='chapter 1' ) self.assertIsInstance(test_chapter, SequenceDescriptor) # refetch parent which should now point to child test_course = self.store.get_course(test_course.id.version_agnostic()) self.assertIn(test_chapter.location, test_course.children) with self.assertRaises(DuplicateCourseError): CourseFactory.create( org='testx', course='course', run='2014', display_name='fun test course', user_id='testbot' )
def test_access_on_course_with_pre_requisites(self): """ Test course access when a course has pre-requisite course yet to be completed """ user = UserFactory.create() pre_requisite_course = CourseFactory.create( org='test_org', number='788', run='test_run' ) pre_requisite_courses = [unicode(pre_requisite_course.id)] course = CourseFactory.create( org='test_org', number='786', run='test_run', pre_requisite_courses=pre_requisite_courses ) set_prerequisite_courses(course.id, pre_requisite_courses) # user should not be able to load course even if enrolled CourseEnrollmentFactory(user=user, course_id=course.id) response = access._has_access_course(user, 'load', course) self.assertFalse(response) self.assertIsInstance(response, access_response.MilestoneAccessError) # Staff can always access course staff = StaffFactory.create(course_key=course.id) self.assertTrue(access._has_access_course(staff, 'load', course)) # User should be able access after completing required course fulfill_course_milestone(pre_requisite_course.id, user) self.assertTrue(access._has_access_course(user, 'load', course))
def setUp(self): # use a different hostname to test Microsites since they are # triggered on subdomain mappings # # NOTE: The Microsite Configuration is in lms/envs/test.py. The content for the Test Microsite is in # test_microsites/test_microsite. # # IMPORTANT: For these tests to work, this domain must be defined via # DNS configuration (either local or published) self.course = CourseFactory.create(display_name='Robot_Super_Course', org='TestMicrositeX') self.chapter0 = ItemFactory.create(parent_location=self.course.location, display_name='Overview') self.chapter9 = ItemFactory.create(parent_location=self.course.location, display_name='factory_chapter') self.section0 = ItemFactory.create(parent_location=self.chapter0.location, display_name='Welcome') self.section9 = ItemFactory.create(parent_location=self.chapter9.location, display_name='factory_section') self.course_outside_microsite = CourseFactory.create(display_name='Robot_Course_Outside_Microsite', org='FooX') # have a course which explicitly sets visibility in catalog to False self.course_hidden_visibility = CourseFactory.create( display_name='Hidden_course', org='TestMicrositeX', catalog_visibility=CATALOG_VISIBILITY_NONE, ) # have a course which explicitly sets visibility in catalog and about to true self.course_with_visibility = CourseFactory.create( display_name='visible_course', org='TestMicrositeX', catalog_visibility=CATALOG_VISIBILITY_CATALOG_AND_ABOUT, )
def setUp(self): super(AboutTestCase, self).setUp() self.course = CourseFactory.create() self.about = ItemFactory.create( category="about", parent_location=self.course.location, data="OOGIE BLOOGIE", display_name="overview" ) self.course_without_about = CourseFactory.create(catalog_visibility=CATALOG_VISIBILITY_NONE) self.about = ItemFactory.create( category="about", parent_location=self.course_without_about.location, data="WITHOUT ABOUT", display_name="overview" ) self.course_with_about = CourseFactory.create(catalog_visibility=CATALOG_VISIBILITY_ABOUT) self.about = ItemFactory.create( category="about", parent_location=self.course_with_about.location, data="WITH ABOUT", display_name="overview" ) self.purchase_course = CourseFactory.create(org='MITx', number='buyme', display_name='Course To Buy') self.course_mode = CourseMode( course_id=self.purchase_course.id, mode_slug=CourseMode.DEFAULT_MODE_SLUG, mode_display_name=CourseMode.DEFAULT_MODE_SLUG, min_price=10 ) self.course_mode.save()
def setUp(self): self.course = CourseFactory.create() self.instructor = InstructorFactory(self.course) self.client.login(username=self.instructor.username, password='******')
def setUpClass(cls): super(ProgressPageCreditRequirementsTest, cls).setUpClass() cls.course = CourseFactory.create()
def setUpClass(cls): super(EmailSendFromDashboardTestCase, cls).setUpClass() course_title = u"ẗëṡẗ title イ乇丂イ ᄊ乇丂丂ムg乇 キo尺 ムレレ тэѕт мэѕѕаБэ" cls.course = CourseFactory.create( display_name=course_title, default_store=ModuleStoreEnum.Type.split)
def setUpClass(cls): super(RefundableTest, cls).setUpClass() cls.course = CourseFactory.create()
def setUpClass(cls): """ Set up course for tests """ super(CoachAccessTestCaseCCX, cls).setUpClass() cls.course = CourseFactory.create()
def test_dashboard_with_resume_buttons_and_view_buttons(self): ''' The Test creates a four-course-card dashboard. The user completes course blocks in the even-numbered course cards. The test checks that courses with completion data have course cards with "Resume Course" buttons; those without have "View Course" buttons. ''' self.override_waffle_switch(True) isEven = lambda n: n % 2 == 0 num_course_cards = 4 html_for_view_buttons = [] html_for_resume_buttons = [] html_for_entitlement = [] for i in range(num_course_cards): course = CourseFactory.create() course_enrollment = CourseEnrollmentFactory(user=self.user, course_id=course.id) course_key = course_enrollment.course_id course_key_string = str(course_key) if i == 1: CourseEntitlementFactory.create( user=self.user, enrollment_course_run=course_enrollment) else: last_completed_block_string = '' course_run_string = self._pull_course_run_from_course_key( course_key_string) # Submit completed course blocks in even-numbered courses. if isEven(i): block_keys = [ ItemFactory.create(category='video', parent_location=course.location, display_name='Video {0}'.format( unicode(number))).location for number in xrange(5) ] last_completed_block_string = str(block_keys[-1]) submit_completions_for_testing(self.user, course_key, block_keys) html_for_view_buttons.append( self._get_html_for_view_course_button(course_key_string, course_run_string)) html_for_resume_buttons.append( self._get_html_for_resume_course_button( course_key_string, last_completed_block_string, course_run_string)) html_for_entitlement.append( self._get_html_for_entitlement_button(course_key_string)) response = self.client.get(reverse('dashboard')) html_for_view_buttons = [ self._remove_whitespace_from_html_string(button) for button in html_for_view_buttons ] html_for_resume_buttons = [ self._remove_whitespace_from_html_string(button) for button in html_for_resume_buttons ] html_for_entitlement = [ self._remove_whitespace_from_html_string(button) for button in html_for_entitlement ] dashboard_html = self._remove_whitespace_from_html_string( response.content) for i in range(num_course_cards): expected_button = None unexpected_button = None if i == 1: expected_button = html_for_entitlement[i] unexpected_button = html_for_view_buttons[ i] + html_for_resume_buttons[i] elif isEven(i): expected_button = html_for_resume_buttons[i] unexpected_button = html_for_view_buttons[ i] + html_for_entitlement[i] else: expected_button = html_for_view_buttons[i] unexpected_button = html_for_resume_buttons[ i] + html_for_entitlement[i] self.assertIn(expected_button, dashboard_html) self.assertNotIn(unexpected_button, dashboard_html)
def setUpClass(cls): super(TestStudentDashboardUnenrollments, cls).setUpClass() cls.course = CourseFactory.create()
def setUpClass(cls): super(EnrollmentTest, cls).setUpClass() cls.course = CourseFactory.create() cls.course_limited = CourseFactory.create()
def setUp(self): super().setUp() self.course = CourseFactory.create()
def setUp(self): self.course = CourseFactory.create() self.user = UserFactory.create() CourseEnrollment.enroll(self.user, self.course.id) self.problem_urlname = 'robot-some-problem-urlname' _module = StudentModule.objects.create( student=self.user, course_id=self.course.id, module_state_key=_msk_from_problem_urlname(self.course.id, self.problem_urlname), state=json.dumps({'attempts': 10}), ) # Endpoints that only Staff or Instructors can access self.staff_level_endpoints = [ ('students_update_enrollment', { 'emails': '*****@*****.**', 'action': 'enroll' }), ('get_grading_config', {}), ('get_students_features', {}), ('get_distribution', {}), ('get_student_progress_url', { 'unique_student_identifier': self.user.username }), ('reset_student_attempts', { 'problem_to_reset': self.problem_urlname, 'unique_student_identifier': self.user.email }), ('update_forum_role_membership', { 'email': self.user.email, 'rolename': 'Moderator', 'action': 'allow' }), ('list_forum_members', { 'rolename': FORUM_ROLE_COMMUNITY_TA }), ('proxy_legacy_analytics', { 'aname': 'ProblemGradeDistribution' }), ('send_email', { 'send_to': 'staff', 'subject': 'test', 'message': 'asdf' }), ('list_instructor_tasks', {}), ('list_background_email_tasks', {}), ] # Endpoints that only Instructors can access self.instructor_level_endpoints = [ ('modify_access', { 'email': self.user.email, 'rolename': 'beta', 'action': 'allow' }), ('list_course_role_members', { 'rolename': 'beta' }), ('rescore_problem', { 'problem_to_reset': self.problem_urlname, 'unique_student_identifier': self.user.email }), ]
def setUpClass(cls): super(TestGradeIteration, cls).setUpClass() cls.course = CourseFactory.create(display_name=cls.COURSE_NAME, number=cls.COURSE_NUM)
def setUpClass(cls): super(TestFindUnit, cls).setUpClass() cls.course = CourseFactory.create() with cls.store.bulk_operations(cls.course.id, emit_signals=False): week1 = ItemFactory.create(parent=cls.course) cls.homework = ItemFactory.create(parent=week1)
def test_studio_user_permissions(self): """ Test that user could attach to the problem only libraries that he has access (or which were created by him). This test was created on the basis of bug described in the pull requests on github: https://github.com/edx/edx-platform/pull/11331 https://github.com/edx/edx-platform/pull/11611 """ self._create_library(org='admin_org_1', library='lib_adm_1', display_name='admin_lib_1') self._create_library(org='admin_org_2', library='lib_adm_2', display_name='admin_lib_2') self._login_as_non_staff_user() self._create_library(org='staff_org_1', library='lib_staff_1', display_name='staff_lib_1') self._create_library(org='staff_org_2', library='lib_staff_2', display_name='staff_lib_2') with modulestore().default_store(ModuleStoreEnum.Type.split): course = CourseFactory.create() instructor_role = CourseInstructorRole(course.id) auth.add_users(self.user, instructor_role, self.non_staff_user) lib_block = ItemFactory.create(category='library_content', parent_location=course.location, user_id=self.non_staff_user.id, publish_item=False) def _get_settings_html(): """ Helper function to get block settings HTML Used to check the available libraries. """ edit_view_url = reverse_usage_url("xblock_view_handler", lib_block.location, {"view_name": STUDIO_VIEW}) resp = self.client.get_json(edit_view_url) self.assertEqual(resp.status_code, 200) return parse_json(resp)['html'] self._login_as_staff_user() staff_settings_html = _get_settings_html() self.assertIn('staff_lib_1', staff_settings_html) self.assertIn('staff_lib_2', staff_settings_html) self.assertIn('admin_lib_1', staff_settings_html) self.assertIn('admin_lib_2', staff_settings_html) self._login_as_non_staff_user() response = self.client.get_json(LIBRARY_REST_URL) staff_libs = parse_json(response) self.assertEqual(2, len(staff_libs)) non_staff_settings_html = _get_settings_html() self.assertIn('staff_lib_1', non_staff_settings_html) self.assertIn('staff_lib_2', non_staff_settings_html) self.assertNotIn('admin_lib_1', non_staff_settings_html) self.assertNotIn('admin_lib_2', non_staff_settings_html)
def setup_course(self, **course_kwargs): """ Set up a course with provided course attributes. """ course = CourseFactory.create(**course_kwargs) inject_field_overrides((course, ), course, self.user) return course
def setUp(self): super(VerificationDeadlineSignalTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments self.end = now().replace(microsecond=0) + timedelta(days=7) self.course = CourseFactory.create(end=self.end) VerificationDeadline.objects.all().delete()
def set_up_course(cls): """ Set up a course for testing gated content. """ cls.course = CourseFactory.create(org='edX', number='EDX101', run='EDX101_RUN1', display_name='edX 101') with modulestore().bulk_operations(cls.course.id): cls.course.enable_subsection_gating = True grading_policy = { "GRADER": [{ "type": "Homework", "min_count": 3, "drop_count": 0, "short_label": "HW", "weight": 1.0 }] } cls.course.grading_policy = grading_policy cls.course.save() cls.store.update_item(cls.course, 0) # create chapter cls.chapter1 = ItemFactory.create( parent_location=cls.course.location, category='chapter', display_name='chapter 1') # create sequentials cls.seq1 = ItemFactory.create( parent_location=cls.chapter1.location, category='sequential', display_name='gating sequential 1', graded=True, format='Homework', ) cls.seq2 = ItemFactory.create( parent_location=cls.chapter1.location, category='sequential', display_name='gated sequential 2', graded=True, format='Homework', ) cls.seq3 = ItemFactory.create( parent_location=cls.chapter1.location, category='sequential', display_name='sequential 3', graded=True, format='Homework', ) # create problem cls.gating_prob1 = ItemFactory.create( parent_location=cls.seq1.location, category='problem', display_name='gating problem 1', ) cls.gated_prob2 = ItemFactory.create( parent_location=cls.seq2.location, category='problem', display_name='gated problem 2', ) cls.prob3 = ItemFactory.create( parent_location=cls.seq3.location, category='problem', display_name='problem 3', )
def setUpClass(cls): super(TestGetModuleScore, cls).setUpClass() cls.course = CourseFactory.create() cls.chapter = ItemFactory.create(parent=cls.course, category="chapter", display_name="Test Chapter") cls.seq1 = ItemFactory.create(parent=cls.chapter, category='sequential', display_name="Test Sequential 1", graded=True) cls.seq2 = ItemFactory.create(parent=cls.chapter, category='sequential', display_name="Test Sequential 2", graded=True) cls.seq3 = ItemFactory.create(parent=cls.chapter, category='sequential', display_name="Test Sequential 3", graded=True) cls.vert1 = ItemFactory.create(parent=cls.seq1, category='vertical', display_name='Test Vertical 1') cls.vert2 = ItemFactory.create(parent=cls.seq2, category='vertical', display_name='Test Vertical 2') cls.vert3 = ItemFactory.create(parent=cls.seq3, category='vertical', display_name='Test Vertical 3') cls.randomize = ItemFactory.create(parent=cls.vert2, category='randomize', display_name='Test Randomize') cls.library_content = ItemFactory.create( parent=cls.vert3, category='library_content', display_name='Test Library Content') problem_xml = MultipleChoiceResponseXMLFactory().build_xml( question_text='The correct answer is Choice 3', choices=[False, False, True, False], choice_names=['choice_0', 'choice_1', 'choice_2', 'choice_3']) cls.problem1 = ItemFactory.create(parent=cls.vert1, category="problem", display_name="Test Problem 1", data=problem_xml) cls.problem2 = ItemFactory.create(parent=cls.vert1, category="problem", display_name="Test Problem 2", data=problem_xml) cls.problem3 = ItemFactory.create(parent=cls.randomize, category="problem", display_name="Test Problem 3", data=problem_xml) cls.problem4 = ItemFactory.create(parent=cls.randomize, category="problem", display_name="Test Problem 4", data=problem_xml) cls.problem5 = ItemFactory.create(parent=cls.library_content, category="problem", display_name="Test Problem 5", data=problem_xml) cls.problem6 = ItemFactory.create(parent=cls.library_content, category="problem", display_name="Test Problem 6", data=problem_xml)
def setUp(self): course = CourseFactory.create() self.course_id = course.id
def setUp(self): # Need to make a *lot* of users for this one self.first_verified_user = UserFactory.create() self.first_verified_user.profile.name = "John Doe" self.first_verified_user.profile.save() self.second_verified_user = UserFactory.create() self.second_verified_user.profile.name = "Jane Deer" self.second_verified_user.profile.save() self.first_audit_user = UserFactory.create() self.first_audit_user.profile.name = "Joe Miller" self.first_audit_user.profile.save() self.second_audit_user = UserFactory.create() self.second_audit_user.profile.name = "Simon Blackquill" self.second_audit_user.profile.save() self.third_audit_user = UserFactory.create() self.third_audit_user.profile.name = "Super Mario" self.third_audit_user.profile.save() self.honor_user = UserFactory.create() self.honor_user.profile.name = "Princess Peach" self.honor_user.profile.save() self.first_refund_user = UserFactory.create() self.first_refund_user.profile.name = u"King Bowsér" self.first_refund_user.profile.save() self.second_refund_user = UserFactory.create() self.second_refund_user.profile.name = u"Súsan Smith" self.second_refund_user.profile.save() # Two are verified, three are audit, one honor self.course_id = "MITx/999/Robot_Super_Course" settings.COURSE_LISTINGS['default'] = [self.course_id] self.cost = 40 self.course = CourseFactory.create(org='MITx', number='999', display_name=u'Robot Super Course') course_mode = CourseMode(course_id=self.course_id, mode_slug="honor", mode_display_name="honor cert", min_price=self.cost) course_mode.save() course_mode2 = CourseMode(course_id=self.course_id, mode_slug="verified", mode_display_name="verified cert", min_price=self.cost) course_mode2.save() # User 1 & 2 will be verified self.cart1 = Order.get_cart_for_user(self.first_verified_user) CertificateItem.add_to_order(self.cart1, self.course_id, self.cost, 'verified') self.cart1.purchase() self.cart2 = Order.get_cart_for_user(self.second_verified_user) CertificateItem.add_to_order(self.cart2, self.course_id, self.cost, 'verified') self.cart2.purchase() # Users 3, 4, and 5 are audit CourseEnrollment.enroll(self.first_audit_user, self.course_id, "audit") CourseEnrollment.enroll(self.second_audit_user, self.course_id, "audit") CourseEnrollment.enroll(self.third_audit_user, self.course_id, "audit") # User 6 is honor CourseEnrollment.enroll(self.honor_user, self.course_id, "honor") self.now = datetime.datetime.now(pytz.UTC) # Users 7 & 8 are refunds self.cart = Order.get_cart_for_user(self.first_refund_user) CertificateItem.add_to_order(self.cart, self.course_id, self.cost, 'verified') self.cart.purchase() CourseEnrollment.unenroll(self.first_refund_user, self.course_id) self.cart = Order.get_cart_for_user(self.second_refund_user) CertificateItem.add_to_order(self.cart, self.course_id, self.cost, 'verified') self.cart.purchase(self.second_refund_user, self.course_id) CourseEnrollment.unenroll(self.second_refund_user, self.course_id) self.test_time = datetime.datetime.now(pytz.UTC) first_refund = CertificateItem.objects.get(id=3) first_refund.fulfilled_time = self.test_time first_refund.refund_requested_time = self.test_time first_refund.save() second_refund = CertificateItem.objects.get(id=4) second_refund.fulfilled_time = self.test_time second_refund.refund_requested_time = self.test_time second_refund.save() self.CORRECT_REFUND_REPORT_CSV = dedent(""" Order Number,Customer Name,Date of Original Transaction,Date of Refund,Amount of Refund,Service Fees (if any) 3,King Bowsér,{time_str},{time_str},40,0 4,Súsan Smith,{time_str},{time_str},40,0 """.format(time_str=str(self.test_time))) self.CORRECT_CERT_STATUS_CSV = dedent(""" University,Course,Course Announce Date,Course Start Date,Course Registration Close Date,Course Registration Period,Total Enrolled,Audit Enrollment,Honor Code Enrollment,Verified Enrollment,Gross Revenue,Gross Revenue over the Minimum,Number of Verified Students Contributing More than the Minimum,Number of Refunds,Dollars Refunded MITx,999 Robot Super Course,,,,,6,3,1,2,80.00,0.00,0,2,80.00 """.format(time_str=str(self.test_time))) self.CORRECT_UNI_REVENUE_SHARE_CSV = dedent(""" University,Course,Number of Transactions,Total Payments Collected,Service Fees (if any),Number of Successful Refunds,Total Amount of Refunds MITx,999 Robot Super Course,6,80.00,0.00,2,80.00 """.format(time_str=str(self.test_time)))
def setUp(self): super(TestCourses, self).setUp() self.course = CourseFactory.create(mobile_available=True)
def setUpClass(cls): super(CourseInfoTestCaseCCX, cls).setUpClass() cls.course = CourseFactory.create()
def setUp(self): super(CourseModeViewTest, self).setUp('course_modes.urls') self.course = CourseFactory.create() self.user = UserFactory.create(username="******", email="*****@*****.**", password="******") self.client.login(username=self.user.username, password="******")
def setUpClass(cls): super(CommentSerializerDeserializationTest, cls).setUpClass() cls.course = CourseFactory.create()
def setUpClass(cls): super(SelfPacedCourseInfoTestCase, cls).setUpClass() cls.instructor_paced_course = CourseFactory.create(self_paced=False) cls.self_paced_course = CourseFactory.create(self_paced=True)
def setup_test_data(self, store_type=ModuleStoreEnum.Type.mongo): """ Create courses and add some test blocks. """ with self.store.default_store(store_type): self.course = CourseFactory.create( display_name='An Introduction to API Testing') self.course_id = unicode(self.course.id) with self.store.bulk_operations(self.course.id): self.chapter_1 = ItemFactory.create( parent_location=self.course.location, category='chapter', display_name='Week 1') self.chapter_2 = ItemFactory.create( parent_location=self.course.location, category='chapter', display_name='Week 2') self.sequential_1 = ItemFactory.create( parent_location=self.chapter_1.location, category='sequential', display_name='Lesson 1') self.sequential_2 = ItemFactory.create( parent_location=self.chapter_1.location, category='sequential', display_name='Lesson 2') self.vertical_1 = ItemFactory.create( parent_location=self.sequential_1.location, category='vertical', display_name='Subsection 1') self.vertical_2 = ItemFactory.create( parent_location=self.sequential_2.location, category='vertical', display_name='Subsection 2') self.vertical_3 = ItemFactory.create( parent_location=self.sequential_2.location, category='vertical', display_name='Subsection 3') self.html_1 = ItemFactory.create( parent_location=self.vertical_2.location, category='html', display_name='Details 1') self.path = [ PathItem(self.chapter_1.location, self.chapter_1.display_name), PathItem(self.sequential_2.location, self.sequential_2.display_name), ] self.bookmark_1 = BookmarkFactory.create( user=self.user, course_key=self.course_id, usage_key=self.sequential_1.location, xblock_cache=XBlockCache.create({ 'display_name': self.sequential_1.display_name, 'usage_key': self.sequential_1.location, }), ) self.bookmark_2 = BookmarkFactory.create( user=self.user, course_key=self.course_id, usage_key=self.sequential_2.location, xblock_cache=XBlockCache.create({ 'display_name': self.sequential_2.display_name, 'usage_key': self.sequential_2.location, }), ) self.other_course = CourseFactory.create( display_name='An Introduction to API Testing 2') with self.store.bulk_operations(self.other_course.id): self.other_chapter_1 = ItemFactory.create( parent_location=self.other_course.location, category='chapter', display_name='Other Week 1') self.other_sequential_1 = ItemFactory.create( parent_location=self.other_chapter_1.location, category='sequential', display_name='Other Lesson 1') self.other_sequential_2 = ItemFactory.create( parent_location=self.other_chapter_1.location, category='sequential', display_name='Other Lesson 2') self.other_vertical_1 = ItemFactory.create( parent_location=self.other_sequential_1.location, category='vertical', display_name='Other Subsection 1') self.other_vertical_2 = ItemFactory.create( parent_location=self.other_sequential_1.location, category='vertical', display_name='Other Subsection 2') # self.other_vertical_1 has two parents self.other_sequential_2.children.append( self.other_vertical_1.location) modulestore().update_item(self.other_sequential_2, self.admin.id) # pylint: disable=no-member self.other_bookmark_1 = BookmarkFactory.create( user=self.user, course_key=unicode(self.other_course.id), usage_key=self.other_vertical_1.location, xblock_cache=XBlockCache.create({ 'display_name': self.other_vertical_1.display_name, 'usage_key': self.other_vertical_1.location, }), )
def _setup_course(self): self.course = CourseFactory.create( highlights_enabled_for_messaging=True ) self.course_key = self.course.id
def setUp(self): self.course = CourseFactory.create() self.staff_user = UserFactory.create(is_staff=True, username="******") self.non_staff_user = UserFactory.create(username="******")
def setUpClass(cls): super(SerializerTestMixin, cls).setUpClass() cls.course = CourseFactory.create()
def setUp(self): course_title = u"ẗëṡẗ title イ乇丂イ ᄊ乇丂丂ムg乇 キo尺 ムレレ тэѕт мэѕѕаБэ" self.course = CourseFactory.create(display_name=course_title)
def test_satisfy_all_requirements(self): """ Test the credit requirements, eligibility notification, email content caching for a credit course. """ # Configure a course with two credit requirements self.add_credit_course() CourseFactory.create(org='edX', number='DemoX', display_name='Demo_Course') requirements = [{ "namespace": "grade", "name": "grade", "display_name": "Grade", "criteria": { "min_grade": 0.8 }, }, { "namespace": "reverification", "name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid", "display_name": "Assessment 1", "criteria": {}, }] api.set_credit_requirements(self.course_key, requirements) user = UserFactory.create(username=self.USER_INFO['username'], password=self.USER_INFO['password']) # Satisfy one of the requirements, but not the other with self.assertNumQueries(7): api.set_credit_requirement_status(user.username, self.course_key, requirements[0]["namespace"], requirements[0]["name"]) # The user should not be eligible (because only one requirement is satisfied) self.assertFalse( api.is_user_eligible_for_credit("bob", self.course_key)) # Satisfy the other requirement with self.assertNumQueries(11): api.set_credit_requirement_status("bob", self.course_key, requirements[1]["namespace"], requirements[1]["name"]) # Now the user should be eligible self.assertTrue(api.is_user_eligible_for_credit( "bob", self.course_key)) # Credit eligibility email should be sent self.assertEqual(len(mail.outbox), 1) self.assertEqual(mail.outbox[0].subject, 'Course Credit Eligibility') # Now verify them email content email_payload_first = mail.outbox[0].attachments[0]._payload # pylint: disable=protected-access # Test that email has two payloads [multipart (plain text and html # content), attached image] self.assertEqual(len(email_payload_first), 2) # pylint: disable=protected-access self.assertIn('text/plain', email_payload_first[0]._payload[0]['Content-Type']) # pylint: disable=protected-access self.assertIn('text/html', email_payload_first[0]._payload[1]['Content-Type']) self.assertIn('image/png', email_payload_first[1]['Content-Type']) # Now check that html email content has same logo image 'Content-ID' # as the attached logo image 'Content-ID' email_image = email_payload_first[1] html_content_first = email_payload_first[0]._payload[1]._payload # pylint: disable=protected-access # strip enclosing angle brackets from 'logo_image' cache 'Content-ID' image_id = email_image.get('Content-ID', '')[1:-1] self.assertIsNotNone(image_id) self.assertIn(image_id, html_content_first) # Delete the eligibility entries and satisfy the user's eligibility # requirement again to trigger eligibility notification CreditEligibility.objects.all().delete() with self.assertNumQueries(12): api.set_credit_requirement_status("bob", self.course_key, requirements[1]["namespace"], requirements[1]["name"]) # Credit eligibility email should be sent self.assertEqual(len(mail.outbox), 2) # Now check that on sending eligibility notification again cached # logo image is used email_payload_second = mail.outbox[1].attachments[0]._payload # pylint: disable=protected-access html_content_second = email_payload_second[0]._payload[1]._payload # pylint: disable=protected-access self.assertIn(image_id, html_content_second) # The user should remain eligible even if the requirement status is later changed api.set_credit_requirement_status("bob", self.course_key, requirements[0]["namespace"], requirements[0]["name"], status="failed") self.assertTrue(api.is_user_eligible_for_credit( "bob", self.course_key))