Merge branch 'master' into enable-download-link

This commit is contained in:
Rebecca Law
2018-01-17 11:08:39 +00:00
committed by GitHub
37 changed files with 254 additions and 102 deletions
+7 -1
View File
@@ -52,7 +52,8 @@
'height': this.nativeHeight,
'top': this.topOffset
})
);
)
.css('position', 'absolute');
this.$scrollableTable = this.$component.find('.fullscreen-scrollable-table');
this.$fixedTable = this.$component.find('.fullscreen-fixed-table');
@@ -100,6 +101,11 @@
this.$scrollableTable.scrollLeft() < (this.$table.width() - this.$scrollableTable.width())
);
setTimeout(
() => this.$component.find('.fullscreen-right-shadow').addClass('with-transition'),
3000
);
};
};
@@ -6,8 +6,7 @@
z-index: 10;
overflow-y: hidden;
box-sizing: border-box;
position: absolute;
margin: 5px 0 $gutter 0;
margin: 0 0 $gutter 0;
padding: 0 0 0 0;
overflow: hidden;
border-bottom: 1px solid $border-colour;
@@ -42,8 +41,13 @@
z-index: 200;
&.visible {
transition: box-shadow 0.3s ease-in-out;
&.with-transition {
transition: box-shadow 0.6s ease-out;
}
box-shadow: inset -1px 0 0 0 $border-colour, inset -3px 0 0 0 rgba($border-colour, 0.2);
}
}
@@ -1,5 +1,7 @@
.radio-select {
min-height: 39px;
&-column {
display: inline-block;
@@ -129,8 +129,31 @@
}
&-index {
@include bold-16;
width: 15px;
a {
&:before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
&:focus {
&:before {
background: $yellow;
z-index: -1;
}
}
}
}
p {
+3 -9
View File
@@ -534,15 +534,9 @@ class RequestToGoLiveForm(StripWhitespaceForm):
'Will the number of messages increase and when will that start?',
validators=[DataRequired(message='Cant be empty')]
)
upload_or_api = RadioField(
'How are you going to send messages?',
choices=[
('File upload', 'Upload a spreadsheet of recipients'),
('API', 'Integrate with the GOV.UK Notify API'),
('API and file upload', 'Both')
],
validators=[DataRequired()]
)
method_one_off = BooleanField('One at a time')
method_upload = BooleanField('Upload a spreadsheet of recipients')
method_api = BooleanField('Integrate with the GOV.UK Notify API')
class ProviderForm(StripWhitespaceForm):
+3 -11
View File
@@ -20,17 +20,10 @@ from app.main.forms import (
PermissionsForm
)
from app import (user_api_client, current_service, service_api_client, invite_api_client)
from app.notify_client.models import roles
from app.utils import user_has_permissions
roles = {
'send_messages': ['send_texts', 'send_emails', 'send_letters'],
'manage_templates': ['manage_templates'],
'manage_service': ['manage_users', 'manage_settings'],
'manage_api_keys': ['manage_api_keys']
}
@main.route("/services/<service_id>/users")
@login_required
@user_has_permissions('view_activity', admin_override=True)
@@ -92,10 +85,9 @@ def edit_user_permissions(service_id, user_id):
user_has_no_mobile_number = user.mobile_number is None
form = PermissionsForm(
**{role: user.has_permissions(permissions=permissions) for role, permissions in roles.items()},
**{role: user.has_permissions(*permissions) for role, permissions in roles.items()},
login_authentication=user.auth_type
)
if form.validate_on_submit():
user_api_client.set_user_permissions(
user_id, service_id,
@@ -122,7 +114,7 @@ def remove_user_from_service(service_id, user_id):
# Need to make the email address read only, or a disabled field?
# Do it through the template or the form class?
form = PermissionsForm(**{
role: user.has_permissions(permissions=permissions) for role, permissions in roles.items()
role: user.has_permissions(*permissions) for role, permissions in roles.items()
})
if request.method == 'POST':
+10 -6
View File
@@ -523,9 +523,12 @@ def _check_messages(service_id, template_type, upload_id, preview_row, letters_a
count_of_recipients = len(list(recipients.rows))
if preview_row < count_of_recipients:
template.values = recipients[preview_row]
elif preview_row > 0:
if preview_row < 2:
abort(404)
if preview_row < count_of_recipients + 2:
template.values = recipients[preview_row - 2]
elif preview_row > 2:
abort(404)
session['upload_data']['notification_count'] = count_of_recipients
@@ -553,7 +556,8 @@ def _check_messages(service_id, template_type, upload_id, preview_row, letters_a
template.template_type == 'letter',
not request.args.get('from_test'),
)),
required_recipient_columns=OrderedSet(recipients.recipient_column_headers) - optional_address_columns
required_recipient_columns=OrderedSet(recipients.recipient_column_headers) - optional_address_columns,
preview_row=preview_row,
)
@@ -561,7 +565,7 @@ def _check_messages(service_id, template_type, upload_id, preview_row, letters_a
@main.route("/services/<service_id>/<template_type>/check/<upload_id>/row-<int:row_index>", methods=['GET'])
@login_required
@user_has_permissions('send_texts', 'send_emails', 'send_letters')
def check_messages(service_id, template_type, upload_id, row_index=0):
def check_messages(service_id, template_type, upload_id, row_index=2):
data = _check_messages(service_id, template_type, upload_id, row_index)
@@ -589,7 +593,7 @@ def check_messages(service_id, template_type, upload_id, row_index=0):
@main.route("/services/<service_id>/<template_type>/check/<upload_id>/row-<int:row_index>.<filetype>", methods=['GET'])
@login_required
@user_has_permissions('send_texts', 'send_emails', 'send_letters')
def check_messages_preview(service_id, template_type, upload_id, filetype, row_index=0):
def check_messages_preview(service_id, template_type, upload_id, filetype, row_index=2):
if filetype not in ('pdf', 'png'):
abort(404)
+11 -4
View File
@@ -153,7 +153,6 @@ def service_request_to_go_live(service_id):
form = RequestToGoLiveForm()
if form.validate_on_submit():
data = {
'person_email': current_user.email_address,
'person_name': current_user.name,
@@ -161,13 +160,17 @@ def service_request_to_go_live(service_id):
'agent_team_id': current_app.config.get('DESKPRO_ASSIGNED_AGENT_TEAM_ID'),
'subject': 'Request to go live - {}'.format(current_service['name']),
'message': (
'On behalf of {} ({})\n\nExpected usage\n---'
'On behalf of {} ({})\n'
'\n---'
'\nOrganisation type: {}'
'\nMOU in place: {}'
'\nChannel: {}\nStart date: {}\nStart volume: {}'
'\nPeak volume: {}\nUpload or API: {}'
'\nPeak volume: {}'
'\nFeatures: {}'
).format(
current_service['name'],
url_for('main.service_dashboard', service_id=current_service['id'], _external=True),
current_service['organisation_type'],
form.mou.data,
formatted_list(filter(None, (
'email' if form.channel_email.data else None,
@@ -177,7 +180,11 @@ def service_request_to_go_live(service_id):
form.start_date.data,
form.start_volume.data,
form.peak_volume.data,
form.upload_or_api.data
formatted_list(filter(None, (
'one off' if form.method_one_off.data else None,
'file upload' if form.method_upload.data else None,
'API' if form.method_api.data else None,
)), before_each='', after_each='')
)
}
+1 -1
View File
@@ -354,7 +354,7 @@ def add_service_template(service_id, template_type):
def abort_403_if_not_admin_user():
if not current_user.has_permissions([], admin_override=True):
if not current_user.has_permissions(admin_override=True):
abort(403)
+19 -2
View File
@@ -1,7 +1,18 @@
from itertools import chain
from flask_login import UserMixin, AnonymousUserMixin
from flask import session
roles = {
'send_messages': ['send_texts', 'send_emails', 'send_letters'],
'manage_templates': ['manage_templates'],
'manage_service': ['manage_users', 'manage_settings'],
'manage_api_keys': ['manage_api_keys']
}
all_permissions = set(chain.from_iterable(roles.values())) | {'view_activity'}
class User(UserMixin):
def __init__(self, fields, max_failed_login_count=3):
self._id = fields.get('id')
@@ -91,7 +102,13 @@ class User(UserMixin):
def permissions(self, permissions):
raise AttributeError("Read only property")
def has_permissions(self, permissions=[], any_=False, admin_override=False):
def has_permissions(self, *permissions, any_=False, admin_override=False):
unknown_permissions = set(permissions) - all_permissions
if unknown_permissions:
raise TypeError('{} are not valid permissions'.format(unknown_permissions))
# Only available to the platform admin user
if admin_override and self.platform_admin:
return True
@@ -166,7 +183,7 @@ class InvitedUser(object):
self.created_at = created_at
self.auth_type = auth_type
def has_permissions(self, permissions):
def has_permissions(self, *permissions):
return set(self.permissions) > set(permissions)
def __eq__(self, other):
+4 -4
View File
@@ -44,17 +44,17 @@
<nav class="navigation">
<ul>
<li><a href="{{ url_for('.service_dashboard', service_id=current_service.id) }}">Dashboard</a></li>
{% if current_user.has_permissions(['view_activity', 'manage_templates', 'manage_api_keys'], admin_override=True, any_=True) %}
{% if current_user.has_permissions('view_activity', 'manage_templates', 'manage_api_keys', admin_override=True, any_=True) %}
<li><a href="{{ url_for('.choose_template', service_id=current_service.id) }}">Templates</a></li>
{% endif %}
{% if current_user.has_permissions(['manage_users', 'manage_settings'], admin_override=True) %}
{% if current_user.has_permissions('manage_users', 'manage_settings', admin_override=True) %}
<li><a href="{{ url_for('.manage_users', service_id=current_service.id) }}">Team members</a></li>
<li><a href="{{ url_for('.usage', service_id=current_service.id) }}">Usage</a></li>
<li><a href="{{ url_for('.service_settings', service_id=current_service.id) }}">Settings</a></li>
{% elif current_user.has_permissions(['view_activity']) %}
{% elif current_user.has_permissions('view_activity') %}
<li><a href="{{ url_for('.manage_users', service_id=current_service.id) }}">Team members</a></li>
{% endif %}
{% if current_user.has_permissions(['manage_api_keys'], admin_override=True) %}
{% if current_user.has_permissions('manage_api_keys', admin_override=True) %}
<li><a href="{{ url_for('.api_integration', service_id=current_service.id) }}">API integration</a></li>
{% endif %}
</ul>
+4
View File
@@ -30,4 +30,8 @@
{% endcall %}
{% endcall %}
</div>
{{ page_footer(
secondary_link=url_for('.api_integration', service_id=current_service.id),
secondary_link_text='Back to API integration'
) }}
{% endblock %}
+6 -2
View File
@@ -59,8 +59,12 @@
] + recipients.column_headers
) %}
{% call index_field() %}
<span class="{% if item.index in recipients.rows_with_errors %}table-field-error{% endif %}">
{{ item.index + 2 }}
<span>
{% if (item.index + 2) == preview_row %}
{{ item.index + 2 }}
{% else %}
<a href="{{ url_for('.check_messages', service_id=current_service.id, template_type=template.template_type, upload_id=upload_id, row_index=(item.index + 2)) }}">{{ item.index + 2 }}</a>
{% endif %}
</span>
{% endcall %}
{% for column in recipients.column_headers %}
@@ -22,7 +22,7 @@
'messages',
) }}
{% if current_user.has_permissions(['send_texts'], admin_override=True) %}
{% if current_user.has_permissions('send_texts', admin_override=True) %}
<p class="sms-message-reply-link">
<a href="{{ url_for('.conversation_reply', service_id=current_service.id, notification_id=notification_id) }}">Send a text message to this phone number</a>
</p>
+2 -2
View File
@@ -15,11 +15,11 @@
<div class="dashboard">
<h1 class="visuallyhidden">Dashboard</h1>
{% if current_user.has_permissions(['manage_templates'], admin_override=True) %}
{% if current_user.has_permissions('manage_templates', admin_override=True) %}
{% if not templates %}
{% include 'views/dashboard/write-first-messages.html' %}
{% endif %}
{% elif not current_user.has_permissions(['send_texts', 'send_emails', 'send_letters', 'manage_api_keys'], any_=True) %}
{% elif not current_user.has_permissions('send_texts', 'send_emails', 'send_letters', 'manage_api_keys', any_=True) %}
{% include 'views/dashboard/no-permissions-banner.html' %}
{% endif %}
+1 -1
View File
@@ -19,7 +19,7 @@
{{ textbox(form.name, width='1-1', hint='Your recipients wont see this', rows=10) }}
{{ textbox(form.subject, width='1-1', highlight_tags=True, rows=2) }}
{{ textbox(form.template_content, highlight_tags=True, width='1-1', rows=8) }}
{% if current_user.has_permissions([], admin_override=True) %}
{% if current_user.has_permissions(admin_override=True) %}
{{ radios(form.process_type) }}
{% endif %}
{{ page_footer(
+1 -1
View File
@@ -20,7 +20,7 @@
</div>
<div class="column-two-thirds">
{{ textbox(form.template_content, highlight_tags=True, width='1-1', rows=5) }}
{% if current_user.has_permissions([], admin_override=True) %}
{% if current_user.has_permissions(admin_override=True) %}
{{ radios(form.process_type) }}
{% endif %}
{{ page_footer(
+11 -11
View File
@@ -23,7 +23,7 @@
Team members
</h1>
</div>
{% if current_user.has_permissions(['manage_users'], admin_override=True) %}
{% if current_user.has_permissions('manage_users', admin_override=True) %}
<div class="column-one-third">
<a href="{{ url_for('.invite_user', service_id=current_service.id) }}" class="button align-with-heading">Invite team member</a>
</div>
@@ -48,19 +48,19 @@
<ul class="tick-cross-list">
<div class="tick-cross-list-permissions">
{{ tick_cross(
user.has_permissions(permissions=['send_texts', 'send_emails', 'send_letters']),
user.has_permissions('send_texts', 'send_emails', 'send_letters'),
'Send messages'
) }}
{{ tick_cross(
user.has_permissions(permissions=['manage_templates']),
user.has_permissions('manage_templates'),
'Add and edit templates'
) }}
{{ tick_cross(
user.has_permissions(permissions=['manage_users', 'manage_settings']),
user.has_permissions('manage_users', 'manage_settings'),
'Manage service'
) }}
{{ tick_cross(
user.has_permissions(permissions=['manage_api_keys']),
user.has_permissions('manage_api_keys'),
'Access API keys'
) }}
{% if 'email_auth' in current_service['permissions'] %}
@@ -73,7 +73,7 @@
</div>
{% endif %}
</div>
{% if current_user.has_permissions(['manage_users'], admin_override=True) %}
{% if current_user.has_permissions('manage_users', admin_override=True) %}
{% if current_user.id != user.id %}
<li class="tick-cross-list-edit-link">
<a href="{{ url_for('.edit_user_permissions', service_id=current_service.id, user_id=user.id)}}">Edit permissions</a>
@@ -98,19 +98,19 @@
<ul class="tick-cross-list">
<div class="tick-cross-list-permissions">
{{ tick_cross(
user.has_permissions(permissions=['send_texts', 'send_emails', 'send_letters']),
user.has_permissions('send_texts', 'send_emails', 'send_letters'),
'Send messages'
) }}
{{ tick_cross(
user.has_permissions(permissions=['manage_templates']),
user.has_permissions('manage_templates'),
'Add and edit templates'
) }}
{{ tick_cross(
user.has_permissions(permissions=['manage_users', 'manage_settings']),
user.has_permissions('manage_users', 'manage_settings'),
'Manage service'
) }}
{{ tick_cross(
user.has_permissions(permissions=['manage_api_keys']),
user.has_permissions('manage_api_keys'),
'Access API keys'
) }}
{% if 'email_auth' in current_service['permissions'] %}
@@ -124,7 +124,7 @@
{% endif %}
</div>
<li class="tick-cross-list-edit-link">
{% if user.status == 'pending' and current_user.has_permissions(['manage_users']) %}
{% if user.status == 'pending' and current_user.has_permissions('manage_users') %}
<a href="{{ url_for('.cancel_invited_user', service_id=current_service.id, invited_user_id=user.id)}}">Cancel invitation</a>
{% else %}
{{ user.status|title }}
@@ -45,7 +45,7 @@
{{ ajax_block(partials, updates_url, 'status', finished=finished) }}
{% endif %}
{% if current_user.has_permissions(['send_texts'], admin_override=True) and template.template_type == 'sms' and can_receive_inbound %}
{% if current_user.has_permissions('send_texts', admin_override=True) and template.template_type == 'sms' and can_receive_inbound %}
<p>
<a href="{{ url_for('.conversation', service_id=current_service.id, notification_id=notification_id, _anchor='n{}'.format(notification_id)) }}">See all text messages sent to this phone number</a>
</p>
+1 -1
View File
@@ -183,7 +183,7 @@
{% endif %}
{% if current_user.has_permissions([], admin_override=True) %}
{% if current_user.has_permissions(admin_override=True) %}
<h2 class="heading-medium">Platform admin settings</h2>
@@ -23,12 +23,8 @@
specified your reply to email address or text message sender in your
<a href="{{ url_for('main.service_settings', service_id=current_service.id) }}">settings</a> page</li>
<li>
added the templates you want to start with, making sure they follow our
<a href="https://www.gov.uk/service-manual/design/using-adapting-and-creating-patterns" rel="external">design patterns</a>,
<a href="https://www.gov.uk/guidance/style-guide" rel="external">style guide</a>
and
<a href="https://www.gov.uk/service-manual/technology/securing-your-information" rel="external">information security guidelines</a>
</li>
added the templates you want to start with, making sure they follow the GOV.UK Service Manual standards for
<a href="https://www.gov.uk/service-manual/design/sending-emails-and-text-messages">writing text messages and emails</a></li>
</ul>
<form method="post">
@@ -48,9 +44,12 @@
{{ textbox(form.start_date, width='1-1') }}
{{ textbox(form.start_volume, width='1-1', hint='For example, 1000 a month.') }}
{{ textbox(form.peak_volume, width='1-1', hint='For example, Messages will increase to 20,000 a month in January.') }}
{{ radios(form.upload_or_api) }}
</div>
{{ checkbox_group('How are you going to send messages?', [
form.method_one_off,
form.method_upload,
form.method_api
]) }}
<p>
Once youve completed the tasks needed to set up, well make your service live. Well do this within one working day.
</p>
@@ -19,6 +19,12 @@
If you want to turn this feature off,
<a href="{{ url_for('.support') }}">get in touch with the GOV.UK Notify team</a>.
</p>
{% if current_user.has_permissions('manage_api_keys', admin_override=True) %}
<p>
You can set up callbacks for received text messages on the
<a href="{{ url_for('.api_callbacks', service_id=current_service.id) }}">API integration page</a>.
</p>
{% endif %}
{% else %}
<p>
Receiving text messages from your users is an
+2 -2
View File
@@ -120,12 +120,12 @@
<div class="grid-row bottom-gutter">
<div class="column-half">
<h3 class="visually-hidden">Services</h3>
<div class="product-page-big-number">131</div>
<div class="product-page-big-number">135</div>
services
</div>
<div class="column-half">
<h3 class="visually-hidden">Organisations</h3>
<div class="product-page-big-number">55</div>
<div class="product-page-big-number">58</div>
organisations
</div>
</div>
+3 -3
View File
@@ -6,7 +6,7 @@
{% else %}
<div class="bottom-gutter-2-3">
<div class="grid-row">
{% if current_user.has_permissions(permissions=['send_texts', 'send_emails', 'send_letters']) %}
{% if current_user.has_permissions('send_texts', 'send_emails', 'send_letters') %}
<div class="{{ 'column-half' if template.template_type == 'letter' else 'column-third' }}">
<a href="{{ url_for(".send_messages", service_id=current_service.id, template_id=template.id) }}" class="pill-separate-item">
Upload recipients
@@ -19,7 +19,7 @@
</div>
{% endif %}
{% if
current_user.has_permissions(permissions=['manage_templates'], admin_override=True) and
current_user.has_permissions('manage_templates', admin_override=True) and
template.template_type != 'letter'
%}
<div class="column-one-third">
@@ -33,7 +33,7 @@
{% endif %}
</div>
<div class="column-whole template-container">
{% if current_user.has_permissions(permissions=['manage_templates'], admin_override=True) and template.template_type == 'letter' %}
{% if current_user.has_permissions('manage_templates', admin_override=True) and template.template_type == 'letter' %}
<a href="{{ url_for(".edit_service_template", service_id=current_service.id, template_id=template.id) }}" class="edit-template-link-letter-body">Edit</a>
<a href="{{ url_for(".set_template_sender", service_id=current_service.id, template_id=template.id) }}" class="edit-template-link-letter-contact">Edit</a>
{% endif %}
@@ -14,7 +14,7 @@
{% if not templates %}
{% if current_user.has_permissions(permissions=['manage_templates'], any_=True) %}
{% if current_user.has_permissions('manage_templates', any_=True) %}
<p class="bottom-gutter">
You need a template before you can send text messages.
</p>
+2 -2
View File
@@ -14,7 +14,7 @@
<h1 class="heading-large">Templates</h1>
{% if current_user.has_permissions(permissions=['manage_templates'], any_=True) %}
{% if current_user.has_permissions('manage_templates', any_=True) %}
<p class="bottom-gutter">
You need a template before you can send
{% if 'letter' in current_service.permissions %}
@@ -41,7 +41,7 @@
<div class="column-two-thirds">
<h1 class="heading-large">Templates</h1>
</div>
{% if current_user.has_permissions(permissions=['manage_templates'], admin_override=True) %}
{% if current_user.has_permissions('manage_templates', admin_override=True) %}
<div class="column-one-third">
<a href="{{ url_for('.add_template_by_type', service_id=current_service.id) }}" class="button align-with-heading">Add new template</a>
</div>
+1 -1
View File
@@ -63,7 +63,7 @@
&emsp;
<br/>
{% endif %}
{% if current_user.has_permissions(permissions=['manage_templates'], admin_override=True) %}
{% if current_user.has_permissions('manage_templates', admin_override=True) %}
{% if not template._template.archived %}
<span class="page-footer-delete-link page-footer-delete-link-without-button bottom-gutter-2-3">
<a href="{{ url_for('.delete_service_template', service_id=current_service.id, template_id=template.id) }}">Delete this template</a>
+1 -1
View File
@@ -39,7 +39,7 @@ Terms of use
<li>get the right levels of consent (to send messages and to use data)</li>
<li>not send unsolicited messages, only ones related to a transaction or something the user has subscribed to be updated about (<a href="https://www.gov.uk/service-manual/design/sending-emails-and-text-messages">check the Service Manual</a> if youre not sure)</li>
<li>
send messages that meet the GOV.UK <a href="https://www.gov.uk/service-manual/design/using-adapting-and-creating-patterns">design patterns</a>, <a href="https://www.gov.uk/guidance/style-guide">style guide</a> and <a href="https://www.gov.uk/service-manual/technology/securing-your-information">information security guidelines</a></li>
send messages that meet the GOV.UK Service Manual standards for <a href="https://www.gov.uk/service-manual/design/sending-emails-and-text-messages">writing text messages and emails</a></li>
<li>not send messages containing any personally or commercially sensitive information</li>
<li>check that the data you add to Notify is accurate and complies with Data Protection Act principles</li>
</ul>
+1 -1
View File
@@ -71,7 +71,7 @@ def user_has_permissions(*permissions, admin_override=False, any_=False):
def wrap_func(*args, **kwargs):
if current_user and current_user.is_authenticated:
if current_user.has_permissions(
permissions=permissions,
*permissions,
admin_override=admin_override,
any_=any_
):
+2 -2
View File
@@ -5,8 +5,8 @@ Flask-Login==0.4.1
boto3==1.5.12
blinker==1.4
pyexcel==0.5.6
pyexcel-io==0.5.5
pyexcel==0.5.7
pyexcel-io==0.5.6
pyexcel-xls==0.5.5
pyexcel-xlsx==0.5.5
pyexcel-ods3==0.5.2
+1 -1
View File
@@ -2,7 +2,7 @@
pytest==3.3.2
pytest-mock==1.6.3
pytest-cov==2.5.1
pytest-xdist==1.21.0
pytest-xdist==1.22.0
coveralls==1.2.0
httpretty==0.8.14
beautifulsoup4==4.6.0
-2
View File
@@ -56,7 +56,6 @@ def service_json(
service_callback_api=None,
permissions=None,
organisation_type='central',
free_sms_fragment_limit=250000,
prefix_sms=True,
):
if users is None:
@@ -70,7 +69,6 @@ def service_json(
'name': name,
'users': users,
'message_limit': message_limit,
'free_sms_fragment_limit': free_sms_fragment_limit,
'active': active,
'restricted': restricted,
'email_from': email_from,
+2 -2
View File
@@ -38,7 +38,7 @@ def test_user_has_permissions_on_endpoint_fail(
_test_permissions(
client,
user,
['something'],
['send_texts'],
'',
False)
@@ -66,7 +66,7 @@ def test_user_has_permissions_or(
_test_permissions(
client,
user,
['something', 'manage_users'],
['send_texts', 'manage_users'],
'',
True,
any_=True)
+4
View File
@@ -1,3 +1,4 @@
import pytest
from app.notify_client.user_api_client import User
@@ -25,3 +26,6 @@ def test_user():
# set failed logins to threshold
user.failed_login_count = 3
assert user.is_locked()
with pytest.raises(TypeError):
user.has_permissions('to_do_bad_things')
+27 -12
View File
@@ -464,19 +464,22 @@ def test_upload_valid_csv_redirects_to_check_page(
)
@pytest.mark.parametrize('extra_args, expected_recipient, expected_message', [
@pytest.mark.parametrize('extra_args, expected_link_in_first_row, expected_recipient, expected_message', [
(
{},
'To: 07700900001',
'Test Service: A, Template <em>content</em> with & entity',
),
(
{'row_index': 0},
None,
'To: 07700900001',
'Test Service: A, Template <em>content</em> with & entity',
),
(
{'row_index': 2},
None,
'To: 07700900001',
'Test Service: A, Template <em>content</em> with & entity',
),
(
{'row_index': 4},
True,
'To: 07700900003',
'Test Service: C, Template <em>content</em> with & entity',
),
@@ -490,6 +493,7 @@ def test_upload_valid_csv_shows_preview_and_table(
mock_get_detailed_service_for_today,
fake_uuid,
extra_args,
expected_link_in_first_row,
expected_recipient,
expected_message,
):
@@ -516,8 +520,16 @@ def test_upload_valid_csv_shows_preview_and_table(
assert page.select_one('.sms-message-recipient').text.strip() == expected_recipient
assert page.select_one('.sms-message-wrapper').text.strip() == expected_message
assert page.select_one('.table-field-index').text.strip() == '2'
if expected_link_in_first_row:
assert page.select_one('.table-field-index a')['href'] == url_for(
'main.check_messages', service_id=SERVICE_ONE_ID, template_type='sms', upload_id=fake_uuid, row_index=2
)
else:
assert not page.select_one('.table-field-index').select_one('a')
for index, cell in enumerate([
'<td class="table-field-index"> <span class=""> 2 </span> </td>',
'<td class="table-field-center-aligned "> <div class=""> 07700900001 </div> </td>',
'<td class="table-field-center-aligned "> <div class=""> A </div> </td>',
(
@@ -530,13 +542,16 @@ def test_upload_valid_csv_shows_preview_and_table(
'</td>'
),
]):
assert normalize_spaces(str(page.select('table tbody td')[index])) == cell
assert normalize_spaces(str(page.select('table tbody td')[index + 1])) == cell
@pytest.mark.parametrize('row_index, expected_status', [
(0, 200),
(0, 404),
(1, 404),
(2, 200),
(3, 404),
(3, 200),
(4, 200),
(5, 404),
])
def test_404_for_previewing_a_row_out_of_range(
client_request,
@@ -1468,11 +1483,11 @@ def test_can_start_letters_job(
{'postcode': 'abc123', 'addressline1': '123 street'},
),
(
{'row_index': 0},
{'row_index': 2},
{'postcode': 'abc123', 'addressline1': '123 street'},
),
(
{'row_index': 1},
{'row_index': 3},
{'postcode': 'cba321', 'addressline1': '321 avenue'},
),
])
+50 -2
View File
@@ -11,6 +11,7 @@ from app.utils import email_safe
from tests import validate_route_permission, service_json
from tests.conftest import (
active_user_with_permissions,
active_user_no_api_key_permission,
platform_admin_user,
normalize_spaces,
multiple_reply_to_email_addresses,
@@ -433,6 +434,14 @@ def test_should_show_request_to_go_live(
assert normalize_spaces(
page.select_one('label[for=channel_{}]'.format(channel)).text
) == label
for feature, label in (
('one_off', 'One at a time'),
('upload', 'Upload a spreadsheet of recipients'),
('api', 'Integrate with the GOV.UK Notify API'),
):
assert normalize_spaces(
page.select_one('label[for=method_{}]'.format(feature)).text
) == label
def test_should_redirect_after_request_to_go_live(
@@ -458,7 +467,9 @@ def test_should_redirect_after_request_to_go_live(
'start_date': '01/01/2017',
'start_volume': '100,000',
'peak_volume': '2,000,000',
'upload_or_api': 'API'
'method_one_off': 'y',
'method_upload': 'y',
'method_api': 'y',
},
_follow_redirects=True
)
@@ -476,11 +487,13 @@ def test_should_redirect_after_request_to_go_live(
)
returned_message = mock_post.call_args[1]['data']['message']
assert 'On behalf of service one' in returned_message
assert 'Organisation type: central' in returned_message
assert 'Channel: email and text messages' in returned_message
assert 'Start date: 01/01/2017' in returned_message
assert 'Start volume: 100,000' in returned_message
assert 'Peak volume: 2,000,000' in returned_message
assert 'Upload or API: API' in returned_message
assert 'Features: one off, file upload and API' in returned_message
assert normalize_spaces(page.select_one('.banner-default').text) == (
'Weve received your request to go live'
@@ -1927,6 +1940,41 @@ def test_set_inbound_sms_when_inbound_number_is_not_set(
assert response.status_code == 200
@pytest.mark.parametrize('user, expected_paragraphs', [
(active_user_with_permissions, [
'Your service can receive text messages sent to 07700900123.',
'If you want to turn this feature off, get in touch with the GOV.UK Notify team.',
'You can set up callbacks for received text messages on the API integration page.',
]),
(active_user_no_api_key_permission, [
'Your service can receive text messages sent to 07700900123.',
'If you want to turn this feature off, get in touch with the GOV.UK Notify team.',
]),
])
def test_set_inbound_sms_when_inbound_number_is_set(
client,
service_one,
mocker,
fake_uuid,
user,
expected_paragraphs,
):
service_one['permissions'] = ['inbound_sms']
mocker.patch('app.inbound_number_client.get_inbound_sms_number_for_service', return_value={
'data': {'number': '07700900123'}
})
client.login(user(fake_uuid), mocker, service_one)
response = client.get(url_for(
'main.service_set_inbound_sms', service_id=SERVICE_ONE_ID
))
paragraphs = BeautifulSoup(response.data.decode('utf-8'), 'html.parser').select('main p')
assert len(paragraphs) == len(expected_paragraphs)
for index, p in enumerate(expected_paragraphs):
assert normalize_spaces(paragraphs[index].text) == p
def test_empty_letter_contact_block_returns_error(
logged_in_client,
service_one,
+26 -1
View File
@@ -1236,6 +1236,31 @@ def active_user_manage_template_permission(fake_uuid):
return user
@pytest.fixture
def active_user_no_api_key_permission(fake_uuid):
from app.notify_client.user_api_client import User
user_data = {
'id': fake_uuid,
'name': 'Test User With Permissions',
'password': 'somepassword',
'password_changed_at': str(datetime.utcnow()),
'email_address': 'test@user.gov.uk',
'mobile_number': '07700 900762',
'state': 'active',
'failed_login_count': 0,
'permissions': {SERVICE_ONE_ID: [
'manage_templates',
'manage_settings',
'view_activity',
]},
'platform_admin': False,
'auth_type': 'sms_auth'
}
user = User(user_data)
return user
@pytest.fixture(scope='function')
def api_user_locked(fake_uuid):
from app.notify_client.user_api_client import User
@@ -1855,7 +1880,7 @@ def mock_no_inbound_number_for_service(mocker):
@pytest.fixture(scope='function')
def mock_has_permissions(mocker):
def _has_permission(permissions=None, any_=False, admin_override=False):
def _has_permission(*permissions, any_=False, admin_override=False):
return True
return mocker.patch(