From 4fefec6aa34bb8528e78006f907b39fcfeb00fb7 Mon Sep 17 00:00:00 2001 From: Rebecca Law Date: Tue, 13 Jun 2017 10:56:03 +0100 Subject: [PATCH] New endpoints to return job stats. Next step is to use the new endpoints in admin. --- app/dao/jobs_dao.py | 8 +++++++ app/job/rest.py | 18 ++++++++++++-- tests/app/dao/test_jobs_dao.py | 16 +++++++------ tests/app/job/test_rest.py | 44 ++++++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 9 deletions(-) diff --git a/app/dao/jobs_dao.py b/app/dao/jobs_dao.py index 9d791b8ad..236ddcab8 100644 --- a/app/dao/jobs_dao.py +++ b/app/dao/jobs_dao.py @@ -159,6 +159,9 @@ def dao_get_job_statistics_for_job(service_id, job_id): Job.scheduled_for, Job.template_id, Job.template_version, + Job.job_status, + Job.service_id, + Job.notification_count, JobStatistics.sent, JobStatistics.delivered, JobStatistics.failed @@ -179,6 +182,11 @@ def dao_get_job_stats_for_service(service_id, page=1, page_size=50, limit_days=N Job.original_file_name, Job.created_at, Job.scheduled_for, + Job.template_id, + Job.template_version, + Job.job_status, + Job.service_id, + Job.notification_count, JobStatistics.sent, JobStatistics.delivered, JobStatistics.failed diff --git a/app/job/rest.py b/app/job/rest.py index 5e5bc33c1..6a8a86ee4 100644 --- a/app/job/rest.py +++ b/app/job/rest.py @@ -5,6 +5,7 @@ from flask import ( current_app ) +from app import DATETIME_FORMAT from app.dao.jobs_dao import ( dao_create_job, dao_update_job, @@ -12,7 +13,8 @@ from app.dao.jobs_dao import ( dao_get_jobs_by_service_id, dao_get_future_scheduled_job_by_id_and_service_id, dao_get_notification_outcomes_for_job, - dao_get_job_stats_for_service) + dao_get_job_stats_for_service, + dao_get_job_statistics_for_job) from app.dao.services_dao import ( dao_fetch_service_by_id @@ -57,6 +59,13 @@ def get_job_by_service_and_job_id(service_id, job_id): return jsonify(data=data) +@job_blueprint.route('/job-stats/', methods=['GET']) +def get_job_stats_by_service_and_job_id(service_id, job_id): + statistic = dao_get_job_statistics_for_job(service_id=service_id, job_id=job_id) + + return jsonify(_serialize_job_stats(statistic)) + + @job_blueprint.route('//cancel', methods=['POST']) def cancel_job(service_id, job_id): job = dao_get_future_scheduled_job_by_id_and_service_id(job_id, service_id) @@ -155,8 +164,13 @@ def _serialize_job_stats(stat): return { "job_id": stat.job_id, "original_file_name": stat.original_file_name, - "created_at": stat.created_at, + "created_at": stat.created_at.strftime(DATETIME_FORMAT), "scheduled_for": stat.scheduled_for, + "template_id": stat.template_id, + "template_version": stat.template_version, + "job_status": stat.job_status, + "service_id": stat.service_id, + "requested": stat.notification_count, "sent": stat.sent, "delivered": stat.delivered, "failed": stat.failed diff --git a/tests/app/dao/test_jobs_dao.py b/tests/app/dao/test_jobs_dao.py index 32508c628..a4517aee5 100644 --- a/tests/app/dao/test_jobs_dao.py +++ b/tests/app/dao/test_jobs_dao.py @@ -429,16 +429,16 @@ def test_dao_get_job_statistics_for_job(notify_db, notify_db_session, sample_job update_job_stats_outcome_count(notification_delivered) update_job_stats_outcome_count(notification_failed) result = dao_get_job_statistics_for_job(sample_job.service_id, sample_job.id) - assert_job_stat(job=sample_job, result=result, sent=3, delivered=1, failed=1, with_template=True) + assert_job_stat(job=sample_job, result=result, sent=3, delivered=1, failed=1) def test_dao_get_job_statistics_for_job(notify_db, notify_db_session, sample_service): job_1, job_2 = stats_set_up(notify_db, notify_db_session, sample_service) result = dao_get_job_statistics_for_job(sample_service.id, job_1.id) - assert_job_stat(job=job_1, result=result, sent=2, delivered=1, failed=0, with_template=True) + assert_job_stat(job=job_1, result=result, sent=2, delivered=1, failed=0) result_2 = dao_get_job_statistics_for_job(sample_service.id, job_2.id) - assert_job_stat(job=job_2, result=result_2, sent=1, delivered=0, failed=1, with_template=True) + assert_job_stat(job=job_2, result=result_2, sent=1, delivered=0, failed=1) def test_dao_get_job_stats_for_service(notify_db, notify_db_session, sample_service): @@ -508,17 +508,19 @@ def test_dao_get_job_returns_jobs_for_status( assert results_2.total == 2 -def assert_job_stat(job, result, sent, delivered, failed, with_template=False): +def assert_job_stat(job, result, sent, delivered, failed): assert result.job_id == job.id assert result.original_file_name == job.original_file_name assert result.created_at == job.created_at assert result.scheduled_for == job.scheduled_for + assert result.template_id == job.template_id + assert result.template_version == job.template_version + assert result.job_status == job.job_status + assert result.service_id == job.service_id + assert result.notification_count == job.notification_count assert result.sent == sent assert result.delivered == delivered assert result.failed == failed - if with_template: - assert result.template_id == job.template_id - assert result.template_version == job.template_version def stats_set_up(notify_db, notify_db_session, service): diff --git a/tests/app/job/test_rest.py b/tests/app/job/test_rest.py index 37fbe02dd..b7ba7689d 100644 --- a/tests/app/job/test_rest.py +++ b/tests/app/job/test_rest.py @@ -6,6 +6,7 @@ from freezegun import freeze_time import pytest import pytz import app.celery.tasks +from app import DATETIME_FORMAT from tests import create_authorization_header from tests.conftest import set_config @@ -779,6 +780,10 @@ def test_get_jobs_for_service_new_endpoint(client, notify_db, notify_db_session, assert resp_json['data'][0]["job_id"] assert resp_json['data'][0]["created_at"] assert not resp_json['data'][0]["scheduled_for"] + assert resp_json['data'][0]["template_id"] + assert resp_json['data'][0]["template_version"] + assert resp_json['data'][0]["service_id"] + assert resp_json['data'][0]["requested"] assert resp_json['data'][0]["sent"] == 0 assert resp_json['data'][0]["delivered"] == 0 assert resp_json['data'][0]["failed"] == 0 @@ -805,3 +810,42 @@ def test_parse_status_turns_empty_string_into_empty_list(): statuses = "" from app.job.rest import _parse_statuses assert _parse_statuses(statuses) == [''] + + +def test_get_job_stats_by_service_id_and_job_id(client, sample_job): + auth_header = create_authorization_header() + response = client.get("/service/{}/job/job-stats/{}".format(sample_job.service_id, sample_job.id), + headers=[auth_header]) + assert response.status_code == 200 + resp_json = json.loads(response.get_data(as_text=True)) + assert resp_json["job_id"] == str(sample_job.id) + assert resp_json["created_at"] == sample_job.created_at.strftime(DATETIME_FORMAT) + assert not resp_json["scheduled_for"] + assert resp_json["template_id"] == str(sample_job.template_id) + assert resp_json["template_version"] == sample_job.template_version + assert resp_json["service_id"] == str(sample_job.service_id) + assert resp_json["requested"] == sample_job.notification_count + assert resp_json["sent"] == 0 + assert resp_json["delivered"] == 0 + assert resp_json["failed"] == 0 + + +def test_get_job_stats_with_invalid_job_id_returns404(client, sample_template): + service_id = sample_template.service.id + path = '/service/{}/job/job-=stats{}'.format(service_id, "bad-id") + auth_header = create_authorization_header() + response = client.get(path, headers=[auth_header]) + assert response.status_code == 404 + resp_json = json.loads(response.get_data(as_text=True)) + assert resp_json['result'] == 'error' + assert resp_json['message'] == 'No result found' + + +def test_get_job_stats_with_invalid_service_id_returns404(client, sample_job): + path = '/service/{}/job/job-=stats{}'.format(uuid.uuid4(), sample_job.id) + auth_header = create_authorization_header() + response = client.get(path, headers=[auth_header]) + assert response.status_code == 404 + resp_json = json.loads(response.get_data(as_text=True)) + assert resp_json['result'] == 'error' + assert resp_json['message'] == 'No result found'