Exemple #1
0
 def setUp(self):
     """
     Setup common conditions for every test case.
     """
     super().setUp()
     self.event_type = "org.openedx.learning.session.login.completed.v1"
     self.user_mock = Mock()
     self.data_attr = {
         "user": Mock,
     }
     self.public_signal = OpenEdxPublicSignal(
         event_type=self.event_type,
         data=self.data_attr,
     )
Exemple #2
0
def create_simple_signal(data_dict):
    """
    Create a basic OpenEdxPublicSignal with init_data = data_dict

    Arguments:
        data_dict: Description of attributes passed to the signal
    """
    return OpenEdxPublicSignal(event_type="simple.signal", data=data_dict)
Exemple #3
0
    def enable_events_by_type(cls, *event_types):
        """
        Enable specific Open edX Events given their type.

        Arguments:
            event_types (list of `str`): types of events to enable.
        """
        for event_type in event_types:
            try:
                event = OpenEdxPublicSignal.get_signal_by_type(event_type)
            except KeyError:
                all_event_types = sorted(
                    s.event_type for s in OpenEdxPublicSignal.all_events())
                err_msg = (
                    "You tried to enable event '{}', but I don't recognize that "
                    "signal type. Did you mean one of these?: {}")
                raise ValueError(err_msg.format(event_type, all_event_types))  # pylint: disable=raise-missing-from
            event.enable()
Exemple #4
0
    def allow_send_events_failure(cls, *event_types):
        """
        Allow that send_event method fails for the specified event.

        This method determines which `send` method to use, send or send_robust.
        The first, raises receivers exceptions while the latter catches them.

        Arguments:
            event_types (list of `str`): types of events to enable.
        """
        for event_type in event_types:
            try:
                event = OpenEdxPublicSignal.get_signal_by_type(event_type)
            except KeyError:
                all_event_types = sorted(
                    s.event_type for s in OpenEdxPublicSignal.all_events())
                err_msg = (
                    "You tried to enable event '{}', but I don't recognize that "
                    "signal type. Did you mean one of these?: {}")
                raise ValueError(err_msg.format(event_type, all_event_types))  # pylint: disable=raise-missing-from
            event.allow_send_event_failure()
Exemple #5
0
class OpenEdxPublicSignalTest(TestCase):
    """
    Test cases for Open edX events base class.
    """
    def setUp(self):
        """
        Setup common conditions for every test case.
        """
        super().setUp()
        self.event_type = "org.openedx.learning.session.login.completed.v1"
        self.user_mock = Mock()
        self.data_attr = {
            "user": Mock,
        }
        self.public_signal = OpenEdxPublicSignal(
            event_type=self.event_type,
            data=self.data_attr,
        )

    def test_string_representation(self):
        """
        This methods checks the string representation for events base class.

        Expected behavior:
            The representation contains the event_type.
        """
        self.assertIn(self.event_type, str(self.public_signal))

    @override_settings(SERVICE_VARIANT="lms")
    @patch("openedx_events.data.openedx_events")
    @patch("openedx_events.data.socket")
    def test_get_signal_metadata(self, socket_mock, events_package_mock):
        """
        This methods tests getting the generated metadata for an event.

        Expected behavior:
            Returns the metadata containing information about the event.
        """
        events_package_mock.__version__ = "0.1.0"
        socket_mock.gethostname.return_value = "edx.devstack.lms"
        expected_metadata = {
            "event_type": self.event_type,
            "minorversion": 0,
            "source": "openedx/lms/web",
            "sourcehost": "edx.devstack.lms",
            "sourcelib": [0, 1, 0],
        }

        metadata = self.public_signal.generate_signal_metadata()

        self.assertDictContainsSubset(expected_metadata, attr.asdict(metadata))

    @patch(
        "openedx_events.tooling.OpenEdxPublicSignal.generate_signal_metadata")
    @patch("openedx_events.tooling.Signal.send")
    def test_send_event_successfully(self, send_mock, fake_metadata):
        """
        This method tests the process of sending an event that's allow to fail.

        Expected behavior:
            The event is sent as a django signal with send method.
        """
        expected_metadata = Mock(some_data="some_data")
        fake_metadata.return_value = expected_metadata
        self.public_signal.allow_send_event_failure()

        self.public_signal.send_event(user=self.user_mock)

        send_mock.assert_called_once_with(
            sender=None,
            user=self.user_mock,
            metadata=expected_metadata,
        )

    @patch(
        "openedx_events.tooling.OpenEdxPublicSignal.generate_signal_metadata")
    @patch("openedx_events.tooling.Signal.send_robust")
    def test_send_robust_event_successfully(self, send_robust_mock,
                                            fake_metadata):
        """
        This method tests the process of sending an event that won't crash.

        Expected behavior:
            The event is sent as a django signal with send_robust method.
        """
        expected_metadata = Mock(some_data="some_data")
        fake_metadata.return_value = expected_metadata
        send_robust_mock.return_value.__name__ = "func_name"

        self.public_signal.send_event(user=self.user_mock)

        send_robust_mock.assert_called_once_with(
            sender=None,
            user=self.user_mock,
            metadata=expected_metadata,
        )

    @ddt.data(
        (
            {
                "student": Mock()
            },
            "SenderValidationError org.openedx.learning.session.login.completed.v1: "
            "Missing required argument 'user'",
        ),
        (
            {
                "user": {
                    "student": Mock()
                }
            },
            "SenderValidationError org.openedx.learning.session.login.completed.v1: "
            "The argument 'user' is not instance of the Class Attribute 'type'",
        ),
        (
            {
                "student": Mock(),
                "user": Mock()
            },
            "SenderValidationError org.openedx.learning.session.login.completed.v1: "
            "There's a mismatch between initialization data and send_event arguments",
        ),
    )
    @ddt.unpack
    def test_invalid_sender(self, send_arguments, exception_message):
        """
        This method tests sending an event with invalid setup on the sender
        side.

        Expected behavior:
            A SenderValidationError exception is raised.
        """
        with self.assertRaisesMessage(SenderValidationError,
                                      exception_message):
            self.public_signal.send_event(**send_arguments)

    def test_send_event_with_django(self):
        """
        This method tests sending an event using the `send` built-in Django
        method.

        Expected behavior:
            A warning is showed advicing to use Open edX events custom
            send_signal method.
        """
        message = "Please, use 'send_event' when triggering an Open edX event."

        with self.assertWarns(Warning, msg=message):
            self.public_signal.send(sender=Mock())

    def test_send_robust_event_with_django(self):
        """
        This method tests sending an event using the `send` built-in Django
        method.

        Expected behavior:
            A warning is showed advicing to use Open edX events custom
            send_signal method.
        """
        message = "Please, use 'send_event' with send_robust equals to True when triggering an Open edX event."

        with self.assertWarns(Warning, msg=message):
            self.public_signal.send_robust(sender=Mock())

    @patch("openedx_events.tooling.Signal.send")
    def test_send_event_disabled(self, send_mock):
        """
        This method tests sending an event that has been disabled.

        Expected behavior:
            The Django Signal associated to the event is not sent.
        """
        self.public_signal.disable()

        result = self.public_signal.send_event(sender=Mock())

        send_mock.assert_not_called()
        self.assertListEqual([], result)
Exemple #6
0
from openedx_events.learning.data import (
    CertificateData,
    CohortData,
    CourseDiscussionConfigurationData,
    CourseEnrollmentData,
    UserData,
)
from openedx_events.tooling import OpenEdxPublicSignal

# .. event_type: org.openedx.learning.student.registration.completed.v1
# .. event_name: STUDENT_REGISTRATION_COMPLETED
# .. event_description: emitted when the user registration process in the LMS is completed.
# .. event_data: UserData
STUDENT_REGISTRATION_COMPLETED = OpenEdxPublicSignal(
    event_type="org.openedx.learning.student.registration.completed.v1",
    data={
        "user": UserData,
    })

# .. event_type: org.openedx.learning.auth.session.login.completed.v1
# .. event_name: SESSION_LOGIN_COMPLETED
# .. event_description: emitted when the user's login process in the LMS is completed.
# .. event_data: UserData
SESSION_LOGIN_COMPLETED = OpenEdxPublicSignal(
    event_type="org.openedx.learning.auth.session.login.completed.v1",
    data={
        "user": UserData,
    })

# .. event_type: org.openedx.learning.course.enrollment.created.v1
# .. event_name: COURSE_ENROLLMENT_CREATED
Exemple #7
0
"""
Custom signals definitions that representing the Open edX platform events.

All signals defined in this module must follow the name and versioning
conventions specified in docs/decisions/0002-events-naming-and-versioning.rst

They also must comply with the payload definition specified in
docs/decisions/0003-events-payload.rst
"""

from openedx_events.enterprise.data import SubscriptionLicenseData
from openedx_events.tooling import OpenEdxPublicSignal

# .. event_type: org.openedx.enterprise.subscription.license.modified.v1
# .. event_name: LICENSE_MODIFIED
# .. event_description: emitted when a Subscription License is modified,
#     where "modified" means created, updated, revoked, etc.
#     WARNING: This event is being used for event bus prototype purposes and
#          should not be used, and should not be copied as a fully vetted pattern.
#     TODO(EventBus): Delete or make production ready post-prototype phase.
#           We will be splitting different actions into their own events (for created,
#           updated, revoked, etc.)
#           See: https://openedx.atlassian.net/browse/ARCHBOM-2008 for more details.
# .. event_data: SubscriptionLicenseData
SUBSCRIPTION_LICENSE_MODIFIED = OpenEdxPublicSignal(
    event_type="org.openedx.enterprise.subscription.license.modified.v0",
    data={
        "license": SubscriptionLicenseData,
    })
Exemple #8
0
 def enable_all_events(cls):
     """
     Enable all events Open edX Events from all subdomains.
     """
     for event in OpenEdxPublicSignal.all_events():
         event.enable()
Exemple #9
0
"""
Signals for discussions
"""
from openedx_events.tooling import OpenEdxPublicSignal

from openedx.core.djangoapps.discussions.data import CourseDiscussionConfigurationData

# TODO: This will be moved to openedx_events. It's currently here to simplify the PR.
# .. event_type: org.openedx.learning.discussions.configuration.change.v1
# .. event_name: COURSE_DISCUSSIONS_UPDATED
# .. event_description: emitted when the configuration for a course's discussions changes in the course
# .. event_data: CourseDiscussionConfigurationData
COURSE_DISCUSSIONS_UPDATED = OpenEdxPublicSignal(
    event_type="org.openedx.learning.discussions.configuration.change.v1",
    data={
        "configuration": CourseDiscussionConfigurationData
    }
)