2016-06-20 13:33:53 +01:00
|
|
|
from datetime import datetime, timedelta
|
2017-01-27 12:30:56 +00:00
|
|
|
from functools import partial
|
2016-06-20 13:33:53 +01:00
|
|
|
|
|
|
|
|
from flask import current_app
|
2016-09-07 15:36:59 +01:00
|
|
|
from freezegun import freeze_time
|
|
|
|
|
from app.celery.scheduled_tasks import s3
|
2016-06-20 13:33:53 +01:00
|
|
|
from app.celery import scheduled_tasks
|
2017-01-27 12:30:56 +00:00
|
|
|
from app.celery.scheduled_tasks import (
|
|
|
|
|
delete_verify_codes,
|
|
|
|
|
remove_csv_files,
|
|
|
|
|
delete_successful_notifications,
|
|
|
|
|
delete_failed_notifications,
|
|
|
|
|
delete_invitations,
|
|
|
|
|
timeout_notifications,
|
|
|
|
|
run_scheduled_jobs,
|
|
|
|
|
send_daily_performance_stats
|
|
|
|
|
)
|
2016-08-24 17:03:56 +01:00
|
|
|
from app.dao.jobs_dao import dao_get_job_by_id
|
2017-01-27 12:30:56 +00:00
|
|
|
from app.utils import get_midnight_for_date
|
|
|
|
|
from tests.app.conftest import (
|
|
|
|
|
sample_notification as create_sample_notification,
|
|
|
|
|
sample_job as create_sample_job,
|
|
|
|
|
sample_notification_history as create_notification_history
|
|
|
|
|
)
|
2016-09-05 16:45:54 +01:00
|
|
|
from unittest.mock import call
|
2016-06-20 13:33:53 +01:00
|
|
|
|
|
|
|
|
|
2016-08-05 10:44:43 +01:00
|
|
|
def test_should_have_decorated_tasks_functions():
|
|
|
|
|
assert delete_verify_codes.__wrapped__.__name__ == 'delete_verify_codes'
|
|
|
|
|
assert delete_successful_notifications.__wrapped__.__name__ == 'delete_successful_notifications'
|
|
|
|
|
assert delete_failed_notifications.__wrapped__.__name__ == 'delete_failed_notifications'
|
|
|
|
|
assert timeout_notifications.__wrapped__.__name__ == 'timeout_notifications'
|
|
|
|
|
assert delete_invitations.__wrapped__.__name__ == 'delete_invitations'
|
2016-08-24 17:03:56 +01:00
|
|
|
assert run_scheduled_jobs.__wrapped__.__name__ == 'run_scheduled_jobs'
|
2016-09-07 15:36:59 +01:00
|
|
|
assert remove_csv_files.__wrapped__.__name__ == 'remove_csv_files'
|
2017-01-27 12:30:56 +00:00
|
|
|
assert send_daily_performance_stats.__wrapped__.__name__ == 'send_daily_performance_stats'
|
2016-08-05 10:44:43 +01:00
|
|
|
|
|
|
|
|
|
2016-06-20 13:33:53 +01:00
|
|
|
def test_should_call_delete_notifications_more_than_week_in_task(notify_api, mocker):
|
2016-08-24 17:03:56 +01:00
|
|
|
mocked = mocker.patch('app.celery.scheduled_tasks.delete_notifications_created_more_than_a_week_ago')
|
2016-06-20 13:33:53 +01:00
|
|
|
delete_successful_notifications()
|
|
|
|
|
assert mocked.assert_called_with('delivered')
|
|
|
|
|
assert scheduled_tasks.delete_notifications_created_more_than_a_week_ago.call_count == 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_should_call_delete_notifications_more_than_week_in_task(notify_api, mocker):
|
|
|
|
|
mocker.patch('app.celery.scheduled_tasks.delete_notifications_created_more_than_a_week_ago')
|
|
|
|
|
delete_failed_notifications()
|
|
|
|
|
assert scheduled_tasks.delete_notifications_created_more_than_a_week_ago.call_count == 4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_should_call_delete_codes_on_delete_verify_codes_task(notify_api, mocker):
|
|
|
|
|
mocker.patch('app.celery.scheduled_tasks.delete_codes_older_created_more_than_a_day_ago')
|
|
|
|
|
delete_verify_codes()
|
|
|
|
|
assert scheduled_tasks.delete_codes_older_created_more_than_a_day_ago.call_count == 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_should_call_delete_invotations_on_delete_invitations_task(notify_api, mocker):
|
|
|
|
|
mocker.patch('app.celery.scheduled_tasks.delete_invitations_created_more_than_two_days_ago')
|
|
|
|
|
delete_invitations()
|
|
|
|
|
assert scheduled_tasks.delete_invitations_created_more_than_two_days_ago.call_count == 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_update_status_of_notifications_after_timeout(notify_api,
|
|
|
|
|
notify_db,
|
|
|
|
|
notify_db_session,
|
|
|
|
|
sample_service,
|
|
|
|
|
sample_template,
|
|
|
|
|
mmg_provider):
|
|
|
|
|
with notify_api.test_request_context():
|
2017-01-27 12:30:56 +00:00
|
|
|
not1 = create_sample_notification(
|
2016-06-20 13:33:53 +01:00
|
|
|
notify_db,
|
|
|
|
|
notify_db_session,
|
|
|
|
|
service=sample_service,
|
|
|
|
|
template=sample_template,
|
|
|
|
|
status='sending',
|
|
|
|
|
created_at=datetime.utcnow() - timedelta(
|
|
|
|
|
seconds=current_app.config.get('SENDING_NOTIFICATIONS_TIMEOUT_PERIOD') + 10))
|
2017-01-27 12:30:56 +00:00
|
|
|
not2 = create_sample_notification(
|
2016-12-16 11:40:58 +00:00
|
|
|
notify_db,
|
|
|
|
|
notify_db_session,
|
|
|
|
|
service=sample_service,
|
|
|
|
|
template=sample_template,
|
|
|
|
|
status='created',
|
|
|
|
|
created_at=datetime.utcnow() - timedelta(
|
|
|
|
|
seconds=current_app.config.get('SENDING_NOTIFICATIONS_TIMEOUT_PERIOD') + 10))
|
2017-01-27 12:30:56 +00:00
|
|
|
not3 = create_sample_notification(
|
2016-12-16 11:40:58 +00:00
|
|
|
notify_db,
|
|
|
|
|
notify_db_session,
|
|
|
|
|
service=sample_service,
|
|
|
|
|
template=sample_template,
|
|
|
|
|
status='pending',
|
|
|
|
|
created_at=datetime.utcnow() - timedelta(
|
|
|
|
|
seconds=current_app.config.get('SENDING_NOTIFICATIONS_TIMEOUT_PERIOD') + 10))
|
2016-06-20 13:33:53 +01:00
|
|
|
timeout_notifications()
|
2016-12-16 11:40:58 +00:00
|
|
|
assert not1.status == 'temporary-failure'
|
|
|
|
|
assert not2.status == 'technical-failure'
|
|
|
|
|
assert not3.status == 'temporary-failure'
|
2016-06-20 13:33:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_not_update_status_of_notification_before_timeout(notify_api,
|
|
|
|
|
notify_db,
|
|
|
|
|
notify_db_session,
|
|
|
|
|
sample_service,
|
|
|
|
|
sample_template,
|
|
|
|
|
mmg_provider):
|
|
|
|
|
with notify_api.test_request_context():
|
2017-01-27 12:30:56 +00:00
|
|
|
not1 = create_sample_notification(
|
2016-06-20 13:33:53 +01:00
|
|
|
notify_db,
|
|
|
|
|
notify_db_session,
|
|
|
|
|
service=sample_service,
|
|
|
|
|
template=sample_template,
|
|
|
|
|
status='sending',
|
|
|
|
|
created_at=datetime.utcnow() - timedelta(
|
|
|
|
|
seconds=current_app.config.get('SENDING_NOTIFICATIONS_TIMEOUT_PERIOD') - 10))
|
|
|
|
|
timeout_notifications()
|
|
|
|
|
assert not1.status == 'sending'
|
2016-08-24 17:03:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_should_update_scheduled_jobs_and_put_on_queue(notify_db, notify_db_session, mocker):
|
|
|
|
|
mocked = mocker.patch('app.celery.tasks.process_job.apply_async')
|
|
|
|
|
|
|
|
|
|
one_minute_in_the_past = datetime.utcnow() - timedelta(minutes=1)
|
2017-01-27 12:30:56 +00:00
|
|
|
job = create_sample_job(notify_db, notify_db_session, scheduled_for=one_minute_in_the_past, job_status='scheduled')
|
2016-08-24 17:03:56 +01:00
|
|
|
|
|
|
|
|
run_scheduled_jobs()
|
|
|
|
|
|
|
|
|
|
updated_job = dao_get_job_by_id(job.id)
|
|
|
|
|
assert updated_job.job_status == 'pending'
|
|
|
|
|
mocked.assert_called_with([str(job.id)], queue='process-job')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_should_update_all_scheduled_jobs_and_put_on_queue(notify_db, notify_db_session, mocker):
|
|
|
|
|
mocked = mocker.patch('app.celery.tasks.process_job.apply_async')
|
|
|
|
|
|
|
|
|
|
one_minute_in_the_past = datetime.utcnow() - timedelta(minutes=1)
|
|
|
|
|
ten_minutes_in_the_past = datetime.utcnow() - timedelta(minutes=10)
|
|
|
|
|
twenty_minutes_in_the_past = datetime.utcnow() - timedelta(minutes=20)
|
2017-01-27 12:30:56 +00:00
|
|
|
job_1 = create_sample_job(
|
|
|
|
|
notify_db,
|
|
|
|
|
notify_db_session,
|
|
|
|
|
scheduled_for=one_minute_in_the_past,
|
|
|
|
|
job_status='scheduled'
|
|
|
|
|
)
|
|
|
|
|
job_2 = create_sample_job(
|
|
|
|
|
notify_db,
|
|
|
|
|
notify_db_session,
|
|
|
|
|
scheduled_for=ten_minutes_in_the_past,
|
|
|
|
|
job_status='scheduled'
|
|
|
|
|
)
|
|
|
|
|
job_3 = create_sample_job(
|
|
|
|
|
notify_db,
|
|
|
|
|
notify_db_session,
|
|
|
|
|
scheduled_for=twenty_minutes_in_the_past,
|
|
|
|
|
job_status='scheduled'
|
|
|
|
|
)
|
2016-08-24 17:03:56 +01:00
|
|
|
|
|
|
|
|
run_scheduled_jobs()
|
|
|
|
|
|
|
|
|
|
assert dao_get_job_by_id(job_1.id).job_status == 'pending'
|
|
|
|
|
assert dao_get_job_by_id(job_2.id).job_status == 'pending'
|
|
|
|
|
assert dao_get_job_by_id(job_2.id).job_status == 'pending'
|
|
|
|
|
|
|
|
|
|
mocked.assert_has_calls([
|
|
|
|
|
call([str(job_3.id)], queue='process-job'),
|
|
|
|
|
call([str(job_2.id)], queue='process-job'),
|
|
|
|
|
call([str(job_1.id)], queue='process-job')
|
|
|
|
|
])
|
2016-09-07 15:36:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_will_remove_csv_files_for_jobs_older_than_seven_days(notify_db, notify_db_session, mocker):
|
|
|
|
|
mocker.patch('app.celery.scheduled_tasks.s3.remove_job_from_s3')
|
|
|
|
|
|
|
|
|
|
one_millisecond_before_midnight = datetime(2016, 10, 9, 23, 59, 59, 999)
|
|
|
|
|
midnight = datetime(2016, 10, 10, 0, 0, 0, 0)
|
|
|
|
|
one_millisecond_past_midnight = datetime(2016, 10, 10, 0, 0, 0, 1)
|
|
|
|
|
|
2017-01-27 12:30:56 +00:00
|
|
|
job_1 = create_sample_job(notify_db, notify_db_session, created_at=one_millisecond_before_midnight)
|
|
|
|
|
create_sample_job(notify_db, notify_db_session, created_at=midnight)
|
|
|
|
|
create_sample_job(notify_db, notify_db_session, created_at=one_millisecond_past_midnight)
|
2016-09-07 15:36:59 +01:00
|
|
|
|
|
|
|
|
with freeze_time('2016-10-17T00:00:00'):
|
|
|
|
|
remove_csv_files()
|
|
|
|
|
s3.remove_job_from_s3.assert_called_once_with(job_1.service_id, job_1.id)
|
2017-01-27 12:30:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@freeze_time("2016-01-11 12:30:00")
|
|
|
|
|
def test_send_daily_performance_stats_calls_with_correct_totals(notify_db, notify_db_session, sample_template, mocker):
|
|
|
|
|
perf_mock = mocker.patch('app.celery.scheduled_tasks.performance_platform_client.send_performance_stats')
|
|
|
|
|
|
|
|
|
|
notification_history = partial(
|
|
|
|
|
create_notification_history,
|
|
|
|
|
notify_db,
|
|
|
|
|
notify_db_session,
|
|
|
|
|
sample_template,
|
|
|
|
|
status='delivered'
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
notification_history(notification_type='email')
|
|
|
|
|
notification_history(notification_type='sms')
|
|
|
|
|
|
|
|
|
|
# Create some notifications for the day before
|
|
|
|
|
yesterday = datetime(2016, 1, 10, 15, 30, 0, 0)
|
|
|
|
|
with freeze_time(yesterday):
|
|
|
|
|
notification_history(notification_type='sms')
|
|
|
|
|
notification_history(notification_type='sms')
|
|
|
|
|
notification_history(notification_type='email')
|
|
|
|
|
notification_history(notification_type='email')
|
|
|
|
|
notification_history(notification_type='email')
|
|
|
|
|
|
|
|
|
|
send_daily_performance_stats()
|
|
|
|
|
|
|
|
|
|
perf_mock.assert_has_calls([
|
|
|
|
|
call(get_midnight_for_date(yesterday), 'sms', 2, 'day'),
|
|
|
|
|
call(get_midnight_for_date(yesterday), 'email', 3, 'day')
|
|
|
|
|
])
|