return all zeros when NotificationStatistics dont exist

This commit is contained in:
Leo Hemsted
2016-05-20 15:16:53 +01:00
parent 1b27c15c16
commit 81e5eb2c0a
4 changed files with 153 additions and 9 deletions

View File

@@ -1,4 +1,4 @@
from sqlalchemy import (desc, func, Integer, and_, asc)
from sqlalchemy import (desc, func, Integer, and_, or_, asc)
from sqlalchemy.sql.expression import cast
from datetime import (
@@ -12,6 +12,7 @@ from werkzeug.datastructures import MultiDict
from app import db
from app.models import (
Service,
Notification,
Job,
NotificationStatistics,
@@ -57,6 +58,51 @@ def dao_get_notification_statistics_for_day(day):
).all()
def dao_get_potential_notification_statistics_for_day(day):
all_services = db.session.query(
Service.id,
NotificationStatistics
).outerjoin(
Service.service_notification_stats
).filter(
or_(
NotificationStatistics.day == day,
NotificationStatistics.day == None # noqa
)
).order_by(
asc(Service.created_at)
)
notification_statistics = []
for service_notification_stats_pair in all_services:
if service_notification_stats_pair.NotificationStatistics:
notification_statistics.append(
service_notification_stats_pair.NotificationStatistics
)
else:
notification_statistics.append(
create_notification_statistics_dict(
service_notification_stats_pair,
day
)
)
return notification_statistics
def create_notification_statistics_dict(service_id, day):
return {
'id': None,
'emails_requested': 0,
'emails_delivered': 0,
'emails_failed': 0,
'sms_requested': 0,
'sms_delivered': 0,
'sms_failed': 0,
'day': day.isoformat(),
'service': service_id
}
def dao_get_7_day_agg_notification_statistics_for_service(service_id,
date_from,
week_count=52):

View File

@@ -28,7 +28,8 @@ from app.schemas import (
sms_template_notification_schema,
notification_status_schema,
notifications_filter_schema,
notifications_statistics_schema
notifications_statistics_schema,
day_schema,
)
from app.celery.tasks import send_sms, send_email
@@ -389,14 +390,12 @@ def send_notification(notification_type):
@notifications.route('/notifications/statistics')
def get_notification_statistics_for_day():
data, errors = notifications_statistics_schema.load(request.args)
data, errors = day_schema.load(request.args)
if errors:
return jsonify(result='error', message=errors), 400
if not data.day:
return jsonify(result='error', message='Please provide day as query parameter.'), 400
statistics = notifications_dao.dao_get_notification_statistics_for_day(
day=data.day
statistics = notifications_dao.dao_get_potential_notification_statistics_for_day(
day=data['day']
)
data, errors = notifications_statistics_schema.dump(statistics, many=True)

View File

@@ -168,7 +168,6 @@ class RequestVerifyCodeSchema(ma.Schema):
class NotificationSchema(ma.Schema):
personalisation = fields.Dict(required=False)
pass
class SmsNotificationSchema(NotificationSchema):
@@ -360,6 +359,14 @@ class FromToDateSchema(ma.Schema):
raise ValidationError("date_from needs to be greater than date_to")
class DaySchema(ma.Schema):
day = fields.Date(required=True)
@validates('day')
def validate_day(self, value):
_validate_not_in_future(value)
class WeekAggregateNotificationStatisticsSchema(ma.Schema):
date_from = fields.Date()
@@ -405,3 +412,4 @@ event_schema = EventSchema()
from_to_date_schema = FromToDateSchema()
provider_details_schema = ProviderDetailsSchema()
week_aggregate_notification_statistics_schema = WeekAggregateNotificationStatisticsSchema()
day_schema = DaySchema()

View File

@@ -4,7 +4,10 @@ from flask import json
from freezegun import freeze_time
from tests import create_authorization_header
from tests.app.conftest import sample_notification_statistics as create_sample_notification_statistics
from tests.app.conftest import (
sample_notification_statistics as create_sample_notification_statistics,
sample_service as create_sample_service
)
def test_get_notification_statistics(notify_api, sample_notification_statistics):
@@ -28,6 +31,7 @@ def test_get_notification_statistics(notify_api, sample_notification_statistics)
assert stats['emails_failed'] == 1
assert stats['sms_requested'] == 2
assert stats['sms_delivered'] == 1
assert stats['sms_failed'] == 1
assert stats['service'] == str(sample_notification_statistics.service_id)
assert response.status_code == 200
@@ -85,6 +89,7 @@ def test_get_notification_statistics_fails_if_no_date(notify_api, sample_notific
resp = json.loads(response.get_data(as_text=True))
assert resp['result'] == 'error'
assert resp['message'] == {'day': ['Missing data for required field.']}
assert response.status_code == 400
@@ -102,4 +107,90 @@ def test_get_notification_statistics_fails_if_invalid_date(notify_api, sample_no
resp = json.loads(response.get_data(as_text=True))
assert resp['result'] == 'error'
assert resp['message'] == {'day': ['Not a valid date.']}
assert response.status_code == 400
def test_get_notification_statistics_returns_zeros_if_not_in_db(notify_api, sample_service):
with notify_api.test_request_context():
with notify_api.test_client() as client:
auth_header = create_authorization_header(
service_id=sample_service.id
)
response = client.get(
'/notifications/statistics?day={}'.format(date.today().isoformat()),
headers=[auth_header]
)
notifications = json.loads(response.get_data(as_text=True))
assert len(notifications['data']) == 1
stats = notifications['data'][0]
assert stats['emails_requested'] == 0
assert stats['emails_delivered'] == 0
assert stats['emails_failed'] == 0
assert stats['sms_requested'] == 0
assert stats['sms_delivered'] == 0
assert stats['sms_failed'] == 0
assert stats['service'] == str(sample_service.id)
assert response.status_code == 200
def test_get_notification_statistics_returns_both_existing_stats_and_generated_zeros(
notify_api,
notify_db,
notify_db_session
):
with notify_api.test_request_context():
with notify_api.test_client() as client:
service_with_stats = create_sample_service(
notify_db,
notify_db_session,
service_name='service_with_stats',
email_from='service_with_stats'
)
service_without_stats = create_sample_service(
notify_db,
notify_db_session,
service_name='service_without_stats',
email_from='service_without_stats'
)
notification_statistics = create_sample_notification_statistics(
notify_db,
notify_db_session,
service=service_with_stats,
day=date.today()
)
auth_header = create_authorization_header(
service_id=service_with_stats.id
)
response = client.get(
'/notifications/statistics?day={}'.format(date.today().isoformat()),
headers=[auth_header]
)
notifications = json.loads(response.get_data(as_text=True))
assert len(notifications['data']) == 2
retrieved_stats = notifications['data'][0]
generated_stats = notifications['data'][1]
assert retrieved_stats['emails_requested'] == 2
assert retrieved_stats['emails_delivered'] == 1
assert retrieved_stats['emails_failed'] == 1
assert retrieved_stats['sms_requested'] == 2
assert retrieved_stats['sms_delivered'] == 1
assert retrieved_stats['sms_failed'] == 1
assert retrieved_stats['service'] == str(service_with_stats.id)
assert generated_stats['emails_requested'] == 0
assert generated_stats['emails_delivered'] == 0
assert generated_stats['emails_failed'] == 0
assert generated_stats['sms_requested'] == 0
assert generated_stats['sms_delivered'] == 0
assert generated_stats['sms_failed'] == 0
assert generated_stats['service'] == str(service_without_stats.id)
assert response.status_code == 200