Ejemplo n.º 1
0
    def test_program_completion_with_no_id_professional(
            self, mock_get_certificates_for_user, mock_get_programs):
        """
        Verify that 'no-id-professional' certificates are treated as if they were
        'professional' certificates when determining program completion.
        """
        # Create serialized course runs like the ones we expect to receive from
        # the discovery service's API. These runs are of type 'professional'.
        course_runs = CourseRunFactory.create_batch(2, type='professional')
        program = ProgramFactory(
            courses=[CourseFactory(course_runs=course_runs)])
        mock_get_programs.return_value = [program]

        # Verify that the test program is not complete.
        meter = ProgramProgressMeter(self.site, self.user)
        self.assertEqual(meter.completed_programs, [])

        # Grant a 'no-id-professional' certificate for one of the course runs,
        # thereby completing the program.
        mock_get_certificates_for_user.return_value = [
            self._make_certificate_result(status='downloadable',
                                          type='no-id-professional',
                                          course_key=course_runs[0]['key'])
        ]

        # Verify that the program is complete.
        meter = ProgramProgressMeter(self.site, self.user)
        self.assertEqual(meter.completed_programs, [program['uuid']])
Ejemplo n.º 2
0
    def test_completed_programs(self, mock_completed_course_runs, mock_get_programs):
        """Verify that completed programs are correctly identified."""
        data = ProgramFactory.create_batch(3)
        mock_get_programs.return_value = data

        program_uuids = []
        course_run_keys = []
        for program in data:
            program_uuids.append(program['uuid'])

            for course in program['courses']:
                for course_run in course['course_runs']:
                    course_run_keys.append(course_run['key'])

        # Verify that no programs are complete.
        meter = ProgramProgressMeter(self.user)
        self.assertEqual(meter.completed_programs, [])

        # Complete all programs.
        self._create_enrollments(*course_run_keys)
        mock_completed_course_runs.return_value = [
            {'course_run_id': course_run_key, 'type': MODES.verified}
            for course_run_key in course_run_keys
        ]

        # Verify that all programs are complete.
        meter = ProgramProgressMeter(self.user)
        self.assertEqual(meter.completed_programs, program_uuids)
Ejemplo n.º 3
0
    def test_completed_programs_no_id_professional(self,
                                                   mock_completed_course_runs,
                                                   mock_get_programs):
        """ Verify the method treats no-id-professional enrollments as professional enrollments. """
        course_runs = CourseRunFactory.create_batch(2,
                                                    type='no-id-professional')
        program = ProgramFactory(
            courses=[CourseFactory(course_runs=course_runs)])
        mock_get_programs.return_value = [program]

        # Verify that no programs are complete.
        meter = ProgramProgressMeter(self.user)
        self.assertEqual(meter.completed_programs, [])

        # Complete all programs.
        for course_run in course_runs:
            CourseEnrollmentFactory(user=self.user,
                                    course_id=course_run['key'],
                                    mode='no-id-professional')

        mock_completed_course_runs.return_value = [{
            'course_run_id':
            course_run['key'],
            'type':
            MODES.professional
        } for course_run in course_runs]

        # Verify that all programs are complete.
        meter = ProgramProgressMeter(self.user)
        self.assertEqual(meter.completed_programs, [program['uuid']])
Ejemplo n.º 4
0
    def handle(self, *args, **options):
        """
        Command's entry point.
        """
        should_commit = not options['no_commit']

        email_sent_records = []
        site = Site.objects.get_current()
        course_to_users_maps = self.get_passed_course_to_users_maps()

        for completed_course_id, users in course_to_users_maps.items():
            course_linked_programs = get_programs(course=completed_course_id)
            course_linked_programs = self.sort_programs(course_linked_programs)
            if course_linked_programs:
                for user in users:
                    meter = ProgramProgressMeter(site=site, user=user, include_course_entitlements=False)
                    programs_progress = meter.progress(programs=course_linked_programs, count_only=False)
                    suggested_program_progress, suggested_course_run = self.get_course_run_to_suggest(
                        programs_progress, completed_course_id
                    )
                    if suggested_course_run:
                        suggested_program = self.get_program(course_linked_programs, suggested_program_progress)
                        completed_course_run = self.get_course_run(suggested_program, completed_course_id)
                        if should_commit:
                            self.emit_event(user, suggested_program, suggested_course_run, completed_course_run)
                        email_sent_records.append(
                            f'User: {user.username}, Completed Course: {completed_course_id}, '
                            f'Suggested Course: {suggested_course_run["key"]}'
                        )

        LOGGER.info(
            '[Program Course Nudge Email] %s Emails sent. Records: %s',
            len(email_sent_records),
            email_sent_records,
        )
Ejemplo n.º 5
0
    def test_completed_course_runs(self, mock_get_certificates_for_user,
                                   _mock_get_programs):
        """
        Verify that the method can find course run certificates when not mocked out.
        """
        mock_get_certificates_for_user.return_value = [
            self._make_certificate_result(status='downloadable',
                                          type='verified',
                                          course_key='downloadable-course'),
            self._make_certificate_result(status='generating',
                                          type='honor',
                                          course_key='generating-course'),
            self._make_certificate_result(status='unknown',
                                          course_key='unknown-course'),
        ]

        meter = ProgramProgressMeter(self.site, self.user)
        self.assertEqual(meter.completed_course_runs, [
            {
                'course_run_id': 'downloadable-course',
                'type': 'verified'
            },
            {
                'course_run_id': 'generating-course',
                'type': 'honor'
            },
        ])
        mock_get_certificates_for_user.assert_called_with(self.user.username)
Ejemplo n.º 6
0
    def render_to_fragment(self, request, **kwargs):
        """
        Render the program listing fragment.
        """
        user = request.user
        try:
            mobile_only = json.loads(request.GET.get('mobile_only', 'false'))
        except ValueError:
            mobile_only = False

        programs_config = kwargs.get(
            'programs_config') or ProgramsApiConfig.current()
        if not programs_config.enabled or not user.is_authenticated:
            raise Http404

        meter = ProgramProgressMeter(request.site,
                                     user,
                                     mobile_only=mobile_only)

        context = {
            'marketing_url':
            get_program_marketing_url(programs_config, mobile_only),
            'programs':
            meter.engaged_programs,
            'progress':
            meter.progress()
        }
        html = render_to_string('learner_dashboard/programs_fragment.html',
                                context)
        programs_fragment = Fragment(html)
        self.add_fragment_resource_urls(programs_fragment)

        return programs_fragment
Ejemplo n.º 7
0
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 = ProgramProgressMeter(request.user)
    engaged_programs = [
        munge_catalog_program(program) for program in meter.engaged_programs
    ]
    progress = [
        munge_progress_map(progress_map) for progress_map in meter.progress
    ]

    context = {
        'credentials': get_programs_credentials(request.user),
        'disable_courseware_js': True,
        'marketing_url': get_program_marketing_url(programs_config),
        'nav_hidden': True,
        'programs': engaged_programs,
        'progress': progress,
        'show_program_listing': programs_config.show_program_listing,
        'uses_pattern_library': True,
    }

    return render_to_response('learner_dashboard/programs.html', context)
Ejemplo n.º 8
0
    def test_course_progress(self, mock_get_programs):
        """
        Verify that the progress meter can represent progress in terms of
        serialized courses.
        """
        course_run_key = generate_course_run_key()
        data = [
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=course_run_key),
                    ]),
                ]
            )
        ]
        mock_get_programs.return_value = data

        self._create_enrollments(course_run_key)

        meter = ProgramProgressMeter(self.user)

        program = data[0]
        expected = [
            ProgressFactory(
                uuid=program['uuid'],
                completed=[],
                in_progress=[program['courses'][0]],
                not_started=[]
            )
        ]

        self.assertEqual(meter.progress(count_only=False), expected)
Ejemplo n.º 9
0
    def test_course_grade_results(self, mock_get_programs):
        grade_percent = .8
        with mock_passing_grade(percent=grade_percent):
            course_run_key = generate_course_run_key()
            data = [
                ProgramFactory(
                    courses=[
                        CourseFactory(course_runs=[
                            CourseRunFactory(key=course_run_key),
                        ]),
                    ]
                )
            ]
            mock_get_programs.return_value = data

            self._create_enrollments(course_run_key)

            meter = ProgramProgressMeter(self.site, self.user)

            program = data[0]
            expected = [
                ProgressFactory(
                    uuid=program['uuid'],
                    completed=[],
                    in_progress=[program['courses'][0]],
                    not_started=[],
                    grades={course_run_key: grade_percent},
                )
            ]

            self.assertEqual(meter.progress(count_only=False), expected)
Ejemplo n.º 10
0
    def test_single_program_engagement(self, mock_get_programs):
        """
        Verify that correct program is returned when the user is enrolled in a
        course run appearing in one program.
        """
        course_run_key = generate_course_run_key()
        data = [
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=course_run_key),
                    ]),
                ]
            ),
            ProgramFactory(),
        ]
        mock_get_programs.return_value = data

        self._create_enrollments(course_run_key)
        meter = ProgramProgressMeter(self.user)

        self._attach_detail_url(data)
        program = data[0]
        self.assertEqual(meter.engaged_programs, [program])
        self._assert_progress(
            meter,
            ProgressFactory(uuid=program['uuid'], in_progress=1)
        )
        self.assertEqual(meter.completed_programs, [])
Ejemplo n.º 11
0
    def test_no_id_professional_in_progress(self, mock_get_programs):
        """
        Verify that the progress meter treats no-id-professional enrollments
        as professional.
        """
        course_run_key = generate_course_run_key()
        data = [
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=course_run_key, type=CourseMode.PROFESSIONAL),
                    ]),
                ]
            )
        ]
        mock_get_programs.return_value = data

        CourseEnrollmentFactory(
            user=self.user, course_id=course_run_key,
            mode=CourseMode.NO_ID_PROFESSIONAL_MODE
        )

        meter = ProgramProgressMeter(self.user)

        program = data[0]
        expected = [
            ProgressFactory(
                uuid=program['uuid'],
                completed=[],
                in_progress=[program['courses'][0]],
                not_started=[]
            )
        ]

        self.assertEqual(meter.progress(count_only=False), expected)
Ejemplo n.º 12
0
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 = 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'] = 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)
Ejemplo n.º 13
0
    def test_nonverified_course_run_completion(self, mock_completed_course_runs, mock_get_programs):
        """
        Course runs aren't necessarily of type verified. Verify that a program can
        still be completed when this is the case.
        """
        course_run_key = generate_course_run_key()
        data = [
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=course_run_key, type='honor'),
                        CourseRunFactory(),
                    ]),
                ]
            ),
            ProgramFactory(),
        ]
        mock_get_programs.return_value = data

        self._create_enrollments(course_run_key)
        mock_completed_course_runs.return_value = [
            {'course_run_id': course_run_key, 'type': MODES.honor},
        ]
        meter = ProgramProgressMeter(self.user)

        program, program_uuid = data[0], data[0]['uuid']
        self._assert_progress(
            meter,
            ProgressFactory(uuid=program_uuid, completed=1)
        )
        self.assertEqual(meter.completed_programs, [program_uuid])
Ejemplo n.º 14
0
    def test_mutiple_program_engagement(self, mock_get_programs):
        """
        Verify that correct programs are returned in the correct order when the
        user is enrolled in course runs appearing in programs.
        """
        newer_course_run_key, older_course_run_key = (
            generate_course_run_key() for __ in range(2))
        data = [
            ProgramFactory(courses=[
                CourseFactory(course_runs=[
                    CourseRunFactory(key=newer_course_run_key),
                ]),
            ]),
            ProgramFactory(courses=[
                CourseFactory(course_runs=[
                    CourseRunFactory(key=older_course_run_key),
                ]),
            ]),
            ProgramFactory(),
        ]
        mock_get_programs.return_value = data

        # The creation time of the enrollments matters to the test. We want
        # the first_course_run_key to represent the newest enrollment.
        self._create_enrollments(older_course_run_key, newer_course_run_key)
        meter = ProgramProgressMeter(self.user)

        self._attach_detail_url(data)
        programs = data[:2]
        self.assertEqual(meter.engaged_programs, programs)
        self._assert_progress(
            meter,
            *(ProgressFactory(uuid=program['uuid'], in_progress=1)
              for program in programs))
        self.assertEqual(meter.completed_programs, [])
Ejemplo n.º 15
0
    def test_completed_course_runs(self, mock_get_certificates_for_user, _mock_get_programs):
        """
        Verify that the method can find course run certificates when not mocked out.
        """
        def make_certificate_result(**kwargs):
            """Helper to create dummy results from the certificates API."""
            result = {
                'username': '******',
                'course_key': 'dummy-course',
                'type': 'dummy-type',
                'status': 'dummy-status',
                'download_url': 'http://www.example.com/cert.pdf',
                'grade': '0.98',
                'created': '2015-07-31T00:00:00Z',
                'modified': '2015-07-31T00:00:00Z',
            }
            result.update(**kwargs)
            return result

        mock_get_certificates_for_user.return_value = [
            make_certificate_result(status='downloadable', type='verified', course_key='downloadable-course'),
            make_certificate_result(status='generating', type='honor', course_key='generating-course'),
            make_certificate_result(status='unknown', course_key='unknown-course'),
        ]

        meter = ProgramProgressMeter(self.user)
        self.assertEqual(
            meter.completed_course_runs,
            [
                {'course_run_id': 'downloadable-course', 'type': 'verified'},
                {'course_run_id': 'generating-course', 'type': 'honor'},
            ]
        )
        mock_get_certificates_for_user.assert_called_with(self.user.username)
Ejemplo n.º 16
0
    def related_programs(self):
        """
        Returns related program data if the effective_user is enrolled.
        Note: related programs can be None depending on the course.
        """
        if self.effective_user.is_anonymous:
            return

        meter = ProgramProgressMeter(self.request.site, self.effective_user)
        inverted_programs = meter.invert_programs()
        related_programs = inverted_programs.get(str(self.course_key))

        if related_programs is None:
            return

        related_progress = meter.progress(programs=related_programs)
        progress_by_program = {
            progress['uuid']: progress
            for progress in related_progress
        }

        programs = [{
            'progress': progress_by_program[program['uuid']],
            'title': program['title'],
            'slug': program['type_attrs']['slug'],
            'url': program['detail_url'],
            'uuid': program['uuid']
        } for program in related_programs]

        return programs
Ejemplo n.º 17
0
 def test_empty_programs(self, mock_get_programs):
     """Verify that programs with no courses do not count as completed."""
     program = ProgramFactory()
     program['courses'] = []
     meter = ProgramProgressMeter(self.site, self.user)
     program_complete = meter._is_program_complete(program)
     self.assertFalse(program_complete)
Ejemplo n.º 18
0
    def render_to_fragment(self, request, program_uuid, **kwargs):
        """View details about a specific program."""
        programs_config = kwargs.get(
            'programs_config') or ProgramsApiConfig.current()
        if not programs_config.enabled or not request.user.is_authenticated():
            raise Http404

        meter = ProgramProgressMeter(request.site,
                                     request.user,
                                     uuid=program_uuid)
        program_data = meter.programs[0]

        if not program_data:
            raise Http404

        try:
            mobile_only = json.loads(request.GET.get('mobile_only', 'false'))
        except ValueError:
            mobile_only = False

        program_data = ProgramDataExtender(program_data,
                                           request.user,
                                           mobile_only=mobile_only).extend()
        course_data = meter.progress(programs=[program_data],
                                     count_only=False)[0]
        certificate_data = get_certificates(request.user, program_data)

        program_data.pop('courses')
        skus = program_data.get('skus')
        ecommerce_service = EcommerceService()

        urls = {
            'program_listing_url':
            reverse('program_listing_view'),
            'track_selection_url':
            strip_course_id(
                reverse('course_modes_choose',
                        kwargs={'course_id': FAKE_COURSE_KEY})),
            'commerce_api_url':
            reverse('commerce_api:v0:baskets:create'),
            'buy_button_url':
            ecommerce_service.get_checkout_page_url(*skus)
        }

        context = {
            'urls': urls,
            'user_preferences': get_user_preferences(request.user),
            'program_data': program_data,
            'course_data': course_data,
            'certificate_data': certificate_data
        }

        html = render_to_string(
            'learner_dashboard/program_details_fragment.html', context)
        program_details_fragment = Fragment(html)
        self.add_fragment_resource_urls(program_details_fragment)
        return program_details_fragment
Ejemplo n.º 19
0
    def test_no_enrollments(self, mock_get_programs):
        """Verify behavior when programs exist, but no relevant enrollments do."""
        data = [ProgramFactory()]
        mock_get_programs.return_value = data

        meter = ProgramProgressMeter(self.user)

        self.assertEqual(meter.engaged_programs, [])
        self._assert_progress(meter)
        self.assertEqual(meter.completed_programs, [])
Ejemplo n.º 20
0
    def render_to_fragment(self, request, program_uuid, **kwargs):
        """View details about a specific program."""
        programs_config = kwargs.get('programs_config') or ProgramsApiConfig.current()
        if not programs_config.enabled or not request.user.is_authenticated:
            raise Http404

        meter = ProgramProgressMeter(request.site, request.user, uuid=program_uuid)
        program_data = meter.programs[0]

        if not program_data:
            raise Http404

        try:
            mobile_only = json.loads(request.GET.get('mobile_only', 'false'))
        except ValueError:
            mobile_only = False

        program_data = ProgramDataExtender(program_data, request.user, mobile_only=mobile_only).extend()
        course_data = meter.progress(programs=[program_data], count_only=False)[0]
        certificate_data = get_certificates(request.user, program_data)

        program_data.pop('courses')
        skus = program_data.get('skus')
        ecommerce_service = EcommerceService()

        # TODO: Don't have business logic of course-certificate==record-available here in LMS.
        # Eventually, the UI should ask Credentials if there is a record available and get a URL from it.
        # But this is here for now so that we can gate this URL behind both this business logic and
        # a waffle flag. This feature is in active developoment.
        program_record_url = get_credentials_records_url(program_uuid=program_uuid)
        if not certificate_data:
            program_record_url = None

        urls = {
            'program_listing_url': reverse('program_listing_view'),
            'track_selection_url': strip_course_id(
                reverse('course_modes_choose', kwargs={'course_id': FAKE_COURSE_KEY})
            ),
            'commerce_api_url': reverse('commerce_api:v0:baskets:create'),
            'buy_button_url': ecommerce_service.get_checkout_page_url(*skus),
            'program_record_url': program_record_url,
        }

        context = {
            'urls': urls,
            'user_preferences': get_user_preferences(request.user),
            'program_data': program_data,
            'course_data': course_data,
            'certificate_data': certificate_data
        }

        html = render_to_string('learner_dashboard/program_details_fragment.html', context)
        program_details_fragment = Fragment(html)
        self.add_fragment_resource_urls(program_details_fragment)
        return program_details_fragment
Ejemplo n.º 21
0
def program_details(request, program_uuid):
    """View details about a specific program."""
    programs_config = ProgramsApiConfig.current()
    if not programs_config.enabled:
        raise Http404

    meter = ProgramProgressMeter(request.user, uuid=program_uuid)
    program_data = meter.programs[0]

    if not program_data:
        raise Http404

    program_data = ProgramDataExtender(program_data, request.user).extend()

    urls = {
        'program_listing_url':
        reverse('program_listing_view'),
        'track_selection_url':
        strip_course_id(
            reverse('course_modes_choose',
                    kwargs={'course_id': FAKE_COURSE_KEY})),
        'commerce_api_url':
        reverse('commerce_api:v0:baskets:create'),
    }

    context = {
        'urls': urls,
        'show_program_listing': programs_config.enabled,
        'nav_hidden': True,
        'disable_courseware_js': True,
        'uses_pattern_library': True,
        'user_preferences': get_user_preferences(request.user)
    }

    if waffle.switch_is_active('new_program_progress'):
        course_data = meter.progress(programs=[program_data],
                                     count_only=False)[0]
        certificate_data = get_certificates(request.user, program_data)

        program_data.pop('courses')

        context.update({
            'program_data': program_data,
            'course_data': course_data,
            'certificate_data': certificate_data,
        })

        return render_to_response(
            'learner_dashboard/program_details_2017.html', context)
    else:
        context.update({'program_data': program_data})

        return render_to_response('learner_dashboard/program_details.html',
                                  context)
Ejemplo n.º 22
0
    def test_no_programs(self, mock_get_programs):
        """Verify behavior when enrollments exist, but no matching programs do."""
        mock_get_programs.return_value = []

        course_run_id = generate_course_run_key()
        self._create_enrollments(course_run_id)
        meter = ProgramProgressMeter(self.user)

        self.assertEqual(meter.engaged_programs, [])
        self._assert_progress(meter)
        self.assertEqual(meter.completed_programs, [])
Ejemplo n.º 23
0
def get_completed_programs(student):
    """
    Given a set of completed courses, determine which programs are completed.

    Args:
        student (User): Representing the student whose completed programs to check for.

    Returns:
        list of program UUIDs

    """
    meter = ProgramProgressMeter(student)
    return meter.completed_programs
Ejemplo n.º 24
0
def get_completed_programs(site, student):
    """
    Given a set of completed courses, determine which programs are completed.

    Args:
        site (Site): Site for which data should be retrieved.
        student (User): Representing the student whose completed programs to check for.

    Returns:
        dict of {program_UUIDs: visible_dates}

    """
    meter = ProgramProgressMeter(site, student)
    return meter.completed_programs_with_available_dates
Ejemplo n.º 25
0
def get_completed_programs(site, student):
    """
    Given a set of completed courses, determine which programs are completed.

    Args:
        site (Site): Site for which data should be retrieved.
        student (User): Representing the student whose completed programs to check for.

    Returns:
        list of program UUIDs

    """
    meter = ProgramProgressMeter(site, student)
    return meter.completed_programs
Ejemplo n.º 26
0
    def test_shared_enrollment_engagement(self, mock_get_programs):
        """
        Verify that correct programs are returned when the user is enrolled in a
        single course run appearing in multiple programs.
        """
        shared_course_run_key, solo_course_run_key = (generate_course_run_key() for __ in range(2))

        batch = [
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=shared_course_run_key),
                    ]),
                ]
            )
            for __ in range(2)
        ]

        joint_programs = sorted(batch, key=lambda program: program['title'])
        data = joint_programs + [
            ProgramFactory(
                courses=[
                    CourseFactory(course_runs=[
                        CourseRunFactory(key=solo_course_run_key),
                    ]),
                ]
            ),
            ProgramFactory(),
        ]

        mock_get_programs.return_value = data

        # Enrollment for the shared course run created last (most recently).
        self._create_enrollments(solo_course_run_key, shared_course_run_key)
        meter = ProgramProgressMeter(self.site, self.user)

        self._attach_detail_url(data)
        programs = data[:3]
        self.assertEqual(meter.engaged_programs, programs)

        grades = {
            solo_course_run_key: 0.0,
            shared_course_run_key: 0.0,
        }

        self._assert_progress(
            meter,
            *(ProgressFactory(uuid=program['uuid'], in_progress=1, grades=grades) for program in programs)
        )
        self.assertEqual(meter.completed_programs, [])
Ejemplo n.º 27
0
 def test_credit_course_counted_complete_for_verified(self, mock_completed_course_runs, mock_get_programs):
     """
     Verify that 'credit' course certificate type are treated as if they were
     "verified" when checking for course completion status.
     """
     course_run_key = generate_course_run_key()
     course = CourseFactory(course_runs=[
         CourseRunFactory(key=course_run_key, type='credit'),
     ])
     program = ProgramFactory(courses=[course])
     mock_get_programs.return_value = [program]
     self._create_enrollments(course_run_key)
     meter = ProgramProgressMeter(self.user)
     mock_completed_course_runs.return_value = [{'course_run_id': course_run_key, 'type': 'verified'}]
     self.assertEqual(meter._is_course_complete(course), True)
Ejemplo n.º 28
0
def program_details(request, program_uuid):
    """View details about a specific program."""
    programs_config = ProgramsApiConfig.current()
    if not programs_config.enabled:
        raise Http404

    meter = ProgramProgressMeter(request.site, request.user, uuid=program_uuid)
    program_data = meter.programs[0]

    if not program_data:
        raise Http404

    program_data = ProgramDataExtender(program_data, request.user).extend()
    course_data = meter.progress(programs=[program_data], count_only=False)[0]
    certificate_data = get_certificates(request.user, program_data)

    program_data.pop('courses')
    skus = program_data.get('skus')
    ecommerce_service = EcommerceService()

    urls = {
        'program_listing_url':
        reverse('program_listing_view'),
        'track_selection_url':
        strip_course_id(
            reverse('course_modes_choose',
                    kwargs={'course_id': FAKE_COURSE_KEY})),
        'commerce_api_url':
        reverse('commerce_api:v0:baskets:create'),
        'buy_button_url':
        ecommerce_service.get_checkout_page_url(*skus)
    }

    context = {
        'urls': urls,
        'show_program_listing': programs_config.enabled,
        'show_dashboard_tabs': True,
        'nav_hidden': True,
        'disable_courseware_js': True,
        'uses_pattern_library': True,
        'user_preferences': get_user_preferences(request.user),
        'program_data': program_data,
        'course_data': course_data,
        'certificate_data': certificate_data
    }

    return render_to_response('learner_dashboard/program_details.html',
                              context)
Ejemplo n.º 29
0
def get_inverted_programs(student):
    """
    Get programs keyed by course run ID.

    Args:
        student (User): Representing the student whose programs to check for.

    Returns:
        dict, programs keyed by course run ID

    """
    inverted_programs = {}
    for site in Site.objects.all():
        meter = ProgramProgressMeter(site, student)
        inverted_programs.update(meter.invert_programs())

    return inverted_programs
Ejemplo n.º 30
0
def program_listing(request):
    """View a list of programs in which the user is engaged."""
    programs_config = ProgramsApiConfig.current()
    if not programs_config.enabled:
        raise Http404

    meter = ProgramProgressMeter(request.user)

    context = {
        'disable_courseware_js': True,
        'marketing_url': get_program_marketing_url(programs_config),
        'nav_hidden': True,
        'programs': meter.engaged_programs,
        'progress': meter.progress(),
        'show_program_listing': programs_config.enabled,
        'uses_pattern_library': True,
    }

    return render_to_response('learner_dashboard/programs.html', context)