diff --git a/app/assets/javascripts/liveSearch.js b/app/assets/javascripts/liveSearch.js new file mode 100644 index 000000000..8f53f3f52 --- /dev/null +++ b/app/assets/javascripts/liveSearch.js @@ -0,0 +1,44 @@ +(function(Modules) { + "use strict"; + + let normalize = (string) => string.toLowerCase().replace(/ /g,''); + + let filter = ($searchBox, $targets) => () => { + + let query = normalize($searchBox.val()); + + $targets.each(function() { + + let content = $(this).text(); + + $(this).toggle( + normalize(content).indexOf(normalize(query)) > -1 + ); + + }); + + }; + + + Modules.LiveSearch = function() { + + this.start = function(component) { + + let $component = $(component); + + let $searchBox = $('input', $component); + + let filterFunc = filter( + $searchBox, + $($component.data('targets')) + ); + + $searchBox.on('keyup input', filterFunc); + + filterFunc(); + + }; + + }; + +})(window.GOVUK.Modules); diff --git a/app/assets/stylesheets/_grids.scss b/app/assets/stylesheets/_grids.scss index 8e59bede1..afd38dc71 100644 --- a/app/assets/stylesheets/_grids.scss +++ b/app/assets/stylesheets/_grids.scss @@ -39,6 +39,11 @@ margin-bottom: $gutter-half; } +.bottom-gutter-1-3 { + @extend %bottom-gutter; + margin-bottom: $gutter/3; +} + .bottom-gutter-3-2 { @extend %bottom-gutter; margin-bottom: $gutter * 3/2; diff --git a/app/assets/stylesheets/components/email-message.scss b/app/assets/stylesheets/components/email-message.scss index d3dbbfde4..e7e122e46 100644 --- a/app/assets/stylesheets/components/email-message.scss +++ b/app/assets/stylesheets/components/email-message.scss @@ -1,9 +1,11 @@ $white-50-opaque: rgba($white, 0.5); $button-bottom-border-colour: rgba(0, 0, 0, 0.17); +$email-message-gutter: $gutter * 2; .email-message { margin-bottom: $gutter; + border: 1px solid $border-colour; &-meta { @@ -13,35 +15,34 @@ $button-bottom-border-colour: rgba(0, 0, 0, 0.17); td, th { @include core-19; - border-bottom: 0; - border-top: 1px solid $border-colour; + border-top: 0; + border-bottom: 1px solid $border-colour; vertical-align: top; } th { color: $secondary-text-colour; + padding-left: $email-message-gutter; } td { width: 99%; + padding-right: $email-message-gutter; } } &-from { padding-top: 15px; - border-top: 1px solid $border-colour; } &-body { width: 100%; box-sizing: border-box; - padding: $gutter-half 0 0 0; - margin: 0 0 $gutter * 1.5 0; + padding: $gutter-half $email-message-gutter 0 $email-message-gutter; + margin: 0 0 0 0; clear: both; - border-top: 1px solid $border-colour; - border-bottom: 1px solid $border-colour; position: relative; word-wrap: break-word; @@ -49,11 +50,13 @@ $button-bottom-border-colour: rgba(0, 0, 0, 0.17); .js-enabled & { max-height: 92px; + padding: 0; overflow: hidden; } .js-enabled .expanded & { max-height: none; + padding-bottom: $gutter; } } diff --git a/app/assets/stylesheets/components/letter.scss b/app/assets/stylesheets/components/letter.scss index 43aea97b2..62882c912 100644 --- a/app/assets/stylesheets/components/letter.scss +++ b/app/assets/stylesheets/components/letter.scss @@ -1,59 +1,34 @@ -// Easing function from: http://easings.net/#easeOutBack -$transition-easing: cubic-bezier(0.175, 0.885, 0.32, 1.275); -$iso-paper-ratio: 70.710678118%; +$iso-paper-ratio: 141.42135624%; + +@keyframes ellipsis { + to { + width: 1.25em; + } +} .letter { padding: 0; margin: 0 0 $gutter 0; position: relative; - - &:after { - content: ""; - display: block; - z-index: 10; - position: absolute; - top: 1px; - left: 5px; - height: 0; - padding: $iso-paper-ratio 0 0 0; - width: 100%; - background: $highlight-colour; - transform-origin: left bottom; - transform: scale(1, 0.985); - box-shadow: inset 0 0 0 1px $border-colour; - transition: all 0.2s $transition-easing; - } + background: $panel-colour; &:before { - content: ""; - z-index: 15; position: absolute; - bottom: -3px; - right: -5px; - width: 4px; - height: 7px; - background: $white; - transform: rotate(45deg); - box-shadow: inset 1px 0 0 0 $border-colour; - } - - &:hover { - - &:after { - transform: skew(-1.3deg, 0deg) scale(1, 0.96); - transition: all 0.1s $transition-easing; - background: mix($highlight-colour, $white); - } - - &:before { - transform: rotate(50deg); - } - + top: 10%; + left: 50%; + margin-left: -0.5em; + font-size: 96px; + color: $white; + overflow: hidden; + display: block; + vertical-align: bottom; + animation: ellipsis steps(4,end) 1.3s infinite; + content: "\2026"; // ellipsis + width: 0px; } a { - display: block; overflow: hidden; width: 100%; @@ -61,19 +36,6 @@ $iso-paper-ratio: 70.710678118%; padding: $iso-paper-ratio 0 0 0; position: relative; z-index: 20; - box-shadow: 0 1px 0 0 $border-colour; - - &:focus { - - outline: none; - box-shadow: 0 3px 0 0 $yellow; - - img { - box-shadow: inset 0 0 0 3px $yellow; - } - - } - } img { diff --git a/app/assets/stylesheets/components/live-search.scss b/app/assets/stylesheets/components/live-search.scss new file mode 100644 index 000000000..1de4dac74 --- /dev/null +++ b/app/assets/stylesheets/components/live-search.scss @@ -0,0 +1,16 @@ +input[type=search] { + // overrides this nasty global from GOV.UK template + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.live-search { + + display: none; + + .js-enabled & { + display: block; + } + +} diff --git a/app/assets/stylesheets/components/sms-message.scss b/app/assets/stylesheets/components/sms-message.scss index fda6d1116..9b260cf9d 100644 --- a/app/assets/stylesheets/components/sms-message.scss +++ b/app/assets/stylesheets/components/sms-message.scss @@ -2,9 +2,9 @@ .sms-message-wrapper { width: 100%; - max-width: 410px; + max-width: 450px; box-sizing: border-box; - padding: $gutter-half; + padding: $gutter-half $gutter-half $gutter-half $gutter-half; background: $panel-colour; border: 1px solid $panel-colour; border-radius: 5px; diff --git a/app/assets/stylesheets/components/tick-cross.scss b/app/assets/stylesheets/components/tick-cross.scss index b3a90660a..74fc461ab 100644 --- a/app/assets/stylesheets/components/tick-cross.scss +++ b/app/assets/stylesheets/components/tick-cross.scss @@ -1,6 +1,6 @@ %tick-cross { - @include core-16; + @include core-19; display: inline-block; background-size: 19px 19px; background-repeat: no-repeat; diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss index 56cc1caf8..7cf0c200d 100644 --- a/app/assets/stylesheets/main.scss +++ b/app/assets/stylesheets/main.scss @@ -58,6 +58,7 @@ $path: '/static/images/'; @import 'components/tick-cross'; @import 'components/list-entry'; @import 'components/letter'; +@import 'components/live-search'; @import 'components/vendor/breadcrumbs'; @import 'components/vendor/responsive-embed'; @@ -65,6 +66,7 @@ $path: '/static/images/'; @import 'views/users'; @import 'views/api'; @import 'views/product-page'; +@import 'views/template'; // TODO: break this up @import 'app'; diff --git a/app/assets/stylesheets/views/template.scss b/app/assets/stylesheets/views/template.scss new file mode 100644 index 000000000..93ca1aea8 --- /dev/null +++ b/app/assets/stylesheets/views/template.scss @@ -0,0 +1,41 @@ +.template-container { + position: relative; +} + +%edit-template-link, +.edit-template-link { + + @include core-19; + position: absolute; + background: $link-colour; + color: $white; + padding: 10px $gutter-half; + z-index: 10000; + + &:link, &:visited { + color: $white; + } + + &:hover { + color: $light-blue-25; + } + +} + +.edit-template-link-letter-contact { + @extend %edit-template-link; + right: -25px; + top: 13.3%; // align to top of contact block +} + +.edit-template-link-letter-address { + @extend %edit-template-link; + top: 16.5%; // align bottom edge to bottom of address + left: -5px; +} + +.edit-template-link-letter-body { + @extend %edit-template-link; + top: 33.3%; // aligns to top of subject + left: -5px; +} diff --git a/app/assets/stylesheets/views/users.scss b/app/assets/stylesheets/views/users.scss index 0d774388a..b04cd671d 100644 --- a/app/assets/stylesheets/views/users.scss +++ b/app/assets/stylesheets/views/users.scss @@ -1,6 +1,6 @@ .user-list { - @include core-16; + @include core-19; margin-bottom: $gutter * 1.5; &-item { diff --git a/app/main/forms.py b/app/main/forms.py index 9ae203e1f..cb5c9943a 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -22,7 +22,7 @@ from wtforms import ( FieldList, DateField, SelectField) -from wtforms.fields.html5 import EmailField, TelField +from wtforms.fields.html5 import EmailField, TelField, SearchField from wtforms.validators import (DataRequired, Email, Length, Regexp, Optional) from app.main.validators import (Blacklist, CsvFileValidator, ValidGovEmail, NoCommasInPlaceHolders, OnlyGSMCharacters) @@ -288,7 +288,18 @@ class EmailTemplateForm(BaseTemplateForm): class LetterTemplateForm(EmailTemplateForm): - pass + + subject = TextAreaField( + u'Title', + validators=[DataRequired(message="Can’t be empty")]) + + template_content = TextAreaField( + u'Body', + validators=[ + DataRequired(message="Can’t be empty"), + NoCommasInPlaceHolders() + ] + ) class ForgotPasswordForm(Form): @@ -591,3 +602,8 @@ class ChooseTemplateType(Form): ('sms', 'Text message'), ('letter', 'Letter') if include_letters else None ]) + + +class SearchTemplatesForm(Form): + + search = SearchField('Search by name') diff --git a/app/main/views/send.py b/app/main/views/send.py index 971e6c433..a5fb034e1 100644 --- a/app/main/views/send.py +++ b/app/main/views/send.py @@ -190,19 +190,6 @@ def send_test(service_id, template_id): ) -@main.route("/services//send//from-api", methods=['GET']) -@login_required -def send_from_api(service_id, template_id): - return render_template( - 'views/send-from-api.html', - template=get_template( - service_api_client.get_service_template(service_id, template_id)['data'], - current_service, - letter_preview_url=url_for('.view_template', service_id=service_id, template_id=template_id) - ) - ) - - def _check_messages(service_id, template_type, upload_id, letters_as_pdf=False): if not session.get('upload_data'): diff --git a/app/main/views/templates.py b/app/main/views/templates.py index c02ad9421..9ecedc0cb 100644 --- a/app/main/views/templates.py +++ b/app/main/views/templates.py @@ -13,7 +13,13 @@ from notifications_python_client.errors import HTTPError from app.main import main from app.utils import user_has_permissions, get_template, png_from_pdf -from app.main.forms import ChooseTemplateType, SMSTemplateForm, EmailTemplateForm, LetterTemplateForm +from app.main.forms import ( + ChooseTemplateType, + SMSTemplateForm, + EmailTemplateForm, + LetterTemplateForm, + SearchTemplatesForm, +) from app.main.views.send import get_example_csv_rows from app import service_api_client, current_service, template_statistics_client @@ -44,15 +50,8 @@ page_headings = { def choose_template(service_id): return render_template( 'views/templates/choose.html', - templates=[ - get_template( - template, - current_service, - letter_preview_url=url_for('.view_template', service_id=service_id, template_id=template['id']), - ) - for template in service_api_client.get_service_templates(service_id)['data'] - if should_show_template(template['template_type']) - ], + templates=service_api_client.get_service_templates(service_id)['data'], + search_form=SearchTemplatesForm(), ) @@ -73,7 +72,8 @@ def view_template(service_id, template_id): service_api_client.get_service_template(service_id, template_id)['data'], current_service, expand_emails=True, - letter_preview_url=url_for('.view_template', service_id=service_id, template_id=template_id) + letter_preview_url=url_for('.view_template', service_id=service_id, template_id=template_id), + show_recipient=True, ) ) @@ -178,6 +178,22 @@ def add_template_by_type(service_id): ) if form.validate_on_submit(): + + if form.template_type.data == 'letter': + blank_letter = service_api_client.create_service_template( + 'Untitled', + 'letter', + 'Content', + service_id, + 'Title', + 'normal', + ) + return redirect(url_for( + '.view_template', + service_id=service_id, + template_id=blank_letter['data']['id'], + )) + return redirect(url_for( '.add_service_template', service_id=service_id, @@ -202,7 +218,7 @@ def add_service_template(service_id, template_type): if form.process_type.data == 'priority': abort_403_if_not_admin_user() try: - service_api_client.create_service_template( + new_template = service_api_client.create_service_template( form.name.data, template_type, form.template_content.data, @@ -221,7 +237,7 @@ def add_service_template(service_id, template_type): raise e else: return redirect( - url_for('.choose_template', service_id=service_id) + url_for('.view_template', service_id=service_id, template_id=new_template['data']['id']) ) return render_template( diff --git a/app/templates/views/api/keys.html b/app/templates/views/api/keys.html index 6dbb99f44..44bbdf177 100644 --- a/app/templates/views/api/keys.html +++ b/app/templates/views/api/keys.html @@ -19,41 +19,43 @@ Create an API key - {% call(item, row_number) list_table( - keys, - empty_message="You haven’t created any API keys yet", - caption="API keys", - caption_visible=false, - field_headings=[ - 'API keys', - 'Action' - ], - field_headings_visible=False - ) %} - {% call field() %} -
- {{ item.name }} - - {% if item.key_type == 'normal' %} - Live – sends to anyone - {% elif item.key_type == 'team' %} - Team and whitelist – limits who you can send to - {% elif item.key_type == 'test' %} - Test – pretends to send messages - {% endif %} - -
+
+ {% call(item, row_number) list_table( + keys, + empty_message="You haven’t created any API keys yet", + caption="API keys", + caption_visible=false, + field_headings=[ + 'API keys', + 'Action' + ], + field_headings_visible=False + ) %} + {% call field() %} +
+ {{ item.name }} +
+ {% if item.key_type == 'normal' %} + Live – sends to anyone + {% elif item.key_type == 'team' %} + Team and whitelist – limits who you can send to + {% elif item.key_type == 'test' %} + Test – pretends to send messages + {% endif %} +
+
+ {% endcall %} + {% if item.expiry_date %} + {% call field(align='right') %} + Revoked {{ item.expiry_date|format_datetime_short }} + {% endcall %} + {% else %} + {% call field(align='right', status='error') %} + Revoke + {% endcall %} + {% endif %} {% endcall %} - {% if item.expiry_date %} - {% call field(align='right') %} - Revoked {{ item.expiry_date|format_datetime_short }} - {% endcall %} - {% else %} - {% call field(align='right', status='error') %} - Revoke - {% endcall %} - {% endif %} - {% endcall %} +
{{ page_footer( secondary_link=url_for('.api_integration', service_id=current_service.id), diff --git a/app/templates/views/check.html b/app/templates/views/check.html index bdb904c78..7d7de30b6 100644 --- a/app/templates/views/check.html +++ b/app/templates/views/check.html @@ -175,7 +175,11 @@ wrapping_class='bottom-gutter-2-3' ) }} {% endif %} + {% if template.template_type != 'letter' or not request.args.from_test %} + {% else %} + Download as PDF + {% endif %} Back {% endif %} diff --git a/app/templates/views/send-from-api.html b/app/templates/views/send-from-api.html deleted file mode 100644 index 9794d7bf1..000000000 --- a/app/templates/views/send-from-api.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "withnav_template.html" %} -{% from "components/api-key.html" import api_key %} - -{% block service_page_title %} - API info -{% endblock %} - -{% block maincolumn_content %} - -

- API info -

- - {{ template|string }} - -
- {{ api_key(template.id, name="Template ID", thing='template ID') }} -
- -{% endblock %} diff --git a/app/templates/views/send-test.html b/app/templates/views/send-test.html index 333c65cdb..53e0a515f 100644 --- a/app/templates/views/send-test.html +++ b/app/templates/views/send-test.html @@ -13,11 +13,17 @@ {% block maincolumn_content %} +

{% if request.args['help'] %} -

Example text message

+ Example text message {% else %} -

Send yourself a test

+ {% if template.template_type == 'letter' %} + Generate preview + {% else %} + Send yourself a test + {% endif %} {% endif %} + {{ template|string }} diff --git a/app/templates/views/service-settings.html b/app/templates/views/service-settings.html index 22328e672..b25b93875 100644 --- a/app/templates/views/service-settings.html +++ b/app/templates/views/service-settings.html @@ -11,7 +11,7 @@

Settings

-
+
{% call mapping_table( caption='Settings', diff --git a/app/templates/views/templates/_template.html b/app/templates/views/templates/_template.html index 9b3126ec0..f7c05eac9 100644 --- a/app/templates/views/templates/_template.html +++ b/app/templates/views/templates/_template.html @@ -1,25 +1,42 @@ -
- {{ template|string }} -
-
+
{% if template._template.archived %} -
- This template was deleted
{{ template._template.updated_at|format_date_normal }} -
+

+ This template was deleted {{ template._template.updated_at|format_datetime_relative }}. +

{% else %} -
- {% if current_user.has_permissions(permissions=['send_texts', 'send_emails', 'send_letters']) %} - - Upload recipients - - - Send yourself a test - - {% endif %} - {% if current_user.has_permissions(permissions=['manage_templates'], admin_override=True) %} - Edit template - {% endif %} - API info +
+
+ {% if current_user.has_permissions(permissions=['send_texts', 'send_emails', 'send_letters']) %} + + + {% endif %} + {% if + current_user.has_permissions(permissions=['manage_templates'], admin_override=True) and + template.template_type != 'letter' + %} + + {% endif %} +
{% endif %}
+
+ {% if current_user.has_permissions(permissions=['manage_templates'], admin_override=True) and template.template_type == 'letter' %} + Edit + Edit + Edit + {% endif %} + {{ template|string }} +
diff --git a/app/templates/views/templates/_template_history.html b/app/templates/views/templates/_template_history.html index ddf5ed391..853a3b059 100644 --- a/app/templates/views/templates/_template_history.html +++ b/app/templates/views/templates/_template_history.html @@ -1,18 +1,16 @@

{{ template.name }}

+

+ {% if template.get_raw('version', 1) > 1 %} + Edit made {% if template.get_raw('updated_at', None) %}{{ template.get_raw('updated_at')|format_datetime_normal }}{% endif %} + {% else %} + Created + {% if template.get_raw('created_at', None) %}{{ template.get_raw('created_at')|format_datetime_normal }}{% endif %} + {% endif %} + by {{ template.get_raw('created_by').name }} +

-
+
{{ template|string }}
- -
- -
diff --git a/app/templates/views/templates/choose.html b/app/templates/views/templates/choose.html index b20ab05fd..1d3590312 100644 --- a/app/templates/views/templates/choose.html +++ b/app/templates/views/templates/choose.html @@ -1,3 +1,6 @@ +{% from "components/message-count-label.html" import message_count_label %} +{% from "components/textbox.html" import textbox %} + {% extends "withnav_template.html" %} {% block service_page_title %} @@ -33,7 +36,7 @@ {% else %} -
+

Templates

@@ -44,19 +47,29 @@ {% endif %}
-
+ {% if templates|length > 7 %} +
+ +
+ {% endif %} + +
+ {% endif %} {% endblock %} diff --git a/app/templates/views/templates/template.html b/app/templates/views/templates/template.html index ef559829b..f18226a98 100644 --- a/app/templates/views/templates/template.html +++ b/app/templates/views/templates/template.html @@ -1,6 +1,7 @@ {% extends "withnav_template.html" %} {% from "components/page-footer.html" import page_footer %} {% from "components/textbox.html" import textbox %} +{% from "components/api-key.html" import api_key %} {% block service_page_title %} {{ template.name }} @@ -17,9 +18,17 @@ {% endwith %}
- {{ page_footer( - secondary_link=url_for('.choose_template', service_id=current_service.id), - secondary_link_text='All templates' - ) }} +
+ {{ api_key(template.id, name="Template ID", thing='template ID') }} +
+ + {% if template._template.updated_at %} +
+

Last edited {{ template._template.updated_at|format_datetime_relative }}

+

+ See previous versions +

+
+ {% endif %} {% endblock %} diff --git a/app/templates/withnav_template.html b/app/templates/withnav_template.html index 9dbffd7e4..ebdf53f6b 100644 --- a/app/templates/withnav_template.html +++ b/app/templates/withnav_template.html @@ -13,10 +13,10 @@ Switch service
-
+
{% include "main_nav.html" %}
-
+
{% include 'flash_messages.html' %} {% block maincolumn_content %}{% endblock %}
diff --git a/app/utils.py b/app/utils.py index 0eae0ca78..de4bbbb5f 100644 --- a/app/utils.py +++ b/app/utils.py @@ -330,7 +330,7 @@ def png_from_pdf(pdf_endpoint): output = BytesIO() with Image( blob=pdf_endpoint.get_data(), - resolution=96, + resolution=150, ) as image: with image.convert('png') as converted: converted.save(file=output) diff --git a/gulpfile.babel.js b/gulpfile.babel.js index ab087224b..5c4a93783 100644 --- a/gulpfile.babel.js +++ b/gulpfile.babel.js @@ -64,6 +64,7 @@ gulp.task('javascripts', () => gulp paths.src + 'javascripts/radioSelect.js', paths.src + 'javascripts/updateContent.js', paths.src + 'javascripts/listEntry.js', + paths.src + 'javascripts/liveSearch.js', paths.src + 'javascripts/main.js' ]) .pipe(plugins.prettyerror()) diff --git a/tests/app/main/views/test_send.py b/tests/app/main/views/test_send.py index 70076b152..16fc3aff3 100644 --- a/tests/app/main/views/test_send.py +++ b/tests/app/main/views/test_send.py @@ -316,25 +316,6 @@ def test_send_test_sms_message_with_placeholders( mock_s3_upload.assert_called_with(fake_uuid, expected_data, 'eu-west-1') -def test_api_info_page( - logged_in_client, - mocker, - api_user_active, - mock_login, - mock_get_service, - mock_get_service_email_template, - mock_s3_upload, - mock_has_permissions, - fake_uuid -): - response = logged_in_client.get( - url_for('main.send_from_api', service_id=fake_uuid, template_id=fake_uuid), - follow_redirects=True - ) - assert response.status_code == 200 - assert 'API info' in response.get_data(as_text=True) - - def test_download_example_csv( logged_in_client, mocker, @@ -664,132 +645,6 @@ def test_route_invalid_permissions( service_one) -def test_route_choose_template_manage_service_permissions( - mocker, - app_, - client, - api_user_active, - service_one, - mock_login, - mock_get_user, - mock_get_service, - mock_check_verify_code, - mock_get_service_templates, - mock_get_jobs, -): - template_id = mock_get_service_templates(service_one['id'])['data'][0]['id'] - resp = validate_route_permission( - mocker, - app_, - "GET", - 200, - url_for( - 'main.choose_template', - service_id=service_one['id'], - ), - ['manage_users', 'manage_templates', 'manage_settings'], - api_user_active, - service_one) - page = resp.get_data(as_text=True) - assert url_for( - "main.send_messages", - service_id=service_one['id'], - template_id=template_id) not in page - assert url_for( - "main.send_test", - service_id=service_one['id'], - template_id=template_id) not in page - assert url_for( - "main.edit_service_template", - service_id=service_one['id'], - template_id=template_id) in page - - -def test_route_choose_template_send_messages_permissions( - mocker, - app_, - client, - active_user_with_permissions, - service_one, - mock_get_service, - mock_check_verify_code, - mock_get_service_templates, - mock_get_jobs, -): - template_id = None - for temp in mock_get_service_templates(service_one['id'])['data']: - if temp['template_type'] == 'sms': - template_id = temp['id'] - assert template_id - resp = validate_route_permission( - mocker, - app_, - "GET", - 200, - url_for( - 'main.choose_template', - service_id=service_one['id'], - template_type='sms'), - ['send_texts', 'send_emails', 'send_letters'], - active_user_with_permissions, - service_one) - page = resp.get_data(as_text=True) - assert url_for( - "main.send_messages", - service_id=service_one['id'], - template_id=template_id) in page - assert url_for( - "main.edit_service_template", - service_id=service_one['id'], - template_id=template_id) not in page - - -def test_route_choose_template_manage_api_keys_permissions( - mocker, - app_, - client, - api_user_active, - service_one, - mock_get_user, - mock_get_service, - mock_check_verify_code, - mock_get_service_templates, - mock_get_jobs, -): - template_id = None - for temp in mock_get_service_templates(service_one['id'])['data']: - if temp['template_type'] == 'sms': - template_id = temp['id'] - assert template_id - resp = validate_route_permission( - mocker, - app_, - "GET", - 200, - url_for( - 'main.choose_template', - service_id=service_one['id'], - template_type='sms'), - ['manage_api_keys'], - api_user_active, - service_one) - page = resp.get_data(as_text=True) - assert url_for( - "main.send_test", - service_id=service_one['id'], - template_id=template_id) not in page - assert url_for( - "main.edit_service_template", - service_id=service_one['id'], - template_id=template_id) not in page - page = BeautifulSoup(resp.data.decode('utf-8'), 'html.parser') - links = page.findAll('a', href=re.compile('^' + url_for( - "main.send_from_api", - service_id=service_one['id'], - template_id=template_id))) - assert len(links) == 1 - - @pytest.mark.parametrize( 'extra_args,expected_url', [ diff --git a/tests/app/main/views/test_templates.py b/tests/app/main/views/test_templates.py index 316cfa95a..71ea2fb8a 100644 --- a/tests/app/main/views/test_templates.py +++ b/tests/app/main/views/test_templates.py @@ -33,6 +33,75 @@ def test_should_show_page_for_one_template( mock_get_service_template.assert_called_with(service_one['id'], template_id) +@pytest.mark.parametrize('permissions, links_to_be_shown', [ + ( + ['view_activity'], + [] + ), + ( + ['manage_templates'], + ['.edit_service_template'] + ), + ( + ['send_texts', 'send_emails', 'send_letters'], + ['.send_messages', '.send_test'] + ), + ( + ['send_texts', 'send_emails', 'send_letters', 'manage_templates'], + ['.send_messages', '.send_test', '.edit_service_template'] + ), +]) +def test_should_be_able_to_view_a_template_with_links( + client, + mock_get_service_template, + active_user_with_permissions, + mocker, + service_one, + fake_uuid, + permissions, + links_to_be_shown, +): + active_user_with_permissions._permissions[service_one['id']] = permissions + client.login(active_user_with_permissions, mocker, service_one) + + response = client.get(url_for( + '.view_template', + service_id=service_one['id'], + template_id=fake_uuid + )) + + assert response.status_code == 200 + page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') + links_in_page = page.select('.pill-separate-item') + + assert len(links_in_page) == len(links_to_be_shown) + + for index, link_to_be_shown in enumerate(links_to_be_shown): + assert links_in_page[index]['href'] == url_for( + link_to_be_shown, + service_id=service_one['id'], + template_id=fake_uuid, + ) + + +def test_should_show_template_id_on_template_page( + logged_in_client, + mock_get_service_template, + service_one, + fake_uuid, +): + + response = logged_in_client.get(url_for( + '.view_template', + service_id=service_one['id'], + template_id=fake_uuid)) + + assert response.status_code == 200 + + page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') + assert page.select('.api-key-key')[0].text == fake_uuid + + def test_should_show_sms_template_with_downgraded_unicode_characters( logged_in_client, mocker, @@ -513,10 +582,10 @@ def test_should_show_page_for_a_deleted_template( assert response.status_code == 200 content = response.get_data(as_text=True) + page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') assert url_for("main.edit_service_template", service_id=fake_uuid, template_id=fake_uuid) not in content - assert url_for("main.send_from_api", service_id=fake_uuid, template_id=fake_uuid) not in content assert url_for("main.send_test", service_id=fake_uuid, template_id=fake_uuid) not in content - assert "This template was deleted
1 January 2016" in content + assert page.select('p.hint')[0].text.strip() == 'This template was deleted today at 3:00pm.' mock_get_deleted_template.assert_called_with(service_id, template_id)