def _push(self, _apns, _body, _user_config): _ios_token = _user_config.get("device_ios_token") if _ios_token == None or len(_ios_token) == 0: return _user_language = _user_config.get("user_language") or "en_US" _title = push_title(_body.get("mt"), _body.get("ms"), _body.get("bo"), _user_language) _sound = None if not _user_config.get("user_silence_notification"): _sound = "beep.wav" _count = _user_config.get("unacked_notification_count") _m = {"alert": _title, "sound": _sound, "badge": _count} from apns2.client import APNsClient from apns2.payload import Payload _dev = _user_config.get("is_development") _client = APNsClient(_apns.get("combination_pem"), use_sandbox=False, use_alternative_port=False) if _dev != None and _dev == True: _client = APNsClient(_apns.get("combination_pem"), use_sandbox=True, use_alternative_port=False) _payload = Payload(**_m) _client.send_notification(_ios_token, _payload) return
def update_card(): print('start update card') users = User.objects.all() for user in users: if user.card_drawer_of_next_day != '10102347454878415': user.update(card_drawer=None, draw_card_status='undraw') user.card_drawer = user.card_drawer_of_next_day user.card_drawer_of_next_day = None user.save() # send push notification print('send notification') try: user_list = User.objects.all() for user in user_list: if user.card_drawer != '10102347454878415': if user.device.ios != '': custom_payload = {'type': 'card'} payload = Payload(alert='已經有新的卡片囉!', sound="default", badge=1, custom=custom_payload) client = APNsClient(APNS_CERT, use_sandbox=USE_SANDBOX, use_alternative_port=False) client.send_notification(user.device.ios, payload, APNS_TOPIC) print('succeed') except Exception as e: print(e)
def send_ios(self, story, user, usersub): if not self.is_ios: return tokens = MUserNotificationTokens.get_tokens_for_user(self.user_id) # To update APNS: # 1. Create certificate signing requeswt in Keychain Access # 2. Upload to https://developer.apple.com/account/resources/certificates/list # 3. Download to secrets/certificates/ios/aps.cer # 4. Open in Keychain Access and export as aps.p12 # 4. Export private key as aps_key.p12 WITH A PASSPHRASE (removed later) # 5. openssl pkcs12 -in aps.p12 -out aps.pem -nodes -clcerts -nokeys # 6. openssl pkcs12 -clcerts -nokeys -out aps.pem -in aps.p12 # 7. cat aps.pem aps_key.noenc.pem > aps.p12.pem # 8. Verify: openssl s_client -connect gateway.push.apple.com:2195 -cert aps.p12.pem # 9. Deploy: aps -l work -t apns,repo,celery apns = APNsClient( '/srv/newsblur/config/certificates/aps.p12.pem', use_sandbox=tokens.use_sandbox ) notification_title_only = is_true(user.profile.preference_value('notification_title_only')) title, subtitle, body = self.title_and_body(story, usersub, notification_title_only) image_url = None if len(story['image_urls']): image_url = story['image_urls'][0] # print image_url confirmed_ios_tokens = [] for token in tokens.ios_tokens: logging.user( user, '~BMStory notification by iOS: ~FY~SB%s~SN~BM~FY/~SB%s' % (story['story_title'][:50], usersub.feed.feed_title[:50]), ) payload = Payload( alert={'title': title, 'subtitle': subtitle, 'body': body}, category="STORY_CATEGORY", mutable_content=True, custom={ 'story_hash': story['story_hash'], 'story_feed_id': story['story_feed_id'], 'image_url': image_url, }, ) try: apns.send_notification(token, payload, topic="com.newsblur.NewsBlur") except (BadDeviceToken, Unregistered): logging.user(user, '~BMiOS token expired: ~FR~SB%s' % (token[:50])) else: confirmed_ios_tokens.append(token) if settings.DEBUG: logging.user( user, '~BMiOS token good: ~FB~SB%s / %s' % (token[:50], len(confirmed_ios_tokens)), ) if len(confirmed_ios_tokens) < len(tokens.ios_tokens): tokens.ios_tokens = confirmed_ios_tokens tokens.save()
def send_Notification( message, key): token_hex = 'e4d3e8cb6e8c29d0dd6af4926e698c69632e2a8965cd17d66ed2d0cdd7869269' payload = Payload(alert="Hello World!", sound="default", badge=1) topic = 'ASU.SeatsFinderBot' client = APNsClient(key, use_sandbox=True, use_alternative_port=False) client.send_notification(token_hex, payload, topic)
class Notify: def __init__(self): self.config = Config() self.topic = 'BEPco.chatter' useSandbox = not self.config.isProd() cert = 'certs/sandbox.pem' if useSandbox else 'certs/prod.pem' self.client = APNsClient(cert, use_sandbox=useSandbox, use_alternative_port=False) def sendMessages(self, apnTokens, message, custom): payload = Payload(alert=message, sound="default", custom=custom, content_available=1) notifications = [ Notification(token=token, payload=payload) for token in apnTokens if token != None ] self.client.send_notification_batch(notifications, self.topic) def clearNotifications(self, apnToken): payload = Payload(alert=None, badge=0, custom={'type': 'clear'}) notifications = [Notification(token=apnToken, payload=payload)] self.client.send_notification_batch(notifications, self.topic)
def test_send_notification_failure_410(): with patch("apns2.credentials.CertificateCredentials.create_connection" ) as create_connection_mock: http_client_mock = MagicMock() http_client_mock.post.return_value = Response(status_code=410, json={ "reason": "BadDeviceToken", "timestamp": time.time() }) create_connection_mock.return_value = http_client_mock client = APNsClient(CertificateCredentials("test/mycert.pem")) exception_raised = False try: client.send_notification( token_hex=TOKEN, notification=Payload(alert="Test alert"), topic=TOPIC, ) except BadDeviceToken: exception_raised = True http_client_mock.post.assert_called_once() assert exception_raised is True
def send_Notification(self, message, key, device_id): token_hex = device_id payload = Payload(alert=message, sound="default", badge=1) topic = 'ASU.SeatsFinderBot' client = APNsClient(key, use_sandbox=False, use_alternative_port=False) client.send_notification(token_hex, payload, topic)
def __init__(self, sandbox=True, yaml_tokens=False): self.sandbox = sandbox self.yaml = yaml_tokens self.payload = None self.tokens = [] with open("app.yaml") as app_file: try: app_data = yaml.safe_load(app_file) except yaml.YAMLError: sys.exit(yaml.YAMLError) else: self.config = { "auth-key": app_data["auth-key"], "auth-key-filename": app_data["auth-key-filename"], "bundle-id": app_data["bundle-id"], "cert-filename": app_data["cert-filename"], "team-id": app_data["team-id"], "api-url": app_data["api-url"] + "/tokens/" + app_data["bundle-id"] } self.credentials = TokenCredentials(auth_key_path=self.config["auth-key-filename"], auth_key_id=self.config["auth-key"], team_id=self.config["team-id"]) self.client = APNsClient(credentials=self.credentials, use_sandbox=self.sandbox) self.load_tokens()
class NotificationService: def __init__(self): self.topic = 'com.epage.QuietMind' self.token_map = {} self.client = APNsClient(DEV_CERT_FILE, use_sandbox=True, use_alternative_port=False) # self.apns = APNs(use_sandbox=True, cert_file=CERT_FILE, key_file=KEY_FILE) # self.apns = APNs(use_sandbox=True, cert_file=CERT_FILE, enhanced=True) # self.client = APNSClient(certificate=CERT_FILE, # default_error_timeout=10, # default_expiration_offset=2592000, # default_batch_size=100, # default_retries=3) def register_token(self, userId, token): print('register notification token', userId, token) self.token_map[userId] = token def get_token(self, userId): if userId in self.token_map: return self.token_map[userId] return DEFAULT_TOKEN def send_notification(self, userId, message="Hello World!"): token_hex = self.get_token(userId) payload = Payload(alert=message, sound="default", badge=1) print(payload.__dict__) topic = 'com.epage.QuietMind' self.client = APNsClient(DEV_CERT_FILE, use_sandbox=True, use_alternative_port=False) self.client.send_notification(token_hex, payload, topic)
def __init__(self): self.config = Config() self.topic = 'BEPco.chatter' useSandbox = not self.config.isProd() cert = 'certs/sandbox.pem' if useSandbox else 'certs/prod.pem' self.client = APNsClient(cert, use_sandbox=useSandbox, use_alternative_port=False)
def send_message(self, message=None, **kwargs): """Send push message to registered devices.""" from apns2.client import APNsClient from apns2.payload import Payload from apns2.errors import Unregistered apns = APNsClient( self.certificate, use_sandbox=self.sandbox, use_alternative_port=False) device_state = kwargs.get(ATTR_TARGET) message_data = kwargs.get(ATTR_DATA) if message_data is None: message_data = {} if isinstance(message, str): rendered_message = message elif isinstance(message, template_helper.Template): rendered_message = message.render() else: rendered_message = "" payload = Payload( alert=rendered_message, badge=message_data.get("badge"), sound=message_data.get("sound"), category=message_data.get("category"), custom=message_data.get("custom", {}), content_available=message_data.get("content_available", False)) device_update = False for push_id, device in self.devices.items(): if not device.disabled: state = None if device.tracking_device_id is not None: state = self.device_states.get( device.full_tracking_device_id) if device_state is None or state == str(device_state): try: apns.send_notification( push_id, payload, topic=self.topic) except Unregistered: logging.error( "Device %s has unregistered.", push_id) device_update = True device.disable() if device_update: self.write_devices() return True
def connect(self) -> bool: try: self.client = APNsClient(credentials=self.credentials, use_sandbox=self.use_sandbox, use_alternative_port=self.use_alternative_port, proto=self.proto, json_encoder=self.json_encoder, password=self.password, proxy_host=self.proxy_host, proxy_port=self.proxy_port) return True except IOError as error: self.error('failed to connect apple server: %s' % error) return False
def send_apn(push_token: str): ''' Sends an empty APN to the given device push_token ''' payload = Payload() client = APNsClient(config.PASS_TYPE_CERTIFICATE_PATH, use_sandbox=False, use_alternative_port=False, password=config.PEM_PASSWORD) client.send_notification(push_token, payload, config.PASS_TYPE_IDENTIFIER)
def send_message(self, message=None, **kwargs): """Send push message to registered devices.""" from apns2.client import APNsClient from apns2.payload import Payload from apns2.errors import Unregistered apns = APNsClient(self.certificate, use_sandbox=self.sandbox, use_alternative_port=False) device_state = kwargs.get(ATTR_TARGET) message_data = kwargs.get(ATTR_DATA) if message_data is None: message_data = {} if isinstance(message, str): rendered_message = message elif isinstance(message, template_helper.Template): rendered_message = message.render() else: rendered_message = "" payload = Payload( alert=rendered_message, badge=message_data.get("badge"), sound=message_data.get("sound"), category=message_data.get("category"), custom=message_data.get("custom", {}), content_available=message_data.get("content_available", False), ) device_update = False for push_id, device in self.devices.items(): if not device.disabled: state = None if device.tracking_device_id is not None: state = self.device_states.get( device.full_tracking_device_id) if device_state is None or state == str(device_state): try: apns.send_notification(push_id, payload, topic=self.topic) except Unregistered: logging.error("Device %s has unregistered", push_id) device_update = True device.disable() if device_update: self.write_devices() return True
def send_notification(self, userId, message="Hello World!"): token_hex = self.get_token(userId) payload = Payload(alert=message, sound="default", badge=1) print(payload.__dict__) topic = 'com.epage.QuietMind' self.client = APNsClient(DEV_CERT_FILE, use_sandbox=True, use_alternative_port=False) self.client.send_notification(token_hex, payload, topic)
def __init__(self, topic, auth_key_path, auth_key_id, team_id, use_sandbox=False): self.topic = topic self.client = APNsClient(TokenCredentials(auth_key_path, auth_key_id, team_id), use_sandbox=use_sandbox, use_alternative_port=False)
def send_notification(apns_token, message, sender, channel, badge=1, network=None, intent=None, private=False): global apns_client if apns_client is None: apns_client = APNsClient(os.path.join(DIRECTORY, 'production.pem'), heartbeat_period=30) query = None if channel: query = channel elif sender: query = sender if message and intent == 'ACTION': message = '* %s' % (message) sound = None alert = {} if message or private: sound = 'default' user_info = {} if query and network: user_info['n'] = network user_info['q'] = query if sender: alert['title'] = sender if channel: alert['subtitle'] = channel if private: alert['loc-key'] = 'INPUT_MESSAGE_PLACEHOLDER' alert['body'] = 'Message' elif message: alert['body'] = message payload = Payload(alert=alert, sound=sound, badge=badge, custom=user_info) apns_client.connect() try: apns_client.send_notification(apns_token, payload, TOPIC) except (BadDeviceToken, Unregistered) as e: with database.transaction(): try: device = Device.get(Device.apns_token == apns_token) device.delete_instance(recursive=True) except Device.DoesNotExist: return
def push(request): #fcm_device = GCMDevice.objects.create(registration_id="e--N1a4DuTg:APA91bGrwQnf8h5o3UHrVPx3PTkTVumOEfHP5dfAdvFDuBA2h6QZVG0MYuQtGRH21nvdnb44sThudENkAeEtrmBND3g1gv2A0IlLW4ZMsCGl_AsBDWCR4FJm6s57pf-PPz5BGTkIWCbw", cloud_message_type="FCM", user='******') #device = GCMDevice.objects.get(registration_id="e--N1a4DuTg:APA91bGrwQnf8h5o3UHrVPx3PTkTVumOEfHP5dfAdvFDuBA2h6QZVG0MYuQtGRH21nvdnb44sThudENkAeEtrmBND3g1gv2A0IlLW4ZMsCGl_AsBDWCR4FJm6s57pf-PPz5BGTkIWCbw") token_hex = '106ececed6c5985efb2afd75618a41120086e7e93488315dc03ccd9eff0be257' payload = Payload(alert="Hello World!", sound="default", badge=1) topic = 'com.example.App' client = APNsClient( 'https://s3-us-west-1.amazonaws.com/blake-deets/aps_development.cer', use_sandbox=False, use_alternative_port=False) client.send_notification(token_hex, payload, topic)
class Notifier: def __init__(self): self.client = APNsClient(cert, use_sandbox=sandbox, use_alternative_port=False) def send(self, token, message, count, isSilent): if isSilent: payload = Payload(content_available=True, badge=count) else: # TODO create custom sound (more so on client) payload = Payload(alert=message, sound="default", badge=count) topic = 'com.bfichter.KookMachine' self.client.send_notification(token, payload, topic)
def sendpushnotification(DeviceToken, OrderID, StoreID, dev_flag, Message): #send the push notification custom = {'launchURL': 'x-com.petco.wrapper.sim://launch'} payload = Payload(alert=Message, sound="popcorn.wav", badge=0, custom=custom) topic = 'com.petco.notifications' IOS_Client = APNsClient('./Apple_Certificate/server1.pem', use_sandbox=dev_flag, use_alternative_port=False) IOS_Client.send_notification(DeviceToken, payload, topic) return True
def send_ios(self, story, user, usersub): if not self.is_ios: return tokens = MUserNotificationTokens.get_tokens_for_user(self.user_id) apns = APNsClient('/srv/newsblur/config/certificates/aps.p12.pem', use_sandbox=tokens.use_sandbox) notification_title_only = is_true( user.profile.preference_value('notification_title_only')) title, subtitle, body = self.title_and_body(story, usersub, notification_title_only) image_url = None if len(story['image_urls']): image_url = story['image_urls'][0] # print image_url confirmed_ios_tokens = [] for token in tokens.ios_tokens: logging.user( user, '~BMStory notification by iOS: ~FY~SB%s~SN~BM~FY/~SB%s' % (story['story_title'][:50], usersub.feed.feed_title[:50])) payload = Payload(alert={ 'title': title, 'subtitle': subtitle, 'body': body }, category="STORY_CATEGORY", mutable_content=True, custom={ 'story_hash': story['story_hash'], 'story_feed_id': story['story_feed_id'], 'image_url': image_url, }) try: apns.send_notification(token, payload, topic="com.newsblur.NewsBlur") except (BadDeviceToken, Unregistered): logging.user(user, '~BMiOS token expired: ~FR~SB%s' % (token[:50])) else: confirmed_ios_tokens.append(token) if settings.DEBUG: logging.user( user, '~BMiOS token good: ~FB~SB%s / %s' % (token[:50], len(confirmed_ios_tokens))) if len(confirmed_ios_tokens) < len(tokens.ios_tokens): tokens.ios_tokens = confirmed_ios_tokens tokens.save()
def send_apn_notification(message, endpoint): token = endpoint.device_token payload = Payload(alert=message, sound="default", badge=1) if settings.APNS_CERT_FILE: # allows for reuse of apns client and reuse of connections # TODO: handles errors by fcm client global apns_client if not apns_client: apns_client = APNsClient(settings.APNS_CERT_FILE, password=settings.APNS_CERT_PASSWORD, use_sandbox=settings.DEBUG, use_alternative_port=False) topic = settings.APNS_APP_BUNDLE_ID apns_client.send_notification(token, payload, topic)
def send_push(self, title, body): connects = UserConnectionField.objects.find_type_connection_by_user( self.user, UserConnectionField.APNS_TYPE) client = APNsClient(settings.APNS_KEY_LOCATION, use_sandbox=settings.APNS_SENDBOX, use_alternative_port=False) payload = Payload(alert=PayloadAlert(title=title, body=body), sound="default", badge=1) for connect in connects: client.send_notification(token_hex=connect.value, notification=payload, topic=settings.APNS_BUNDLE_ID)
def push(category, title, body, device_token, params): payload = Payload(alert=PayloadAlert(title=None if title == '' else title, body=body), sound='1107', badge=int(params['badge']) if 'badge' in params else 0, category=category, mutable_content=True, custom=params) client = APNsClient(CERT_PATH) try: client.send_notification(device_token, payload, 'me.fin.bark') return '' except APNsException as e: return str(e)
def setUp(self): self.open_streams = 0 self.max_open_streams = 0 self.mock_results = None self.next_stream_id = 0 with patch('apns2.credentials.HTTP20Connection' ) as mock_connection_constructor, patch( 'apns2.credentials.init_context'): self.mock_connection = MagicMock() self.mock_connection.get_response.side_effect = self.mock_get_response self.mock_connection.request.side_effect = self.mock_request self.mock_connection._conn.__enter__.return_value = self.mock_connection._conn self.mock_connection._conn.remote_settings.max_concurrent_streams = 500 mock_connection_constructor.return_value = self.mock_connection self.client = APNsClient(credentials=None)
def apns_send(tokens, data): if current_app.config['TESTING'] is True: current_app.config['TESTING_APNS'].append(data) return payload = Payload(alert=data['service']['name'], sound="default", badge=1, custom=data) notifications = [ Notification(token=token, payload=payload) for token in tokens ] topic = 'me.elrod.iPushjet' client = APNsClient(apns_cert_path, use_sandbox=True, use_alternative_port=False) client.send_notification_batch(notifications, topic)
def test_send_notification_success(): with patch("apns2.credentials.CertificateCredentials.create_connection" ) as create_connection_mock: http_client_mock = MagicMock() http_client_mock.post.return_value = Mock(status_code=200) create_connection_mock.return_value = http_client_mock client = APNsClient(CertificateCredentials("test/mycert.pem")) client.send_notification( token_hex=TOKEN, notification=Payload(alert="Test alert"), topic=TOPIC, ) http_client_mock.post.assert_called_once()
def get_apns_client() -> APNsClient: global _apns_client if _apns_client is None: # NB if called concurrently, this will make excess connections. # That's a little sloppy, but harmless unless a server gets # hammered with a ton of these all at once after startup. _apns_client = APNsClient(credentials=settings.APNS_CERT_FILE, use_sandbox=settings.APNS_SANDBOX) return _apns_client
def send_notification(user_id, st_code, condition, curr_value): logger.info("User to notify: %s" % user_id) notif_flag = False # Get the real name of the station station_name = Station.query.filter(Station.code == st_code).one().name logger.info("Station to be notified about: %s" % station_name) # Get the notification token from the users table token_hex = User.query.filter(User.device_id == user_id).one().notif_token logger.info("Notification token: %s" % token_hex) # Get the key, key path and team_id from the constants file and build # token credentials object token_credentials = TokenCredentials(auth_key_path=NOTIF_AUTH_KEY_PATH, auth_key_id=NOTIF_AUTH_KEY_ID, team_id=NOTIF_TEAM_ID) # Compose the text notif_text = notif_texts_format[condition['dimension']][condition['quantifier']] % \ (station_name,condition['value'],float(curr_value)) logger.info("Sending notification: %s" % notif_text) # Compose the dict with the station code and station name custom_data = {'station_code': st_code, 'station_name': station_name} topic = NOTIF_TOPIC payload = Payload(alert=notif_text, sound="default", badge=0, custom=custom_data) client = APNsClient(credentials=token_credentials, use_sandbox=True) try: #apns.gateway_server.send_notification(token_hex, payload,identifier=identifier) client.send_notification(token_hex, payload, topic) mark_as_notified(user_id, st_code, condition) logger.info("Notification sent!") notif_flag = True except: logger.error("Error sending notification!!") print("ERROR ENVIANDO NOTIFICACION") return notif_flag
def push(): # test token = '9dsfeg2fa913b390fc6b3d3ec637a764867241f516d847b54d24ce7e37963b6e' token_hexs = [] for i in range(10): token_hexs.append(token) token_hexs.append('sss') payload = Payload(alert="Hello World!", sound="default") client = APNsClient( 'Dev_Push_Cer-key.pem', # 'Release_Push_Cer_Key.pem', use_sandbox=True, use_alternative_port=False) st = time.time() response = client.send_notification_multiple(token_hexs, payload) et = time.time() print(et - st) print(response)
class NotificationPusher(object): def __init__(self, topic, auth_key_path, auth_key_id, team_id, use_sandbox=False): self.topic = topic self.client = APNsClient(TokenCredentials(auth_key_path, auth_key_id, team_id), use_sandbox=use_sandbox, use_alternative_port=False) def push(self, token_hex, beverage): payload = Payload(alert=f"{beverage} is ready!", sound="default", badge=1) self.client.send_notification(token_hex, payload, self.topic)
def send_message(self, message=None, **kwargs): """Send push message to registered devices.""" apns = APNsClient( self.certificate, use_sandbox=self.sandbox, use_alternative_port=False ) device_state = kwargs.get(ATTR_TARGET) if (message_data := kwargs.get(ATTR_DATA)) is None: message_data = {}
class SMS: """ Push SMS via APNs """ def __init__(self, text: str): self.__client = APNsClient(credentials=credentials, use_sandbox=use_sandbox) self.__payload = Payload(alert=text) def send(self, identifier: str) -> int: identifier = ID.parse(identifier=identifier) device = Device(identifier) tokens = device.tokens if tokens is None: print('Device token not found, failed to push message: %s' % self.__payload.alert) return 0 count = 0 for token in tokens: self.__client.send_notification(token_hex=token, notification=self.__payload) count += 1 print('Message has been sent to %d device(s)' % count) return count
def setUp(self): self.open_streams = 0 self.max_open_streams = 0 self.mock_results = None self.next_stream_id = 0 with patch('apns2.credentials.HTTP20Connection') as mock_connection_constructor, patch('apns2.credentials.init_context'): self.mock_connection = MagicMock() self.mock_connection.get_response.side_effect = self.mock_get_response self.mock_connection.request.side_effect = self.mock_request self.mock_connection._conn.__enter__.return_value = self.mock_connection._conn self.mock_connection._conn.remote_settings.max_concurrent_streams = 500 mock_connection_constructor.return_value = self.mock_connection self.client = APNsClient(credentials=None)
class ClientTestCase(TestCase): @classmethod def setUpClass(cls): # Ignore all log messages so that test output is not cluttered. logging.basicConfig(level=logging.CRITICAL) cls.tokens = ['%064x' % i for i in range(10000)] cls.payload = Payload(alert='Test alert') cls.notifications = [Notification(token=token, payload=cls.payload) for token in cls.tokens] cls.topic = 'com.example.App' def setUp(self): self.open_streams = 0 self.max_open_streams = 0 self.mock_results = None self.next_stream_id = 0 with patch('apns2.credentials.HTTP20Connection') as mock_connection_constructor, patch('apns2.credentials.init_context'): self.mock_connection = MagicMock() self.mock_connection.get_response.side_effect = self.mock_get_response self.mock_connection.request.side_effect = self.mock_request self.mock_connection._conn.__enter__.return_value = self.mock_connection._conn self.mock_connection._conn.remote_settings.max_concurrent_streams = 500 mock_connection_constructor.return_value = self.mock_connection self.client = APNsClient(credentials=None) @contextlib.contextmanager def mock_get_response(self, stream_id): self.open_streams -= 1 if self.mock_results: reason = self.mock_results[stream_id] response = Mock(status=200 if reason == 'Success' else 400) response.read.return_value = ('{"reason": "%s"}' % reason).encode('utf-8') yield response else: yield Mock(status=200) def mock_request(self, *dummy_args): self.open_streams += 1 if self.open_streams > self.max_open_streams: self.max_open_streams = self.open_streams stream_id = self.next_stream_id self.next_stream_id += 1 return stream_id def test_send_notification_batch_returns_results_in_order(self): results = self.client.send_notification_batch(self.notifications, self.topic) expected_results = {token: 'Success' for token in self.tokens} self.assertEqual(results, expected_results) def test_send_notification_batch_respects_max_concurrent_streams_from_server(self): self.client.send_notification_batch(self.notifications, self.topic) self.assertEqual(self.max_open_streams, 500) def test_send_notification_batch_overrides_server_max_concurrent_streams_if_too_large(self): self.mock_connection._conn.remote_settings.max_concurrent_streams = 5000 self.client.send_notification_batch(self.notifications, self.topic) self.assertEqual(self.max_open_streams, CONCURRENT_STREAMS_SAFETY_MAXIMUM) def test_send_notification_batch_overrides_server_max_concurrent_streams_if_too_small(self): self.mock_connection._conn.remote_settings.max_concurrent_streams = 0 self.client.send_notification_batch(self.notifications, self.topic) self.assertEqual(self.max_open_streams, 1) def test_send_notification_batch_reports_different_results(self): self.mock_results = ( ['BadDeviceToken'] * 1000 + ['Success'] * 1000 + ['DeviceTokenNotForTopic'] * 2000 + ['Success'] * 1000 + ['BadDeviceToken'] * 500 + ['PayloadTooLarge'] * 4500 ) results = self.client.send_notification_batch(self.notifications, self.topic) expected_results = dict(zip(self.tokens, self.mock_results)) self.assertEqual(results, expected_results) def test_send_empty_batch_does_nothing(self): self.client.send_notification_batch([], self.topic) self.assertEqual(self.mock_connection.request.call_count, 0) def test_connect_establishes_connection(self): self.client.connect() self.mock_connection.connect.assert_called_once_with() def test_connect_retries_failed_connection(self): self.mock_connection.connect.side_effect = [RuntimeError, RuntimeError, None] self.client.connect() self.assertEqual(self.mock_connection.connect.call_count, 3) def test_connect_stops_on_reaching_max_retries(self): self.mock_connection.connect.side_effect = [RuntimeError] * 4 with self.assertRaises(ConnectionFailed): self.client.connect() self.assertEqual(self.mock_connection.connect.call_count, 3)