diff --git a/app/assets/images/preview_error.png b/app/assets/images/preview_error.png new file mode 100644 index 000000000..fe8b448cb Binary files /dev/null and b/app/assets/images/preview_error.png differ diff --git a/app/main/views/notifications.py b/app/main/views/notifications.py index 365ffb25b..350fdd92b 100644 --- a/app/main/views/notifications.py +++ b/app/main/views/notifications.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import base64 +import os from datetime import datetime from flask import ( @@ -11,6 +13,7 @@ from flask import ( url_for, ) from flask_login import login_required +from notifications_python_client.errors import APIError from app import ( current_service, @@ -19,7 +22,7 @@ from app import ( notification_api_client, ) from app.main import main -from app.template_previews import TemplatePreview, get_page_count_for_letter +from app.template_previews import get_page_count_for_letter from app.utils import ( DELIVERED_STATUSES, FAILURE_STATUSES, @@ -83,6 +86,12 @@ def view_notification(service_id, notification_id): ) +def get_preview_error_image(): + path = os.path.join(os.path.dirname(__file__), "..", "..", "assets", "images", "preview_error.png") + with open(path, "rb") as file: + return file.read() + + @main.route("/services//notification/.") @login_required @user_has_permissions('view_activity') @@ -91,23 +100,19 @@ def view_letter_notification_as_preview(service_id, notification_id, filetype): if filetype not in ('pdf', 'png'): abort(404) - notification = notification_api_client.get_notification(service_id, notification_id) - notification['template'].update({'reply_to_text': notification['reply_to_text']}) + try: + preview = notification_api_client.get_notification_letter_preview( + service_id, + notification_id, + filetype, + page=request.args.get('page') + ) - template = get_template( - notification['template'], - current_service, - letter_preview_url=url_for( - '.view_letter_notification_as_preview', - service_id=service_id, - notification_id=notification_id, - filetype='png', - ), - ) + display_file = base64.b64decode(preview['content']) + except APIError: + display_file = get_preview_error_image() - template.values = notification['personalisation'] - - return TemplatePreview.from_utils_template(template, filetype, page=request.args.get('page')) + return display_file @main.route("/services//notification/.json") diff --git a/app/notify_client/notification_api_client.py b/app/notify_client/notification_api_client.py index 9e80af511..6f903e835 100644 --- a/app/notify_client/notification_api_client.py +++ b/app/notify_client/notification_api_client.py @@ -73,3 +73,14 @@ class NotificationApiClient(NotifyAdminAPIClient): if notification['notification_type'] == 'letter' and notification['status'] in ('created', 'sending'): notification['status'] = 'accepted' return notifications + + def get_notification_letter_preview(self, service_id, notification_id, file_type, page=None): + + get_url = '/service/{}/template/preview/{}/{}{}'.format( + service_id, + notification_id, + file_type, + '?page={}'.format(page) if page else '' + ) + + return self.get(url=get_url) diff --git a/tests/app/main/views/test_notifications.py b/tests/app/main/views/test_notifications.py index 958c2827d..0f89d2de4 100644 --- a/tests/app/main/views/test_notifications.py +++ b/tests/app/main/views/test_notifications.py @@ -1,9 +1,11 @@ +import base64 from functools import partial +from unittest.mock import mock_open import pytest from flask import url_for from freezegun import freeze_time -from notifications_utils.template import LetterImageTemplate +from notifications_python_client.errors import APIError from tests.conftest import ( SERVICE_ONE_ID, mock_get_notification, @@ -163,9 +165,11 @@ def test_should_show_image_of_letter_notification( mock_get_notification(mocker, fake_uuid, template_type='letter') - mocked_preview = mocker.patch( - 'app.main.views.templates.TemplatePreview.from_utils_template', - return_value='foo' + mocker.patch( + 'app.notify_client.notification_api_client.NotificationApiClient.get', + return_value={ + 'content': base64.b64encode(b'foo').decode('utf-8') + } ) response = logged_in_client.get(url_for( @@ -177,8 +181,32 @@ def test_should_show_image_of_letter_notification( assert response.status_code == 200 assert response.get_data(as_text=True) == 'foo' - assert isinstance(mocked_preview.call_args[0][0], LetterImageTemplate) - assert mocked_preview.call_args[0][1] == filetype + + +def test_should_show_preview_error_image_letter_notification_on_preview_error( + logged_in_client, + fake_uuid, + mocker, +): + + mock_get_notification(mocker, fake_uuid, template_type='letter') + + mocker.patch( + 'app.notify_client.notification_api_client.NotificationApiClient.get', + side_effect=APIError + ) + + mocker.patch("builtins.open", mock_open(read_data="preview error image")) + + response = logged_in_client.get(url_for( + 'main.view_letter_notification_as_preview', + service_id=SERVICE_ONE_ID, + notification_id=fake_uuid, + filetype='png' + )) + + assert response.status_code == 200 + assert response.get_data(as_text=True) == 'preview error image' def test_should_404_for_unknown_extension(