示例#1
0
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'
    }
示例#2
0
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
示例#3
0
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']
示例#4
0
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']])
示例#5
0
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
示例#10
0
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)
示例#11
0
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
示例#12
0
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
示例#13
0
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'
            }
示例#14
0
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']])
示例#15
0
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
示例#16
0
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)
示例#17
0
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
示例#19
0
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']
示例#20
0
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']
示例#21
0
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()
示例#22
0
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,
            }
示例#23
0
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
示例#24
0
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)
示例#28
0
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
示例#29
0
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'
示例#32
0
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'
示例#34
0
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'
示例#35
0
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")
示例#37
0
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")
示例#38
0
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'
示例#40
0
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'
示例#41
0
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)
示例#44
0
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
示例#45
0
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()
示例#47
0
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)
示例#48
0
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')])
示例#50
0
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']
示例#51
0
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
示例#57
0
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)
示例#59
0
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'