# Path: autopush/exceptions.py
# class RouterException(AutopushException):
#     """Exception if routing has failed, may include a custom status_code and
#     body to write to the response.
# 
#     """
#     def __init__(self, message, status_code=500, response_body="",
#                  router_data=None, headers=None, log_exception=True,
#                  errno=None, logged_status=None, **kwargs):
#         """Create a new RouterException"""
#         super(AutopushException, self).__init__(message)
#         self.status_code = status_code
#         self.headers = {} if headers is None else headers
#         self.log_exception = log_exception
#         self.response_body = response_body or message
#         self.errno = errno
#         self.logged_status = logged_status
#         self.extra = kwargs
# 
# Path: autopush/router/fcmv1client.py
# class FCMv1(object):
#     def __init__(self,
#                  project_id,
#                  service_cred_path=None,
#                  logger=None,
#                  metrics=None,
#                  **options):
#         self.project_id = project_id
#         self.endpoint = ("https://fcm.googleapis.com/v1/"
#                          "projects/{}/messages:send".format(self.project_id))
# 
#         self.token = None
#         self.metrics = metrics
#         self.logger = logger or Logger()
#         self._options = options
#         if service_cred_path:
#             self.svc_cred = ServiceAccountCredentials.from_json_keyfile_name(
#                 service_cred_path,
#                 ["https://www.googleapis.com/auth/firebase.messaging"])
#         self._sender = treq.post
# 
#     def _get_access_token(self):
#         return self.svc_cred.get_access_token()
# 
#     def _build_message(self, token, notif):
#         msg = {
#             "token": token,
#             # Specify the various formats (we use android only)
#             "android": {
#                 # TTL is a duration string e.g. ("60s")
#                 "ttl": str(int(notif.get("ttl", 0)))+"s",
#                 "data": notif.get("data_message")
#             },
#         }
#         # Wrap up the whole thing in a "message" tag.
#         return {"message": msg}
# 
#     def process(self, response, payload=None):
#         if response.code == 401:
#             raise FCMAuthenticationError("Authentication Error")
# 
#         result = Result(response)
# 
#         d = response.text()
#         d.addCallback(result.parse_response)
#         return d
# 
#     def error(self, failure):
#         if isinstance(failure.value,
#                       (FCMAuthenticationError, FCMNotFoundError,
#                        TimeoutError, ConnectError)):
#             raise failure.value
#         self.logger.error("FCMv1Client failure: {}".format(failure.value))
#         raise RouterException("Server error: {}".format(failure.value))
# 
#     def send(self, token, payload):
#         atoken = self._get_access_token()
#         headers = {
#             'Authorization': 'Bearer {}'.format(atoken.access_token),
#             'Content-Type': 'application/json; UTF-8'
#         }
#         message = self._build_message(token, payload)
#         if 'timeout' not in self._options:
#             self._options['timeout'] = DEFAULT_ROUTER_TIMEOUT
# 
#         d = self._sender(
#             url=self.endpoint,
#             headers=headers,
#             data=json.dumps(message),
#             **self._options
#         )
#         d.addCallback(self.process, payload)
#         d.addErrback(self.error)
#         return d
# 
# class FCMAuthenticationError(Exception):
#     pass


import json
import pytest
import treq
from mock import Mock
from oauth2client.service_account import ServiceAccountCredentials
from twisted.internet.defer import Deferred, inlineCallbacks
from twisted.trial import unittest
from twisted.web.http_headers import Headers
from autopush.exceptions import RouterException
from autopush.router.fcmv1client import FCMv1, FCMAuthenticationError
                                          u'a valid FCM registration token')}],
                        u'@type': u'type.googleapis.com/google.rpc.BadRequest'}
                ]
            }
        }

    @inlineCallbacks
    def test_send(self):
        content = json.dumps(self._success)
        self._m_resp_text.callback(content)
        self._m_request.callback(self._m_response)
        result = yield self.fcm.send("token", self.m_payload)
        assert result.success == 1

    @inlineCallbacks
    def test_bad_reply(self):
        self._m_response.code = 400
        content = json.dumps("Invalid JSON")
        self._m_resp_text.callback(content)
        self._m_request.callback(self._m_response)
        with pytest.raises(RouterException) as ex:
            yield self.fcm.send("token", self.m_payload)
        assert ex.value.status_code == 500

    @inlineCallbacks
    def test_fail_400(self):
        self._m_response.code = 400
        content = json.dumps(self._failure)
        self._m_resp_text.callback(content)
        self._m_request.callback(self._m_response)

# Path: autopush/exceptions.py
# class RouterException(AutopushException):
#     """Exception if routing has failed, may include a custom status_code and
#     body to write to the response.
# 
#     """
#     def __init__(self, message, status_code=500, response_body="",
#                  router_data=None, headers=None, log_exception=True,
#                  errno=None, logged_status=None, **kwargs):
#         """Create a new RouterException"""
#         super(AutopushException, self).__init__(message)
#         self.status_code = status_code
#         self.headers = {} if headers is None else headers
#         self.log_exception = log_exception
#         self.response_body = response_body or message
#         self.errno = errno
#         self.logged_status = logged_status
#         self.extra = kwargs
# 
# Path: autopush/router/fcmv1client.py
# class FCMv1(object):
#     def __init__(self,
#                  project_id,
#                  service_cred_path=None,
#                  logger=None,
#                  metrics=None,
#                  **options):
#         self.project_id = project_id
#         self.endpoint = ("https://fcm.googleapis.com/v1/"
#                          "projects/{}/messages:send".format(self.project_id))
# 
#         self.token = None
#         self.metrics = metrics
#         self.logger = logger or Logger()
#         self._options = options
#         if service_cred_path:
#             self.svc_cred = ServiceAccountCredentials.from_json_keyfile_name(
#                 service_cred_path,
#                 ["https://www.googleapis.com/auth/firebase.messaging"])
#         self._sender = treq.post
# 
#     def _get_access_token(self):
#         return self.svc_cred.get_access_token()
# 
#     def _build_message(self, token, notif):
#         msg = {
#             "token": token,
#             # Specify the various formats (we use android only)
#             "android": {
#                 # TTL is a duration string e.g. ("60s")
#                 "ttl": str(int(notif.get("ttl", 0)))+"s",
#                 "data": notif.get("data_message")
#             },
#         }
#         # Wrap up the whole thing in a "message" tag.
#         return {"message": msg}
# 
#     def process(self, response, payload=None):
#         if response.code == 401:
#             raise FCMAuthenticationError("Authentication Error")
# 
#         result = Result(response)
# 
#         d = response.text()
#         d.addCallback(result.parse_response)
#         return d
# 
#     def error(self, failure):
#         if isinstance(failure.value,
#                       (FCMAuthenticationError, FCMNotFoundError,
#                        TimeoutError, ConnectError)):
#             raise failure.value
#         self.logger.error("FCMv1Client failure: {}".format(failure.value))
#         raise RouterException("Server error: {}".format(failure.value))
# 
#     def send(self, token, payload):
#         atoken = self._get_access_token()
#         headers = {
#             'Authorization': 'Bearer {}'.format(atoken.access_token),
#             'Content-Type': 'application/json; UTF-8'
#         }
#         message = self._build_message(token, payload)
#         if 'timeout' not in self._options:
#             self._options['timeout'] = DEFAULT_ROUTER_TIMEOUT
# 
#         d = self._sender(
#             url=self.endpoint,
#             headers=headers,
#             data=json.dumps(message),
#             **self._options
#         )
#         d.addCallback(self.process, payload)
#         d.addErrback(self.error)
#         return d
# 
# class FCMAuthenticationError(Exception):
#     pass


# Path: autopush/tests/test_fcmclient.py
import json
import pytest
import treq
from mock import Mock
from oauth2client.service_account import ServiceAccountCredentials
from twisted.internet.defer import Deferred, inlineCallbacks
from twisted.trial import unittest
from twisted.web.http_headers import Headers
from autopush.exceptions import RouterException
from autopush.router.fcmv1client import FCMv1, FCMAuthenticationError

                                          u'a valid FCM registration token')}],
                        u'@type': u'type.googleapis.com/google.rpc.BadRequest'}
                ]
            }
        }

    @inlineCallbacks
    def test_send(self):
        content = json.dumps(self._success)
        self._m_resp_text.callback(content)
        self._m_request.callback(self._m_response)
        result = yield self.fcm.send("token", self.m_payload)
        assert result.success == 1

    @inlineCallbacks
    def test_bad_reply(self):
        self._m_response.code = 400
        content = json.dumps("Invalid JSON")
        self._m_resp_text.callback(content)
        self._m_request.callback(self._m_response)
        with pytest.raises(RouterException) as ex:
            yield self.fcm.send("token", self.m_payload)
        assert ex.value.status_code == 500

    @inlineCallbacks
    def test_fail_400(self):
        self._m_response.code = 400
        content = json.dumps(self._failure)
        self._m_resp_text.callback(content)
        self._m_request.callback(self._m_response)

        with pytest.raises(RouterException) as ex: