Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MatMaul committed May 17, 2024
1 parent dbb2029 commit 0481753
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 20 deletions.
19 changes: 10 additions & 9 deletions sygnal/gcmpushkin.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,6 @@ def __init__(self, name: str, sygnal: "Sygnal", config: Dict[str, Any]) -> None:
proxy_url_str=proxy_url,
)

# Use the fcm_options config dictionary as a foundation for the body;
# this lets the Sygnal admin choose custom FCM options
# (e.g. content_available).
self.base_request_body = self.get_config("fcm_options", dict, {})
if not isinstance(self.base_request_body, dict):
raise PushkinSetupException(
"Config field fcm_options, if set, must be a dictionary of options"
)

self.api_version = APIVersion.Legacy
version_str = self.get_config("api_version", str)
if not version_str:
Expand Down Expand Up @@ -224,6 +215,15 @@ def __init__(self, name: str, sygnal: "Sygnal", config: Dict[str, Any]) -> None:
session=session
)

# Use the fcm_options config dictionary as a foundation for the body;
# this lets the Sygnal admin choose custom FCM options
# (e.g. content_available).
self.base_request_body = self.get_config("fcm_options", dict, {})
if not isinstance(self.base_request_body, dict):
raise PushkinSetupException(
"Config field fcm_options, if set, must be a dictionary of options"
)

@classmethod
async def create(
cls, name: str, sygnal: "Sygnal", config: Dict[str, Any]
Expand Down Expand Up @@ -498,6 +498,7 @@ async def _get_auth_header(self) -> str:
:return: Needed content of the `Authorization` header
"""
print("_get_auth_header")
if self.api_version is APIVersion.Legacy:
return "key=%s" % (self.api_key,)
else:
Expand Down
57 changes: 46 additions & 11 deletions tests/test_gcm.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import tempfile
from typing import TYPE_CHECKING, Any, AnyStr, Dict, List, Tuple
from unittest.mock import MagicMock

from sygnal.gcmpushkin import GcmPushkin, PushkinSetupException
from sygnal.gcmpushkin import APIVersion, GcmPushkin

from tests import testutils
from tests.testutils import DummyResponse
Expand Down Expand Up @@ -79,25 +80,36 @@
}


class TestCredentials:
def __init__(self) -> None:
self.valid = False

@property
def token(self) -> str:
if self.valid:
return "myaccesstoken"
else:
raise Exception()

async def refresh(self, request: Any) -> None:
self.valid = True


class TestGcmPushkin(GcmPushkin):
"""
A GCM pushkin with the ability to make HTTP requests removed and instead
can be preloaded with virtual requests.
"""

def __init__(self, name: str, sygnal: "Sygnal", config: Dict[str, Any]):
super().__init__(name, sygnal, config)
self.preloaded_response = DummyResponse(0)
self.preloaded_response_payload: Dict[str, Any] = {}
self.last_request_body: Dict[str, Any] = {}
self.last_request_headers: Dict[AnyStr, List[AnyStr]] = {} # type: ignore[valid-type]
self.num_requests = 0
try:
super().__init__(name, sygnal, config)
except PushkinSetupException as e:
# for FCM v1 API we get an exception because the service account file
# does not exist, let's ignore it and move forward
if "service_account_file" not in str(e):
raise e
if self.api_version is APIVersion.V1:
self.credentials = TestCredentials() # type: ignore[assignment]

def preload_with_response(
self, code: int, response_payload: Dict[str, Any]
Expand All @@ -116,8 +128,22 @@ async def _perform_http_request( # type: ignore[override]
self.num_requests += 1
return self.preloaded_response, json.dumps(self.preloaded_response_payload)

async def _get_auth_header(self) -> str:
return "token"

FAKE_SERVICE_ACCOUNT_FILE = b"""
{
"type": "service_account",
"project_id": "project_id",
"private_key_id": "private_key_id",
"private_key": "-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC0PwE6TeTHjD5R\\nY2nOw1rsTgQZ38LCR2CLtx36n+LUkgej/9b+fwC88oKIqJKjUwn43JEOhf4rbA/a\\nqo4jVoLgv754G5+7Glfarr3/rqg+AVT75x6J5DRvhIYpDXwMIUqLAAbfk3TTFNJn\\n2ctrkBF2ZP9p3mzZ3NRjU63Wbf3LBpRqs8jdFEQu8JAecG8VKV1mboJIXG3hwqFN\\nJmcpC/+sWaxB5iMgSqy0w/rGFs6ZbZF6D10XYvf40lEEk9jQIovT+QD4+6GTlroT\\nbOk8uIwxFQcwMFpXj4MktqVNSNyiuuttptIvBWcMWHlaabXrR89vqUFe1g1Jx4GL\\nCF89RrcLAgMBAAECggEAPUYZ3b8zId78JGDeTEq+8wwGeuFFbRQkrvpeN5/41Xib\\nHlZPuQ5lqtXqKBjeWKVXA4G/0icc45gFv7kxPrQfI9YrItuJLmrjKNU0g+HVEdcU\\nE9pa2Fd6t9peXUBXRixfEee9bm3LTiKK8IDqlTNRrGTjKxNQ/7MBhI6izv1vRH/x\\n8i0o1xxNdqstHZ9wBFKYO9w8UQjtfzckkBNDLkaJ/WN0BoRubmUiV1+KwAyyBr6O\\nRnnZ9Tvy8VraSNSdJhX36ai36y18/sT6PWOp99zHYuDyz89KIz1la/fT9eSoR0Jy\\nYePmTEi+9pWhvtpAkqJkRxe5IDz71JVsQ07KoVfzaQKBgQDzKKUd/0ujhv/B9MQf\\nHcwSeWu/XnQ4hlcwz8dTWQjBV8gv9l4yBj9Pra62rg/tQ7b5XKMt6lv/tWs1IpdA\\neMsySY4972VPrmggKXgCnyKckDUYydNtHAIj9buo6AV8rONaneYnGv5wpSsf3q2c\\nOZrkamRgbBkI+B2mZ2obH1oVlQKBgQC9w9HkrDMvZ5L/ilZmpsvoHNFlQwmDgNlN\\n0ej5QGID5rljRM3CcLNHdyQiKqvLA9MCpPEXb2vVJPdmquD12A7a9s0OwxB/dtOD\\nykofcTY0ZHEM1HEyYJGmdK4FvZuNU4o2/D268dePjtj1Xw3c5fs0bcDiGQMtjWlz\\n5hjBzMsyHwKBgGjrIsPcwlBfEcAo0u7yNnnKNnmuUcuJ+9kt7j3Cbwqty80WKvK+\\ny1agBIECfhDMZQkXtbk8JFIjf4y/zi+db1/VaTDEORy2jmtCOWw4KgEQIDj/7OBp\\nc2r8vupUovl2x+rzsrkw5pTIT+FCffqoyHLCjWkle2/pTzHb8Waekoo5AoGAbELk\\nYy5uwTO45Hr60fOEzzZpq/iz28dNshz4agL2KD2gNGcTcEO1tCbfgXKQsfDLmG2b\\ncgBKJ77AOl1wnDEYQIme8TYOGnojL8Pfx9Jh10AaUvR8Y/49+hYFFhdXQCiR6M69\\nNQM2NJuNYWdKVGUMjJu0+AjHDFzp9YonQ6Ffp4cCgYEAmVALALCjU9GjJymgJ0lx\\nD9LccVHMwf9NmR/sMg0XNePRbCEcMDHKdtVJ1zPGS5txuxY3sRb/tDpv7TfuitrU\\nAw0/2ooMzunaoF/HXo+C/+t+pfuqPqLK4sCCyezUlMfCcaPdwXN2FmbgsaFHfe7I\\n7sGEnS/d8wEgydMiptJEf9s=\\n-----END PRIVATE KEY-----\\n",
"client_email": "firebase-adminsdk@project_id.iam.gserviceaccount.com",
"client_id": "client_id",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-04u89%40tchap-beta.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}
"""


class GcmTestCase(testutils.TestCase):
Expand All @@ -134,11 +160,14 @@ def config_setup(self, config: Dict[str, Any]) -> None:
"api_key": "kii",
"fcm_options": {"content_available": True, "mutable_content": True},
}
self.service_account_file = tempfile.NamedTemporaryFile()
self.service_account_file.write(FAKE_SERVICE_ACCOUNT_FILE)
self.service_account_file.flush()
config["apps"]["com.example.gcm.apiv1"] = {
"type": "tests.test_gcm.TestGcmPushkin",
"api_version": "v1",
"project_id": "example_project",
"service_account_file": "/path/to/file.json",
"service_account_file": self.service_account_file.name,
"fcm_options": {
"apns": {
"payload": {
Expand All @@ -152,6 +181,9 @@ def config_setup(self, config: Dict[str, Any]) -> None:
},
}

def tearDown(self) -> None:
self.service_account_file.close()

def get_test_pushkin(self, name: str) -> TestGcmPushkin:
pushkin = self.sygnal.pushkins[name]
assert isinstance(pushkin, TestGcmPushkin)
Expand Down Expand Up @@ -266,6 +298,9 @@ def test_expected_api_v1(self) -> None:
)

self.assertEqual(resp, {"rejected": []})
self.assertEqual(
gcm.last_request_headers.get("Authorization"), ["Bearer myaccesstoken"]
)

def test_expected_with_default_payload(self) -> None:
"""
Expand Down

0 comments on commit 0481753

Please sign in to comment.