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)

    job_1 = sample_job(notify_db, notify_db_session, created_at=one_millisecond_before_midnight)
    sample_job(notify_db, notify_db_session, created_at=midnight)
    sample_job(notify_db, notify_db_session, created_at=one_millisecond_past_midnight)

    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)
def test_should_process_email_job_if_exactly_on_send_limits(notify_db,
                                                            notify_db_session,
                                                            mocker):
    service = sample_service(notify_db, notify_db_session, limit=10)
    template = sample_email_template(notify_db, notify_db_session, service=service)
    job = sample_job(notify_db, notify_db_session, service=service, template=template, notification_count=10)

    mocker.patch('app.celery.tasks.s3.get_job_from_s3', return_value=load_example_csv('multiple_email'))
    mocker.patch('app.celery.tasks.send_email.apply_async')
    mocker.patch('app.encryption.encrypt', return_value="something_encrypted")
    mocker.patch('app.celery.tasks.create_uuid', return_value="uuid")

    process_job(job.id)

    s3.get_job_from_s3.assert_called_once_with(
        str(job.service.id),
        str(job.id)
    )
    job = jobs_dao.dao_get_job_by_id(job.id)
    assert job.job_status == 'finished'
    tasks.send_email.apply_async.assert_called_with(
        (
            str(job.service_id),
            "uuid",
            "something_encrypted",
            "2016-01-01T11:09:00.061258Z"
        ),
        queue="db-email"
    )
def test_should_process_email_job_into_research_mode_queue_if_research_mode_service(
        notify_db, notify_db_session, mocker
):
    mocker.patch('app.celery.tasks.s3.get_job_from_s3', return_value=load_example_csv('sms'))
    mocker.patch('app.celery.tasks.send_email.apply_async')
    mocker.patch('app.encryption.encrypt', return_value="something_encrypted")
    mocker.patch('app.celery.tasks.create_uuid', return_value="uuid")

    service = sample_service(notify_db, notify_db_session)
    service.research_mode = True
    services_dao.dao_update_service(service)
    template = sample_email_template(notify_db, notify_db_session, service=service)
    job = sample_job(notify_db, notify_db_session, template=template, service=service)

    process_job(job.id)
    s3.get_job_from_s3.assert_called_once_with(
        str(job.service.id),
        str(job.id)
    )
    tasks.send_email.apply_async.assert_called_once_with(
        (str(job.service_id),
         "uuid",
         "something_encrypted",
         "2016-01-01T11:09:00.061258Z"),
        queue="research-mode"
    )
def test_should_not_update_status_by_reference_if_not_sending_and_does_not_update_job(notify_db, notify_db_session):
    job = sample_job(notify_db, notify_db_session)
    notification = sample_notification(notify_db, notify_db_session, status='delivered', reference='reference', job=job)
    assert Notification.query.get(notification.id).status == 'delivered'
    assert not update_notification_status_by_reference('reference', 'failed')
    assert Notification.query.get(notification.id).status == 'delivered'
    assert job == Job.query.get(notification.job_id)
def test_should_not_process_job_if_already_pending(notify_db, notify_db_session, mocker):
    job = sample_job(notify_db, notify_db_session, job_status='scheduled')

    mocker.patch('app.celery.tasks.s3.get_job_from_s3')
    mocker.patch('app.celery.tasks.send_sms.apply_async')

    process_job(job.id)

    assert s3.get_job_from_s3.called is False
    assert tasks.send_sms.apply_async.called is False
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)
    job = sample_job(notify_db, notify_db_session, scheduled_for=one_minute_in_the_past, job_status='scheduled')

    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)
    job_1 = sample_job(notify_db, notify_db_session, scheduled_for=one_minute_in_the_past, job_status='scheduled')
    job_2 = sample_job(notify_db, notify_db_session, scheduled_for=ten_minutes_in_the_past, job_status='scheduled')
    job_3 = sample_job(notify_db, notify_db_session, scheduled_for=twenty_minutes_in_the_past, job_status='scheduled')

    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')
    ])
def test_save_notification_and_increment_correct_job(notify_db, notify_db_session, sample_template, mmg_provider):
    from tests.app.conftest import sample_job
    job_1 = sample_job(notify_db, notify_db_session, sample_template.service)
    job_2 = sample_job(notify_db, notify_db_session, sample_template.service)

    assert Notification.query.count() == 0
    data = _notification_json(sample_template, job_id=job_1.id)

    notification = Notification(**data)
    dao_create_notification(notification)

    assert Notification.query.count() == 1
    notification_from_db = Notification.query.all()[0]
    assert notification_from_db.id
    assert data['to'] == notification_from_db.to
    assert data['job_id'] == notification_from_db.job_id
    assert data['service'] == notification_from_db.service
    assert data['template'] == notification_from_db.template
    assert data['template_version'] == notification_from_db.template_version
    assert data['created_at'] == notification_from_db.created_at
    assert notification_from_db.status == 'created'
    assert job_1.id != job_2.id
def test_should_not_process_email_job_if_would_exceed_send_limits(notify_db, notify_db_session, mocker):
    service = sample_service(notify_db, notify_db_session, limit=0)
    template = sample_email_template(notify_db, notify_db_session, service=service)
    job = sample_job(notify_db, notify_db_session, service=service, template=template)

    mocker.patch('app.celery.tasks.s3.get_job_from_s3')
    mocker.patch('app.celery.tasks.send_email.apply_async')

    process_job(job.id)

    job = jobs_dao.dao_get_job_by_id(job.id)
    assert job.job_status == 'sending limits exceeded'
    assert s3.get_job_from_s3.called is False
    assert tasks.send_email.apply_async.called is False
def test_should_not_process_email_job_if_would_exceed_send_limits_inc_today(notify_db, notify_db_session, mocker):
    service = sample_service(notify_db, notify_db_session, limit=1)
    template = sample_email_template(notify_db, notify_db_session, service=service)
    job = sample_job(notify_db, notify_db_session, service=service, template=template)

    sample_notification(notify_db, notify_db_session, service=service, job=job)

    mocker.patch('app.celery.tasks.s3.get_job_from_s3', return_value=load_example_csv('email'))
    mocker.patch('app.celery.tasks.send_email.apply_async')

    process_job(job.id)

    job = jobs_dao.dao_get_job_by_id(job.id)
    assert job.job_status == 'sending limits exceeded'
    assert s3.get_job_from_s3.called is False
    assert tasks.send_email.apply_async.called is False
def test_should_not_process_sms_job_if_would_exceed_send_limits(notify_db,
                                                                notify_db_session,
                                                                mocker):
    service = sample_service(notify_db, notify_db_session, limit=9)
    job = sample_job(notify_db, notify_db_session, service=service, notification_count=10)

    mocker.patch('app.celery.tasks.s3.get_job_from_s3', return_value=load_example_csv('multiple_sms'))
    mocker.patch('app.celery.tasks.send_sms.apply_async')
    mocker.patch('app.encryption.encrypt', return_value="something_encrypted")
    mocker.patch('app.celery.tasks.create_uuid', return_value="uuid")

    process_job(job.id)

    job = jobs_dao.dao_get_job_by_id(job.id)
    assert job.job_status == 'sending limits exceeded'
    assert s3.get_job_from_s3.called is False
    assert tasks.send_sms.apply_async.called is False
def test_should_return_notifications_including_jobs(notify_db, notify_db_session, sample_service):
    assert len(Notification.query.all()) == 0

    job = sample_job(notify_db, notify_db_session)
    with_job = sample_notification(
        notify_db, notify_db_session, created_at=datetime.utcnow(), status="delivered", job=job
    )

    all_notifications = Notification.query.all()
    assert len(all_notifications) == 1

    all_notifications = get_notifications_for_service(sample_service.id).items
    assert len(all_notifications) == 0

    all_notifications = get_notifications_for_service(sample_service.id, limit_days=1, include_jobs=True).items
    assert len(all_notifications) == 1
    assert all_notifications[0].id == with_job.id
def test_should_return_notifications_excluding_jobs_by_default(notify_db, notify_db_session, sample_service):
    assert len(Notification.query.all()) == 0

    job = sample_job(notify_db, notify_db_session)
    with_job = sample_notification(
        notify_db, notify_db_session, created_at=datetime.utcnow(), status="delivered", job=job
    )
    without_job = sample_notification(
        notify_db, notify_db_session, created_at=datetime.utcnow(), status="delivered"
    )

    all_notifications = Notification.query.all()
    assert len(all_notifications) == 2

    all_notifications = get_notifications_for_service(sample_service.id).items
    assert len(all_notifications) == 1
    assert all_notifications[0].id == without_job.id