Пример #1
0
def get_last_used_datetime_for_template(service_id, template_id):
    # Check the template and service exist
    dao_get_template_by_id_and_service_id(template_id, service_id)

    last_date_used = dao_get_last_date_template_was_used(template_id=template_id,
                                                         service_id=service_id)

    return jsonify(last_date_used=last_date_used.strftime(DATETIME_FORMAT) if last_date_used else last_date_used)
Пример #2
0
def test_get_template_version_returns_none_for_hidden_templates(
        sample_service):
    sample_template = create_template(template_name='Test Template',
                                      hidden=True,
                                      service=sample_service)

    with pytest.raises(NoResultFound):
        dao_get_template_by_id_and_service_id(sample_template.id,
                                              sample_service.id, '1')
Пример #3
0
def test_get_template_by_id_and_service_returns_none_for_hidden_templates(
        notify_db, notify_db_session, sample_service):
    sample_template = create_sample_template(notify_db,
                                             notify_db_session,
                                             template_name='Test Template',
                                             hidden=True,
                                             service=sample_service)

    with pytest.raises(NoResultFound):
        dao_get_template_by_id_and_service_id(template_id=sample_template.id,
                                              service_id=sample_service.id)
Пример #4
0
def create_broadcast_message(service_id):
    data = request.get_json()

    validate(data, create_broadcast_message_schema)
    service = dao_fetch_service_by_id(data['service_id'])
    user = get_user_by_id(data['created_by'])
    template = dao_get_template_by_id_and_service_id(data['template_id'], data['service_id'])

    personalisation = data.get('personalisation', {})
    broadcast_message = BroadcastMessage(
        service_id=service.id,
        template_id=template.id,
        template_version=template.version,
        personalisation=personalisation,
        areas={"areas": data.get("areas", []), "simple_polygons": data.get("simple_polygons", [])},
        status=BroadcastStatusType.DRAFT,
        starts_at=_parse_nullable_datetime(data.get('starts_at')),
        finishes_at=_parse_nullable_datetime(data.get('finishes_at')),
        created_by_id=user.id,
        content=template._as_utils_template_with_personalisation(
            personalisation
        ).content_with_placeholders_filled_in,
    )

    dao_save_object(broadcast_message)

    return jsonify(broadcast_message.serialize()), 201
Пример #5
0
def check_template_exists_by_id_and_service(template_id, service):
    try:
        return templates_dao.dao_get_template_by_id_and_service_id(
            template_id=template_id, service_id=service.id)
    except NoResultFound:
        message = "Template not found"
        raise BadRequestError(message=message, fields=[{"template": message}])
Пример #6
0
def post_template_preview(template_id):
    # The payload is empty when there are no place holders in the template.
    _data = request.get_data(as_text=True)
    if not _data:
        _data = {}
    else:
        _data = get_valid_json()

    _data['id'] = template_id

    data = validate(_data, post_template_preview_request)

    template = templates_dao.dao_get_template_by_id_and_service_id(
        template_id, authenticated_service.id)

    template_object = template._as_utils_template_with_personalisation(
        data.get('personalisation')
    )

    check_placeholders(template_object)

    resp = create_post_template_preview_response(template=template,
                                                 template_object=template_object)

    return jsonify(resp), 200
def send_one_off_notification(service_id, post_data):
    service = dao_fetch_service_by_id(service_id)
    template = dao_get_template_by_id_and_service_id(
        template_id=post_data['template_id'],
        service_id=service_id
    )

    personalisation = post_data.get('personalisation', None)

    validate_template(template.id, personalisation, service, template.template_type)

    check_service_over_daily_message_limit(KEY_TYPE_NORMAL, service)

    validate_and_format_recipient(
        send_to=post_data['to'],
        key_type=KEY_TYPE_NORMAL,
        service=service,
        notification_type=template.template_type,
        allow_whitelisted_recipients=False,
    )

    validate_created_by(service, post_data['created_by'])

    sender_id = post_data.get('sender_id', None)
    reply_to = get_reply_to_text(
        notification_type=template.template_type,
        sender_id=sender_id,
        service=service,
        template=template
    )
    notification = persist_notification(
        template_id=template.id,
        template_version=template.version,
        template_postage=template.postage,
        recipient=post_data['to'],
        service=service,
        personalisation=personalisation,
        notification_type=template.template_type,
        api_key_id=None,
        key_type=KEY_TYPE_NORMAL,
        created_by_id=post_data['created_by'],
        reply_to_text=reply_to,
        reference=create_one_off_reference(template.template_type),
    )

    queue_name = QueueNames.PRIORITY if template.process_type == PRIORITY else None

    if template.template_type == LETTER_TYPE and service.research_mode:
        _update_notification_status(
            notification,
            NOTIFICATION_DELIVERED,
        )
    else:
        send_notification_to_queue(
            notification=notification,
            research_mode=service.research_mode,
            queue=queue_name,
        )

    return {'id': str(notification.id)}
Пример #8
0
def test_can_get_template_then_redacted_returns_right_values(sample_template):
    template = dao_get_template_by_id_and_service_id(
        template_id=sample_template.id, service_id=sample_template.service_id)
    assert not template.redact_personalisation
    dao_redact_template(template=template,
                        user_id=sample_template.created_by_id)
    assert template.redact_personalisation
Пример #9
0
def test_get_template_history_version(sample_user, sample_service,
                                      sample_template):
    old_content = sample_template.content
    sample_template.content = "New content"
    dao_update_template(sample_template)
    old_template = dao_get_template_by_id_and_service_id(
        sample_template.id, sample_service.id, '1')
    assert old_template.content == old_content
Пример #10
0
def get_template_statistics_for_template_id(service_id, template_id):
    template = dao_get_template_by_id_and_service_id(template_id, service_id)

    data = None
    notification = dao_get_last_template_usage(template_id, template.template_type, template.service_id)
    if notification:
        data = notification_with_template_schema.dump(notification).data

    return jsonify(data=data)
Пример #11
0
def test_get_template_by_id_and_service(sample_service):
    sample_template = create_template(template_name='Test Template',
                                      service=sample_service)
    template = dao_get_template_by_id_and_service_id(
        template_id=sample_template.id, service_id=sample_service.id)
    assert template.id == sample_template.id
    assert template.name == 'Test Template'
    assert template.version == sample_template.version
    assert not template.redact_personalisation
def test_check_notification_content_is_not_empty_passes(
        notify_api, mocker, sample_service):
    template_id = create_template(sample_service,
                                  content="Content is not empty").id
    template = templates_dao.dao_get_template_by_id_and_service_id(
        template_id=template_id, service_id=sample_service.id)
    template_with_content = create_content_for_notification(template, {})
    assert check_notification_content_is_not_empty(
        template_with_content) is None
Пример #13
0
def get_template_version(service_id, template_id, version):
    data = template_history_schema.dump(
        dao_get_template_by_id_and_service_id(
            template_id=template_id,
            service_id=service_id,
            version=version
        )
    ).data
    return jsonify(data=data)
Пример #14
0
def get_template_version(service_id, template_id, version):
    data = template_history_schema.dump(
        dao_get_template_by_id_and_service_id(
            template_id=template_id,
            service_id=service_id,
            version=version
        )
    ).data
    return jsonify(data=data)
def test_get_template_by_id_and_service(notify_db, notify_db_session, sample_service):
    sample_template = create_sample_template(
        notify_db,
        notify_db_session,
        template_name='Test Template',
        service=sample_service)
    assert dao_get_template_by_id_and_service_id(
        template_id=sample_template.id,
        service_id=sample_service.id).name == 'Test Template'
    assert Template.query.count() == 1
def test_check_content_char_count_passes_for_long_email_or_letter(
        sample_service, template_type):
    t = create_template(service=sample_service,
                        content='a' * 1000,
                        template_type=template_type)
    template = templates_dao.dao_get_template_by_id_and_service_id(
        template_id=t.id, service_id=t.service_id)
    template_with_content = get_template_instance(template=template.__dict__,
                                                  values={})
    assert check_content_char_count(template_with_content) is None
def test_get_template_history_version(sample_user, sample_service, sample_template):
    old_content = sample_template.content
    sample_template.content = "New content"
    dao_update_template(sample_template)
    old_template = dao_get_template_by_id_and_service_id(
        sample_template.id,
        sample_service.id,
        '1'
    )
    assert old_template.content == old_content
Пример #18
0
def get_template_by_id(template_id, version=None):
    _data = {'id': template_id}
    if version:
        _data['version'] = version

    data = validate(_data, get_template_by_id_request)

    template = templates_dao.dao_get_template_by_id_and_service_id(
        template_id, authenticated_service.id, data.get('version'))
    return jsonify(template.serialize()), 200
Пример #19
0
def send_one_off_notification(service_id, post_data):
    service = dao_fetch_service_by_id(service_id)
    template = dao_get_template_by_id_and_service_id(template_id=post_data["template_id"], service_id=service_id)

    personalisation = post_data.get("personalisation", None)

    validate_template(template.id, personalisation, service, template.template_type)

    check_service_over_daily_message_limit(KEY_TYPE_NORMAL, service)

    validate_and_format_recipient(
        send_to=post_data["to"],
        key_type=KEY_TYPE_NORMAL,
        service=service,
        notification_type=template.template_type,
        allow_safelisted_recipients=False,
    )

    validate_created_by(service, post_data["created_by"])

    sender_id = post_data.get("sender_id", None)
    reply_to = get_reply_to_text(
        notification_type=template.template_type,
        sender_id=sender_id,
        service=service,
        template=template,
    )
    notification = persist_notification(
        template_id=template.id,
        template_version=template.version,
        template_postage=template.postage,
        recipient=post_data["to"],
        service=service,
        personalisation=personalisation,
        notification_type=template.template_type,
        api_key_id=None,
        key_type=KEY_TYPE_NORMAL,
        created_by_id=post_data["created_by"],
        reply_to_text=reply_to,
        reference=create_one_off_reference(template.template_type),
    )

    if template.template_type == LETTER_TYPE and service.research_mode:
        _update_notification_status(
            notification,
            NOTIFICATION_DELIVERED,
        )
    else:
        send_notification_to_queue(
            notification=notification,
            research_mode=service.research_mode,
            queue=template.queue_to_use(),
        )

    return {"id": str(notification.id)}
Пример #20
0
def test_check_content_char_count_fails(notify_db_session, show_prefix, char_count):
    with pytest.raises(BadRequestError) as e:
        service = create_service(prefix_sms=show_prefix)
        t = create_template(service=service, content='a' * char_count, template_type='sms')
        template = templates_dao.dao_get_template_by_id_and_service_id(template_id=t.id, service_id=service.id)
        template_with_content = get_template_instance(template=template.__dict__, values={})
        check_content_char_count(template_with_content)
    assert e.value.status_code == 400
    assert e.value.message == f'Text messages cannot be longer than {SMS_CHAR_COUNT_LIMIT} characters. ' \
                              f'Your message is {char_count} characters'
    assert e.value.fields == []
Пример #21
0
    def get_dict(template_id, service_id):
        from app.dao import templates_dao
        from app.schemas import template_schema

        fetched_template = templates_dao.dao_get_template_by_id_and_service_id(
            template_id=template_id, service_id=service_id)

        template_dict = template_schema.dump(fetched_template).data
        db.session.commit()

        return {'data': template_dict}
def test_check_content_char_count_passes(notify_db_session, show_prefix,
                                         char_count, template_type):
    service = create_service(prefix_sms=show_prefix)
    t = create_template(service=service,
                        content='a' * char_count,
                        template_type=template_type)
    template = templates_dao.dao_get_template_by_id_and_service_id(
        template_id=t.id, service_id=service.id)
    template_with_content = get_template_instance(template=template.__dict__,
                                                  values={})
    assert check_content_char_count(template_with_content) is None
Пример #23
0
def get_template_statistics_for_template_id(service_id, template_id):
    template = dao_get_template_by_id_and_service_id(template_id, service_id)
    if not template:
        message = 'No template found for id {}'.format(template_id)
        errors = {'template_id': [message]}
        raise InvalidRequest(errors, status_code=404)

    data = None
    notification = dao_get_last_template_usage(template_id,
                                               template.template_type)
    if notification:
        data = notification_with_template_schema.dump(notification).data

    return jsonify(data=data)
def test_check_notification_content_is_not_empty_fails(notify_api, mocker,
                                                       sample_service,
                                                       template_content,
                                                       notification_values):
    template_id = create_template(sample_service, content=template_content).id
    template = templates_dao.dao_get_template_by_id_and_service_id(
        template_id=template_id, service_id=sample_service.id)
    template_with_content = create_content_for_notification(
        template, notification_values)
    with pytest.raises(BadRequestError) as e:
        check_notification_content_is_not_empty(template_with_content)
    assert e.value.status_code == 400
    assert e.value.message == 'Your message is empty.'
    assert e.value.fields == []
def __validate_template(form, service, notification_type):
    try:
        template = templates_dao.dao_get_template_by_id_and_service_id(
            template_id=form["template_id"], service_id=service.id
        )
    except NoResultFound:
        message = "Template not found"
        raise BadRequestError(message=message, fields=[{"template": message}])

    check_template_is_for_notification_type(notification_type, template.template_type)
    check_template_is_active(template)
    template_with_content = create_content_for_notification(template, form.get("personalisation", {}))
    if template.template_type == SMS_TYPE:
        check_sms_content_char_count(template_with_content.content_count)
    return template, template_with_content
Пример #26
0
def preview_template_by_id_and_service_id(service_id, template_id):
    fetched_template = dao_get_template_by_id_and_service_id(template_id=template_id, service_id=service_id)
    data = template_schema.dump(fetched_template).data
    template_object = get_template_instance(data, values=request.args.to_dict())

    if template_object.missing_data:
        raise InvalidRequest(
            {'template': [
                'Missing personalisation: {}'.format(", ".join(template_object.missing_data))
            ]}, status_code=400
        )

    data['subject'], data['content'] = template_object.subject, str(template_object)

    return jsonify(data)
Пример #27
0
def update_template(service_id, template_id):
    fetched_template = dao_get_template_by_id_and_service_id(
        template_id=template_id, service_id=service_id)

    if not service_has_permission(
            fetched_template.template_type,
        [p.permission for p in fetched_template.service.permissions]):
        message = "Updating {} templates is not allowed".format(
            get_public_notify_type_text(fetched_template.template_type))
        errors = {'template_type': [message]}

        raise InvalidRequest(errors, 403)

    data = request.get_json()
    validate(data, post_update_template_schema)

    # if redacting, don't update anything else
    if data.get('redact_personalisation') is True:
        return redact_template(fetched_template, data)

    if "reply_to" in data:
        check_reply_to(service_id, data.get("reply_to"),
                       fetched_template.template_type)
        updated = dao_update_template_reply_to(template_id=template_id,
                                               reply_to=data.get("reply_to"))
        return jsonify(data=template_schema.dump(updated).data), 200

    current_data = dict(template_schema.dump(fetched_template).data.items())
    updated_template = dict(
        template_schema.dump(fetched_template).data.items())
    updated_template.update(data)

    # Check if there is a change to make.
    if _template_has_not_changed(current_data, updated_template):
        return jsonify(data=updated_template), 200

    over_limit = _content_count_greater_than_limit(
        updated_template['content'], fetched_template.template_type)
    if over_limit:
        message = 'Content has a character count greater than the limit of {}'.format(
            SMS_CHAR_COUNT_LIMIT)
        errors = {'content': [message]}
        raise InvalidRequest(errors, status_code=400)

    update_dict = template_schema.load(updated_template).data

    dao_update_template(update_dict)
    return jsonify(data=template_schema.dump(update_dict).data), 200
Пример #28
0
def validate_template(template_id, personalisation, service,
                      notification_type):
    try:
        template = templates_dao.dao_get_template_by_id_and_service_id(
            template_id=template_id, service_id=service.id)
    except NoResultFound:
        message = 'Template not found'
        raise BadRequestError(message=message, fields=[{'template': message}])

    check_template_is_for_notification_type(notification_type,
                                            template.template_type)
    check_template_is_active(template)
    template_with_content = create_content_for_notification(
        template, personalisation)
    if template.template_type == SMS_TYPE:
        check_sms_content_char_count(template_with_content.content_count)
    return template, template_with_content
Пример #29
0
def test_check_is_message_too_long_passes_for_long_email(sample_service):
    email_character_count = 2_000_001
    t = create_template(service=sample_service, content='a' * email_character_count, template_type='email')
    template = templates_dao.dao_get_template_by_id_and_service_id(template_id=t.id,
                                                                   service_id=t.service_id)
    template_with_content = get_template_instance(template=template.__dict__, values={})
    template_with_content.values
    with pytest.raises(BadRequestError) as e:
        check_is_message_too_long(template_with_content)
    assert e.value.status_code == 400
    expected_message = (
        'Your message is too long. ' +
        'Emails cannot be longer than 2000000 bytes. ' +
        'Your message is 2000001 bytes.'
    )
    assert e.value.message == expected_message
    assert e.value.fields == []
Пример #30
0
def move_to_template_folder(service_id, target_template_folder_id=None):
    data = request.get_json()

    validate(data, post_move_template_folder_schema)

    if target_template_folder_id:
        target_template_folder = dao_get_template_folder_by_id_and_service_id(
            target_template_folder_id, service_id)
    else:
        target_template_folder = None

    for template_folder_id in data["folders"]:
        try:
            template_folder = dao_get_template_folder_by_id_and_service_id(
                template_folder_id, service_id)
        except NoResultFound:
            msg = "No folder found with id {} for service {}".format(
                template_folder_id, service_id)
            raise InvalidRequest(msg, status_code=400)
        _validate_folder_move(
            target_template_folder,
            target_template_folder_id,
            template_folder,
            template_folder_id,
        )

        template_folder.parent = target_template_folder

    for template_id in data["templates"]:
        try:
            template = dao_get_template_by_id_and_service_id(
                template_id, service_id)
        except NoResultFound:
            msg = "Could not move to folder: No template found with id {} for service {}".format(
                template_id, service_id)
            raise InvalidRequest(msg, status_code=400)

        if template.archived:
            current_app.logger.info(
                "Could not move to folder: Template {} is archived. (Skipping)"
                .format(template_id))
        else:
            template.folder = target_template_folder
    return "", 204
Пример #31
0
def update_template(service_id, template_id):
    fetched_template = dao_get_template_by_id_and_service_id(template_id=template_id, service_id=service_id)

    current_data = dict(template_schema.dump(fetched_template).data.items())
    updated_template = dict(template_schema.dump(fetched_template).data.items())
    updated_template.update(request.get_json())
    updated_template['content'] = _strip_html(updated_template['content'])
    # Check if there is a change to make.
    if _template_has_not_changed(current_data, updated_template):
        return jsonify(data=updated_template), 200

    update_dict = template_schema.load(updated_template).data
    over_limit = _content_count_greater_than_limit(updated_template['content'], fetched_template.template_type)
    if over_limit:
        char_count_limit = current_app.config.get('SMS_CHAR_COUNT_LIMIT')
        message = 'Content has a character count greater than the limit of {}'.format(char_count_limit)
        errors = {'content': [message]}
        raise InvalidRequest(errors, status_code=400)
    dao_update_template(update_dict)
    return jsonify(data=template_schema.dump(update_dict).data), 200
Пример #32
0
def post_template_preview(template_id):
    _data = request.get_json()
    if _data is None:
        _data = {}

    _data['id'] = template_id

    data = validate(_data, post_template_preview_request)

    template = templates_dao.dao_get_template_by_id_and_service_id(
        template_id, authenticated_service.id)

    template_object = get_template_instance(template.__dict__,
                                            values=data.get('personalisation'))

    check_placeholders(template_object)

    resp = create_post_template_preview_response(
        template=template, template_object=template_object)

    return jsonify(resp), 200
Пример #33
0
def preview_template_by_id_and_service_id(service_id, template_id):
    fetched_template = dao_get_template_by_id_and_service_id(
        template_id=template_id, service_id=service_id)
    data = template_schema.dump(fetched_template).data
    template_object = fetched_template._as_utils_template_with_personalisation(
        request.args.to_dict())

    if template_object.missing_data:
        raise InvalidRequest(
            {
                'template': [
                    'Missing personalisation: {}'.format(", ".join(
                        template_object.missing_data))
                ]
            },
            status_code=400)

    data['subject'] = template_object.subject
    data['content'] = template_object.content_with_placeholders_filled_in

    return jsonify(data)
Пример #34
0
def preview_template_by_id_and_service_id(service_id, template_id):
    fetched_template = dao_get_template_by_id_and_service_id(template_id=template_id, service_id=service_id)
    data = template_schema.dump(fetched_template).data

    template_object = get_template_instance(data, values=request.args.to_dict())

    if template_object.missing_data:
        raise InvalidRequest(
            {'template': [
                'Missing personalisation: {}'.format(", ".join(template_object.missing_data))
            ]}, status_code=400
        )

    if template_object.additional_data:
        raise InvalidRequest(
            {'template': [
                'Personalisation not needed for template: {}'.format(", ".join(template_object.additional_data))
            ]}, status_code=400
        )

    data['subject'], data['content'] = template_object.subject, str(template_object)

    return jsonify(data)
Пример #35
0
def create_broadcast_message(service_id):
    data = request.get_json()

    validate(data, create_broadcast_message_schema)
    service = dao_fetch_service_by_id(data['service_id'])
    user = get_user_by_id(data['created_by'])
    template = dao_get_template_by_id_and_service_id(data['template_id'],
                                                     data['service_id'])

    broadcast_message = BroadcastMessage(
        service_id=service.id,
        template_id=template.id,
        template_version=template.version,
        personalisation=data.get('personalisation', {}),
        areas=data.get('areas', []),
        status=BroadcastStatusType.DRAFT,
        starts_at=_parse_nullable_datetime(data.get('starts_at')),
        finishes_at=_parse_nullable_datetime(data.get('finishes_at')),
        created_by_id=user.id,
    )

    dao_save_object(broadcast_message)

    return jsonify(broadcast_message.serialize()), 201
def test_get_template_by_id_and_service_returns_none_if_no_template(sample_service, fake_uuid):
    with pytest.raises(NoResultFound) as e:
        dao_get_template_by_id_and_service_id(template_id=fake_uuid, service_id=sample_service.id)
    assert 'No row was found for one' in str(e.value)
Пример #37
0
def get_template_by_id_and_service_id(service_id, template_id):
    fetched_template = dao_get_template_by_id_and_service_id(template_id=template_id, service_id=service_id)
    data = template_schema.dump(fetched_template).data
    return jsonify(data=data)
def test_get_template_by_id_and_service_returns_none_if_no_template(sample_service, fake_uuid):
    with pytest.raises(NoResultFound) as e:
        dao_get_template_by_id_and_service_id(template_id=fake_uuid, service_id=sample_service.id)
    assert 'No row was found for one' in str(e.value)