示例#1
0
    def test_bulk_publish_list_exclude(self):
        """
        Make sure we can bulk publish to a number of users
        passing in a list, and also pass in an exclusion list to
        make sure the people in the exclude list does not get
        the notification
        """

        msg = NotificationMessage(namespace='test-runner',
                                  msg_type=self.msg_type,
                                  payload={'foo': 'bar'})

        user_ids = list(
            range(1, const.NOTIFICATION_BULK_PUBLISH_CHUNK_SIZE * 2 + 1))
        exclude_user_ids = list(
            range(1, const.NOTIFICATION_BULK_PUBLISH_CHUNK_SIZE * 2 + 1, 2))

        # now send to more than our internal chunking size
        bulk_publish_notification_to_users(user_ids,
                                           msg,
                                           exclude_user_ids=exclude_user_ids)

        # now read them all back
        for user_id in range(
                1, const.NOTIFICATION_BULK_PUBLISH_CHUNK_SIZE * 2 + 1):
            notifications = get_notifications_for_user(user_id)

            self.assertTrue(isinstance(notifications, list))
            self.assertEqual(len(notifications),
                             1 if user_id not in exclude_user_ids else 0)
            if user_id not in exclude_user_ids:
                self.assertTrue(isinstance(notifications[0], UserNotification))
示例#2
0
    def test_bulk_publish_generator(self):
        """
        Make sure we can bulk publish to a number of users
        passing in a generator function
        """

        msg = NotificationMessage(namespace='test-runner',
                                  msg_type=self.msg_type,
                                  payload={'foo': 'bar'})

        def _user_id_generator():
            """
            Just spit our an generator that goes from 1 to 100
            """
            for user_id in range(1, 100):
                yield user_id

        # now send to more than our internal chunking size
        bulk_publish_notification_to_users(_user_id_generator(), msg)

        # now read them all back
        for user_id in range(1, 100):
            notifications = get_notifications_for_user(user_id)

            self.assertTrue(isinstance(notifications, list))
            self.assertEqual(len(notifications), 1)
            self.assertTrue(isinstance(notifications[0], UserNotification))
示例#3
0
def publish_course_notifications_task(course_id, notification_msg, exclude_user_ids=None):  # pylint: disable=invalid-name
    """
    This function will call the edx_notifications api method "bulk_publish_notification_to_users"
    and run as a new Celery task.
    """
    # get the enrolled and active user_id list for this course.
    user_ids = CourseEnrollment.objects.values_list('user_id', flat=True).filter(
        is_active=1,
        course_id=course_id
    )

    try:
        bulk_publish_notification_to_users(user_ids, notification_msg, exclude_user_ids=exclude_user_ids)
        # if we have a course announcement notification publish it to urban airship too
        if notification_msg.msg_type.name == 'open-edx.studio.announcements.new-announcement':
            # fetch all active mobile apps to send notifications to all apps
            mobile_apps = MobileApp.objects.filter(is_active=True)
            for mobile_app in mobile_apps:
                channel_context = {
                    "api_credentials": mobile_app.get_api_keys()
                }
                preferred_channel = mobile_app.get_notification_provider_name()
                if preferred_channel:
                    bulk_publish_notification_to_users(
                        user_ids,
                        notification_msg,
                        exclude_user_ids=exclude_user_ids,
                        preferred_channel=preferred_channel,
                        channel_context=channel_context
                    )
    except Exception, ex:
        # Notifications are never critical, so we don't want to disrupt any
        # other logic processing. So log and continue.
        log.exception(ex)
示例#4
0
def publish_course_notifications_task(course_id,
                                      notification_msg,
                                      exclude_user_ids=None):  # pylint: disable=invalid-name
    """
    This function will call the edx_notifications api method "bulk_publish_notification_to_users"
    and run as a new Celery task.
    """
    # get the enrolled and active user_id list for this course.
    user_ids = CourseEnrollment.objects.values_list(
        'user_id', flat=True).filter(is_active=1, course_id=course_id)

    try:
        bulk_publish_notification_to_users(user_ids,
                                           notification_msg,
                                           exclude_user_ids=exclude_user_ids)
        # if we have a course announcement notification publish it to urban airship too
        if notification_msg.msg_type.name == 'open-edx.studio.announcements.new-announcement':
            # fetch all active mobile apps to send notifications to all apps
            mobile_apps = MobileApp.objects.filter(is_active=True)
            for mobile_app in mobile_apps:
                channel_context = {
                    "api_credentials": mobile_app.get_api_keys()
                }
                preferred_channel = mobile_app.get_notification_provider_name()
                if preferred_channel:
                    bulk_publish_notification_to_users(
                        user_ids,
                        notification_msg,
                        exclude_user_ids=exclude_user_ids,
                        preferred_channel=preferred_channel,
                        channel_context=channel_context)
    except Exception as ex:
        # Notifications are never critical, so we don't want to disrupt any
        # other logic processing. So log and continue.
        log.exception(ex)
示例#5
0
    def test_bulk_publish_generator(self):
        """
        Make sure we can bulk publish to a number of users
        passing in a generator function
        """

        msg = NotificationMessage(namespace="test-runner", msg_type=self.msg_type, payload={"foo": "bar"})

        def _user_id_generator():
            """
            Just spit our an generator that goes from 1 to 100
            """
            for user_id in range(1, 100):
                yield user_id

        # now send to more than our internal chunking size
        bulk_publish_notification_to_users(_user_id_generator(), msg)

        # now read them all back
        for user_id in range(1, 100):
            notifications = get_notifications_for_user(user_id)

            self.assertTrue(isinstance(notifications, list))
            self.assertEqual(len(notifications), 1)
            self.assertTrue(isinstance(notifications[0], UserNotification))
示例#6
0
    def test_bulk_publish_list(self):
        """
        Make sure we can bulk publish to a number of users
        passing in a list
        """

        msg = NotificationMessage(
            namespace='test-runner',
            msg_type=self.msg_type,
            payload={
                'foo': 'bar'
            }
        )

        # now send to more than our internal chunking size
        bulk_publish_notification_to_users(
            list(range(1, const.NOTIFICATION_BULK_PUBLISH_CHUNK_SIZE * 2 + 1)),
            msg
        )

        # now read them all back
        for user_id in range(1, const.NOTIFICATION_BULK_PUBLISH_CHUNK_SIZE * 2 + 1):
            notifications = get_notifications_for_user(user_id)

            self.assertTrue(isinstance(notifications, list))
            self.assertEqual(len(notifications), 1)
            self.assertTrue(isinstance(notifications[0], UserNotification))
示例#7
0
    def test_bulk_publish_bad_type(self):
        """
        Make sure we have to pass in the right type
        """
        msg = NotificationMessage(namespace="test-runner", msg_type=self.msg_type, payload={"foo": "bar"})

        with self.assertRaises(TypeError):
            bulk_publish_notification_to_users("this should fail", msg)
示例#8
0
    def test_bulk_publish_bad_type(self):
        """
        Make sure we have to pass in the right type
        """
        msg = NotificationMessage(namespace='test-runner',
                                  msg_type=self.msg_type,
                                  payload={'foo': 'bar'})

        with self.assertRaises(TypeError):
            bulk_publish_notification_to_users("this should fail", msg)
示例#9
0
 def test_bulk_user_notification(self, mock_ua_push_api):
     """
     Test publish notification to list of users
     """
     mock_ua_push_api.return_value = {'ok': 'true'}
     response = bulk_publish_notification_to_users([10, 11, 12], self.msg, preferred_channel='urban-airship')
     self.assertEqual(response['ok'], 'true')
示例#10
0
def _send_to_scoped_users(msg,
                          scope_name,
                          scope_context,
                          preferred_channel=None,
                          channel_context=None):
    """
    Helper method to send to a scoped set of users.
    scope_context contains all of the information
    that can be passed into a NotificationScopeResolver
    """

    # user_ids can be a list, a generator function, or a ValuesQuerySet/ValuesListQuerySet (Django ORM)
    user_ids = resolve_user_scope(scope_name, scope_context)

    if not user_ids:
        err_msg = (
            'Could not resolve distribution scope "{name}" with context {context}! '
            'Message id "{_id}" was not sent!').format(name=scope_name,
                                                       context=scope_context,
                                                       _id=msg.id)

        raise Exception(err_msg)

    # optional parameter to exclude certain
    # ids
    exclude_list = scope_context.get('exclude_user_ids')

    num_dispatched = bulk_publish_notification_to_users(
        user_ids,
        msg,
        exclude_user_ids=exclude_list,
        preferred_channel=preferred_channel,
        channel_context=channel_context)

    return num_dispatched
def publish_mobile_apps_notifications_task(user_ids, notification_msg,
                                           api_keys, provider):
    """
    This function will call the edx_notifications api method "bulk_publish_notification_to_users"
    and run as a new Celery task.
    """
    try:
        bulk_publish_notification_to_users(
            user_ids,
            notification_msg,
            preferred_channel=provider,
            channel_context={"api_credentials": api_keys})
    except Exception as ex:
        # Notifications are never critical, so we don't want to disrupt any
        # other logic processing. So log and continue.
        log.exception(ex)
 def test_bulk_dispatch_notification_count(self):  # pylint: disable=invalid-name
     """
     Test bulk dispatch notification using email channel count should be valid
     """
     count = bulk_publish_notification_to_users(
         [1001, 1002], self.msg, preferred_channel='triggered-email')
     self.assertEqual(count, 2)
示例#13
0
    def test_bulk_publish_orm_query(self):
        """
        Make sure we can bulk publish to a number of users
        passing in a resultset from a Django ORM query
        """

        # set up some test users in Django User's model
        User(username='******').save()
        User(username='******').save()
        User(username='******').save()

        msg = NotificationMessage(namespace='test-runner',
                                  msg_type=self.msg_type,
                                  payload={'foo': 'bar'})

        resultset = User.objects.values_list('id', flat=True).all()  # pylint: disable=no-member

        num_sent = bulk_publish_notification_to_users(resultset, msg)

        # make sure we sent 3
        self.assertEqual(num_sent, 3)

        # now read them back
        for user in User.objects.all():  # pylint: disable=no-member
            notifications = get_notifications_for_user(user.id)

            self.assertTrue(isinstance(notifications, list))
            self.assertEqual(len(notifications), 1)
            self.assertTrue(isinstance(notifications[0], UserNotification))
示例#14
0
def _send_to_scoped_users(msg, scope_name, scope_context, preferred_channel=None, channel_context=None):
    """
    Helper method to send to a scoped set of users.
    scope_context contains all of the information
    that can be passed into a NotificationScopeResolver
    """

    # user_ids can be a list, a generator function, or a ValuesQuerySet/ValuesListQuerySet (Django ORM)
    user_ids = resolve_user_scope(scope_name, scope_context)

    if not user_ids:
        err_msg = (
            'Could not resolve distribution scope "{name}" with context {context}! '
            'Message id "{_id}" was not sent!'
        ).format(name=scope_name, context=scope_context, _id=msg.id)

        raise Exception(err_msg)

    # optional parameter to exclude certain
    # ids
    exclude_list = scope_context.get('exclude_user_ids')

    num_dispatched = bulk_publish_notification_to_users(
        user_ids,
        msg,
        exclude_user_ids=exclude_list,
        preferred_channel=preferred_channel,
        channel_context=channel_context
    )

    return num_dispatched
示例#15
0
    def test_bulk_publish_orm_query(self):
        """
        Make sure we can bulk publish to a number of users
        passing in a resultset from a Django ORM query
        """

        # set up some test users in Django User's model
        User(username="******").save()
        User(username="******").save()
        User(username="******").save()

        msg = NotificationMessage(namespace="test-runner", msg_type=self.msg_type, payload={"foo": "bar"})

        resultset = User.objects.values_list("id", flat=True).all()

        num_sent = bulk_publish_notification_to_users(resultset, msg)

        # make sure we sent 3
        self.assertEqual(num_sent, 3)

        # now read them back
        for user in User.objects.all():
            notifications = get_notifications_for_user(user.id)

            self.assertTrue(isinstance(notifications, list))
            self.assertEqual(len(notifications), 1)
            self.assertTrue(isinstance(notifications[0], UserNotification))
示例#16
0
def publish_course_group_notification_task(course_group_id, notification_msg, exclude_user_ids=None):  # pylint: disable=invalid-name
    """
    This function will call the edx_notifications api method "bulk_publish_notification_to_users"
    and run as a new Celery task in order to broadcast a message to an entire course cohort
    """

    # get the enrolled and active user_id list for this course.
    user_ids = CourseUserGroup.objects.values_list('users', flat=True).filter(
        id=course_group_id
    )

    try:
        bulk_publish_notification_to_users(user_ids, notification_msg, exclude_user_ids=exclude_user_ids)
    except Exception, ex:  # pylint: disable=broad-except
        # Notifications are never critical, so we don't want to disrupt any
        # other logic processing. So log and continue.
        log.exception(ex)
示例#17
0
def publish_course_group_notification_task(course_group_id, notification_msg, exclude_user_ids=None):  # pylint: disable=invalid-name
    """
    This function will call the edx_notifications api method "bulk_publish_notification_to_users"
    and run as a new Celery task in order to broadcast a message to an entire course cohort
    """

    # get the enrolled and active user_id list for this course.
    user_ids = CourseUserGroup.objects.values_list('users', flat=True).filter(
        id=course_group_id
    )

    try:
        bulk_publish_notification_to_users(user_ids, notification_msg, exclude_user_ids=exclude_user_ids)
    except Exception as ex:  # pylint: disable=broad-except
        # Notifications are never critical, so we don't want to disrupt any
        # other logic processing. So log and continue.
        log.exception(ex)
示例#18
0
 def test_tag_group_notification(self, mock_ua_push_api):
     """
     Test publish notification to a tag group
     """
     mock_ua_push_api.return_value = {'ok': 'true'}
     self.msg.payload['open_url'] = 'http://example.com'
     self.msg.payload['tag_group'] = 'enrollments'
     response = bulk_publish_notification_to_users([], self.msg, preferred_channel='urban-airship')
     self.assertTrue(response)
     self.assertEqual(response['ok'], 'true')
示例#19
0
    def test_bulk_publish_list(self):
        """
        Make sure we can bulk publish to a number of users
        passing in a list
        """

        msg = NotificationMessage(namespace="test-runner", msg_type=self.msg_type, payload={"foo": "bar"})

        # now send to more than our internal chunking size
        bulk_publish_notification_to_users(
            [user_id for user_id in range(1, const.NOTIFICATION_BULK_PUBLISH_CHUNK_SIZE * 2 + 1)], msg
        )

        # now read them all back
        for user_id in range(1, const.NOTIFICATION_BULK_PUBLISH_CHUNK_SIZE * 2 + 1):
            notifications = get_notifications_for_user(user_id)

            self.assertTrue(isinstance(notifications, list))
            self.assertEqual(len(notifications), 1)
            self.assertTrue(isinstance(notifications[0], UserNotification))
示例#20
0
    def test_bulk_publish_list_exclude(self):
        """
        Make sure we can bulk publish to a number of users
        passing in a list, and also pass in an exclusion list to
        make sure the people in the exclude list does not get
        the notification
        """

        msg = NotificationMessage(namespace="test-runner", msg_type=self.msg_type, payload={"foo": "bar"})

        user_ids = [user_id for user_id in range(1, const.NOTIFICATION_BULK_PUBLISH_CHUNK_SIZE * 2 + 1)]
        exclude_user_ids = [user_id for user_id in range(1, const.NOTIFICATION_BULK_PUBLISH_CHUNK_SIZE * 2 + 1, 2)]

        # now send to more than our internal chunking size
        bulk_publish_notification_to_users(user_ids, msg, exclude_user_ids=exclude_user_ids)

        # now read them all back
        for user_id in range(1, const.NOTIFICATION_BULK_PUBLISH_CHUNK_SIZE * 2 + 1):
            notifications = get_notifications_for_user(user_id)

            self.assertTrue(isinstance(notifications, list))
            self.assertEqual(len(notifications), 1 if user_id not in exclude_user_ids else 0)
            if user_id not in exclude_user_ids:
                self.assertTrue(isinstance(notifications[0], UserNotification))
 def test_bulk_dispatch_notification_count(self):  # pylint: disable=invalid-name
     """
     Test bulk dispatch notification using email channel count should be valid
     """
     count = bulk_publish_notification_to_users([1001, 1002], self.msg, preferred_channel="triggered-email")
     self.assertEqual(count, 2)