From 3a32c35dd2904341310d8425478701f4cf0d0c4e Mon Sep 17 00:00:00 2001 From: Rebecca Law Date: Wed, 5 Feb 2020 13:03:54 +0000 Subject: [PATCH] Added a new endpoint to return the last used date for a template. The existing endpoint returned a whole notification for the last time the template was used. But this only takes into account data in the last week. This new methods allows us to be specific about when the template was last used if ever but looking into the ft_notification_status table as well. --- app/dao/notifications_dao.py | 32 +++++++++++ app/template_statistics/rest.py | 15 ++++- .../test_notification_dao_template_usage.py | 57 ++++++++++++++++++- tests/app/template_statistics/test_rest.py | 43 +++++++++++++- 4 files changed, 143 insertions(+), 4 deletions(-) diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index 3f46577b3..5251546e2 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -30,6 +30,7 @@ from app.dao.dao_utils import transactional from app.errors import InvalidRequest from app.letters.utils import get_letter_pdf_filename from app.models import ( + FactNotificationStatus, Notification, NotificationHistory, ProviderDetails, @@ -70,6 +71,37 @@ def dao_get_last_template_usage(template_id, template_type, service_id): ).first() +@statsd(namespace="dao") +def dao_get_last_date_template_was_used(template_id, template_type, service_id): + last_date = db.session.query( + functions.max(FactNotificationStatus.bst_date) + ).filter( + FactNotificationStatus.template_id == template_id, + FactNotificationStatus.key_type != KEY_TYPE_TEST + ).scalar() + + last_date_from_notifications = db.session.query( + functions.max(Notification.created_at) + ).filter( + Notification.service_id == service_id, + Notification.notification_type == template_type, + Notification.template_id == template_id, + Notification.key_type != KEY_TYPE_TEST + ).scalar() + + if last_date and last_date_from_notifications: + if datetime.combine(last_date, datetime.utcnow().min.time()) >= last_date_from_notifications: + return last_date + else: + return last_date_from_notifications + elif not last_date: + return last_date_from_notifications + elif not last_date_from_notifications: + return last_date + else: + return None + + @statsd(namespace="dao") @transactional def dao_create_notification(notification): diff --git a/app/template_statistics/rest.py b/app/template_statistics/rest.py index fc179b49a..5a420b4e9 100644 --- a/app/template_statistics/rest.py +++ b/app/template_statistics/rest.py @@ -1,5 +1,7 @@ from flask import Blueprint, jsonify, request -from app.dao.notifications_dao import dao_get_last_template_usage + +from app import DATETIME_FORMAT +from app.dao.notifications_dao import dao_get_last_template_usage, dao_get_last_date_template_was_used from app.dao.templates_dao import dao_get_template_by_id_and_service_id from app.dao.fact_notification_status_dao import fetch_notification_status_for_service_for_today_and_7_previous_days @@ -52,3 +54,14 @@ def get_template_statistics_for_template_id(service_id, template_id): data = notification_with_template_schema.dump(notification).data return jsonify(data=data) + + +@template_statistics.route('/last-used/') +def get_last_used_datetime_for_template(service_id, template_id): + template = dao_get_template_by_id_and_service_id(template_id, service_id) + + last_date_used = dao_get_last_date_template_was_used(template_id=template_id, + template_type=template.template_type, + service_id=service_id) + + return jsonify(last_date_used=last_date_used.strftime(DATETIME_FORMAT)) diff --git a/tests/app/dao/notification_dao/test_notification_dao_template_usage.py b/tests/app/dao/notification_dao/test_notification_dao_template_usage.py index 4006fd9c2..2e6ef2b85 100644 --- a/tests/app/dao/notification_dao/test_notification_dao_template_usage.py +++ b/tests/app/dao/notification_dao/test_notification_dao_template_usage.py @@ -1,7 +1,7 @@ from datetime import datetime, timedelta import pytest -from app.dao.notifications_dao import dao_get_last_template_usage -from tests.app.db import create_notification, create_template +from app.dao.notifications_dao import dao_get_last_template_usage, dao_get_last_date_template_was_used +from tests.app.db import create_notification, create_template, create_ft_notification_status def test_last_template_usage_should_get_right_data(sample_notification): @@ -54,3 +54,56 @@ def test_last_template_usage_should_be_able_to_get_no_template_usage_history_if_ sample_template): results = dao_get_last_template_usage(sample_template.id, 'sms', sample_template.service_id) assert not results + + +@pytest.mark.parametrize('last_status_date, last_notification_date', + [((datetime.utcnow() - timedelta(days=2)).date(), None), + ((datetime.utcnow() - timedelta(days=2)).date(), datetime.utcnow() - timedelta(days=3))] + ) +def test_dao_get_last_date_template_was_used_returns_bst_date_from_stats_table( + sample_template, last_status_date, last_notification_date +): + create_ft_notification_status(bst_date=last_status_date, + template=sample_template) + if last_notification_date: + create_notification(template=sample_template, created_at=last_notification_date) + last_used_date = dao_get_last_date_template_was_used(template_id=sample_template.id, + template_type='sms', + service_id=sample_template.service_id) + assert last_used_date == last_status_date + + +@pytest.mark.parametrize('last_notification_date, last_status_date', + [(datetime.utcnow() - timedelta(hours=2), None), + (datetime.utcnow() - timedelta(hours=2), (datetime.utcnow() - timedelta(days=2)).date())] + ) +def test_dao_get_last_date_template_was_used_returns_created_at_from_notifications( + sample_template, last_status_date, last_notification_date +): + create_notification(template=sample_template, created_at=last_notification_date) + + if last_status_date: + create_ft_notification_status(bst_date=last_status_date, template=sample_template) + last_used_date = dao_get_last_date_template_was_used(template_id=sample_template.id, + template_type='sms', + service_id=sample_template.service_id) + assert last_used_date == last_notification_date + + +def test_dao_get_last_date_template_was_used_returns_none_if_never_used(sample_template): + assert not dao_get_last_date_template_was_used(template_id=sample_template.id, + template_type='sms', + service_id=sample_template.service_id) + + +def test_dao_get_last_date_template_was_used_correct_date(sample_template): + date_from_notification = datetime.utcnow() - timedelta(hours=2) + create_notification(template=sample_template, created_at=date_from_notification) + date_from_ft_status = (datetime.utcnow() - timedelta(days=2)).date() + create_ft_notification_status(bst_date=date_from_ft_status, + template=sample_template) + + actual_result = dao_get_last_date_template_was_used(template_id=sample_template.id, + template_type='sms', + service_id=sample_template.service_id) + assert actual_result == date_from_notification diff --git a/tests/app/template_statistics/test_rest.py b/tests/app/template_statistics/test_rest.py index 45659a712..b0deb5bf8 100644 --- a/tests/app/template_statistics/test_rest.py +++ b/tests/app/template_statistics/test_rest.py @@ -1,10 +1,12 @@ import uuid +from datetime import datetime, timedelta from unittest.mock import Mock import pytest from freezegun import freeze_time -from tests.app.db import create_notification +from app import DATETIME_FORMAT +from tests.app.db import create_ft_notification_status, create_notification def set_up_get_all_from_hash(mock_redis, side_effect): @@ -189,3 +191,42 @@ def test_get_template_statistics_for_template_returns_empty_for_old_notification ) assert not json_resp['data'] + + +def test_get_last_used_datetime_for_template( + admin_request, sample_template +): + date_from_notification = datetime.utcnow() - timedelta(hours=2) + create_notification(template=sample_template, created_at=date_from_notification) + date_from_ft_status = (datetime.utcnow() - timedelta(days=2)).date() + create_ft_notification_status(bst_date=date_from_ft_status, + template=sample_template) + + json_resp = admin_request.get( + 'template_statistics.get_last_used_datetime_for_template', + service_id=str(sample_template.service_id), + template_id=sample_template.id + ) + assert json_resp['last_date_used'] == date_from_notification.strftime(DATETIME_FORMAT) + + +def test_get_last_used_datetime_for_template_returns_400_if_service_does_not_exist( + admin_request, sample_template +): + admin_request.get( + 'template_statistics.get_last_used_datetime_for_template', + service_id=uuid.uuid4(), + template_id=sample_template.id, + _expected_status=404 + ) + + +def test_get_last_used_datetime_for_template_returns_400_if_template_does_not_exist( + admin_request, sample_template +): + admin_request.get( + 'template_statistics.get_last_used_datetime_for_template', + service_id=sample_template.service_id, + template_id=uuid.uuid4(), + _expected_status=404 + )