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 + )