Exemplo n.º 1
0
    def test_get_many(self, mock_warning, mock_info):
        pathways = PathwayFactory.create_batch(3)

        # Cache details for 2 of 3 programs.
        partial_pathways = {
            PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway
            for pathway in pathways[:2]
        }
        cache.set_many(partial_pathways, None)

        # When called before pathways are cached, the function should return an
        # empty list and log a warning.
        assert get_pathways(self.site) == []
        mock_warning.assert_called_once_with(
            'Failed to get credit pathway ids from the cache.')
        mock_warning.reset_mock()

        # Cache all 3 pathways
        cache.set(
            SITE_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site.domain),
            [pathway['id'] for pathway in pathways], None)

        actual_pathways = get_pathways(self.site)

        # The 2 cached pathways should be returned while info and warning
        # messages should be logged for the missing one.
        assert {pathway['id'] for pathway in actual_pathways} ==\
               {pathway['id'] for pathway in partial_pathways.values()}
        mock_info.assert_called_with(
            'Failed to get details for 1 pathways. Retrying.')
        mock_warning.assert_called_with(
            'Failed to get details for credit pathway {id} from the cache.'.
            format(id=pathways[2]['id']))
        mock_warning.reset_mock()

        # We can't use a set comparison here because these values are dictionaries
        # and aren't hashable. We've already verified that all pathways came out
        # of the cache above, so all we need to do here is verify the accuracy of
        # the data itself.
        for pathway in actual_pathways:
            key = PATHWAY_CACHE_KEY_TPL.format(id=pathway['id'])
            assert pathway == partial_pathways[key]

        # Cache details for all 3 pathways.
        all_pathways = {
            PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway
            for pathway in pathways
        }
        cache.set_many(all_pathways, None)

        actual_pathways = get_pathways(self.site)

        # All 3 pathways should be returned.
        assert {pathway['id'] for pathway in actual_pathways} ==\
               {pathway['id'] for pathway in all_pathways.values()}
        assert not mock_warning.called

        for pathway in actual_pathways:
            key = PATHWAY_CACHE_KEY_TPL.format(id=pathway['id'])
            assert pathway == all_pathways[key]
Exemplo n.º 2
0
    def setUp(self):
        super(TestCachePrograms, self).setUp()

        httpretty.httpretty.reset()

        self.catalog_integration = self.create_catalog_integration()
        self.site_domain = 'testsite.com'
        self.site = self.set_up_site(
            self.site_domain,
            {
                'COURSE_CATALOG_API_URL': self.catalog_integration.get_internal_api_url().rstrip('/')
            }
        )

        self.list_url = self.catalog_integration.get_internal_api_url().rstrip('/') + '/programs/'
        self.detail_tpl = self.list_url.rstrip('/') + '/{uuid}/'
        self.pathway_url = self.catalog_integration.get_internal_api_url().rstrip('/') + '/pathways/'

        self.programs = ProgramFactory.create_batch(3)
        self.pathways = PathwayFactory.create_batch(3)
        self.child_program = ProgramFactory.create()

        self.programs[0]['curricula'][0]['programs'].append(self.child_program)
        self.programs.append(self.child_program)

        self.programs[0]['authoring_organizations'] = OrganizationFactory.create_batch(2)

        for pathway in self.pathways:
            self.programs += pathway['programs']

        self.uuids = [program['uuid'] for program in self.programs]

        # add some of the previously created programs to some pathways
        self.pathways[0]['programs'].extend([self.programs[0], self.programs[1]])
        self.pathways[1]['programs'].append(self.programs[0])
Exemplo n.º 3
0
    def test_get_many_with_missing(self, mock_cache, mock_warning, mock_info):
        pathways = PathwayFactory.create_batch(3)

        all_pathways = {
            PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways
        }

        partial_pathways = {
            PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways[:2]
        }

        def fake_get_many(keys):
            if len(keys) == 1:
                return {PATHWAY_CACHE_KEY_TPL.format(id=pathways[-1]['id']): pathways[-1]}
            else:
                return partial_pathways

        mock_cache.get.return_value = [pathway['id'] for pathway in pathways]
        mock_cache.get_many.side_effect = fake_get_many

        actual_pathways = get_pathways(self.site)

        # All 3 cached pathways should be returned. An info message should be
        # logged about the one that was initially missing, but the code should
        # be able to stitch together all the details.
        self.assertEqual(
            set(pathway['id'] for pathway in actual_pathways),
            set(pathway['id'] for pathway in all_pathways.values())
        )
        self.assertFalse(mock_warning.called)
        mock_info.assert_called_with('Failed to get details for 1 pathways. Retrying.')

        for pathway in actual_pathways:
            key = PATHWAY_CACHE_KEY_TPL.format(id=pathway['id'])
            self.assertEqual(pathway, all_pathways[key])
    def setUp(self):
        super(TestCachePrograms, self).setUp()

        httpretty.httpretty.reset()

        self.catalog_integration = self.create_catalog_integration()
        self.site_domain = 'testsite.com'
        self.set_up_site(
            self.site_domain,
            {
                'COURSE_CATALOG_API_URL': self.catalog_integration.get_internal_api_url().rstrip('/')
            }
        )

        self.list_url = self.catalog_integration.get_internal_api_url().rstrip('/') + '/programs/'
        self.detail_tpl = self.list_url.rstrip('/') + '/{uuid}/'
        self.pathway_url = self.catalog_integration.get_internal_api_url().rstrip('/') + '/pathways/'

        self.programs = ProgramFactory.create_batch(3)
        self.pathways = PathwayFactory.create_batch(3)

        for pathway in self.pathways:
            self.programs += pathway['programs']

        self.uuids = [program['uuid'] for program in self.programs]

        # add some of the previously created programs to some pathways
        self.pathways[0]['programs'].extend([self.programs[0], self.programs[1]])
        self.pathways[1]['programs'].append(self.programs[0])
Exemplo n.º 5
0
    def test_pathways_multiple_pages(self):
        """
        Verify that the command properly caches credit pathways when multiple pages are returned from its endpoint
        """
        UserFactory(username=self.catalog_integration.service_username)
        new_pathways = PathwayFactory.create_batch(40)
        for new_pathway in new_pathways:
            new_pathway['programs'] = []
        pathways = self.pathways + new_pathways

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

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

        # mock 3 pages of credit pathways, starting at the last
        self.mock_pathways(pathways[40:], page_number=3, final=True)
        self.mock_pathways(pathways[20:40], page_number=2, final=False)
        self.mock_pathways(pathways[:20], page_number=1, final=False)

        call_command('cache_programs')

        pathways_dict = {
            PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways
        }
        pathway_keys = list(pathways_dict.keys())

        cached_pathway_keys = cache.get(SITE_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site_domain))
        self.assertEqual(
            set(cached_pathway_keys),
            set(pathway_keys)
        )

        cached_pathways = cache.get_many(pathway_keys)
        self.assertEqual(
            set(cached_pathways),
            set(pathways_dict)
        )

        # We can't use a set comparison here because these values are dictionaries
        # and aren't hashable. We've already verified that all pathways came out
        # of the cache above, so all we need to do here is verify the accuracy of
        # the data itself.
        for key, pathway in cached_pathways.items():
            # cached pathways store just program uuids instead of the full programs, transform before comparing
            pathways_dict[key]['program_uuids'] = [program['uuid'] for program in pathways_dict[key]['programs']]
            del pathways_dict[key]['programs']

            self.assertEqual(pathway, pathways_dict[key])
Exemplo n.º 6
0
    def setUpClass(cls):
        super().setUpClass()

        modulestore_course = ModuleStoreCourseFactory()
        course_run = CourseRunFactory(key=str(modulestore_course.id))  # lint-amnesty, pylint: disable=no-member
        course = CourseFactory(course_runs=[course_run])

        cls.program_data = ProgramFactory(uuid=cls.program_uuid, courses=[course])
        cls.pathway_data = PathwayFactory()
        cls.program_data['pathway_ids'] = [cls.pathway_data['id']]
        cls.pathway_data['program_uuids'] = [cls.program_data['uuid']]
        del cls.pathway_data['programs']  # lint-amnesty, pylint: disable=unsupported-delete-operation
Exemplo n.º 7
0
    def setUpClass(cls):
        super(TestProgramDetails, cls).setUpClass()

        modulestore_course = ModuleStoreCourseFactory()
        course_run = CourseRunFactory(key=six.text_type(modulestore_course.id))
        course = CourseFactory(course_runs=[course_run])

        cls.program_data = ProgramFactory(uuid=cls.program_uuid, courses=[course])
        cls.pathway_data = PathwayFactory()
        cls.program_data['pathway_ids'] = [cls.pathway_data['id']]
        cls.pathway_data['program_uuids'] = [cls.program_data['uuid']]
        del cls.pathway_data['programs']
    def test_pathways_multiple_pages(self):
        """
        Verify that the command properly caches credit pathways when multiple pages are returned from its endpoint
        """
        UserFactory(username=self.catalog_integration.service_username)
        new_pathways = PathwayFactory.create_batch(40)
        for new_pathway in new_pathways:
            new_pathway['programs'] = []
        pathways = self.pathways + new_pathways

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

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

        # mock 3 pages of credit pathways, starting at the last
        self.mock_pathways(pathways[40:], page_number=3, final=True)
        self.mock_pathways(pathways[20:40], page_number=2, final=False)
        self.mock_pathways(pathways[:20], page_number=1, final=False)

        call_command('cache_programs')

        pathways_dict = {
            PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways
        }
        pathway_keys = list(pathways_dict.keys())

        cached_pathway_keys = cache.get(SITE_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site_domain))
        self.assertEqual(
            set(cached_pathway_keys),
            set(pathway_keys)
        )

        cached_pathways = cache.get_many(pathway_keys)
        self.assertEqual(
            set(cached_pathways),
            set(pathways_dict)
        )

        # We can't use a set comparison here because these values are dictionaries
        # and aren't hashable. We've already verified that all pathways came out
        # of the cache above, so all we need to do here is verify the accuracy of
        # the data itself.
        for key, pathway in cached_pathways.items():
            # cached pathways store just program uuids instead of the full programs, transform before comparing
            pathways_dict[key]['program_uuids'] = [program['uuid'] for program in pathways_dict[key]['programs']]
            del pathways_dict[key]['programs']

            self.assertEqual(pathway, pathways_dict[key])
Exemplo n.º 9
0
    def setUp(self):
        super(ProgramPageBase, self).setUp()

        self.set_programs_api_configuration(is_enabled=True)

        self.programs = ProgramFactory.create_batch(3)
        self.pathways = PathwayFactory.create_batch(3)
        for pathway in self.pathways:
            self.programs += pathway['programs']

        # add some of the previously created programs to some pathways
        self.pathways[0]['programs'].extend([self.programs[0], self.programs[1]])
        self.pathways[1]['programs'].append(self.programs[0])

        self.username = None
    def setUp(self):
        super().setUp()

        self.set_programs_api_configuration(is_enabled=True)

        self.programs = ProgramFactory.create_batch(3)
        self.pathways = PathwayFactory.create_batch(3)
        for pathway in self.pathways:
            self.programs += pathway['programs']

        # add some of the previously created programs to some pathways
        self.pathways[0]['programs'].extend([self.programs[0], self.programs[1]])
        self.pathways[1]['programs'].append(self.programs[0])

        self.username = None
Exemplo n.º 11
0
    def test_get_one(self, mock_warning, _mock_info):
        expected_pathway = PathwayFactory()
        expected_id = expected_pathway['id']

        self.assertEqual(get_pathways(self.site, pathway_id=expected_id), None)
        mock_warning.assert_called_once_with(
            u'Failed to get details for credit pathway {id} from the cache.'.
            format(id=expected_id))
        mock_warning.reset_mock()

        cache.set(PATHWAY_CACHE_KEY_TPL.format(id=expected_id),
                  expected_pathway, None)

        actual_pathway = get_pathways(self.site, pathway_id=expected_id)
        self.assertEqual(actual_pathway, expected_pathway)
        self.assertFalse(mock_warning.called)
Exemplo n.º 12
0
    def setUp(self):
        super(ProgramPageBase, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments

        self.set_programs_api_configuration(is_enabled=True)

        self.programs = ProgramFactory.create_batch(3)
        self.pathways = PathwayFactory.create_batch(3)
        for pathway in self.pathways:
            self.programs += pathway['programs']

        # add some of the previously created programs to some pathways
        self.pathways[0]['programs'].extend(
            [self.programs[0], self.programs[1]])
        self.pathways[1]['programs'].append(self.programs[0])

        self.username = None
Exemplo n.º 13
0
    def test_get_one(self, mock_warning, _mock_info):
        expected_pathway = PathwayFactory()
        expected_id = expected_pathway['id']

        assert get_pathways(self.site, pathway_id=expected_id) is None
        mock_warning.assert_called_once_with(
            f'Failed to get details for credit pathway {expected_id} from the cache.'
        )
        mock_warning.reset_mock()

        cache.set(PATHWAY_CACHE_KEY_TPL.format(id=expected_id),
                  expected_pathway, None)

        actual_pathway = get_pathways(self.site, pathway_id=expected_id)
        assert actual_pathway == expected_pathway
        assert not mock_warning.called
Exemplo n.º 14
0
    def test_get_many(self, mock_warning, mock_info):
        pathways = PathwayFactory.create_batch(3)

        # Cache details for 2 of 3 programs.
        partial_pathways = {
            PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways[:2]
        }
        cache.set_many(partial_pathways, None)

        # When called before pathways are cached, the function should return an
        # empty list and log a warning.
        self.assertEqual(get_pathways(self.site), [])
        mock_warning.assert_called_once_with('Failed to get credit pathway ids from the cache.')
        mock_warning.reset_mock()

        # Cache all 3 pathways
        cache.set(
            SITE_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site.domain),
            [pathway['id'] for pathway in pathways],
            None
        )

        actual_pathways = get_pathways(self.site)

        # The 2 cached pathways should be returned while info and warning
        # messages should be logged for the missing one.
        self.assertEqual(
            set(pathway['id'] for pathway in actual_pathways),
            set(pathway['id'] for pathway in partial_pathways.values())
        )
        mock_info.assert_called_with('Failed to get details for 1 pathways. Retrying.')
        mock_warning.assert_called_with(
            'Failed to get details for credit pathway {id} from the cache.'.format(id=pathways[2]['id'])
        )
        mock_warning.reset_mock()

        # We can't use a set comparison here because these values are dictionaries
        # and aren't hashable. We've already verified that all pathways came out
        # of the cache above, so all we need to do here is verify the accuracy of
        # the data itself.
        for pathway in actual_pathways:
            key = PATHWAY_CACHE_KEY_TPL.format(id=pathway['id'])
            self.assertEqual(pathway, partial_pathways[key])

        # Cache details for all 3 pathways.
        all_pathways = {
            PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways
        }
        cache.set_many(all_pathways, None)

        actual_pathways = get_pathways(self.site)

        # All 3 pathways should be returned.
        self.assertEqual(
            set(pathway['id'] for pathway in actual_pathways),
            set(pathway['id'] for pathway in all_pathways.values())
        )
        self.assertFalse(mock_warning.called)

        for pathway in actual_pathways:
            key = PATHWAY_CACHE_KEY_TPL.format(id=pathway['id'])
            self.assertEqual(pathway, all_pathways[key])