diff --git a/tests/README.md b/tests/README.md index 22188c89ed..fdf24282c3 100644 --- a/tests/README.md +++ b/tests/README.md @@ -10,9 +10,8 @@ The docker-compose command used to run the full test suite sets environment vari 1. Stop all running containers associated with Notification-api. 2. Start the Postgres (ci_db_1) container, and any other containers required by the functionality under test: `docker start ci-db-1`. All migrations should already be applied. -3. Start a test container shell by running `docker run --rm -it -v "$(pwd):/app" --env-file tests/env_vars --name ci-test ci-test bash`. -4. Add the test container started in the previous step to the default network: `docker network connect ci_default ci-test`. -5. In the test container shell, run `pytest -h` to see the syntax for running tests. Without flags, you can run `pytest [file or directory]...`. +3. Start a test container shell by running `docker run --rm -it -v "$(pwd):/app" --env-file tests/env_vars --name ci-test --network ci_default ci-test bash`. +4. In the test container shell, run `pytest -h` to see the syntax for running tests. Without flags, you can run `pytest [file or directory]...`. ## Running Individual Tests diff --git a/tests/app/celery/test_process_delivery_status_result_tasks.py b/tests/app/celery/test_process_delivery_status_result_tasks.py index d11bf0c5b6..f077119e60 100644 --- a/tests/app/celery/test_process_delivery_status_result_tasks.py +++ b/tests/app/celery/test_process_delivery_status_result_tasks.py @@ -10,15 +10,6 @@ from app.models import Notification -@pytest.fixture -def sample_translate_return_value(): - return { - 'payload': 'eyJhcmdzIjogW3siTWVzc2FnZSI6IHsiYm9keSI6ICJSYXdEbHJEb25lRGF0ZT0yMzAzMDkyMDI', - 'reference': 'MessageSID', - 'record_status': 'sent', - } - - @pytest.fixture def sample_delivery_status_result_message(): return { @@ -53,16 +44,6 @@ def sample_sqs_message_with_provider(): } -@pytest.fixture() -def sample_sqs_message_with_twilio_provider(): - return { - 'body': 'UmF3RGxyRG9uZURhdGU9MjMwMzIyMjMzOCZTbXNTaWQ9U014eHgmU21zU3RhdHVzPWRlbGl2ZXJlZCZNZXNzYWdlU3RhdHV' - 'zPWRlbGl2ZXJlZCZUbz0lMkIxMTExMTExMTExMSZNZXNzYWdlU2lkPVNNeXl5JkFjY291bnRTaWQ9QUN6enomRnJvbT0lMkIx' - 'MjIyMzMzNDQ0NCZBcGlWZXJzaW9uPTIwMTAtMDQtMDE=', - 'provider': 'twilio', - } - - @pytest.fixture() def sample_sqs_message_without_provider(): return { diff --git a/tests/app/celery/test_service_callback_tasks.py b/tests/app/celery/test_service_callback_tasks.py index 8b286b12a3..def91a4bbd 100644 --- a/tests/app/celery/test_service_callback_tasks.py +++ b/tests/app/celery/test_service_callback_tasks.py @@ -387,7 +387,7 @@ def _set_up_data_for_complaint(callback_api, complaint, notification): class TestSendInboundSmsToService: def test_post_https_request_to_service( - self, mocker, sample_inbound_sms, sample_service, sample_service_callback, sample_sms_sender_v2 + self, mocker, sample_inbound_sms, sample_service, sample_service_callback, sample_sms_sender ): service = sample_service() inbound_api = sample_service_callback( # nosec @@ -408,7 +408,7 @@ def test_post_https_request_to_service( provider_date=datetime(2017, 6, 20), content='Here is some content', ) - sms_sender = sample_sms_sender_v2(service_id=service.id, sms_sender='0751421') + sms_sender = sample_sms_sender(service_id=service.id, sms_sender='0751421') expected_data = { 'id': str(inbound_sms.id), diff --git a/tests/app/celery/test_tasks.py b/tests/app/celery/test_tasks.py index cffb94fd7d..177a4f52ec 100644 --- a/tests/app/celery/test_tasks.py +++ b/tests/app/celery/test_tasks.py @@ -404,18 +404,19 @@ def test_process_row_when_sender_id_is_provided(mocker, fake_uuid): def test_should_send_template_to_correct_sms_task_and_persist( - notify_db_session, sample_template_with_placeholders, mocker + notify_db_session, sample_service, sample_template, mocker ): - notification = _notification_json( - sample_template_with_placeholders, to='+1 650 253 2222', personalisation={'name': 'Jo'} - ) + service = sample_service() + template = sample_template(service=service) + + notification = _notification_json(template, to='+1 650 253 2222', personalisation={'name': 'Jo'}) mocked_deliver_sms = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') notification_id = uuid4() save_sms( - sample_template_with_placeholders.service_id, + template.service_id, notification_id, encryption.encrypt(notification), ) @@ -424,8 +425,8 @@ def test_should_send_template_to_correct_sms_task_and_persist( try: assert persisted_notification.to == '+1 650 253 2222' - assert persisted_notification.template_id == sample_template_with_placeholders.id - assert persisted_notification.template_version == sample_template_with_placeholders.version + assert persisted_notification.template_id == template.id + assert persisted_notification.template_version == template.version assert persisted_notification.status == 'created' assert persisted_notification.created_at <= datetime.utcnow() assert not persisted_notification.sent_at @@ -1106,13 +1107,13 @@ def test_save_sms_uses_sms_sender_reply_to_text(mocker, notify_db_session, sampl def test_save_sms_uses_non_default_sms_sender_reply_to_text_if_provided( - mocker, notify_db_session, sample_service, sample_template, sample_sms_sender_v2 + mocker, notify_db_session, sample_service, sample_template, sample_sms_sender ): mock_feature_flag(mocker, FeatureFlag.SMS_SENDER_RATE_LIMIT_ENABLED, 'True') service = sample_service(sms_sender='07123123123') template = sample_template(service=service) # new_sender = service_sms_sender_dao.dao_add_sms_sender_for_service(service.id, 'new-sender', False) - new_sender = sample_sms_sender_v2(service.id, sms_sender='new-sender', is_default=False) + new_sender = sample_sms_sender(service.id, sms_sender='new-sender', is_default=False) sms_sender = mocker.Mock() sms_sender.rate_limit = 1 sms_sender.sms_sender = 'new-sender' diff --git a/tests/app/conftest.py b/tests/app/conftest.py index e8e418b273..d6e17b166b 100644 --- a/tests/app/conftest.py +++ b/tests/app/conftest.py @@ -9,14 +9,11 @@ from app.clients.sms import SmsClient from app.clients.sms.firetext import FiretextClient from app.dao.invited_user_dao import save_invited_user -from app.dao.jobs_dao import dao_create_job from app.dao.organisation_dao import dao_create_organisation, dao_add_service_to_organisation from app.dao.permissions_dao import default_service_permissions -from app.dao.provider_rates_dao import create_provider_rates from app.dao.service_data_retention_dao import insert_service_data_retention from app.dao.services_dao import DEFAULT_SERVICE_PERMISSIONS from app.dao.service_sms_sender_dao import ( - dao_add_sms_sender_for_service, dao_update_service_sms_sender, ) from app.dao.users_dao import create_secret_code, create_user_code @@ -63,7 +60,6 @@ Rate, SMS_TYPE, ScheduledNotification, - SERVICE_PERMISSION_TYPES, ServiceCallback, ServiceDataRetention, ServiceEmailReplyTo, @@ -83,23 +79,19 @@ UserServiceRoles, WEBHOOK_CHANNEL_TYPE, ) -from app.service.service_data import ServiceData from datetime import datetime, timedelta from flask import current_app, url_for from random import randint, randrange -from sqlalchemy import asc, delete, update, select, Table +from sqlalchemy import delete, update, select, Table from sqlalchemy.exc import SAWarning from sqlalchemy.orm import scoped_session from sqlalchemy.orm.session import make_transient from tests import create_admin_authorization_header from tests.app.db import ( create_api_key, - create_inbound_number, create_job, - create_letter_contact, create_notification, create_service, - create_template, create_user, version_api_key, version_service, @@ -137,40 +129,6 @@ def rmock(): yield rmock -@pytest.fixture(scope='function') -def service_factory(notify_db_session): - class ServiceFactory(object): - def get(self, service_name, user=None, template_type=None, email_from=None): - if not user: - user = create_user() - if not email_from: - email_from = service_name - - service = create_service( - email_from=email_from, - service_name=service_name, - service_permissions=None, - user=user, - check_if_service_exists=True, - ) - if template_type == EMAIL_TYPE: - create_template( - service, - template_name='Template Name', - template_type=template_type, - subject=service.email_from, - ) - else: - create_template( - service, - template_name='Template Name', - template_type='sms', - ) - return service - - return ServiceFactory() - - @pytest.fixture def set_user_as_admin(notify_db_session): def _wrapper(user: User) -> User: @@ -185,9 +143,32 @@ def _wrapper(user: User) -> User: def sample_user(notify_db_session, set_user_as_admin) -> User: created_user_ids = [] - def _sample_user(*args, platform_admin=False, **kwargs): + def _wrapper( + blocked=False, + check_if_user_exists=False, + email=None, + identity_provider_user_id=None, + idp_id=None, + idp_name=None, + mobile_number='+16502532222', + name='Test User', + platform_admin=False, + state='active', + user_id=None, + ): # Cannot set platform admin when creating a user (schema) - user = create_user(*args, **kwargs) + user = create_user( + blocked=blocked, + check_if_user_exists=check_if_user_exists, + email=email, + identity_provider_user_id=identity_provider_user_id, + idp_id=idp_id, + idp_name=idp_name, + mobile_number=mobile_number, + name=name, + state=state, + user_id=user_id, + ) if platform_admin: user = set_user_as_admin(user) @@ -195,7 +176,7 @@ def _sample_user(*args, platform_admin=False, **kwargs): return user - yield _sample_user + yield _wrapper # Teardown cleanup_user(created_user_ids, notify_db_session.session) @@ -316,14 +297,6 @@ def sample_service_role_udpated(notify_db_session, sample_service): yield user_service_role -@pytest.fixture -def notify_user(sample_user, worker_id): - return sample_user( - email=f'notify-service-user-{worker_id}@digital.cabinet-office.gov.uk', - user_id=current_app.config['NOTIFY_USER_ID'], - ) - - @pytest.fixture def sample_domain(notify_db_session): domain_domains = [] @@ -354,20 +327,6 @@ def create_code(notify_db_session, code_type, usr=None, code=None): return create_user_code(usr, code, code_type), code -@pytest.fixture(scope='function') -def sample_email_code(notify_db, notify_db_session, code=None, code_type='email', usr=None): - code, txt_code = create_code(notify_db, notify_db_session, code_type, usr=usr, code=code) - code.txt_code = txt_code - return code - - -@pytest.fixture(scope='function') -def sample_sms_code(notify_db, notify_db_session, code=None, code_type='sms', usr=None): - code, txt_code = create_code(notify_db, notify_db_session, code_type, usr=usr, code=code) - code.txt_code = txt_code - return code - - def create_user_model( mobile_number='+16502532222', email='notify@notify.va.gov', @@ -459,8 +418,6 @@ def create_template_model( @pytest.fixture(scope='function') def sample_notification_model_with_organization( - notify_db, - notify_db_session, service=None, template=None, job=None, @@ -531,34 +488,66 @@ def sample_service( sample_user, sample_permissions, sample_service_permissions, - sample_sms_sender_v2, + sample_sms_sender, sample_service_email_reply_to, ): created_service_ids = [] - def _sample_service(*args, **kwargs): + def _sample_service( + active=True, + check_if_service_exists=False, + count_as_live=True, + crown=True, + email_address='', + email_from='', + go_live_at=None, + go_live_user=None, + message_limit=1000, + organisation=None, + organisation_type='other', + prefix_sms=False, + research_mode=False, + restricted=False, + service_id=None, + service_name=None, + service_permissions=DEFAULT_SERVICE_PERMISSIONS, + sms_sender=None, + smtp_user=None, + user=None, + ): # Handle where they are checking if it exists by name - if kwargs.pop('check_if_service_exists', False) and 'service_name' in kwargs: - service = notify_db_session.session.scalar(select(Service).where(Service.name == kwargs['service_name'])) - if service is not None: - return service + if check_if_service_exists and service_name is not None: + stmt = select(Service).where(Service.name == service_name) + service = notify_db_session.session.scalar(stmt) + return service # We do not want create_service to create users because it does not clean them up. - if len(args) == 0 and 'user' not in kwargs: - kwargs['user'] = sample_user(email=f'sample_service_{uuid4()}@va.gov') - - # Remove things that Service does not expect. - service_permissions = kwargs.pop('service_permissions', DEFAULT_SERVICE_PERMISSIONS) - user = kwargs.pop('user') - sms_sender = kwargs.pop('sms_sender', None) - email_address = kwargs.pop('email_address', '') + if user is None: + user = sample_user(email=f'sample_service_{uuid4()}@va.gov') - service: Service = sample_service_helper(user, *args, **kwargs) + service: Service = sample_service_helper( + user, + active=active, + count_as_live=count_as_live, + crown=crown, + email_from=email_from, + go_live_at=go_live_at, + go_live_user=go_live_user, + message_limit=message_limit, + organisation=organisation, + organisation_type=organisation_type, + prefix_sms=prefix_sms, + research_mode=research_mode, + restricted=restricted, + service_id=service_id, + service_name=service_name, + smtp_user=smtp_user, + ) service.users.append(user) sample_service_permissions(service, service_permissions) sample_permissions(user, service) - sample_sms_sender_v2(service.id, sms_sender) + sample_sms_sender(service.id, sms_sender) if email_address is not None: sample_service_email_reply_to(service, email_address=email_address) # Service should be version 1 in the history after calling this @@ -574,20 +563,20 @@ def _sample_service(*args, **kwargs): def sample_service_helper( user, - service_name=None, - service_id=None, - restricted=False, - count_as_live=True, - research_mode=False, active=True, + count_as_live=True, + crown=True, email_from='', - prefix_sms=False, - message_limit=1000, - organisation_type='other', - go_live_user=None, go_live_at=None, - crown=True, + go_live_user=None, + message_limit=1000, organisation=None, + organisation_type='other', + prefix_sms=False, + research_mode=False, + restricted=False, + service_id=None, + service_name=None, smtp_user=None, ): service_name = service_name or f'sample service {uuid4()}' @@ -736,37 +725,6 @@ def _wrapper(user, service, permissions=default_service_permissions): notify_db_session.session.commit() -@pytest.fixture -def sample_service_full_permissions(notify_db_session, sample_service): - service = sample_service( - service_name=f'sample service full permissions {uuid4()}', - service_permissions=set(SERVICE_PERMISSION_TYPES), - check_if_service_exists=True, - ) - - # The inbound number is a unique, non-nullable 12-digit string. With tests running - # in parallel, this could result in a collision, although that's unlikely. - number = str(randint(100000000000, 999999999999)) - inbound_number = create_inbound_number(number, service_id=service.id) - - yield service - - # Teardown - notify_db_session.session.delete(inbound_number) - notify_db_session.session.commit() - - -@pytest.fixture(scope='function', name='sample_service_custom_letter_contact_block') -def _sample_service_custom_letter_contact_block(sample_service): - create_letter_contact(sample_service, contact_block='((contact block))') - return sample_service - - -@pytest.fixture(scope='function') -def sample_service_data(sample_service): - return ServiceData(sample_service) - - def sample_template_helper( name, template_type, @@ -822,24 +780,59 @@ def sample_template( ): template_ids = [] - def _sample_template(*args, **kwargs): - assert len(args) == 0, 'sample_template method does not accept positional arguments' + def _sample_template( + archived=False, + communication_item_id=None, + content=None, + name=None, + folder=None, + hidden=False, + id=None, + postage=None, + process_type=NORMAL, + reply_to=None, + reply_to_email=None, + service=None, + subject=None, + template_type=SMS_TYPE, + user=None, + version=0, + ): # Mandatory arguments - ignore args - kwargs['name'] = kwargs.get('name', f'function template {uuid4()}') - kwargs['template_type'] = kwargs.get('template_type', SMS_TYPE) + if name is None: + name = f'function template {uuid4()}' # Using fixtures as defaults creates those objects! Do not make a fixture the default param - kwargs['user'] = kwargs.get('user') or sample_user() - kwargs['service'] = kwargs.get('service') or sample_service() + if user is None: + user = sample_user() - if 'subject' in kwargs: - kwargs['subject_line'] = kwargs.pop('subject') - kwargs['communication_item_id'] = kwargs.get('communication_item_id', sample_communication_item().id) + if service is None: + service = sample_service() - template_data = sample_template_helper(*args, **kwargs) + if communication_item_id is None: + communication_item_id = sample_communication_item().id - if kwargs['template_type'] == LETTER_TYPE: - template_data['postage'] = kwargs.get('postage', 'second') + template_data = sample_template_helper( + name, + template_type, + service, + user, + archived=archived, + content=content, + folder=folder, + hidden=hidden, + postage=postage, + subject_line=subject, + reply_to=reply_to, + reply_to_email=reply_to_email, + process_type=process_type, + version=version, + id=id, + communication_item_id=communication_item_id, + ) + + if template_type == LETTER_TYPE: + template_data['postage'] = postage or 'second' # Create template object and put it in the DB template_dao = Template(**template_data) @@ -929,189 +922,9 @@ def template_folder_cleanup( @pytest.fixture -def sample_sms_template_func(notify_db_session, sample_service, sample_user): - """ - Use this function-scoped SMS template for tests that don't need to modify the template. - """ - - template_data = sample_template_helper( - f'function sms template {uuid4()}', SMS_TYPE, sample_service(), sample_user() - ) - template = Template(**template_data) - dao_create_template(template) - - yield template - - # Teardown - template_history = notify_db_session.session.get(TemplateHistory, (template.id, template.version)) - notify_db_session.session.delete(template_history) - template_redacted = notify_db_session.session.get(TemplateRedacted, template.id) - notify_db_session.session.delete(template_redacted) - notify_db_session.session.delete(template) - notify_db_session.session.commit() - - -@pytest.fixture(scope='session') -def sample_sms_template(notify_db, sample_service, sample_user, worker_id): - """ - Use this session-scoped SMS template for tests that don't need to modify the template. - """ - - template_data = sample_template_helper(f'session sms template {worker_id}', SMS_TYPE, sample_service, sample_user) - template = Template(**template_data) - notify_db.session.add(template) - notify_db.session.commit() - - yield template - - notify_db.session.delete(template) - notify_db.session.commit() - - -@pytest.fixture(scope='session') -def sample_sms_template_history(notify_db, sample_service, sample_user, worker_id): - """ - Use this session-scoped SMS TemplateHistory for tests that don't need to modify templates. - Create a template history instance for any template instance used to create a Notification instance. - Otherwise, attempting to create a Notification will lead to an InegrityError. - - Note that Notification instances have foreign keys to TemplateHistory instances rather than - Template instances. - """ - - template_data = sample_template_helper( - f'session sms template history {worker_id}', SMS_TYPE, sample_service, sample_user - ) - template_history = TemplateHistory(**template_data) - notify_db.session.add(template_history) - notify_db.session.commit() - - yield template_history - - notify_db.session.delete(template_history) - notify_db.session.commit() - - -@pytest.fixture -def sample_email_template_func(notify_db_session, sample_service, sample_user): - """ - Use this function-scoped e-mail template for tests that don't need to modify the template. - """ - - template_data = sample_template_helper( - f'function e-mail template {uuid4()}', EMAIL_TYPE, sample_service(), sample_user() - ) - template = Template(**template_data) - dao_create_template(template) - - yield template - - # Teardown - template_history = notify_db_session.session.get(TemplateHistory, (template.id, template.version)) - notify_db_session.session.delete(template_history) - template_redacted = notify_db_session.session.get(TemplateRedacted, template.id) - notify_db_session.session.delete(template_redacted) - notify_db_session.session.delete(template) - notify_db_session.session.commit() - - -@pytest.fixture(scope='session') -def sample_email_template(notify_db, sample_service, sample_user, worker_id): - """ - Use this session-scoped e-mail template for tests that don't need to modify the template. - """ - - template_data = sample_template_helper( - f'session e-mail template {worker_id}', EMAIL_TYPE, sample_service, sample_user - ) - template = Template(**template_data) - notify_db.session.add(template) - notify_db.session.commit() - - yield template - - notify_db.session.delete(template) - notify_db.session.commit() - - -@pytest.fixture -def sample_email_template_history(notify_db, sample_service, sample_user, worker_id): - """ - Use this e-mail TemplateHistory for tests that don't need to modify templates. - Create a template history instance for any template instance used to create a Notification instance. - Otherwise, attempting to create a Notification will lead to an InegrityError. - - Note that Notification instances have foreign keys to TemplateHistory instances rather than - Template instances. - """ - - templates = [] - template_data = sample_template_helper( - f'session e-mail template history {worker_id}', EMAIL_TYPE, sample_service(), sample_user() - ) - template_history = TemplateHistory(**template_data) - notify_db.session.add(template_history) - notify_db.session.commit() - templates.append(template_history) - - yield template_history - - for template in templates: - notify_db.session.delete(template) - notify_db.session.commit() - - -@pytest.fixture -def sample_template_without_sms_permission(notify_db_session, sample_service, sample_template): - service = sample_service(service_permissions=[EMAIL_TYPE], check_if_service_exists=True) - template = sample_template(service=service, template_type=SMS_TYPE) - yield template - - # Teardown - template_history = notify_db_session.session.get(TemplateHistory, (template.id, template.version)) - notify_db_session.session.delete(template_history) - - template_redacted = notify_db_session.session.get(TemplateRedacted, template.id) - notify_db_session.session.delete(template_redacted) - notify_db_session.session.delete(template) - notify_db_session.session.commit() - - -@pytest.fixture -def sample_template_with_placeholders(sample_template): - return sample_template(content='Hello (( Name))\nYour thing is due soon') - - -@pytest.fixture -def sample_sms_template_with_html(sample_service, sample_template): - # deliberate space and title case in placeholder - sample_service.prefix_sms = True - return sample_template(sample_service, content='Hello (( Name))\nHere is some HTML & entities') - - -@pytest.fixture -def sample_template_without_email_permission(sample_service, sample_template): - service = sample_service(service_permissions=[SMS_TYPE], check_if_service_exists=True) - return sample_template(service=service, template_type=EMAIL_TYPE) - - -@pytest.fixture -def other_sample_template(notify_db_session): - service = create_service( - service_permissions=[SMS_TYPE], service_name='OTHER_SMS_SERVICE', check_if_service_exists=False - ) - return create_template(service, template_type=SMS_TYPE, template_name='OTHER_SMS_TEMLATE') - - -@pytest.fixture -def sample_letter_template(sample_service_full_permissions, sample_template): - return sample_template(service=sample_service_full_permissions, template_type=LETTER_TYPE, postage='second') - - -@pytest.fixture -def sample_trial_letter_template(sample_service_full_permissions, sample_template): - sample_service_full_permissions.restricted = True - return sample_template(service=sample_service_full_permissions, template_type=LETTER_TYPE) +def sample_letter_template(sample_service, sample_template): + service = sample_service(service_permissions=[LETTER_TYPE]) + return sample_template(service=service, template_type=LETTER_TYPE, postage='second') @pytest.fixture @@ -1123,35 +936,6 @@ def sample_email_template_with_placeholders(sample_template): ) -@pytest.fixture -def sample_email_template_with_reply_to(sample_template): - return sample_template( - template_type=EMAIL_TYPE, - subject='((name))', - content='Hello ((name))\nThis is an email from GOV.UK', - reply_to_email='testing@email.com', - ) - - -@pytest.fixture -def sample_email_template_with_html(sample_template): - return sample_template( - template_type=EMAIL_TYPE, - subject='((name)) some HTML', - content='Hello ((name))\nThis is an email from GOV.UK with some HTML', - ) - - -@pytest.fixture -def sample_email_template_with_onsite_true(sample_template): - return sample_template( - template_type=EMAIL_TYPE, - subject='((name))', - content='Hello ((name))\nThis is an email from GOV.UK', - onsite_notification=True, - ) - - @pytest.fixture def sample_api_key(notify_db_session, sample_service): created_key_ids = [] @@ -1227,65 +1011,14 @@ def _sample_job(template, **kwargs): @pytest.fixture -def email_job_with_placeholders(sample_job, sample_email_template_with_placeholders): - return sample_job(sample_email_template_with_placeholders) - - -@pytest.fixture -def sample_job_with_placeholdered_template(sample_job, sample_template_with_placeholders): - return sample_job(sample_template_with_placeholders) - - -@pytest.fixture -def sample_scheduled_job(sample_job, sample_template_with_placeholders): +def sample_scheduled_job(sample_job, sample_template): return sample_job( - sample_template_with_placeholders, + sample_template(content='Hello (( Name))\nYour thing is due soon'), job_status=JOB_STATUS_SCHEDULED, scheduled_for=(datetime.utcnow() + timedelta(minutes=60)).isoformat(), ) -@pytest.fixture -def sample_email_job(notify_db, notify_db_session, service=None, template=None): - if service is None: - service = create_service(check_if_service_exists=True) - if template is None: - template = sample_email_template_func(notify_db, notify_db_session, service=service) - job_id = uuid4() - data = { - 'id': job_id, - 'service_id': service.id, - 'service': service, - 'template_id': template.id, - 'template_version': template.version, - 'original_file_name': 'some.csv', - 'notification_count': 1, - 'created_by': service.created_by, - } - job = Job(**data) - dao_create_job(job) - return job - - -@pytest.fixture -def sample_letter_job(sample_letter_template): - service = sample_letter_template.service - data = { - 'id': uuid4(), - 'service_id': service.id, - 'service': service, - 'template_id': sample_letter_template.id, - 'template_version': sample_letter_template.version, - 'original_file_name': 'some.csv', - 'notification_count': 1, - 'created_at': datetime.utcnow(), - 'created_by': service.created_by, - } - job = Job(**data) - dao_create_job(job) - return job - - @pytest.fixture def sample_annual_billing( notify_db_session, @@ -1717,20 +1450,6 @@ def _sample_notification(*args, gen_type: str = SMS_TYPE, **kwargs): notify_db_session.session.commit() -@pytest.fixture -def sample_letter_notification(sample_letter_template, sample_notification): - address = { - 'address_line_1': 'A1', - 'address_line_2': 'A2', - 'address_line_3': 'A3', - 'address_line_4': 'A4', - 'address_line_5': 'A5', - 'address_line_6': 'A6', - 'postcode': 'A_POST', - } - return sample_notification(template=sample_letter_template, reference='foo', personalisation=address) - - @pytest.fixture def sample_email_notification(sample_template, sample_notification): template = sample_template(template_type=EMAIL_TYPE) @@ -1797,26 +1516,6 @@ def _sample_notification_history( notify_db_session.session.commit() -@pytest.fixture(scope='function') -def mock_celery_send_sms_code(mocker): - return mocker.patch('app.celery.tasks.send_sms_code.apply_async') - - -@pytest.fixture(scope='function') -def mock_celery_email_registration_verification(mocker): - return mocker.patch('app.celery.tasks.email_registration_verification.apply_async') - - -@pytest.fixture(scope='function') -def mock_celery_send_email(mocker): - return mocker.patch('app.celery.tasks.send_email.apply_async') - - -@pytest.fixture(scope='function') -def mock_encryption(mocker): - return mocker.patch('app.encryption.encrypt', return_value='something_encrypted') - - @pytest.fixture def sample_invited_user(notify_db_session, sample_service): created_invited_user_ids = [] @@ -1885,30 +1584,6 @@ def _sample_invited_org_user(organisation=None, invited_by=None, email_address=f notify_db_session.session.commit() -@pytest.fixture -def sample_user_service_permission(notify_db_session, service=None, user=None, permission='manage_settings'): - if user is None: - user = create_user() - if service is None: - service = create_service(user=user, check_if_service_exists=True) - data = { - 'user': user, - 'service': service, - 'permission': permission, - } - - stmt = select(Permission).where( - Permission.user == user, Permission.service == service, Permission.permission == permission - ) - p_model = notify_db_session.session.scalars(stmt).first() - - if not p_model: - p_model = Permission(**data) - notify_db_session.session.add(p_model) - notify_db_session.session.commit() - return p_model - - @pytest.fixture(scope='function') def fake_uuid(): return '6ce466d0-fd6a-11e5-82f5-e0accb9d11a6' @@ -1922,16 +1597,6 @@ def fake_uuid_v2(): return uuid4() -@pytest.fixture -def current_sms_provider(notify_db_session): - stmt = ( - select(ProviderDetails) - .where(ProviderDetails.notification_type == 'sms') - .order_by(asc(ProviderDetails.priority)) - ) - return notify_db_session.session.scalars(stmt).first() - - @pytest.fixture def sample_provider(notify_db_session, worker_id): created_provider_ids = {worker_id: []} @@ -2006,23 +1671,6 @@ def _sample_provider( notify_db_session.session.commit() -@pytest.fixture -def ses_provider(notify_db_session): - stmt = select(ProviderDetails).where(ProviderDetails.identifier == 'ses') - return notify_db_session.session.scalars(stmt).one() - - -@pytest.fixture -def firetext_provider(notify_db_session): - stmt = select(ProviderDetails).where(ProviderDetails.identifier == 'firetext') - return notify_db_session.session.scalars(stmt).one() - - -@pytest.fixture -def mmg_provider(sample_provider): - return sample_provider(identifier=MMG_PROVIDER, get=True) - - @pytest.fixture(scope='function') def mock_firetext_client(mocker, statsd_client=None): client = FiretextClient() @@ -2034,171 +1682,6 @@ def mock_firetext_client(mocker, statsd_client=None): return client -@pytest.fixture -def email_verification_template( - notify_service, - sample_template, -): - service, user = notify_service - - return sample_template( - service=service, - user=user, - template_config_name='NEW_USER_EMAIL_VERIFICATION_TEMPLATE_ID', - content='((user_name)) use ((url)) to complete registration', - template_type=EMAIL_TYPE, - ) - - -@pytest.fixture -def invitation_email_template( - notify_service, - sample_template, -): - service, user = notify_service - content = ('((user_name)) is invited to Notify by ((service_name)) ((url)) to complete registration',) - - return sample_template( - service=service, - user=user, - template_config_name='INVITATION_EMAIL_TEMPLATE_ID', - content=content, - subject='Invitation to ((service_name))', - template_type=EMAIL_TYPE, - ) - - -@pytest.fixture -def org_invite_email_template(notify_service, sample_template): - service, user = notify_service - - return sample_template( - service=service, - user=user, - template_config_name='ORGANISATION_INVITATION_EMAIL_TEMPLATE_ID', - content='((user_name)) ((organisation_name)) ((url))', - subject='Invitation to ((organisation_name))', - template_type=EMAIL_TYPE, - ) - - -@pytest.fixture -def password_reset_email_template( - notify_service, - sample_template, -): - service, user = notify_service - - return sample_template( - service=service, - user=user, - template_config_name='PASSWORD_RESET_TEMPLATE_ID', - content='((user_name)) you can reset password by clicking ((url))', - subject='Reset your password', - template_type=EMAIL_TYPE, - ) - - -@pytest.fixture -def verify_reply_to_address_email_template(notify_service, sample_template): - service, user = notify_service - - return sample_template( - service=service, - user=user, - template_config_name='REPLY_TO_EMAIL_ADDRESS_VERIFICATION_TEMPLATE_ID', - content="Hi,This address has been provided as the reply-to email address so we are verifying if it's working", - subject='Your GOV.UK Notify reply-to email address', - template_type=EMAIL_TYPE, - ) - - -@pytest.fixture -def team_member_email_edit_template(notify_service, sample_template): - service, user = notify_service - - return sample_template( - service=service, - user=user, - template_config_name='TEAM_MEMBER_EDIT_EMAIL_TEMPLATE_ID', - content='Hi ((name)) ((servicemanagername)) changed your email to ((email address))', - subject='Your GOV.UK Notify email address has changed', - template_type=EMAIL_TYPE, - ) - - -@pytest.fixture -def team_member_mobile_edit_template(notify_service, sample_template): - service, user = notify_service - - return sample_template( - service=service, - user=user, - template_config_name='TEAM_MEMBER_EDIT_MOBILE_TEMPLATE_ID', - content='Your mobile number was changed by ((servicemanagername)).', - template_type='sms', - ) - - -@pytest.fixture -def already_registered_template( - notify_service, - sample_template, -): - service, user = notify_service - - content = ( - """Sign in here: ((signin_url)) If you’ve forgotten your password, """ - """you can reset it here: ((forgot_password_url)) feedback:((feedback_url))""" - ) - - return sample_template( - service=service, - user=user, - template_config_name='ALREADY_REGISTERED_EMAIL_TEMPLATE_ID', - content=content, - template_type=EMAIL_TYPE, - ) - - -@pytest.fixture -def contact_us_template( - notify_service, - sample_template, -): - service, user = notify_service - content = """User ((user)) sent the following message: ((message))""" - - return sample_template( - service=service, - user=user, - template_config_name='CONTACT_US_TEMPLATE_ID', - content=content, - template_type=EMAIL_TYPE, - ) - - -@pytest.fixture -def change_email_confirmation_template( - notify_service, - sample_template, -): - service, user = notify_service - content = """Hi ((name)), - Click this link to confirm your new email address: - ((url)) - If you didn’t try to change the email address for your GOV.UK Notify account, let us know here: - ((feedback_url))""" - - return sample_template( - service=service, - user=user, - template_config_name='CHANGE_EMAIL_CONFIRMATION_TEMPLATE_ID', - content=content, - template_type=EMAIL_TYPE, - ) - - @pytest.fixture def sample_smtp_template(sample_service, sample_template): def _wrapper(): @@ -2216,68 +1699,6 @@ def _wrapper(): yield _wrapper -@pytest.fixture(scope='function') -def mou_signed_templates(notify_db, notify_db_session): - service, user = notify_service(notify_db, notify_db_session) - import importlib - - alembic_script = importlib.import_module('migrations.versions.0298_add_mou_signed_receipt') - - return { - config_name: sample_template( - service, - user, - config_name, - EMAIL_TYPE, - content='\n'.join( - next(x for x in alembic_script.templates if x['id'] == current_app.config[config_name])['content_lines'] - ), - ) - for config_name in [ - 'MOU_SIGNER_RECEIPT_TEMPLATE_ID', - 'MOU_SIGNED_ON_BEHALF_SIGNER_RECEIPT_TEMPLATE_ID', - 'MOU_SIGNED_ON_BEHALF_ON_BEHALF_RECEIPT_TEMPLATE_ID', - 'MOU_NOTIFY_TEAM_ALERT_TEMPLATE_ID', - ] - } - - -@pytest.fixture -def notify_service( - notify_db_session, - sample_user, - sample_service, -): - user = sample_user() - service = notify_db_session.session.get(Service, current_app.config['NOTIFY_SERVICE_ID']) - - if service is None: - service = sample_service( - service_id=current_app.config['NOTIFY_SERVICE_ID'], - service_name='Notify Service', - message_limit=1000, - restricted=False, - email_from='notify.service', - user=user, - prefix_sms=False, - ) - - data = { - 'service': service, - 'email_address': 'notify@gov.uk', - 'is_default': True, - } - reply_to = ServiceEmailReplyTo(**data) - - notify_db_session.session.add(reply_to) - notify_db_session.session.commit() - - yield service, user - - notify_db_session.session.delete(reply_to) - notify_db_session.session.commit() - - @pytest.fixture(scope='function') def sample_service_whitelist(notify_db_session, sample_service): whitelist_user_ids = [] @@ -2307,15 +1728,6 @@ def _wrapper(service: Service = None, email_address: str = '', phone_number: str notify_db_session.session.commit() -@pytest.fixture(scope='function') -def sample_provider_rate(notify_db_session, valid_from=None, rate=None, provider_identifier=None): - create_provider_rates( - provider_identifier=provider_identifier if provider_identifier is not None else MMG_PROVIDER, - valid_from=valid_from if valid_from is not None else datetime.utcnow(), - rate=rate if rate is not None else 1, - ) - - @pytest.fixture def sample_inbound_sms(notify_db_session, sample_service, sample_inbound_number): created_inbound_sms_ids = [] @@ -2405,7 +1817,7 @@ def _sample_inbound_number( @pytest.fixture def sample_inbound_numbers(sample_service, sample_inbound_number): - service = sample_service(service_name=str(uuid4()), check_if_service_exists=True) + service = sample_service(service_name=str(uuid4()), check_if_service_exists=False) inbound_numbers = [ sample_inbound_number(provider=MMG_PROVIDER), sample_inbound_number(provider=MMG_PROVIDER, active=False, service_id=service.id), @@ -2633,12 +2045,6 @@ def mock_email_client(mocker): return mocked_client -@pytest.fixture(scope='function') -def mocked_build_ga_pixel_url(mocker): - mocked_builder = mocker.patch('app.googleanalytics.pixels.build_ga_pixel_url', return_value='url') - return mocked_builder - - @pytest.fixture(scope='function') def mocked_provider_stats(sample_user, mocker): return [ @@ -2680,7 +2086,7 @@ def datetime_in_past(days=0, seconds=0): @pytest.fixture -def sample_sms_sender_v2(notify_db_session): +def sample_sms_sender(notify_db_session): sms_sender_ids = [] def _wrapper( @@ -2717,23 +2123,6 @@ def _wrapper( notify_db_session.session.commit() -@pytest.fixture -def sample_sms_sender(notify_db_session, sample_service): - created_sms_senders = [] - - def _sample_sms_sender(service_id: str): - service_sms_sender = dao_add_sms_sender_for_service(service_id, '+12025555555', True) - created_sms_senders.append(service_sms_sender) - return service_sms_sender - - yield _sample_sms_sender - - # Teardown - for sms_sender in created_sms_senders: - notify_db_session.session.delete(sms_sender) - notify_db_session.session.commit() - - @pytest.fixture def sample_communication_item(notify_db_session): created_communication_item_ids = [] @@ -3014,58 +2403,6 @@ def _wrapper(service=None, **kwargs): notify_db.session.commit() -@pytest.fixture(scope='session') -def sample_template_session(notify_db, sample_service_session, sample_user_session, worker_id): - """ - Use this session-scoped SMS template for tests that don't need to modify the template. - """ - template_ids = [] - - def _wrapper(*args, **kwargs): - # Guard statements - assert len(args) == 0, 'sample_template method does not accept positional arguments' - if str(kwargs.get('id')) in template_ids: - return notify_db.session.get(Template, kwargs['id']) - - # Mandatory arguments - ignore args - kwargs['name'] = kwargs.get('name', f'function template {uuid4()}') - kwargs['template_type'] = kwargs.get('template_type', SMS_TYPE) - - # Using fixtures as defaults creates those objects! Do not make a fixture the default param - kwargs['user'] = kwargs.get('user') or sample_user_session() - kwargs['service'] = kwargs.get('service') or sample_service_session() - - if 'subject' in kwargs: - kwargs['subject_line'] = kwargs.pop('subject') - - template_data = sample_template_helper(*args, **kwargs) - - if kwargs['template_type'] == LETTER_TYPE: - template_data['postage'] = kwargs.get('postage', 'second') - - # Create template object and put it in the DB - template = Template(**template_data) - dao_create_template(template) - template_ids.append(str(template.id)) - - return template - - yield _wrapper - - # Teardown - service_ids = [t.service_id for t in template_ids] - stmt = delete(TemplateHistory).where(TemplateHistory.service_id.in_(service_ids)) - notify_db.session.execute(stmt) - - stmt = delete(TemplateRedacted).where(TemplateRedacted.id.in_(template_ids)) - notify_db.session.execute(stmt) - - stmt = delete(Template).where(Template.id.in_(template_ids)) - notify_db.session.execute(stmt) - - notify_db.session.commit() - - @pytest.fixture(scope='session') def sample_user_session(notify_db): created_user_ids = [] diff --git a/tests/app/dao/test_organisation_dao.py b/tests/app/dao/test_organisation_dao.py index 949445aa5b..1dcc369a29 100644 --- a/tests/app/dao/test_organisation_dao.py +++ b/tests/app/dao/test_organisation_dao.py @@ -16,8 +16,7 @@ dao_get_users_for_organisation, dao_update_organisation, ) -from app.dao.services_dao import dao_add_user_to_service, dao_create_service -from app.models import OrganisationTypes, Service +from app.models import Service def test_get_organisations_gets_all_organisations_alphabetically_with_active_organisations_first(sample_organisation): @@ -65,57 +64,6 @@ def test_update_organisation_does_not_update_the_service_org_type_if_org_type_is assert service.organisation_type == 'other' -@pytest.fixture(scope='function') -def setup_org_type(notify_db_session): - org_type = OrganisationTypes(name='some other', annual_free_sms_fragment_limit=25000) - notify_db_session.session.add(org_type) - notify_db_session.session.commit() - return org_type - - -@pytest.fixture -def setup_service( - notify_db_session, - sample_user, - service_name='Sample service', - user=None, - restricted=False, - limit=1000, - email_from=None, - permissions=None, - research_mode=None, -): - if user is None: - user = sample_user() - if email_from is None: - email_from = service_name.lower().replace(' ', '.') - - data = { - 'name': service_name, - 'message_limit': limit, - 'restricted': restricted, - 'email_from': email_from, - 'created_by': user, - 'crown': True, - } - - stmt = select(Service).where(Service.name == service_name) - service = notify_db_session.session.scalars(stmt).first() - - if not service: - service = Service(**data) - dao_create_service(service, user, service_permissions=permissions) - - if research_mode: - service.research_mode = research_mode - - else: - if user not in service.users: - dao_add_user_to_service(service, user) - - return service - - def test_add_service_to_organisation(notify_db_session, sample_service, sample_organisation): service = sample_service() organisation = sample_organisation() diff --git a/tests/app/delivery/test_send_to_providers.py b/tests/app/delivery/test_send_to_providers.py index 42c69e9a93..91df3cac95 100644 --- a/tests/app/delivery/test_send_to_providers.py +++ b/tests/app/delivery/test_send_to_providers.py @@ -416,13 +416,13 @@ def test_should_send_sms_with_downgraded_content( def test_send_sms_should_use_service_sms_sender( sample_api_key, sample_notification, - sample_sms_sender_v2, + sample_sms_sender, sample_template, mock_sms_client, ): template = sample_template() api_key = sample_api_key(service=template.service) - sms_sender = sample_sms_sender_v2(service_id=template.service.id, sms_sender='123456', is_default=False) + sms_sender = sample_sms_sender(service_id=template.service.id, sms_sender='123456', is_default=False) db_notification = sample_notification(template=template, reply_to_text=sms_sender.sms_sender, api_key=api_key) send_to_providers.send_sms_to_provider( diff --git a/tests/app/integration/test_callback.py b/tests/app/integration/test_callback.py index 3bab3fcf7c..3db4b32112 100644 --- a/tests/app/integration/test_callback.py +++ b/tests/app/integration/test_callback.py @@ -1,52 +1,16 @@ import json -import pytest +from uuid import uuid4 + +from botocore.stub import ANY + from flask import url_for from flask_jwt_extended import create_access_token +import pytest + from app.celery.process_pinpoint_inbound_sms import CeleryEvent, process_pinpoint_inbound_sms from app.dao.permissions_dao import permission_dao -from app.feature_flags import FeatureFlag from app.models import QUEUE_CHANNEL_TYPE, INBOUND_SMS_CALLBACK_TYPE, PLATFORM_ADMIN, Permission -from tests.app.factories.feature_flag import mock_feature_flag -from botocore.stub import Stubber, ANY -from app import sqs_client, notify_celery -from tests.conftest import set_config_values - - -@pytest.fixture() -def sqs_stub(): - with Stubber(sqs_client._client) as stubber: - yield stubber - stubber.assert_no_pending_responses() - - -@pytest.fixture() -def integration_celery_config(notify_api): - with set_config_values( - notify_api, - { - 'CELERY_SETTINGS': { - 'broker_url': 'sqs://', - 'task_always_eager': True, - 'imports': ( - 'app.celery.tasks', - 'app.celery.scheduled_tasks', - 'app.celery.reporting_tasks', - 'app.celery.nightly_tasks', - 'app.celery.process_pinpoint_receipt_tasks', - 'app.celery.process_pinpoint_inbound_sms' 'app.celery.service_callback_tasks', - ), - } - }, - ): - notify_celery.init_app(notify_api) - yield - notify_celery.init_app(notify_api) - - -@pytest.fixture -def pinpoint_inbound_sms_toggle_enabled(mocker): - mock_feature_flag(mocker, FeatureFlag.PINPOINT_INBOUND_SMS_ENABLED, 'True') class AnySms(object): @@ -72,13 +36,15 @@ def __eq__(self, other): @pytest.mark.skip(reason='Integration test fails when run in suite, passes when run alone') -def test_sqs_callback( - integration_celery_config, sqs_stub, sample_service_full_permissions, client, pinpoint_inbound_sms_toggle_enabled -): - sample_service = sample_service_full_permissions +def test_sqs_callback(integration_celery_config, sqs_stub, sample_service, client, pinpoint_inbound_sms_toggle_enabled): + service = sample_service( + service_name=f'sample service full permissions {uuid4()}', + service_permissions=set(SERVICE_PERMISSION_TYPES), + check_if_service_exists=False, + ) user = sample_service.users[0] permission_dao.set_user_service_permission( - user, sample_service, [Permission(service_id=sample_service.id, user_id=user.id, permission=PLATFORM_ADMIN)] + user, sample_service, [Permission(service_id=service.id, user_id=user.id, permission=PLATFORM_ADMIN)] ) user.platform_admin = True diff --git a/tests/app/notifications/rest/test_send_notification.py b/tests/app/notifications/rest/test_send_notification.py index 859450c05e..f25e489bfc 100644 --- a/tests/app/notifications/rest/test_send_notification.py +++ b/tests/app/notifications/rest/test_send_notification.py @@ -237,7 +237,7 @@ def test_should_allow_valid_sms_notification( sample_api_key, sample_template, mocker, - sample_sms_sender_v2, + sample_sms_sender, ): with notify_api.test_request_context(): with notify_api.test_client() as client: @@ -247,7 +247,7 @@ def test_should_allow_valid_sms_notification( data = { 'to': '6502532222', 'template': str(template.id), - 'sms_sender_id': str(sample_sms_sender_v2(service_id=template.service.id).id), + 'sms_sender_id': str(sample_sms_sender(service_id=template.service.id).id), } auth_header = create_authorization_header(sample_api_key(service=template.service)) @@ -438,7 +438,7 @@ def test_should_allow_api_call_if_under_day_limit_regardless_of_type( sample_user, mocker, restricted, - sample_sms_sender_v2, + sample_sms_sender, ): with notify_api.test_request_context(): with notify_api.test_client() as client: @@ -453,7 +453,7 @@ def test_should_allow_api_call_if_under_day_limit_regardless_of_type( data = { 'to': sample_user().mobile_number, 'template': str(sms_template.id), - 'sms_sender_id': str(sample_sms_sender_v2(service_id=service.id).id), + 'sms_sender_id': str(sample_sms_sender(service_id=service.id).id), } auth_header = create_authorization_header(api_key) @@ -540,7 +540,7 @@ def test_should_not_send_sms_if_team_api_key_and_not_a_service_user( sample_api_key, sample_template, mocker, - sample_sms_sender_v2, + sample_sms_sender, ): with notify_api.test_request_context(), notify_api.test_client() as client: mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') @@ -549,7 +549,7 @@ def test_should_not_send_sms_if_team_api_key_and_not_a_service_user( data = { 'to': '6502532229', 'template': str(template.id), - 'sms_sender_id': str(sample_sms_sender_v2(service_id=template.service.id).id), + 'sms_sender_id': str(sample_sms_sender(service_id=template.service.id).id), } auth_header = create_authorization_header(sample_api_key(service=template.service, key_type=KEY_TYPE_TEAM)) @@ -648,7 +648,7 @@ def test_should_persist_notification( mocker, template_type, queue_name, - sample_sms_sender_v2, + sample_sms_sender, ): mocked = mocker.patch('app.celery.provider_tasks.deliver_{}.apply_async'.format(template_type)) mocked_uuid = str(uuid4()) @@ -664,7 +664,7 @@ def test_should_persist_notification( data = { 'to': to, 'template': template.id, - 'sms_sender_id': str(sample_sms_sender_v2(service_id=template.service.id).id), + 'sms_sender_id': str(sample_sms_sender(service_id=template.service.id).id), } auth_header = create_jwt_token(secret=api_key.secret, client_id=str(api_key.service_id)) @@ -705,7 +705,7 @@ def test_should_delete_notification_and_return_error_if_sqs_fails( mocker, template_type, queue_name, - sample_sms_sender_v2, + sample_sms_sender, ): mocked = mocker.patch( 'app.celery.provider_tasks.deliver_{}.apply_async'.format(template_type), @@ -724,7 +724,7 @@ def test_should_delete_notification_and_return_error_if_sqs_fails( data = { 'to': to, 'template': template.id, - 'sms_sender_id': str(sample_sms_sender_v2(service_id=template.service.id).id), + 'sms_sender_id': str(sample_sms_sender(service_id=template.service.id).id), } auth_header = create_jwt_token(secret=api_key.secret, client_id=str(api_key.service_id)) @@ -761,7 +761,7 @@ def test_should_not_send_notification_to_non_whitelist_recipient_in_trial_mode( to, key_type, mocker, - sample_sms_sender_v2, + sample_sms_sender, ): template = sample_template(template_type=notification_type) service = template.service @@ -779,7 +779,7 @@ def test_should_not_send_notification_to_non_whitelist_recipient_in_trial_mode( data = { 'to': to, 'template': str(template.id), - 'sms_sender_id': str(sample_sms_sender_v2(service_id=service.id).id), + 'sms_sender_id': str(sample_sms_sender(service_id=service.id).id), } auth_header = create_jwt_token(secret=api_key.secret, client_id=str(api_key.service_id)) @@ -824,7 +824,7 @@ def test_should_send_notification_to_whitelist_recipient( key_type, service_restricted, mocker, - sample_sms_sender_v2, + sample_sms_sender, ): service = sample_service() service.message_limit = 2 @@ -846,7 +846,7 @@ def test_should_send_notification_to_whitelist_recipient( data = { 'to': to, 'template': str(template.id), - 'sms_sender_id': str(sample_sms_sender_v2(service_id=service.id).id), + 'sms_sender_id': str(sample_sms_sender(service_id=service.id).id), } test_key = sample_api_key(service=service, key_type=key_type) @@ -883,13 +883,13 @@ def test_should_error_if_notification_type_does_not_match_template_type( template_type, notification_type, to, - sample_sms_sender_v2, + sample_sms_sender, ): template = sample_template(template_type=template_type) data = { 'to': to, 'template': template.id, - 'sms_sender_id': str(sample_sms_sender_v2(service_id=template.service.id).id), + 'sms_sender_id': str(sample_sms_sender(service_id=template.service.id).id), } auth_header = create_authorization_header(sample_api_key(service=template.service)) response = client.post( @@ -909,11 +909,12 @@ def test_should_error_if_notification_type_does_not_match_template_type( def test_create_template_raises_invalid_request_exception_with_missing_personalisation( notify_db_session, - sample_template_with_placeholders, + sample_template, ): - template = notify_db_session.session.get(Template, sample_template_with_placeholders.id) from app.notifications.rest import create_template_object_for_notification + template = sample_template(content='Hello (( Name))\nYour thing is due soon') + with pytest.raises(InvalidRequest) as e: create_template_object_for_notification(template, {}) assert {'template': ['Missing personalisation: Name']} == e.value.message @@ -921,11 +922,11 @@ def test_create_template_raises_invalid_request_exception_with_missing_personali def test_create_template_doesnt_raise_with_too_much_personalisation( notify_db_session, - sample_template_with_placeholders, + sample_template, ): from app.notifications.rest import create_template_object_for_notification - template = notify_db_session.session.get(Template, sample_template_with_placeholders.id) + template = sample_template(content='Hello (( Name))\nYour thing is due soon') create_template_object_for_notification(template, {'name': 'Jo', 'extra': 'stuff'}) @@ -962,7 +963,7 @@ def test_create_template_raises_invalid_request_when_content_too_large( @pytest.mark.parametrize('notification_type, send_to', [('sms', '6502532222'), ('email', 'sample@email.com')]) def test_send_notification_uses_priority_queue_when_template_is_marked_as_priority( - client, notify_db_session, sample_api_key, sample_template, mocker, notification_type, send_to, sample_sms_sender_v2 + client, notify_db_session, sample_api_key, sample_template, mocker, notification_type, send_to, sample_sms_sender ): template = sample_template(template_type=notification_type, process_type='priority') mocked = mocker.patch('app.celery.provider_tasks.deliver_{}.apply_async'.format(notification_type)) @@ -970,7 +971,7 @@ def test_send_notification_uses_priority_queue_when_template_is_marked_as_priori data = { 'to': send_to, 'template': str(template.id), - 'sms_sender_id': str(sample_sms_sender_v2(service_id=template.service.id).id), + 'sms_sender_id': str(sample_sms_sender(service_id=template.service.id).id), } auth_header = create_authorization_header(sample_api_key(service=template.service)) @@ -1008,7 +1009,7 @@ def test_returns_a_429_limit_exceeded_if_rate_limit_exceeded( mocker, notification_type, send_to, - sample_sms_sender_v2, + sample_sms_sender, ): template = sample_template(template_type=notification_type) persist_mock = mocker.patch('app.notifications.rest.persist_notification') @@ -1019,7 +1020,7 @@ def test_returns_a_429_limit_exceeded_if_rate_limit_exceeded( data = { 'to': send_to, 'template': str(template.id), - 'sms_sender_id': str(sample_sms_sender_v2(service_id=template.service.id).id), + 'sms_sender_id': str(sample_sms_sender(service_id=template.service.id).id), } auth_header = create_authorization_header(sample_api_key(template.service)) @@ -1045,7 +1046,7 @@ def test_should_not_allow_international_number_on_sms_notification( sample_service, sample_template, mocker, - sample_sms_sender_v2, + sample_sms_sender, ): mocked = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') service = sample_service(service_permissions=[EMAIL_TYPE, SMS_TYPE]) @@ -1056,7 +1057,7 @@ def test_should_not_allow_international_number_on_sms_notification( data = { 'to': '+20-12-1234-1234', 'template': str(template.id), - 'sms_sender_id': str(sample_sms_sender_v2(service_id=service.id).id), + 'sms_sender_id': str(sample_sms_sender(service_id=service.id).id), } auth_header = create_authorization_header(sample_api_key(service=service)) @@ -1080,7 +1081,7 @@ def test_should_allow_international_number_on_sms_notification( sample_service, sample_template, mocker, - sample_sms_sender_v2, + sample_sms_sender, ): mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') @@ -1091,7 +1092,7 @@ def test_should_allow_international_number_on_sms_notification( data = { 'to': '+20-12-1234-1234', 'template': str(template.id), - 'sms_sender_id': str(sample_sms_sender_v2(service_id=service.id).id), + 'sms_sender_id': str(sample_sms_sender(service_id=service.id).id), } auth_header = create_authorization_header(sample_api_key(service=service)) @@ -1113,16 +1114,19 @@ def test_should_not_allow_sms_notifications_if_service_permission_not_set( client, mocker, sample_api_key, - sample_template_without_sms_permission, - sample_sms_sender_v2, + sample_service, + sample_sms_sender, + sample_template, ): mocked = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') - service = sample_template_without_sms_permission.service + service = sample_service(service_permissions=[EMAIL_TYPE], check_if_service_exists=True) + template = sample_template(service=service) + data = { 'to': '+16502532222', - 'template': str(sample_template_without_sms_permission.id), - 'sms_sender_id': str(sample_sms_sender_v2(service_id=service.id).id), + 'template': str(template.id), + 'sms_sender_id': str(sample_sms_sender(service_id=service.id).id), } auth_header = create_authorization_header(sample_api_key(service=service)) @@ -1143,13 +1147,17 @@ def test_should_not_allow_email_notifications_if_service_permission_not_set( client, mocker, sample_api_key, - sample_template_without_email_permission, + sample_service, + sample_template, ): mocked = mocker.patch('app.celery.provider_tasks.deliver_email.apply_async') - data = {'to': 'notify@digital.cabinet-office.gov.uk', 'template': str(sample_template_without_email_permission.id)} + service = sample_service(service_permissions=[SMS_TYPE]) + template = sample_template(service=service, template_type=EMAIL_TYPE) + + data = {'to': 'notify@digital.cabinet-office.gov.uk', 'template': str(template.id)} - auth_header = create_authorization_header(sample_api_key(service=sample_template_without_email_permission.service)) + auth_header = create_authorization_header(sample_api_key(service=template.service)) response = client.post( path='/notifications/email', data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header] diff --git a/tests/app/notifications/test_aws_sns_status_callback.py b/tests/app/notifications/test_aws_sns_status_callback.py index da4d7c4e24..c0250a129f 100644 --- a/tests/app/notifications/test_aws_sns_status_callback.py +++ b/tests/app/notifications/test_aws_sns_status_callback.py @@ -15,13 +15,13 @@ def mock_notification(mocker): return notification -class TestSendcCllbackMetrics: +class TestSendCallbackMetrics: @pytest.fixture def mocks_statsd(self, mocker): return mocker.patch('app.notifications.aws_sns_status_callback.statsd_client') @pytest.mark.parametrize('status', [NOTIFICATION_SENT, NOTIFICATION_FAILED]) - def test_should_increase_counter_for_status(self, client, mock_notification, mocks_statsd, status): + def test_should_increase_counter_for_status(self, notify_api, mock_notification, mocks_statsd, status): mock_notification.status = status send_callback_metrics(mock_notification) mocks_statsd.incr.assert_called_with(f'callback.sns.{status}') @@ -29,7 +29,7 @@ def test_should_increase_counter_for_status(self, client, mock_notification, moc @freeze_time('2020-11-03T22:45:00') @pytest.mark.parametrize('sent_at, should_call', [(None, False), (datetime(2020, 11, 3, 22, 30, 0), True)]) def test_should_report_timing_only_when_notification_sent_at( - self, client, mock_notification, mocks_statsd, sent_at, should_call + self, notify_api, mock_notification, mocks_statsd, sent_at, should_call ): mock_notification.sent_at = sent_at send_callback_metrics(mock_notification) diff --git a/tests/app/notifications/test_process_notifications.py b/tests/app/notifications/test_process_notifications.py index ba94a8818b..f2b2d611a7 100644 --- a/tests/app/notifications/test_process_notifications.py +++ b/tests/app/notifications/test_process_notifications.py @@ -20,6 +20,7 @@ ScheduledNotification, Template, LETTER_TYPE, + SERVICE_PERMISSION_TYPES, EMAIL_TYPE, SMS_TYPE, RecipientIdentifier, @@ -832,14 +833,17 @@ def test_persist_letter_notification_finds_correct_postage( postage_argument, template_postage, expected_postage, - sample_service_full_permissions, + sample_service, sample_api_key, sample_template, ): api_key = sample_api_key() - template = sample_template( - service=sample_service_full_permissions, template_type=LETTER_TYPE, postage=template_postage + service = sample_service( + service_name=f'sample service full permissions {uuid.uuid4()}', + service_permissions=set(SERVICE_PERMISSION_TYPES), + check_if_service_exists=False, ) + template = sample_template(service=service, template_type=LETTER_TYPE, postage=template_postage) mocker.patch('app.dao.templates_dao.dao_get_template_by_id', return_value=template) notification = persist_notification( @@ -847,7 +851,7 @@ def test_persist_letter_notification_finds_correct_postage( template_version=template.version, template_postage=template.postage, recipient='Jane Doe, 10 Downing Street, London', - service_id=sample_service_full_permissions.id, + service_id=service.id, personalisation=None, notification_type=LETTER_TYPE, api_key_id=api_key.id, diff --git a/tests/app/service/test_send_one_off_notification.py b/tests/app/service/test_send_one_off_notification.py index 6c98b281f4..56553c3360 100644 --- a/tests/app/service/test_send_one_off_notification.py +++ b/tests/app/service/test_send_one_off_notification.py @@ -270,13 +270,13 @@ def test_send_one_off_notification_should_add_email_reply_to_text_for_notificati def test_send_one_off_sms_notification_should_use_sms_sender_reply_to_text( notify_db_session, sample_service, - sample_sms_sender_v2, + sample_sms_sender, sample_template, celery_mock, ): service = sample_service() template = sample_template(service=service) - sms_sender = sample_sms_sender_v2(service_id=service.id, sms_sender='6502532222', is_default=False) + sms_sender = sample_sms_sender(service_id=service.id, sms_sender='6502532222', is_default=False) data = { 'to': '6502532223', @@ -299,14 +299,14 @@ def test_send_one_off_sms_notification_should_use_sms_sender_reply_to_text( def test_send_one_off_sms_notification_should_use_default_service_reply_to_text( notify_db_session, sample_service, - sample_sms_sender_v2, + sample_sms_sender, sample_template, celery_mock, ): service = sample_service() template = sample_template(service=service) service.service_sms_senders[0].is_default = False - sample_sms_sender_v2(service_id=service.id, sms_sender='6502532222', is_default=True) + sample_sms_sender(service_id=service.id, sms_sender='6502532222', is_default=True) data = { 'to': '6502532223', diff --git a/tests/app/service/test_sms_sender_rest.py b/tests/app/service/test_sms_sender_rest.py index 550566fb05..7829786abd 100644 --- a/tests/app/service/test_sms_sender_rest.py +++ b/tests/app/service/test_sms_sender_rest.py @@ -63,12 +63,12 @@ def test_add_service_sms_sender_return_404_when_rate_limit_too_small(admin_reque def test_update_service_sms_sender( admin_request, sample_service, - sample_sms_sender_v2, + sample_sms_sender, ): service = sample_service() sender_specifics = {'data': 'This is something specific.'} - service_sms_sender = sample_sms_sender_v2( + service_sms_sender = sample_sms_sender( service_id=service.id, sms_sender='1235', is_default=False, sms_sender_specifics=sender_specifics ) @@ -97,11 +97,11 @@ def test_update_service_sms_sender_does_not_allow_sender_update_for_inbound_numb admin_request, sample_inbound_number, sample_service, - sample_sms_sender_v2, + sample_sms_sender, ): service = sample_service() inbound_number = sample_inbound_number('12345', service_id=service.id) - service_sms_sender = sample_sms_sender_v2( + service_sms_sender = sample_sms_sender( service_id=service.id, sms_sender='1235', is_default=False, inbound_number_id=inbound_number.id ) payload = {'sms_sender': 'second', 'is_default': True, 'inbound_number_id': str(inbound_number.id)} @@ -131,10 +131,10 @@ def test_update_service_sms_sender_return_404_when_service_does_not_exist(admin_ def test_delete_service_sms_sender_can_archive_sms_sender( admin_request, sample_service, - sample_sms_sender_v2, + sample_sms_sender, ): service = sample_service() - service_sms_sender = sample_sms_sender_v2(service_id=service.id, sms_sender='5678', is_default=False) + service_sms_sender = sample_sms_sender(service_id=service.id, sms_sender='5678', is_default=False) assert not service_sms_sender.archived, 'This should be False by default.' @@ -168,9 +168,9 @@ def test_delete_service_sms_sender_returns_400_if_archiving_inbound_number( def test_get_service_sms_sender_by_id( admin_request, sample_service, - sample_sms_sender_v2, + sample_sms_sender, ): - service_sms_sender = sample_sms_sender_v2(service_id=sample_service().id, sms_sender='1235', is_default=False) + service_sms_sender = sample_sms_sender(service_id=sample_service().id, sms_sender='1235', is_default=False) response_json = admin_request.get( 'service_sms_sender.get_service_sms_sender_by_id', @@ -196,11 +196,11 @@ def test_get_service_sms_sender_by_id_returns_404_when_service_sms_sender_does_n def test_get_service_sms_senders_for_service( admin_request, sample_service, - sample_sms_sender_v2, + sample_sms_sender, ): sender_specifics = {'data': 'This is something specific.'} - service_sms_sender = sample_sms_sender_v2( + service_sms_sender = sample_sms_sender( service_id=sample_service().id, sms_sender='second', is_default=False, sms_sender_specifics=sender_specifics ) diff --git a/tests/app/template/test_rest.py b/tests/app/template/test_rest.py index e4c622a009..5c43243423 100644 --- a/tests/app/template/test_rest.py +++ b/tests/app/template/test_rest.py @@ -1634,7 +1634,7 @@ def test_should_create_template_without_created_by_using_current_user_id( service = sample_service( service_name=f'sample service full permissions {uuid.uuid4()}', service_permissions=set(SERVICE_PERMISSION_TYPES), - check_if_service_exists=True, + check_if_service_exists=False, ) user = service.users[0] permission_dao.set_user_service_permission( diff --git a/tests/app/v2/notifications/test_post_notifications.py b/tests/app/v2/notifications/test_post_notifications.py index d2d2e03120..2b6c1ff724 100644 --- a/tests/app/v2/notifications/test_post_notifications.py +++ b/tests/app/v2/notifications/test_post_notifications.py @@ -36,34 +36,6 @@ from . import post_send_notification -@pytest.fixture -def enable_accept_recipient_identifiers_enabled_feature_flag(mocker): - mocker.patch('app.v2.notifications.post_notifications.accept_recipient_identifiers_enabled', return_value=True) - - -@pytest.fixture -def mock_template_with_version(mocker): - mock_template = mocker.Mock() - mock_template.id = 'template-id' - mock_template.version = 1 - - return mock_template - - -@pytest.fixture -def mock_api_key(mocker): - mock_api_key = mocker.Mock() - mock_api_key.id = 'some-id' - mock_api_key.key_type = 'some-type' - - return mock_api_key - - -@pytest.fixture -def check_recipient_communication_permissions_enabled(mocker): - mock_feature_flag(mocker, FeatureFlag.CHECK_RECIPIENT_COMMUNICATION_PERMISSIONS_ENABLED, 'True') - - @pytest.fixture(autouse=True) def mock_deliver_email(mocker): return mocker.patch('app.celery.provider_tasks.deliver_email.apply_async') @@ -143,12 +115,12 @@ def test_post_sms_notification_uses_inbound_number_as_sender( sample_service, sample_template, sample_inbound_number, - sample_sms_sender_v2, + sample_sms_sender, ): service = sample_service() template = sample_template(service=service, content='Hello (( Name))\nYour thing is due soon') inbound_number = sample_inbound_number(service_id=service.id, number=str(randint(1, 999999999))) - sms_sender = sample_sms_sender_v2( + sms_sender = sample_sms_sender( service_id=service.id, inbound_number_id=inbound_number.id, sms_sender=str(randint(1, 999999999)) )