add new template folder

The add new templates page now has option to add template folders.
Tweaked wording of other options and h1 to clarify options since it's
not all about templates any more.

Added api client and stuff for it
This commit is contained in:
Leo Hemsted
2018-11-01 15:33:09 +00:00
committed by Alexey Bezhan
parent 37295f4b6e
commit 7cbf5de240
11 changed files with 134 additions and 10 deletions

View File

@@ -67,6 +67,7 @@ from app.notify_client.inbound_number_client import inbound_number_client
from app.notify_client.billing_api_client import billing_api_client
from app.notify_client.complaint_api_client import complaint_api_client
from app.notify_client.platform_stats_api_client import platform_stats_api_client
from app.notify_client.template_folder_api_client import template_folder_api_client
from app.commands import setup_commands
from app.utils import get_cdn_domain, gmt_timezones, id_safe
@@ -128,6 +129,7 @@ def create_app(application):
billing_api_client.init_app(application)
complaint_api_client.init_app(application)
platform_stats_api_client.init_app(application)
template_folder_api_client.init_app(application)
login_manager.init_app(application)
login_manager.login_view = 'main.sign_in'

View File

@@ -850,21 +850,22 @@ class DateFilterForm(StripWhitespaceForm):
class ChooseTemplateType(StripWhitespaceForm):
template_type = RadioField(
'What kind of template do you want to add?',
'',
validators=[
DataRequired()
]
)
def __init__(self, include_letters=False, include_copy=False, *args, **kwargs):
def __init__(self, include_letters=False, include_copy=False, include_folder=False, *args, **kwargs):
super().__init__(*args, **kwargs)
self.template_type.choices = filter(None, [
('email', 'Email'),
('sms', 'Text message'),
('letter', 'Letter') if include_letters else None,
('email', 'Email template'),
('sms', 'Text message template'),
('letter', 'Letter template') if include_letters else None,
('copy-existing', 'Copy of an existing template') if include_copy else None,
('folder', 'Folder') if include_folder else None,
])

View File

@@ -183,6 +183,7 @@ def add_template_by_type(service_id):
service_api_client.count_service_templates(service_id) > 0,
len(user_api_client.get_service_ids_for_user(current_user)) > 1,
)),
include_folder=current_service.has_permission('edit_folders')
)
if form.validate_on_submit():
@@ -288,6 +289,20 @@ def action_blocked(service_id, notification_type, return_to, template_id):
)
@main.route("/services/<service_id>/templates/add-folder", methods=['GET', 'POST'])
def add_folder(service_id):
if not current_service.has_permission('edit_folders'):
abort(403)
form = NewFolderForm()
if form.validate_on_submit():
folder_api_client.create_template_folder(form.name.data, current_service.id, parent_id=None)
return redirect(
url_for('.view_templates', service_id=service_id)
)
@main.route("/services/<service_id>/templates/add-<template_type>", methods=['GET', 'POST'])
@login_required
@user_has_permissions('manage_templates')

View File

@@ -8,6 +8,7 @@ from app.notify_client.job_api_client import job_api_client
from app.notify_client.organisations_api_client import organisations_client
from app.notify_client.service_api_client import service_api_client
from app.notify_client.user_api_client import user_api_client
from app.notify_client.template_folder_client import template_folder_client
from app.utils import get_default_sms_sender
@@ -252,3 +253,7 @@ class Service():
@property
def has_inbound_number(self):
return bool(self.inbound_number)
@cached_property
def template_folders(self):
return template_folder_client.get_template_folders(self.id)

View File

@@ -109,6 +109,7 @@ class HeaderNavigation(Navigation):
'add_service',
'add_service_template',
'add_template_by_type',
'add_folder',
'agreement',
'api_callbacks',
'api_documentation',
@@ -299,6 +300,7 @@ class MainNavigation(Navigation):
'action_blocked',
'add_service_template',
'add_template_by_type',
'add_folder',
'check_messages',
'check_notification',
'choose_template',
@@ -552,6 +554,7 @@ class CaseworkNavigation(Navigation):
'add_service',
'add_service_template',
'add_template_by_type',
'add_folder',
'agreement',
'api_callbacks',
'api_documentation',
@@ -787,6 +790,7 @@ class OrgNavigation(Navigation):
'add_service',
'add_service_template',
'add_template_by_type',
'add_folder',
'agreement',
'api_callbacks',
'api_documentation',

View File

@@ -1,4 +1,3 @@
from __future__ import unicode_literals
from app.notify_client import NotifyAdminAPIClient, _attach_current_user, cache

View File

@@ -0,0 +1,28 @@
from app.notify_client import NotifyAdminAPIClient, cache
class TemplateFolderAPIClient(NotifyAdminAPIClient):
# Fudge assert in the super __init__ so
# we can set those variables later.
def __init__(self):
super().__init__('a' * 73, 'b')
@cache.delete('service-{service_id}-template-folders')
def create_template_folder(
self,
service_id,
name,
parent_id=None
):
data = {
'name': name,
'parent_id': parent_id
}
return self.post('/service/{}/template-folder'.format(service_id), data)['data']['id']
@cache.set('service-{service_id}-template-folders')
def get_template_folders(self, service_id):
return self.get('/service/{}/template-folder'.format(service_id))['data']
template_folder_api_client = TemplateFolderAPIClient()

View File

@@ -5,12 +5,12 @@
{% extends "withnav_template.html" %}
{% block service_page_title %}
Add new template
Add new template or folder
{% endblock %}
{% block maincolumn_content %}
<h1 class="heading-large">Add new template</h1>
<h1 class="heading-large">What do you want to add?</h1>
{% call form_wrapper() %}
{{ radios(form.template_type) }}

View File

@@ -56,11 +56,11 @@ def test_letters_lets_in_without_permission(
@pytest.mark.parametrize('permissions, choices', [
(
['email', 'sms', 'letter'],
['Email', 'Text message', 'Letter', 'Copy of an existing template']
['Email template', 'Text message template', 'Letter template', 'Copy of an existing template']
),
(
['email', 'sms'],
['Email', 'Text message', 'Copy of an existing template']
['Email template', 'Text message template', 'Copy of an existing template']
),
])
def test_given_option_to_add_letters_if_allowed(

View File

@@ -0,0 +1,28 @@
def test_add_folder(
client_request,
service_one,
mocker,
mock_get_service_templates,
mock_get_organisations_and_services_for_user,
):
service_one['permissions'] += ['edit_folders']
mocker.patch('app.service_api_client.get_service', return_value={"data": service_one})
page = client_request.get(
'main.add_template_by_type',
service_id=service_one['id'],
_test_page_title=False
)
radios = page.select('input[type=radio]')
labels = page.select('label')
assert [x['value'] for x in radios] == ['email', 'sms', 'copy-existing', 'folder']
assert [x.text.strip() for x in labels] == [
'Email template',
'Text message template',
'Copy of an existing template',
'Folder'
]

View File

@@ -0,0 +1,42 @@
import pytest
import uuid
from app.notify_client.template_folder_api_client import TemplateFolderAPIClient
@pytest.mark.parametrize('parent_id', [uuid.uuid4(), None])
def test_create_template_folder_calls_correct_api_endpoint(mocker, api_user_active, parent_id):
mock_redis_delete = mocker.patch('app.notify_client.RedisClient.delete')
some_service_id = uuid.uuid4()
expected_url = '/service/{}/template-folder'.format(some_service_id)
data = {'name': 'foo', 'parent_id': parent_id}
client = TemplateFolderAPIClient()
mock_post = mocker.patch('app.notify_client.template_folder_api_client.TemplateFolderAPIClient.post')
client.create_template_folder(some_service_id, name='foo', parent_id=parent_id)
mock_post.assert_called_once_with(expected_url, data)
mock_redis_delete.assert_called_once_with('service-{}-template-folders'.format(some_service_id))
def test_get_template_folders_calls_correct_api_endpoint(mocker, api_user_active):
mock_redis_get = mocker.patch('app.notify_client.RedisClient.get', return_value=None)
mock_api_get = mocker.patch('app.notify_client.NotifyAdminAPIClient.get', return_value={'data': {'a': 'b'}})
mock_redis_set = mocker.patch('app.notify_client.RedisClient.set')
some_service_id = uuid.uuid4()
expected_url = '/service/{}/template-folder'.format(some_service_id)
redis_key = 'service-{}-template-folders'.format(some_service_id)
client = TemplateFolderAPIClient()
ret = client.get_template_folders(some_service_id)
assert ret == {'a': 'b'}
mock_redis_get.assert_called_once_with(redis_key)
mock_api_get.assert_called_once_with(expected_url)
mock_redis_set.assert_called_once_with(redis_key, '{"a": "b"}', ex=604800)