From 8f7a05200de0c7791bd67f354c2690e85ebbb315 Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Tue, 15 Oct 2019 15:53:29 +0100 Subject: [PATCH] Add function to map template-preview errors to user-friendly errors Template preview now returns a short string as it's error message plus a list of invalid pages. --- app/utils.py | 53 ++++++++++++++++++++++++++++++++++++++++- tests/app/test_utils.py | 23 ++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/app/utils.py b/app/utils.py index 71e058fd3..9f3d9483e 100644 --- a/app/utils.py +++ b/app/utils.py @@ -17,7 +17,10 @@ from dateutil import parser from flask import abort, current_app, redirect, request, session, url_for from flask_login import current_user, login_required from notifications_utils.field import Field -from notifications_utils.formatters import make_quotes_smart +from notifications_utils.formatters import ( + make_quotes_smart, + unescaped_formatted_list, +) from notifications_utils.letter_timings import letter_can_be_cancelled from notifications_utils.recipients import RecipientCSV from notifications_utils.take import Take @@ -544,6 +547,54 @@ def get_letter_printing_statement(status, created_at): return 'Printed on {} at 5:30pm'.format(printed_date) +LETTER_VALIDATION_MESSAGES = { + 'letter-not-a4-portrait-oriented': { + 'title': 'We cannot print your letter', + 'detail': 'Your letter is not A4 portrait size on {invalid_pages}
' + 'Files must meet our letter specification.' + }, + 'content-outside-printable-area': { + 'title': 'We cannot print your letter', + 'detail': 'The content appears outside the printable area on {invalid_pages}
' + 'Files must meet our letter specification.' + }, + 'letter-too-long': { + 'title': 'Your letter is too long', + 'detail': 'Letters must be 10 pages or less.
Your letter is {page_count} pages long.' + }, + 'no-encoded-string': { + 'title': 'Sanitise failed - No encoded string' + }, + 'unable-to-read-the-file': { + 'title': 'There’s a problem with your file', + 'detail': 'Notify cannot read this PDF.
Save a new copy of your file and try again.' + } +} + + +def get_letter_validation_error(validation_message, invalid_pages=None, page_count=None): + if validation_message not in LETTER_VALIDATION_MESSAGES: + return {'title': 'Validation failed'} + + invalid_pages = unescaped_formatted_list( + invalid_pages or [], + before_each='', + after_each='', + prefix='page', + prefix_plural='pages' + ) + + return { + 'title': LETTER_VALIDATION_MESSAGES[validation_message]['title'], + 'detail': LETTER_VALIDATION_MESSAGES[validation_message]['detail'].format( + invalid_pages=invalid_pages, + page_count=page_count, + ) + } + + class PermanentRedirect(RequestRedirect): """ In Werkzeug 0.15.0 the status code for RequestRedirect changed from 301 to 308. diff --git a/tests/app/test_utils.py b/tests/app/test_utils.py index b230188ad..cb493adeb 100644 --- a/tests/app/test_utils.py +++ b/tests/app/test_utils.py @@ -14,6 +14,7 @@ from app.utils import ( generate_notifications_csv, generate_previous_dict, get_letter_printing_statement, + get_letter_validation_error, get_logo_cdn_domain, printing_today_or_tomorrow, ) @@ -404,3 +405,25 @@ def test_get_letter_printing_statement_for_letter_that_has_been_sent(created_at, statement = get_letter_printing_statement('delivered', created_at) assert statement == 'Printed {} at 5:30pm'.format(print_day) + + +def test_get_letter_validation_error_for_unknown_error(): + assert get_letter_validation_error('Unknown error') == { + 'title': 'Validation failed' + } + + +@pytest.mark.parametrize('error_message, expected_title, expected_content', [ + ('letter-not-a4-portrait-oriented', 'We cannot print your letter', 'A4 portrait size on page 2'), + ('content-outside-printable-area', 'We cannot print your letter', 'outside the printable area on page 2'), + ('letter-too-long', 'Your letter is too long', 'letter is 13 pages long.') +]) +def test_get_letter_validation_error_for_known_errors( + error_message, + expected_title, + expected_content, +): + error = get_letter_validation_error(error_message, invalid_pages=[2], page_count=13) + + assert error['title'] == expected_title + assert expected_content in error['detail']