mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-24 01:11:38 -05:00
Merge pull request #3323 from alphagov/add-permission-local-dev
Make it easy to develop with broadcast services
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import csv
|
||||
import functools
|
||||
import itertools
|
||||
import os
|
||||
import uuid
|
||||
from datetime import datetime, timedelta
|
||||
from decimal import Decimal
|
||||
@@ -43,6 +44,7 @@ from app.dao.organisation_dao import (
|
||||
dao_add_service_to_organisation,
|
||||
dao_get_organisation_by_email_address,
|
||||
)
|
||||
from app.dao.permissions_dao import permission_dao
|
||||
from app.dao.provider_rates_dao import (
|
||||
create_provider_rates as dao_create_provider_rates,
|
||||
)
|
||||
@@ -75,6 +77,7 @@ from app.models import (
|
||||
LetterBranding,
|
||||
Notification,
|
||||
Organisation,
|
||||
Permission,
|
||||
Service,
|
||||
User,
|
||||
)
|
||||
@@ -91,17 +94,25 @@ class notify_command:
|
||||
self.name = name
|
||||
|
||||
def __call__(self, func):
|
||||
# we need to call the flask with_appcontext decorator to ensure the config is loaded, db connected etc etc.
|
||||
# we also need to use functools.wraps to carry through the names and docstrings etc of the functions.
|
||||
# Then we need to turn it into a click.Command - that's what command_group.add_command expects.
|
||||
@click.command(name=self.name)
|
||||
@functools.wraps(func)
|
||||
@flask.cli.with_appcontext
|
||||
decorators = [
|
||||
click.command(name=self.name), # turn it into a click.Command
|
||||
functools.wraps(func) # carry through function name, docstrings, etc.
|
||||
]
|
||||
|
||||
# in the test environment the app context is already provided and having
|
||||
# another will lead to the test db connection being closed prematurely
|
||||
if os.getenv('NOTIFY_ENVIRONMENT', '') != 'test':
|
||||
# with_appcontext ensures the config is loaded, db connected, etc.
|
||||
decorators.insert(0, flask.cli.with_appcontext)
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
return func(*args, **kwargs)
|
||||
|
||||
command_group.add_command(wrapper)
|
||||
for decorator in decorators:
|
||||
# this syntax is equivalent to e.g. "@flask.cli.with_appcontext"
|
||||
wrapper = decorator(wrapper)
|
||||
|
||||
command_group.add_command(wrapper)
|
||||
return wrapper
|
||||
|
||||
|
||||
@@ -914,3 +925,32 @@ def populate_annual_billing_with_defaults(year, missing_services_only):
|
||||
|
||||
for service in active_services:
|
||||
set_default_free_allowance_for_service(service, year)
|
||||
|
||||
|
||||
@click.option('-u', '--user-id', required=True)
|
||||
@notify_command(name='local-dev-broadcast-permissions')
|
||||
def local_dev_broadcast_permissions(user_id):
|
||||
if os.getenv('NOTIFY_ENVIRONMENT', '') not in ['development', 'test']:
|
||||
current_app.logger.error('Can only be run in development')
|
||||
return
|
||||
|
||||
user = User.query.filter_by(id=user_id).one()
|
||||
|
||||
user_broadcast_services = Service.query.filter(
|
||||
Service.permissions.any(permission='broadcast'),
|
||||
Service.users.any(id=user_id)
|
||||
)
|
||||
|
||||
for service in user_broadcast_services:
|
||||
permission_list = [
|
||||
Permission(service_id=service.id, user_id=user_id, permission=permission)
|
||||
for permission in [
|
||||
'reject_broadcasts', 'cancel_broadcasts', # required to create / approve
|
||||
'create_broadcasts', 'approve_broadcasts', # minimum for testing
|
||||
'manage_templates', # unlikely but might be useful
|
||||
]
|
||||
]
|
||||
|
||||
permission_dao.set_user_service_permission(
|
||||
user, service, permission_list, _commit=True, replace=True
|
||||
)
|
||||
|
||||
@@ -71,11 +71,11 @@ def rmock():
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def service_factory(notify_db, notify_db_session):
|
||||
def service_factory(sample_user):
|
||||
class ServiceFactory(object):
|
||||
def get(self, service_name, user=None, template_type=None, email_from=None):
|
||||
if not user:
|
||||
user = create_user()
|
||||
user = sample_user
|
||||
if not email_from:
|
||||
email_from = service_name
|
||||
|
||||
@@ -106,7 +106,9 @@ def service_factory(notify_db, notify_db_session):
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def sample_user(notify_db_session):
|
||||
return create_user()
|
||||
return create_user(
|
||||
email='notify@digital.cabinet-office.gov.uk'
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
@@ -131,8 +133,7 @@ def sample_sms_code(notify_db_session):
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def sample_service(notify_db_session):
|
||||
user = create_user()
|
||||
def sample_service(sample_user):
|
||||
service_name = 'Sample service'
|
||||
email_from = service_name.lower().replace(' ', '.')
|
||||
|
||||
@@ -141,23 +142,22 @@ def sample_service(notify_db_session):
|
||||
'message_limit': 1000,
|
||||
'restricted': False,
|
||||
'email_from': email_from,
|
||||
'created_by': user,
|
||||
'created_by': sample_user,
|
||||
'crown': True
|
||||
}
|
||||
service = Service.query.filter_by(name=service_name).first()
|
||||
if not service:
|
||||
service = Service(**data)
|
||||
dao_create_service(service, user, service_permissions=None)
|
||||
dao_create_service(service, sample_user, service_permissions=None)
|
||||
else:
|
||||
if user not in service.users:
|
||||
dao_add_user_to_service(service, user)
|
||||
if sample_user not in service.users:
|
||||
dao_add_user_to_service(service, sample_user)
|
||||
|
||||
return service
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def sample_broadcast_service(notify_db_session, broadcast_organisation):
|
||||
user = create_user()
|
||||
def sample_broadcast_service(broadcast_organisation, sample_user):
|
||||
service_name = 'Sample broadcast service'
|
||||
email_from = service_name.lower().replace(' ', '.')
|
||||
|
||||
@@ -166,19 +166,19 @@ def sample_broadcast_service(notify_db_session, broadcast_organisation):
|
||||
'message_limit': 1000,
|
||||
'restricted': False,
|
||||
'email_from': email_from,
|
||||
'created_by': user,
|
||||
'created_by': sample_user,
|
||||
'crown': True,
|
||||
'count_as_live': False,
|
||||
}
|
||||
service = Service.query.filter_by(name=service_name).first()
|
||||
if not service:
|
||||
service = Service(**data)
|
||||
dao_create_service(service, user, service_permissions=[BROADCAST_TYPE])
|
||||
dao_create_service(service, sample_user, service_permissions=[BROADCAST_TYPE])
|
||||
insert_or_update_service_broadcast_settings(service, channel="severe")
|
||||
dao_add_service_to_organisation(service, current_app.config['BROADCAST_ORGANISATION_ID'])
|
||||
else:
|
||||
if user not in service.users:
|
||||
dao_add_user_to_service(service, user)
|
||||
if sample_user not in service.users:
|
||||
dao_add_user_to_service(service, sample_user)
|
||||
|
||||
return service
|
||||
|
||||
@@ -201,8 +201,7 @@ def _sample_service_custom_letter_contact_block(sample_service):
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def sample_template(notify_db_session):
|
||||
user = create_user()
|
||||
def sample_template(sample_user):
|
||||
service = create_service(service_permissions=[EMAIL_TYPE, SMS_TYPE], check_if_service_exists=True)
|
||||
|
||||
data = {
|
||||
@@ -210,7 +209,7 @@ def sample_template(notify_db_session):
|
||||
'template_type': 'sms',
|
||||
'content': 'This is a template:\nwith a newline',
|
||||
'service': service,
|
||||
'created_by': user,
|
||||
'created_by': sample_user,
|
||||
'archived': False,
|
||||
'hidden': False,
|
||||
'process_type': 'normal'
|
||||
@@ -240,15 +239,14 @@ def sample_sms_template_with_html(sample_service):
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def sample_email_template(notify_db_session):
|
||||
user = create_user()
|
||||
service = create_service(user=user, service_permissions=[EMAIL_TYPE, SMS_TYPE], check_if_service_exists=True)
|
||||
def sample_email_template(sample_user):
|
||||
service = create_service(user=sample_user, service_permissions=[EMAIL_TYPE, SMS_TYPE], check_if_service_exists=True)
|
||||
data = {
|
||||
'name': 'Email Template Name',
|
||||
'template_type': EMAIL_TYPE,
|
||||
'content': 'This is a template',
|
||||
'service': service,
|
||||
'created_by': user,
|
||||
'created_by': sample_user,
|
||||
'subject': 'Email Subject'
|
||||
}
|
||||
template = Template(**data)
|
||||
@@ -551,18 +549,17 @@ def sample_invited_org_user(sample_user, sample_organisation):
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def sample_user_service_permission(notify_db_session):
|
||||
user = create_user()
|
||||
service = create_service(user=user, check_if_service_exists=True)
|
||||
def sample_user_service_permission(sample_user):
|
||||
service = create_service(user=sample_user, check_if_service_exists=True)
|
||||
permission = 'manage_settings'
|
||||
|
||||
data = {
|
||||
'user': user,
|
||||
'user': sample_user,
|
||||
'service': service,
|
||||
'permission': permission
|
||||
}
|
||||
p_model = Permission.query.filter_by(
|
||||
user=user,
|
||||
user=sample_user,
|
||||
service=service,
|
||||
permission=permission).first()
|
||||
if not p_model:
|
||||
@@ -828,8 +825,7 @@ def letter_volumes_email_template(notify_service):
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def notify_service(notify_db, notify_db_session):
|
||||
user = create_user()
|
||||
def notify_service(sample_user):
|
||||
service = Service.query.get(current_app.config['NOTIFY_SERVICE_ID'])
|
||||
if not service:
|
||||
service = Service(
|
||||
@@ -837,13 +833,13 @@ def notify_service(notify_db, notify_db_session):
|
||||
message_limit=1000,
|
||||
restricted=False,
|
||||
email_from='notify.service',
|
||||
created_by=user,
|
||||
created_by=sample_user,
|
||||
prefix_sms=False,
|
||||
)
|
||||
dao_create_service(
|
||||
service=service,
|
||||
service_id=current_app.config['NOTIFY_SERVICE_ID'],
|
||||
user=user
|
||||
user=sample_user
|
||||
)
|
||||
|
||||
data = {
|
||||
|
||||
@@ -81,7 +81,7 @@ from app.models import (
|
||||
def create_user(
|
||||
*,
|
||||
mobile_number="+447700900986",
|
||||
email="notify@digital.cabinet-office.gov.uk",
|
||||
email=None,
|
||||
state='active',
|
||||
id_=None,
|
||||
name="Test User"
|
||||
@@ -89,7 +89,7 @@ def create_user(
|
||||
data = {
|
||||
'id': id_ or uuid.uuid4(),
|
||||
'name': name,
|
||||
'email_address': email,
|
||||
'email_address': email or f"{uuid.uuid4()}@digital.cabinet-office.gov.uk",
|
||||
'password': 'password',
|
||||
'mobile_number': mobile_number,
|
||||
'state': state
|
||||
|
||||
23
tests/app/test_commands.py
Normal file
23
tests/app/test_commands.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from app.commands import local_dev_broadcast_permissions
|
||||
from app.dao.services_dao import dao_add_user_to_service
|
||||
from tests.app.db import create_user
|
||||
|
||||
|
||||
def test_local_dev_broadcast_permissions(
|
||||
sample_service,
|
||||
sample_broadcast_service,
|
||||
notify_api,
|
||||
):
|
||||
user = create_user()
|
||||
dao_add_user_to_service(sample_service, user)
|
||||
dao_add_user_to_service(sample_broadcast_service, user)
|
||||
|
||||
assert len(user.get_permissions(sample_service.id)) == 0
|
||||
assert len(user.get_permissions(sample_broadcast_service.id)) == 0
|
||||
|
||||
notify_api.test_cli_runner().invoke(
|
||||
local_dev_broadcast_permissions, ['-u', user.id]
|
||||
)
|
||||
|
||||
assert len(user.get_permissions(sample_service.id)) == 0
|
||||
assert len(user.get_permissions(sample_broadcast_service.id)) > 0
|
||||
Reference in New Issue
Block a user