def test_single_program_engagement(self): """ Verify that correct program is returned when the user has a single enrollment appearing in one program. """ course_id = 'org/course/run' data = [ factories.Program(organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=course_id), ]), ]), factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[factories.RunMode()]), ]), ] self._mock_programs_api(data) self._create_enrollments(course_id) meter = utils.ProgramProgressMeter(self.user) program = data[0] self.assertEqual(meter.engaged_programs, [program]) self._assert_progress( meter, factories.Progress(id=program['id'], in_progress=self._extract_names(program, 0))) self.assertEqual(meter.completed_programs, [])
def view_programs(request): """View programs in which the user is engaged.""" programs_config = ProgramsApiConfig.current() if not programs_config.show_program_listing: raise Http404 meter = utils.ProgramProgressMeter(request.user) programs = meter.engaged_programs # TODO: Pull 'xseries' string from configuration model. marketing_root = urljoin(settings.MKTG_URLS.get('ROOT'), 'xseries').rstrip('/') for program in programs: program['detail_url'] = utils.get_program_detail_url( program, marketing_root) program['display_category'] = utils.get_display_category(program) context = { 'programs': programs, 'progress': meter.progress, 'xseries_url': marketing_root if programs_config.show_xseries_ad else None, 'nav_hidden': True, 'show_program_listing': programs_config.show_program_listing, 'credentials': get_programs_credentials(request.user, category='xseries'), 'disable_courseware_js': True, 'uses_pattern_library': True } return render_to_response('learner_dashboard/programs.html', context)
def program_listing(request): """View a list of programs in which the user is engaged.""" programs_config = ProgramsApiConfig.current() if not programs_config.show_program_listing: raise Http404 meter = utils.ProgramProgressMeter(request.user) programs = meter.engaged_programs marketing_url = urljoin(settings.MKTG_URLS.get('ROOT'), programs_config.marketing_path).rstrip('/') for program in programs: program['detail_url'] = utils.get_program_detail_url( program, marketing_url) context = { 'credentials': get_programs_credentials(request.user), 'disable_courseware_js': True, 'marketing_url': marketing_url, 'nav_hidden': True, 'programs': programs, 'progress': meter.progress, 'show_program_listing': programs_config.show_program_listing, 'uses_pattern_library': True, } return render_to_response('learner_dashboard/programs.html', context)
def test_nonstandard_run_mode_completion(self, mock_get_completed_courses): """ A valid run mode isn't necessarily verified. Verify that the program can still be completed when this is the case. """ course_id = 'org/course/run' data = [ factories.Program(organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=course_id, mode_slug=MODES.honor), ]), ]), ] self._mock_programs_api(data) enrollments = self._create_enrollments(course_id) meter = utils.ProgramProgressMeter(self.user, enrollments) mock_get_completed_courses.return_value = [ { 'course_id': course_id, 'mode': MODES.honor }, ] program = data[0] self._assert_progress( meter, factories.Progress(id=program['id'], completed=self._extract_names(program, 0)))
def test_no_programs(self): """Verify behavior when enrollments exist, but no matching programs do.""" self._mock_programs_api([]) enrollments = self._create_enrollments('org/course/run') meter = utils.ProgramProgressMeter(self.user, enrollments) self.assertEqual(meter.engaged_programs, []) self._assert_progress(meter)
def test_shared_enrollment_engagement(self): """ Verify that correct programs are returned when the user has a single enrollment appearing in multiple programs. """ shared_course_id, solo_course_id = 'org/shared-course/run', 'org/solo-course/run' data = [ factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=shared_course_id), ]), ]), factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=shared_course_id), ]), ]), factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=solo_course_id), ]), ]), factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[factories.RunMode()]), ]), ] self._mock_programs_api(data) # Enrollment for the shared course ID created last (most recently). self._create_enrollments(solo_course_id, shared_course_id) meter = utils.ProgramProgressMeter(self.user) programs = data[:3] self.assertEqual(meter.engaged_programs, programs) self._assert_progress( meter, factories.Progress(id=programs[0]['id'], in_progress=self._extract_names(programs[0], 0)), factories.Progress(id=programs[1]['id'], in_progress=self._extract_names(programs[1], 0)), factories.Progress(id=programs[2]['id'], in_progress=self._extract_names(programs[2], 0))) self.assertEqual(meter.completed_programs, [])
def test_completed_programs(self, mock_get_completed_courses): """Verify that completed programs are correctly identified.""" program_count, course_code_count, run_mode_count = 3, 2, 2 data = [ factories.Program(organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode() for _ in range(run_mode_count) ]) for _ in range(course_code_count) ]) for _ in range(program_count) ] self._mock_programs_api(data) program_ids = [] course_ids = [] for program in data: program_ids.append(program['id']) for course_code in program['course_codes']: for run_mode in course_code['run_modes']: course_ids.append(run_mode['course_key']) # Verify that no programs are complete. meter = utils.ProgramProgressMeter(self.user) self.assertEqual(meter.completed_programs, []) # "Complete" all programs. self._create_enrollments(*course_ids) mock_get_completed_courses.return_value = [{ 'course_id': course_id, 'mode': MODES.verified } for course_id in course_ids] # Verify that all programs are complete. meter = utils.ProgramProgressMeter(self.user) self.assertEqual(meter.completed_programs, program_ids)
def test_no_enrollments(self): """Verify behavior when programs exist, but no relevant enrollments do.""" data = [ factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[factories.RunMode()]), ]), ] self._mock_programs_api(data) meter = utils.ProgramProgressMeter(self.user, []) self.assertEqual(meter.engaged_programs, []) self._assert_progress(meter)
def program_listing_marketing(request): """View a list of programs available in system""" programs_config = ProgramsApiConfig.current() if not programs_config.show_program_listing: raise Http404 auth_user = authenticate( username='******', password='******') if request.user.is_anonymous() else request.user meter = utils.ProgramProgressMeter(auth_user) context = { 'marketing_url': utils.get_program_marketing_url(programs_config), 'programs': meter.programs, } return render_to_response('learner_dashboard/programs_marketing.html', context)
def test_mutiple_program_engagement(self): """ Verify that correct programs are returned in the correct order when the user has multiple enrollments. """ first_course_id, second_course_id = 'org/first-course/run', 'org/second-course/run' data = [ factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=first_course_id), ]), ]), factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=second_course_id), ]), ]), factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[factories.RunMode()]), ]), ] self._mock_programs_api(data) self._create_enrollments(second_course_id, first_course_id) meter = utils.ProgramProgressMeter(self.user) self._attach_detail_url(data) programs = data[:2] self.assertEqual(meter.engaged_programs(), programs) self._assert_progress( meter, factories.Progress(id=programs[0]['id'], in_progress=self._extract_names(programs[0], 0)), factories.Progress(id=programs[1]['id'], in_progress=self._extract_names(programs[1], 0))) self.assertEqual(meter.completed_programs, [])
def program_listing(request): """View a list of programs in which the user is engaged.""" programs_config = ProgramsApiConfig.current() if not programs_config.show_program_listing: raise Http404 meter = utils.ProgramProgressMeter(request.user) context = { 'credentials': get_programs_credentials(request.user), 'disable_courseware_js': True, 'marketing_url': utils.get_program_marketing_url(programs_config), 'nav_hidden': True, 'programs': meter.engaged_programs(), 'progress': meter.progress, 'show_program_listing': programs_config.show_program_listing, 'uses_pattern_library': True, } return render_to_response('learner_dashboard/programs.html', context)
def view_programs(request): """View programs in which the user is engaged.""" show_program_listing = ProgramsApiConfig.current().show_program_listing if not show_program_listing: raise Http404 enrollments = list(get_course_enrollments(request.user, None, [])) meter = utils.ProgramProgressMeter(request.user, enrollments) programs = meter.engaged_programs # TODO: Pull 'xseries' string from configuration model. marketing_root = urljoin(settings.MKTG_URLS.get('ROOT'), 'xseries').strip('/') for program in programs: program['display_category'] = utils.get_display_category(program) program['marketing_url'] = '{root}/{slug}'.format( root=marketing_root, slug=program['marketing_slug']) context = { 'programs': programs, 'progress': meter.progress, 'xseries_url': marketing_root if ProgramsApiConfig.current().show_xseries_ad else None, 'nav_hidden': True, 'show_program_listing': show_program_listing, 'credentials': get_programs_credentials(request.user, category='xseries'), 'disable_courseware_js': True, 'uses_pattern_library': True } return render_to_response('learner_dashboard/programs.html', context)
def test_simulate_progress(self, mock_get_completed_courses): """Simulate the entirety of a user's progress through a program.""" first_course_id, second_course_id = 'org/first-course/run', 'org/second-course/run' data = [ factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[ factories.RunMode(course_key=first_course_id), ]), factories.CourseCode(run_modes=[ factories.RunMode(course_key=second_course_id), ]), ]), factories.Program( organizations=[factories.Organization()], course_codes=[ factories.CourseCode(run_modes=[factories.RunMode()]), ]), ] self._mock_programs_api(data) # No enrollments, no program engaged. meter = utils.ProgramProgressMeter(self.user) self._assert_progress(meter) self.assertEqual(meter.completed_programs, []) # One enrollment, program engaged. self._create_enrollments(first_course_id) meter = utils.ProgramProgressMeter(self.user) program, program_id = data[0], data[0]['id'] self._assert_progress( meter, factories.Progress(id=program_id, in_progress=self._extract_names(program, 0), not_started=self._extract_names(program, 1))) self.assertEqual(meter.completed_programs, []) # Two enrollments, program in progress. self._create_enrollments(second_course_id) meter = utils.ProgramProgressMeter(self.user) self._assert_progress( meter, factories.Progress(id=program_id, in_progress=self._extract_names(program, 0, 1))) self.assertEqual(meter.completed_programs, []) # One valid certificate earned, one course code complete. mock_get_completed_courses.return_value = [ { 'course_id': first_course_id, 'mode': MODES.verified }, ] meter = utils.ProgramProgressMeter(self.user) self._assert_progress( meter, factories.Progress(id=program_id, completed=self._extract_names(program, 0), in_progress=self._extract_names(program, 1))) self.assertEqual(meter.completed_programs, []) # Invalid certificate earned, still one course code to complete. mock_get_completed_courses.return_value = [ { 'course_id': first_course_id, 'mode': MODES.verified }, { 'course_id': second_course_id, 'mode': MODES.honor }, ] meter = utils.ProgramProgressMeter(self.user) self._assert_progress( meter, factories.Progress(id=program_id, completed=self._extract_names(program, 0), in_progress=self._extract_names(program, 1))) self.assertEqual(meter.completed_programs, []) # Second valid certificate obtained, all course codes complete. mock_get_completed_courses.return_value = [ { 'course_id': first_course_id, 'mode': MODES.verified }, { 'course_id': second_course_id, 'mode': MODES.verified }, ] meter = utils.ProgramProgressMeter(self.user) self._assert_progress( meter, factories.Progress(id=program_id, completed=self._extract_names(program, 0, 1))) self.assertEqual(meter.completed_programs, [program_id])