def test_get_notifications_for_service_returns_merged_template_content( client, notify_db, notify_db_session, sample_template_with_placeholders): with freeze_time('2001-01-01T12:00:00'): create_sample_notification( notify_db, notify_db_session, service=sample_template_with_placeholders.service, template=sample_template_with_placeholders, personalisation={"name": "merged with first"}) with freeze_time('2001-01-01T12:00:01'): create_sample_notification( notify_db, notify_db_session, service=sample_template_with_placeholders.service, template=sample_template_with_placeholders, personalisation={"name": "merged with second"}) auth_header = create_authorization_header( service_id=sample_template_with_placeholders.service_id) response = client.get(path='/notifications', headers=[auth_header]) assert response.status_code == 200 assert { noti['body'] for noti in json.loads(response.get_data( as_text=True))['notifications'] } == { 'Hello merged with first\nYour thing is due soon', 'Hello merged with second\nYour thing is due soon' }
def test_should_return_pagination_links(notify_api, notify_db, notify_db_session, sample_email_template): with notify_api.test_request_context(): with notify_api.test_client() as client: # Effectively mocking page size original_page_size = notify_api.config['PAGE_SIZE'] try: notify_api.config['PAGE_SIZE'] = 1 create_sample_notification(notify_db, notify_db_session, sample_email_template.service) notification_2 = create_sample_notification(notify_db, notify_db_session, sample_email_template.service) create_sample_notification(notify_db, notify_db_session, sample_email_template.service) auth_header = create_authorization_header(service_id=sample_email_template.service_id) response = client.get( '/notifications?page=2', headers=[auth_header]) notifications = json.loads(response.get_data(as_text=True)) assert len(notifications['notifications']) == 1 assert notifications['links']['last'] == '/notifications?page=3' assert notifications['links']['prev'] == '/notifications?page=1' assert notifications['links']['next'] == '/notifications?page=3' assert notifications['notifications'][0]['to'] == notification_2.to assert response.status_code == 200 finally: notify_api.config['PAGE_SIZE'] = original_page_size
def test_get_notification_selects_correct_template_for_personalisation( client, notify_db, notify_db_session, sample_template): create_sample_notification(notify_db, notify_db_session, service=sample_template.service, template=sample_template) original_content = sample_template.content sample_template.content = '((name))' dao_update_template(sample_template) notify_db.session.commit() create_sample_notification(notify_db, notify_db_session, service=sample_template.service, template=sample_template, personalisation={"name": "foo"}) auth_header = create_authorization_header( service_id=sample_template.service_id) response = client.get(path='/notifications', headers=[auth_header]) assert response.status_code == 200 resp = json.loads(response.get_data(as_text=True)) notis = sorted(resp['notifications'], key=lambda x: x['template_version']) assert len(notis) == 2 assert notis[0]['template_version'] == 1 assert notis[0]['body'] == original_content assert notis[1]['template_version'] == 2 assert notis[1]['body'] == 'foo' assert notis[0]['template_version'] == notis[0]['template']['version'] assert notis[1]['template_version'] == notis[1]['template']['version']
def test_filter_by_multiple_statuss(notify_api, notify_db, notify_db_session, sample_email_template): with notify_api.test_request_context(): with notify_api.test_client() as client: notification_1 = create_sample_notification( notify_db, notify_db_session, service=sample_email_template.service, template=sample_email_template, status="delivered") notification_2 = create_sample_notification( notify_db, notify_db_session, service=sample_email_template.service, template=sample_email_template, status='sending') auth_header = create_authorization_header(service_id=sample_email_template.service_id) response = client.get( '/notifications?status=delivered&status=sending', headers=[auth_header]) assert response.status_code == 200 notifications = json.loads(response.get_data(as_text=True)) assert len(notifications['notifications']) == 2 set(['delivered', 'sending']) == set( [x['status'] for x in notifications['notifications']])
def test_filter_by_status_and_template_type(notify_api, notify_db, notify_db_session, sample_template, sample_email_template): with notify_api.test_request_context(): with notify_api.test_client() as client: notification_1 = create_sample_notification( notify_db, notify_db_session, service=sample_email_template.service, template=sample_template) notification_2 = create_sample_notification( notify_db, notify_db_session, service=sample_email_template.service, template=sample_email_template) notification_3 = create_sample_notification( notify_db, notify_db_session, service=sample_email_template.service, template=sample_email_template, status="delivered") auth_header = create_authorization_header(service_id=sample_email_template.service_id) response = client.get( '/notifications?template_type=email&status=delivered', headers=[auth_header]) notifications = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert len(notifications['notifications']) == 1 assert notifications['notifications'][0]['template']['template_type'] == 'email' assert notifications['notifications'][0]['status'] == 'delivered'
def test_should_block_api_call_if_over_day_limit_for_restricted_service( notify_db, notify_db_session, notify_api, mocker): with notify_api.test_request_context(): with notify_api.test_client() as client: mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') mocker.patch('app.encryption.encrypt', return_value="something_encrypted") service = create_sample_service(notify_db, notify_db_session, limit=1, restricted=True) email_template = create_sample_email_template(notify_db, notify_db_session, service=service) create_sample_notification( notify_db, notify_db_session, template=email_template, service=service, created_at=datetime.utcnow() ) data = { 'to': '*****@*****.**', 'template': str(email_template.id) } auth_header = create_authorization_header(service_id=service.id) response = client.post( path='/notifications/email', data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) json.loads(response.get_data(as_text=True)) assert response.status_code == 429
def test_should_allow_api_call_if_under_day_limit_regardless_of_type( notify_db, notify_db_session, notify_api, sample_user, mocker, restricted): with notify_api.test_request_context(): with notify_api.test_client() as client: mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') mocker.patch('app.encryption.encrypt', return_value="something_encrypted") service = create_sample_service(notify_db, notify_db_session, limit=2, restricted=restricted) email_template = create_sample_email_template(notify_db, notify_db_session, service=service) sms_template = create_sample_template(notify_db, notify_db_session, service=service) create_sample_notification(notify_db, notify_db_session, template=email_template, service=service) data = { 'to': sample_user.mobile_number, 'template': str(sms_template.id) } auth_header = create_authorization_header(service_id=service.id) response = client.post( path='/notifications/sms', data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 201
def test_get_all_notifications_filter_by_template_type(client, notify_db, notify_db_session): email_template = create_sample_template(notify_db, notify_db_session, template_type="email") sms_template = create_sample_template(notify_db, notify_db_session, template_type="sms") notification = create_sample_notification( notify_db, notify_db_session, template=email_template, to_field="*****@*****.**") create_sample_notification(notify_db, notify_db_session, template=sms_template) auth_header = create_authorization_header(service_id=notification.service_id) response = client.get( path='/v2/notifications?template_type=email', headers=[('Content-Type', 'application/json'), auth_header]) json_response = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert response.headers['Content-type'] == "application/json" assert json_response['links']['current'].endswith("/v2/notifications?template_type=email") assert 'next' in json_response['links'].keys() assert len(json_response['notifications']) == 1 assert json_response['notifications'][0]['id'] == str(notification.id) assert json_response['notifications'][0]['status'] == "created" assert json_response['notifications'][0]['template'] == { 'id': str(email_template.id), 'uri': email_template.get_link(), 'version': 1 } assert json_response['notifications'][0]['email_address'] == "*****@*****.**" assert json_response['notifications'][0]['type'] == "email"
def test_get_all_notifications_filter_by_failed_status(client, notify_db, notify_db_session): created_notification = create_sample_notification(notify_db, notify_db_session, status="created") failed_notifications = [ create_sample_notification(notify_db, notify_db_session, status=_status) for _status in ["technical-failure", "temporary-failure", "permanent-failure"] ] auth_header = create_authorization_header(service_id=created_notification.service_id) response = client.get( path='/v2/notifications?status=failed', headers=[('Content-Type', 'application/json'), auth_header]) json_response = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert response.headers['Content-type'] == "application/json" assert json_response['links']['current'].endswith("/v2/notifications?status=failed") assert 'next' in json_response['links'].keys() assert len(json_response['notifications']) == 3 returned_notification_ids = [n['id'] for n in json_response['notifications']] for _id in [_notification.id for _notification in failed_notifications]: assert str(_id) in returned_notification_ids assert created_notification.id not in returned_notification_ids
def test_get_all_notifications_only_returns_notifications_of_matching_type( notify_api, notify_db, notify_db_session, sample_service, key_type ): with notify_api.test_request_context(), notify_api.test_client() as client: team_api_key = ApiKey(service=sample_service, name='team_api_key', created_by=sample_service.created_by, key_type=KEY_TYPE_TEAM) save_model_api_key(team_api_key) normal_api_key = ApiKey(service=sample_service, name='normal_api_key', created_by=sample_service.created_by, key_type=KEY_TYPE_NORMAL) save_model_api_key(normal_api_key) test_api_key = ApiKey(service=sample_service, name='test_api_key', created_by=sample_service.created_by, key_type=KEY_TYPE_TEST) save_model_api_key(test_api_key) normal_notification = create_sample_notification( notify_db, notify_db_session, api_key_id=normal_api_key.id, key_type=KEY_TYPE_NORMAL ) team_notification = create_sample_notification( notify_db, notify_db_session, api_key_id=team_api_key.id, key_type=KEY_TYPE_TEAM ) test_notification = create_sample_notification( notify_db, notify_db_session, api_key_id=test_api_key.id, key_type=KEY_TYPE_TEST ) notification_objs = { KEY_TYPE_NORMAL: normal_notification, KEY_TYPE_TEAM: team_notification, KEY_TYPE_TEST: test_notification } response = client.get( path='/notifications', headers=_create_auth_header_from_key(notification_objs[key_type].api_key)) assert response.status_code == 200 notifications = json.loads(response.get_data(as_text=True))['notifications'] assert len(notifications) == 1 assert notifications[0]['id'] == str(notification_objs[key_type].id)
def test_should_return_pagination_links(client, notify_db, notify_db_session, sample_email_template): # Effectively mocking page size original_page_size = current_app.config["API_PAGE_SIZE"] try: current_app.config["API_PAGE_SIZE"] = 1 create_sample_notification(notify_db, notify_db_session, sample_email_template.service) notification_2 = create_sample_notification( notify_db, notify_db_session, sample_email_template.service) create_sample_notification(notify_db, notify_db_session, sample_email_template.service) auth_header = create_authorization_header( service_id=sample_email_template.service_id) response = client.get("/notifications?page=2", headers=[auth_header]) notifications = json.loads(response.get_data(as_text=True)) assert len(notifications["notifications"]) == 1 assert notifications["links"]["last"] == "/notifications?page=3" assert notifications["links"]["prev"] == "/notifications?page=1" assert notifications["links"]["next"] == "/notifications?page=3" assert notifications["notifications"][0]["to"] == notification_2.to assert response.status_code == 200 finally: current_app.config["API_PAGE_SIZE"] = original_page_size
def test_filter_by_template_type(client, notify_db, notify_db_session, sample_template, sample_email_template): create_sample_notification( notify_db, notify_db_session, service=sample_email_template.service, template=sample_template, ) create_sample_notification( notify_db, notify_db_session, service=sample_email_template.service, template=sample_email_template, ) auth_header = create_authorization_header( service_id=sample_email_template.service_id) response = client.get("/notifications?template_type=sms", headers=[auth_header]) notifications = json.loads(response.get_data(as_text=True)) assert len(notifications["notifications"]) == 1 assert notifications["notifications"][0]["template"][ "template_type"] == "sms" assert response.status_code == 200
def test_get_notifications_for_service_returns_merged_template_content(notify_api, notify_db, notify_db_session, sample_template_with_placeholders): with freeze_time('2001-01-01T12:00:00'): create_sample_notification(notify_db, notify_db_session, service=sample_template_with_placeholders.service, template=sample_template_with_placeholders, personalisation={"name": "merged with first"}) with freeze_time('2001-01-01T12:00:01'): create_sample_notification(notify_db, notify_db_session, service=sample_template_with_placeholders.service, template=sample_template_with_placeholders, personalisation={"name": "merged with second"}) with notify_api.test_request_context(): with notify_api.test_client() as client: auth_header = create_authorization_header(service_id=sample_template_with_placeholders.service_id) response = client.get( path='/notifications', headers=[auth_header]) assert response.status_code == 200 assert {noti['body'] for noti in json.loads(response.get_data(as_text=True))['notifications']} == { 'Hello merged with first\nYour thing is due soon', 'Hello merged with second\nYour thing is due soon' }
def test_filter_by_multiple_template_types(notify_api, notify_db, notify_db_session, sample_template, sample_email_template): with notify_api.test_request_context(): with notify_api.test_client() as client: notification_1 = create_sample_notification( notify_db, notify_db_session, service=sample_email_template.service, template=sample_template) notification_2 = create_sample_notification( notify_db, notify_db_session, service=sample_email_template.service, template=sample_email_template) auth_header = create_authorization_header(service_id=sample_email_template.service_id) response = client.get( '/notifications?template_type=sms&template_type=email', headers=[auth_header]) assert response.status_code == 200 notifications = json.loads(response.get_data(as_text=True)) assert len(notifications['notifications']) == 2 set(['sms', 'email']) == set( [x['template']['template_type'] for x in notifications['notifications']])
def test_should_return_pagination_links(client, notify_db, notify_db_session, sample_email_template): # Effectively mocking page size original_page_size = current_app.config['API_PAGE_SIZE'] try: current_app.config['API_PAGE_SIZE'] = 1 create_sample_notification(notify_db, notify_db_session, sample_email_template.service) notification_2 = create_sample_notification( notify_db, notify_db_session, sample_email_template.service) create_sample_notification(notify_db, notify_db_session, sample_email_template.service) auth_header = create_authorization_header( service_id=sample_email_template.service_id) response = client.get('/notifications?page=2', headers=[auth_header]) notifications = json.loads(response.get_data(as_text=True)) assert len(notifications['notifications']) == 1 assert notifications['links']['last'] == '/notifications?page=3' assert notifications['links']['prev'] == '/notifications?page=1' assert notifications['links']['next'] == '/notifications?page=3' assert notifications['notifications'][0]['to'] == notification_2.to assert response.status_code == 200 finally: current_app.config['API_PAGE_SIZE'] = original_page_size
def test_get_all_notifications_only_returns_notifications_of_matching_type( client, notify_db, notify_db_session, sample_service, key_type ): team_api_key = ApiKey(service=sample_service, name='team_api_key', created_by=sample_service.created_by, key_type=KEY_TYPE_TEAM) save_model_api_key(team_api_key) normal_api_key = ApiKey(service=sample_service, name='normal_api_key', created_by=sample_service.created_by, key_type=KEY_TYPE_NORMAL) save_model_api_key(normal_api_key) test_api_key = ApiKey(service=sample_service, name='test_api_key', created_by=sample_service.created_by, key_type=KEY_TYPE_TEST) save_model_api_key(test_api_key) normal_notification = create_sample_notification( notify_db, notify_db_session, api_key=normal_api_key, key_type=KEY_TYPE_NORMAL ) team_notification = create_sample_notification( notify_db, notify_db_session, api_key=team_api_key, key_type=KEY_TYPE_TEAM ) test_notification = create_sample_notification( notify_db, notify_db_session, api_key=test_api_key, key_type=KEY_TYPE_TEST ) notification_objs = { KEY_TYPE_NORMAL: normal_notification, KEY_TYPE_TEAM: team_notification, KEY_TYPE_TEST: test_notification } response = client.get( path='/notifications', headers=_create_auth_header_from_key(notification_objs[key_type].api_key)) assert response.status_code == 200 notifications = json.loads(response.get_data(as_text=True))['notifications'] assert len(notifications) == 1 assert notifications[0]['id'] == str(notification_objs[key_type].id)
def test_only_normal_api_keys_can_return_job_notifications( client, notify_db, notify_db_session, sample_service, sample_job, key_type): team_api_key = ApiKey( service=sample_service, name="team_api_key", created_by=sample_service.created_by, key_type=KEY_TYPE_TEAM, ) save_model_api_key(team_api_key) normal_api_key = ApiKey( service=sample_service, name="normal_api_key", created_by=sample_service.created_by, key_type=KEY_TYPE_NORMAL, ) save_model_api_key(normal_api_key) test_api_key = ApiKey( service=sample_service, name="test_api_key", created_by=sample_service.created_by, key_type=KEY_TYPE_TEST, ) save_model_api_key(test_api_key) create_sample_notification(notify_db, notify_db_session, job=sample_job) normal_notification = create_sample_notification(notify_db, notify_db_session, api_key=normal_api_key, key_type=KEY_TYPE_NORMAL) team_notification = create_sample_notification(notify_db, notify_db_session, api_key=team_api_key, key_type=KEY_TYPE_TEAM) test_notification = create_sample_notification(notify_db, notify_db_session, api_key=test_api_key, key_type=KEY_TYPE_TEST) notification_objs = { KEY_TYPE_NORMAL: normal_notification, KEY_TYPE_TEAM: team_notification, KEY_TYPE_TEST: test_notification, } response = client.get( path="/notifications?include_jobs=true", headers=_create_auth_header_from_key( notification_objs[key_type[0]].api_key), ) assert response.status_code == 200 notifications = json.loads( response.get_data(as_text=True))["notifications"] assert len(notifications) == key_type[1] assert notifications[0]["id"] == str(notification_objs[key_type[0]].id)
def test_ses_callback_should_update_multiple_notification_status_sent( notify_api, notify_db, notify_db_session, sample_email_template, mocker): with notify_api.test_request_context(): with notify_api.test_client() as client: notification1 = create_sample_notification( notify_db, notify_db_session, template=sample_email_template, reference='ref1', sent_at=datetime.utcnow(), status='sending') notification2 = create_sample_notification( notify_db, notify_db_session, template=sample_email_template, reference='ref2', sent_at=datetime.utcnow(), status='sending') notification3 = create_sample_notification( notify_db, notify_db_session, template=sample_email_template, reference='ref3', sent_at=datetime.utcnow(), status='sending') resp1 = client.post( path='/notifications/email/ses', data=ses_notification_callback(ref='ref1'), headers=[('Content-Type', 'text/plain; charset=UTF-8')] ) resp2 = client.post( path='/notifications/email/ses', data=ses_notification_callback(ref='ref2'), headers=[('Content-Type', 'text/plain; charset=UTF-8')] ) resp3 = client.post( path='/notifications/email/ses', data=ses_notification_callback(ref='ref3'), headers=[('Content-Type', 'text/plain; charset=UTF-8')] ) assert resp1.status_code == 200 assert resp2.status_code == 200 assert resp3.status_code == 200
def test_invalid_page_size_param(client, notify_db, notify_db_session, sample_email_template): create_sample_notification(notify_db, notify_db_session) create_sample_notification(notify_db, notify_db_session) auth_header = create_authorization_header(service_id=sample_email_template.service_id) response = client.get( '/notifications?page=1&page_size=invalid', headers=[auth_header]) notifications = json.loads(response.get_data(as_text=True)) assert response.status_code == 400 assert notifications['result'] == 'error' assert 'Not a valid integer.' in notifications['message']['page_size']
def test_invalid_page_size_param(notify_api, notify_db, notify_db_session, sample_email_template): with notify_api.test_request_context(): n1 = create_sample_notification(notify_db, notify_db_session) n2 = create_sample_notification(notify_db, notify_db_session) with notify_api.test_client() as client: auth_header = create_authorization_header(service_id=sample_email_template.service_id) response = client.get( '/notifications?page=1&page_size=invalid', headers=[auth_header]) notifications = json.loads(response.get_data(as_text=True)) assert response.status_code == 400 assert notifications['result'] == 'error' assert 'Not a valid integer.' in notifications['message']['page_size']
def test_ses_callback_does_not_call_send_delivery_status_if_no_db_entry( client, notify_db, notify_db_session, sample_email_template, mocker): with freeze_time('2001-01-01T12:00:00'): send_mock = mocker.patch( 'app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async' ) notification = create_sample_notification( notify_db, notify_db_session, template=sample_email_template, reference='ref', status='sending', sent_at=datetime.utcnow() ) assert get_notification_by_id(notification.id).status == 'sending' assert process_ses_results_task(ses_notification_callback(reference='ref')) assert get_notification_by_id(notification.id).status == 'delivered' send_mock.assert_not_called()
def test_create_complaint_callback_data( notify_db, notify_db_session, sample_email_template, ): notification = create_sample_notification( notify_db, notify_db_session, template=sample_email_template, status="delivered", sent_at=datetime.utcnow(), ) complaint = create_complaint(notification=notification, service=notification.service) callback_api = create_service_callback_api( service=sample_email_template.service, url="https://original_url.com") assert encryption.decrypt( create_complaint_callback_data( complaint, notification, callback_api, "*****@*****.**")) == { "complaint_id": str(complaint.id), "notification_id": str(notification.id), "reference": notification.client_reference, "to": "*****@*****.**", "complaint_date": complaint.complaint_date.strftime(DATETIME_FORMAT), "service_callback_api_url": callback_api.url, "service_callback_api_bearer_token": callback_api.bearer_token, }
def test_valid_page_size_param(notify_api, notify_db, notify_db_session, sample_email_template): with notify_api.test_request_context(): create_sample_notification(notify_db, notify_db_session) create_sample_notification(notify_db, notify_db_session) with notify_api.test_client() as client: auth_header = create_authorization_header(service_id=sample_email_template.service_id) response = client.get( '/notifications?page=1&page_size=1', headers=[auth_header]) notifications = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert len(notifications['notifications']) == 1 assert notifications['total'] == 2 assert notifications['page_size'] == 1
def test_sap_callback_should_return_400_if_no_status(client, sample_sap_oauth2_client, notify_db, notify_db_session, mocker): mocker.patch('app.statsd_client.incr') notification = create_sample_notification(notify_db, notify_db_session, status='sending', sent_at=datetime.utcnow()) data = { "messageId": "1234", "recipient": "+61412345678", "message": "message" } response = sap_post(client, sample_sap_oauth2_client, notification.id, data) json_resp = json.loads(response.get_data(as_text=True)) assert response.status_code == 400 assert json_resp['result'] == 'error' assert json_resp['message'] == ['sap callback failed: status missing']
def test_process_mmg_response_status_4_updates_notification_with_temporary_failed( notify_db, notify_db_session, client, mocker): mocker.patch( 'app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async' ) notification = create_sample_notification(notify_db, notify_db_session, status='sending', sent_at=datetime.utcnow()) data = json.dumps({ "reference": "mmg_reference", "CID": str(notification.id), "MSISDN": "447777349060", "status": 4 }) response = mmg_post(client, data) assert response.status_code == 200 json_data = json.loads(response.data) assert json_data['result'] == 'success' assert json_data[ 'message'] == 'MMG callback succeeded. reference {} updated'.format( notification.id) assert get_notification_by_id( notification.id).status == 'temporary-failure'
def test_get_all_notifications_returns_200(client, notify_db, notify_db_session): notifications = [create_sample_notification(notify_db, notify_db_session) for _ in range(2)] notification = notifications[-1] auth_header = create_authorization_header(service_id=notification.service_id) response = client.get( path='/v2/notifications', headers=[('Content-Type', 'application/json'), auth_header]) json_response = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert response.headers['Content-type'] == "application/json" assert json_response['links']['current'].endswith("/v2/notifications") assert 'next' in json_response['links'].keys() assert len(json_response['notifications']) == 2 assert json_response['notifications'][0]['id'] == str(notification.id) assert json_response['notifications'][0]['status'] == "created" assert json_response['notifications'][0]['template'] == { 'id': str(notification.template.id), 'uri': notification.template.get_link(), 'version': 1 } assert json_response['notifications'][0]['phone_number'] == "+447700900855" assert json_response['notifications'][0]['type'] == "sms"
def test_process_mmg_response_records_statsd(notify_db, notify_db_session, client, mocker): with freeze_time('2001-01-01T12:00:00'): mocker.patch('app.statsd_client.incr') mocker.patch('app.statsd_client.timing_with_dates') mocker.patch( 'app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async' ) notification = create_sample_notification(notify_db, notify_db_session, status='sending', sent_at=datetime.utcnow()) data = json.dumps({ "reference": "mmg_reference", "CID": str(notification.id), "MSISDN": "447777349060", "status": "3", "deliverytime": "2016-04-05 16:01:07" }) mmg_post(client, data) app.statsd_client.incr.assert_any_call("callback.mmg.delivered") app.statsd_client.timing_with_dates.assert_any_call( "callback.mmg.elapsed-time", datetime.utcnow(), notification.sent_at)
def test_get_email_notification_by_id(notify_api, notify_db, notify_db_session, sample_email_template): email_notification = create_sample_notification(notify_db, notify_db_session, service=sample_email_template.service, template=sample_email_template, status='sending') with notify_api.test_request_context(): with notify_api.test_client() as client: auth_header = create_authorization_header(service_id=email_notification.service_id) response = client.get( '/notifications/{}'.format(email_notification.id), headers=[auth_header]) notification = json.loads(response.get_data(as_text=True))['data']['notification'] assert notification['status'] == 'sending' assert notification['template'] == { 'id': str(email_notification.template.id), 'name': email_notification.template.name, 'template_type': email_notification.template.template_type, 'version': 1 } assert notification['to'] == '+447700900855' assert notification['service'] == str(email_notification.service_id) assert response.status_code == 200 assert notification['body'] == sample_email_template.content assert notification['subject'] == sample_email_template.subject
def test_sap_callback_should_record_statsd(client, sample_sap_oauth2_client, notify_db, notify_db_session, mocker): with freeze_time('2001-01-01T12:00:00'): mocker.patch('app.statsd_client.incr') mocker.patch('app.statsd_client.timing_with_dates') mocker.patch( 'app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async' ) notification = create_sample_notification(notify_db, notify_db_session, status='sending', sent_at=datetime.utcnow()) data = { "messageId": "1234", "status": "DELIVERED", "recipient": "+61412345678", "message": "message" } sap_post(client, sample_sap_oauth2_client, notification.id, data) app.statsd_client.timing_with_dates.assert_any_call( "callback.sap.elapsed-time", datetime.utcnow(), notification.sent_at) app.statsd_client.incr.assert_any_call("callback.sap.delivered")
def test_process_sns_results_failed( sample_template, notify_db, notify_db_session, mocker, provider_response, expected_status, should_log_warning, ): mock_logger = mocker.patch( 'app.celery.process_sns_receipts_tasks.current_app.logger.info') mock_warning_logger = mocker.patch( 'app.celery.process_sns_receipts_tasks.current_app.logger.warning') notification = create_sample_notification(notify_db, notify_db_session, template=sample_template, reference='ref', status=NOTIFICATION_SENT, sent_by='sns', sent_at=datetime.utcnow()) assert get_notification_by_id(notification.id).status == NOTIFICATION_SENT assert process_sns_results( sns_failed_callback(provider_response=provider_response, reference='ref')) assert get_notification_by_id(notification.id).status == expected_status mock_logger.assert_called_once_with(( f'SNS delivery failed: notification id {notification.id} and reference ref has error found. ' f'Provider response: {provider_response}')) assert mock_warning_logger.call_count == int(should_log_warning)
def test_ses_callback_should_not_set_status_once_status_is_delivered(notify_api, notify_db, notify_db_session, sample_email_template): with notify_api.test_request_context(): with notify_api.test_client() as client: notification = create_sample_notification( notify_db, notify_db_session, template=sample_email_template, reference='ref', status='delivered', sent_at=datetime.utcnow() ) assert get_notification_by_id(notification.id).status == 'delivered' response = client.post( path='/notifications/email/ses', data=ses_soft_bounce_callback(), headers=[('Content-Type', 'text/plain; charset=UTF-8')] ) json_resp = json.loads(response.get_data(as_text=True)) assert response.status_code == 404 assert json_resp['result'] == 'error' assert json_resp['message'] == 'SES callback failed: notification either not found or already updated from sending. Status temporary-failure' # noqa assert get_notification_by_id(notification.id).status == 'delivered'
def test_valid_page_size_param(notify_api, notify_db, notify_db_session, sample_email_template): with notify_api.test_request_context(): n1 = create_sample_notification(notify_db, notify_db_session) n2 = create_sample_notification(notify_db, notify_db_session) with notify_api.test_client() as client: auth_header = create_authorization_header(service_id=sample_email_template.service_id) response = client.get( '/notifications?page=1&page_size=1', headers=[auth_header]) notifications = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert len(notifications['notifications']) == 1 assert notifications['total'] == 2 assert notifications['page_size'] == 1
def test_firetext_callback_should_update_notification_status_failed( notify_db, notify_db_session, notify_api, sample_template, mocker ): with notify_api.test_request_context(): with notify_api.test_client() as client: mocker.patch('app.statsd_client.incr') notification = create_sample_notification( notify_db, notify_db_session, template=sample_template, reference='ref', status='sending', sent_at=datetime.utcnow()) original = get_notification_by_id(notification.id) assert original.status == 'sending' response = client.post( path='/notifications/sms/firetext', data='mobile=441234123123&status=1&time=2016-03-10 14:17:00&reference={}'.format( notification.id ), headers=[('Content-Type', 'application/x-www-form-urlencoded')]) json_resp = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert json_resp['result'] == 'success' assert json_resp['message'] == 'Firetext callback succeeded. reference {} updated'.format( notification.id ) assert get_notification_by_id(notification.id).status == 'permanent-failure'
def test_firetext_callback_should_update_notification_status_failed( notify_db, notify_db_session, client, sample_template, mocker ): mocker.patch('app.statsd_client.incr') mocker.patch( 'app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async' ) notification = create_sample_notification( notify_db, notify_db_session, template=sample_template, reference='ref', status='sending', sent_at=datetime.utcnow()) original = get_notification_by_id(notification.id) assert original.status == 'sending' data = 'mobile=61412345678&status=1&time=2016-03-10 14:17:00&reference={}'.format( notification.id) response = firetext_post(client, data) json_resp = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert json_resp['result'] == 'success' assert json_resp['message'] == 'Firetext callback succeeded. reference {} updated'.format( notification.id ) assert get_notification_by_id(notification.id).status == 'permanent-failure'
def test_ses_callback_should_set_status_to_permanent_failure( notify_db, notify_db_session, sample_email_template, mocker, bounce_subtype, provider_response, ): send_mock = mocker.patch( "app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async" ) notification = create_sample_notification( notify_db, notify_db_session, template=sample_email_template, reference="ref", status="sending", sent_at=datetime.utcnow(), ) create_service_callback_api(service=sample_email_template.service, url="https://original_url.com") assert get_notification_by_id(notification.id).status == "sending" assert process_ses_results( ses_hard_bounce_callback(reference="ref", bounce_subtype=bounce_subtype)) notification = get_notification_by_id(notification.id) assert notification.status == "permanent-failure" assert notification.provider_response == provider_response assert send_mock.called
def test_process_sns_results_calls_service_callback(sample_template, notify_db_session, notify_db, mocker): with freeze_time('2021-01-01T12:00:00'): mocker.patch('app.statsd_client.incr') mocker.patch('app.statsd_client.timing_with_dates') send_mock = mocker.patch( 'app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async' ) notification = create_sample_notification(notify_db, notify_db_session, template=sample_template, reference='ref', status=NOTIFICATION_SENT, sent_by='sns', sent_at=datetime.utcnow()) callback_api = create_service_callback_api( service=sample_template.service, url="https://example.com") assert get_notification_by_id( notification.id).status == NOTIFICATION_SENT assert process_sns_results(sns_success_callback(reference='ref')) assert get_notification_by_id( notification.id).status == NOTIFICATION_DELIVERED statsd_client.timing_with_dates.assert_any_call( "callback.sns.elapsed-time", datetime.utcnow(), notification.sent_at) statsd_client.incr.assert_any_call("callback.sns.delivered") updated_notification = get_notification_by_id(notification.id) encrypted_data = create_delivery_status_callback_data( updated_notification, callback_api) send_mock.assert_called_once_with( [str(notification.id), encrypted_data], queue="service-callbacks")
def test_ses_callback_should_update_notification_status( notify_db, notify_db_session, sample_email_template, mocker): with freeze_time("2001-01-01T12:00:00"): mocker.patch("app.statsd_client.incr") mocker.patch("app.statsd_client.timing_with_dates") send_mock = mocker.patch( "app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async" ) notification = create_sample_notification( notify_db, notify_db_session, template=sample_email_template, reference="ref", status="sending", sent_at=datetime.utcnow(), ) callback_api = create_service_callback_api( service=sample_email_template.service, url="https://original_url.com") assert get_notification_by_id(notification.id).status == "sending" assert process_ses_results(ses_notification_callback(reference="ref")) notification = get_notification_by_id(notification.id) assert notification.status == "delivered" assert notification.provider_response is None statsd_client.timing_with_dates.assert_any_call( "callback.ses.elapsed-time", datetime.utcnow(), notification.sent_at) statsd_client.incr.assert_any_call("callback.ses.delivered") updated_notification = Notification.query.get(notification.id) encrypted_data = create_delivery_status_callback_data( updated_notification, callback_api) send_mock.assert_called_once_with( [str(notification.id), encrypted_data], queue="service-callbacks")
def test_ses_callback_should_update_notification_status( client, notify_db, notify_db_session, sample_email_template, mocker): with freeze_time('2001-01-01T12:00:00'): mocker.patch('app.statsd_client.incr') mocker.patch('app.statsd_client.timing_with_dates') send_mock = mocker.patch( 'app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async' ) notification = create_sample_notification( notify_db, notify_db_session, template=sample_email_template, reference='ref', status='sending', sent_at=datetime.utcnow()) callback_api = create_service_callback_api( service=sample_email_template.service, url="https://original_url.com") assert get_notification_by_id(notification.id).status == 'sending' errors = process_ses_response( ses_notification_callback(reference='ref')) assert errors is None assert get_notification_by_id(notification.id).status == 'delivered' statsd_client.timing_with_dates.assert_any_call( "callback.ses.elapsed-time", datetime.utcnow(), notification.sent_at) statsd_client.incr.assert_any_call("callback.ses.delivered") updated_notification = Notification.query.get(notification.id) encrypted_data = create_delivery_status_callback_data( updated_notification, callback_api) send_mock.assert_called_once_with( [str(notification.id), encrypted_data], queue="service-callbacks")
def test_ses_callback_should_set_status_to_permanent_failure(notify_api, notify_db, notify_db_session, sample_email_template): with notify_api.test_request_context(): with notify_api.test_client() as client: notification = create_sample_notification( notify_db, notify_db_session, template=sample_email_template, reference='ref', status='sending', sent_at=datetime.utcnow() ) assert get_notification_by_id(notification.id).status == 'sending' response = client.post( path='/notifications/email/ses', data=ses_hard_bounce_callback(), headers=[('Content-Type', 'text/plain; charset=UTF-8')] ) json_resp = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert json_resp['result'] == 'success' assert json_resp['message'] == 'SES callback succeeded' assert get_notification_by_id(notification.id).status == 'permanent-failure'
def test_process_sendgrid_response_returs_a_400(client, notify_db, notify_db_session, sample_email_template, mocker): create_sample_notification(notify_db, notify_db_session, template=sample_email_template, reference='ref', status='created', sent_at=datetime.utcnow()) data = json.dumps([{"event": "delivered"}]) response = client.post(path='/notifications/email/sendgrid', data=data, headers=[('Content-Type', 'application/json')]) assert response.status == '400 BAD REQUEST'
def test_get_all_notifications_newest_first(client, notify_db, notify_db_session, sample_email_template): notification_1 = create_sample_notification(notify_db, notify_db_session, sample_email_template.service) notification_2 = create_sample_notification(notify_db, notify_db_session, sample_email_template.service) notification_3 = create_sample_notification(notify_db, notify_db_session, sample_email_template.service) auth_header = create_authorization_header(service_id=sample_email_template.service_id) response = client.get( '/notifications', headers=[auth_header]) notifications = json.loads(response.get_data(as_text=True)) assert len(notifications['notifications']) == 3 assert notifications['notifications'][0]['to'] == notification_3.to assert notifications['notifications'][1]['to'] == notification_2.to assert notifications['notifications'][2]['to'] == notification_1.to assert response.status_code == 200
def test_should_send_notification_to_whitelist_recipient( client, notify_db, notify_db_session, notification_type, to, _create_sample_template, key_type, service_restricted, mocker ): service = create_sample_service(notify_db, notify_db_session, limit=2, restricted=service_restricted) apply_async = mocker.patch('app.celery.provider_tasks.deliver_{}.apply_async'.format(notification_type)) template = _create_sample_template(notify_db, notify_db_session, service=service) if notification_type == 'sms': service_whitelist = create_sample_service_whitelist(notify_db, notify_db_session, service=service, mobile_number=to) elif notification_type == 'email': service_whitelist = create_sample_service_whitelist(notify_db, notify_db_session, service=service, email_address=to) assert service_whitelist.service_id == service.id assert to in [member.recipient for member in service.whitelist] create_sample_notification(notify_db, notify_db_session, template=template, service=service) data = { 'to': to, 'template': str(template.id) } sample_key = create_sample_api_key(notify_db, notify_db_session, service, key_type=key_type) auth_header = create_jwt_token(secret=sample_key.unsigned_secret, client_id=str(sample_key.service_id)) response = client.post( path='/notifications/{}'.format(notification_type), data=json.dumps(data), headers=[('Content-Type', 'application/json'), ('Authorization', 'Bearer {}'.format(auth_header))]) json_resp = json.loads(response.get_data(as_text=True)) assert response.status_code == 201 assert json_resp['data']['notification']['id'] assert json_resp['data']['body'] == template.content assert json_resp['data']['template_version'] == template.version assert apply_async.called
def test_get_all_notifications_filter_by_id(client, notify_db, notify_db_session): older_notification = create_sample_notification(notify_db, notify_db_session) newer_notification = create_sample_notification(notify_db, notify_db_session) auth_header = create_authorization_header(service_id=newer_notification.service_id) response = client.get( path='/v2/notifications?older_than={}'.format(newer_notification.id), headers=[('Content-Type', 'application/json'), auth_header]) json_response = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert response.headers['Content-type'] == "application/json" assert json_response['links']['current'].endswith("/v2/notifications?older_than={}".format(newer_notification.id)) assert 'next' in json_response['links'].keys() assert len(json_response['notifications']) == 1 assert json_response['notifications'][0]['id'] == str(older_notification.id)
def test_get_all_notifications_newest_first(notify_api, notify_db, notify_db_session, sample_email_template): with notify_api.test_request_context(): with notify_api.test_client() as client: notification_1 = create_sample_notification(notify_db, notify_db_session, sample_email_template.service) notification_2 = create_sample_notification(notify_db, notify_db_session, sample_email_template.service) notification_3 = create_sample_notification(notify_db, notify_db_session, sample_email_template.service) auth_header = create_authorization_header(service_id=sample_email_template.service_id) response = client.get( '/notifications', headers=[auth_header]) notifications = json.loads(response.get_data(as_text=True)) assert len(notifications['notifications']) == 3 assert notifications['notifications'][0]['to'] == notification_3.to assert notifications['notifications'][1]['to'] == notification_2.to assert notifications['notifications'][2]['to'] == notification_1.to assert response.status_code == 200
def test_ses_callback_should_not_set_status_once_status_is_delivered( client, notify_db, notify_db_session, sample_email_template, mocker): notification = create_sample_notification(notify_db, notify_db_session, template=sample_email_template, reference='ref', status='delivered', sent_at=datetime.utcnow()) assert get_notification_by_id(notification.id).status == 'delivered'
def test_should_not_send_notification_to_non_whitelist_recipient_in_trial_mode( client, notify_db, notify_db_session, notification_type, to, _create_sample_template, key_type, mocker ): service = create_sample_service(notify_db, notify_db_session, limit=2, restricted=True) service_whitelist = create_sample_service_whitelist(notify_db, notify_db_session, service=service) apply_async = mocker.patch('app.celery.provider_tasks.deliver_{}.apply_async'.format(notification_type)) template = _create_sample_template(notify_db, notify_db_session, service=service) assert service_whitelist.service_id == service.id assert to not in [member.recipient for member in service.whitelist] create_sample_notification(notify_db, notify_db_session, template=template, service=service) data = { 'to': to, 'template': str(template.id) } api_key = create_sample_api_key(notify_db, notify_db_session, service, key_type=key_type) auth_header = create_jwt_token(secret=api_key.unsigned_secret, client_id=str(api_key.service_id)) response = client.post( path='/notifications/{}'.format(notification_type), data=json.dumps(data), headers=[('Content-Type', 'application/json'), ('Authorization', 'Bearer {}'.format(auth_header))]) expected_response_message = ( 'Can’t send to this recipient when service is in trial mode ' '– see https://www.notifications.service.gov.uk/trial-mode' ) if key_type == KEY_TYPE_NORMAL else ('Can’t send to this recipient using a team-only API key') json_resp = json.loads(response.get_data(as_text=True)) assert response.status_code == 400 assert json_resp['result'] == 'error' assert expected_response_message in json_resp['message']['to'] apply_async.assert_not_called()
def test_firetext_callback_should_set_status_technical_failure_if_status_unknown( client, notify_db, notify_db_session, mocker): notification = create_sample_notification( notify_db, notify_db_session, status='sending', sent_at=datetime.utcnow() ) mocker.patch('app.statsd_client.incr') data = 'mobile=61412345678&status=99&time=2016-03-10 14:17:00&reference={}'.format(notification.id) with pytest.raises(ClientException) as e: firetext_post(client, data) assert get_notification_by_id(notification.id).status == 'technical-failure' assert 'Firetext callback failed: status 99 not found.' in str(e.value)
def test_ses_callback_should_update_multiple_notification_status_sent( client, notify_db, notify_db_session, sample_email_template, mocker): send_mock = mocker.patch( 'app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async' ) create_sample_notification(notify_db, notify_db_session, template=sample_email_template, reference='ref1', sent_at=datetime.utcnow(), status='sending') create_sample_notification(notify_db, notify_db_session, template=sample_email_template, reference='ref2', sent_at=datetime.utcnow(), status='sending') create_sample_notification(notify_db, notify_db_session, template=sample_email_template, reference='ref3', sent_at=datetime.utcnow(), status='sending') create_service_callback_api(service=sample_email_template.service, url="https://original_url.com") assert process_ses_response( ses_notification_callback(reference='ref1')) is None assert process_ses_response( ses_notification_callback(reference='ref2')) is None assert process_ses_response( ses_notification_callback(reference='ref3')) is None assert send_mock.called
def test_firetext_callback_should_update_multiple_notification_status_sent( notify_api, notify_db, notify_db_session, mocker ): with notify_api.test_request_context(): with notify_api.test_client() as client: mocker.patch('app.statsd_client.incr') notification1 = create_sample_notification( notify_db, notify_db_session, status='sending', sent_at=datetime.utcnow() ) notification2 = create_sample_notification( notify_db, notify_db_session, status='sending', sent_at=datetime.utcnow() ) notification3 = create_sample_notification( notify_db, notify_db_session, status='sending', sent_at=datetime.utcnow() ) client.post( path='/notifications/sms/firetext', data='mobile=441234123123&status=0&time=2016-03-10 14:17:00&reference={}'.format( notification1.id ), headers=[('Content-Type', 'application/x-www-form-urlencoded')]) client.post( path='/notifications/sms/firetext', data='mobile=441234123123&status=0&time=2016-03-10 14:17:00&reference={}'.format( notification2.id ), headers=[('Content-Type', 'application/x-www-form-urlencoded')]) client.post( path='/notifications/sms/firetext', data='mobile=441234123123&status=0&time=2016-03-10 14:17:00&reference={}'.format( notification3.id ), headers=[('Content-Type', 'application/x-www-form-urlencoded')])
def test_get_notification_selects_correct_template_for_personalisation(notify_api, notify_db, notify_db_session, sample_template): create_sample_notification(notify_db, notify_db_session, service=sample_template.service, template=sample_template) original_content = sample_template.content sample_template.content = '((name))' dao_update_template(sample_template) notify_db.session.commit() create_sample_notification(notify_db, notify_db_session, service=sample_template.service, template=sample_template, personalisation={"name": "foo"}) with notify_api.test_request_context(), notify_api.test_client() as client: auth_header = create_authorization_header(service_id=sample_template.service_id) response = client.get(path='/notifications', headers=[auth_header]) assert response.status_code == 200 resp = json.loads(response.get_data(as_text=True)) notis = sorted(resp['notifications'], key=lambda x: x['template_version']) assert len(notis) == 2 assert notis[0]['template_version'] == 1 assert notis[0]['body'] == original_content assert notis[1]['template_version'] == 2 assert notis[1]['body'] == 'foo' assert notis[0]['template_version'] == notis[0]['template']['version'] assert notis[1]['template_version'] == notis[1]['template']['version']
def test_process_sendgrid_response(client, notify_db, notify_db_session, sample_email_template, mocker): notification = create_sample_notification(notify_db, notify_db_session, template=sample_email_template, reference='ref', status='created', sent_at=datetime.utcnow()) data = json.dumps([{"sg_message_id": "ref.abcd", "event": "delivered"}]) client.post(path='/notifications/email/sendgrid', data=data, headers=[('Content-Type', 'application/json')]) assert get_notification_by_id(notification.id).status == 'sent'
def test_get_all_notifications_filter_by_id_no_notifications_if_nonexistent_id(client, notify_db, notify_db_session): notification = create_sample_notification(notify_db, notify_db_session) auth_header = create_authorization_header(service_id=notification.service_id) response = client.get( path='/v2/notifications?older_than=dd4b8b9d-d414-4a83-9256-580046bf18f9', headers=[('Content-Type', 'application/json'), auth_header]) json_response = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert response.headers['Content-type'] == "application/json" assert json_response['links']['current'].endswith( "/v2/notifications?older_than=dd4b8b9d-d414-4a83-9256-580046bf18f9") assert 'next' not in json_response['links'].keys() assert len(json_response['notifications']) == 0
def test_get_notification_by_id_returns_200( client, notify_db, notify_db_session, sample_provider_rate, billable_units, provider ): sample_notification = create_sample_notification( notify_db, notify_db_session, billable_units=billable_units, sent_by=provider ) auth_header = create_authorization_header(service_id=sample_notification.service_id) response = client.get( path='/v2/notifications/{}'.format(sample_notification.id), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 200 assert response.headers['Content-type'] == 'application/json' json_response = json.loads(response.get_data(as_text=True)) expected_template_response = { 'id': '{}'.format(sample_notification.serialize()['template']['id']), 'version': sample_notification.serialize()['template']['version'], 'uri': sample_notification.serialize()['template']['uri'] } expected_response = { 'id': '{}'.format(sample_notification.id), 'reference': None, 'email_address': None, 'phone_number': '{}'.format(sample_notification.to), 'line_1': None, 'line_2': None, 'line_3': None, 'line_4': None, 'line_5': None, 'line_6': None, 'postcode': None, 'type': '{}'.format(sample_notification.notification_type), 'status': '{}'.format(sample_notification.status), 'template': expected_template_response, 'created_at': sample_notification.created_at.strftime(DATETIME_FORMAT), 'body': sample_notification.template.content, "subject": None, 'sent_at': sample_notification.sent_at, 'completed_at': sample_notification.completed_at() } assert json_response == expected_response
def test_get_notification_by_reference_returns_200(client, notify_db, notify_db_session): sample_notification_with_reference = create_sample_notification( notify_db, notify_db_session, client_reference='some-client-reference') auth_header = create_authorization_header(service_id=sample_notification_with_reference.service_id) response = client.get( path='/v2/notifications?reference={}'.format(sample_notification_with_reference.client_reference), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 200 assert response.headers['Content-type'] == 'application/json' json_response = json.loads(response.get_data(as_text=True)) assert len(json_response['notifications']) == 1 assert json_response['notifications'][0]['id'] == str(sample_notification_with_reference.id) assert json_response['notifications'][0]['reference'] == "some-client-reference"
def test_get_notification_by_id_with_placeholders_returns_200( client, notify_db, notify_db_session, sample_email_template_with_placeholders ): sample_notification = create_sample_notification( notify_db, notify_db_session, template=sample_email_template_with_placeholders, personalisation={"name": "Bob"} ) auth_header = create_authorization_header(service_id=sample_notification.service_id) response = client.get( path='/v2/notifications/{}'.format(sample_notification.id), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 200 assert response.headers['Content-type'] == 'application/json' json_response = json.loads(response.get_data(as_text=True)) expected_template_response = { 'id': '{}'.format(sample_notification.serialize()['template']['id']), 'version': sample_notification.serialize()['template']['version'], 'uri': sample_notification.serialize()['template']['uri'] } expected_response = { 'id': '{}'.format(sample_notification.id), 'reference': None, 'email_address': '{}'.format(sample_notification.to), 'phone_number': None, 'line_1': None, 'line_2': None, 'line_3': None, 'line_4': None, 'line_5': None, 'line_6': None, 'postcode': None, 'type': '{}'.format(sample_notification.notification_type), 'status': '{}'.format(sample_notification.status), 'template': expected_template_response, 'created_at': sample_notification.created_at.strftime(DATETIME_FORMAT), 'body': "Hello Bob\nThis is an email from GOV.\u200bUK", "subject": "Bob", 'sent_at': sample_notification.sent_at, 'completed_at': sample_notification.completed_at() } assert json_response == expected_response
def test_ses_callback_should_set_status_to_temporary_failure( client, notify_db, notify_db_session, sample_email_template, mocker): send_mock = mocker.patch( 'app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async' ) notification = create_sample_notification(notify_db, notify_db_session, template=sample_email_template, reference='ref', status='sending', sent_at=datetime.utcnow()) create_service_callback_api(service=notification.service, url="https://original_url.com") assert get_notification_by_id(notification.id).status == 'sending' assert process_ses_results(ses_soft_bounce_callback(reference='ref')) assert get_notification_by_id( notification.id).status == 'temporary-failure' assert send_mock.called
def test_process_mmg_response_unknown_status_updates_notification_with_technical_failure( notify_db, notify_db_session, client, mocker ): send_mock = mocker.patch( 'app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async' ) notification = create_sample_notification( notify_db, notify_db_session, status='sending', sent_at=datetime.utcnow() ) data = json.dumps({"reference": "mmg_reference", "CID": str(notification.id), "MSISDN": "447777349060", "status": 10}) create_service_callback_api(service=notification.service, url="https://original_url.com") with pytest.raises(ClientException) as e: mmg_post(client, data) assert 'MMG callback failed: status 10 not found.' in str(e.value) assert get_notification_by_id(notification.id).status == 'technical-failure' assert send_mock.called
def test_get_all_notifications_filter_multiple_query_parameters(client, notify_db, notify_db_session): email_template = create_sample_template(notify_db, notify_db_session, template_type="email") # this is the notification we are looking for older_notification = create_sample_notification( notify_db, notify_db_session, template=email_template, status="pending") # wrong status create_sample_notification(notify_db, notify_db_session, template=email_template) # wrong template create_sample_notification(notify_db, notify_db_session, status="pending") # we only want notifications created before this one newer_notification = create_sample_notification(notify_db, notify_db_session) # this notification was created too recently create_sample_notification(notify_db, notify_db_session, template=email_template, status="pending") auth_header = create_authorization_header(service_id=newer_notification.service_id) response = client.get( path='/v2/notifications?status=pending&template_type=email&older_than={}'.format(newer_notification.id), headers=[('Content-Type', 'application/json'), auth_header]) json_response = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert response.headers['Content-type'] == "application/json" # query parameters aren't returned in order for url_part in [ "/v2/notifications?", "template_type=email", "status=pending", "older_than={}".format(newer_notification.id) ]: assert url_part in json_response['links']['current'] assert 'next' in json_response['links'].keys() assert len(json_response['notifications']) == 1 assert json_response['notifications'][0]['id'] == str(older_notification.id)
def test_sap_callback_should_update_notification_status( notify_db, notify_db_session, client, sample_sap_oauth2_client, sample_email_template, mocker): mocker.patch('app.statsd_client.incr') send_mock = mocker.patch( 'app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async' ) notification = create_sample_notification(notify_db, notify_db_session, template=sample_email_template, reference='ref', status='sending', sent_at=datetime.utcnow()) original = get_notification_by_id(notification.id) assert original.status == 'sending' data = { "messageId": "1234", "status": "DELIVERED", "recipient": "+61412345678", "message": "message" } response = sap_post(client, sample_sap_oauth2_client, notification.id, data) json_resp = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert json_resp['result'] == 'success' assert json_resp[ 'message'] == 'sap callback succeeded. reference {} updated'.format( notification.id) updated = get_notification_by_id(notification.id) assert updated.status == 'delivered' assert get_notification_by_id(notification.id).status == 'delivered' assert send_mock.called_once_with([notification.id], queue="notify-internal-tasks")
def test_process_mmg_response_status_2_updates_notification_with_permanently_failed( notify_db, notify_db_session, notify_api ): with notify_api.test_client() as client: notification = create_sample_notification( notify_db, notify_db_session, status='sending', sent_at=datetime.utcnow() ) data = json.dumps({"reference": "mmg_reference", "CID": str(notification.id), "MSISDN": "447777349060", "status": 2}) response = client.post(path='notifications/sms/mmg', data=data, headers=[('Content-Type', 'application/json')]) assert response.status_code == 200 json_data = json.loads(response.data) assert json_data['result'] == 'success' assert json_data['message'] == 'MMG callback succeeded. reference {} updated'.format(notification.id) assert get_notification_by_id(notification.id).status == 'permanent-failure'