Updates to create job to handle scheduling

- If the job JSON contains a scheduling date then the new 'job_status" column is set to "scheduled"
- the date is persisted on the JOB row in the database
- Also the job WILL NOT be placed onto the queue of jobs. This is deferred to a later celery beat task.
This commit is contained in:
Martyn Inglis
2016-08-24 16:00:21 +01:00
parent cf3c14dbbd
commit 10f499805c
4 changed files with 152 additions and 34 deletions

View File

@@ -1,9 +1,10 @@
import json
import uuid
from datetime import datetime, timedelta
from freezegun import freeze_time
import pytest
import pytz
import app.celery.tasks
from tests import create_authorization_header
@@ -108,10 +109,9 @@ def test_get_job_by_id(notify_api, sample_job):
assert resp_json['data']['created_by']['name'] == 'Test User'
def test_create_job(notify_api, sample_template, mocker, fake_uuid):
def test_create_unscheduled_job(notify_api, sample_template, mocker, fake_uuid):
with notify_api.test_request_context():
with notify_api.test_client() as client:
mocker.patch('app.celery.tasks.process_job.apply_async')
data = {
'id': fake_uuid,
@@ -140,11 +140,120 @@ def test_create_job(notify_api, sample_template, mocker, fake_uuid):
assert resp_json['data']['id'] == fake_uuid
assert resp_json['data']['status'] == 'pending'
assert not resp_json['data']['scheduled_for']
assert resp_json['data']['job_status'] == 'pending'
assert resp_json['data']['template'] == str(sample_template.id)
assert resp_json['data']['original_file_name'] == 'thisisatest.csv'
def test_create_scheduled_job(notify_api, sample_template, mocker, fake_uuid):
with notify_api.test_request_context():
with notify_api.test_client() as client:
with freeze_time("2016-01-01 12:00:00.000000"):
scheduled_date = (datetime.utcnow() + timedelta(hours=23, minutes=59)).isoformat()
mocker.patch('app.celery.tasks.process_job.apply_async')
data = {
'id': fake_uuid,
'service': str(sample_template.service.id),
'template': str(sample_template.id),
'original_file_name': 'thisisatest.csv',
'notification_count': 1,
'created_by': str(sample_template.created_by.id),
'scheduled_for': scheduled_date
}
path = '/service/{}/job'.format(sample_template.service.id)
auth_header = create_authorization_header(service_id=sample_template.service.id)
headers = [('Content-Type', 'application/json'), auth_header]
response = client.post(
path,
data=json.dumps(data),
headers=headers)
assert response.status_code == 201
app.celery.tasks.process_job.apply_async.assert_not_called()
resp_json = json.loads(response.get_data(as_text=True))
assert resp_json['data']['id'] == fake_uuid
assert resp_json['data']['status'] == 'pending'
assert resp_json['data']['scheduled_for'] == datetime(2016, 1, 2, 11, 59, 0,
tzinfo=pytz.UTC).isoformat()
assert resp_json['data']['job_status'] == 'scheduled'
assert resp_json['data']['template'] == str(sample_template.id)
assert resp_json['data']['original_file_name'] == 'thisisatest.csv'
def test_should_not_create_scheduled_job_more_then_24_hours_hence(notify_api, sample_template, mocker, fake_uuid):
with notify_api.test_request_context():
with notify_api.test_client() as client:
with freeze_time("2016-01-01 11:09:00.061258"):
scheduled_date = (datetime.utcnow() + timedelta(hours=24, minutes=1)).isoformat()
mocker.patch('app.celery.tasks.process_job.apply_async')
data = {
'id': fake_uuid,
'service': str(sample_template.service.id),
'template': str(sample_template.id),
'original_file_name': 'thisisatest.csv',
'notification_count': 1,
'created_by': str(sample_template.created_by.id),
'scheduled_for': scheduled_date
}
path = '/service/{}/job'.format(sample_template.service.id)
auth_header = create_authorization_header(service_id=sample_template.service.id)
headers = [('Content-Type', 'application/json'), auth_header]
print(json.dumps(data))
response = client.post(
path,
data=json.dumps(data),
headers=headers)
assert response.status_code == 400
app.celery.tasks.process_job.apply_async.assert_not_called()
resp_json = json.loads(response.get_data(as_text=True))
assert resp_json['result'] == 'error'
assert 'scheduled_for' in resp_json['message']
assert resp_json['message']['scheduled_for'] == ['Date cannot be more than 24hrs in the future']
def test_should_not_create_scheduled_job_in_the_past(notify_api, sample_template, mocker, fake_uuid):
with notify_api.test_request_context():
with notify_api.test_client() as client:
with freeze_time("2016-01-01 11:09:00.061258"):
scheduled_date = (datetime.utcnow() - timedelta(minutes=1)).isoformat()
mocker.patch('app.celery.tasks.process_job.apply_async')
data = {
'id': fake_uuid,
'service': str(sample_template.service.id),
'template': str(sample_template.id),
'original_file_name': 'thisisatest.csv',
'notification_count': 1,
'created_by': str(sample_template.created_by.id),
'scheduled_for': scheduled_date
}
path = '/service/{}/job'.format(sample_template.service.id)
auth_header = create_authorization_header(service_id=sample_template.service.id)
headers = [('Content-Type', 'application/json'), auth_header]
print(json.dumps(data))
response = client.post(
path,
data=json.dumps(data),
headers=headers)
assert response.status_code == 400
app.celery.tasks.process_job.apply_async.assert_not_called()
resp_json = json.loads(response.get_data(as_text=True))
assert resp_json['result'] == 'error'
assert 'scheduled_for' in resp_json['message']
assert resp_json['message']['scheduled_for'] == ['Date cannot be in the past']
def test_create_job_returns_400_if_missing_data(notify_api, sample_template, mocker):
with notify_api.test_request_context():
with notify_api.test_client() as client:
@@ -303,35 +412,19 @@ def test_get_all_notifications_for_job_in_order_of_job_number(notify_api,
@pytest.mark.parametrize(
"expected_notification_count, status_args",
[
(
1,
'?status={}'.format(NOTIFICATION_STATUS_TYPES[0])
),
(
0,
'?status={}'.format(NOTIFICATION_STATUS_TYPES[1])
),
(
1,
'?status={}&status={}&status={}'.format(
*NOTIFICATION_STATUS_TYPES[0:3]
)
),
(
0,
'?status={}&status={}&status={}'.format(
*NOTIFICATION_STATUS_TYPES[3:6]
)
),
(1, '?status={}'.format(NOTIFICATION_STATUS_TYPES[0])),
(0, '?status={}'.format(NOTIFICATION_STATUS_TYPES[1])),
(1, '?status={}&status={}&status={}'.format(*NOTIFICATION_STATUS_TYPES[0:3])),
(0, '?status={}&status={}&status={}'.format(*NOTIFICATION_STATUS_TYPES[3:6])),
]
)
def test_get_all_notifications_for_job_filtered_by_status(
notify_api,
notify_db,
notify_db_session,
sample_service,
expected_notification_count,
status_args
notify_api,
notify_db,
notify_db_session,
sample_service,
expected_notification_count,
status_args
):
with notify_api.test_request_context(), notify_api.test_client() as client:
job = create_job(notify_db, notify_db_session, service=sample_service)

View File

@@ -1,4 +1,3 @@
from datetime import datetime, timedelta
import uuid
import pytest