Exemplo n.º 1
0
    def init_cache(self):
        """ This function plays the role of the ``cache_programs`` management command. """
        all_programs = [
            self.masters_program_1, self.masters_program_2,
            self.bachelors_program, self.no_type_program,
            self.masters_program_other_site
        ]
        cached_programs = {
            PROGRAM_CACHE_KEY_TPL.format(uuid=program['uuid']): program
            for program in all_programs
        }
        cache.set_many(cached_programs, None)

        programs_by_type = defaultdict(list)
        programs_by_type_slug = defaultdict(list)
        for program in all_programs:
            program_type = normalize_program_type(program.get('type'))
            program_type_slug = (program.get('type_attrs') or {}).get('slug')
            site_id = self.site.id

            if program == self.masters_program_other_site:
                site_id = self.other_site.id

            program_type_cache_key = PROGRAMS_BY_TYPE_CACHE_KEY_TPL.format(
                site_id=site_id, program_type=program_type)
            program_type_slug_cache_key = PROGRAMS_BY_TYPE_SLUG_CACHE_KEY_TPL.format(
                site_id=site_id, program_slug=program_type_slug)
            programs_by_type[program_type_cache_key].append(program['uuid'])
            programs_by_type_slug[program_type_slug_cache_key].append(
                program['uuid'])

        cache.set_many(programs_by_type, None)
        cache.set_many(programs_by_type_slug, None)
Exemplo n.º 2
0
    def get(self, request):
        """
        How to respond to a GET request to this endpoint
        """

        request_user = request.user

        programs = []
        requested_program_type = normalize_program_type(
            request.GET.get('type', self.DEFAULT_PROGRAM_TYPE))

        if request_user.is_staff:
            programs = get_programs_by_type(request.site,
                                            requested_program_type)
        else:
            program_dict = {}
            # Check if the user is a course staff of any course which is a part of a program.
            for staff_program in self.get_programs_user_is_course_staff_for(
                    request_user, requested_program_type):
                program_dict.setdefault(staff_program['uuid'], staff_program)

            # Now get the program enrollments for user purely as a learner add to the list
            for learner_program in self._get_enrolled_programs_from_model(
                    request_user):
                program_dict.setdefault(learner_program['uuid'],
                                        learner_program)

            programs = list(program_dict.values())

        programs_in_which_user_has_access = [{
            'uuid': program['uuid'],
            'slug': program['marketing_slug']
        } for program in programs]

        return Response(programs_in_which_user_has_access, status.HTTP_200_OK)
Exemplo n.º 3
0
    def get(self, request):
        """
        How to respond to a GET request to this endpoint
        """

        request_user = request.user

        programs = []
        requested_program_type = normalize_program_type(
            request.GET.get('type', self.DEFAULT_PROGRAM_TYPE))

        if request_user.is_staff:
            programs = get_programs_by_type(request.site,
                                            requested_program_type)
        elif self.is_course_staff(request_user):
            programs = self.get_programs_user_is_course_staff_for(
                request_user, requested_program_type)
        else:
            program_enrollments = fetch_program_enrollments_by_student(
                user=request.user,
                program_enrollment_statuses=ProgramEnrollmentStatuses.
                __ACTIVE__,
            )
            uuids = [
                enrollment.program_uuid for enrollment in program_enrollments
            ]
            programs = get_programs(uuids=uuids) or []

        programs_in_which_user_has_access = [{
            'uuid': program['uuid'],
            'slug': program['marketing_slug']
        } for program in programs]

        return Response(programs_in_which_user_has_access, status.HTTP_200_OK)
Exemplo n.º 4
0
 def get_programs_by_type(self, site, programs):
     """
     Returns a dictionary mapping site-aware cache keys corresponding to program types
     to lists of program uuids with that type.
     """
     programs_by_type = defaultdict(list)
     for program in programs.values():
         program_type = normalize_program_type(program.get('type'))
         cache_key = PROGRAMS_BY_TYPE_CACHE_KEY_TPL.format(site_id=site.id, program_type=program_type)
         programs_by_type[cache_key].append(program['uuid'])
     return programs_by_type
Exemplo n.º 5
0
 def test_normalize_program_type(self):
     self.assertEqual('none', normalize_program_type(None))
     self.assertEqual('false', normalize_program_type(False))
     self.assertEqual('true', normalize_program_type(True))
     self.assertEqual('', normalize_program_type(''))
     self.assertEqual('masters', normalize_program_type('Masters'))
     self.assertEqual('masters', normalize_program_type('masters'))
Exemplo n.º 6
0
 def test_normalize_program_type(self):
     assert 'none' == normalize_program_type(None)
     assert 'false' == normalize_program_type(False)
     assert 'true' == normalize_program_type(True)
     assert '' == normalize_program_type('')
     assert 'masters' == normalize_program_type('Masters')
     assert 'masters' == normalize_program_type('masters')
Exemplo n.º 7
0
    def test_handle_programs(self):
        """
        Verify that the command requests and caches program UUIDs and details.
        """
        # Ideally, this user would be created in the test setup and deleted in
        # the one test case which covers the case where the user is missing. However,
        # that deletion causes "OperationalError: no such table: wiki_attachmentrevision"
        # when run on Jenkins.
        UserFactory(username=self.catalog_integration.service_username)

        programs = {
            PROGRAM_CACHE_KEY_TPL.format(uuid=program['uuid']): program
            for program in self.programs
        }

        self.mock_list()
        self.mock_pathways(self.pathways)

        for uuid in self.uuids:
            program = programs[PROGRAM_CACHE_KEY_TPL.format(uuid=uuid)]
            self.mock_detail(uuid, program)

        call_command('cache_programs')

        cached_uuids = cache.get(
            SITE_PROGRAM_UUIDS_CACHE_KEY_TPL.format(domain=self.site_domain))
        self.assertEqual(set(cached_uuids), set(self.uuids))

        program_keys = list(programs.keys())
        cached_programs = cache.get_many(program_keys)
        # Verify that the keys were all cache hits.
        self.assertEqual(set(cached_programs), set(programs))

        # We can't use a set comparison here because these values are dictionaries
        # and aren't hashable. We've already verified that all programs came out
        # of the cache above, so all we need to do here is verify the accuracy of
        # the data itself.
        for key, program in cached_programs.items():
            # cached programs have a pathways field added to them, remove before comparing
            del program['pathway_ids']
            self.assertEqual(program, programs[key])

        # the courses in the child program's first curriculum (the active one)
        # should point to both the child program and the first program
        # in the cache.
        for course in self.child_program['curricula'][0]['courses']:
            for course_run in course['course_runs']:
                course_run_cache_key = COURSE_PROGRAMS_CACHE_KEY_TPL.format(
                    course_run_id=course_run['key'])
                self.assertIn(self.programs[0]['uuid'],
                              cache.get(course_run_cache_key))
                self.assertIn(self.child_program['uuid'],
                              cache.get(course_run_cache_key))

        # for each program, assert that the program's UUID is in a cached list of
        # program UUIDS by program type and a cached list of UUIDs by authoring organization
        for program in self.programs:
            program_type = normalize_program_type(program.get('type', 'None'))
            program_type_cache_key = PROGRAMS_BY_TYPE_CACHE_KEY_TPL.format(
                site_id=self.site.id, program_type=program_type)
            self.assertIn(program['uuid'], cache.get(program_type_cache_key))

            for organization in program['authoring_organizations']:
                organization_cache_key = PROGRAMS_BY_ORGANIZATION_CACHE_KEY_TPL.format(
                    org_key=organization['key'])
                self.assertIn(program['uuid'],
                              cache.get(organization_cache_key))