def test_user_message_does_not_exist(self):
     # type: () -> None
     missed_message = {'message_id': 100}
     with mock.patch('logging.error') as mock_logger:
         apn.handle_push_notification(self.user_profile.id, missed_message)
         mock_logger.assert_called_with("Could not find UserMessage with "
                                        "message_id 100")
示例#2
0
    def consume(self, event: Dict[str, Any]) -> None:
        try:
            if event.get("type", "add") == "remove":
                message_ids = event.get("message_ids")
                if message_ids is None:
                    # TODO/compatibility: Previously, we sent only one `message_id` in
                    # a payload for notification remove events. This was later changed
                    # to send a list of `message_ids` (with that field name), but we need
                    # compatibility code for events present in the queue during upgrade.
                    # Remove this when one can no longer upgrade from 1.9.2 (or earlier)
                    # to any version after 2.0.0
                    message_ids = [event["message_id"]]
                handle_remove_push_notification(event["user_profile_id"],
                                                message_ids)
            else:
                handle_push_notification(event["user_profile_id"], event)
        except PushNotificationBouncerRetryLaterError:

            def failure_processor(event: Dict[str, Any]) -> None:
                logger.warning(
                    "Maximum retries exceeded for trigger:%s event:push_notification",
                    event["user_profile_id"],
                )

            retry_event(self.queue_name, event, failure_processor)
    def test_send_notifications_to_bouncer(self):
        # type: () -> None
        user_profile = self.example_user('hamlet')
        message = self.get_message(Recipient.PERSONAL, type_id=1)
        UserMessage.objects.create(
            user_profile=user_profile,
            message=message
        )

        missed_message = {
            'message_id': message.id,
            'trigger': 'private_message',
        }
        with self.settings(PUSH_NOTIFICATION_BOUNCER_URL=True), \
                mock.patch('zerver.lib.push_notifications.get_apns_payload',
                           return_value={'apns': True}), \
                mock.patch('zerver.lib.push_notifications.get_gcm_payload',
                           return_value={'gcm': True}), \
                mock.patch('zerver.lib.push_notifications'
                           '.send_notifications_to_bouncer') as mock_send:
            apn.handle_push_notification(user_profile.id, missed_message)
            mock_send.assert_called_with(user_profile.id,
                                         {'apns': True},
                                         {'gcm': True},
                                         )
示例#4
0
 def consume(self, data: Mapping[str, Any]) -> None:
     if data.get("type", "add") == "remove":
         message_ids = data.get('message_ids')
         if message_ids is None:  # legacy task across an upgrade
             message_ids = [data['message_id']]
         handle_remove_push_notification(data['user_profile_id'], message_ids)
     else:
         handle_push_notification(data['user_profile_id'], data)
示例#5
0
 def consume(self, data: Mapping[str, Any]) -> None:
     if data.get("type", "add") == "remove":
         message_ids = data.get('message_ids')
         if message_ids is None:  # legacy task across an upgrade
             message_ids = [data['message_id']]
         handle_remove_push_notification(data['user_profile_id'], message_ids)
     else:
         handle_push_notification(data['user_profile_id'], data)
 def test_disabled_notifications(self):
     # type: () -> None
     user_profile = self.example_user('hamlet')
     user_profile.enable_online_email_notifications = False
     user_profile.enable_online_push_notifications = False
     user_profile.enable_offline_email_notifications = False
     user_profile.enable_offline_push_notifications = False
     user_profile.enable_stream_push_notifications = False
     user_profile.save()
     apn.handle_push_notification(user_profile.id, {})
    def test_end_to_end(self):
        # type: () -> None
        remote_gcm_tokens = [u'dddd']
        for token in remote_gcm_tokens:
            RemotePushDeviceToken.objects.create(
                kind=RemotePushDeviceToken.GCM,
                token=apn.hex_to_b64(token),
                user_id=self.user_profile.id,
                server=RemoteZulipServer.objects.get(uuid=self.server_uuid),
            )

        message = self.get_message(Recipient.PERSONAL, type_id=1)
        UserMessage.objects.create(
            user_profile=self.user_profile,
            message=message
        )

        missed_message = {
            'message_id': message.id,
            'triggers': {
                'private_message': True,
                'mentioned': False,
                'stream_push_notify': False,
            },
        }
        with self.settings(PUSH_NOTIFICATION_BOUNCER_URL=''), \
                mock.patch('zerver.lib.push_notifications.requests.request',
                           side_effect=self.bounce_request), \
                mock.patch('zerver.lib.push_notifications.gcm') as mock_gcm, \
                mock.patch('zerver.lib.push_notifications._apns_client') as mock_apns, \
                mock.patch('logging.info') as mock_info, \
                mock.patch('logging.warning'):
            apns_devices = [
                (apn.b64_to_hex(device.token), device.ios_app_id, device.token)
                for device in RemotePushDeviceToken.objects.filter(
                    kind=PushDeviceToken.APNS)
            ]
            gcm_devices = [
                (apn.b64_to_hex(device.token), device.ios_app_id, device.token)
                for device in RemotePushDeviceToken.objects.filter(
                    kind=PushDeviceToken.GCM)
            ]
            mock_gcm.json_request.return_value = {
                'success': {gcm_devices[0][2]: message.id}}
            mock_apns.get_notification_result.return_value = 'Success'
            apn.handle_push_notification(self.user_profile.id, missed_message)
            for _, _, token in apns_devices:
                mock_info.assert_any_call(
                    "APNs: Success sending for user %d to device %s",
                    self.user_profile.id, token)
            for _, _, token in gcm_devices:
                mock_info.assert_any_call(
                    "GCM: Sent %s as %s" % (token, message.id))
示例#8
0
    def test_read_message(self):
        # type: () -> None
        user_profile = self.example_user('hamlet')
        message = self.get_message(Recipient.PERSONAL, type_id=1)
        UserMessage.objects.create(user_profile=user_profile,
                                   flags=UserMessage.flags.read,
                                   message=message)

        missed_message = {
            'message_id': message.id,
            'trigger': 'private_message',
        }
        apn.handle_push_notification(user_profile.id, missed_message)
    def test_end_to_end_connection_error(self):
        # type: () -> None
        remote_gcm_tokens = [u'dddd']
        for token in remote_gcm_tokens:
            RemotePushDeviceToken.objects.create(
                kind=RemotePushDeviceToken.GCM,
                token=apn.hex_to_b64(token),
                user_id=self.user_profile.id,
                server=RemoteZulipServer.objects.get(uuid=self.server_uuid),
            )

        message = self.get_message(Recipient.PERSONAL, type_id=1)
        UserMessage.objects.create(
            user_profile=self.user_profile,
            message=message
        )

        def retry(queue_name, event, processor):
            # type: (Any, Any, Any) -> None
            apn.handle_push_notification(event['user_profile_id'], event)

        missed_message = {
            'user_profile_id': self.user_profile.id,
            'message_id': message.id,
            'triggers': {
                'private_message': True,
                'mentioned': False,
                'stream_push_notify': False,
            },
        }
        with self.settings(PUSH_NOTIFICATION_BOUNCER_URL=''), \
                mock.patch('zerver.lib.push_notifications.requests.request',
                           side_effect=self.bounce_request), \
                mock.patch('zerver.lib.push_notifications.gcm') as mock_gcm, \
                mock.patch('zerver.lib.push_notifications.send_notifications_to_bouncer',
                           side_effect=requests.ConnectionError), \
                mock.patch('zerver.lib.queue.queue_json_publish',
                           side_effect=retry) as mock_retry, \
                mock.patch('logging.warning') as mock_warn:
            gcm_devices = [
                (apn.b64_to_hex(device.token), device.ios_app_id, device.token)
                for device in RemotePushDeviceToken.objects.filter(
                    kind=PushDeviceToken.GCM)
            ]
            mock_gcm.json_request.return_value = {
                'success': {gcm_devices[0][2]: message.id}}
            apn.handle_push_notification(self.user_profile.id, missed_message)
            self.assertEqual(mock_retry.call_count, 3)
            mock_warn.assert_called_with("Maximum retries exceeded for "
                                         "trigger:%s event:"
                                         "push_notification" % (self.user_profile.id,))
    def test_end_to_end(self):
        # type: () -> None
        remote_gcm_tokens = [u'dddd']
        for token in remote_gcm_tokens:
            RemotePushDeviceToken.objects.create(
                kind=RemotePushDeviceToken.GCM,
                token=apn.hex_to_b64(token),
                user_id=self.user_profile.id,
                server=RemoteZulipServer.objects.get(uuid=self.server_uuid),
            )

        message = self.get_message(Recipient.PERSONAL, type_id=1)
        UserMessage.objects.create(
            user_profile=self.user_profile,
            message=message
        )

        missed_message = {
            'message_id': message.id,
            'trigger': 'private_message',
        }
        with self.settings(PUSH_NOTIFICATION_BOUNCER_URL=''), \
                mock.patch('zerver.lib.push_notifications.requests.request',
                           side_effect=self.bounce_request), \
                mock.patch('zerver.lib.push_notifications.gcm') as mock_gcm, \
                mock.patch('zerver.lib.push_notifications._apns_client') as mock_apns, \
                mock.patch('logging.info') as mock_info, \
                mock.patch('logging.warning'):
            apns_devices = [
                (apn.b64_to_hex(device.token), device.ios_app_id, device.token)
                for device in RemotePushDeviceToken.objects.filter(
                    kind=PushDeviceToken.APNS)
            ]
            gcm_devices = [
                (apn.b64_to_hex(device.token), device.ios_app_id, device.token)
                for device in RemotePushDeviceToken.objects.filter(
                    kind=PushDeviceToken.GCM)
            ]
            mock_gcm.json_request.return_value = {
                'success': {gcm_devices[0][2]: message.id}}
            mock_apns.get_notification_result.return_value = 'Success'
            apn.handle_push_notification(self.user_profile.id, missed_message)
            for _, _, token in apns_devices:
                mock_info.assert_any_call(
                    "APNs: Success sending for user %d to device %s",
                    self.user_profile.id, token)
            for _, _, token in gcm_devices:
                mock_info.assert_any_call(
                    "GCM: Sent %s as %s" % (token, message.id))
示例#11
0
 def consume(self, event: Dict[str, Any]) -> None:
     try:
         if event.get("type", "add") == "remove":
             message_ids = event.get('message_ids')
             if message_ids is None:  # legacy task across an upgrade
                 message_ids = [event['message_id']]
             handle_remove_push_notification(event['user_profile_id'], message_ids)
         else:
             handle_push_notification(event['user_profile_id'], event)
     except PushNotificationBouncerRetryLaterError:
         def failure_processor(event: Dict[str, Any]) -> None:
             logger.warning(
                 "Maximum retries exceeded for trigger:%s event:push_notification",
                 event['user_profile_id'])
         retry_event(self.queue_name, event, failure_processor)
    def test_read_message(self):
        # type: () -> None
        user_profile = self.example_user('hamlet')
        message = self.get_message(Recipient.PERSONAL, type_id=1)
        UserMessage.objects.create(
            user_profile=user_profile,
            flags=UserMessage.flags.read,
            message=message
        )

        missed_message = {
            'message_id': message.id,
            'trigger': 'private_message',
        }
        apn.handle_push_notification(user_profile.id, missed_message)
    def test_end_to_end_connection_error(self):
        # type: () -> None
        remote_gcm_tokens = [u'dddd']
        for token in remote_gcm_tokens:
            RemotePushDeviceToken.objects.create(
                kind=RemotePushDeviceToken.GCM,
                token=apn.hex_to_b64(token),
                user_id=self.user_profile.id,
                server=RemoteZulipServer.objects.get(uuid=self.server_uuid),
            )

        message = self.get_message(Recipient.PERSONAL, type_id=1)
        UserMessage.objects.create(
            user_profile=self.user_profile,
            message=message
        )

        def retry(queue_name, event, processor):
            # type: (Any, Any, Any) -> None
            apn.handle_push_notification(event['user_profile_id'], event)

        missed_message = {
            'user_profile_id': self.user_profile.id,
            'message_id': message.id,
            'trigger': 'private_message',
        }
        with self.settings(PUSH_NOTIFICATION_BOUNCER_URL=''), \
                mock.patch('zerver.lib.push_notifications.requests.request',
                           side_effect=self.bounce_request), \
                mock.patch('zerver.lib.push_notifications.gcm') as mock_gcm, \
                mock.patch('zerver.lib.push_notifications.send_notifications_to_bouncer',
                           side_effect=requests.ConnectionError), \
                mock.patch('zerver.lib.queue.queue_json_publish',
                           side_effect=retry) as mock_retry, \
                mock.patch('logging.warning') as mock_warn:
            gcm_devices = [
                (apn.b64_to_hex(device.token), device.ios_app_id, device.token)
                for device in RemotePushDeviceToken.objects.filter(
                    kind=PushDeviceToken.GCM)
            ]
            mock_gcm.json_request.return_value = {
                'success': {gcm_devices[0][2]: message.id}}
            apn.handle_push_notification(self.user_profile.id, missed_message)
            self.assertEqual(mock_retry.call_count, 3)
            mock_warn.assert_called_with("Maximum retries exceeded for "
                                         "trigger:%s event:"
                                         "push_notification" % (self.user_profile.id,))
示例#14
0
    def test_non_bouncer_push(self):
        # type: () -> None
        message = self.get_message(Recipient.PERSONAL, type_id=1)
        UserMessage.objects.create(
            user_profile=self.user_profile,
            message=message
        )

        for token in [u'dddd']:
            PushDeviceToken.objects.create(
                kind=PushDeviceToken.GCM,
                token=apn.hex_to_b64(token),
                user=self.user_profile)

        android_devices = list(
            PushDeviceToken.objects.filter(user=self.user_profile,
                                           kind=PushDeviceToken.GCM))

        apple_devices = list(
            PushDeviceToken.objects.filter(user=self.user_profile,
                                           kind=PushDeviceToken.APNS))

        missed_message = {
            'message_id': message.id,
            'triggers': {
                'private_message': True,
                'mentioned': False,
                'stream_push_notify': False,
            },
        }
        with mock.patch('zerver.lib.push_notifications.get_apns_payload',
                        return_value={'apns': True}), \
                mock.patch('zerver.lib.push_notifications.get_gcm_payload',
                           return_value={'gcm': True}), \
                mock.patch('zerver.lib.push_notifications'
                           '.send_apple_push_notification') as mock_send_apple, \
                mock.patch('zerver.lib.push_notifications'
                           '.send_android_push_notification') as mock_send_android:

            apn.handle_push_notification(self.user_profile.id, missed_message)
            mock_send_apple.assert_called_with(self.user_profile.id,
                                               apple_devices,
                                               {'apns': True})
            mock_send_android.assert_called_with(android_devices,
                                                 {'gcm': True})
    def test_non_bouncer_push(self):
        # type: () -> None
        message = self.get_message(Recipient.PERSONAL, type_id=1)
        UserMessage.objects.create(
            user_profile=self.user_profile,
            message=message
        )

        for token in [u'dddd']:
            PushDeviceToken.objects.create(
                kind=PushDeviceToken.GCM,
                token=apn.hex_to_b64(token),
                user=self.user_profile)

        android_devices = list(
            PushDeviceToken.objects.filter(user=self.user_profile,
                                           kind=PushDeviceToken.GCM))

        apple_devices = list(
            PushDeviceToken.objects.filter(user=self.user_profile,
                                           kind=PushDeviceToken.APNS))

        missed_message = {
            'message_id': message.id,
            'trigger': 'private_message',
        }
        with mock.patch('zerver.lib.push_notifications.get_apns_payload',
                        return_value={'apns': True}), \
                mock.patch('zerver.lib.push_notifications.get_gcm_payload',
                           return_value={'gcm': True}), \
                mock.patch('zerver.lib.push_notifications'
                           '.send_apple_push_notification') as mock_send_apple, \
                mock.patch('zerver.lib.push_notifications'
                           '.send_android_push_notification') as mock_send_android:

            apn.handle_push_notification(self.user_profile.id, missed_message)
            mock_send_apple.assert_called_with(self.user_profile.id,
                                               apple_devices,
                                               {'apns': True})
            mock_send_android.assert_called_with(android_devices,
                                                 {'gcm': True})
示例#16
0
 def consume(self, data: Mapping[str, Any]) -> None:
     if data.get("type", "add") == "remove":
         handle_remove_push_notification(data['user_profile_id'],
                                         data['message_id'])
     else:
         handle_push_notification(data['user_profile_id'], data)
示例#17
0
 def consume(self, data):
     # type: (Mapping[str, Any]) -> None
     handle_push_notification(data['user_profile_id'], data)
示例#18
0
 def consume(self, data):
     # type: (Mapping[str, Any]) -> None
     handle_push_notification(data['user_profile_id'], data)
示例#19
0
 def consume(self, data: Mapping[str, Any]) -> None:
     if data.get("type", "add") == "remove":
         handle_remove_push_notification(data['user_profile_id'], data['message_id'])
     else:
         handle_push_notification(data['user_profile_id'], data)
 def retry(queue_name, event, processor):
     # type: (Any, Any, Any) -> None
     apn.handle_push_notification(event['user_profile_id'], event)