From 8039e40f47bdce418480075fee906e8fec896fa9 Mon Sep 17 00:00:00 2001 From: Kyle McCormick Date: Thu, 20 Jan 2022 18:46:59 -0500 Subject: [PATCH] refactor: move coursegraph to cms This code was originally located at: ./openedx/core/djangoapps/coursegraph However, code makes more sense within the ./cms tree, because: * it is responsible for publishing course content to an external system, with is within the responsibilities of CMS, and * is uses modulestore, which is discouraged for use in LMS (see 0011-limit-modulestore-use-in-lms.rst). So, we move the code to: ./cms/djangoapps/coursegraph and uninstall coursegraph from LMS. We do not expect this refactor to have any breaking downstream effects. --- .github/workflows/unit-test-shards.json | 3 +- .../djangoapps/coursegraph/README.rst | 0 .../djangoapps/coursegraph/__init__.py | 0 .../djangoapps/coursegraph/apps.py | 4 +- .../coursegraph/management/__init__.py | 0 .../management/commands/__init__.py | 0 .../management/commands/dump_to_neo4j.py | 2 +- .../management/commands/tests/__init__.py | 0 .../commands/tests/test_dump_to_neo4j.py | 44 +++++++++---------- .../management/commands/tests/utils.py | 0 .../djangoapps/coursegraph/tasks.py | 0 cms/envs/common.py | 2 +- cms/envs/production.py | 2 +- lms/envs/common.py | 4 -- 14 files changed, 28 insertions(+), 33 deletions(-) rename {openedx/core => cms}/djangoapps/coursegraph/README.rst (100%) rename {openedx/core => cms}/djangoapps/coursegraph/__init__.py (100%) rename {openedx/core => cms}/djangoapps/coursegraph/apps.py (65%) rename {openedx/core => cms}/djangoapps/coursegraph/management/__init__.py (100%) rename {openedx/core => cms}/djangoapps/coursegraph/management/commands/__init__.py (100%) rename {openedx/core => cms}/djangoapps/coursegraph/management/commands/dump_to_neo4j.py (97%) rename {openedx/core => cms}/djangoapps/coursegraph/management/commands/tests/__init__.py (100%) rename {openedx/core => cms}/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py (91%) rename {openedx/core => cms}/djangoapps/coursegraph/management/commands/tests/utils.py (100%) rename {openedx/core => cms}/djangoapps/coursegraph/tasks.py (100%) diff --git a/.github/workflows/unit-test-shards.json b/.github/workflows/unit-test-shards.json index f7cd11bf2c..838d0fe261 100644 --- a/.github/workflows/unit-test-shards.json +++ b/.github/workflows/unit-test-shards.json @@ -99,7 +99,6 @@ "openedx/core/djangoapps/course_apps/", "openedx/core/djangoapps/course_date_signals/", "openedx/core/djangoapps/course_groups/", - "openedx/core/djangoapps/coursegraph/", "openedx/core/djangoapps/courseware_api/", "openedx/core/djangoapps/crawlers/", "openedx/core/djangoapps/credentials/", @@ -181,7 +180,6 @@ "openedx/core/djangoapps/course_apps/", "openedx/core/djangoapps/course_date_signals/", "openedx/core/djangoapps/course_groups/", - "openedx/core/djangoapps/coursegraph/", "openedx/core/djangoapps/courseware_api/", "openedx/core/djangoapps/crawlers/", "openedx/core/djangoapps/credentials/", @@ -240,6 +238,7 @@ "paths": [ "cms/djangoapps/api/", "cms/djangoapps/cms_user_tasks/", + "cms/djangoapps/coursegraph/", "cms/djangoapps/course_creators/", "cms/djangoapps/export_course_metadata/", "cms/djangoapps/maintenance/", diff --git a/openedx/core/djangoapps/coursegraph/README.rst b/cms/djangoapps/coursegraph/README.rst similarity index 100% rename from openedx/core/djangoapps/coursegraph/README.rst rename to cms/djangoapps/coursegraph/README.rst diff --git a/openedx/core/djangoapps/coursegraph/__init__.py b/cms/djangoapps/coursegraph/__init__.py similarity index 100% rename from openedx/core/djangoapps/coursegraph/__init__.py rename to cms/djangoapps/coursegraph/__init__.py diff --git a/openedx/core/djangoapps/coursegraph/apps.py b/cms/djangoapps/coursegraph/apps.py similarity index 65% rename from openedx/core/djangoapps/coursegraph/apps.py rename to cms/djangoapps/coursegraph/apps.py index ecedf33d19..95d7873fce 100644 --- a/openedx/core/djangoapps/coursegraph/apps.py +++ b/cms/djangoapps/coursegraph/apps.py @@ -12,6 +12,6 @@ class CoursegraphConfig(AppConfig): """ AppConfig for courseware app """ - name = 'openedx.core.djangoapps.coursegraph' + name = 'cms.djangoapps.coursegraph' - from openedx.core.djangoapps.coursegraph import tasks + from cms.djangoapps.coursegraph import tasks diff --git a/openedx/core/djangoapps/coursegraph/management/__init__.py b/cms/djangoapps/coursegraph/management/__init__.py similarity index 100% rename from openedx/core/djangoapps/coursegraph/management/__init__.py rename to cms/djangoapps/coursegraph/management/__init__.py diff --git a/openedx/core/djangoapps/coursegraph/management/commands/__init__.py b/cms/djangoapps/coursegraph/management/commands/__init__.py similarity index 100% rename from openedx/core/djangoapps/coursegraph/management/commands/__init__.py rename to cms/djangoapps/coursegraph/management/commands/__init__.py diff --git a/openedx/core/djangoapps/coursegraph/management/commands/dump_to_neo4j.py b/cms/djangoapps/coursegraph/management/commands/dump_to_neo4j.py similarity index 97% rename from openedx/core/djangoapps/coursegraph/management/commands/dump_to_neo4j.py rename to cms/djangoapps/coursegraph/management/commands/dump_to_neo4j.py index 226b3c174a..5fcaefafcb 100644 --- a/openedx/core/djangoapps/coursegraph/management/commands/dump_to_neo4j.py +++ b/cms/djangoapps/coursegraph/management/commands/dump_to_neo4j.py @@ -9,7 +9,7 @@ from textwrap import dedent from django.core.management.base import BaseCommand -from openedx.core.djangoapps.coursegraph.tasks import ModuleStoreSerializer +from cms.djangoapps.coursegraph.tasks import ModuleStoreSerializer log = logging.getLogger(__name__) diff --git a/openedx/core/djangoapps/coursegraph/management/commands/tests/__init__.py b/cms/djangoapps/coursegraph/management/commands/tests/__init__.py similarity index 100% rename from openedx/core/djangoapps/coursegraph/management/commands/tests/__init__.py rename to cms/djangoapps/coursegraph/management/commands/tests/__init__.py diff --git a/openedx/core/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py b/cms/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py similarity index 91% rename from openedx/core/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py rename to cms/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py index 0d03f56d5f..37d2dfaf66 100644 --- a/openedx/core/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py +++ b/cms/djangoapps/coursegraph/management/commands/tests/test_dump_to_neo4j.py @@ -13,10 +13,10 @@ from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory import openedx.core.djangoapps.content.block_structure.config as block_structure_config -from openedx.core.djangoapps.content.block_structure.signals import update_block_structure_on_course_publish -from openedx.core.djangoapps.coursegraph.management.commands.dump_to_neo4j import ModuleStoreSerializer -from openedx.core.djangoapps.coursegraph.management.commands.tests.utils import MockGraph, MockNodeMatcher -from openedx.core.djangoapps.coursegraph.tasks import ( +from cms.djangoapps.content.block_structure.signals import update_block_structure_on_course_publish +from cms.djangoapps.coursegraph.management.commands.dump_to_neo4j import ModuleStoreSerializer +from cms.djangoapps.coursegraph.management.commands.tests.utils import MockGraph, MockNodeMatcher +from cms.djangoapps.coursegraph.tasks import ( coerce_types, serialize_course, serialize_item, @@ -115,8 +115,8 @@ class TestDumpToNeo4jCommand(TestDumpToNeo4jCommandBase): Tests for the dump to neo4j management command """ - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.NodeMatcher') - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.Graph') + @mock.patch('cms.djangoapps.coursegraph.tasks.NodeMatcher') + @mock.patch('cms.djangoapps.coursegraph.tasks.Graph') @ddt.data(1, 2) def test_dump_specific_courses(self, number_of_courses, mock_graph_class, mock_matcher_class): """ @@ -140,8 +140,8 @@ class TestDumpToNeo4jCommand(TestDumpToNeo4jCommandBase): number_rollbacks=0 ) - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.NodeMatcher') - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.Graph') + @mock.patch('cms.djangoapps.coursegraph.tasks.NodeMatcher') + @mock.patch('cms.djangoapps.coursegraph.tasks.Graph') def test_dump_skip_course(self, mock_graph_class, mock_matcher_class): """ Test that you can skip courses. @@ -166,8 +166,8 @@ class TestDumpToNeo4jCommand(TestDumpToNeo4jCommandBase): number_rollbacks=0, ) - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.NodeMatcher') - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.Graph') + @mock.patch('cms.djangoapps.coursegraph.tasks.NodeMatcher') + @mock.patch('cms.djangoapps.coursegraph.tasks.Graph') def test_dump_skip_beats_specifying(self, mock_graph_class, mock_matcher_class): """ Test that if you skip and specify the same course, you'll skip it. @@ -193,8 +193,8 @@ class TestDumpToNeo4jCommand(TestDumpToNeo4jCommandBase): number_rollbacks=0, ) - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.NodeMatcher') - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.Graph') + @mock.patch('cms.djangoapps.coursegraph.tasks.NodeMatcher') + @mock.patch('cms.djangoapps.coursegraph.tasks.Graph') def test_dump_all_courses(self, mock_graph_class, mock_matcher_class): """ Test if you don't specify which courses to dump, then you'll dump @@ -395,8 +395,8 @@ class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase): coerced_value = coerce_types(original_value) assert coerced_value == coerced_expected - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.NodeMatcher') - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.authenticate_and_create_graph') + @mock.patch('cms.djangoapps.coursegraph.tasks.NodeMatcher') + @mock.patch('cms.djangoapps.coursegraph.tasks.authenticate_and_create_graph') def test_dump_to_neo4j(self, mock_graph_constructor, mock_matcher_class): """ Tests the dump_to_neo4j method works against a mock @@ -423,8 +423,8 @@ class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase): assert len(mock_graph.nodes) == 11 self.assertCountEqual(submitted, self.course_strings) - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.NodeMatcher') - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.authenticate_and_create_graph') + @mock.patch('cms.djangoapps.coursegraph.tasks.NodeMatcher') + @mock.patch('cms.djangoapps.coursegraph.tasks.authenticate_and_create_graph') def test_dump_to_neo4j_rollback(self, mock_graph_constructor, mock_matcher_class): """ Tests that the the dump_to_neo4j method handles the case where there's @@ -447,8 +447,8 @@ class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase): self.assertCountEqual(submitted, self.course_strings) - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.NodeMatcher') - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.authenticate_and_create_graph') + @mock.patch('cms.djangoapps.coursegraph.tasks.NodeMatcher') + @mock.patch('cms.djangoapps.coursegraph.tasks.authenticate_and_create_graph') @ddt.data((True, 2), (False, 0)) @ddt.unpack def test_dump_to_neo4j_cache( @@ -480,8 +480,8 @@ class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase): ) assert len(submitted) == expected_number_courses - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.NodeMatcher') - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.authenticate_and_create_graph') + @mock.patch('cms.djangoapps.coursegraph.tasks.NodeMatcher') + @mock.patch('cms.djangoapps.coursegraph.tasks.authenticate_and_create_graph') def test_dump_to_neo4j_published(self, mock_graph_constructor, mock_matcher_class): """ Tests that we only dump those courses that have been published after @@ -506,8 +506,8 @@ class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase): assert len(submitted) == 1 assert submitted[0] == str(self.course.id) - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.get_course_last_published') - @mock.patch('openedx.core.djangoapps.coursegraph.tasks.get_command_last_run') + @mock.patch('cms.djangoapps.coursegraph.tasks.get_course_last_published') + @mock.patch('cms.djangoapps.coursegraph.tasks.get_command_last_run') @ddt.data( ( str(datetime(2016, 3, 30)), str(datetime(2016, 3, 31)), diff --git a/openedx/core/djangoapps/coursegraph/management/commands/tests/utils.py b/cms/djangoapps/coursegraph/management/commands/tests/utils.py similarity index 100% rename from openedx/core/djangoapps/coursegraph/management/commands/tests/utils.py rename to cms/djangoapps/coursegraph/management/commands/tests/utils.py diff --git a/openedx/core/djangoapps/coursegraph/tasks.py b/cms/djangoapps/coursegraph/tasks.py similarity index 100% rename from openedx/core/djangoapps/coursegraph/tasks.py rename to cms/djangoapps/coursegraph/tasks.py diff --git a/cms/envs/common.py b/cms/envs/common.py index 2cad881cec..31e73c2559 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -1611,7 +1611,7 @@ INSTALLED_APPS = [ 'openedx.core.djangoapps.self_paced', # Coursegraph - 'openedx.core.djangoapps.coursegraph.apps.CoursegraphConfig', + 'cms.djangoapps.coursegraph.apps.CoursegraphConfig', # Credit courses 'openedx.core.djangoapps.credit.apps.CreditConfig', diff --git a/cms/envs/production.py b/cms/envs/production.py index 8b29e3d3f3..82244acbde 100644 --- a/cms/envs/production.py +++ b/cms/envs/production.py @@ -603,7 +603,7 @@ EXPLICIT_QUEUES = { 'queue': POLICY_CHANGE_GRADES_ROUTING_KEY}, 'cms.djangoapps.contentstore.tasks.update_search_index': { 'queue': UPDATE_SEARCH_INDEX_JOB_QUEUE}, - 'openedx.core.djangoapps.coursegraph.tasks.dump_course_to_neo4j': { + 'cms.djangoapps.coursegraph.tasks.dump_course_to_neo4j': { 'queue': COURSEGRAPH_JOB_QUEUE}, } diff --git a/lms/envs/common.py b/lms/envs/common.py index 83709b11db..bf81a9769e 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -3083,10 +3083,6 @@ INSTALLED_APPS = [ 'openedx.core.djangoapps.content.block_structure.apps.BlockStructureConfig', 'lms.djangoapps.course_blocks', - - # Coursegraph - 'openedx.core.djangoapps.coursegraph.apps.CoursegraphConfig', - # Mailchimp Syncing 'lms.djangoapps.mailing',