def test_user_verify_password_valid_password_resets_failed_logins(notify_api, sample_user): with notify_api.test_request_context(): with notify_api.test_client() as client: data = json.dumps({'password': '******'}) auth_header = create_authorization_header() assert sample_user.failed_login_count == 0 resp = client.post( url_for('user.verify_user_password', user_id=sample_user.id), data=data, headers=[('Content-Type', 'application/json'), auth_header]) assert resp.status_code == 400 json_resp = json.loads(resp.get_data(as_text=True)) assert 'Incorrect password' in json_resp['message']['password'] assert sample_user.failed_login_count == 1 data = json.dumps({'password': '******'}) auth_header = create_authorization_header() resp = client.post( url_for('user.verify_user_password', user_id=sample_user.id), data=data, headers=[('Content-Type', 'application/json'), auth_header]) assert resp.status_code == 204 assert sample_user.failed_login_count == 0
def test_api_key_should_create_multiple_new_api_key_for_service(notify_api, notify_db, notify_db_session, sample_service): with notify_api.test_request_context(): with notify_api.test_client() as client: assert ApiKey.query.count() == 0 data = {'name': 'some secret name'} auth_header = create_authorization_header(path=url_for('service.renew_api_key', service_id=sample_service.id), method='POST', request_body=json.dumps(data)) response = client.post(url_for('service.renew_api_key', service_id=sample_service.id), data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 201 assert ApiKey.query.count() == 1 data = {'name': 'another secret name'} auth_header = create_authorization_header(path=url_for('service.renew_api_key', service_id=sample_service.id), method='POST', request_body=json.dumps(data)) response2 = client.post(url_for('service.renew_api_key', service_id=sample_service.id), data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) assert response2.status_code == 201 assert response2.get_data != response.get_data assert ApiKey.query.count() == 2
def test_get_provider_details_by_id(client, notify_db): response = client.get( '/provider-details', headers=[create_authorization_header()] ) json_resp = json.loads(response.get_data(as_text=True))['provider_details'] provider_resp = client.get( '/provider-details/{}'.format(json_resp[0]['id']), headers=[create_authorization_header()] ) provider = json.loads(provider_resp.get_data(as_text=True))['provider_details'] assert provider['identifier'] == json_resp[0]['identifier']
def test_should_be_able_to_get_all_templates_for_a_service(client, sample_user, sample_service): data = { 'name': 'my template 1', 'template_type': 'email', 'subject': 'subject 1', 'content': 'template content', 'service': str(sample_service.id), 'created_by': str(sample_user.id) } data_1 = json.dumps(data) data = { 'name': 'my template 2', 'template_type': 'email', 'subject': 'subject 2', 'content': 'template content', 'service': str(sample_service.id), 'created_by': str(sample_user.id) } data_2 = json.dumps(data) auth_header = create_authorization_header() client.post( '/service/{}/template'.format(sample_service.id), headers=[('Content-Type', 'application/json'), auth_header], data=data_1 ) auth_header = create_authorization_header() client.post( '/service/{}/template'.format(sample_service.id), headers=[('Content-Type', 'application/json'), auth_header], data=data_2 ) auth_header = create_authorization_header() response = client.get( '/service/{}/template'.format(sample_service.id), headers=[auth_header] ) assert response.status_code == 200 update_json_resp = json.loads(response.get_data(as_text=True)) assert update_json_resp['data'][0]['name'] == 'my template 2' assert update_json_resp['data'][0]['version'] == 1 assert update_json_resp['data'][0]['created_at'] assert update_json_resp['data'][1]['name'] == 'my template 1' assert update_json_resp['data'][1]['version'] == 1 assert update_json_resp['data'][1]['created_at']
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_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_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_get_whitelist_returns_no_data(client, sample_service): path = 'service/{}/whitelist'.format(sample_service.id) response = client.get(path, headers=[create_authorization_header()]) assert response.status_code == 200 assert json.loads(response.get_data(as_text=True)) == {'email_addresses': [], 'phone_numbers': []}
def test_get_api_keys_should_return_all_keys_for_service(notify_api, notify_db, notify_db_session, sample_api_key): with notify_api.test_request_context(): with notify_api.test_client() as client: another_user = create_user(notify_db, notify_db_session, email='*****@*****.**') another_service = create_sample_service( notify_db, notify_db_session, service_name='another', user=another_user, email_from='another' ) # key for another service create_sample_api_key(notify_db, notify_db_session, service=another_service) # this service already has one key, add two more, one expired create_sample_api_key(notify_db, notify_db_session, service=sample_api_key.service) one_to_expire = create_sample_api_key(notify_db, notify_db_session, service=sample_api_key.service) expire_api_key(service_id=one_to_expire.service_id, api_key_id=one_to_expire.id) assert ApiKey.query.count() == 4 auth_header = create_authorization_header() response = client.get(url_for('service.get_api_keys', service_id=sample_api_key.service_id), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 200 json_resp = json.loads(response.get_data(as_text=True)) assert len(json_resp['apiKeys']) == 3
def test_get_all_invited_users_by_service(notify_api, notify_db, notify_db_session, sample_service): from tests.app.conftest import sample_invited_user invites = [] for i in range(0, 5): email = 'invited_user_{}@service.gov.uk'.format(i) invited_user = sample_invited_user(notify_db, notify_db_session, sample_service, email) invites.append(invited_user) with notify_api.test_request_context(): with notify_api.test_client() as client: url = '/service/{}/invite'.format(sample_service.id) auth_header = create_authorization_header() response = client.get( url, headers=[('Content-Type', 'application/json'), auth_header] ) assert response.status_code == 200 json_resp = json.loads(response.get_data(as_text=True)) invite_from = sample_service.users[0] for invite in json_resp['data']: assert invite['service'] == str(sample_service.id) assert invite['from_user'] == str(invite_from.id) assert invite['id']
def test_create_invited_user_invalid_email(notify_api, sample_service, mocker): with notify_api.test_request_context(): with notify_api.test_client() as client: mocker.patch('app.celery.tasks.send_email.apply_async') email_address = 'notanemail' invite_from = sample_service.users[0] data = { 'service': str(sample_service.id), 'email_address': email_address, 'from_user': str(invite_from.id), 'permissions': 'send_messages,manage_service,manage_api_keys' } data = json.dumps(data) auth_header = create_authorization_header() response = client.post( '/service/{}/invite'.format(sample_service.id), headers=[('Content-Type', 'application/json'), auth_header], data=data ) assert response.status_code == 400 json_resp = json.loads(response.get_data(as_text=True)) assert json_resp['result'] == 'error' assert json_resp['message'] == {'email_address': ['Not a valid email address.']} app.celery.tasks.send_email.apply_async.assert_not_called()
def test_should_preview_a_single_template( notify_db, client, sample_user, service_factory, subject, content, path, expected_subject, expected_content, expected_error ): template = create_sample_template( notify_db, notify_db.session, subject_line=subject, content=content, template_type='email' ) response = client.get( path.format(template.service.id, template.id), headers=[create_authorization_header()] ) content = json.loads(response.get_data(as_text=True)) if expected_error: assert response.status_code == 400 assert content['message']['template'] == [expected_error] else: assert response.status_code == 200 assert content['content'] == expected_content assert content['subject'] == expected_subject
def test_should_create_a_new_template_for_a_service( client, sample_user, sample_service, template_type, subject ): data = { 'name': 'my template', 'template_type': template_type, 'content': 'template <b>content</b>', 'service': str(sample_service.id), 'created_by': str(sample_user.id) } if subject: data.update({'subject': subject}) data = json.dumps(data) auth_header = create_authorization_header() response = client.post( '/service/{}/template'.format(sample_service.id), headers=[('Content-Type', 'application/json'), auth_header], data=data ) assert response.status_code == 201 json_resp = json.loads(response.get_data(as_text=True)) assert json_resp['data']['name'] == 'my template' assert json_resp['data']['template_type'] == template_type assert json_resp['data']['content'] == 'template content' assert json_resp['data']['service'] == str(sample_service.id) assert json_resp['data']['id'] assert json_resp['data']['version'] == 1 if subject: assert json_resp['data']['subject'] == 'subject' else: assert not json_resp['data']['subject']
def test_post_email_notification_returns_201(client, sample_email_template_with_placeholders, mocker, reference): mocked = mocker.patch('app.celery.provider_tasks.deliver_email.apply_async') data = { "email_address": sample_email_template_with_placeholders.service.users[0].email_address, "template_id": sample_email_template_with_placeholders.id, "personalisation": {"name": "Bob"} } if reference: data.update({"reference": reference}) auth_header = create_authorization_header(service_id=sample_email_template_with_placeholders.service_id) response = client.post( path="v2/notifications/email", data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 201 resp_json = json.loads(response.get_data(as_text=True)) notification = Notification.query.first() assert resp_json['id'] == str(notification.id) assert resp_json['reference'] == reference assert notification.reference is None assert resp_json['content']['body'] == sample_email_template_with_placeholders.content\ .replace('((name))', 'Bob').replace('GOV.UK', u'GOV.\u200bUK') assert resp_json['content']['subject'] == sample_email_template_with_placeholders.subject\ .replace('((name))', 'Bob') assert resp_json['content']['from_email'] == sample_email_template_with_placeholders.service.email_from assert 'v2/notifications/{}'.format(notification.id) in resp_json['uri'] assert resp_json['template']['id'] == str(sample_email_template_with_placeholders.id) assert resp_json['template']['version'] == sample_email_template_with_placeholders.version assert 'v2/templates/{}'.format(sample_email_template_with_placeholders.id) in resp_json['template']['uri'] assert mocked.called
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_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_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(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_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_set_user_permissions_multiple(notify_api, notify_db, notify_db_session, sample_user, sample_service): with notify_api.test_request_context(): with notify_api.test_client() as client: data = json.dumps([{'permission': MANAGE_SETTINGS}, {'permission': MANAGE_TEMPLATES}]) header = create_authorization_header() headers = [('Content-Type', 'application/json'), header] response = client.post( url_for( 'user.set_permissions', user_id=str(sample_user.id), service_id=str(sample_service.id)), headers=headers, data=data) assert response.status_code == 204 permission = Permission.query.filter_by(permission=MANAGE_SETTINGS).first() assert permission.user == sample_user assert permission.service == sample_service assert permission.permission == MANAGE_SETTINGS permission = Permission.query.filter_by(permission=MANAGE_TEMPLATES).first() assert permission.user == sample_user assert permission.service == sample_service assert permission.permission == MANAGE_TEMPLATES
def test_send_user_reset_password_should_send_reset_password_link(notify_api, sample_user, mocker, password_reset_email_template): with notify_api.test_request_context(): with notify_api.test_client() as client: mocker.patch('notifications_utils.url_safe_token.generate_token', return_value='the-token') mocker.patch('uuid.uuid4', return_value='some_uuid') # for the notification id mocker.patch('app.celery.tasks.send_email.apply_async') data = json.dumps({'email': sample_user.email_address}) auth_header = create_authorization_header() resp = client.post( url_for('user.send_user_reset_password'), data=data, headers=[('Content-Type', 'application/json'), auth_header]) message = { 'template': str(password_reset_email_template.id), 'template_version': password_reset_email_template.version, 'to': sample_user.email_address, 'personalisation': { 'user_name': sample_user.name, 'url': current_app.config['ADMIN_BASE_URL'] + '/new-password/' + 'the-token' } } assert resp.status_code == 204 app.celery.tasks.send_email.apply_async.assert_called_once_with( [str(current_app.config['NOTIFY_SERVICE_ID']), 'some_uuid', app.encryption.encrypt(message), "2016-01-01T11:09:00.061258Z"], queue="notify")
def test_send_already_registered_email(notify_api, sample_user, already_registered_template, mocker): with notify_api.test_request_context(): with notify_api.test_client() as client: data = json.dumps({'email': sample_user.email_address}) auth_header = create_authorization_header() mocker.patch('app.celery.tasks.send_email.apply_async') mocker.patch('uuid.uuid4', return_value='some_uuid') # for the notification id resp = client.post( url_for('user.send_already_registered_email', user_id=str(sample_user.id)), data=data, headers=[('Content-Type', 'application/json'), auth_header]) assert resp.status_code == 204 message = { 'template': str(already_registered_template.id), 'template_version': already_registered_template.version, 'to': sample_user.email_address, 'personalisation': { 'signin_url': current_app.config['ADMIN_BASE_URL'] + '/sign-in', 'forgot_password_url': current_app.config['ADMIN_BASE_URL'] + '/forgot-password', 'feedback_url': current_app.config['ADMIN_BASE_URL'] + '/feedback' } } app.celery.tasks.send_email.apply_async.assert_called_once_with( (str(current_app.config['NOTIFY_SERVICE_ID']), 'some_uuid', app.encryption.encrypt(message), "2016-01-01T11:09:00.061258Z"), queue="notify")
def test_post_user(notify_api, notify_db, notify_db_session): """ Tests POST endpoint '/' to create a user. """ with notify_api.test_request_context(): with notify_api.test_client() as client: assert User.query.count() == 0 data = { "name": "Test User", "email_address": "*****@*****.**", "password": "******", "mobile_number": "+447700900986", "logged_in_at": None, "state": "active", "failed_login_count": 0, "permissions": {} } auth_header = create_authorization_header() headers = [('Content-Type', 'application/json'), auth_header] resp = client.post( url_for('user.create_user'), data=json.dumps(data), headers=headers) assert resp.status_code == 201 user = User.query.filter_by(email_address='*****@*****.**').first() json_resp = json.loads(resp.get_data(as_text=True)) assert json_resp['data']['email_address'] == user.email_address assert json_resp['data']['id'] == str(user.id)
def test_put_user(notify_api, notify_db, notify_db_session, sample_service): """ Tests PUT endpoint '/' to update a user. """ with notify_api.test_request_context(): with notify_api.test_client() as client: assert User.query.count() == 1 sample_user = sample_service.users[0] new_email = '*****@*****.**' data = { 'name': sample_user.name, 'email_address': new_email, 'mobile_number': sample_user.mobile_number } auth_header = create_authorization_header() headers = [('Content-Type', 'application/json'), auth_header] resp = client.put( url_for('user.update_user', user_id=sample_user.id), data=json.dumps(data), headers=headers) assert resp.status_code == 200 assert User.query.count() == 1 json_resp = json.loads(resp.get_data(as_text=True)) assert json_resp['data']['email_address'] == new_email expected_permissions = default_service_permissions fetched = json_resp['data'] assert str(sample_user.id) == fetched['id'] assert sample_user.name == fetched['name'] assert sample_user.mobile_number == fetched['mobile_number'] assert new_email == fetched['email_address'] assert sample_user.state == fetched['state'] assert sorted(expected_permissions) == sorted(fetched['permissions'][str(sample_service.id)])
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_send_user_code_for_sms_with_optional_to_field(notify_api, sample_user, sms_code_template, mocker): """ Tests POST endpoint /user/<user_id>/sms-code with optional to field """ with notify_api.test_request_context(): with notify_api.test_client() as client: to_number = '+441119876757' mocked = mocker.patch('app.user.rest.create_secret_code', return_value='11111') mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') data = json.dumps({'to': to_number}) auth_header = create_authorization_header() resp = client.post( url_for('user.send_user_sms_code', user_id=sample_user.id), data=data, headers=[('Content-Type', 'application/json'), auth_header]) assert resp.status_code == 204 assert mocked.call_count == 1 notification = Notification.query.first() assert notification.to == to_number app.celery.provider_tasks.deliver_sms.apply_async.assert_called_once_with( ([str(notification.id)]), queue="notify" )
def test_user_verify_code_email_bad_code(notify_api, notify_db, notify_db_session, sample_admin_service_id, sample_email_code): """ Tests POST endpoint '/<user_id>/verify/code' """ with notify_api.test_request_context(): with notify_api.test_client() as client: assert not VerifyCode.query.first().code_used data = json.dumps({ 'code_type': sample_email_code.code_type, 'code': "blah"}) auth_header = create_authorization_header( service_id=sample_admin_service_id, path=url_for('user.verify_user_code', user_id=sample_email_code.user.id), method='POST', request_body=data) resp = client.post( url_for('user.verify_user_code', user_id=sample_email_code.user.id), data=data, headers=[('Content-Type', 'application/json'), auth_header]) assert resp.status_code == 404 assert not VerifyCode.query.first().code_used
def test_post_user_missing_attribute_email(notify_api, notify_db, notify_db_session): """ Tests POST endpoint '/' missing attribute email. """ with notify_api.test_request_context(): with notify_api.test_client() as client: assert User.query.count() == 0 data = { "name": "Test User", "password": "******", "mobile_number": "+447700900986", "logged_in_at": None, "state": "active", "failed_login_count": 0, "permissions": {} } auth_header = create_authorization_header() headers = [('Content-Type', 'application/json'), auth_header] resp = client.post( url_for('user.create_user'), data=json.dumps(data), headers=headers) assert resp.status_code == 400 assert User.query.count() == 0 json_resp = json.loads(resp.get_data(as_text=True)) assert {'email_address': ['Missing data for required field.']} == json_resp['message']
def test_post_sms_notification_returns_201(notify_api, sample_template_with_placeholders, mocker, reference): with notify_api.test_request_context(): with notify_api.test_client() as client: mocked = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') data = { 'phone_number': '+447700900855', 'template_id': str(sample_template_with_placeholders.id), 'personalisation': {' Name': 'Jo'} } if reference: data.update({"reference": reference}) auth_header = create_authorization_header(service_id=sample_template_with_placeholders.service_id) response = client.post( path='/v2/notifications/sms', data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 201 resp_json = json.loads(response.get_data(as_text=True)) notifications = Notification.query.all() assert len(notifications) == 1 notification_id = notifications[0].id assert resp_json['id'] == str(notification_id) assert resp_json['reference'] == reference assert resp_json['content']['body'] == sample_template_with_placeholders.content.replace("(( Name))", "Jo") # conftest fixture service does not have a sms sender, use config default assert resp_json['content']['from_number'] == notify_api.config["FROM_NUMBER"] assert 'v2/notifications/{}'.format(notification_id) in resp_json['uri'] assert resp_json['template']['id'] == str(sample_template_with_placeholders.id) assert resp_json['template']['version'] == sample_template_with_placeholders.version assert 'v2/templates/{}'.format(sample_template_with_placeholders.id) in resp_json['template']['uri'] assert mocked.called
def test_get_user_list(notify_api, notify_db, notify_db_session, sample_user, sample_admin_service_id): """ Tests GET endpoint '/' to retrieve entire user list. """ with notify_api.test_request_context(): with notify_api.test_client() as client: header = create_authorization_header(service_id=sample_admin_service_id, path=url_for('user.get_user'), method='GET') response = client.get(url_for('user.get_user'), headers=[header]) assert response.status_code == 200 json_resp = json.loads(response.get_data(as_text=True)) assert len(json_resp['data']) == 2 expected = { "name": "Test User", "email_address": sample_user.email_address, "id": sample_user.id, "mobile_number": "+447700900986", "password_changed_at": None, "logged_in_at": None, "state": "active", "failed_login_count": 0 } assert expected in json_resp['data']
def test_create_job_returns_404_if_template_does_not_exist( notify_api, sample_service, mocker): with notify_api.test_request_context(): with notify_api.test_client() as client: mocker.patch('app.celery.tasks.process_job.apply_async') data = {'template': str(sample_service.id)} path = '/service/{}/job'.format(sample_service.id) auth_header = create_authorization_header() headers = [('Content-Type', 'application/json'), auth_header] response = client.post(path, data=json.dumps(data), headers=headers) resp_json = json.loads(response.get_data(as_text=True)) assert response.status_code == 404 app.celery.tasks.process_job.apply_async.assert_not_called() assert resp_json['result'] == 'error' assert resp_json['message'] == 'No result found'
def test_should_not_return_html_in_body(notify_api, sample_service, mocker): with notify_api.test_request_context(): with notify_api.test_client() as client: mocker.patch('app.celery.provider_tasks.deliver_email.apply_async') email_template = create_template(sample_service, template_type=EMAIL_TYPE, content='hello\nthere') data = { 'to': '*****@*****.**', 'template': str(email_template.id) } auth_header = create_authorization_header(service_id=email_template.service_id) response = client.post( path='/notifications/email', data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 201 assert json.loads(response.get_data(as_text=True))['data']['body'] == 'hello\nthere'
def test_post_notification_returns_201_when_content_type_is_missing_but_payload_is_valid_json( client, sample_service, notification_type, mocker): template = create_template(service=sample_service, template_type=notification_type) mocker.patch('app.celery.provider_tasks.deliver_{}.apply_async'.format(notification_type)) auth_header = create_authorization_header(service_id=sample_service.id) valid_json = { "template_id": str(template.id), } if notification_type == 'email': valid_json.update({"email_address": sample_service.users[0].email_address}) else: valid_json.update({"phone_number": "+447700900855"}) response = client.post( path='/v2/notifications/{}'.format(notification_type), data=json.dumps(valid_json), headers=[auth_header], ) assert response.status_code == 201
def test_get_all_notifications_filter_by_id_no_notifications_if_nonexistent_id( client, sample_template): notification = create_notification(template=sample_template) 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_filter_by_status_and_template_type(client, sample_template, sample_email_template): create_notification(sample_template) create_notification(sample_email_template) create_notification(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_set_user_folder_permissions_when_user_does_not_belong_to_service( client, sample_user): service = create_service() tf1 = create_template_folder(service) tf2 = create_template_folder(service) data = json.dumps({ 'permissions': [], 'folder_permissions': [str(tf1.id), str(tf2.id)] }) response = client.post(url_for('user.set_permissions', user_id=str(sample_user.id), service_id=str(service.id)), headers=[('Content-Type', 'application/json'), create_authorization_header()], data=data) assert response.status_code == 404
def test_should_error_if_created_by_missing(client, sample_user, sample_service): service_id = str(sample_service.id) data = { 'name': 'my template', 'template_type': SMS_TYPE, 'content': 'template content', 'service': service_id } data = json.dumps(data) auth_header = create_authorization_header() response = client.post('/service/{}/template'.format(service_id), headers=[('Content-Type', 'application/json'), auth_header], data=data) json_resp = json.loads(response.get_data(as_text=True)) assert response.status_code == 400 assert json_resp['result'] == 'error'
def test_get_pdf_for_notification_fails_for_non_letters( client, sample_notification): auth_header = create_authorization_header( service_id=sample_notification.service_id) response = client.get( path=url_for( "v2_notifications.get_pdf_for_notification", notification_id=sample_notification.id, ), headers=[("Content-Type", "application/json"), auth_header], ) assert response.status_code == 400 assert response.json["errors"] == [{ "error": "BadRequestError", "message": "Notification is not a letter" }]
def test_get_all_notifications_filter_by_id_no_notifications_if_last_notification( client, sample_template): notification = create_notification(template=sample_template) auth_header = create_authorization_header( service_id=notification.service_id) response = client.get( path="/v2/notifications?older_than={}".format(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(notification.id)) assert "next" not in json_response["links"].keys() assert len(json_response["notifications"]) == 0
def test_remove_user_folder_permissions(client, sample_user, sample_service): tf1 = create_template_folder(sample_service) tf2 = create_template_folder(sample_service) service_user = dao_get_service_user(sample_user.id, sample_service.id) service_user.folders = [tf1, tf2] dao_update_service_user(service_user) data = json.dumps({'permissions': [], 'folder_permissions': []}) response = client.post(url_for('user.set_permissions', user_id=str(sample_user.id), service_id=str(sample_service.id)), headers=[('Content-Type', 'application/json'), create_authorization_header()], data=data) assert response.status_code == 204 assert service_user.folders == []
def test_send_template_content(notify_api, notify_db, notify_db_session, sample_api_key, sample_template, sample_user, mocker): """ Test POST endpoint '/sms' with service notification. """ with notify_api.test_request_context(): with notify_api.test_client() as client: mocker.patch('app.notify_alpha_client.send_sms', return_value={ "notification": { "createdAt": "2015-11-03T09:37:27.414363Z", "id": 100, "jobId": 65, "message": sample_template.content, "method": "sms", "status": "created", "to": sample_user.mobile_number } }) data = { 'notification': { 'to': sample_user.mobile_number, 'template': sample_template.id } } auth_header = create_authorization_header( service_id=sample_template.service.id, request_body=json.dumps(data), path=url_for('notifications.create_sms_notification'), method='POST') response = client.post( url_for('notifications.create_sms_notification'), data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) json_resp = json.loads(response.get_data(as_text=True)) assert response.status_code == 200 assert json_resp['notification']['id'] == 100 notify_alpha_client.send_sms.assert_called_with( mobile_number=sample_user.mobile_number, message=sample_template.content)
def test_update_template_reply_to_updates_history(client, sample_letter_template): auth_header = create_authorization_header() letter_contact = create_letter_contact(sample_letter_template.service, "Edinburgh, ED1 1AA") sample_letter_template.reply_to = letter_contact.id dao_update_template(sample_letter_template) resp = client.get('/service/{}/template/{}/version/2'.format( sample_letter_template.service_id, sample_letter_template.id), headers=[auth_header]) assert resp.status_code == 200 hist_json_resp = json.loads(resp.get_data(as_text=True)) assert 'service_letter_contact_id' not in hist_json_resp['data'] assert hist_json_resp['data']['reply_to'] == str(letter_contact.id) assert hist_json_resp['data'][ 'reply_to_text'] == letter_contact.contact_block
def test_get_all_notifications_filter_by_status_invalid_status( client, sample_notification): auth_header = create_authorization_header( service_id=sample_notification.service_id) response = client.get(path='/v2/notifications?status=elephant', headers=[('Content-Type', 'application/json'), auth_header]) json_response = json.loads(response.get_data(as_text=True)) assert response.status_code == 400 assert response.headers['Content-type'] == "application/json" assert json_response['status_code'] == 400 assert len(json_response['errors']) == 1 assert json_response['errors'][0]['message'] == "status elephant is not one of [cancelled, created, sending, " \ "sent, delivered, pending, failed, technical-failure, temporary-failure, permanent-failure, " \ "pending-virus-check, validation-failed, virus-scan-failed, returned-letter, " \ "pii-check-failed, accepted, received]"
def test_send_sms_code_returns_204_when_too_many_codes_already_created(client, sample_user): for i in range(10): verify_code = VerifyCode( code_type='sms', _code=12345, created_at=datetime.utcnow() - timedelta(minutes=10), expiry_datetime=datetime.utcnow() + timedelta(minutes=40), user=sample_user ) db.session.add(verify_code) db.session.commit() assert VerifyCode.query.count() == 10 auth_header = create_authorization_header() resp = client.post( url_for('user.send_user_2fa_code', code_type='sms', user_id=sample_user.id), data=json.dumps({}), headers=[('Content-Type', 'application/json'), auth_header]) assert resp.status_code == 204 assert VerifyCode.query.count() == 10
def test_update_guest_list_replaces_old_guest_list(client, sample_service_guest_list): data = { 'email_addresses': ['*****@*****.**'], 'phone_numbers': ['07123456789'] } response = client.put( f'service/{sample_service_guest_list.service_id}/guest-list', data=json.dumps(data), headers=[('Content-Type', 'application/json'), create_authorization_header()]) assert response.status_code == 204 guest_list = ServiceGuestList.query.order_by( ServiceGuestList.recipient).all() assert len(guest_list) == 2 assert guest_list[0].recipient == '07123456789' assert guest_list[1].recipient == '*****@*****.**'
def test_get_all_notifications_filter_by_single_status(client, sample_template): notification = create_notification(template=sample_template, status="pending") create_notification(template=sample_template) auth_header = create_authorization_header(service_id=notification.service_id) response = client.get( path='/v2/notifications?status=pending', 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=pending") 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'] == "pending"
def test_valid_post_broadcast_returns_201( client, sample_broadcast_service, ): auth_header = create_authorization_header( service_id=sample_broadcast_service.id) response = client.post( path='/v2/broadcast', data=json.dumps({ 'content': 'This is a test', 'reference': 'abc123', 'category': 'Other', 'areas': [ { 'name': 'Hackney Marshes', 'polygons': [[ [-0.038280487060546875, 51.55738264619775], [-0.03184318542480469, 51.553913882566754], [-0.023174285888671875, 51.55812972989382], [-0.023174285888671999, 51.55812972989999], [-0.029869079589843747, 51.56165153059717], [-0.038280487060546875, 51.55738264619775], ]], }, ], }), headers=[('Content-Type', 'application/json'), auth_header], ) assert response.status_code == 415 assert json.loads(response.get_data(as_text=True)) == { 'errors': [{ 'error': 'BadRequestError', 'message': 'Content type application/json not supported' }], 'status_code': 415, }
def test_get_template_by_id_returns_placeholders( client, sample_service, version, create_template_args, expected_personalisation, ): template = create_template(sample_service, **create_template_args) auth_header = create_authorization_header(service_id=sample_service.id) version_path = '/version/{}'.format(version) if version else '' response = client.get(path='/v2/template/{}{}'.format( template.id, version_path), headers=[('Content-Type', 'application/json'), auth_header]) json_response = json.loads(response.get_data(as_text=True)) assert json_response['personalisation'] == expected_personalisation
def test_get_notification_by_id_nonexistent_id(client, sample_notification): auth_header = create_authorization_header(service_id=sample_notification.service_id) response = client.get( path='/v2/notifications/dd4b8b9d-d414-4a83-9256-580046bf18f9', headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 404 assert response.headers['Content-type'] == 'application/json' json_response = json.loads(response.get_data(as_text=True)) assert json_response == { "errors": [ { "error": "NoResultFound", "message": "No result found" } ], "status_code": 404 }
def test_post_email_notification_with_invalid_reply_to_id_returns_400( client, sample_email_template, mocker, fake_uuid): mocker.patch('app.celery.provider_tasks.deliver_email.apply_async') data = { "email_address": sample_email_template.service.users[0].email_address, "template_id": sample_email_template.id, 'email_reply_to_id': fake_uuid } auth_header = create_authorization_header( service_id=sample_email_template.service_id) response = client.post(path="v2/notifications/email", data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 400 resp_json = json.loads(response.get_data(as_text=True)) assert 'email_reply_to_id {} does not exist in database for service id {}'. \ format(fake_uuid, sample_email_template.service_id) in resp_json['errors'][0]['message'] assert 'BadRequestError' in resp_json['errors'][0]['error']
def test_get_notification_by_id_invalid_id(client, sample_notification, id): auth_header = create_authorization_header( service_id=sample_notification.service_id) response = client.get(path='/v2/notifications/{}'.format(id), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 400 assert response.headers['Content-type'] == 'application/json' json_response = json.loads(response.get_data(as_text=True)) assert json_response == { "errors": [{ "error": "ValidationError", "message": "notification_id is not a valid UUID" }], "status_code": 400 }
def test_user_verify_code_expired_code_and_increments_failed_login_count( client, sample_sms_code): assert not VerifyCode.query.first().code_used sample_sms_code.expiry_datetime = (datetime.utcnow() - timedelta(hours=1)) db.session.add(sample_sms_code) db.session.commit() data = json.dumps({ 'code_type': sample_sms_code.code_type, 'code': sample_sms_code.txt_code }) auth_header = create_authorization_header() resp = client.post(url_for('user.verify_user_code', user_id=sample_sms_code.user.id), data=data, headers=[('Content-Type', 'application/json'), auth_header]) assert resp.status_code == 400 assert not VerifyCode.query.first().code_used assert User.query.get(sample_sms_code.user.id).failed_login_count == 1
def test_get_inbound_sms_returns_200_when_service_has_callbacks( client, sample_service ): create_service_inbound_api( service=sample_service, url="https://inbound.example.com", ) create_service_callback_api( service=sample_service, url="https://inbound.example.com", ) auth_header = create_authorization_header(service_id=sample_service.id) response = client.get( path='/v2/received-text-messages', headers=[('Content-Type', 'application/json'), auth_header], ) assert response.status_code == 200
def test_post_notification_with_document_upload(client, notify_db, notify_db_session, mocker): service = sample_service(notify_db, notify_db_session, permissions=[EMAIL_TYPE, UPLOAD_DOCUMENT]) template = create_sample_template(notify_db, notify_db_session, service=service, template_type='email', content="Document: ((document))") mocker.patch('app.celery.provider_tasks.deliver_email.apply_async') document_download_mock = mocker.patch( 'app.v2.notifications.post_notifications.document_download_client') document_download_mock.upload_document.return_value = 'https://document-url/' data = { "email_address": service.users[0].email_address, "template_id": template.id, "personalisation": { "document": { "file": "abababab" } } } auth_header = create_authorization_header(service_id=service.id) response = client.post(path="v2/notifications/email", data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 201, response.get_data(as_text=True) resp_json = json.loads(response.get_data(as_text=True)) assert validate(resp_json, post_email_response) == resp_json notification = Notification.query.one() assert notification.status == NOTIFICATION_CREATED assert notification.personalisation == { 'document': 'https://document-url/' } assert resp_json['content']['body'] == 'Document: https://document-url/'
def test_get_notification_by_id_returns_merged_template_content_for_email( client, sample_email_template_with_placeholders ): sample_notification = create_notification( sample_email_template_with_placeholders, personalisation={"name": "world"} ) auth_header = create_authorization_header(service_id=sample_notification.service_id) response = client.get( '/notifications/{}'.format(sample_notification.id), headers=[auth_header]) notification = json.loads(response.get_data(as_text=True))['data']['notification'] assert response.status_code == 200 assert notification['body'] == 'Hello world\nThis is an email from GOV.UK' assert notification['subject'] == 'world' assert notification['content_char_count'] is None
def test_create_notification_should_reject_if_missing_required_fields(notify_api, sample_api_key, mocker, template_type): with notify_api.test_request_context(): with notify_api.test_client() as client: mocked = mocker.patch('app.celery.provider_tasks.deliver_{}.apply_async'.format(template_type)) data = {} auth_header = create_authorization_header(service_id=sample_api_key.service_id) response = client.post( path='/notifications/{}'.format(template_type), data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) json_resp = json.loads(response.get_data(as_text=True)) mocked.assert_not_called() assert json_resp['result'] == 'error' assert 'Missing data for required field.' in json_resp['message']['to'][0] assert 'Missing data for required field.' in json_resp['message']['template'][0] assert response.status_code == 400
def test_post_notification_returns_400_and_missing_template( client, sample_service, notification_type, key_send_to, send_to): data = {key_send_to: send_to, 'template_id': str(uuid.uuid4())} auth_header = create_authorization_header(service_id=sample_service.id) response = client.post( path='/v2/notifications/{}'.format(notification_type), data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 400 assert response.headers['Content-type'] == 'application/json' error_json = json.loads(response.get_data(as_text=True)) assert error_json['status_code'] == 400 assert error_json['errors'] == [{ "error": "BadRequestError", "message": 'Template not found' }]
def test_get_provider_contains_correct_fields(client, sample_service, sample_template): create_ft_billing('2018-06-01', 'sms', sample_template, sample_service, provider='mmg', billable_unit=1) response = client.get('/provider-details', headers=[create_authorization_header()]) json_resp = json.loads(response.get_data(as_text=True))['provider_details'] allowed_keys = { "id", "created_by_name", "display_name", "identifier", "priority", 'notification_type', "active", "updated_at", "supports_international", "current_month_billable_sms" } assert len(json_resp) == 7 assert allowed_keys == set(json_resp[0].keys())
def test_post_notification_returns_501_when_recipient_identifiers_present_and_feature_flag_disabled( client, mocker, sample_email_template): mocker.patch( 'app.v2.notifications.post_notifications.accept_recipient_identifiers_enabled', return_value=False) data = { "template_id": sample_email_template.id, "recipient_identifier": { 'id_type': VA_PROFILE_ID, 'id_value': "foo" } } auth_header = create_authorization_header( service_id=sample_email_template.service_id) response = client.post(path="v2/notifications/email", data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 501
def test_post_precompiled_letter_with_invalid_base64(client, notify_user, mocker): sample_service = create_service(service_permissions=["letter"]) mocker.patch("app.v2.notifications.post_notifications.upload_letter_pdf") data = {"reference": "letter-reference", "content": "hi"} auth_header = create_authorization_header(service_id=sample_service.id) response = client.post( path="v2/notifications/letter", data=json.dumps(data), headers=[("Content-Type", "application/json"), auth_header], ) assert response.status_code == 400, response.get_data(as_text=True) resp_json = json.loads(response.get_data(as_text=True)) assert resp_json["errors"][0][ "message"] == "Cannot decode letter content (invalid base64 encoding)" assert not Notification.query.first()