"""Tests for send_push_notifications service""" import json import uuid import exponent_server_sdk as expo import pytest from apollo_main_db.push_notifications.models import PushMessageReceipt, UserDeviceToken from send_push_notifications.constants import DEVICE_NOT_REGISTERED_ERROR from send_push_notifications.handler import handle_error_message, handler, send_messages from send_push_notifications.logger import get_logger from send_push_notifications.push_client import PushClient from tests.factories import UserDeviceFactory @pytest.mark.parametrize( 'raise_exception,error_details,status', ( (False, {'error': 'DeviceNotRegistered'}, 'error',), (False, {}, 'ok',), (False, 'null', 'error',), (False, None, 'error',), (True, {'error': 'Connection problems'}, 'error',), ) ) def test_send_messages( mocker, db_session, raise_exception, error_details, status ): user_device = UserDeviceFactory.create() message = expo.PushMessage( to=f'ExponentPushToken {user_device.token}', body='Hello world', title='Title', data={} ) logger = get_logger('test') # mock request to expo server mocker.patch.object(PushClient, 'send') if raise_exception: message = expo.PushMessage( to=f'ExponentPushToken {user_device.token}', body='Hello world', title='Title', data={} ) else: message = expo.PushMessage( to=message.to, body=message.body, title=message.title, data={}, ) PushClient.send.return_value = [ expo.PushResponse( push_message=message, status=status, message='', details=error_details ) ] send_messages([message], db_session, logger) push_messages = db_session.query(PushMessageReceipt).all() assert len(push_messages) == 0 if raise_exception else 1 for push_message in push_messages: assert push_message.status == status assert push_message.created_at response_message = json.dumps(error_details) if error_details else '' assert push_message.response_message == response_message def test_handle_error_message(db_session): not_registered_device = UserDeviceFactory.create(is_active=True) registered_device = UserDeviceFactory.create(is_active=True) response_message = {'error': DEVICE_NOT_REGISTERED_ERROR} handle_error_message(response_message, not_registered_device.token, db_session) db_session.commit() db_session.query(UserDeviceToken).filter_by( token=not_registered_device.token, is_active=False).one() db_session.query(UserDeviceToken).filter_by( token=registered_device.token, is_active=True).one() def test_handler(db_session, mocker, redis_client): tokens = [ device.token for device in UserDeviceFactory.create_batch(size=3)] title = 'title' message = 'message' message_id = str(uuid.uuid4()) event = { 'Records': [{ 'messageId': message_id, 'body': json.dumps({ 'title': title, 'message': message, 'data': {}, 'tokens': tokens }) }] } mocker.patch.object(PushClient, 'send') for token in tokens: PushClient.send.return_value = [ expo.PushResponse( push_message=expo.PushMessage( to=token, body=message, title=title, data={'id': message_id}, ), status='ok', message='', details=None, ) ] logger = get_logger('test') handler(logger, event, redis_client) push_receipts = db_session.query(PushMessageReceipt).all() assert len(push_receipts) == 1 for receipt in push_receipts: assert receipt.token in tokens assert str(receipt.message_id) == message_id