Merge pull request #658 from alphagov/last-used-message

Last used message
This commit is contained in:
Leo Hemsted
2016-06-07 16:13:30 +01:00
5 changed files with 126 additions and 10 deletions

View File

@@ -1,9 +1,11 @@
from datetime import datetime, timedelta
from string import ascii_uppercase
from flask import request, render_template, redirect, url_for, flash, abort, session
from flask import request, render_template, redirect, url_for, flash, abort
from flask_login import login_required
from dateutil.parser import parse
from notifications_utils.template import Template, TemplateChange
from notifications_utils.template import Template
from notifications_utils.recipients import first_column_heading
from notifications_python_client.errors import HTTPError
@@ -11,7 +13,7 @@ from app.main import main
from app.utils import user_has_permissions
from app.main.forms import SMSTemplateForm, EmailTemplateForm
from app.main.views.send import get_example_csv_rows
from app import service_api_client, current_service
from app import service_api_client, current_service, template_statistics_client
form_objects = {
@@ -183,7 +185,10 @@ def delete_service_template(service_id, template_id):
template['template_content'] = template['content']
form = form_objects[template['template_type']](**template)
flash('Are you sure you want to delete {}?'.format(form.name.data), 'delete')
template_statistics = template_statistics_client.get_template_statistics_for_service(service_id, template['id'])
last_use_message = get_last_use_message(form.name.data, template_statistics)
flash('{}. Are you sure you want to delete it?'.format(last_use_message), 'delete')
return render_template(
'views/edit-{}-template.html'.format(template['template_type']),
h1='Edit template',
@@ -216,3 +221,33 @@ def view_template_versions(service_id, template_id):
) for template in service_api_client.get_service_template_versions(service_id, template_id)['data']
]
)
def get_last_use_message(template_name, template_statistics):
try:
most_recent_use = max(
parse(template_stats['updated_at']).replace(tzinfo=None)
for template_stats in template_statistics
)
except ValueError:
return '{} has never been used'.format(template_name)
return '{} was last used {} ago'.format(
template_name,
get_human_readable_delta(most_recent_use, datetime.utcnow())
)
def get_human_readable_delta(from_time, until_time):
delta = until_time - from_time
if delta < timedelta(seconds=60):
return 'under a minute'
elif delta < timedelta(hours=1):
minutes = int(delta.seconds / 60)
return '{} minute{}'.format(minutes, '' if minutes == 1 else 's')
elif delta < timedelta(days=1):
hours = int(delta.seconds / 3600)
return '{} hour{}'.format(hours, '' if hours == 1 else 's')
else:
days = delta.days
return '{} day{}'.format(days, '' if days == 1 else 's')

View File

@@ -20,3 +20,8 @@ class TemplateStatisticsApiClient(BaseAPIClient):
url='/service/{}/template-statistics'.format(service_id),
params=params
)['data']
def get_template_statistics_for_template(self, service_id, template_id):
return self.get(
url='/service/{}/template-statistics/{}'.format(service_id, template_id)
)['data']

View File

@@ -3,7 +3,7 @@ import uuid
from app.notify_client.template_statistics_api_client import TemplateStatisticsApiClient
def test_template_statistics_client_calls_correct_api_endpoint(mocker, api_user_active):
def test_template_statistics_client_calls_correct_api_endpoint_for_service(mocker, api_user_active):
some_service_id = uuid.uuid4()
expected_url = '/service/{}/template-statistics'.format(some_service_id)
@@ -15,3 +15,16 @@ def test_template_statistics_client_calls_correct_api_endpoint(mocker, api_user_
client.get_template_statistics_for_service(some_service_id)
mock_get.assert_called_once_with(url=expected_url, params={})
def test_template_statistics_client_calls_correct_api_endpoint_for_template(mocker, api_user_active):
some_service_id = uuid.uuid4()
some_template_id = uuid.uuid4()
expected_url = '/service/{}/template-statistics/{}'.format(some_service_id, some_template_id)
client = TemplateStatisticsApiClient()
mock_get = mocker.patch('app.notify_client.template_statistics_api_client.TemplateStatisticsApiClient.get')
client.get_template_statistics_for_template(some_service_id, some_template_id)
mock_get.assert_called_once_with(url=expected_url)

View File

@@ -1,9 +1,12 @@
import json
import uuid
from bs4 import BeautifulSoup
from tests import validate_route_permission
from datetime import datetime
import pytest
from bs4 import BeautifulSoup
from flask import url_for
from freezegun import freeze_time
from tests import validate_route_permission
from app.main.views.templates import get_last_use_message, get_human_readable_delta
def test_should_show_page_for_one_templates(app_,
@@ -226,6 +229,8 @@ def test_should_show_delete_template_page(app_,
mock_get_user,
mock_get_user_by_email,
mock_has_permissions,
mock_get_template_statistics,
mock_get_template_statistics_for_template,
fake_uuid):
with app_.test_request_context():
with app_.test_client() as client:
@@ -292,6 +297,8 @@ def test_route_permissions(mocker,
api_user_active,
service_one,
mock_get_service_template,
mock_get_template_statistics,
mock_get_template_statistics_for_template,
fake_uuid):
routes = [
'main.add_service_template',
@@ -360,3 +367,35 @@ def test_route_invalid_permissions(mocker,
['view_activity'],
api_user_active,
service_one)
def test_get_last_use_message_returns_no_template_message():
assert get_last_use_message('My Template', []) == 'My Template has never been used'
@freeze_time('2000-01-01T15:00')
def test_get_last_use_message_uses_most_recent_statistics():
template_statistics = [
{
'updated_at': '2000-01-01T12:00:00.000000+00:00'
},
{
'updated_at': '2000-01-01T09:00:00.000000+00:00'
},
]
assert get_last_use_message('My Template', template_statistics) == 'My Template was last used 3 hours ago'
@pytest.mark.parametrize('from_time, until_time, message', [
(datetime(2000, 1, 1, 12, 0), datetime(2000, 1, 1, 12, 0, 59), 'under a minute'),
(datetime(2000, 1, 1, 12, 0), datetime(2000, 1, 1, 12, 1), '1 minute'),
(datetime(2000, 1, 1, 12, 0), datetime(2000, 1, 1, 12, 2, 35), '2 minutes'),
(datetime(2000, 1, 1, 12, 0), datetime(2000, 1, 1, 12, 59), '59 minutes'),
(datetime(2000, 1, 1, 12, 0), datetime(2000, 1, 1, 13, 0), '1 hour'),
(datetime(2000, 1, 1, 12, 0), datetime(2000, 1, 1, 14, 0), '2 hours'),
(datetime(2000, 1, 1, 12, 0), datetime(2000, 1, 2, 11, 59), '23 hours'),
(datetime(2000, 1, 1, 12, 0), datetime(2000, 1, 2, 12, 0), '1 day'),
(datetime(2000, 1, 1, 12, 0), datetime(2000, 1, 3, 14, 0), '2 days'),
])
def test_get_human_readable_delta(from_time, until_time, message):
assert get_human_readable_delta(from_time, until_time) == message

View File

@@ -995,7 +995,8 @@ def mock_get_template_statistics(mocker, service_one, fake_uuid):
},
"service": template['service'],
"id": str(generate_uuid()),
"day": "2016-04-04"
"day": "2016-04-04",
"updated_at": "2016-04-04T12:00:00.000000+00:00"
}
def _get_stats(service_id, limit_days=None):
@@ -1005,6 +1006,29 @@ def mock_get_template_statistics(mocker, service_one, fake_uuid):
'app.template_statistics_client.get_template_statistics_for_service', side_effect=_get_stats)
@pytest.fixture(scope='function')
def mock_get_template_statistics_for_template(mocker, service_one):
def _get_stats(service_id, template_id):
template = template_json(service_id, template_id, "Test template", "sms", "Something very interesting")
return [
{
"usage_count": 1,
"template": {
"name": template['name'],
"template_type": template['template_type'],
"id": template['id']
},
"service": template['service'],
"id": str(generate_uuid()),
"day": "2016-04-04",
"updated_at": "2016-04-04T12:00:00.000000+00:00"
}
]
return mocker.patch(
'app.template_statistics_client.get_template_statistics_for_service', side_effect=_get_stats)
@pytest.fixture(scope='function')
def mock_get_usage(mocker, service_one, fake_uuid):
def _get_usage(service_id):