diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py
index 4918aaf8081cb97b94e94f860cd3b084375c971c..541d387f5db8d3b91ebff1bd2f9766ee63983f27 100644
--- a/common/djangoapps/student/models.py
+++ b/common/djangoapps/student/models.py
@@ -55,6 +55,13 @@ from simple_history.models import HistoricalRecords
 from slumber.exceptions import HttpClientError, HttpServerError
 from user_util import user_util
 
+from openedx_events.learning.data import (
+    CourseData,
+    CourseEnrollmentData,
+    UserData,
+    UserPersonalData,
+)
+from openedx_events.learning.signals import COURSE_ENROLLMENT_CREATED
 import openedx.core.djangoapps.django_comment_common.comment_client as cc
 from common.djangoapps.course_modes.models import CourseMode, get_cosmetic_verified_display_price
 from common.djangoapps.student.emails import send_proctoring_requirements_email
@@ -1569,9 +1576,16 @@ class CourseEnrollment(models.Model):
         # All the server-side checks for whether a user is allowed to enroll.
         try:
             course = CourseOverview.get_from_id(course_key)
+            course_data = CourseData(
+                course_key=course.id,
+                display_name=course.display_name,
+            )
         except CourseOverview.DoesNotExist:
             # This is here to preserve legacy behavior which allowed enrollment in courses
             # announced before the start of content creation.
+            course_data = CourseData(
+                course_key=course_key,
+            )
             if check_access:
                 log.warning("User %s failed to enroll in non-existent course %s", user.username, str(course_key))
                 raise NonExistentCourseError  # lint-amnesty, pylint: disable=raise-missing-from
@@ -1607,6 +1621,25 @@ class CourseEnrollment(models.Model):
         enrollment.update_enrollment(is_active=True, mode=mode, enterprise_uuid=enterprise_uuid)
         enrollment.send_signal(EnrollStatusChange.enroll)
 
+        # Announce user's enrollment
+        COURSE_ENROLLMENT_CREATED.send_event(
+            enrollment=CourseEnrollmentData(
+                user=UserData(
+                    pii=UserPersonalData(
+                        username=user.username,
+                        email=user.email,
+                        name=user.profile.name,
+                    ),
+                    id=user.id,
+                    is_active=user.is_active,
+                ),
+                course=course_data,
+                mode=enrollment.mode,
+                is_active=enrollment.is_active,
+                creation_date=enrollment.created,
+            )
+        )
+
         return enrollment
 
     @classmethod
diff --git a/common/djangoapps/student/tests/test_enrollment.py b/common/djangoapps/student/tests/test_enrollment.py
index 28fe2a9f786c08b0094ddfa73d8bf38939feff7d..5165ca57d2e8f742d11691d99122672014c149f2 100644
--- a/common/djangoapps/student/tests/test_enrollment.py
+++ b/common/djangoapps/student/tests/test_enrollment.py
@@ -10,6 +10,7 @@ import ddt
 import pytest
 from django.conf import settings
 from django.urls import reverse
+from openedx_events.tests.utils import OpenEdxEventsTestMixin
 
 from common.djangoapps.course_modes.models import CourseMode
 from common.djangoapps.course_modes.tests.factories import CourseModeFactory
@@ -30,11 +31,13 @@ from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
 @ddt.ddt
 @patch.dict('django.conf.settings.FEATURES', {'ENABLE_SPECIAL_EXAMS': True})
 @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
-class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
+class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase, OpenEdxEventsTestMixin):
     """
     Test student enrollment, especially with different course modes.
     """
 
+    ENABLED_OPENEDX_EVENTS = []
+
     USERNAME = "Bob"
     EMAIL = "bob@example.com"
     PASSWORD = "edx"
@@ -42,7 +45,14 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
 
     @classmethod
     def setUpClass(cls):
+        """
+        Set up class method for the Test class.
+
+        This method starts manually events isolation. Explanation here:
+        openedx/core/djangoapps/user_authn/views/tests/test_events.py#L44
+        """
         super().setUpClass()
+        cls.start_events_isolation()
         cls.course = CourseFactory.create()
         cls.course_limited = CourseFactory.create()
         cls.proctored_course = CourseFactory(
diff --git a/common/djangoapps/student/tests/test_events.py b/common/djangoapps/student/tests/test_events.py
index 938952f571fce4cd37e9a3ba7c4f5650576bdc7b..00b0b62784cb58eb0ccbd2a0e8e5e0219f5ed93e 100644
--- a/common/djangoapps/student/tests/test_events.py
+++ b/common/djangoapps/student/tests/test_events.py
@@ -10,10 +10,23 @@ from django.db.utils import IntegrityError
 from django.test import TestCase
 from django_countries.fields import Country
 
-from common.djangoapps.student.models import CourseEnrollmentAllowed
-from common.djangoapps.student.tests.factories import CourseEnrollmentAllowedFactory, UserFactory
+from common.djangoapps.student.models import CourseEnrollmentAllowed, CourseEnrollment
+from common.djangoapps.student.tests.factories import CourseEnrollmentAllowedFactory, UserFactory, UserProfileFactory
 from common.djangoapps.student.tests.tests import UserSettingsEventTestMixin
 
+from openedx_events.learning.data import (
+    CourseData,
+    CourseEnrollmentData,
+    UserData,
+    UserPersonalData,
+)
+from openedx_events.learning.signals import COURSE_ENROLLMENT_CREATED
+from openedx_events.tests.utils import OpenEdxEventsTestMixin
+from openedx.core.djangolib.testing.utils import skip_unless_lms
+
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
+from xmodule.modulestore.tests.factories import CourseFactory
+
 
 class TestUserProfileEvents(UserSettingsEventTestMixin, TestCase):
     """
@@ -179,3 +192,87 @@ class TestUserEvents(UserSettingsEventTestMixin, TestCase):
         # CEAs shouldn't have been affected
         assert CourseEnrollmentAllowed.objects.count() == 1
         assert CourseEnrollmentAllowed.objects.filter(email='test@edx.org').count() == 1
+
+
+@skip_unless_lms
+class EnrollmentEventsTest(SharedModuleStoreTestCase, OpenEdxEventsTestMixin):
+    """
+    Tests for the Open edX Events associated with the enrollment process through the enroll method.
+
+    This class guarantees that the following events are sent during the user's enrollment, with
+    the exact Data Attributes as the event definition stated:
+
+        - COURSE_ENROLLMENT_CREATED: sent after the user's enrollment.
+    """
+
+    ENABLED_OPENEDX_EVENTS = ["org.openedx.learning.course.enrollment.created.v1"]
+
+    @classmethod
+    def setUpClass(cls):
+        """
+        Set up class method for the Test class.
+
+        This method starts manually events isolation. Explanation here:
+        openedx/core/djangoapps/user_authn/views/tests/test_events.py#L44
+        """
+        super().setUpClass()
+        cls.start_events_isolation()
+
+    def setUp(self):  # pylint: disable=arguments-differ
+        super().setUp()
+        self.course = CourseFactory.create()
+        self.user = UserFactory.create(
+            username="test",
+            email="test@example.com",
+            password="password",
+        )
+        self.user_profile = UserProfileFactory.create(user=self.user, name="Test Example")
+        self.receiver_called = False
+
+    def _event_receiver_side_effect(self, **kwargs):  # pylint: disable=unused-argument
+        """
+        Used show that the Open edX Event was called by the Django signal handler.
+        """
+        self.receiver_called = True
+
+    def test_enrollment_created_event_emitted(self):
+        """
+        Test whether the student enrollment event is sent after the user's
+        enrollment process.
+
+        Expected result:
+            - COURSE_ENROLLMENT_CREATED is sent and received by the mocked receiver.
+            - The arguments that the receiver gets are the arguments sent by the event
+            except the metadata generated on the fly.
+        """
+        event_receiver = mock.Mock(side_effect=self._event_receiver_side_effect)
+        COURSE_ENROLLMENT_CREATED.connect(event_receiver)
+
+        enrollment = CourseEnrollment.enroll(self.user, self.course.id)
+
+        self.assertTrue(self.receiver_called)
+        self.assertDictContainsSubset(
+            {
+                "signal": COURSE_ENROLLMENT_CREATED,
+                "sender": None,
+                "enrollment": CourseEnrollmentData(
+                    user=UserData(
+                        pii=UserPersonalData(
+                            username=self.user.username,
+                            email=self.user.email,
+                            name=self.user.profile.name,
+                        ),
+                        id=self.user.id,
+                        is_active=self.user.is_active,
+                    ),
+                    course=CourseData(
+                        course_key=self.course.id,
+                        display_name=self.course.display_name,
+                    ),
+                    mode=enrollment.mode,
+                    is_active=enrollment.is_active,
+                    creation_date=enrollment.created,
+                ),
+            },
+            event_receiver.call_args.kwargs
+        )
diff --git a/openedx/core/djangoapps/user_authn/views/login.py b/openedx/core/djangoapps/user_authn/views/login.py
index 6b31252c17fc5c174e4148409e50c81ad68cba79..a92cad9e05a4746066fe233c6c7d6a2920086814 100644
--- a/openedx/core/djangoapps/user_authn/views/login.py
+++ b/openedx/core/djangoapps/user_authn/views/login.py
@@ -29,6 +29,8 @@ from edx_django_utils.monitoring import set_custom_attribute
 from ratelimit.decorators import ratelimit
 from rest_framework.views import APIView
 
+from openedx_events.learning.data import UserData, UserPersonalData
+from openedx_events.learning.signals import SESSION_LOGIN_COMPLETED
 from common.djangoapps.edxmako.shortcuts import render_to_response
 from openedx.core.djangoapps.password_policy import compliance as password_policy_compliance
 from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
@@ -298,6 +300,19 @@ def _handle_successful_authentication_and_login(user, request):
         django_login(request, user)
         request.session.set_expiry(604800 * 4)
         log.debug("Setting user session expiry to 4 weeks")
+
+        # Announce user's login
+        SESSION_LOGIN_COMPLETED.send_event(
+            user=UserData(
+                pii=UserPersonalData(
+                    username=user.username,
+                    email=user.email,
+                    name=user.profile.name,
+                ),
+                id=user.id,
+                is_active=user.is_active,
+            ),
+        )
     except Exception as exc:
         AUDIT_LOG.critical("Login failed - Could not create session. Is memcached running?")
         log.critical("Login failed - Could not create session. Is memcached running?")
diff --git a/openedx/core/djangoapps/user_authn/views/register.py b/openedx/core/djangoapps/user_authn/views/register.py
index c7ce726b7cad9b983c5dc6eadcfba905874c07e8..23e0c413b5006a49d998c865e7537629b031f7cc 100644
--- a/openedx/core/djangoapps/user_authn/views/register.py
+++ b/openedx/core/djangoapps/user_authn/views/register.py
@@ -23,6 +23,8 @@ from django.views.decorators.csrf import csrf_exempt, ensure_csrf_cookie
 from django.views.decorators.debug import sensitive_post_parameters
 from edx_django_utils.monitoring import set_custom_attribute
 from edx_toggles.toggles import LegacyWaffleFlag, LegacyWaffleFlagNamespace
+from openedx_events.learning.data import UserData, UserPersonalData
+from openedx_events.learning.signals import STUDENT_REGISTRATION_COMPLETED
 from pytz import UTC
 from ratelimit.decorators import ratelimit
 from requests import HTTPError
@@ -252,6 +254,18 @@ def create_account_with_params(request, params):
     # Announce registration
     REGISTER_USER.send(sender=None, user=user, registration=registration)
 
+    STUDENT_REGISTRATION_COMPLETED.send_event(
+        user=UserData(
+            pii=UserPersonalData(
+                username=user.username,
+                email=user.email,
+                name=user.profile.name,
+            ),
+            id=user.id,
+            is_active=user.is_active,
+        ),
+    )
+
     create_comments_service_user(user)
 
     try:
diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_events.py b/openedx/core/djangoapps/user_authn/views/tests/test_events.py
new file mode 100644
index 0000000000000000000000000000000000000000..acec4a935d6032bec88a8b1919c1f327a56cba02
--- /dev/null
+++ b/openedx/core/djangoapps/user_authn/views/tests/test_events.py
@@ -0,0 +1,183 @@
+"""
+Test classes for the events sent in the registration process.
+
+Classes:
+    RegistrationEventTest: Test event sent after registering a user through the
+    user API.
+    LoginSessionEventTest: Test event sent after creating the user's login session
+    user through the user API.
+"""
+from unittest.mock import Mock
+
+from django.contrib.auth.models import User  # lint-amnesty, pylint: disable=imported-auth-user
+from django.urls import reverse
+from openedx_events.learning.data import UserData, UserPersonalData
+from openedx_events.learning.signals import SESSION_LOGIN_COMPLETED, STUDENT_REGISTRATION_COMPLETED
+from openedx_events.tests.utils import OpenEdxEventsTestMixin
+
+from common.djangoapps.student.tests.factories import UserFactory, UserProfileFactory
+from openedx.core.djangoapps.user_api.tests.test_views import UserAPITestCase
+from openedx.core.djangolib.testing.utils import skip_unless_lms
+
+
+@skip_unless_lms
+class RegistrationEventTest(UserAPITestCase, OpenEdxEventsTestMixin):
+    """
+    Tests for the Open edX Events associated with the registration process through
+    the registration view.
+
+    This class guarantees that the following events are sent after registering
+    a user, with the exact Data Attributes as the event definition stated:
+
+        - STUDENT_REGISTRATION_COMPLETED: after the user's registration has been
+        completed.
+    """
+
+    ENABLED_OPENEDX_EVENTS = ["org.openedx.learning.student.registration.completed.v1"]
+
+    @classmethod
+    def setUpClass(cls):
+        """
+        Set up class method for the Test class.
+
+        So the Open edX Events Isolation starts, the setUpClass must be explicitly
+        called with the method that executes the isolation. We do this to avoid
+        MRO resolution conflicts with other sibling classes while ensuring the
+        isolation process begins.
+        """
+        super().setUpClass()
+        cls.start_events_isolation()
+
+    def setUp(self):  # pylint: disable=arguments-differ
+        super().setUp()
+        self.url = reverse("user_api_registration")
+        self.user_info = {
+            "email": "user@example.com",
+            "name": "Test User",
+            "username": "test",
+            "password": "password",
+            "honor_code": "true",
+        }
+        self.receiver_called = False
+
+    def _event_receiver_side_effect(self, **kwargs):  # pylint: disable=unused-argument
+        """
+        Used show that the Open edX Event was called by the Django signal handler.
+        """
+        self.receiver_called = True
+
+    def test_send_registration_event(self):
+        """
+        Test whether the student registration event is sent during the user's
+        registration process.
+
+        Expected result:
+            - STUDENT_REGISTRATION_COMPLETED is sent and received by the mocked receiver.
+            - The arguments that the receiver gets are the arguments sent by the event
+            except the metadata generated on the fly.
+        """
+        event_receiver = Mock(side_effect=self._event_receiver_side_effect)
+        STUDENT_REGISTRATION_COMPLETED.connect(event_receiver)
+
+        self.client.post(self.url, self.user_info)
+
+        user = User.objects.get(username=self.user_info.get("username"))
+        self.assertTrue(self.receiver_called)
+        self.assertDictContainsSubset(
+            {
+                "signal": STUDENT_REGISTRATION_COMPLETED,
+                "sender": None,
+                "user": UserData(
+                    pii=UserPersonalData(
+                        username=user.username,
+                        email=user.email,
+                        name=user.profile.name,
+                    ),
+                    id=user.id,
+                    is_active=user.is_active,
+                ),
+            },
+            event_receiver.call_args.kwargs
+        )
+
+
+@skip_unless_lms
+class LoginSessionEventTest(UserAPITestCase, OpenEdxEventsTestMixin):
+    """
+    Tests for the Open edX Events associated with the login process through the
+    login_user view.
+
+    This class guarantees that the following events are sent after the user's
+    session creation, with the exact Data Attributes as the event definition
+    stated:
+
+        - SESSION_LOGIN_COMPLETED: after login has been completed.
+    """
+
+    ENABLED_OPENEDX_EVENTS = ["org.openedx.learning.auth.session.login.completed.v1"]
+
+    @classmethod
+    def setUpClass(cls):
+        """
+        Set up class method for the Test class.
+
+        This method starts manually events isolation. Explanation here:
+        openedx/core/djangoapps/user_authn/views/tests/test_events.py#L44
+        """
+        super().setUpClass()
+        cls.start_events_isolation()
+
+    def setUp(self):  # pylint: disable=arguments-differ
+        super().setUp()
+        self.url = reverse("user_api_login_session", kwargs={"api_version": "v1"})
+        self.user = UserFactory.create(
+            username="test",
+            email="test@example.com",
+            password="password",
+        )
+        self.user_profile = UserProfileFactory.create(user=self.user, name="Test Example")
+        self.receiver_called = True
+
+    def _event_receiver_side_effect(self, **kwargs):  # pylint: disable=unused-argument
+        """
+        Used show that the Open edX Event was called by the Django signal handler.
+        """
+        self.receiver_called = True
+
+    def test_send_login_event(self):
+        """
+        Test whether the student login event is sent after the user's
+        login process.
+
+        Expected result:
+            - SESSION_LOGIN_COMPLETED is sent and received by the mocked receiver.
+            - The arguments that the receiver gets are the arguments sent by the event
+            except the metadata generated on the fly.
+        """
+        event_receiver = Mock(side_effect=self._event_receiver_side_effect)
+        SESSION_LOGIN_COMPLETED.connect(event_receiver)
+        data = {
+            "email": "test@example.com",
+            "password": "password",
+        }
+
+        self.client.post(self.url, data)
+
+        user = User.objects.get(username=self.user.username)
+        self.assertTrue(self.receiver_called)
+        self.assertDictContainsSubset(
+            {
+                "signal": SESSION_LOGIN_COMPLETED,
+                "sender": None,
+                "user": UserData(
+                    pii=UserPersonalData(
+                        username=user.username,
+                        email=user.email,
+                        name=user.profile.name,
+                    ),
+                    id=user.id,
+                    is_active=user.is_active,
+                ),
+            },
+            event_receiver.call_args.kwargs
+        )
diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_login.py b/openedx/core/djangoapps/user_authn/views/tests/test_login.py
index 50827e65404da699575e6cb677eff40157af87b3..8c5a08521514b76070a8f78ef9680a1ee0896310 100644
--- a/openedx/core/djangoapps/user_authn/views/tests/test_login.py
+++ b/openedx/core/djangoapps/user_authn/views/tests/test_login.py
@@ -21,6 +21,7 @@ from django.urls import NoReverseMatch, reverse
 from edx_toggles.toggles.testutils import override_waffle_flag, override_waffle_switch
 from freezegun import freeze_time
 from common.djangoapps.student.tests.factories import RegistrationFactory, UserFactory, UserProfileFactory
+from openedx_events.tests.utils import OpenEdxEventsTestMixin
 
 from openedx.core.djangoapps.password_policy.compliance import (
     NonCompliantPasswordException,
@@ -44,11 +45,13 @@ from common.djangoapps.util.password_policy_validators import DEFAULT_MAX_PASSWO
 
 
 @ddt.ddt
-class LoginTest(SiteMixin, CacheIsolationTestCase):
+class LoginTest(SiteMixin, CacheIsolationTestCase, OpenEdxEventsTestMixin):
     """
     Test login_user() view
     """
 
+    ENABLED_OPENEDX_EVENTS = []
+
     ENABLED_CACHES = ['default']
     LOGIN_FAILED_WARNING = 'Email or password is incorrect'
     ACTIVATE_ACCOUNT_WARNING = 'In order to sign in, you need to activate your account'
@@ -56,6 +59,17 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
     user_email = 'test@edx.org'
     password = 'test_password'
 
+    @classmethod
+    def setUpClass(cls):
+        """
+        Set up class method for the Test class.
+
+        This method starts manually events isolation. Explanation here:
+        openedx/core/djangoapps/user_authn/views/tests/test_events.py#L44
+        """
+        super().setUpClass()
+        cls.start_events_isolation()
+
     def setUp(self):
         """Setup a test user along with its registration and profile"""
         super().setUp()
@@ -954,13 +968,26 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
 
 @ddt.ddt
 @skip_unless_lms
-class LoginSessionViewTest(ApiTestCase):
+class LoginSessionViewTest(ApiTestCase, OpenEdxEventsTestMixin):
     """Tests for the login end-points of the user API. """
 
+    ENABLED_OPENEDX_EVENTS = []
+
     USERNAME = "bob"
     EMAIL = "bob@example.com"
     PASSWORD = "password"
 
+    @classmethod
+    def setUpClass(cls):
+        """
+        Set up class method for the Test class.
+
+        This method starts manually events isolation. Explanation here:
+        openedx/core/djangoapps/user_authn/views/tests/test_events.py#L44
+        """
+        super().setUpClass()
+        cls.start_events_isolation()
+
     def setUp(self):
         super().setUp()
         self.url = reverse("user_api_login_session", kwargs={'api_version': 'v1'})
diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_register.py b/openedx/core/djangoapps/user_authn/views/tests/test_register.py
index 869a270c399e35eae24109ef48557e41eb659b40..fa1933d53bb486c0b5addff701d1b7a71092c069 100644
--- a/openedx/core/djangoapps/user_authn/views/tests/test_register.py
+++ b/openedx/core/djangoapps/user_authn/views/tests/test_register.py
@@ -17,6 +17,7 @@ from django.test.utils import override_settings
 from django.urls import reverse
 from pytz import UTC
 from social_django.models import Partial, UserSocialAuth
+from openedx_events.tests.utils import OpenEdxEventsTestMixin
 
 from edx_toggles.toggles.testutils import override_waffle_flag
 from openedx.core.djangoapps.site_configuration.helpers import get_value
@@ -69,12 +70,16 @@ from common.djangoapps.util.password_policy_validators import (
 
 @ddt.ddt
 @skip_unless_lms
-class RegistrationViewValidationErrorTest(ThirdPartyAuthTestMixin, UserAPITestCase, RetirementTestCase):
+class RegistrationViewValidationErrorTest(
+    ThirdPartyAuthTestMixin, UserAPITestCase, RetirementTestCase, OpenEdxEventsTestMixin
+):
     """
     Tests for catching duplicate email and username validation errors within
     the registration end-points of the User API.
     """
 
+    ENABLED_OPENEDX_EVENTS = []
+
     maxDiff = None
 
     USERNAME = "bob"
@@ -88,6 +93,17 @@ class RegistrationViewValidationErrorTest(ThirdPartyAuthTestMixin, UserAPITestCa
     COUNTRY = "us"
     GOALS = "Learn all the things!"
 
+    @classmethod
+    def setUpClass(cls):
+        """
+        Set up class method for the Test class.
+
+        This method starts manually events isolation. Explanation here:
+        openedx/core/djangoapps/user_authn/views/tests/test_events.py#L44
+        """
+        super().setUpClass()
+        cls.start_events_isolation()
+
     def setUp(self):  # pylint: disable=arguments-differ
         super().setUp()
         self.url = reverse("user_api_registration")
@@ -423,9 +439,13 @@ class RegistrationViewValidationErrorTest(ThirdPartyAuthTestMixin, UserAPITestCa
 
 @ddt.ddt
 @skip_unless_lms
-class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
+class RegistrationViewTestV1(
+    ThirdPartyAuthTestMixin, UserAPITestCase, OpenEdxEventsTestMixin
+):
     """Tests for the registration end-points of the User API. """
 
+    ENABLED_OPENEDX_EVENTS = []
+
     maxDiff = None
 
     USERNAME = "bob"
@@ -486,6 +506,17 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
     ]
     link_template = "<a href='/honor' rel='noopener' target='_blank'>{link_label}</a>"
 
+    @classmethod
+    def setUpClass(cls):
+        """
+        Set up class method for the Test class.
+
+        This method starts manually events isolation. Explanation here:
+        openedx/core/djangoapps/user_authn/views/tests/test_events.py#L44
+        """
+        super().setUpClass()
+        cls.start_events_isolation()
+
     def setUp(self):  # pylint: disable=arguments-differ
         super().setUp()
         self.url = reverse("user_api_registration")
@@ -1815,6 +1846,17 @@ class RegistrationViewTestV2(RegistrationViewTestV1):
 
     # pylint: disable=test-inherits-tests
 
+    @classmethod
+    def setUpClass(cls):
+        """
+        Set up class method for the Test class.
+
+        This method starts manually events isolation. Explanation here:
+        openedx/core/djangoapps/user_authn/views/tests/test_events.py#L44
+        """
+        super().setUpClass()
+        cls.start_events_isolation()
+
     def setUp(self):  # pylint: disable=arguments-differ
         super(RegistrationViewTestV1, self).setUp()  # lint-amnesty, pylint: disable=bad-super-call
         self.url = reverse("user_api_registration_v2")
@@ -2043,16 +2085,31 @@ class RegistrationViewTestV2(RegistrationViewTestV1):
 
 @httpretty.activate
 @ddt.ddt
-class ThirdPartyRegistrationTestMixin(ThirdPartyOAuthTestMixin, CacheIsolationTestCase):
+class ThirdPartyRegistrationTestMixin(
+    ThirdPartyOAuthTestMixin, CacheIsolationTestCase, OpenEdxEventsTestMixin
+):
     """
     Tests for the User API registration endpoint with 3rd party authentication.
     """
     CREATE_USER = False
 
+    ENABLED_OPENEDX_EVENTS = []
+
     ENABLED_CACHES = ['default']
 
     __test__ = False
 
+    @classmethod
+    def setUpClass(cls):
+        """
+        Set up class method for the Test class.
+
+        This method starts manually events isolation. Explanation here:
+        openedx/core/djangoapps/user_authn/views/tests/test_events.py#L44
+        """
+        super().setUpClass()
+        cls.start_events_isolation()
+
     def setUp(self):
         super().setUp()
         self.url = reverse('user_api_registration')
@@ -2209,11 +2266,25 @@ class ThirdPartyRegistrationTestMixin(ThirdPartyOAuthTestMixin, CacheIsolationTe
 
 @skipUnless(settings.FEATURES.get("ENABLE_THIRD_PARTY_AUTH"), "third party auth not enabled")
 class TestFacebookRegistrationView(
-    ThirdPartyRegistrationTestMixin, ThirdPartyOAuthTestMixinFacebook, TransactionTestCase
+    ThirdPartyRegistrationTestMixin, ThirdPartyOAuthTestMixinFacebook, TransactionTestCase, OpenEdxEventsTestMixin
 ):
     """Tests the User API registration endpoint with Facebook authentication."""
+
+    ENABLED_OPENEDX_EVENTS = []
+
     __test__ = True
 
+    @classmethod
+    def setUpClass(cls):
+        """
+        Set up class method for the Test class.
+
+        This method starts manually events isolation. Explanation here:
+        openedx/core/djangoapps/user_authn/views/tests/test_events.py#L44
+        """
+        super().setUpClass()
+        cls.start_events_isolation()
+
     def test_social_auth_exception(self):
         """
         According to the do_auth method in social_core.backends.facebook.py,
@@ -2227,21 +2298,48 @@ class TestFacebookRegistrationView(
 
 @skipUnless(settings.FEATURES.get("ENABLE_THIRD_PARTY_AUTH"), "third party auth not enabled")
 class TestGoogleRegistrationView(
-    ThirdPartyRegistrationTestMixin, ThirdPartyOAuthTestMixinGoogle, TransactionTestCase
+    ThirdPartyRegistrationTestMixin, ThirdPartyOAuthTestMixinGoogle, TransactionTestCase, OpenEdxEventsTestMixin
 ):
     """Tests the User API registration endpoint with Google authentication."""
+
+    ENABLED_OPENEDX_EVENTS = []
+
     __test__ = True
 
+    @classmethod
+    def setUpClass(cls):
+        """
+        Set up class method for the Test class.
+
+        This method starts manually events isolation. Explanation here:
+        openedx/core/djangoapps/user_authn/views/tests/test_events.py#L44
+        """
+        super().setUpClass()
+        cls.start_events_isolation()
+
 
 @ddt.ddt
-class RegistrationValidationViewTests(test_utils.ApiTestCase):
+class RegistrationValidationViewTests(test_utils.ApiTestCase, OpenEdxEventsTestMixin):
     """
     Tests for validity of user data in registration forms.
     """
 
+    ENABLED_OPENEDX_EVENTS = []
+
     endpoint_name = 'registration_validation'
     path = reverse(endpoint_name)
 
+    @classmethod
+    def setUpClass(cls):
+        """
+        Set up class method for the Test class.
+
+        This method starts manually events isolation. Explanation here:
+        openedx/core/djangoapps/user_authn/views/tests/test_events.py#L44
+        """
+        super().setUpClass()
+        cls.start_events_isolation()
+
     def setUp(self):
         super().setUp()
         cache.clear()
diff --git a/requirements/edx/base.in b/requirements/edx/base.in
index 1c3d9af99fec30620ff1e712b99996da65267cf8..4c3d1897d72b1a793ac997ab1da4a1e237f1db5e 100644
--- a/requirements/edx/base.in
+++ b/requirements/edx/base.in
@@ -122,6 +122,7 @@ nltk                                # Natural language processing; used by the c
 nodeenv                             # Utility for managing Node.js environments; we use this for deployments and testing
 oauthlib                            # OAuth specification support for authenticating via LTI or other Open edX services
 openedx-calc                        # Library supporting mathematical calculations for Open edX
+openedx-events                      # Open edX Events from Hooks Extension Framework (OEP-50)
 ora2
 piexif                              # Exif image metadata manipulation, used in the profile_images app
 Pillow                              # Image manipulation library; used for course assets, profile images, invoice PDFs, etc.
diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt
index e64164e8ca0e475c0d9ab134e1f3f847e5717332..b9b52e0c74a6e5ce92c9915d9543af7327a3b5ca 100644
--- a/requirements/edx/base.txt
+++ b/requirements/edx/base.txt
@@ -53,6 +53,7 @@ attrs==21.2.0
     #   -r requirements/edx/base.in
     #   aiohttp
     #   edx-ace
+    #   openedx-events
 babel==2.9.1
     # via
     #   -r requirements/edx/base.in
@@ -220,6 +221,7 @@ django==2.2.24
     #   help-tokens
     #   jsonfield2
     #   lti-consumer-xblock
+    #   openedx-events
     #   ora2
     #   rest-condition
     #   super-csv
@@ -469,6 +471,7 @@ edx-opaque-keys[django]==2.2.2
     #   edx-user-state-client
     #   edx-when
     #   lti-consumer-xblock
+    #   openedx-events
     #   ora2
     #   xmodule
 edx-organizations==6.10.0
@@ -702,6 +705,8 @@ oauthlib==3.0.1
     #   social-auth-core
 openedx-calc==2.0.1
     # via -r requirements/edx/base.in
+openedx-events==0.5.1
+    # via -r requirements/edx/base.in
 ora2==3.6.20
     # via -r requirements/edx/base.in
 packaging==21.0
diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt
index dbf6234ee7519714a4ec21d3b1ea955560c56e8f..6ace173a4082b756a083c425f859b3a1e2f75b3c 100644
--- a/requirements/edx/development.txt
+++ b/requirements/edx/development.txt
@@ -74,6 +74,7 @@ attrs==21.2.0
     #   aiohttp
     #   edx-ace
     #   jsonschema
+    #   openedx-events
     #   pytest
 babel==2.9.1
     # via
@@ -298,6 +299,7 @@ django==2.2.24
     #   help-tokens
     #   jsonfield2
     #   lti-consumer-xblock
+    #   openedx-events
     #   ora2
     #   rest-condition
     #   super-csv
@@ -574,6 +576,7 @@ edx-opaque-keys[django]==2.2.2
     #   edx-user-state-client
     #   edx-when
     #   lti-consumer-xblock
+    #   openedx-events
     #   ora2
     #   xmodule
 edx-organizations==6.10.0
@@ -929,6 +932,8 @@ oauthlib==3.0.1
     #   social-auth-core
 openedx-calc==2.0.1
     # via -r requirements/edx/testing.txt
+openedx-events==0.5.1
+    # via -r requirements/edx/testing.txt
 ora2==3.6.20
     # via -r requirements/edx/testing.txt
 packaging==21.0
diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt
index 66b6f71350e0e72ae2d8595749782ef21748a4dc..533b39582e4e5bb3ed81f2e6ee199cef42b3beb3 100644
--- a/requirements/edx/testing.txt
+++ b/requirements/edx/testing.txt
@@ -68,6 +68,7 @@ attrs==21.2.0
     #   -r requirements/edx/base.txt
     #   aiohttp
     #   edx-ace
+    #   openedx-events
     #   pytest
 babel==2.9.1
     # via
@@ -283,6 +284,7 @@ distlib==0.3.2
     #   help-tokens
     #   jsonfield2
     #   lti-consumer-xblock
+    #   openedx-events
     #   ora2
     #   rest-condition
     #   super-csv
@@ -556,6 +558,7 @@ edx-opaque-keys[django]==2.2.2
     #   edx-user-state-client
     #   edx-when
     #   lti-consumer-xblock
+    #   openedx-events
     #   ora2
     #   xmodule
 edx-organizations==6.10.0
@@ -877,6 +880,8 @@ oauthlib==3.0.1
     #   social-auth-core
 openedx-calc==2.0.1
     # via -r requirements/edx/base.txt
+openedx-events==0.5.1
+    # via -r requirements/edx/base.txt
 ora2==3.6.20
     # via -r requirements/edx/base.txt
 packaging==21.0