From 298c3498ae5ccb24fc9d4538ef0c3ef1214b6cf0 Mon Sep 17 00:00:00 2001 From: Kyle McCormick Date: Wed, 18 Sep 2019 12:12:41 -0400 Subject: [PATCH] Add course_exists utility to CourseOverview class --- .../content/course_overviews/models.py | 19 ++++++++++++ .../tests/test_course_overviews.py | 31 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/openedx/core/djangoapps/content/course_overviews/models.py b/openedx/core/djangoapps/content/course_overviews/models.py index d8b05c8b7c..e474107948 100644 --- a/openedx/core/djangoapps/content/course_overviews/models.py +++ b/openedx/core/djangoapps/content/course_overviews/models.py @@ -271,6 +271,25 @@ class CourseOverview(TimeStampedModel): else: raise cls.DoesNotExist() + @classmethod + def course_exists(cls, course_id): + """ + Check whether a course run exists (in CourseOverviews _or_ modulestore). + + Checks the CourseOverview table first. + If it is not there, check the modulestore. + Equivalent to, but more efficient than: + bool(CourseOverview.get_from_id(course_id)) + + Arguments: + course_id (CourseKey) + + Returns: bool + """ + if cls.objects.filter(id=course_id).exists(): + return True + return modulestore().has_course(course_id) + @classmethod def get_from_id(cls, course_id): """ diff --git a/openedx/core/djangoapps/content/course_overviews/tests/test_course_overviews.py b/openedx/core/djangoapps/content/course_overviews/tests/test_course_overviews.py index 08dab713d4..8b903fd64d 100644 --- a/openedx/core/djangoapps/content/course_overviews/tests/test_course_overviews.py +++ b/openedx/core/djangoapps/content/course_overviews/tests/test_course_overviews.py @@ -322,6 +322,37 @@ class CourseOverviewTestCase(CatalogIntegrationMixin, ModuleStoreTestCase, Cache with self.assertRaises(CourseOverview.DoesNotExist): CourseOverview.get_from_id(store.make_course_key('Non', 'Existent', 'Course')) + @ddt.data(ModuleStoreEnum.Type.split, ModuleStoreEnum.Type.mongo) + def test_course_with_course_overview_exists(self, modulestore_type): + """ + Tests that calling course_exists on an existent course + that is cached in CourseOverview table returns True. + """ + course = CourseFactory.create(default_store=modulestore_type) + CourseOverview.get_from_id(course.id) # Ensure course in cached in CourseOverviews + self.assertTrue(CourseOverview.objects.filter(id=course.id).exists()) + self.assertTrue(CourseOverview.course_exists(course.id)) + + @ddt.data(ModuleStoreEnum.Type.split, ModuleStoreEnum.Type.mongo) + def test_course_without_overview_exists(self, modulestore_type): + """ + Tests that calling course_exists on an existent course + that is NOT cached in CourseOverview table returns True. + """ + course = CourseFactory.create(default_store=modulestore_type) + CourseOverview.objects.filter(id=course.id).delete() + self.assertTrue(CourseOverview.course_exists(course.id)) + self.assertFalse(CourseOverview.objects.filter(id=course.id).exists()) + + @ddt.data(ModuleStoreEnum.Type.split, ModuleStoreEnum.Type.mongo) + def test_nonexistent_course_does_not_exists(self, modulestore_type): + """ + Tests that calling course_exists on an non-existent course returns False. + """ + store = modulestore()._get_modulestore_by_type(modulestore_type) # pylint: disable=protected-access + course_id = store.make_course_key('Non', 'Existent', 'Course') + self.assertFalse(CourseOverview.course_exists(course_id)) + def test_get_errored_course(self): """ Test that getting an ErrorDescriptor back from the module store causes