Remove contact list db, dao, and s3 code

This commit is contained in:
Ryan Ahearn
2023-04-12 13:30:50 -04:00
parent f7418d62cb
commit e07b596857
22 changed files with 1 additions and 567 deletions

View File

@@ -43,16 +43,6 @@ def get_job_location(service_id, job_id):
) )
def get_contact_list_location(service_id, contact_list_id):
return (
current_app.config['CONTACT_LIST_BUCKET']['bucket'],
FILE_LOCATION_STRUCTURE.format(service_id, contact_list_id),
current_app.config['CONTACT_LIST_BUCKET']['access_key_id'],
current_app.config['CONTACT_LIST_BUCKET']['secret_access_key'],
current_app.config['CONTACT_LIST_BUCKET']['region'],
)
def get_job_and_metadata_from_s3(service_id, job_id): def get_job_and_metadata_from_s3(service_id, job_id):
obj = get_s3_object(*get_job_location(service_id, job_id)) obj = get_s3_object(*get_job_location(service_id, job_id))
return obj.get()['Body'].read().decode('utf-8'), obj.get()['Metadata'] return obj.get()['Body'].read().decode('utf-8'), obj.get()['Metadata']
@@ -72,10 +62,6 @@ def remove_job_from_s3(service_id, job_id):
return remove_s3_object(*get_job_location(service_id, job_id)) return remove_s3_object(*get_job_location(service_id, job_id))
def remove_contact_list_from_s3(service_id, contact_list_id):
return remove_s3_object(*get_contact_list_location(service_id, contact_list_id))
def remove_s3_object(bucket_name, object_key, access_key, secret_key, region): def remove_s3_object(bucket_name, object_key, access_key, secret_key, region):
obj = get_s3_object(bucket_name, object_key, access_key, secret_key, region) obj = get_s3_object(bucket_name, object_key, access_key, secret_key, region)
return obj.delete() return obj.delete()

View File

@@ -296,7 +296,6 @@ class Development(Config):
# Buckets # Buckets
CSV_UPLOAD_BUCKET = _s3_credentials_from_env('CSV') CSV_UPLOAD_BUCKET = _s3_credentials_from_env('CSV')
CONTACT_LIST_BUCKET = _s3_credentials_from_env('CONTACT')
# credential overrides # credential overrides
DANGEROUS_SALT = 'development-notify-salt' DANGEROUS_SALT = 'development-notify-salt'
@@ -333,8 +332,6 @@ class Production(Config):
# buckets # buckets
CSV_UPLOAD_BUCKET = cloud_config.s3_credentials( CSV_UPLOAD_BUCKET = cloud_config.s3_credentials(
f"notify-api-csv-upload-bucket-{Config.NOTIFY_ENVIRONMENT}") f"notify-api-csv-upload-bucket-{Config.NOTIFY_ENVIRONMENT}")
CONTACT_LIST_BUCKET = cloud_config.s3_credentials(
f"notify-api-contact-list-bucket-{Config.NOTIFY_ENVIRONMENT}")
FROM_NUMBER = 'US Notify' FROM_NUMBER = 'US Notify'
CRONITOR_ENABLED = True CRONITOR_ENABLED = True

View File

@@ -50,7 +50,6 @@ def dao_get_jobs_by_service_id(
page=1, page=1,
page_size=50, page_size=50,
statuses=None, statuses=None,
contact_list_id=None,
): ):
query_filter = [ query_filter = [
Job.service_id == service_id, Job.service_id == service_id,
@@ -63,8 +62,6 @@ def dao_get_jobs_by_service_id(
query_filter.append( query_filter.append(
Job.job_status.in_(statuses) Job.job_status.in_(statuses)
) )
if contact_list_id is not None:
query_filter.append(Job.contact_list_id == contact_list_id)
return Job.query \ return Job.query \
.filter(*query_filter) \ .filter(*query_filter) \
.order_by(Job.processing_started.desc(), Job.created_at.desc()) \ .order_by(Job.processing_started.desc(), Job.created_at.desc()) \

View File

@@ -1,33 +0,0 @@
from app import db
from app.models import ServiceContactList
def dao_get_contact_list_by_id(service_id, contact_list_id):
contact_list = ServiceContactList.query.filter_by(
service_id=service_id,
id=contact_list_id,
archived=False,
).one()
return contact_list
def dao_get_contact_lists(service_id):
contact_lists = ServiceContactList.query.filter_by(
service_id=service_id,
archived=False,
).order_by(
ServiceContactList.created_at.desc()
)
return contact_lists.all()
def save_service_contact_list(service_contact_list):
db.session.add(service_contact_list)
db.session.commit()
def dao_archive_contact_list(service_contact_list):
service_contact_list.archived = True
db.session.add(service_contact_list)
db.session.commit()

View File

@@ -30,7 +30,6 @@ from app.models import (
Organisation, Organisation,
Permission, Permission,
Service, Service,
ServiceContactList,
ServiceEmailReplyTo, ServiceEmailReplyTo,
ServicePermission, ServicePermission,
ServiceSmsSender, ServiceSmsSender,
@@ -360,7 +359,6 @@ def delete_service_and_all_associated_db_objects(service):
_delete_commit(ServiceSmsSender.query.filter_by(service=service)) _delete_commit(ServiceSmsSender.query.filter_by(service=service))
_delete_commit(ServiceEmailReplyTo.query.filter_by(service=service)) _delete_commit(ServiceEmailReplyTo.query.filter_by(service=service))
_delete_commit(ServiceContactList.query.filter_by(service=service))
_delete_commit(InvitedUser.query.filter_by(service=service)) _delete_commit(InvitedUser.query.filter_by(service=service))
_delete_commit(Permission.query.filter_by(service=service)) _delete_commit(Permission.query.filter_by(service=service))
_delete_commit(NotificationHistory.query.filter_by(service=service)) _delete_commit(NotificationHistory.query.filter_by(service=service))

View File

@@ -52,7 +52,6 @@ def dao_get_uploads_by_service_id(service_id, limit_days=None, page=1, page_size
func.coalesce( func.coalesce(
Job.processing_started, Job.created_at Job.processing_started, Job.created_at
) >= today - func.coalesce(ServiceDataRetention.days_of_retention, 7), ) >= today - func.coalesce(ServiceDataRetention.days_of_retention, 7),
Job.contact_list_id.is_(None),
] ]
if limit_days is not None: if limit_days is not None:
jobs_query_filter.append(Job.created_at >= midnight_n_days_ago(limit_days)) jobs_query_filter.append(Job.created_at >= midnight_n_days_ago(limit_days))

View File

@@ -122,7 +122,6 @@ def get_jobs_by_service(service_id):
limit_days=limit_days, limit_days=limit_days,
statuses=[x.strip() for x in request.args.get('statuses', '').split(',')], 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)),
contact_list_id=request.args.get('contact_list_id'),
)) ))
@@ -192,7 +191,6 @@ def get_paginated_jobs(
limit_days, limit_days,
statuses, statuses,
page, page,
contact_list_id,
): ):
pagination = dao_get_jobs_by_service_id( pagination = dao_get_jobs_by_service_id(
service_id, service_id,
@@ -200,7 +198,6 @@ def get_paginated_jobs(
page=page, page=page,
page_size=current_app.config['PAGE_SIZE'], page_size=current_app.config['PAGE_SIZE'],
statuses=statuses, statuses=statuses,
contact_list_id=contact_list_id,
) )
data = job_schema.dump(pagination.items, many=True) data = job_schema.dump(pagination.items, many=True)
for job_data in data: for job_data in data:

View File

@@ -256,7 +256,6 @@ class ServiceSchema(BaseSchema, UUIDsAsStringsMixin):
'annual_billing', 'annual_billing',
'api_keys', 'api_keys',
'complaints', 'complaints',
'contact_list',
'created_at', 'created_at',
'data_retention', 'data_retention',
'guest_list', 'guest_list',
@@ -309,7 +308,6 @@ class DetailedServiceSchema(BaseSchema):
'all_template_folders', 'all_template_folders',
'annual_billing', 'annual_billing',
'api_keys', 'api_keys',
'contact_list',
'created_by', 'created_by',
'email_branding', 'email_branding',
'email_from', 'email_from',
@@ -450,7 +448,6 @@ class JobSchema(BaseSchema):
template_name = fields.Method('get_template_name', dump_only=True) template_name = fields.Method('get_template_name', dump_only=True)
template_type = fields.Method('get_template_type', dump_only=True) template_type = fields.Method('get_template_type', dump_only=True)
contact_list_id = field_for(models.Job, 'contact_list_id')
def get_template_name(self, job): def get_template_name(self, job):
return job.template.name return job.template.name

View File

@@ -7,7 +7,6 @@ from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm.exc import NoResultFound from sqlalchemy.orm.exc import NoResultFound
from werkzeug.datastructures import MultiDict from werkzeug.datastructures import MultiDict
from app.aws import s3
from app.config import QueueNames from app.config import QueueNames
from app.dao import fact_notification_status_dao, notifications_dao from app.dao import fact_notification_status_dao, notifications_dao
from app.dao.annual_billing_dao import set_default_free_allowance_for_service from app.dao.annual_billing_dao import set_default_free_allowance_for_service
@@ -28,12 +27,6 @@ from app.dao.fact_notification_status_dao import (
) )
from app.dao.inbound_numbers_dao import dao_allocate_number_for_service from app.dao.inbound_numbers_dao import dao_allocate_number_for_service
from app.dao.organisation_dao import dao_get_organisation_by_service_id from app.dao.organisation_dao import dao_get_organisation_by_service_id
from app.dao.service_contact_list_dao import (
dao_archive_contact_list,
dao_get_contact_list_by_id,
dao_get_contact_lists,
save_service_contact_list,
)
from app.dao.service_data_retention_dao import ( from app.dao.service_data_retention_dao import (
fetch_service_data_retention, fetch_service_data_retention,
fetch_service_data_retention_by_id, fetch_service_data_retention_by_id,
@@ -80,13 +73,7 @@ from app.dao.services_dao import (
from app.dao.templates_dao import dao_get_template_by_id from app.dao.templates_dao import dao_get_template_by_id
from app.dao.users_dao import get_user_by_id from app.dao.users_dao import get_user_by_id
from app.errors import InvalidRequest, register_errors from app.errors import InvalidRequest, register_errors
from app.models import ( from app.models import KEY_TYPE_NORMAL, EmailBranding, Permission, Service
KEY_TYPE_NORMAL,
EmailBranding,
Permission,
Service,
ServiceContactList,
)
from app.notifications.process_notifications import ( from app.notifications.process_notifications import (
persist_notification, persist_notification,
send_notification_to_queue, send_notification_to_queue,
@@ -103,9 +90,6 @@ from app.schemas import (
from app.service import statistics from app.service import statistics
from app.service.send_notification import send_one_off_notification from app.service.send_notification import send_one_off_notification
from app.service.sender import send_notification_to_service_users from app.service.sender import send_notification_to_service_users
from app.service.service_contact_list_schema import (
create_service_contact_list_schema,
)
from app.service.service_data_retention_schema import ( from app.service.service_data_retention_schema import (
add_service_data_retention_request, add_service_data_retention_request,
update_service_data_retention_request, update_service_data_retention_request,
@@ -923,45 +907,3 @@ def check_if_reply_to_address_already_in_use(service_id, email_address):
raise InvalidRequest( raise InvalidRequest(
"Your service already uses {} as an email reply-to address.".format(email_address), status_code=409 "Your service already uses {} as an email reply-to address.".format(email_address), status_code=409
) )
@service_blueprint.route('/<uuid:service_id>/contact-list', methods=['GET'])
def get_contact_list(service_id):
contact_lists = dao_get_contact_lists(service_id)
return jsonify([x.serialize() for x in contact_lists])
@service_blueprint.route('/<uuid:service_id>/contact-list/<uuid:contact_list_id>', methods=['GET'])
def get_contact_list_by_id(service_id, contact_list_id):
contact_list = dao_get_contact_list_by_id(
service_id=service_id,
contact_list_id=contact_list_id
)
return jsonify(contact_list.serialize())
@service_blueprint.route('/<uuid:service_id>/contact-list/<uuid:contact_list_id>', methods=['DELETE'])
def delete_contact_list_by_id(service_id, contact_list_id):
contact_list = dao_get_contact_list_by_id(
service_id=service_id,
contact_list_id=contact_list_id,
)
dao_archive_contact_list(contact_list)
s3.remove_contact_list_from_s3(service_id, contact_list_id)
return '', 204
@service_blueprint.route('/<uuid:service_id>/contact-list', methods=['POST'])
def create_contact_list(service_id):
service_contact_list = validate(request.get_json(), create_service_contact_list_schema)
service_contact_list['created_by_id'] = service_contact_list.pop('created_by')
service_contact_list['created_at'] = datetime.utcnow()
service_contact_list['service_id'] = str(service_id)
list_to_save = ServiceContactList(**service_contact_list)
save_service_contact_list(list_to_save)
return jsonify(list_to_save.serialize()), 201

View File

@@ -1,16 +0,0 @@
from app.schema_validation.definitions import uuid
create_service_contact_list_schema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "POST create service contact list schema",
"type": "object",
"title": "Create service contact list",
"properties": {
"id": uuid,
"original_file_name": {"type": "string"},
"row_count": {"type": "integer"},
"template_type": {"enum": ['email', 'sms']},
"created_by": uuid
},
"required": ["id", "original_file_name", "row_count", "template_type", "created_by"]
}

View File

@@ -12,7 +12,6 @@ applications:
- notify-api-rds-((env)) - notify-api-rds-((env))
- notify-api-redis-((env)) - notify-api-redis-((env))
- notify-api-csv-upload-bucket-((env)) - notify-api-csv-upload-bucket-((env))
- notify-api-contact-list-bucket-((env))
- name: notify-api-ses-((env)) - name: notify-api-ses-((env))
parameters: parameters:
notification_webhook: "https://((public_api_route))/notifications/email/ses" notification_webhook: "https://((public_api_route))/notifications/email/ses"

View File

@@ -35,15 +35,6 @@ module "csv_upload_bucket" {
name = "${local.app_name}-csv-upload-bucket-${local.env}" name = "${local.app_name}-csv-upload-bucket-${local.env}"
} }
module "contact_list_bucket" {
source = "github.com/18f/terraform-cloudgov//s3?ref=v0.2.0"
cf_org_name = local.cf_org_name
cf_space_name = local.cf_space_name
recursive_delete = local.recursive_delete
name = "${local.app_name}-contact-list-bucket-${local.env}"
}
module "egress-space" { module "egress-space" {
source = "../shared/egress_space" source = "../shared/egress_space"

View File

@@ -18,19 +18,6 @@ resource "cloudfoundry_service_key" "csv_key" {
service_instance = module.csv_upload_bucket.bucket_id service_instance = module.csv_upload_bucket.bucket_id
} }
module "contact_list_bucket" {
source = "github.com/18f/terraform-cloudgov//s3?ref=v0.2.0"
cf_org_name = local.cf_org_name
cf_space_name = local.cf_space_name
recursive_delete = local.recursive_delete
name = "${var.username}-contact-list-bucket"
}
resource "cloudfoundry_service_key" "contact_list_key" {
name = local.key_name
service_instance = module.contact_list_bucket.bucket_id
}
data "cloudfoundry_space" "staging" { data "cloudfoundry_space" "staging" {
org_name = local.cf_org_name org_name = local.cf_org_name
name = "notify-staging" name = "notify-staging"
@@ -69,11 +56,6 @@ CSV_BUCKET_NAME=${cloudfoundry_service_key.csv_key.credentials.bucket}
CSV_AWS_ACCESS_KEY_ID=${cloudfoundry_service_key.csv_key.credentials.access_key_id} CSV_AWS_ACCESS_KEY_ID=${cloudfoundry_service_key.csv_key.credentials.access_key_id}
CSV_AWS_SECRET_ACCESS_KEY=${cloudfoundry_service_key.csv_key.credentials.secret_access_key} CSV_AWS_SECRET_ACCESS_KEY=${cloudfoundry_service_key.csv_key.credentials.secret_access_key}
CSV_AWS_REGION=${cloudfoundry_service_key.csv_key.credentials.region} CSV_AWS_REGION=${cloudfoundry_service_key.csv_key.credentials.region}
# CONTACT_LIST_BUCKET
CONTACT_BUCKET_NAME=${cloudfoundry_service_key.contact_list_key.credentials.bucket}
CONTACT_AWS_ACCESS_KEY_ID=${cloudfoundry_service_key.contact_list_key.credentials.access_key_id}
CONTACT_AWS_SECRET_ACCESS_KEY=${cloudfoundry_service_key.contact_list_key.credentials.secret_access_key}
CONTACT_AWS_REGION=${cloudfoundry_service_key.contact_list_key.credentials.region}
# SES_EMAIL # SES_EMAIL
SES_AWS_ACCESS_KEY_ID=${cloudfoundry_service_key.ses_key.credentials.smtp_user} SES_AWS_ACCESS_KEY_ID=${cloudfoundry_service_key.ses_key.credentials.smtp_user}
SES_AWS_SECRET_ACCESS_KEY=${cloudfoundry_service_key.ses_key.credentials.secret_access_key} SES_AWS_SECRET_ACCESS_KEY=${cloudfoundry_service_key.ses_key.credentials.secret_access_key}

View File

@@ -35,15 +35,6 @@ module "csv_upload_bucket" {
name = "${local.app_name}-csv-upload-bucket-${local.env}" name = "${local.app_name}-csv-upload-bucket-${local.env}"
} }
module "contact_list_bucket" {
source = "github.com/18f/terraform-cloudgov//s3?ref=v0.2.0"
cf_org_name = local.cf_org_name
cf_space_name = local.cf_space_name
recursive_delete = local.recursive_delete
name = "${local.app_name}-contact-list-bucket-${local.env}"
}
module "egress-space" { module "egress-space" {
source = "../shared/egress_space" source = "../shared/egress_space"

View File

@@ -35,15 +35,6 @@ module "csv_upload_bucket" {
name = "${local.app_name}-csv-upload-bucket-${local.env}" name = "${local.app_name}-csv-upload-bucket-${local.env}"
} }
module "contact_list_bucket" {
source = "github.com/18f/terraform-cloudgov//s3?ref=v0.2.0"
cf_org_name = local.cf_org_name
cf_space_name = local.cf_space_name
recursive_delete = local.recursive_delete
name = "${local.app_name}-contact-list-bucket-${local.env}"
}
module "egress-space" { module "egress-space" {
source = "../shared/egress_space" source = "../shared/egress_space"

View File

@@ -35,15 +35,6 @@ module "csv_upload_bucket" {
name = "${local.app_name}-csv-upload-bucket-${local.env}" name = "${local.app_name}-csv-upload-bucket-${local.env}"
} }
module "contact_list_bucket" {
source = "github.com/18f/terraform-cloudgov//s3?ref=v0.2.0"
cf_org_name = local.cf_org_name
cf_space_name = local.cf_space_name
recursive_delete = local.recursive_delete
name = "${local.app_name}-contact-list-bucket-${local.env}"
}
module "egress-space" { module "egress-space" {
source = "../shared/egress_space" source = "../shared/egress_space"

View File

@@ -23,7 +23,6 @@ from tests.app.db import (
create_job, create_job,
create_notification, create_notification,
create_service, create_service,
create_service_contact_list,
create_template, create_template,
) )
@@ -165,26 +164,6 @@ def test_get_jobs_for_service_in_processed_at_then_created_at_order(notify_db_se
assert jobs[index].id == created_jobs[index].id assert jobs[index].id == created_jobs[index].id
def test_get_jobs_for_service_by_contact_list(sample_template):
contact_list = create_service_contact_list()
job_1 = create_job(sample_template)
job_2 = create_job(sample_template, contact_list_id=contact_list.id)
assert dao_get_jobs_by_service_id(
sample_template.service.id
).items == [
job_2,
job_1,
]
assert dao_get_jobs_by_service_id(
sample_template.service.id,
contact_list_id=contact_list.id,
).items == [
job_2,
]
def test_update_job(sample_job): def test_update_job(sample_job):
assert sample_job.job_status == 'pending' assert sample_job.job_status == 'pending'

View File

@@ -1,15 +0,0 @@
from app.dao.service_contact_list_dao import dao_get_contact_lists
from tests.app.db import create_service_contact_list
def test_dao_get_contact_lists(notify_db_session):
contact_list = create_service_contact_list()
create_service_contact_list(
service=contact_list.service,
archived=True,
)
fetched_list = dao_get_contact_lists(contact_list.service_id)
assert len(fetched_list) == 1
assert fetched_list[0] == contact_list

View File

@@ -9,7 +9,6 @@ from tests.app.db import (
create_job, create_job,
create_notification, create_notification,
create_service, create_service,
create_service_contact_list,
create_service_data_retention, create_service_data_retention,
create_template, create_template,
) )
@@ -43,9 +42,6 @@ def create_uploaded_template(service):
@freeze_time("2020-02-02 09:00") # GMT time @freeze_time("2020-02-02 09:00") # GMT time
def test_get_uploads_for_service(sample_template): def test_get_uploads_for_service(sample_template):
create_service_data_retention(sample_template.service, 'sms', days_of_retention=9) create_service_data_retention(sample_template.service, 'sms', days_of_retention=9)
contact_list = create_service_contact_list()
# Jobs created from contact lists should be filtered out
create_job(sample_template, contact_list_id=contact_list.id)
job = create_job(sample_template, processing_started=datetime.utcnow()) job = create_job(sample_template, processing_started=datetime.utcnow())
letter_template = create_uploaded_template(sample_template.service) letter_template = create_uploaded_template(sample_template.service)
letter = create_uploaded_letter(letter_template, sample_template.service) letter = create_uploaded_letter(letter_template, sample_template.service)

View File

@@ -51,7 +51,6 @@ from app.models import (
Rate, Rate,
Service, Service,
ServiceCallbackApi, ServiceCallbackApi,
ServiceContactList,
ServiceEmailReplyTo, ServiceEmailReplyTo,
ServiceGuestList, ServiceGuestList,
ServiceInboundApi, ServiceInboundApi,
@@ -376,7 +375,6 @@ def create_job(
processing_finished=None, processing_finished=None,
original_file_name='some.csv', original_file_name='some.csv',
archived=False, archived=False,
contact_list_id=None,
): ):
data = { data = {
'id': uuid.uuid4(), 'id': uuid.uuid4(),
@@ -393,7 +391,6 @@ def create_job(
'processing_started': processing_started, 'processing_started': processing_started,
'processing_finished': processing_finished, 'processing_finished': processing_finished,
'archived': archived, 'archived': archived,
'contact_list_id': contact_list_id,
} }
job = Job(**data) job = Job(**data)
dao_create_job(job) dao_create_job(job)
@@ -944,31 +941,6 @@ def set_up_usage_data(start_date):
} }
def create_service_contact_list(
service=None,
original_file_name='EmergencyContactList.xls',
row_count=100,
template_type='email',
created_by_id=None,
archived=False,
):
if not service:
service = create_service(service_name='service for contact list', user=create_user())
contact_list = ServiceContactList(
service_id=service.id,
original_file_name=original_file_name,
row_count=row_count,
template_type=template_type,
created_by_id=created_by_id or service.users[0].id,
created_at=datetime.utcnow(),
archived=archived,
)
db.session.add(contact_list)
db.session.commit()
return contact_list
def create_webauthn_credential( def create_webauthn_credential(
user, user,
name='my key', name='my key',

View File

@@ -16,7 +16,6 @@ from tests.app.db import (
create_job, create_job,
create_notification, create_notification,
create_service, create_service,
create_service_contact_list,
create_template, create_template,
) )
from tests.conftest import set_config from tests.conftest import set_config
@@ -186,39 +185,6 @@ def test_create_scheduled_job(client, sample_template, mocker, fake_uuid):
assert resp_json['data']['notification_count'] == 1 assert resp_json['data']['notification_count'] == 1
@pytest.mark.parametrize('contact_list_archived', (
True, False,
))
def test_create_job_with_contact_list_id(
client,
mocker,
sample_template,
fake_uuid,
contact_list_archived,
):
mocker.patch('app.celery.tasks.process_job.apply_async')
mocker.patch('app.job.rest.get_job_metadata_from_s3', return_value={
'template_id': str(sample_template.id)
})
contact_list = create_service_contact_list(archived=contact_list_archived)
data = {
'id': fake_uuid,
'valid': 'True',
'original_file_name': contact_list.original_file_name,
'created_by': str(sample_template.service.users[0].id),
'notification_count': 100,
'contact_list_id': str(contact_list.id),
}
response = client.post(
f'/service/{sample_template.service_id}/job',
data=json.dumps(data),
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()])
resp_json = response.get_json()
assert response.status_code == 201
assert resp_json['data']['contact_list_id'] == str(contact_list.id)
assert resp_json['data']['original_file_name'] == 'EmergencyContactList.xls'
def test_create_job_returns_403_if_service_is_not_active(client, fake_uuid, sample_service, mocker): def test_create_job_returns_403_if_service_is_not_active(client, fake_uuid, sample_service, mocker):
sample_service.active = False sample_service.active = False
mock_job_dao = mocker.patch("app.dao.jobs_dao.dao_create_job") mock_job_dao = mocker.patch("app.dao.jobs_dao.dao_create_job")
@@ -645,7 +611,6 @@ def test_get_jobs(admin_request, sample_template):
'template_type': 'sms', 'template_type': 'sms',
'template_version': 1, 'template_version': 1,
'updated_at': None, 'updated_at': None,
'contact_list_id': None
} }
@@ -664,20 +629,6 @@ def test_get_jobs_with_limit_days(admin_request, sample_template):
assert len(resp_json['data']) == 2 assert len(resp_json['data']) == 2
def test_get_jobs_by_contact_list(admin_request, sample_template):
contact_list = create_service_contact_list()
create_job(template=sample_template)
create_job(template=sample_template, contact_list_id=contact_list.id)
resp_json = admin_request.get(
'job.get_jobs_by_service',
service_id=sample_template.service_id,
contact_list_id=contact_list.id,
)
assert len(resp_json['data']) == 1
def test_get_jobs_should_return_statistics(admin_request, sample_template): def test_get_jobs_should_return_statistics(admin_request, sample_template):
now = datetime.utcnow() now = datetime.utcnow()
earlier = datetime.utcnow() - timedelta(days=1) earlier = datetime.utcnow() - timedelta(days=1)

View File

@@ -1,258 +0,0 @@
import uuid
from datetime import datetime, timedelta
import pytest
from freezegun import freeze_time
from app.models import ServiceContactList
from tests.app.db import (
create_job,
create_service,
create_service_contact_list,
create_service_data_retention,
create_template,
)
def test_create_service_contact_list(sample_service, admin_request):
data = {
"id": str(uuid.uuid4()),
"row_count": 100,
"original_file_name": "staff_emergency_list.xls",
"template_type": 'email',
"created_by": str(sample_service.users[0].id)
}
response = admin_request.post(
'service.create_contact_list',
_data=data,
service_id=sample_service.id,
_expected_status=201
)
assert response['id'] == data['id']
assert response['original_file_name'] == 'staff_emergency_list.xls'
assert response['row_count'] == 100
assert response['template_type'] == 'email'
assert response['service_id'] == str(sample_service.id)
assert response['created_at']
db_results = ServiceContactList.query.all()
assert len(db_results) == 1
assert str(db_results[0].id) == data['id']
def test_create_service_contact_list_cannot_save_type_letter(sample_service, admin_request):
data = {
"id": str(uuid.uuid4()),
"row_count": 100,
"original_file_name": "staff_emergency_list.xls",
"template_type": 'letter',
"created_by": str(sample_service.users[0].id)
}
response = admin_request.post(
'service.create_contact_list',
_data=data,
service_id=sample_service.id,
_expected_status=400
)
assert response['errors'][0]['message'] == "template_type letter is not one of [email, sms]"
@freeze_time('2020-06-06 12:00')
def test_get_contact_list(admin_request, notify_db_session):
contact_list = create_service_contact_list()
response = admin_request.get(
'service.get_contact_list',
service_id=contact_list.service_id
)
assert len(response) == 1
assert response[0] == contact_list.serialize()
assert response[0]['recent_job_count'] == 0
assert response[0]['created_at'] == '2020-06-06T12:00:00.000000Z'
@pytest.mark.parametrize('days_of_email_retention, expected_job_count', (
(None, 8),
(7, 8),
(3, 4),
))
def test_get_contact_list_counts_jobs(
sample_template,
admin_request,
days_of_email_retention,
expected_job_count,
):
if days_of_email_retention:
create_service_data_retention(sample_template.service, 'email', days_of_email_retention)
# This should be ignored because its another template type
create_service_data_retention(sample_template.service, 'sms', 1)
contact_list_1 = create_service_contact_list(service=sample_template.service)
contact_list_2 = create_service_contact_list(service=sample_template.service)
for i in range(10):
create_job(
template=sample_template,
contact_list_id=contact_list_2.id,
created_at=datetime.utcnow() - timedelta(days=i)
)
response = admin_request.get(
'service.get_contact_list',
service_id=contact_list_1.service_id
)
assert len(response) == 2
assert response[0]['id'] == str(contact_list_2.id)
assert response[0]['recent_job_count'] == expected_job_count
assert response[0]['has_jobs'] is True
assert response[1]['id'] == str(contact_list_1.id)
assert response[1]['recent_job_count'] == 0
assert response[1]['has_jobs'] is False
def test_get_contact_list_returns_for_service(admin_request, notify_db_session):
service_1 = create_service(service_name='Service under test')
service_2 = create_service(service_name='Service should return results')
expected_list_1 = create_service_contact_list(service=service_1)
expected_list_2 = create_service_contact_list(service=service_1)
# not included in results
create_service_contact_list(service=service_2)
create_service_contact_list(service=service_1, archived=True)
response = admin_request.get(
'service.get_contact_list',
service_id=service_1.id
)
assert len(response) == 2
assert response[0] == expected_list_2.serialize()
assert response[1] == expected_list_1.serialize()
def test_dao_get_contact_list_by_id(admin_request, sample_service):
service_1 = create_service(service_name='Service under test')
expected_list_1 = create_service_contact_list(service=service_1)
create_service_contact_list(service=service_1)
response = admin_request.get(
'service.get_contact_list_by_id',
service_id=service_1.id,
contact_list_id=expected_list_1.id
)
assert response == expected_list_1.serialize()
def test_dao_get_archived_contact_list_by_id(admin_request):
contact_list = create_service_contact_list(archived=True)
admin_request.get(
'service.get_contact_list_by_id',
service_id=contact_list.service.id,
contact_list_id=contact_list.id,
_expected_status=404,
)
def test_dao_get_contact_list_by_id_does_not_return_if_contact_list_id_for_another_service(
admin_request, sample_service
):
service_1 = create_service(service_name='Service requesting list')
service_2 = create_service(service_name='Service that owns the list')
create_service_contact_list(service=service_1)
list_2 = create_service_contact_list(service=service_2)
response = admin_request.get(
'service.get_contact_list_by_id',
service_id=service_1.id,
contact_list_id=list_2.id,
_expected_status=404
)
assert response['message'] == "No result found"
def test_archive_contact_list_by_id(mocker, admin_request, sample_service):
mock_s3 = mocker.patch('app.service.rest.s3.remove_contact_list_from_s3')
service_1 = create_service(service_name='Service under test')
template_1 = create_template(service=service_1)
expected_list = create_service_contact_list(service=service_1)
other_list = create_service_contact_list(service=service_1)
# Job linked to the contact list were deleting
job_1 = create_job(template=template_1, contact_list_id=expected_list.id)
# Other jobs and lists shouldnt be affected
job_2 = create_job(template=template_1, contact_list_id=other_list.id)
job_3 = create_job(template=template_1)
admin_request.delete(
'service.delete_contact_list_by_id',
service_id=service_1.id,
contact_list_id=expected_list.id,
)
assert job_1.contact_list_id == expected_list.id
assert expected_list.archived is True
assert job_2.contact_list_id == other_list.id
assert other_list.archived is False
assert job_3.contact_list_id is None
mock_s3.assert_called_once_with(
expected_list.service.id,
expected_list.id,
)
def test_archive_contact_list_when_unused(mocker, admin_request, sample_service):
mock_s3 = mocker.patch('app.service.rest.s3.remove_contact_list_from_s3')
service = create_service(service_name='Service under test')
expected_list = create_service_contact_list(service=service)
assert ServiceContactList.query.count() == 1
admin_request.delete(
'service.delete_contact_list_by_id',
service_id=service.id,
contact_list_id=expected_list.id
)
assert ServiceContactList.query.count() == 1
assert expected_list.archived is True
mock_s3.assert_called_once_with(
expected_list.service.id,
expected_list.id,
)
def test_archive_contact_list_by_id_for_different_service(mocker, admin_request, sample_service):
mock_s3 = mocker.patch('app.service.rest.s3.remove_contact_list_from_s3')
service_1 = create_service(service_name='Service under test')
service_2 = create_service(service_name='Other service')
contact_list = create_service_contact_list(service=service_1)
assert ServiceContactList.query.count() == 1
admin_request.delete(
'service.delete_contact_list_by_id',
service_id=service_2.id,
contact_list_id=contact_list.id,
_expected_status=404,
)
assert ServiceContactList.query.count() == 1
assert mock_s3.called is False