示例#1
0
    def test_init(self, ffcm):
        conf = AutopushConfig(
            hostname="localhost",
            statsd_host=None,
        )

        def throw_auth(*args, **kwargs):
            raise Exception("oopsy")

        ffcm.side_effect = throw_auth
        with pytest.raises(IOError):
            FCMRouter(conf, {}, SinkMetrics())
示例#2
0
    def test_init(self, ffcm):
        settings = AutopushSettings(
            hostname="localhost",
            statsd_host=None,
        )

        def throw_auth(*args, **kwargs):
            raise Exception("oopsy")

        ffcm.side_effect = throw_auth
        with assert_raises(IOError):
            FCMRouter(settings, {})
示例#3
0
 def setUp(self, ffcm):
     conf = AutopushConfig(
         hostname="localhost",
         statsd_host=None,
     )
     self.fcm_config = {
         'max_data': 32,
         'ttl': 60,
         'senderID': 'test123',
         "auth": "12345678abcdefg"
     }
     self.fcm = ffcm
     self.router = FCMRouter(conf, self.fcm_config, SinkMetrics())
     self.headers = {
         "content-encoding": "aesgcm",
         "encryption": "test",
         "encryption-key": "test"
     }
     # Payloads are Base64-encoded.
     self.notif = WebPushNotification(uaid=uuid.UUID(dummy_uaid),
                                      channel_id=uuid.UUID(dummy_chid),
                                      data="q60d6g",
                                      headers=self.headers,
                                      ttl=200)
     self.notif.cleanup_headers()
     self.router_data = dict(router_data=dict(
         token="connect_data",
         creds=dict(senderID="test123", auth="12345678abcdefg")))
     mock_result = dict(
         multicast_id="",
         success=0,
         failure=0,
         canonical_ids=0,
         results=[dict()],
     )
     self.mock_result = mock_result
     ffcm.notify_single_device.return_value = mock_result
示例#4
0
class FCMRouterTestCase(unittest.TestCase):
    @patch("pyfcm.FCMNotification", spec=pyfcm.FCMNotification)
    def setUp(self, ffcm):
        conf = AutopushConfig(
            hostname="localhost",
            statsd_host=None,
        )
        self.fcm_config = {
            'max_data': 32,
            'ttl': 60,
            'senderID': 'test123',
            "auth": "12345678abcdefg"
        }
        self.fcm = ffcm
        self.router = FCMRouter(conf, self.fcm_config, SinkMetrics())
        self.headers = {
            "content-encoding": "aesgcm",
            "encryption": "test",
            "encryption-key": "test"
        }
        # Payloads are Base64-encoded.
        self.notif = WebPushNotification(uaid=uuid.UUID(dummy_uaid),
                                         channel_id=uuid.UUID(dummy_chid),
                                         data="q60d6g",
                                         headers=self.headers,
                                         ttl=200)
        self.notif.cleanup_headers()
        self.router_data = dict(router_data=dict(
            token="connect_data",
            creds=dict(senderID="test123", auth="12345678abcdefg")))
        mock_result = dict(
            multicast_id="",
            success=0,
            failure=0,
            canonical_ids=0,
            results=[dict()],
        )
        self.mock_result = mock_result
        ffcm.notify_single_device.return_value = mock_result

    def _check_error_call(self, exc, code):
        assert isinstance(exc, RouterException)
        assert exc.status_code == code
        assert self.router.fcm.notify_single_device.called
        self.flushLoggedErrors()

    @patch("pyfcm.FCMNotification", spec=pyfcm.FCMNotification)
    def test_init(self, ffcm):
        conf = AutopushConfig(
            hostname="localhost",
            statsd_host=None,
        )

        def throw_auth(*args, **kwargs):
            raise Exception("oopsy")

        ffcm.side_effect = throw_auth
        with pytest.raises(IOError):
            FCMRouter(conf, {}, SinkMetrics())

    def test_register(self):
        router_data = {"token": "test123"}
        self.router.register("uaid", router_data=router_data, app_id="test123")
        # Check the information that will be recorded for this user
        assert router_data == {
            "token": "test123",
            "creds": {
                "senderID": "test123",
                "auth": "12345678abcdefg"
            }
        }

    def test_register_bad(self):
        with pytest.raises(RouterException):
            self.router.register("uaid", router_data={}, app_id="invalid123")

    def test_route_notification(self):
        self.router.fcm = self.fcm
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(result):
            assert isinstance(result, RouterResponse)
            assert result.status_code == 201
            assert result.logged_status == 200
            assert "TTL" in result.headers
            assert self.router.fcm.notify_single_device.called
            # Make sure the data was encoded as base64
            args = self.router.fcm.notify_single_device.call_args[1]
            data = args['data_message']
            assert data['body'] == 'q60d6g'
            assert data['chid'] == dummy_chid
            assert data['enc'] == 'test'
            assert data['enckey'] == 'test'
            assert data['con'] == 'aesgcm'

        d.addCallback(check_results)
        return d

    def test_ttl_none(self):
        self.router.fcm = self.fcm
        self.notif = WebPushNotification(uaid=uuid.UUID(dummy_uaid),
                                         channel_id=uuid.UUID(dummy_chid),
                                         data="q60d6g",
                                         headers=self.headers,
                                         ttl=None)
        self.notif.cleanup_headers()
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(result):
            assert isinstance(result, RouterResponse)
            assert self.router.fcm.notify_single_device.called
            # Make sure the data was encoded as base64
            args = self.router.fcm.notify_single_device.call_args[1]
            data = args['data_message']
            assert data['body'] == 'q60d6g'
            assert data['chid'] == dummy_chid
            assert data['enc'] == 'test'
            assert data['enckey'] == 'test'
            assert data['con'] == 'aesgcm'
            # use the defined min TTL
            assert args['time_to_live'] == 60

        d.addCallback(check_results)
        return d

    def test_ttl_high(self):
        self.router.fcm = self.fcm
        self.notif = WebPushNotification(uaid=uuid.UUID(dummy_uaid),
                                         channel_id=uuid.UUID(dummy_chid),
                                         data="q60d6g",
                                         headers=self.headers,
                                         ttl=5184000)
        self.notif.cleanup_headers()
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(result):
            assert isinstance(result, RouterResponse)
            assert self.router.fcm.notify_single_device.called
            # Make sure the data was encoded as base64
            args = self.router.fcm.notify_single_device.call_args[1]
            data = args['data_message']
            assert data['body'] == 'q60d6g'
            assert data['chid'] == dummy_chid
            assert data['enc'] == 'test'
            assert data['enckey'] == 'test'
            assert data['con'] == 'aesgcm'
            # use the defined min TTL
            assert args['time_to_live'] == 2419200

        d.addCallback(check_results)
        return d

    def test_long_data(self):
        self.router.fcm = self.fcm
        bad_notif = WebPushNotification(
            uaid=uuid.UUID(dummy_uaid),
            channel_id=uuid.UUID(dummy_chid),
            data="\x01abcdefghijklmnopqrstuvwxyz0123456789",
            headers=self.headers,
            ttl=200,
            message_id=10,
        )
        self.notif.cleanup_headers()
        d = self.router.route_notification(bad_notif, self.router_data)

        def check_results(result):
            assert isinstance(result.value, RouterException)
            assert result.value.status_code == 413
            assert result.value.errno == 104

        d.addBoth(check_results)
        return d

    def test_route_crypto_notification(self):
        self.router.fcm = self.fcm
        del (self.notif.headers['encryption_key'])
        self.notif.headers['crypto_key'] = 'crypto'
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(result):
            assert isinstance(result, RouterResponse)
            assert self.router.fcm.notify_single_device.called

        d.addCallback(check_results)
        return d

    def test_router_notification_fcm_auth_error(self):
        def throw_auth(*args, **kwargs):
            raise pyfcm.errors.AuthenticationError()

        self.fcm.notify_single_device.side_effect = throw_auth
        self.router.fcm = self.fcm
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(fail):
            self._check_error_call(fail.value, 500)

        d.addBoth(check_results)
        return d

    def test_router_notification_fcm_other_error(self):
        def throw_other(*args, **kwargs):
            raise Exception("oh my!")

        self.fcm.notify_single_device.side_effect = throw_other
        self.router.fcm = self.fcm
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(fail):
            self._check_error_call(fail.value, 500)

        d.addBoth(check_results)
        return d

    def test_router_notification_connection_error(self):
        from requests.exceptions import ConnectionError

        def throw_other(*args, **kwargs):
            raise ConnectionError("oh my!")

        self.fcm.notify_single_device.side_effect = throw_other
        self.router.fcm = self.fcm
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(fail):
            self._check_error_call(fail.value, 502)

        d.addBoth(check_results)
        return d

    def test_router_notification_fcm_id_change(self):
        self.mock_result['canonical_ids'] = 1
        self.mock_result['results'][0] = {'registration_id': "new"}
        self.router.fcm = self.fcm
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(result):
            assert isinstance(result, RouterResponse)
            assert result.router_data == dict(token="new")
            assert self.router.fcm.notify_single_device.called

        d.addCallback(check_results)
        return d

    def test_router_notification_fcm_not_regged(self):
        self.mock_result['failure'] = 1
        self.mock_result['results'][0] = {'error': 'NotRegistered'}
        self.router.fcm = self.fcm
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(result):
            assert isinstance(result, RouterResponse)
            assert result.router_data == dict()
            assert self.router.fcm.notify_single_device.called

        d.addCallback(check_results)
        return d

    def test_router_notification_fcm_failed_items(self):
        self.mock_result['failure'] = 1
        self.mock_result['results'][0] = {'error': 'TopicsMessageRateExceeded'}
        self.router.fcm = self.fcm
        d = self.router.route_notification(self.notif, self.router_data)

        def check_results(fail):
            self._check_error_call(fail.value, 503)

        d.addBoth(check_results)
        return d

    def test_router_notification_fcm_no_auth(self):
        d = self.router.route_notification(self.notif,
                                           {"router_data": {
                                               "token": ""
                                           }})

        def check_results(fail):
            assert fail.value.status_code == 410

        d.addBoth(check_results)
        return d

    def test_amend(self):
        self.router.register(uaid="uaid",
                             router_data={"token": "test123"},
                             app_id="test123")
        resp = {"key": "value"}
        self.router.amend_endpoint_response(
            resp, self.router_data.get('router_data'))
        assert {"key": "value", "senderid": "test123"} == resp

    def test_register_invalid_token(self):
        with pytest.raises(RouterException):
            self.router.register(uaid="uaid",
                                 router_data={"token": "invalid"},
                                 app_id="invalid")