mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-03 01:41:05 -05:00
add statuses filter to GET /service/{}/job
can now pass in a query string `?statuses=x,y,z` to filter jobs based on `Job.job_status`. Not passing in a status or passing in an empty string is equivalent to selecting every filter type at once.
This commit is contained in:
@@ -27,10 +27,14 @@ def dao_get_job_by_service_id_and_job_id(service_id, job_id):
|
|||||||
return Job.query.filter_by(service_id=service_id, id=job_id).one()
|
return Job.query.filter_by(service_id=service_id, id=job_id).one()
|
||||||
|
|
||||||
|
|
||||||
def dao_get_jobs_by_service_id(service_id, limit_days=None, page=1, page_size=50):
|
def dao_get_jobs_by_service_id(service_id, limit_days=None, page=1, page_size=50, statuses=''):
|
||||||
query_filter = [Job.service_id == service_id]
|
query_filter = [Job.service_id == service_id]
|
||||||
if limit_days is not None:
|
if limit_days is not None:
|
||||||
query_filter.append(cast(Job.created_at, sql_date) >= days_ago(limit_days))
|
query_filter.append(cast(Job.created_at, sql_date) >= days_ago(limit_days))
|
||||||
|
if statuses != ['']:
|
||||||
|
query_filter.append(
|
||||||
|
Job.job_status.in_(statuses)
|
||||||
|
)
|
||||||
return Job.query \
|
return Job.query \
|
||||||
.filter(*query_filter) \
|
.filter(*query_filter) \
|
||||||
.order_by(desc(Job.created_at)) \
|
.order_by(desc(Job.created_at)) \
|
||||||
|
|||||||
@@ -102,8 +102,10 @@ def get_jobs_by_service(service_id):
|
|||||||
else:
|
else:
|
||||||
limit_days = None
|
limit_days = None
|
||||||
|
|
||||||
|
statuses = [x.strip() for x in request.args.get('statuses', '').split(',')]
|
||||||
|
|
||||||
page = int(request.args.get('page', 1))
|
page = int(request.args.get('page', 1))
|
||||||
return jsonify(**get_paginated_jobs(service_id, limit_days, page))
|
return jsonify(**get_paginated_jobs(service_id, limit_days, statuses, page))
|
||||||
|
|
||||||
|
|
||||||
@job.route('', methods=['POST'])
|
@job.route('', methods=['POST'])
|
||||||
@@ -140,14 +142,14 @@ def create_job(service_id):
|
|||||||
return jsonify(data=job_json), 201
|
return jsonify(data=job_json), 201
|
||||||
|
|
||||||
|
|
||||||
def get_paginated_jobs(service_id, limit_days, page):
|
def get_paginated_jobs(service_id, limit_days, statuses, page):
|
||||||
pagination = dao_get_jobs_by_service_id(
|
pagination = dao_get_jobs_by_service_id(
|
||||||
service_id,
|
service_id,
|
||||||
limit_days=limit_days,
|
limit_days=limit_days,
|
||||||
page=page,
|
page=page,
|
||||||
page_size=current_app.config['PAGE_SIZE']
|
page_size=current_app.config['PAGE_SIZE'],
|
||||||
|
statuses=statuses
|
||||||
)
|
)
|
||||||
|
|
||||||
data = job_schema.dump(pagination.items, many=True).data
|
data = job_schema.dump(pagination.items, many=True).data
|
||||||
for job_data in data:
|
for job_data in data:
|
||||||
statistics = dao_get_notification_outcomes_for_job(service_id, job_data['id'])
|
statistics = dao_get_notification_outcomes_for_job(service_id, job_data['id'])
|
||||||
|
|||||||
@@ -304,7 +304,14 @@ JOB_STATUS_FINISHED = 'finished'
|
|||||||
JOB_STATUS_SENDING_LIMITS_EXCEEDED = 'sending limits exceeded'
|
JOB_STATUS_SENDING_LIMITS_EXCEEDED = 'sending limits exceeded'
|
||||||
JOB_STATUS_SCHEDULED = 'scheduled'
|
JOB_STATUS_SCHEDULED = 'scheduled'
|
||||||
JOB_STATUS_CANCELLED = 'cancelled'
|
JOB_STATUS_CANCELLED = 'cancelled'
|
||||||
|
JOB_STATUS_TYPES = [
|
||||||
|
JOB_STATUS_PENDING,
|
||||||
|
JOB_STATUS_IN_PROGRESS,
|
||||||
|
JOB_STATUS_FINISHED,
|
||||||
|
JOB_STATUS_SENDING_LIMITS_EXCEEDED,
|
||||||
|
JOB_STATUS_SCHEDULED,
|
||||||
|
JOB_STATUS_CANCELLED
|
||||||
|
]
|
||||||
|
|
||||||
class JobStatus(db.Model):
|
class JobStatus(db.Model):
|
||||||
__tablename__ = 'job_status'
|
__tablename__ = 'job_status'
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from tests.app.conftest import (
|
|||||||
sample_notification as create_notification
|
sample_notification as create_notification
|
||||||
)
|
)
|
||||||
from app.dao.templates_dao import dao_update_template
|
from app.dao.templates_dao import dao_update_template
|
||||||
from app.models import NOTIFICATION_STATUS_TYPES
|
from app.models import NOTIFICATION_STATUS_TYPES, JOB_STATUS_TYPES, JOB_STATUS_PENDING
|
||||||
|
|
||||||
|
|
||||||
def test_get_job_with_invalid_service_id_returns404(notify_api, sample_api_key, sample_service):
|
def test_get_job_with_invalid_service_id_returns404(notify_api, sample_api_key, sample_service):
|
||||||
@@ -655,6 +655,42 @@ def test_get_jobs_accepts_page_parameter(
|
|||||||
assert set(resp_json['links'].keys()) == {'prev', 'next', 'last'}
|
assert set(resp_json['links'].keys()) == {'prev', 'next', 'last'}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('statuses_filter, expected_statuses', [
|
||||||
|
('', JOB_STATUS_TYPES),
|
||||||
|
('pending', [JOB_STATUS_PENDING]),
|
||||||
|
('pending, in progress, finished, sending limits exceeded, scheduled, cancelled', JOB_STATUS_TYPES),
|
||||||
|
# bad statuses are accepted, just return no data
|
||||||
|
('foo', [])
|
||||||
|
])
|
||||||
|
def test_get_jobs_can_filter_on_statuses(
|
||||||
|
notify_db,
|
||||||
|
notify_db_session,
|
||||||
|
client,
|
||||||
|
sample_service,
|
||||||
|
statuses_filter,
|
||||||
|
expected_statuses
|
||||||
|
):
|
||||||
|
create_job(notify_db, notify_db_session, job_status='pending')
|
||||||
|
create_job(notify_db, notify_db_session, job_status='in progress')
|
||||||
|
create_job(notify_db, notify_db_session, job_status='finished')
|
||||||
|
create_job(notify_db, notify_db_session, job_status='sending limits exceeded')
|
||||||
|
create_job(notify_db, notify_db_session, job_status='scheduled')
|
||||||
|
create_job(notify_db, notify_db_session, job_status='cancelled')
|
||||||
|
|
||||||
|
path = '/service/{}/job'.format(sample_service.id)
|
||||||
|
response = client.get(
|
||||||
|
path,
|
||||||
|
headers=[create_authorization_header()],
|
||||||
|
query_string={'statuses': statuses_filter}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
resp_json = json.loads(response.get_data(as_text=True))
|
||||||
|
from pprint import pprint
|
||||||
|
pprint(resp_json)
|
||||||
|
assert {x['job_status'] for x in resp_json['data']} == set(expected_statuses)
|
||||||
|
|
||||||
|
|
||||||
def create_10_jobs(db, session, service, template):
|
def create_10_jobs(db, session, service, template):
|
||||||
with freeze_time('2015-01-01T00:00:00') as the_time:
|
with freeze_time('2015-01-01T00:00:00') as the_time:
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
|
|||||||
Reference in New Issue
Block a user