def post_email_notification():
    form = validate(request.get_json(), post_email_request)
    service = services_dao.dao_fetch_service_by_id(api_user.service_id)

    check_service_message_limit(api_user.key_type, service)
    service_can_send_to_recipient(form["email_address"], api_user.key_type, service)

    template, template_with_content = __validate_template(form, service, EMAIL_TYPE)
    notification = persist_notification(
        template_id=template.id,
        template_version=template.version,
        recipient=form["email_address"],
        service_id=service.id,
        personalisation=form.get("personalisation", None),
        notification_type=EMAIL_TYPE,
        api_key_id=api_user.id,
        key_type=api_user.key_type,
        reference=form.get("reference"),
    )

    send_notification_to_queue(notification, service.research_mode)

    resp = create_post_email_response_from_notification(
        notification=notification,
        content=str(template_with_content),
        subject=template_with_content.subject,
        email_from=service.email_from,
        url_root=request.url_root,
    )
    return jsonify(resp), 201
def post_sms_notification():
    form = validate(request.get_json(), post_sms_request)
    service = services_dao.dao_fetch_service_by_id(api_user.service_id)

    check_service_message_limit(api_user.key_type, service)
    service_can_send_to_recipient(form["phone_number"], api_user.key_type, service)

    template, template_with_content = __validate_template(form, service, SMS_TYPE)

    notification = persist_notification(
        template_id=template.id,
        template_version=template.version,
        recipient=form["phone_number"],
        service_id=service.id,
        personalisation=form.get("personalisation", None),
        notification_type=SMS_TYPE,
        api_key_id=api_user.id,
        key_type=api_user.key_type,
        reference=form.get("reference"),
    )
    send_notification_to_queue(notification, service.research_mode)
    sms_sender = service.sms_sender if service.sms_sender else current_app.config.get("FROM_NUMBER")
    resp = create_post_sms_response_from_notification(
        notification, str(template_with_content), sms_sender, request.url_root
    )
    return jsonify(resp), 201
def test_check_service_message_limit_in_cache_under_message_limit_passes(
        key_type,
        sample_service,
        mocker):
    mocker.patch('app.notifications.validators.redis_store.get', return_value=1)
    mocker.patch('app.notifications.validators.redis_store.set')
    mocker.patch('app.notifications.validators.services_dao')
    check_service_message_limit(key_type, sample_service)
    app.notifications.validators.redis_store.set.assert_not_called()
    assert not app.notifications.validators.services_dao.mock_calls
def test_should_set_cache_value_as_value_from_database_if_cache_not_set(
        key_type,
        notify_db,
        notify_db_session,
        sample_service,
        mocker
):
    with freeze_time("2016-01-01 12:00:00.000000"):
        for x in range(5):
            create_notification(notify_db, notify_db_session, service=sample_service)
        mocker.patch('app.notifications.validators.redis_store.get', return_value=None)
        mocker.patch('app.notifications.validators.redis_store.set')
        check_service_message_limit(key_type, sample_service)
        app.notifications.validators.redis_store.set.assert_called_with(
            str(sample_service.id) + "-2016-01-01-count", 5, ex=3600
        )
def test_exception_thown_by_redis_store_set_should_not_be_fatal(
        key_type,
        sample_service,
        mocker):
    mocker.patch('app.notifications.validators.redis_store.redis_store.set', side_effect=Exception("broken redis"))
    mocker.patch('app.notifications.validators.redis_store.get', return_value=None)
    assert not check_service_message_limit(key_type, sample_service)
def test_check_service_message_limit_over_message_limit_fails(key_type, notify_db, notify_db_session, mocker):
    with freeze_time("2016-01-01 12:00:00.000000"):
        mocker.patch('app.redis_store.get', return_value=None)
        mocker.patch('app.notifications.validators.redis_store.set')

        service = create_service(notify_db, notify_db_session, restricted=True, limit=4)
        for x in range(5):
            create_notification(notify_db, notify_db_session, service=service)
        with pytest.raises(TooManyRequestsError) as e:
            check_service_message_limit(key_type, service)
        assert e.value.status_code == 429
        assert e.value.message == 'Exceeded send limits (4) for today'
        assert e.value.fields == []
        app.notifications.validators.redis_store.set.assert_called_with(
            str(service.id) + "-2016-01-01-count", 5, ex=3600
        )
def test_check_service_message_limit_in_cache_over_message_limit_fails(
        notify_db,
        notify_db_session,
        key_type,
        mocker):
    with freeze_time("2016-01-01 12:00:00.000000"):
        mocker.patch('app.redis_store.get', return_value=5)
        mocker.patch('app.notifications.validators.redis_store.set')
        mocker.patch('app.notifications.validators.services_dao')

        service = create_service(notify_db, notify_db_session, restricted=True, limit=4)
        with pytest.raises(TooManyRequestsError) as e:
            check_service_message_limit(key_type, service)
        assert e.value.status_code == 429
        assert e.value.message == 'Exceeded send limits (4) for today'
        assert e.value.fields == []
        app.notifications.validators.redis_store.set.assert_not_called()
        assert not app.notifications.validators.services_dao.mock_calls
def test_exception_thrown_by_redis_store_get_should_not_be_fatal(
        notify_db,
        notify_db_session,
        notify_api,
        key_type,
        mocker):
    with freeze_time("2016-01-01 12:00:00.000000"):

        mocker.patch('app.notifications.validators.redis_store.redis_store.get', side_effect=Exception("broken redis"))
        mocker.patch('app.notifications.validators.redis_store.redis_store.set')

        service = create_service(notify_db, notify_db_session, restricted=True, limit=4)
        for x in range(5):
            create_notification(notify_db, notify_db_session, service=service)

        with pytest.raises(TooManyRequestsError) as e:
            check_service_message_limit(key_type, service)
        assert e.value.status_code == 429
        assert e.value.message == 'Exceeded send limits (4) for today'
        assert e.value.fields == []
        app.notifications.validators.redis_store.redis_store.set.assert_called_with(
            "{}-2016-01-01-count".format(str(service.id)), 5, 3600, None, False, False
        )
def test_should_not_interact_with_cache_for_test_key(sample_service, mocker):
    mocker.patch('app.notifications.validators.redis_store')
    check_service_message_limit('test', sample_service)
    assert not app.notifications.validators.redis_store.mock_calls