Switch to using Pathways instead of CreditPathways.
This commit is contained in:
@@ -15,7 +15,7 @@ class StubCatalogServiceHandler(StubHttpRequestHandler):
|
||||
r'/api/v1/programs/$': self.program_list,
|
||||
r'/api/v1/programs/([0-9a-f-]+)/$': self.program_detail,
|
||||
r'/api/v1/program_types/$': self.program_types,
|
||||
r'/api/v1/credit_pathways/$': self.credit_pathways
|
||||
r'/api/v1/pathways/$': self.pathways
|
||||
}
|
||||
|
||||
if self.match_pattern(pattern_handlers):
|
||||
@@ -48,9 +48,9 @@ class StubCatalogServiceHandler(StubHttpRequestHandler):
|
||||
program_types = self.server.config.get('catalog.programs_types', [])
|
||||
self.send_json_response(program_types)
|
||||
|
||||
def credit_pathways(self):
|
||||
credit_pathways = self.server.config.get('catalog.credit_pathways', [])
|
||||
self.send_json_response(credit_pathways)
|
||||
def pathways(self):
|
||||
pathways = self.server.config.get('catalog.pathways', [])
|
||||
self.send_json_response(pathways)
|
||||
|
||||
|
||||
class StubCatalogService(StubHttpService):
|
||||
|
||||
@@ -40,16 +40,16 @@ class CatalogFixture(object):
|
||||
data={key: json.dumps(uuids)},
|
||||
)
|
||||
|
||||
def install_credit_pathways(self, credit_pathways):
|
||||
def install_pathways(self, pathways):
|
||||
"""
|
||||
Stub the discovery service's credit pathways API endpoint
|
||||
|
||||
Arguments:
|
||||
credit_pathways (list): A list of credit pathways. List endpoint will be stubbed using data from this list.
|
||||
pathways (list): A list of credit pathways. List endpoint will be stubbed using data from this list.
|
||||
"""
|
||||
requests.put(
|
||||
'{}/set_config'.format(CATALOG_STUB_URL),
|
||||
data={'catalog.credit_pathways': json.dumps({'results': credit_pathways, 'next': None})}
|
||||
data={'catalog.pathways': json.dumps({'results': pathways, 'next': None})}
|
||||
)
|
||||
|
||||
def install_program_types(self, program_types):
|
||||
|
||||
@@ -11,7 +11,7 @@ from common.test.acceptance.tests.helpers import UniqueCourseTest
|
||||
from openedx.core.djangoapps.catalog.tests.factories import (
|
||||
CourseFactory,
|
||||
CourseRunFactory,
|
||||
CreditPathwayFactory,
|
||||
PathwayFactory,
|
||||
ProgramFactory,
|
||||
ProgramTypeFactory
|
||||
)
|
||||
@@ -25,13 +25,13 @@ class ProgramPageBase(ProgramsConfigMixin, CatalogIntegrationMixin, UniqueCourse
|
||||
self.set_programs_api_configuration(is_enabled=True)
|
||||
|
||||
self.programs = ProgramFactory.create_batch(3)
|
||||
self.credit_pathways = CreditPathwayFactory.create_batch(3)
|
||||
for pathway in self.credit_pathways:
|
||||
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.credit_pathways[0]['programs'].extend([self.programs[0], self.programs[1]])
|
||||
self.credit_pathways[1]['programs'].append(self.programs[0])
|
||||
self.pathways[0]['programs'].extend([self.programs[0], self.programs[1]])
|
||||
self.pathways[1]['programs'].append(self.programs[0])
|
||||
|
||||
self.username = None
|
||||
|
||||
@@ -53,7 +53,7 @@ class ProgramPageBase(ProgramsConfigMixin, CatalogIntegrationMixin, UniqueCourse
|
||||
program_type = ProgramTypeFactory()
|
||||
return ProgramFactory(courses=[course], type=program_type['name'])
|
||||
|
||||
def stub_catalog_api(self, programs, credit_pathways):
|
||||
def stub_catalog_api(self, programs, pathways):
|
||||
"""
|
||||
Stub the discovery service's program list and detail API endpoints, as well as
|
||||
the credit pathway list endpoint.
|
||||
@@ -64,7 +64,7 @@ class ProgramPageBase(ProgramsConfigMixin, CatalogIntegrationMixin, UniqueCourse
|
||||
program_types = [program['type'] for program in programs]
|
||||
CatalogFixture().install_program_types(program_types)
|
||||
|
||||
CatalogFixture().install_credit_pathways(credit_pathways)
|
||||
CatalogFixture().install_pathways(pathways)
|
||||
|
||||
def cache_programs(self):
|
||||
"""
|
||||
@@ -86,7 +86,7 @@ class ProgramListingPageTest(ProgramPageBase):
|
||||
def test_no_enrollments(self):
|
||||
"""Verify that no cards appear when the user has no enrollments."""
|
||||
self.auth(enroll=False)
|
||||
self.stub_catalog_api(self.programs, self.credit_pathways)
|
||||
self.stub_catalog_api(self.programs, self.pathways)
|
||||
self.cache_programs()
|
||||
|
||||
self.listing_page.visit()
|
||||
@@ -100,7 +100,7 @@ class ProgramListingPageTest(ProgramPageBase):
|
||||
but none are included in an active program.
|
||||
"""
|
||||
self.auth()
|
||||
self.stub_catalog_api(self.programs, self.credit_pathways)
|
||||
self.stub_catalog_api(self.programs, self.pathways)
|
||||
self.cache_programs()
|
||||
|
||||
self.listing_page.visit()
|
||||
@@ -122,7 +122,7 @@ class ProgramListingPageA11yTest(ProgramPageBase):
|
||||
def test_empty_a11y(self):
|
||||
"""Test a11y of the page's empty state."""
|
||||
self.auth(enroll=False)
|
||||
self.stub_catalog_api(programs=[self.program], credit_pathways=[])
|
||||
self.stub_catalog_api(programs=[self.program], pathways=[])
|
||||
self.cache_programs()
|
||||
|
||||
self.listing_page.visit()
|
||||
@@ -134,7 +134,7 @@ class ProgramListingPageA11yTest(ProgramPageBase):
|
||||
def test_cards_a11y(self):
|
||||
"""Test a11y when program cards are present."""
|
||||
self.auth()
|
||||
self.stub_catalog_api(programs=[self.program], credit_pathways=[])
|
||||
self.stub_catalog_api(programs=[self.program], pathways=[])
|
||||
self.cache_programs()
|
||||
|
||||
self.listing_page.visit()
|
||||
@@ -158,7 +158,7 @@ class ProgramDetailsPageA11yTest(ProgramPageBase):
|
||||
def test_a11y(self):
|
||||
"""Test the page's a11y compliance."""
|
||||
self.auth()
|
||||
self.stub_catalog_api(programs=[self.program], credit_pathways=[])
|
||||
self.stub_catalog_api(programs=[self.program], pathways=[])
|
||||
self.cache_programs()
|
||||
|
||||
self.details_page.visit()
|
||||
|
||||
@@ -12,7 +12,7 @@ from web_fragments.fragment import Fragment
|
||||
|
||||
from lms.djangoapps.commerce.utils import EcommerceService
|
||||
from lms.djangoapps.learner_dashboard.utils import FAKE_COURSE_KEY, strip_course_id
|
||||
from openedx.core.djangoapps.catalog.utils import get_credit_pathways
|
||||
from openedx.core.djangoapps.catalog.utils import get_pathways
|
||||
from openedx.core.djangoapps.credentials.utils import get_credentials_records_url
|
||||
from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
|
||||
from openedx.core.djangoapps.programs.models import ProgramsApiConfig
|
||||
@@ -107,12 +107,12 @@ class ProgramDetailsFragmentView(EdxFragmentView):
|
||||
if not certificate_data:
|
||||
program_record_url = None
|
||||
|
||||
credit_pathways = []
|
||||
pathways = []
|
||||
try:
|
||||
for pathway_id in program_data['pathway_ids']:
|
||||
pathway = get_credit_pathways(request.site, pathway_id)
|
||||
pathway = get_pathways(request.site, pathway_id)
|
||||
if pathway and pathway['email']:
|
||||
credit_pathways.append(pathway)
|
||||
pathways.append(pathway)
|
||||
# if pathway caching did not complete fully (no pathway_ids)
|
||||
except KeyError:
|
||||
pass
|
||||
@@ -133,7 +133,7 @@ class ProgramDetailsFragmentView(EdxFragmentView):
|
||||
'program_data': program_data,
|
||||
'course_data': course_data,
|
||||
'certificate_data': certificate_data,
|
||||
'credit_pathways': credit_pathways,
|
||||
'pathways': pathways,
|
||||
}
|
||||
|
||||
html = render_to_string('learner_dashboard/program_details_fragment.html', context)
|
||||
|
||||
@@ -15,7 +15,7 @@ from django.test import override_settings
|
||||
|
||||
from lms.envs.test import CREDENTIALS_PUBLIC_SERVICE_URL
|
||||
from openedx.core.djangoapps.catalog.tests.factories import (
|
||||
CreditPathwayFactory,
|
||||
PathwayFactory,
|
||||
CourseFactory,
|
||||
CourseRunFactory,
|
||||
ProgramFactory
|
||||
@@ -180,7 +180,7 @@ class TestProgramListing(ProgramsApiConfigMixin, SharedModuleStoreTestCase):
|
||||
|
||||
|
||||
@skip_unless_lms
|
||||
@mock.patch(PROGRAMS_MODULE + '.get_credit_pathways')
|
||||
@mock.patch(PROGRAMS_MODULE + '.get_pathways')
|
||||
@mock.patch(PROGRAMS_UTILS_MODULE + '.get_programs')
|
||||
class TestProgramDetails(ProgramsApiConfigMixin, CatalogIntegrationMixin, SharedModuleStoreTestCase):
|
||||
"""Unit tests for the program details page."""
|
||||
@@ -198,7 +198,7 @@ class TestProgramDetails(ProgramsApiConfigMixin, CatalogIntegrationMixin, Shared
|
||||
course = CourseFactory(course_runs=[course_run])
|
||||
|
||||
cls.program_data = ProgramFactory(uuid=cls.program_uuid, courses=[course])
|
||||
cls.pathway_data = CreditPathwayFactory()
|
||||
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']
|
||||
@@ -230,7 +230,7 @@ class TestProgramDetails(ProgramsApiConfigMixin, CatalogIntegrationMixin, Shared
|
||||
self.assertContains(response, 'creditPathways')
|
||||
self.assertContains(response, self.pathway_data['name'])
|
||||
|
||||
def test_login_required(self, mock_get_programs, mock_get_credit_pathways):
|
||||
def test_login_required(self, mock_get_programs, mock_get_pathways):
|
||||
"""
|
||||
Verify that login is required to access the page.
|
||||
"""
|
||||
@@ -240,7 +240,7 @@ class TestProgramDetails(ProgramsApiConfigMixin, CatalogIntegrationMixin, Shared
|
||||
UserFactory(username=catalog_integration.service_username)
|
||||
|
||||
mock_get_programs.return_value = self.program_data
|
||||
mock_get_credit_pathways.return_value = self.pathway_data
|
||||
mock_get_pathways.return_value = self.pathway_data
|
||||
|
||||
self.client.logout()
|
||||
|
||||
@@ -259,7 +259,7 @@ class TestProgramDetails(ProgramsApiConfigMixin, CatalogIntegrationMixin, Shared
|
||||
self.assert_program_data_present(response)
|
||||
self.assert_pathway_data_present(response)
|
||||
|
||||
def test_404_if_disabled(self, _mock_get_programs, _mock_get_credit_pathways):
|
||||
def test_404_if_disabled(self, _mock_get_programs, _mock_get_pathways):
|
||||
"""
|
||||
Verify that the page 404s if disabled.
|
||||
"""
|
||||
@@ -268,7 +268,7 @@ class TestProgramDetails(ProgramsApiConfigMixin, CatalogIntegrationMixin, Shared
|
||||
response = self.client.get(self.url)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
def test_404_if_no_data(self, mock_get_programs, _mock_get_credit_pathways):
|
||||
def test_404_if_no_data(self, mock_get_programs, _mock_get_pathways):
|
||||
"""Verify that the page 404s if no program data is found."""
|
||||
self.create_programs_config()
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ ProgramDetailsFactory({
|
||||
certificateData: ${certificate_data | n, dump_js_escaped_json},
|
||||
urls: ${urls | n, dump_js_escaped_json},
|
||||
userPreferences: ${user_preferences | n, dump_js_escaped_json},
|
||||
creditPathways: ${credit_pathways | n, dump_js_escaped_json},
|
||||
creditPathways: ${pathways | n, dump_js_escaped_json},
|
||||
});
|
||||
</%static:webpack>
|
||||
</%block>
|
||||
|
||||
@@ -5,7 +5,7 @@ PROGRAM_CACHE_KEY_TPL = 'program-{uuid}'
|
||||
SITE_PROGRAM_UUIDS_CACHE_KEY_TPL = 'program-uuids-{domain}'
|
||||
|
||||
# Template used to create cache keys for individual pathways
|
||||
CREDIT_PATHWAY_CACHE_KEY_TPL = 'credit-pathway-{id}'
|
||||
PATHWAY_CACHE_KEY_TPL = 'pathway-{id}'
|
||||
|
||||
# Cache key used to locate an item containing a list of all credit pathway ids for a site.
|
||||
SITE_CREDIT_PATHWAY_IDS_CACHE_KEY_TPL = 'credit-pathway-ids-{domain}'
|
||||
SITE_PATHWAY_IDS_CACHE_KEY_TPL = 'pathway-ids-{domain}'
|
||||
|
||||
@@ -7,9 +7,9 @@ from django.core.cache import cache
|
||||
from django.core.management import BaseCommand
|
||||
|
||||
from openedx.core.djangoapps.catalog.cache import (
|
||||
CREDIT_PATHWAY_CACHE_KEY_TPL,
|
||||
PATHWAY_CACHE_KEY_TPL,
|
||||
PROGRAM_CACHE_KEY_TPL,
|
||||
SITE_CREDIT_PATHWAY_IDS_CACHE_KEY_TPL,
|
||||
SITE_PATHWAY_IDS_CACHE_KEY_TPL,
|
||||
SITE_PROGRAM_UUIDS_CACHE_KEY_TPL
|
||||
)
|
||||
from openedx.core.djangoapps.catalog.models import CatalogIntegration
|
||||
@@ -51,7 +51,7 @@ class Command(BaseCommand):
|
||||
if site_config is None or not site_config.get_value('COURSE_CATALOG_API_URL'):
|
||||
logger.info('Skipping site {domain}. No configuration.'.format(domain=site.domain))
|
||||
cache.set(SITE_PROGRAM_UUIDS_CACHE_KEY_TPL.format(domain=site.domain), [], None)
|
||||
cache.set(SITE_CREDIT_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=site.domain), [], None)
|
||||
cache.set(SITE_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=site.domain), [], None)
|
||||
continue
|
||||
|
||||
client = create_catalog_api_client(user, site=site)
|
||||
@@ -78,7 +78,7 @@ class Command(BaseCommand):
|
||||
total=len(pathway_ids),
|
||||
site_name=site.domain,
|
||||
))
|
||||
cache.set(SITE_CREDIT_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=site.domain), pathway_ids, None)
|
||||
cache.set(SITE_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=site.domain), pathway_ids, None)
|
||||
|
||||
successful_programs = len(programs)
|
||||
logger.info('Caching details for {successful_programs} programs.'.format(
|
||||
@@ -140,11 +140,11 @@ class Command(BaseCommand):
|
||||
"""
|
||||
pathways = []
|
||||
failure = False
|
||||
logger.info('Requesting credit pathways for {domain}.'.format(domain=site.domain))
|
||||
logger.info('Requesting pathways for {domain}.'.format(domain=site.domain))
|
||||
try:
|
||||
next_page = 1
|
||||
while next_page:
|
||||
new_pathways = client.credit_pathways.get(exclude_utm=1, page=next_page)
|
||||
new_pathways = client.pathways.get(exclude_utm=1, page=next_page)
|
||||
pathways.extend(new_pathways['results'])
|
||||
next_page = next_page + 1 if new_pathways['next'] else None
|
||||
|
||||
@@ -152,7 +152,7 @@ class Command(BaseCommand):
|
||||
logger.error('Failed to retrieve credit pathways for site: {domain}.'.format(domain=site.domain))
|
||||
failure = True
|
||||
|
||||
logger.info('Received {total} credit pathways for site {domain}'.format(
|
||||
logger.info('Received {total} pathways for site {domain}'.format(
|
||||
total=len(pathways),
|
||||
domain=site.domain
|
||||
))
|
||||
@@ -170,7 +170,7 @@ class Command(BaseCommand):
|
||||
for pathway in pathways:
|
||||
try:
|
||||
pathway_id = pathway['id']
|
||||
pathway_cache_key = CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathway_id)
|
||||
pathway_cache_key = PATHWAY_CACHE_KEY_TPL.format(id=pathway_id)
|
||||
processed_pathways[pathway_cache_key] = pathway
|
||||
uuids = []
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@ from django.core.cache import cache
|
||||
from django.core.management import call_command
|
||||
|
||||
from openedx.core.djangoapps.catalog.cache import (
|
||||
CREDIT_PATHWAY_CACHE_KEY_TPL,
|
||||
PATHWAY_CACHE_KEY_TPL,
|
||||
PROGRAM_CACHE_KEY_TPL,
|
||||
SITE_CREDIT_PATHWAY_IDS_CACHE_KEY_TPL,
|
||||
SITE_PATHWAY_IDS_CACHE_KEY_TPL,
|
||||
SITE_PROGRAM_UUIDS_CACHE_KEY_TPL
|
||||
)
|
||||
from openedx.core.djangoapps.catalog.tests.factories import CreditPathwayFactory, ProgramFactory
|
||||
from openedx.core.djangoapps.catalog.tests.factories import PathwayFactory, ProgramFactory
|
||||
from openedx.core.djangoapps.catalog.tests.mixins import CatalogIntegrationMixin
|
||||
from openedx.core.djangoapps.site_configuration.tests.mixins import SiteMixin
|
||||
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_unless_lms
|
||||
@@ -38,10 +38,10 @@ class TestCachePrograms(CatalogIntegrationMixin, CacheIsolationTestCase, SiteMix
|
||||
|
||||
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('/') + '/credit_pathways/'
|
||||
self.pathway_url = self.catalog_integration.get_internal_api_url().rstrip('/') + '/pathways/'
|
||||
|
||||
self.programs = ProgramFactory.create_batch(3)
|
||||
self.pathways = CreditPathwayFactory.create_batch(3)
|
||||
self.pathways = PathwayFactory.create_batch(3)
|
||||
|
||||
for pathway in self.pathways:
|
||||
self.programs += pathway['programs']
|
||||
@@ -179,7 +179,7 @@ class TestCachePrograms(CatalogIntegrationMixin, CacheIsolationTestCase, SiteMix
|
||||
}
|
||||
|
||||
pathways = {
|
||||
CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in self.pathways
|
||||
PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in self.pathways
|
||||
}
|
||||
|
||||
self.mock_list()
|
||||
@@ -191,7 +191,7 @@ class TestCachePrograms(CatalogIntegrationMixin, CacheIsolationTestCase, SiteMix
|
||||
|
||||
call_command('cache_programs')
|
||||
|
||||
cached_pathway_keys = cache.get(SITE_CREDIT_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site_domain))
|
||||
cached_pathway_keys = cache.get(SITE_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site_domain))
|
||||
pathway_keys = pathways.keys()
|
||||
self.assertEqual(
|
||||
set(cached_pathway_keys),
|
||||
@@ -220,7 +220,7 @@ class TestCachePrograms(CatalogIntegrationMixin, CacheIsolationTestCase, SiteMix
|
||||
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 = CreditPathwayFactory.create_batch(40)
|
||||
new_pathways = PathwayFactory.create_batch(40)
|
||||
for new_pathway in new_pathways:
|
||||
new_pathway['programs'] = []
|
||||
pathways = self.pathways + new_pathways
|
||||
@@ -242,11 +242,11 @@ class TestCachePrograms(CatalogIntegrationMixin, CacheIsolationTestCase, SiteMix
|
||||
call_command('cache_programs')
|
||||
|
||||
pathways_dict = {
|
||||
CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways
|
||||
PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways
|
||||
}
|
||||
pathway_keys = pathways_dict.keys()
|
||||
|
||||
cached_pathway_keys = cache.get(SITE_CREDIT_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site_domain))
|
||||
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)
|
||||
@@ -314,7 +314,7 @@ class TestCachePrograms(CatalogIntegrationMixin, CacheIsolationTestCase, SiteMix
|
||||
call_command('cache_programs')
|
||||
self.assertEqual(context.exception.code, 1)
|
||||
|
||||
cached_pathways = cache.get(SITE_CREDIT_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site_domain))
|
||||
cached_pathways = cache.get(SITE_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site_domain))
|
||||
self.assertEqual(cached_pathways, [])
|
||||
|
||||
def test_handle_missing_programs(self):
|
||||
|
||||
@@ -213,7 +213,7 @@ class ProgramTypeFactory(DictFactoryBase):
|
||||
logo_image = factory.LazyFunction(generate_sized_stdimage)
|
||||
|
||||
|
||||
class CreditPathwayFactory(DictFactoryBase):
|
||||
class PathwayFactory(DictFactoryBase):
|
||||
id = factory.Sequence(lambda x: x)
|
||||
description = factory.Faker('sentence')
|
||||
destination_url = factory.Faker('url')
|
||||
|
||||
@@ -17,16 +17,16 @@ from course_modes.tests.factories import CourseModeFactory
|
||||
from entitlements.tests.factories import CourseEntitlementFactory
|
||||
from openedx.core.constants import COURSE_UNPUBLISHED
|
||||
from openedx.core.djangoapps.catalog.cache import (
|
||||
CREDIT_PATHWAY_CACHE_KEY_TPL,
|
||||
PATHWAY_CACHE_KEY_TPL,
|
||||
PROGRAM_CACHE_KEY_TPL,
|
||||
SITE_CREDIT_PATHWAY_IDS_CACHE_KEY_TPL,
|
||||
SITE_PATHWAY_IDS_CACHE_KEY_TPL,
|
||||
SITE_PROGRAM_UUIDS_CACHE_KEY_TPL
|
||||
)
|
||||
from openedx.core.djangoapps.catalog.models import CatalogIntegration
|
||||
from openedx.core.djangoapps.catalog.tests.factories import (
|
||||
CourseFactory,
|
||||
CourseRunFactory,
|
||||
CreditPathwayFactory,
|
||||
PathwayFactory,
|
||||
ProgramFactory,
|
||||
ProgramTypeFactory
|
||||
)
|
||||
@@ -35,7 +35,7 @@ from openedx.core.djangoapps.catalog.utils import (
|
||||
get_course_runs,
|
||||
get_course_runs_for_course,
|
||||
get_course_run_details,
|
||||
get_credit_pathways,
|
||||
get_pathways,
|
||||
get_currency_data,
|
||||
get_localized_price_text,
|
||||
get_program_types,
|
||||
@@ -187,36 +187,36 @@ class TestGetPrograms(CacheIsolationTestCase):
|
||||
@skip_unless_lms
|
||||
@mock.patch(UTILS_MODULE + '.logger.info')
|
||||
@mock.patch(UTILS_MODULE + '.logger.warning')
|
||||
class TestGetCreditPathways(CacheIsolationTestCase):
|
||||
class TestGetPathways(CacheIsolationTestCase):
|
||||
ENABLED_CACHES = ['default']
|
||||
|
||||
def setUp(self):
|
||||
super(TestGetCreditPathways, self).setUp()
|
||||
super(TestGetPathways, self).setUp()
|
||||
self.site = SiteFactory()
|
||||
|
||||
def test_get_many(self, mock_warning, mock_info):
|
||||
pathways = CreditPathwayFactory.create_batch(3)
|
||||
pathways = PathwayFactory.create_batch(3)
|
||||
|
||||
# Cache details for 2 of 3 programs.
|
||||
partial_pathways = {
|
||||
CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways[:2]
|
||||
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_credit_pathways(self.site), [])
|
||||
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_CREDIT_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site.domain),
|
||||
SITE_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=self.site.domain),
|
||||
[pathway['id'] for pathway in pathways],
|
||||
None
|
||||
)
|
||||
|
||||
actual_pathways = get_credit_pathways(self.site)
|
||||
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.
|
||||
@@ -235,16 +235,16 @@ class TestGetCreditPathways(CacheIsolationTestCase):
|
||||
# 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 = CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathway['id'])
|
||||
key = PATHWAY_CACHE_KEY_TPL.format(id=pathway['id'])
|
||||
self.assertEqual(pathway, partial_pathways[key])
|
||||
|
||||
# Cache details for all 3 pathways.
|
||||
all_pathways = {
|
||||
CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways
|
||||
PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways
|
||||
}
|
||||
cache.set_many(all_pathways, None)
|
||||
|
||||
actual_pathways = get_credit_pathways(self.site)
|
||||
actual_pathways = get_pathways(self.site)
|
||||
|
||||
# All 3 pathways should be returned.
|
||||
self.assertEqual(
|
||||
@@ -254,31 +254,31 @@ class TestGetCreditPathways(CacheIsolationTestCase):
|
||||
self.assertFalse(mock_warning.called)
|
||||
|
||||
for pathway in actual_pathways:
|
||||
key = CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathway['id'])
|
||||
key = PATHWAY_CACHE_KEY_TPL.format(id=pathway['id'])
|
||||
self.assertEqual(pathway, all_pathways[key])
|
||||
|
||||
@mock.patch(UTILS_MODULE + '.cache')
|
||||
def test_get_many_with_missing(self, mock_cache, mock_warning, mock_info):
|
||||
pathways = CreditPathwayFactory.create_batch(3)
|
||||
pathways = PathwayFactory.create_batch(3)
|
||||
|
||||
all_pathways = {
|
||||
CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways
|
||||
PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways
|
||||
}
|
||||
|
||||
partial_pathways = {
|
||||
CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways[:2]
|
||||
PATHWAY_CACHE_KEY_TPL.format(id=pathway['id']): pathway for pathway in pathways[:2]
|
||||
}
|
||||
|
||||
def fake_get_many(keys):
|
||||
if len(keys) == 1:
|
||||
return {CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathways[-1]['id']): pathways[-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_credit_pathways(self.site)
|
||||
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
|
||||
@@ -291,26 +291,26 @@ class TestGetCreditPathways(CacheIsolationTestCase):
|
||||
mock_info.assert_called_with('Failed to get details for 1 pathways. Retrying.')
|
||||
|
||||
for pathway in actual_pathways:
|
||||
key = CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathway['id'])
|
||||
key = PATHWAY_CACHE_KEY_TPL.format(id=pathway['id'])
|
||||
self.assertEqual(pathway, all_pathways[key])
|
||||
|
||||
def test_get_one(self, mock_warning, _mock_info):
|
||||
expected_pathway = CreditPathwayFactory()
|
||||
expected_pathway = PathwayFactory()
|
||||
expected_id = expected_pathway['id']
|
||||
|
||||
self.assertEqual(get_credit_pathways(self.site, pathway_id=expected_id), None)
|
||||
self.assertEqual(get_pathways(self.site, pathway_id=expected_id), None)
|
||||
mock_warning.assert_called_once_with(
|
||||
'Failed to get details for credit pathway {id} from the cache.'.format(id=expected_id)
|
||||
)
|
||||
mock_warning.reset_mock()
|
||||
|
||||
cache.set(
|
||||
CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=expected_id),
|
||||
PATHWAY_CACHE_KEY_TPL.format(id=expected_id),
|
||||
expected_pathway,
|
||||
None
|
||||
)
|
||||
|
||||
actual_pathway = get_credit_pathways(self.site, pathway_id=expected_id)
|
||||
actual_pathway = get_pathways(self.site, pathway_id=expected_id)
|
||||
self.assertEqual(actual_pathway, expected_pathway)
|
||||
self.assertFalse(mock_warning.called)
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ from pytz import UTC
|
||||
|
||||
from entitlements.utils import is_course_run_entitlement_fulfillable
|
||||
from openedx.core.constants import COURSE_PUBLISHED
|
||||
from openedx.core.djangoapps.catalog.cache import (CREDIT_PATHWAY_CACHE_KEY_TPL, PROGRAM_CACHE_KEY_TPL,
|
||||
SITE_CREDIT_PATHWAY_IDS_CACHE_KEY_TPL,
|
||||
from openedx.core.djangoapps.catalog.cache import (PATHWAY_CACHE_KEY_TPL, PROGRAM_CACHE_KEY_TPL,
|
||||
SITE_PATHWAY_IDS_CACHE_KEY_TPL,
|
||||
SITE_PROGRAM_UUIDS_CACHE_KEY_TPL)
|
||||
from openedx.core.djangoapps.catalog.models import CatalogIntegration
|
||||
from openedx.core.lib.edx_api_utils import get_edx_api_data
|
||||
@@ -125,7 +125,7 @@ def get_program_types(name=None):
|
||||
return []
|
||||
|
||||
|
||||
def get_credit_pathways(site, pathway_id=None):
|
||||
def get_pathways(site, pathway_id=None):
|
||||
"""
|
||||
Read pathways from the cache.
|
||||
The cache is populated by a management command, cache_programs.
|
||||
@@ -143,16 +143,16 @@ def get_credit_pathways(site, pathway_id=None):
|
||||
missing_details_msg_tpl = 'Failed to get details for credit pathway {id} from the cache.'
|
||||
|
||||
if pathway_id:
|
||||
pathway = cache.get(CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathway_id))
|
||||
pathway = cache.get(PATHWAY_CACHE_KEY_TPL.format(id=pathway_id))
|
||||
if not pathway:
|
||||
logger.warning(missing_details_msg_tpl.format(id=pathway_id))
|
||||
|
||||
return pathway
|
||||
pathway_ids = cache.get(SITE_CREDIT_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=site.domain), [])
|
||||
pathway_ids = cache.get(SITE_PATHWAY_IDS_CACHE_KEY_TPL.format(domain=site.domain), [])
|
||||
if not pathway_ids:
|
||||
logger.warning('Failed to get credit pathway ids from the cache.')
|
||||
|
||||
pathways = cache.get_many([CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathway_id) for pathway_id in pathway_ids])
|
||||
pathways = cache.get_many([PATHWAY_CACHE_KEY_TPL.format(id=pathway_id) for pathway_id in pathway_ids])
|
||||
pathways = pathways.values()
|
||||
|
||||
# The get_many above sometimes fails to bring back details cached on one or
|
||||
@@ -170,7 +170,7 @@ def get_credit_pathways(site, pathway_id=None):
|
||||
)
|
||||
|
||||
retried_pathways = cache.get_many(
|
||||
[CREDIT_PATHWAY_CACHE_KEY_TPL.format(id=pathway_id) for pathway_id in missing_ids]
|
||||
[PATHWAY_CACHE_KEY_TPL.format(id=pathway_id) for pathway_id in missing_ids]
|
||||
)
|
||||
pathways += retried_pathways.values()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user