2016-02-26 13:07:35 +00:00
|
|
|
import uuid
|
2016-03-07 18:18:52 +00:00
|
|
|
from datetime import date, datetime, timedelta
|
2016-03-10 14:29:31 +00:00
|
|
|
from unittest.mock import Mock
|
2015-11-25 15:29:12 +00:00
|
|
|
import pytest
|
2016-01-21 12:28:05 +00:00
|
|
|
|
2016-01-27 12:22:32 +00:00
|
|
|
from app import create_app
|
2016-01-22 16:46:59 +00:00
|
|
|
|
2016-01-21 12:28:05 +00:00
|
|
|
from . import (
|
2016-01-29 15:35:35 +00:00
|
|
|
service_json,
|
|
|
|
|
TestClient,
|
|
|
|
|
template_json,
|
|
|
|
|
api_key_json,
|
2016-02-26 15:33:17 +00:00
|
|
|
job_json,
|
2016-03-02 16:15:15 +00:00
|
|
|
notification_json,
|
2016-02-26 15:33:17 +00:00
|
|
|
invite_json
|
2016-01-29 15:35:35 +00:00
|
|
|
)
|
2016-02-29 17:35:21 +00:00
|
|
|
from app.notify_client.models import (
|
|
|
|
|
User,
|
|
|
|
|
InvitedUser
|
|
|
|
|
)
|
2015-11-25 15:29:12 +00:00
|
|
|
|
2016-03-10 14:29:31 +00:00
|
|
|
from notifications_python_client.errors import HTTPError
|
|
|
|
|
|
2016-01-06 16:51:35 +00:00
|
|
|
|
2015-12-10 14:48:01 +00:00
|
|
|
@pytest.fixture(scope='session')
|
2016-01-15 15:15:35 +00:00
|
|
|
def app_(request):
|
2016-03-17 13:45:59 +00:00
|
|
|
app = create_app()
|
2015-12-10 14:48:01 +00:00
|
|
|
|
2015-11-25 15:29:12 +00:00
|
|
|
ctx = app.app_context()
|
|
|
|
|
ctx.push()
|
|
|
|
|
|
|
|
|
|
def teardown():
|
|
|
|
|
ctx.pop()
|
|
|
|
|
|
|
|
|
|
request.addfinalizer(teardown)
|
2016-01-06 16:40:38 +00:00
|
|
|
app.test_client_class = TestClient
|
2015-11-25 15:29:12 +00:00
|
|
|
return app
|
|
|
|
|
|
|
|
|
|
|
2015-12-10 14:48:01 +00:00
|
|
|
@pytest.fixture(scope='function')
|
2016-03-18 10:49:22 +00:00
|
|
|
def service_one(api_user_active):
|
|
|
|
|
return service_json(SERVICE_ONE_ID, 'service one', [api_user_active.id])
|
2016-01-15 15:15:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_send_sms(request, mocker):
|
2016-03-17 10:46:47 +00:00
|
|
|
return mocker.patch("app.service_api_client.send_sms")
|
2016-01-15 15:15:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 12:22:32 +00:00
|
|
|
def mock_get_service(mocker, api_user_active):
|
2016-01-22 16:46:59 +00:00
|
|
|
def _get(service_id):
|
2016-01-18 16:01:04 +00:00
|
|
|
service = service_json(
|
2016-01-27 12:22:32 +00:00
|
|
|
service_id, "Test Service", [api_user_active.id], limit=1000,
|
2016-01-18 16:01:04 +00:00
|
|
|
active=False, restricted=True)
|
2016-01-27 16:30:33 +00:00
|
|
|
return {'data': service}
|
2016-01-21 12:28:05 +00:00
|
|
|
|
2016-03-17 10:46:47 +00:00
|
|
|
return mocker.patch('app.service_api_client.get_service', side_effect=_get)
|
2016-01-15 15:15:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_create_service(mocker):
|
|
|
|
|
def _create(service_name, active, limit, restricted, user_id):
|
|
|
|
|
service = service_json(
|
|
|
|
|
101, service_name, [user_id], limit=limit,
|
|
|
|
|
active=active, restricted=restricted)
|
2016-03-13 09:37:17 +00:00
|
|
|
return service['id']
|
2016-01-21 12:28:05 +00:00
|
|
|
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch(
|
2016-03-17 10:46:47 +00:00
|
|
|
'app.service_api_client.create_service', side_effect=_create)
|
2016-01-15 15:15:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_update_service(mocker):
|
|
|
|
|
def _update(service_id,
|
|
|
|
|
service_name,
|
|
|
|
|
active,
|
|
|
|
|
limit,
|
|
|
|
|
restricted,
|
|
|
|
|
users):
|
|
|
|
|
service = service_json(
|
|
|
|
|
service_id, service_name, users, limit=limit,
|
|
|
|
|
active=active, restricted=restricted)
|
|
|
|
|
return {'data': service}
|
2016-01-21 12:28:05 +00:00
|
|
|
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch(
|
2016-03-17 10:46:47 +00:00
|
|
|
'app.service_api_client.update_service', side_effect=_update)
|
2016-01-15 15:15:35 +00:00
|
|
|
|
|
|
|
|
|
2016-03-10 14:29:31 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_update_service_raise_httperror_duplicate_name(mocker):
|
|
|
|
|
def _update(service_id,
|
|
|
|
|
service_name,
|
|
|
|
|
active,
|
|
|
|
|
limit,
|
|
|
|
|
restricted,
|
|
|
|
|
users):
|
|
|
|
|
json_mock = Mock(return_value={'message': {'name': ["Duplicate service name '{}'".format(service_name)]}})
|
|
|
|
|
resp_mock = Mock(status_code=400, json=json_mock)
|
|
|
|
|
http_error = HTTPError(response=resp_mock, message="Default message")
|
|
|
|
|
raise http_error
|
|
|
|
|
|
|
|
|
|
return mocker.patch(
|
2016-03-17 10:46:47 +00:00
|
|
|
'app.service_api_client.update_service', side_effect=_update)
|
2016-03-10 14:29:31 +00:00
|
|
|
|
|
|
|
|
|
2016-03-09 09:29:35 +00:00
|
|
|
SERVICE_ONE_ID = "596364a0-858e-42c8-9062-a8fe822260eb"
|
|
|
|
|
SERVICE_TWO_ID = "147ad62a-2951-4fa1-9ca0-093cd1a52c52"
|
|
|
|
|
|
|
|
|
|
|
2016-01-15 15:15:35 +00:00
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def mock_get_services(mocker, user=None):
|
|
|
|
|
if user is None:
|
2016-03-18 16:20:37 +00:00
|
|
|
user = active_user_with_permissions()
|
2016-01-27 16:30:33 +00:00
|
|
|
|
|
|
|
|
def _create(user_id=None):
|
2016-01-15 15:15:35 +00:00
|
|
|
service_one = service_json(
|
2016-03-09 09:29:35 +00:00
|
|
|
SERVICE_ONE_ID, "service_one", [user.id], 1000, True, False)
|
2016-01-15 15:15:35 +00:00
|
|
|
service_two = service_json(
|
2016-03-09 09:29:35 +00:00
|
|
|
SERVICE_TWO_ID, "service_two", [user.id], 1000, True, False)
|
2016-01-15 15:15:35 +00:00
|
|
|
return {'data': [service_one, service_two]}
|
2016-01-21 12:28:05 +00:00
|
|
|
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch(
|
2016-03-17 10:46:47 +00:00
|
|
|
'app.service_api_client.get_services', side_effect=_create)
|
2016-01-18 16:01:04 +00:00
|
|
|
|
|
|
|
|
|
2016-02-05 14:25:48 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_services_with_one_service(mocker, user=None):
|
|
|
|
|
if user is None:
|
|
|
|
|
user = api_user_active()
|
|
|
|
|
|
|
|
|
|
def _create(user_id=None):
|
|
|
|
|
return {'data': [service_json(
|
2016-03-09 09:29:35 +00:00
|
|
|
SERVICE_ONE_ID, "service_one", [user.id], 1000, True, False
|
2016-02-05 14:25:48 +00:00
|
|
|
)]}
|
|
|
|
|
|
|
|
|
|
return mocker.patch(
|
2016-03-17 10:46:47 +00:00
|
|
|
'app.service_api_client.get_services', side_effect=_create)
|
2016-02-05 14:25:48 +00:00
|
|
|
|
|
|
|
|
|
2016-01-18 16:01:04 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_delete_service(mocker, mock_get_service):
|
|
|
|
|
def _delete(service_id):
|
|
|
|
|
return mock_get_service.side_effect(service_id)
|
2016-01-21 12:28:05 +00:00
|
|
|
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch(
|
2016-03-17 10:46:47 +00:00
|
|
|
'app.service_api_client.delete_service', side_effect=_delete)
|
2016-01-19 15:54:12 +00:00
|
|
|
|
|
|
|
|
|
2016-03-17 11:44:00 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_service_statistics(mocker):
|
|
|
|
|
def _create(service_id):
|
2016-03-17 11:45:48 +00:00
|
|
|
return {'data': [{}]}
|
2016-03-17 11:44:00 +00:00
|
|
|
|
|
|
|
|
return mocker.patch(
|
|
|
|
|
'app.statistics_api_client.get_statistics_for_service', side_effect=_create)
|
|
|
|
|
|
|
|
|
|
|
2016-01-19 15:54:12 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_service_template(mocker):
|
|
|
|
|
def _create(service_id, template_id):
|
|
|
|
|
template = template_json(
|
2016-03-16 16:57:10 +00:00
|
|
|
service_id, template_id, "Two week reminder", "sms", "Your vehicle tax is about to expire")
|
2016-01-19 15:54:12 +00:00
|
|
|
return {'data': template}
|
2016-01-21 12:28:05 +00:00
|
|
|
|
2016-01-19 15:54:12 +00:00
|
|
|
return mocker.patch(
|
2016-03-17 10:46:47 +00:00
|
|
|
'app.service_api_client.get_service_template', side_effect=_create)
|
2016-01-19 15:54:12 +00:00
|
|
|
|
|
|
|
|
|
2016-03-02 17:02:41 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_service_email_template(mocker):
|
|
|
|
|
def _create(service_id, template_id):
|
|
|
|
|
template = template_json(
|
2016-03-16 16:57:10 +00:00
|
|
|
service_id, template_id, "Two week reminder", "email", "Your vehicle tax is about to expire")
|
2016-03-02 17:02:41 +00:00
|
|
|
return {'data': template}
|
|
|
|
|
|
|
|
|
|
return mocker.patch(
|
2016-03-17 10:46:47 +00:00
|
|
|
'app.service_api_client.get_service_template', side_effect=_create)
|
2016-03-02 17:02:41 +00:00
|
|
|
|
|
|
|
|
|
2016-01-19 15:54:12 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_create_service_template(mocker):
|
|
|
|
|
def _create(name, type_, content, service):
|
|
|
|
|
template = template_json(
|
|
|
|
|
101, name, type_, content, service)
|
|
|
|
|
return {'data': template}
|
2016-01-21 12:28:05 +00:00
|
|
|
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch(
|
2016-03-17 10:46:47 +00:00
|
|
|
'app.service_api_client.create_service_template',
|
2016-01-19 15:54:12 +00:00
|
|
|
side_effect=_create)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_update_service_template(mocker):
|
|
|
|
|
def _update(id_, name, type_, content, service):
|
|
|
|
|
template = template_json(
|
|
|
|
|
id_, name, type_, content, service)
|
|
|
|
|
return {'data': template}
|
2016-01-21 12:28:05 +00:00
|
|
|
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch(
|
2016-03-17 10:46:47 +00:00
|
|
|
'app.service_api_client.update_service_template',
|
2016-01-19 15:54:12 +00:00
|
|
|
side_effect=_update)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_service_templates(mocker):
|
|
|
|
|
def _create(service_id):
|
2016-02-22 17:17:18 +00:00
|
|
|
return {'data': [
|
|
|
|
|
template_json(
|
2016-03-18 16:32:10 +00:00
|
|
|
service_id, 1, "sms_template_one", "sms", "sms template one content"
|
2016-02-22 17:17:18 +00:00
|
|
|
),
|
|
|
|
|
template_json(
|
2016-03-18 16:32:10 +00:00
|
|
|
service_id, 2, "sms_template_two", "sms", "sms template two content"
|
2016-02-22 17:17:18 +00:00
|
|
|
),
|
|
|
|
|
template_json(
|
2016-03-18 16:32:10 +00:00
|
|
|
service_id, 3, "email_template_one", "email", "email template one content"
|
2016-02-22 17:17:18 +00:00
|
|
|
),
|
|
|
|
|
template_json(
|
2016-03-18 16:32:10 +00:00
|
|
|
service_id, 4, "email_template_two", "email", "email template two content"
|
2016-02-22 17:17:18 +00:00
|
|
|
)
|
|
|
|
|
]}
|
2016-01-21 12:28:05 +00:00
|
|
|
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch(
|
2016-03-17 10:46:47 +00:00
|
|
|
'app.service_api_client.get_service_templates',
|
2016-01-19 15:54:12 +00:00
|
|
|
side_effect=_create)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_delete_service_template(mocker):
|
|
|
|
|
def _delete(service_id, template_id):
|
|
|
|
|
template = template_json(
|
2016-03-16 16:57:10 +00:00
|
|
|
service_id, template_id, "Template to delete", "sms", "content to be deleted")
|
2016-01-19 15:54:12 +00:00
|
|
|
return {'data': template}
|
2016-01-21 12:28:05 +00:00
|
|
|
|
2016-01-19 16:35:52 +00:00
|
|
|
return mocker.patch(
|
2016-03-17 10:46:47 +00:00
|
|
|
'app.service_api_client.delete_service_template', side_effect=_delete)
|
2016-01-19 16:35:52 +00:00
|
|
|
|
|
|
|
|
|
2016-01-20 15:13:15 +00:00
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def api_user_pending():
|
2016-01-19 22:47:42 +00:00
|
|
|
from app.notify_client.user_api_client import User
|
2016-01-27 16:30:33 +00:00
|
|
|
user_data = {'id': 111,
|
2016-01-20 15:13:15 +00:00
|
|
|
'name': 'Test User',
|
|
|
|
|
'password': 'somepassword',
|
|
|
|
|
'email_address': 'test@user.gov.uk',
|
2016-01-21 12:12:06 +00:00
|
|
|
'mobile_number': '+4412341234',
|
2016-01-21 11:33:53 +00:00
|
|
|
'state': 'pending',
|
2016-02-29 14:57:07 +00:00
|
|
|
'failed_login_count': 0,
|
|
|
|
|
'permissions': {}
|
2016-01-20 15:13:15 +00:00
|
|
|
}
|
2016-01-19 22:47:42 +00:00
|
|
|
user = User(user_data)
|
2016-01-20 15:13:15 +00:00
|
|
|
return user
|
|
|
|
|
|
|
|
|
|
|
2016-03-17 10:46:47 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def platform_admin_user():
|
|
|
|
|
from app.notify_client.user_api_client import User
|
|
|
|
|
user_data = {'id': 222,
|
|
|
|
|
'name': 'Platform admin user',
|
|
|
|
|
'password': 'somepassword',
|
|
|
|
|
'email_address': 'platform@admin.gov.uk',
|
|
|
|
|
'mobile_number': '+4472341234',
|
|
|
|
|
'state': 'active',
|
|
|
|
|
'failed_login_count': 0,
|
|
|
|
|
'permissions': {},
|
|
|
|
|
'platform_admin': True
|
|
|
|
|
}
|
|
|
|
|
user = User(user_data)
|
|
|
|
|
return user
|
|
|
|
|
|
|
|
|
|
|
2016-01-20 15:13:15 +00:00
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def api_user_active():
|
2016-01-27 12:22:32 +00:00
|
|
|
from app.notify_client.user_api_client import User
|
2016-01-27 16:30:33 +00:00
|
|
|
user_data = {'id': 222,
|
2016-01-27 12:22:32 +00:00
|
|
|
'name': 'Test User',
|
|
|
|
|
'password': 'somepassword',
|
|
|
|
|
'email_address': 'test@user.gov.uk',
|
|
|
|
|
'mobile_number': '+4412341234',
|
|
|
|
|
'state': 'active',
|
2016-02-29 14:57:07 +00:00
|
|
|
'failed_login_count': 0,
|
|
|
|
|
'permissions': {}
|
2016-01-27 12:22:32 +00:00
|
|
|
}
|
|
|
|
|
user = User(user_data)
|
|
|
|
|
return user
|
|
|
|
|
|
|
|
|
|
|
2016-03-18 10:49:22 +00:00
|
|
|
@pytest.fixture(scope='function')
|
2016-03-18 16:20:37 +00:00
|
|
|
def active_user_with_permissions():
|
2016-03-18 10:49:22 +00:00
|
|
|
from app.notify_client.user_api_client import User
|
|
|
|
|
|
|
|
|
|
user_data = {'id': 222,
|
|
|
|
|
'name': 'Test User',
|
|
|
|
|
'password': 'somepassword',
|
|
|
|
|
'email_address': 'test@user.gov.uk',
|
|
|
|
|
'mobile_number': '+4412341234',
|
|
|
|
|
'state': 'active',
|
|
|
|
|
'failed_login_count': 0,
|
|
|
|
|
'permissions': {SERVICE_ONE_ID: ['send_texts',
|
2016-03-18 16:20:37 +00:00
|
|
|
'send_emails',
|
|
|
|
|
'send_letters',
|
|
|
|
|
'manage_users',
|
|
|
|
|
'manage_templates',
|
|
|
|
|
'manage_settings',
|
|
|
|
|
'manage_api_keys',
|
|
|
|
|
'access_developer_docs']},
|
|
|
|
|
'platform_admin': False
|
2016-03-18 10:49:22 +00:00
|
|
|
}
|
|
|
|
|
user = User(user_data)
|
|
|
|
|
return user
|
|
|
|
|
|
|
|
|
|
|
2016-01-27 12:22:32 +00:00
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def api_user_locked():
|
|
|
|
|
from app.notify_client.user_api_client import User
|
|
|
|
|
user_data = {'id': 333,
|
|
|
|
|
'name': 'Test User',
|
|
|
|
|
'password': 'somepassword',
|
|
|
|
|
'email_address': 'test@user.gov.uk',
|
|
|
|
|
'mobile_number': '+4412341234',
|
|
|
|
|
'state': 'active',
|
2016-02-29 14:57:07 +00:00
|
|
|
'failed_login_count': 5,
|
|
|
|
|
'permissions': {}
|
2016-01-27 16:30:33 +00:00
|
|
|
}
|
|
|
|
|
user = User(user_data)
|
|
|
|
|
return user
|
2016-01-20 15:13:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def api_user_request_password_reset():
|
|
|
|
|
from app.notify_client.user_api_client import User
|
|
|
|
|
user_data = {'id': 555,
|
|
|
|
|
'name': 'Test User',
|
|
|
|
|
'password': 'somepassword',
|
|
|
|
|
'email_address': 'test@user.gov.uk',
|
|
|
|
|
'mobile_number': '+4412341234',
|
2016-03-07 18:18:52 +00:00
|
|
|
'state': 'active',
|
2016-02-29 14:57:07 +00:00
|
|
|
'failed_login_count': 5,
|
2016-03-07 18:18:52 +00:00
|
|
|
'permissions': {},
|
|
|
|
|
'password_changed_at': None
|
|
|
|
|
}
|
|
|
|
|
user = User(user_data)
|
|
|
|
|
return user
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def api_user_changed_password():
|
|
|
|
|
from app.notify_client.user_api_client import User
|
|
|
|
|
user_data = {'id': 555,
|
|
|
|
|
'name': 'Test User',
|
|
|
|
|
'password': 'somepassword',
|
|
|
|
|
'email_address': 'test@user.gov.uk',
|
|
|
|
|
'mobile_number': '+4412341234',
|
|
|
|
|
'state': 'active',
|
|
|
|
|
'failed_login_count': 5,
|
|
|
|
|
'permissions': {},
|
|
|
|
|
'password_changed_at': str(datetime.now() + timedelta(minutes=1))
|
2016-01-27 16:30:33 +00:00
|
|
|
}
|
|
|
|
|
user = User(user_data)
|
|
|
|
|
return user
|
2016-01-20 15:13:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def mock_register_user(mocker, api_user_pending):
|
|
|
|
|
def _register(name, email_address, mobile_number, password):
|
|
|
|
|
api_user_pending.name = name
|
|
|
|
|
api_user_pending.email_address = email_address
|
|
|
|
|
api_user_pending.mobile_number = mobile_number
|
|
|
|
|
api_user_pending.password = password
|
2016-01-27 12:22:32 +00:00
|
|
|
return api_user_pending
|
2016-01-20 15:13:15 +00:00
|
|
|
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch('app.user_api_client.register_user', side_effect=_register)
|
2016-01-20 15:13:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 12:22:32 +00:00
|
|
|
def mock_get_user(mocker, api_user_active):
|
|
|
|
|
def _get_user(id):
|
2016-03-11 16:36:15 +00:00
|
|
|
api_user_active.id = id
|
2016-01-27 12:22:32 +00:00
|
|
|
return api_user_active
|
|
|
|
|
return mocker.patch(
|
|
|
|
|
'app.user_api_client.get_user', side_effect=_get_user)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def mock_get_user_locked(mocker, api_user_locked):
|
|
|
|
|
return mocker.patch(
|
|
|
|
|
'app.user_api_client.get_user', return_value=api_user_locked)
|
2016-01-21 12:12:06 +00:00
|
|
|
|
|
|
|
|
|
2016-01-21 12:31:09 +00:00
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def mock_get_user_pending(mocker, api_user_pending):
|
|
|
|
|
return mocker.patch(
|
|
|
|
|
'app.user_api_client.get_user', return_value=api_user_pending)
|
2016-01-23 23:14:50 +00:00
|
|
|
|
2016-01-27 16:30:33 +00:00
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_user_by_email(mocker, api_user_active):
|
2016-01-21 11:33:53 +00:00
|
|
|
|
2016-01-21 12:12:06 +00:00
|
|
|
def _get_user(email_address):
|
2016-01-27 16:30:33 +00:00
|
|
|
api_user_active._email_address = email_address
|
2016-01-27 12:22:32 +00:00
|
|
|
return api_user_active
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch('app.user_api_client.get_user_by_email', side_effect=_get_user)
|
2016-01-21 12:12:06 +00:00
|
|
|
|
|
|
|
|
|
2016-03-03 09:02:56 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_user_with_permissions(mocker, api_user_active):
|
|
|
|
|
def _get_user(id):
|
|
|
|
|
api_user_active._permissions[''] = ['manage_users', 'manage_templates', 'manage_settings']
|
|
|
|
|
return api_user_active
|
2016-03-17 14:25:28 +00:00
|
|
|
return mocker.patch(
|
|
|
|
|
'app.user_api_client.get_user', side_effect=_get_user)
|
|
|
|
|
|
|
|
|
|
|
2016-02-17 10:24:32 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_dont_get_user_by_email(mocker):
|
|
|
|
|
|
|
|
|
|
def _get_user(email_address):
|
|
|
|
|
return None
|
|
|
|
|
return mocker.patch(
|
|
|
|
|
'app.user_api_client.get_user_by_email',
|
|
|
|
|
side_effect=_get_user,
|
|
|
|
|
autospec=True
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2016-01-21 12:31:09 +00:00
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def mock_get_user_by_email_request_password_reset(mocker, api_user_request_password_reset):
|
|
|
|
|
return mocker.patch(
|
|
|
|
|
'app.user_api_client.get_user_by_email',
|
|
|
|
|
return_value=api_user_request_password_reset)
|
2016-01-21 12:31:09 +00:00
|
|
|
|
|
|
|
|
|
2016-03-07 18:18:52 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_user_by_email_user_changed_password(mocker, api_user_changed_password):
|
|
|
|
|
return mocker.patch(
|
|
|
|
|
'app.user_api_client.get_user_by_email',
|
|
|
|
|
return_value=api_user_changed_password)
|
|
|
|
|
|
|
|
|
|
|
2016-01-21 12:12:06 +00:00
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def mock_get_user_by_email_locked(mocker, api_user_locked):
|
|
|
|
|
return mocker.patch(
|
|
|
|
|
'app.user_api_client.get_user_by_email', return_value=api_user_locked)
|
2016-01-21 11:33:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def mock_get_user_by_email_inactive(mocker, api_user_pending):
|
2016-03-11 11:47:21 +00:00
|
|
|
return mocker.patch('app.user_api_client.get_user_by_email', return_value=api_user_pending)
|
2016-01-27 12:22:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def mock_get_user_by_email_pending(mocker, api_user_pending):
|
2016-01-27 12:22:32 +00:00
|
|
|
return mocker.patch(
|
2016-01-27 16:30:33 +00:00
|
|
|
'app.user_api_client.get_user_by_email',
|
|
|
|
|
return_value=api_user_pending)
|
2016-01-27 12:22:32 +00:00
|
|
|
|
2016-01-21 11:33:53 +00:00
|
|
|
|
2016-01-27 12:22:32 +00:00
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def mock_get_user_by_email_not_found(mocker):
|
|
|
|
|
return mocker.patch('app.user_api_client.get_user_by_email', return_value=None)
|
2016-01-20 15:13:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 12:22:32 +00:00
|
|
|
def mock_verify_password(mocker):
|
|
|
|
|
def _verify_password(user, password):
|
|
|
|
|
return True
|
|
|
|
|
return mocker.patch(
|
|
|
|
|
'app.user_api_client.verify_password',
|
|
|
|
|
side_effect=_verify_password)
|
|
|
|
|
|
|
|
|
|
|
2016-01-20 15:13:15 +00:00
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 12:22:32 +00:00
|
|
|
def mock_update_user(mocker):
|
|
|
|
|
|
|
|
|
|
def _update(user):
|
|
|
|
|
return user
|
|
|
|
|
return mocker.patch('app.user_api_client.update_user', side_effect=_update)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def mock_is_email_unique(mocker):
|
2016-03-17 13:07:52 +00:00
|
|
|
return mocker.patch('app.user_api_client.is_email_unique', return_value=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_is_email_not_unique(mocker):
|
|
|
|
|
return mocker.patch('app.user_api_client.is_email_unique', return_value=False)
|
2016-01-24 15:00:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def mock_get_all_users_from_api(mocker):
|
|
|
|
|
return mocker.patch('app.main.dao.users_dao.user_api_client.get_users')
|
2016-01-20 17:32:55 +00:00
|
|
|
|
|
|
|
|
|
2016-01-21 12:28:05 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_create_api_key(mocker):
|
2016-01-27 16:30:33 +00:00
|
|
|
|
2016-01-21 12:28:05 +00:00
|
|
|
def _create(service_id, key_name):
|
|
|
|
|
import uuid
|
|
|
|
|
return {'data': str(uuid.uuid4())}
|
|
|
|
|
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch('app.api_key_api_client.create_api_key', side_effect=_create)
|
2016-01-21 12:28:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_revoke_api_key(mocker):
|
|
|
|
|
def _revoke(service_id, key_id):
|
|
|
|
|
return {}
|
|
|
|
|
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch(
|
2016-01-27 12:22:32 +00:00
|
|
|
'app.api_key_api_client.revoke_api_key',
|
|
|
|
|
side_effect=_revoke)
|
2016-01-21 12:28:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_api_keys(mocker):
|
|
|
|
|
def _get_keys(service_id, key_id=None):
|
|
|
|
|
keys = {'apiKeys': [api_key_json(1, 'some key name'),
|
|
|
|
|
api_key_json(2, 'another key name', expiry_date=str(date.fromtimestamp(0)))]}
|
|
|
|
|
return keys
|
|
|
|
|
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch('app.api_key_api_client.get_api_keys', side_effect=_get_keys)
|
2016-01-21 12:28:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_no_api_keys(mocker):
|
|
|
|
|
def _get_keys(service_id):
|
|
|
|
|
keys = {'apiKeys': []}
|
|
|
|
|
return keys
|
|
|
|
|
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch('app.api_key_api_client.get_api_keys', side_effect=_get_keys)
|
2016-01-27 12:22:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-01-27 16:30:33 +00:00
|
|
|
def mock_login(mocker, mock_get_user, mock_update_user):
|
2016-01-27 12:22:32 +00:00
|
|
|
def _verify_code(user_id, code, code_type):
|
|
|
|
|
return True, ''
|
2016-02-05 15:08:36 +00:00
|
|
|
|
|
|
|
|
def _no_services(user_id=None):
|
|
|
|
|
return {'data': []}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
mocker.patch(
|
|
|
|
|
'app.user_api_client.check_verify_code',
|
|
|
|
|
side_effect=_verify_code
|
|
|
|
|
),
|
|
|
|
|
mocker.patch(
|
2016-03-17 10:46:47 +00:00
|
|
|
'app.service_api_client.get_services',
|
2016-02-05 15:08:36 +00:00
|
|
|
side_effect=_no_services
|
|
|
|
|
)
|
|
|
|
|
)
|
2016-01-27 12:22:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_send_verify_code(mocker):
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch('app.user_api_client.send_verify_code')
|
2016-01-27 12:22:32 +00:00
|
|
|
|
|
|
|
|
|
2016-03-17 13:07:52 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_send_verify_email(mocker):
|
|
|
|
|
return mocker.patch('app.user_api_client.send_verify_email')
|
|
|
|
|
|
|
|
|
|
|
2016-01-27 12:22:32 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_check_verify_code(mocker):
|
|
|
|
|
def _verify(user_id, code, code_type):
|
|
|
|
|
return True, ''
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch(
|
2016-01-27 12:22:32 +00:00
|
|
|
'app.user_api_client.check_verify_code',
|
|
|
|
|
side_effect=_verify)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_check_verify_code_code_not_found(mocker):
|
|
|
|
|
def _verify(user_id, code, code_type):
|
|
|
|
|
return False, 'Code not found'
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch(
|
2016-01-27 12:22:32 +00:00
|
|
|
'app.user_api_client.check_verify_code',
|
|
|
|
|
side_effect=_verify)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_check_verify_code_code_expired(mocker):
|
|
|
|
|
def _verify(user_id, code, code_type):
|
|
|
|
|
return False, 'Code has expired'
|
2016-01-27 16:30:33 +00:00
|
|
|
return mocker.patch(
|
2016-01-27 12:22:32 +00:00
|
|
|
'app.user_api_client.check_verify_code',
|
|
|
|
|
side_effect=_verify)
|
2016-01-27 16:30:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-01-29 15:35:35 +00:00
|
|
|
def job_data():
|
|
|
|
|
return job_json()
|
2016-01-29 10:27:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_create_job(mocker, job_data):
|
2016-02-22 14:52:16 +00:00
|
|
|
def _create(job_id, service_id, template_id, file_name, notification_count):
|
2016-01-29 15:35:35 +00:00
|
|
|
job_data['id'] = job_id
|
2016-01-29 12:19:50 +00:00
|
|
|
job_data['service'] = service_id
|
|
|
|
|
job_data['template'] = template_id
|
2016-02-04 12:06:06 +00:00
|
|
|
job_data['bucket_name'] = 'service-{}-notify'.format(job_id)
|
2016-01-29 12:19:50 +00:00
|
|
|
job_data['original_file_name'] = file_name
|
2016-01-29 15:35:35 +00:00
|
|
|
job_data['file_name'] = '{}.csv'.format(job_id)
|
2016-02-22 14:52:16 +00:00
|
|
|
job_data['notification_count'] = notification_count
|
2016-01-29 10:27:23 +00:00
|
|
|
return job_data
|
|
|
|
|
return mocker.patch('app.job_api_client.create_job', side_effect=_create)
|
2016-01-29 15:35:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_job(mocker, job_data):
|
|
|
|
|
def _get_job(service_id, job_id):
|
|
|
|
|
job_data['id'] = job_id
|
|
|
|
|
job_data['service'] = service_id
|
|
|
|
|
return {"data": job_data}
|
|
|
|
|
return mocker.patch('app.job_api_client.get_job', side_effect=_get_job)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_jobs(mocker):
|
|
|
|
|
def _get_jobs(service_id):
|
|
|
|
|
import uuid
|
|
|
|
|
data = []
|
|
|
|
|
for i in range(5):
|
|
|
|
|
job_data = job_json()
|
|
|
|
|
job_data['id'] = str(uuid.uuid4())
|
|
|
|
|
job_data['service'] = service_id
|
|
|
|
|
data.append(job_data)
|
|
|
|
|
return {"data": data}
|
|
|
|
|
return mocker.patch('app.job_api_client.get_job', side_effect=_get_jobs)
|
2016-02-29 14:57:07 +00:00
|
|
|
|
|
|
|
|
|
2016-03-02 16:15:15 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_notifications(mocker):
|
2016-03-16 16:57:10 +00:00
|
|
|
def _get_notifications(service_id, job_id=None, page=1):
|
|
|
|
|
return notification_json(service_id)
|
|
|
|
|
return mocker.patch(
|
|
|
|
|
'app.notification_api_client.get_notifications_for_service',
|
|
|
|
|
side_effect=_get_notifications
|
|
|
|
|
)
|
2016-03-18 16:20:37 +00:00
|
|
|
|
2016-03-16 16:57:10 +00:00
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_notifications_with_previous_next(mocker):
|
|
|
|
|
def _get_notifications(service_id, job_id=None, page=1):
|
|
|
|
|
return notification_json(service_id, with_links=True)
|
2016-03-02 16:15:15 +00:00
|
|
|
return mocker.patch(
|
|
|
|
|
'app.notification_api_client.get_notifications_for_service',
|
|
|
|
|
side_effect=_get_notifications
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2016-02-29 14:57:07 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_has_permissions(mocker):
|
2016-03-18 16:20:37 +00:00
|
|
|
def _has_permission(permissions=None, or_=False, admin_override=False):
|
2016-02-29 14:57:07 +00:00
|
|
|
return True
|
|
|
|
|
return mocker.patch(
|
|
|
|
|
'app.notify_client.user_api_client.User.has_permissions',
|
|
|
|
|
side_effect=_has_permission)
|
2016-02-29 14:59:15 +00:00
|
|
|
|
|
|
|
|
|
2016-02-23 17:51:09 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_get_users_by_service(mocker):
|
|
|
|
|
def _get_users_for_service(service_id):
|
|
|
|
|
data = [{'id': 1,
|
|
|
|
|
'logged_in_at': None,
|
|
|
|
|
'mobile_number': '+447700900986',
|
2016-03-18 10:49:22 +00:00
|
|
|
'permissions': {SERVICE_ONE_ID: ['send_texts',
|
|
|
|
|
'send_emails',
|
|
|
|
|
'send_letters',
|
|
|
|
|
'manage_users',
|
|
|
|
|
'manage_templates',
|
|
|
|
|
'manage_settings',
|
|
|
|
|
'manage_api_keys',
|
|
|
|
|
'access_developer_docs']},
|
2016-02-23 17:51:09 +00:00
|
|
|
'state': 'active',
|
|
|
|
|
'password_changed_at': None,
|
|
|
|
|
'name': 'Test User',
|
|
|
|
|
'email_address': 'notify@digital.cabinet-office.gov.uk',
|
|
|
|
|
'failed_login_count': 0}]
|
2016-03-01 10:45:13 +00:00
|
|
|
return [User(data[0])]
|
2016-02-24 09:09:50 +00:00
|
|
|
return mocker.patch('app.user_api_client.get_users_for_service', side_effect=_get_users_for_service, autospec=True)
|
2016-02-26 10:54:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_s3_upload(mocker):
|
|
|
|
|
def _upload(upload_id, service_id, filedata, region):
|
|
|
|
|
pass
|
|
|
|
|
return mocker.patch('app.main.views.send.s3upload', side_effect=_upload)
|
2016-02-26 13:07:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-03-04 14:42:52 +00:00
|
|
|
def sample_invite(mocker, service_one, status='pending'):
|
2016-02-29 17:35:21 +00:00
|
|
|
import datetime
|
|
|
|
|
id = str(uuid.uuid4())
|
|
|
|
|
from_user = service_one['users'][0]
|
|
|
|
|
email_address = 'invited_user@test.gov.uk'
|
|
|
|
|
service_id = service_one['id']
|
|
|
|
|
permissions = 'send_messages,manage_service,manage_api_keys'
|
2016-03-02 15:25:04 +00:00
|
|
|
created_at = str(datetime.datetime.now())
|
2016-03-04 14:42:52 +00:00
|
|
|
return invite_json(id, from_user, service_id, email_address, permissions, created_at, status)
|
2016-02-29 17:35:21 +00:00
|
|
|
|
|
|
|
|
|
2016-03-03 15:26:18 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def sample_invited_user(mocker, sample_invite):
|
|
|
|
|
return InvitedUser(**sample_invite)
|
|
|
|
|
|
|
|
|
|
|
2016-02-29 17:35:21 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_create_invite(mocker, sample_invite):
|
|
|
|
|
|
2016-02-29 11:03:35 +00:00
|
|
|
def _create_invite(from_user, service_id, email_address, permissions):
|
2016-02-29 17:35:21 +00:00
|
|
|
sample_invite['from_user'] = from_user
|
|
|
|
|
sample_invite['service'] = service_id
|
|
|
|
|
sample_invite['email_address'] = email_address
|
|
|
|
|
sample_invite['status'] = 'pending'
|
|
|
|
|
sample_invite['permissions'] = permissions
|
|
|
|
|
return InvitedUser(**sample_invite)
|
2016-02-26 13:07:35 +00:00
|
|
|
return mocker.patch('app.invite_api_client.create_invite', side_effect=_create_invite)
|
2016-02-26 15:33:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-02-29 17:35:21 +00:00
|
|
|
def mock_get_invites_for_service(mocker, service_one, sample_invite):
|
|
|
|
|
import copy
|
|
|
|
|
|
2016-02-26 15:33:17 +00:00
|
|
|
def _get_invites(service_id):
|
|
|
|
|
data = []
|
|
|
|
|
for i in range(0, 5):
|
2016-02-29 17:35:21 +00:00
|
|
|
invite = copy.copy(sample_invite)
|
|
|
|
|
invite['email_address'] = 'user_{}@testnotify.gov.uk'.format(i)
|
|
|
|
|
data.append(InvitedUser(**invite))
|
2016-02-26 15:33:17 +00:00
|
|
|
return data
|
|
|
|
|
return mocker.patch('app.invite_api_client.get_invites_for_service', side_effect=_get_invites)
|
2016-02-29 17:35:21 +00:00
|
|
|
|
|
|
|
|
|
2016-03-03 17:53:16 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_check_invite_token(mocker, sample_invite):
|
|
|
|
|
def _check_token(token):
|
|
|
|
|
return InvitedUser(**sample_invite)
|
|
|
|
|
return mocker.patch('app.invite_api_client.check_token', side_effect=_check_token)
|
|
|
|
|
|
|
|
|
|
|
2016-02-29 17:35:21 +00:00
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_accept_invite(mocker, sample_invite):
|
2016-03-03 17:53:16 +00:00
|
|
|
def _accept(service_id, invite_id):
|
2016-03-01 17:23:23 +00:00
|
|
|
return InvitedUser(**sample_invite)
|
2016-03-03 17:53:16 +00:00
|
|
|
return mocker.patch('app.invite_api_client.accept_invite', side_effect=_accept)
|
2016-02-29 17:35:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
2016-03-01 17:23:23 +00:00
|
|
|
def mock_add_user_to_service(mocker, service_one, api_user_active):
|
2016-03-03 17:53:16 +00:00
|
|
|
def _add_user(service_id, user_id, permissions):
|
2016-02-29 17:35:21 +00:00
|
|
|
return api_user_active
|
|
|
|
|
return mocker.patch('app.user_api_client.add_user_to_service', side_effect=_add_user)
|
2016-03-03 14:32:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_set_user_permissions(mocker):
|
|
|
|
|
return mocker.patch('app.user_api_client.set_user_permissions', return_value=None)
|
2016-03-23 10:46:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
|
|
def mock_remove_user_from_service(mocker):
|
|
|
|
|
return mocker.patch('app.service_api_client.remove_user_from_service', return_value=None)
|