Esempio n. 1
0
def test_fetch_stats_counts_should_ignore_team_key(notify_db_session):
    service = create_service()
    template = create_template(service=service)
    live_api_key = create_api_key(service=service, key_type=KEY_TYPE_NORMAL)
    team_api_key = create_api_key(service=service, key_type=KEY_TYPE_TEAM)
    test_api_key = create_api_key(service=service, key_type=KEY_TYPE_TEST)

    # two created email, one failed email, and one created sms
    create_notification(template=template, api_key=live_api_key, key_type=live_api_key.key_type)
    create_notification(template=template, api_key=test_api_key, key_type=test_api_key.key_type)
    create_notification(template=template, api_key=team_api_key, key_type=team_api_key.key_type)
    create_notification(template=template)

    stats = dao_fetch_stats_for_service(template.service_id, 7)
    assert len(stats) == 1
    assert stats[0].notification_type == 'sms'
    assert stats[0].status == 'created'
    assert stats[0].count == 3
Esempio n. 2
0
def test_dao_suspend_service_marks_service_as_inactive_and_expires_api_keys(notify_db_session):
    service = create_service()
    api_key = create_api_key(service=service)
    dao_suspend_service(service.id)
    service = Service.query.get(service.id)
    assert not service.active
    assert service.name == service.name

    api_key = ApiKey.query.get(api_key.id)
    assert api_key.expiry_date == datetime(2001, 1, 1, 23, 59, 00)
Esempio n. 3
0
def test_get_api_key_ranked_by_notifications_created(notify_db_session):
    service = create_service(service_name='Service 1')
    api_key_1 = create_api_key(service,
                               key_type=KEY_TYPE_NORMAL,
                               key_name="Key 1")
    api_key_2 = create_api_key(service,
                               key_type=KEY_TYPE_NORMAL,
                               key_name="Key 2")
    template_email = create_template(service=service, template_type='email')
    template_sms = create_template(service=service, template_type='sms')
    email_sends = 1
    sms_sends = 10

    for x in range(email_sends):
        create_notification(template=template_email, api_key=api_key_1)

    for x in range(sms_sends):
        create_notification(template=template_sms, api_key=api_key_1)
        create_notification(template=template_sms, api_key=api_key_2)

    api_keys_ranked = get_api_key_ranked_by_notifications_created(2)

    assert len(api_keys_ranked) == 2

    first_place = api_keys_ranked[0]
    second_place = api_keys_ranked[1]

    # check there are 9 fields/columns returned
    assert len(first_place) == 9
    assert len(second_place) == 9

    assert first_place[0] == api_key_1.name
    assert first_place[2] == service.name
    assert int(first_place[6]) == email_sends
    assert int(first_place[7]) == sms_sends
    assert int(first_place[8]) == sms_sends + email_sends

    assert second_place[0] == api_key_2.name
    assert second_place[2] == service.name
    assert int(second_place[6]) == 0
    assert int(second_place[7]) == sms_sends
    assert int(second_place[8]) == sms_sends
Esempio n. 4
0
def test_get_api_key_stats_no_sends(admin_request, notify_db, notify_db_session):

    service = create_service(service_name="Service 2")
    api_key = create_api_key(service)

    api_key_stats = admin_request.get("api_key.get_api_key_stats", api_key_id=api_key.id)["data"]

    assert api_key_stats["api_key_id"] == str(api_key.id)
    assert api_key_stats["email_sends"] == 0
    assert api_key_stats["sms_sends"] == 0
    assert api_key_stats["total_sends"] == 0
    assert api_key_stats["last_send"] is None
def test_that_when_not_exceeded_rate_limit_request_succeeds(
        sample_service, mocker):
    with freeze_time("2016-01-01 12:00:00.000000"):
        mocker.patch('app.redis_store.exceeded_rate_limit', return_value=False)
        mocker.patch('app.notifications.validators.services_dao')

        sample_service.restricted = True
        api_key = create_api_key(sample_service)

        check_service_over_api_rate_limit(sample_service, api_key)
        assert app.redis_store.exceeded_rate_limit.called_with(
            "{}-{}".format(str(sample_service.id), api_key.key_type), 3000, 60)
def test_should_not_rate_limit_if_limiting_is_disabled(sample_service, mocker):
    with freeze_time("2016-01-01 12:00:00.000000"):
        current_app.config['API_RATE_LIMIT_ENABLED'] = False

        mocker.patch('app.redis_store.exceeded_rate_limit', return_value=False)
        mocker.patch('app.notifications.validators.services_dao')

        sample_service.restricted = True
        api_key = create_api_key(sample_service)

        check_service_over_api_rate_limit(sample_service, api_key)
        assert not app.redis_store.exceeded_rate_limit.called
Esempio n. 7
0
def test_dao_resume_service_marks_service_as_active_and_api_keys_are_still_revoked(notify_db_session):
    service = create_service()
    api_key = create_api_key(service=service)
    dao_suspend_service(service.id)
    service = Service.query.get(service.id)
    assert not service.active

    dao_resume_service(service.id)
    assert Service.query.get(service.id).active

    api_key = ApiKey.query.get(api_key.id)
    assert api_key.expiry_date == datetime(2001, 1, 1, 23, 59, 00)
Esempio n. 8
0
def test_post_sms_notification_returns_400_if_number_not_in_guest_list(
        notify_db_session, client, restricted
):
    service = create_service(restricted=restricted, service_permissions=[SMS_TYPE, INTERNATIONAL_SMS_TYPE])
    template = create_template(service=service)
    create_api_key(service=service, key_type='team')

    data = {
        "phone_number": '+327700900855',
        "template_id": template.id,
    }
    auth_header = create_authorization_header(service_id=service.id, key_type='team')

    response = client.post(
        path='/v2/notifications/sms',
        data=json.dumps(data),
        headers=[('Content-Type', 'application/json'), auth_header])

    assert response.status_code == 400
    error_json = json.loads(response.get_data(as_text=True))
    assert error_json['status_code'] == 400
    assert error_json['errors'] == [
        {"error": "BadRequestError", "message": 'Can’t send to this recipient using a team-only API key'}
    ]
def archived_service_with_deleted_stuff(client, sample_service):
    with freeze_time('2001-01-01'):
        template = create_template(sample_service, template_name='a')
        api_key = create_api_key(sample_service)

        expire_api_key(sample_service.id, api_key.id)

        template.archived = True
        dao_update_template(template)

    with freeze_time('2002-02-02'):
        auth_header = create_authorization_header()
        response = client.post('/service/{}/archive'.format(sample_service.id), headers=[auth_header])

    assert response.status_code == 204
    assert response.data == b''
    return sample_service
Esempio n. 10
0
def test_get_last_send_for_api_key(notify_db_session):
    service = create_service(service_name='First Service')
    api_key = create_api_key(service)
    template_email = create_template(service=service, template_type=EMAIL_TYPE)
    total_sends = 10

    last_send = get_last_send_for_api_key(str(api_key.id))
    assert last_send == []

    for x in range(total_sends):
        create_notification(template=template_email, api_key=api_key)

    # the following lines test that a send has occurred within the last second
    last_send = get_last_send_for_api_key(str(api_key.id))[0][0]
    now = datetime.utcnow()
    time_delta = now - last_send
    assert abs(time_delta.total_seconds()) < 1
Esempio n. 11
0
def sample_notification(notify_db_session):
    created_at = datetime.utcnow()
    service = create_service(check_if_service_exists=True)
    template = create_template(service=service)

    api_key = ApiKey.query.filter(ApiKey.service == template.service,
                                  ApiKey.key_type == KEY_TYPE_NORMAL).first()
    if not api_key:
        api_key = create_api_key(template.service, key_type=KEY_TYPE_NORMAL)

    notification_id = uuid.uuid4()
    to = '+447700900855'

    data = {
        'id': notification_id,
        'to': to,
        'job_id': None,
        'job': None,
        'service_id': service.id,
        'service': service,
        'template_id': template.id,
        'template_version': template.version,
        'status': 'created',
        'reference': None,
        'created_at': created_at,
        'sent_at': None,
        'billable_units': 1,
        'personalisation': None,
        'notification_type': template.template_type,
        'api_key': api_key,
        'api_key_id': api_key and api_key.id,
        'key_type': api_key.key_type,
        'sent_by': None,
        'updated_at': None,
        'client_reference': None,
        'rate_multiplier': 1.0,
        'normalised_to': None,
        'postage': None,
    }

    notification = Notification(**data)
    dao_create_notification(notification)

    return notification
Esempio n. 12
0
def test_should_send_notification_to_whitelist_recipient(
    client,
    sample_service,
    notification_type,
    to,
    key_type,
    service_restricted,
    mocker
):
    sample_service.message_limit = 2
    sample_service.restricted = service_restricted

    apply_async = mocker.patch('app.celery.provider_tasks.deliver_{}.apply_async'.format(notification_type))
    template = create_template(sample_service, template_type=notification_type)
    if notification_type == SMS_TYPE:
        service_whitelist = create_service_whitelist(sample_service, mobile_number=to)
    elif notification_type == EMAIL_TYPE:
        service_whitelist = create_service_whitelist(sample_service, email_address=to)

    assert service_whitelist.service_id == sample_service.id
    assert to in [member.recipient for member in sample_service.whitelist]

    create_notification(template=template)

    data = {
        'to': to,
        'template': str(template.id)
    }

    sample_key = create_api_key(sample_service, key_type=key_type)
    auth_header = create_jwt_token(secret=sample_key.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
Esempio n. 13
0
def test_should_not_send_notification_to_non_whitelist_recipient_in_trial_mode(
    client,
    sample_service_whitelist,
    notification_type,
    to,
    key_type,
    mocker
):
    service = sample_service_whitelist.service
    service.restricted = True
    service.message_limit = 2

    apply_async = mocker.patch('app.celery.provider_tasks.deliver_{}.apply_async'.format(notification_type))
    template = create_template(service, template_type=notification_type)
    assert sample_service_whitelist.service_id == service.id
    assert to not in [member.recipient for member in service.whitelist]

    create_notification(template=template)

    data = {
        'to': to,
        'template': str(template.id)
    }

    api_key = create_api_key(service, key_type=key_type)
    auth_header = create_jwt_token(secret=api_key.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()
Esempio n. 14
0
def test_persist_notification_doesnt_touch_cache_for_old_keys_that_dont_exist(notify_db_session, mocker):
    service = create_service(restricted=True)
    template = create_template(service=service)
    api_key = create_api_key(service=service)
    mock_incr = mocker.patch('app.notifications.process_notifications.redis_store.incr')
    mocker.patch('app.notifications.process_notifications.redis_store.get', return_value=None)
    mocker.patch('app.notifications.process_notifications.redis_store.get_all_from_hash', return_value=None)

    persist_notification(
        template_id=template.id,
        template_version=template.version,
        recipient='+447111111111',
        service=template.service,
        personalisation={},
        notification_type='sms',
        api_key_id=api_key.id,
        key_type=api_key.key_type,
        reference="ref"
    )
    mock_incr.assert_not_called()
def test_get_total_notifications_sent_for_api_key(notify_db_session):
    service = create_service(service_name='First Service')
    api_key = create_api_key(service)
    template_email = create_template(service=service, template_type=EMAIL_TYPE)
    template_sms = create_template(service=service, template_type=SMS_TYPE)
    total_sends = 10

    api_key_stats_1 = get_total_notifications_sent_for_api_key(str(api_key.id))
    assert api_key_stats_1 == []

    for x in range(total_sends):
        create_notification(template=template_email, api_key=api_key)

    api_key_stats_2 = get_total_notifications_sent_for_api_key(str(api_key.id))
    assert api_key_stats_2 == [(EMAIL_TYPE, total_sends), ]

    for x in range(total_sends):
        create_notification(template=template_sms, api_key=api_key)

    api_key_stats_3 = get_total_notifications_sent_for_api_key(str(api_key.id))
    assert set(api_key_stats_3) == set([(EMAIL_TYPE, total_sends), (SMS_TYPE, total_sends)])
Esempio n. 16
0
def sample_notification_history(
    notify_db,
    notify_db_session,
    sample_template,
    status="created",
    created_at=None,
    notification_type=None,
    key_type=KEY_TYPE_NORMAL,
    sent_at=None,
    api_key=None,
):
    if created_at is None:
        created_at = datetime.utcnow()

    if sent_at is None:
        sent_at = datetime.utcnow()

    if notification_type is None:
        notification_type = sample_template.template_type

    if not api_key:
        api_key = create_api_key(sample_template.service, key_type=key_type)

    notification_history = NotificationHistory(
        id=uuid.uuid4(),
        service=sample_template.service,
        template_id=sample_template.id,
        template_version=sample_template.version,
        status=status,
        created_at=created_at,
        notification_type=notification_type,
        key_type=key_type,
        api_key=api_key,
        api_key_id=api_key and api_key.id,
        sent_at=sent_at,
    )
    notify_db.session.add(notification_history)
    notify_db.session.commit()

    return notification_history
Esempio n. 17
0
def sample_notification_history(notify_db, notify_db_session, sample_template):
    created_at = datetime.utcnow()
    sent_at = datetime.utcnow()
    notification_type = sample_template.template_type
    api_key = create_api_key(sample_template.service, key_type=KEY_TYPE_NORMAL)

    notification_history = NotificationHistory(
        id=uuid.uuid4(),
        service=sample_template.service,
        template_id=sample_template.id,
        template_version=sample_template.version,
        status='created',
        created_at=created_at,
        notification_type=notification_type,
        key_type=KEY_TYPE_NORMAL,
        api_key=api_key,
        api_key_id=api_key and api_key.id,
        sent_at=sent_at)
    notify_db.session.add(notification_history)
    notify_db.session.commit()

    return notification_history
Esempio n. 18
0
def test_get_api_key_stats_with_sends(admin_request, notify_db, notify_db_session):

    service = create_service(service_name="Service 1")
    api_key = create_api_key(service)
    template = create_template(service=service, template_type="email")
    total_sends = 10

    for x in range(total_sends):
        create_notification(template=template, api_key=api_key)

    api_key_stats = admin_request.get("api_key.get_api_key_stats", api_key_id=api_key.id)["data"]

    assert api_key_stats["api_key_id"] == str(api_key.id)
    assert api_key_stats["email_sends"] == total_sends
    assert api_key_stats["sms_sends"] == 0
    assert api_key_stats["total_sends"] == total_sends

    # the following lines test that a send has occurred within the last second
    last_send_dt = datetime.strptime(api_key_stats["last_send"], DATETIME_FORMAT)
    now = datetime.utcnow()
    time_delta = now - last_send_dt
    assert abs(time_delta.total_seconds()) < 1
Esempio n. 19
0
def test_persist_notification_does_not_increments_cache_live_service(
    notify_db_session, mocker
):
    service = create_service(restricted=False)
    template = create_template(service=service)
    api_key = create_api_key(service=service)
    mock_incr = mocker.patch('app.notifications.process_notifications.redis_store.incr')
    mocker.patch('app.notifications.process_notifications.redis_store.get', return_value=1)
    mocker.patch('app.notifications.process_notifications.redis_store.get_all_from_hash',
                 return_value={template.id, 1})

    persist_notification(
        template_id=template.id,
        template_version=template.version,
        recipient='+447111111122',
        service=template.service,
        personalisation={},
        notification_type='sms',
        api_key_id=api_key.id,
        key_type=api_key.key_type,
        reference="ref2")

    assert not mock_incr.called
Esempio n. 20
0
def test_persist_notification_increments_cache_if_key_exists_and_for_trial_service(
    notify_db_session, mocker
):
    service = create_service(restricted=True)
    template = create_template(service=service)
    api_key = create_api_key(service=service)
    mock_incr = mocker.patch('app.notifications.process_notifications.redis_store.incr')
    mocker.patch('app.notifications.process_notifications.redis_store.get', return_value=1)
    mocker.patch('app.notifications.process_notifications.redis_store.get_all_from_hash',
                 return_value={template.id, 1})

    persist_notification(
        template_id=template.id,
        template_version=template.version,
        recipient='+447111111122',
        service=template.service,
        personalisation={},
        notification_type='sms',
        api_key_id=api_key.id,
        key_type=api_key.key_type,
        reference="ref2")

    mock_incr.assert_called_once_with(str(service.id) + "-2016-01-01-count", )
Esempio n. 21
0
def sample_team_api_key(sample_api_key):
    service = create_service(check_if_service_exists=True)

    return create_api_key(service, key_type=KEY_TYPE_TEAM)
Esempio n. 22
0
def sample_notification(
    notify_db,
    notify_db_session,
    service=None,
    template=None,
    job=None,
    job_row_number=None,
    to_field=None,
    status="created",
    provider_response=None,
    reference=None,
    created_at=None,
    sent_at=None,
    billable_units=1,
    personalisation=None,
    api_key=None,
    key_type=KEY_TYPE_NORMAL,
    sent_by=None,
    international=False,
    client_reference=None,
    rate_multiplier=1.0,
    scheduled_for=None,
    normalised_to=None,
    postage=None,
):
    if created_at is None:
        created_at = datetime.utcnow()
    if service is None:
        service = create_service(check_if_service_exists=True)
    if template is None:
        template = create_template(service=service)

    if job is None and api_key is None:
        # we didn't specify in test - lets create it
        api_key = ApiKey.query.filter(ApiKey.service == template.service, ApiKey.key_type == key_type).first()
        if not api_key:
            api_key = create_api_key(template.service, key_type=key_type)

    notification_id = uuid.uuid4()

    if to_field:
        to = to_field
    else:
        to = "+16502532222"

    data = {
        "id": notification_id,
        "to": to,
        "job_id": job.id if job else None,
        "job": job,
        "service_id": service.id,
        "service": service,
        "template_id": template.id,
        "template_version": template.version,
        "status": status,
        "provider_response": provider_response,
        "reference": reference,
        "created_at": created_at,
        "sent_at": sent_at,
        "billable_units": billable_units,
        "personalisation": personalisation,
        "notification_type": template.template_type,
        "api_key": api_key,
        "api_key_id": api_key and api_key.id,
        "key_type": api_key.key_type if api_key else key_type,
        "sent_by": sent_by,
        "updated_at": created_at if status in NOTIFICATION_STATUS_TYPES_COMPLETED else None,
        "client_reference": client_reference,
        "rate_multiplier": rate_multiplier,
        "normalised_to": normalised_to,
        "postage": postage,
    }
    if job_row_number is not None:
        data["job_row_number"] = job_row_number
    notification = Notification(**data)
    dao_create_notification(notification)
    if scheduled_for:
        scheduled_notification = ScheduledNotification(
            id=uuid.uuid4(),
            notification_id=notification.id,
            scheduled_for=datetime.strptime(scheduled_for, "%Y-%m-%d %H:%M"),
        )
        if status != "created":
            scheduled_notification.pending = False
        db.session.add(scheduled_notification)
        db.session.commit()

    return notification
Esempio n. 23
0
def sample_notification(
    notify_db,
    notify_db_session,
    service=None,
    template=None,
    job=None,
    job_row_number=None,
    to_field=None,
    status='created',
    reference=None,
    created_at=None,
    sent_at=None,
    billable_units=1,
    personalisation=None,
    api_key=None,
    key_type=KEY_TYPE_NORMAL,
    sent_by=None,
    international=False,
    client_reference=None,
    rate_multiplier=1.0,
    scheduled_for=None,
    normalised_to=None,
    postage=None,
):
    if created_at is None:
        created_at = datetime.utcnow()
    if service is None:
        service = create_service(check_if_service_exists=True)
    if template is None:
        template = create_template(service=service)

    if job is None and api_key is None:
        # we didn't specify in test - lets create it
        api_key = ApiKey.query.filter(ApiKey.service == template.service,
                                      ApiKey.key_type == key_type).first()
        if not api_key:
            api_key = create_api_key(template.service, key_type=key_type)

    notification_id = uuid.uuid4()

    if to_field:
        to = to_field
    else:
        to = '+16502532222'

    data = {
        'id':
        notification_id,
        'to':
        to,
        'job_id':
        job.id if job else None,
        'job':
        job,
        'service_id':
        service.id,
        'service':
        service,
        'template_id':
        template.id,
        'template_version':
        template.version,
        'status':
        status,
        'reference':
        reference,
        'created_at':
        created_at,
        'sent_at':
        sent_at,
        'billable_units':
        billable_units,
        'personalisation':
        personalisation,
        'notification_type':
        template.template_type,
        'api_key':
        api_key,
        'api_key_id':
        api_key and api_key.id,
        'key_type':
        api_key.key_type if api_key else key_type,
        'sent_by':
        sent_by,
        'updated_at':
        created_at if status in NOTIFICATION_STATUS_TYPES_COMPLETED else None,
        'client_reference':
        client_reference,
        'rate_multiplier':
        rate_multiplier,
        'normalised_to':
        normalised_to,
        'postage':
        postage,
    }
    if job_row_number is not None:
        data['job_row_number'] = job_row_number
    notification = Notification(**data)
    dao_create_notification(notification)
    if scheduled_for:
        scheduled_notification = ScheduledNotification(
            id=uuid.uuid4(),
            notification_id=notification.id,
            scheduled_for=datetime.strptime(scheduled_for, "%Y-%m-%d %H:%M"))
        if status != 'created':
            scheduled_notification.pending = False
        db.session.add(scheduled_notification)
        db.session.commit()

    return notification