mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-24 00:07:02 -04:00
Merge pull request #1224 from alphagov/letters-from-a-service
Letters from template-preview service
This commit is contained in:
@@ -25,9 +25,10 @@ Languages needed
|
|||||||
- [Node](https://nodejs.org/) 5.0.0 or greater
|
- [Node](https://nodejs.org/) 5.0.0 or greater
|
||||||
- [npm](https://www.npmjs.com/) 3.0.0 or greater
|
- [npm](https://www.npmjs.com/) 3.0.0 or greater
|
||||||
```shell
|
```shell
|
||||||
brew install node imagemagick ghostscript cairo pango
|
brew install node
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
[NPM](npmjs.org) is Node's package management tool. `n` is a tool for managing
|
[NPM](npmjs.org) is Node's package management tool. `n` is a tool for managing
|
||||||
different versions of Node. The following installs `n` and uses the latest
|
different versions of Node. The following installs `n` and uses the latest
|
||||||
version of Node.
|
version of Node.
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ def set_config_env_vars(vcap_services):
|
|||||||
extract_hosted_graphite_config(s)
|
extract_hosted_graphite_config(s)
|
||||||
elif s['name'] == 'deskpro':
|
elif s['name'] == 'deskpro':
|
||||||
extract_deskpro_config(s)
|
extract_deskpro_config(s)
|
||||||
|
elif s['name'] == 'notify-template-preview':
|
||||||
|
extract_template_preview_config(s)
|
||||||
|
|
||||||
|
|
||||||
def extract_notify_config(notify_config):
|
def extract_notify_config(notify_config):
|
||||||
@@ -49,3 +51,8 @@ def extract_hosted_graphite_config(hosted_graphite_config):
|
|||||||
def extract_deskpro_config(deskpro_config):
|
def extract_deskpro_config(deskpro_config):
|
||||||
os.environ['DESKPRO_API_HOST'] = deskpro_config['credentials']['api_host']
|
os.environ['DESKPRO_API_HOST'] = deskpro_config['credentials']['api_host']
|
||||||
os.environ['DESKPRO_API_KEY'] = deskpro_config['credentials']['api_key']
|
os.environ['DESKPRO_API_KEY'] = deskpro_config['credentials']['api_key']
|
||||||
|
|
||||||
|
|
||||||
|
def extract_template_preview_config(template_preview_config):
|
||||||
|
os.environ['TEMPLATE_PREVIEW_API_HOST'] = template_preview_config['credentials']['api_host']
|
||||||
|
os.environ['TEMPLATE_PREVIEW_API_KEY'] = template_preview_config['credentials']['api_key']
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ class Config(object):
|
|||||||
# if we're not on cloudfoundry, we can get to this app from localhost. but on cloudfoundry its different
|
# if we're not on cloudfoundry, we can get to this app from localhost. but on cloudfoundry its different
|
||||||
ADMIN_BASE_URL = os.environ.get('ADMIN_BASE_URL', 'http://localhost:6012')
|
ADMIN_BASE_URL = os.environ.get('ADMIN_BASE_URL', 'http://localhost:6012')
|
||||||
|
|
||||||
|
TEMPLATE_PREVIEW_API_HOST = os.environ.get('TEMPLATE_PREVIEW_API_HOST', 'http://localhost:6013')
|
||||||
|
TEMPLATE_PREVIEW_API_KEY = os.environ.get('TEMPLATE_PREVIEW_API_KEY', 'my-secret-key')
|
||||||
|
|
||||||
# Hosted graphite statsd prefix
|
# Hosted graphite statsd prefix
|
||||||
STATSD_PREFIX = os.getenv('STATSD_PREFIX')
|
STATSD_PREFIX = os.getenv('STATSD_PREFIX')
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ from flask import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from flask_weasyprint import HTML, render_pdf
|
|
||||||
|
|
||||||
from notifications_utils.columns import Columns
|
from notifications_utils.columns import Columns
|
||||||
from notifications_utils.recipients import RecipientCSV, first_column_headings, validate_and_format_phone_number
|
from notifications_utils.recipients import RecipientCSV, first_column_headings, validate_and_format_phone_number
|
||||||
@@ -36,9 +35,9 @@ from app.utils import (
|
|||||||
get_errors_for_csv,
|
get_errors_for_csv,
|
||||||
Spreadsheet,
|
Spreadsheet,
|
||||||
get_help_argument,
|
get_help_argument,
|
||||||
get_template,
|
get_template
|
||||||
png_from_pdf,
|
|
||||||
)
|
)
|
||||||
|
from app.template_previews import TemplatePreview
|
||||||
|
|
||||||
|
|
||||||
def get_page_headings(template_type):
|
def get_page_headings(template_type):
|
||||||
@@ -291,23 +290,17 @@ def check_messages(service_id, template_type, upload_id):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@main.route("/services/<service_id>/<template_type>/check/<upload_id>.pdf", methods=['GET'])
|
@main.route("/services/<service_id>/<template_type>/check/<upload_id>.<filetype>", methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
@user_has_permissions('send_texts', 'send_emails', 'send_letters')
|
@user_has_permissions('send_texts', 'send_emails', 'send_letters')
|
||||||
def check_messages_as_pdf(service_id, template_type, upload_id):
|
def check_messages_preview(service_id, template_type, upload_id, filetype):
|
||||||
|
if filetype not in ('pdf', 'png'):
|
||||||
|
abort(404)
|
||||||
|
|
||||||
template = _check_messages(
|
template = _check_messages(
|
||||||
service_id, template_type, upload_id, letters_as_pdf=True
|
service_id, template_type, upload_id, letters_as_pdf=True
|
||||||
)['template']
|
)['template']
|
||||||
return render_pdf(HTML(string=str(template)))
|
return TemplatePreview.from_utils_template(template, filetype)
|
||||||
|
|
||||||
|
|
||||||
@main.route("/services/<service_id>/<template_type>/check/<upload_id>.png", methods=['GET'])
|
|
||||||
@login_required
|
|
||||||
@user_has_permissions('send_texts', 'send_emails', 'send_letters')
|
|
||||||
def check_messages_as_png(service_id, template_type, upload_id):
|
|
||||||
return send_file(**png_from_pdf(
|
|
||||||
check_messages_as_pdf(service_id, template_type, upload_id)
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
@main.route("/services/<service_id>/<template_type>/check/<upload_id>", methods=['POST'])
|
@main.route("/services/<service_id>/<template_type>/check/<upload_id>", methods=['POST'])
|
||||||
|
|||||||
@@ -8,20 +8,17 @@ from flask import (
|
|||||||
url_for,
|
url_for,
|
||||||
flash,
|
flash,
|
||||||
abort,
|
abort,
|
||||||
send_file,
|
|
||||||
current_app
|
|
||||||
)
|
)
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from flask_weasyprint import HTML, render_pdf
|
|
||||||
from dateutil.parser import parse
|
from dateutil.parser import parse
|
||||||
|
|
||||||
from notifications_utils.formatters import escape_html
|
from notifications_utils.formatters import escape_html
|
||||||
from notifications_utils.template import LetterPreviewTemplate
|
|
||||||
from notifications_utils.recipients import first_column_headings
|
from notifications_utils.recipients import first_column_headings
|
||||||
from notifications_python_client.errors import HTTPError
|
from notifications_python_client.errors import HTTPError
|
||||||
|
|
||||||
from app.main import main
|
from app.main import main
|
||||||
from app.utils import user_has_permissions, get_template, png_from_pdf
|
from app.utils import user_has_permissions, get_template
|
||||||
|
from app.template_previews import TemplatePreview
|
||||||
from app.main.forms import (
|
from app.main.forms import (
|
||||||
ChooseTemplateType,
|
ChooseTemplateType,
|
||||||
SMSTemplateForm,
|
SMSTemplateForm,
|
||||||
@@ -87,26 +84,15 @@ def view_template(service_id, template_id):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@main.route("/services/<service_id>/templates/<template_id>.pdf")
|
@main.route("/services/<service_id>/templates/<template_id>.<filetype>")
|
||||||
@login_required
|
@login_required
|
||||||
@user_has_permissions('view_activity', admin_override=True)
|
@user_has_permissions('view_activity', admin_override=True)
|
||||||
def view_letter_template_as_pdf(service_id, template_id):
|
def view_letter_template_preview(service_id, template_id, filetype):
|
||||||
return render_pdf(HTML(string=str(
|
if filetype not in ('pdf', 'png'):
|
||||||
LetterPreviewTemplate(
|
abort(404)
|
||||||
service_api_client.get_service_template(service_id, template_id)['data'],
|
|
||||||
contact_block=current_service['letter_contact_block'],
|
|
||||||
admin_base_url=current_app.config['ADMIN_BASE_URL']
|
|
||||||
)
|
|
||||||
)))
|
|
||||||
|
|
||||||
|
db_template = service_api_client.get_service_template(service_id, template_id)['data']
|
||||||
@main.route("/services/<service_id>/templates/<template_id>.png")
|
return TemplatePreview.from_database_object(db_template, filetype)
|
||||||
@login_required
|
|
||||||
@user_has_permissions('view_activity', admin_override=True)
|
|
||||||
def view_letter_template_as_png(service_id, template_id):
|
|
||||||
return send_file(**png_from_pdf(
|
|
||||||
view_letter_template_as_pdf(service_id, template_id)
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
def _view_template_version(service_id, template_id, version, letters_as_pdf=False):
|
def _view_template_version(service_id, template_id, version, letters_as_pdf=False):
|
||||||
@@ -141,7 +127,7 @@ def view_template_version(service_id, template_id, version):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@main.route("/services/<service_id>/templates/<template_id>/version/<int:version>.pdf")
|
@main.route("/services/<service_id>/templates/<template_id>/version/<int:version>.<filetype>")
|
||||||
@login_required
|
@login_required
|
||||||
@user_has_permissions(
|
@user_has_permissions(
|
||||||
'view_activity',
|
'view_activity',
|
||||||
@@ -152,31 +138,9 @@ def view_template_version(service_id, template_id, version):
|
|||||||
admin_override=True,
|
admin_override=True,
|
||||||
any_=True
|
any_=True
|
||||||
)
|
)
|
||||||
def view_template_version_as_pdf(service_id, template_id, version):
|
def view_template_version_preview(service_id, template_id, version, filetype):
|
||||||
return render_pdf(HTML(string=str(
|
db_template = service_api_client.get_service_template(service_id, template_id, version=version)['data']
|
||||||
LetterPreviewTemplate(
|
return TemplatePreview.from_database_object(db_template, filetype)
|
||||||
service_api_client.get_service_template(service_id, template_id, version=version)['data'],
|
|
||||||
contact_block=current_service['letter_contact_block'],
|
|
||||||
admin_base_url=current_app.config['ADMIN_BASE_URL']
|
|
||||||
)
|
|
||||||
)))
|
|
||||||
|
|
||||||
|
|
||||||
@main.route("/services/<service_id>/templates/<template_id>/version/<int:version>.png")
|
|
||||||
@login_required
|
|
||||||
@user_has_permissions(
|
|
||||||
'view_activity',
|
|
||||||
'send_texts',
|
|
||||||
'send_emails',
|
|
||||||
'manage_templates',
|
|
||||||
'manage_api_keys',
|
|
||||||
admin_override=True,
|
|
||||||
any_=True
|
|
||||||
)
|
|
||||||
def view_template_version_as_png(service_id, template_id, version):
|
|
||||||
return send_file(**png_from_pdf(
|
|
||||||
view_template_version_as_pdf(service_id, template_id, version)
|
|
||||||
))
|
|
||||||
|
|
||||||
|
|
||||||
@main.route("/services/<service_id>/templates/add", methods=['GET', 'POST'])
|
@main.route("/services/<service_id>/templates/add", methods=['GET', 'POST'])
|
||||||
|
|||||||
28
app/template_previews.py
Normal file
28
app/template_previews.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
from flask import current_app
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from app import current_service
|
||||||
|
|
||||||
|
|
||||||
|
class TemplatePreview:
|
||||||
|
@classmethod
|
||||||
|
def from_database_object(cls, template, filetype, values=None):
|
||||||
|
data = {
|
||||||
|
'letter_contact_block': current_service['letter_contact_block'],
|
||||||
|
'template': template,
|
||||||
|
'values': values
|
||||||
|
}
|
||||||
|
resp = requests.post(
|
||||||
|
'{}/preview.{}'.format(current_app.config['TEMPLATE_PREVIEW_API_HOST'], filetype),
|
||||||
|
json=data,
|
||||||
|
headers={'Authorization': 'Token {}'.format(current_app.config['TEMPLATE_PREVIEW_API_KEY'])}
|
||||||
|
)
|
||||||
|
return (resp.content, resp.status_code, resp.headers.items())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_utils_template(cls, template, filetype):
|
||||||
|
return cls.from_database_object(
|
||||||
|
template._template,
|
||||||
|
filetype,
|
||||||
|
template.values
|
||||||
|
)
|
||||||
17
app/utils.py
17
app/utils.py
@@ -16,8 +16,6 @@ from flask import (
|
|||||||
)
|
)
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
from wand.image import Image
|
|
||||||
|
|
||||||
from notifications_utils.template import (
|
from notifications_utils.template import (
|
||||||
SMSPreviewTemplate,
|
SMSPreviewTemplate,
|
||||||
EmailPreviewTemplate,
|
EmailPreviewTemplate,
|
||||||
@@ -327,21 +325,6 @@ def get_template(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def png_from_pdf(pdf_endpoint):
|
|
||||||
output = BytesIO()
|
|
||||||
with Image(
|
|
||||||
blob=pdf_endpoint.get_data(),
|
|
||||||
resolution=150,
|
|
||||||
) as image:
|
|
||||||
with image.convert('png') as converted:
|
|
||||||
converted.save(file=output)
|
|
||||||
output.seek(0)
|
|
||||||
return dict(
|
|
||||||
filename_or_fp=output,
|
|
||||||
mimetype='image/png',
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_current_financial_year():
|
def get_current_financial_year():
|
||||||
now = datetime.utcnow()
|
now = datetime.utcnow()
|
||||||
current_month = int(now.strftime('%-m'))
|
current_month = int(now.strftime('%-m'))
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ Flask==0.10.1
|
|||||||
Flask-Script==2.0.5
|
Flask-Script==2.0.5
|
||||||
Flask-WTF==0.11
|
Flask-WTF==0.11
|
||||||
Flask-Login==0.3.2
|
Flask-Login==0.3.2
|
||||||
Flask-WeasyPrint==0.5
|
|
||||||
|
|
||||||
html5lib==1.0b10
|
|
||||||
credstash==1.8.0
|
credstash==1.8.0
|
||||||
boto3==1.4.4
|
boto3==1.4.4
|
||||||
Pygments==2.0.2
|
Pygments==2.0.2
|
||||||
@@ -20,7 +18,6 @@ pyexcel-xlsx==0.1.0
|
|||||||
pyexcel-ods3==0.1.1
|
pyexcel-ods3==0.1.1
|
||||||
pytz==2016.4
|
pytz==2016.4
|
||||||
six==1.10.0
|
six==1.10.0
|
||||||
wand==0.4.4
|
|
||||||
gunicorn==19.6.0
|
gunicorn==19.6.0
|
||||||
whitenoise==1.0.6 #manages static assets
|
whitenoise==1.0.6 #manages static assets
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,13 @@ import uuid
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from os import path
|
from os import path
|
||||||
from glob import glob
|
from glob import glob
|
||||||
import re
|
|
||||||
from itertools import repeat
|
from itertools import repeat
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from unittest.mock import patch
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from flask import url_for
|
from flask import url_for
|
||||||
|
from notifications_utils.template import LetterPreviewTemplate
|
||||||
|
|
||||||
from app.main.views.send import get_check_messages_back_url
|
from app.main.views.send import get_check_messages_back_url
|
||||||
|
|
||||||
@@ -524,18 +523,9 @@ def test_can_start_letters_job(
|
|||||||
assert response.status_code == 302
|
assert response.status_code == 302
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize('filetype', ['pdf', 'png'])
|
||||||
'view, expected_content_type',
|
|
||||||
[
|
|
||||||
('.check_messages_as_pdf', 'application/pdf'),
|
|
||||||
('.check_messages_as_png', 'image/png'),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
@patch('app.utils.LetterPreviewTemplate.jinja_template.render', return_value='')
|
|
||||||
def test_should_show_preview_letter_message(
|
def test_should_show_preview_letter_message(
|
||||||
mock_letter_preview,
|
filetype,
|
||||||
view,
|
|
||||||
expected_content_type,
|
|
||||||
logged_in_platform_admin_client,
|
logged_in_platform_admin_client,
|
||||||
mock_get_service_letter_template,
|
mock_get_service_letter_template,
|
||||||
mock_get_users_by_service,
|
mock_get_users_by_service,
|
||||||
@@ -554,6 +544,10 @@ def test_should_show_preview_letter_message(
|
|||||||
['123 street, abc123']
|
['123 street, abc123']
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
mocked_preview = mocker.patch(
|
||||||
|
'app.main.views.send.TemplatePreview.from_utils_template',
|
||||||
|
return_value='foo'
|
||||||
|
)
|
||||||
|
|
||||||
service_id = service_one['id']
|
service_id = service_one['id']
|
||||||
template_id = fake_uuid
|
template_id = fake_uuid
|
||||||
@@ -565,18 +559,41 @@ def test_should_show_preview_letter_message(
|
|||||||
'valid': True
|
'valid': True
|
||||||
}
|
}
|
||||||
response = logged_in_platform_admin_client.get(
|
response = logged_in_platform_admin_client.get(
|
||||||
url_for(view, service_id=service_id, template_type='letter', upload_id=fake_uuid)
|
url_for(
|
||||||
|
'main.check_messages_preview',
|
||||||
|
service_id=service_id,
|
||||||
|
template_type='letter',
|
||||||
|
upload_id=fake_uuid,
|
||||||
|
filetype=filetype
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
assert response.status_code == 200
|
|
||||||
assert response.content_type == expected_content_type
|
|
||||||
mock_get_service_letter_template.assert_called_with(service_id, template_id)
|
mock_get_service_letter_template.assert_called_with(service_id, template_id)
|
||||||
assert mock_letter_preview.call_args[0][0]['subject'] == (
|
|
||||||
'Subject'
|
assert response.status_code == 200
|
||||||
)
|
assert response.get_data(as_text=True) == 'foo'
|
||||||
assert mock_letter_preview.call_args[0][0]['message'] == (
|
assert mocked_preview.call_args[0][0].id == template_id
|
||||||
'<p>Template <em>content</em> with & entity</p>'
|
assert type(mocked_preview.call_args[0][0]) == LetterPreviewTemplate
|
||||||
|
assert mocked_preview.call_args[0][1] == filetype
|
||||||
|
|
||||||
|
|
||||||
|
def test_dont_show_preview_letter_templates_for_bad_filetype(
|
||||||
|
logged_in_client,
|
||||||
|
mock_get_service_template,
|
||||||
|
service_one,
|
||||||
|
fake_uuid
|
||||||
|
):
|
||||||
|
resp = logged_in_client.get(
|
||||||
|
url_for(
|
||||||
|
'main.check_messages_preview',
|
||||||
|
service_id=service_one['id'],
|
||||||
|
template_type='letter',
|
||||||
|
upload_id=fake_uuid,
|
||||||
|
filetype='blah'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
assert resp.status_code == 404
|
||||||
|
assert mock_get_service_template.called is False
|
||||||
|
|
||||||
|
|
||||||
def test_check_messages_should_revalidate_file_when_uploading_file(
|
def test_check_messages_should_revalidate_file_when_uploading_file(
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
from itertools import repeat
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from unittest.mock import Mock, patch, ANY
|
from unittest.mock import Mock, ANY
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
@@ -148,44 +147,60 @@ def test_should_show_page_template_with_priority_select_if_platform_admin(
|
|||||||
mock_get_service_template.assert_called_with('1234', template_id)
|
mock_get_service_template.assert_called_with('1234', template_id)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('view_suffix, expected_content_type', [
|
@pytest.mark.parametrize('filetype', ['pdf', 'png'])
|
||||||
('as_pdf', 'application/pdf'),
|
|
||||||
('as_png', 'image/png'),
|
|
||||||
])
|
|
||||||
@pytest.mark.parametrize('view, extra_view_args', [
|
@pytest.mark.parametrize('view, extra_view_args', [
|
||||||
('.view_letter_template', {}),
|
('.view_letter_template_preview', {}),
|
||||||
('.view_template_version', {'version': 1}),
|
('.view_template_version_preview', {'version': 1}),
|
||||||
])
|
])
|
||||||
@patch('app.main.views.templates.LetterPreviewTemplate.jinja_template.render', return_value='foo')
|
|
||||||
def test_should_show_preview_letter_templates(
|
def test_should_show_preview_letter_templates(
|
||||||
mock_letter_preview,
|
|
||||||
view,
|
view,
|
||||||
extra_view_args,
|
extra_view_args,
|
||||||
view_suffix,
|
filetype,
|
||||||
expected_content_type,
|
|
||||||
logged_in_client,
|
logged_in_client,
|
||||||
mock_get_service_email_template,
|
mock_get_service_email_template,
|
||||||
mock_get_user_by_email,
|
|
||||||
service_one,
|
service_one,
|
||||||
fake_uuid
|
fake_uuid,
|
||||||
|
mocker
|
||||||
):
|
):
|
||||||
|
mocked_preview = mocker.patch(
|
||||||
|
'app.main.views.templates.TemplatePreview.from_database_object',
|
||||||
|
return_value='foo'
|
||||||
|
)
|
||||||
|
|
||||||
service_id, template_id = service_one['id'], fake_uuid
|
service_id, template_id = service_one['id'], fake_uuid
|
||||||
|
|
||||||
response = logged_in_client.get(url_for(
|
response = logged_in_client.get(url_for(
|
||||||
'{}_{}'.format(view, view_suffix),
|
view,
|
||||||
service_id=service_id,
|
service_id=service_id,
|
||||||
template_id=template_id,
|
template_id=template_id,
|
||||||
|
filetype=filetype,
|
||||||
**extra_view_args
|
**extra_view_args
|
||||||
))
|
))
|
||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.content_type == expected_content_type
|
assert response.get_data(as_text=True) == 'foo'
|
||||||
mock_get_service_email_template.assert_called_with(service_id, template_id, **extra_view_args)
|
mock_get_service_email_template.assert_called_with(service_id, template_id, **extra_view_args)
|
||||||
assert mock_letter_preview.call_args[0][0]['subject'] == (
|
assert mocked_preview.call_args[0][0]['id'] == template_id
|
||||||
"Your <span class='placeholder'>((thing))</span> is due soon"
|
assert mocked_preview.call_args[0][0]['service'] == service_id
|
||||||
)
|
assert mocked_preview.call_args[0][1] == filetype
|
||||||
assert mock_letter_preview.call_args[0][0]['message'] == (
|
|
||||||
"<p>Your vehicle tax expires on <span class='placeholder'>((date))</span></p>"
|
|
||||||
|
def test_dont_show_preview_letter_templates_for_bad_filetype(
|
||||||
|
logged_in_client,
|
||||||
|
mock_get_service_template,
|
||||||
|
service_one,
|
||||||
|
fake_uuid
|
||||||
|
):
|
||||||
|
resp = logged_in_client.get(
|
||||||
|
url_for(
|
||||||
|
'.view_letter_template_preview',
|
||||||
|
service_id=service_one['id'],
|
||||||
|
template_id=fake_uuid,
|
||||||
|
filetype='blah'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
assert resp.status_code == 404
|
||||||
|
assert mock_get_service_template.called is False
|
||||||
|
|
||||||
|
|
||||||
def test_should_redirect_when_saving_a_template(
|
def test_should_redirect_when_saving_a_template(
|
||||||
|
|||||||
@@ -52,12 +52,24 @@ def deskpro_config():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def template_preview_config():
|
||||||
|
return {
|
||||||
|
'name': 'notify-template-preview',
|
||||||
|
'credentials': {
|
||||||
|
'api_host': 'template-preview api host',
|
||||||
|
'api_key': 'template-preview api key'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def cloudfoundry_config(
|
def cloudfoundry_config(
|
||||||
notify_config,
|
notify_config,
|
||||||
aws_config,
|
aws_config,
|
||||||
hosted_graphite_config,
|
hosted_graphite_config,
|
||||||
deskpro_config,
|
deskpro_config,
|
||||||
|
template_preview_config,
|
||||||
):
|
):
|
||||||
return {
|
return {
|
||||||
'user-provided': [
|
'user-provided': [
|
||||||
@@ -65,6 +77,7 @@ def cloudfoundry_config(
|
|||||||
aws_config,
|
aws_config,
|
||||||
hosted_graphite_config,
|
hosted_graphite_config,
|
||||||
deskpro_config,
|
deskpro_config,
|
||||||
|
template_preview_config,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,3 +141,11 @@ def test_deskpro_config():
|
|||||||
|
|
||||||
assert os.environ['DESKPRO_API_HOST'] == 'deskpro api host'
|
assert os.environ['DESKPRO_API_HOST'] == 'deskpro api host'
|
||||||
assert os.environ['DESKPRO_API_KEY'] == 'deskpro api key'
|
assert os.environ['DESKPRO_API_KEY'] == 'deskpro api key'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures('os_environ', 'cloudfoundry_environ')
|
||||||
|
def test_template_preview_config():
|
||||||
|
extract_cloudfoundry_config()
|
||||||
|
|
||||||
|
assert os.environ['TEMPLATE_PREVIEW_API_HOST'] == 'template-preview api host'
|
||||||
|
assert os.environ['TEMPLATE_PREVIEW_API_KEY'] == 'template-preview api key'
|
||||||
|
|||||||
35
tests/app/test_template_previews.py
Normal file
35
tests/app/test_template_previews.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
from unittest.mock import Mock
|
||||||
|
from notifications_utils.template import LetterPreviewTemplate
|
||||||
|
|
||||||
|
from app.template_previews import TemplatePreview
|
||||||
|
|
||||||
|
|
||||||
|
def test_from_utils_template_calls_through(mocker, mock_get_service_letter_template):
|
||||||
|
mock_from_db = mocker.patch('app.template_previews.TemplatePreview.from_database_object')
|
||||||
|
template = LetterPreviewTemplate(mock_get_service_letter_template(None, None)['data'])
|
||||||
|
|
||||||
|
ret = TemplatePreview.from_utils_template(template, 'foo')
|
||||||
|
|
||||||
|
assert ret == mock_from_db.return_value
|
||||||
|
mock_from_db.assert_called_once_with(template._template, 'foo', template.values)
|
||||||
|
|
||||||
|
|
||||||
|
def test_from_database_object_makes_request(mocker, client):
|
||||||
|
resp = Mock(content='a', status_code='b', headers={'c': 'd'})
|
||||||
|
request_mock = mocker.patch('app.template_previews.requests.post', return_value=resp)
|
||||||
|
mocker.patch('app.template_previews.current_service', __getitem__=Mock(return_value='123'))
|
||||||
|
|
||||||
|
ret = TemplatePreview.from_database_object(template='foo', filetype='bar')
|
||||||
|
|
||||||
|
assert ret[0] == 'a'
|
||||||
|
assert ret[1] == 'b'
|
||||||
|
assert list(ret[2]) == [('c', 'd')]
|
||||||
|
url = 'http://localhost:6013/preview.bar'
|
||||||
|
data = {
|
||||||
|
'letter_contact_block': '123',
|
||||||
|
'template': 'foo',
|
||||||
|
'values': None
|
||||||
|
}
|
||||||
|
headers = {'Authorization': 'Token my-secret-key'}
|
||||||
|
|
||||||
|
request_mock.assert_called_once_with(url, json=data, headers=headers)
|
||||||
Reference in New Issue
Block a user