diff --git a/lms/djangoapps/ccx/views.py b/lms/djangoapps/ccx/views.py index 08d6ec19824c..fcbc70ec58ce 100644 --- a/lms/djangoapps/ccx/views.py +++ b/lms/djangoapps/ccx/views.py @@ -21,11 +21,14 @@ from django.shortcuts import redirect from django.urls import reverse from django.utils.translation import gettext as _ +from django.utils.timezone import timezone from django.views.decorators.cache import cache_control from django.views.decorators.csrf import ensure_csrf_cookie from opaque_keys.edx.keys import CourseKey from six import StringIO +from openedx_events.content_authoring.data import CourseData +from openedx_events.content_authoring.signals import COURSE_CREATED from common.djangoapps.edxmako.shortcuts import render_to_response from common.djangoapps.student.models import CourseEnrollment from common.djangoapps.student.roles import CourseCcxCoachRole @@ -301,6 +304,14 @@ def create_ccx(request, course, ccx=None): user=request.user, ) + # .. event_implemented_name: COURSE_CREATED + COURSE_CREATED.send_event( + time=datetime.datetime.now(tz=timezone.utc), + course=CourseData( + course_key=ccx_id, + ) + ) + return redirect(url) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 3017d343ad31..38872ccdfe56 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -100,4 +100,4 @@ pytz==2022.2.1 # openedx-events>0.13.0 causes test failures due to breaking changes # These broken tests will be fixed in a separate PR -openedx-events==0.13.0 +openedx-events==8.3.0 diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 038129222d69..2c7e75896ccc 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -759,7 +759,7 @@ openedx-calc==3.0.1 # via -r requirements/edx/base.in openedx-django-pyfs==3.2.1 # via xblock -openedx-events==0.13.0 +openedx-events==8.3.0 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/base.in diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 3e5ba143d975..406ff19b1614 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -991,7 +991,7 @@ openedx-django-pyfs==3.2.1 # via # -r requirements/edx/testing.txt # xblock -openedx-events==0.13.0 +openedx-events==8.3.0 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/testing.txt diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 84935527d441..e1ea3eb1187f 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -942,7 +942,7 @@ openedx-django-pyfs==3.2.1 # via # -r requirements/edx/base.txt # xblock -openedx-events==0.13.0 +openedx-events==8.3.0 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt diff --git a/xmodule/modulestore/mixed.py b/xmodule/modulestore/mixed.py index 17b5e8a0869d..639a624ce1a9 100644 --- a/xmodule/modulestore/mixed.py +++ b/xmodule/modulestore/mixed.py @@ -13,6 +13,10 @@ from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.locator import LibraryLocator +from openedx_events.content_authoring.data import CourseData +from openedx_events.content_authoring.signals import COURSE_CREATED + +from django.utils.timezone import datetime, timezone from xmodule.assetstore import AssetMetadata from . import XMODULE_FIELDS_WITH_USAGE_KEYS, ModuleStoreWriteBase @@ -667,6 +671,14 @@ def create_course(self, org, course, run, user_id, **kwargs): # lint-amnesty, p # add new course to the mapping self.mappings[course_key] = store + # .. event_implemented_name: COURSE_CREATED + COURSE_CREATED.send_event( + time=datetime.now(timezone.utc), + course=CourseData( + course_key=course_key, + ) + ) + return course @strip_key diff --git a/xmodule/modulestore/tests/test_mixed_modulestore.py b/xmodule/modulestore/tests/test_mixed_modulestore.py index 318f6dc57d9b..e4bbdf6ebcb7 100644 --- a/xmodule/modulestore/tests/test_mixed_modulestore.py +++ b/xmodule/modulestore/tests/test_mixed_modulestore.py @@ -15,6 +15,7 @@ from unittest.mock import Mock, call, patch import ddt +from openedx_events.content_authoring.signals import COURSE_CREATED import pymongo import pytest # Mixed modulestore depends on django, so we'll manually configure some django settings @@ -109,6 +110,9 @@ class CommonMixedModuleStoreSetup(CourseComparisonTest): ], 'xblock_mixins': modulestore_options['xblock_mixins'], } + ENABLED_OPENEDX_EVENTS = [ + "org.openedx.content_authoring.course.created.v1", + ] def setUp(self): """ @@ -724,6 +728,29 @@ def test_publish_automatically_after_delete_unit(self, default_ms): self.store.delete_item(vertical.location, self.user_id) assert not self._has_changes(sequential.location) + @ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split) + def test_course_create_event(self, default_ms): + """ + Check that COURSE_CREATED event is sent when a course is created. + """ + self.initdb(default_ms) + event_receiver = Mock() + COURSE_CREATED.connect(event_receiver) + + test_course = self.store.create_course('test_org', 'test_course', 'test_run', self.user_id) + + event_receiver.assert_called_once() + self.assertDictContainsSubset( + { + "signal": COURSE_CREATED, + "sender": None, + "course": CourseData( + course_key=test_course.id, + ), + }, + event_receiver.call_args.kwargs, + ) + def setup_has_changes(self, default_ms): """ Common set up for has_changes tests below.