import pytest from flask import session, url_for from app.utils import is_gov_user from tests import organisation_json from tests.conftest import mock_get_organisation_by_domain, normalize_spaces def test_non_gov_user_cannot_see_add_service_button( client, mock_login, mock_get_non_govuser, api_nongov_user_active, mock_get_organisations, mock_get_organisations_and_services_for_user, ): client.login(api_nongov_user_active) response = client.get(url_for('main.choose_account')) assert 'Add a new service' not in response.get_data(as_text=True) assert response.status_code == 200 @pytest.mark.parametrize('org_json', ( None, organisation_json(organisation_type=None), )) def test_get_should_render_add_service_template( client_request, mocker, org_json, ): mocker.patch( 'app.organisations_client.get_organisation_by_domain', return_value=org_json, ) page = client_request.get('main.add_service') assert page.select_one('h1').text.strip() == 'About your service' assert page.select_one('input[name=name]')['value'] == '' assert [ label.text.strip() for label in page.select('.multiple-choice label') ] == [ 'Central government', 'Local government', 'NHS', ] assert [ radio['value'] for radio in page.select('.multiple-choice input') ] == [ 'central', 'local', 'nhs', ] def test_get_should_not_render_radios_if_org_type_known( client_request, mocker, ): mock_get_organisation_by_domain(mocker, organisation_type='central') page = client_request.get('main.add_service') assert page.select_one('h1').text.strip() == 'About your service' assert page.select_one('input[name=name]')['value'] == '' assert not page.select('.multiple-choice') @pytest.mark.parametrize('email_address', ( # User’s email address doesn’t matter when the organisation is known 'test@example.gov.uk', 'test@example.nhs.uk', )) @pytest.mark.parametrize('inherited, posted, persisted, sms_limit', ( (None, 'central', 'central', 250000), ('central', None, 'central', 250000), ('nhs', None, 'nhs', 25000), ('local', None, 'local', 25000), ('central', 'local', 'central', 250000), )) def test_should_add_service_and_redirect_to_tour_when_no_services( mocker, client_request, mock_create_service, mock_create_service_template, mock_get_services_with_no_services, api_user_active, mock_create_or_update_free_sms_fragment_limit, mock_get_all_email_branding, inherited, email_address, posted, persisted, sms_limit, ): api_user_active['email_address'] = email_address client_request.login(api_user_active) mock_get_organisation_by_domain(mocker, organisation_type=inherited) client_request.post( 'main.add_service', _data={ 'name': 'testing the post', 'organisation_type': posted, }, _expected_status=302, _expected_redirect=url_for( 'main.start_tour', service_id=101, template_id="Example%20text%20message%20template", _external=True, ), ) assert mock_get_services_with_no_services.called mock_create_service.assert_called_once_with( service_name='testing the post', organisation_type=persisted, message_limit=50, restricted=True, user_id=api_user_active['id'], email_from='testing.the.post', ) mock_create_service_template.assert_called_once_with( 'Example text message template', 'sms', ( 'Hey ((name)), I’m trying out Notify. Today is ' '((day of week)) and my favourite colour is ((colour)).' ), 101, ) assert session['service_id'] == 101 mock_create_or_update_free_sms_fragment_limit.assert_called_once_with(101, sms_limit) def test_add_service_has_to_choose_org_type( mocker, client_request, mock_create_service, mock_create_service_template, mock_get_services_with_no_services, api_user_active, mock_create_or_update_free_sms_fragment_limit, mock_get_all_email_branding, ): mocker.patch( 'app.organisations_client.get_organisation_by_domain', return_value=None, ) page = client_request.post( 'main.add_service', _data={ 'name': 'testing the post', }, _expected_status=200, ) assert normalize_spaces(page.select_one('.error-message').text) == ( 'Not a valid choice' ) assert mock_create_service.called is False assert mock_create_service_template.called is False assert mock_create_or_update_free_sms_fragment_limit.called is False @pytest.mark.parametrize('email_address', ( 'test@nhs.net', 'test@nhs.uk', 'test@example.NhS.uK', 'test@EXAMPLE.NHS.NET', pytest.param( 'test@not-nhs.uk', marks=pytest.mark.xfail(raises=AssertionError) ) )) def test_add_service_guesses_org_type_for_unknown_nhs_orgs( mocker, client_request, mock_create_service, mock_create_service_template, mock_get_services_with_no_services, api_user_active, mock_create_or_update_free_sms_fragment_limit, mock_get_all_email_branding, email_address, ): api_user_active['email_address'] = email_address client_request.login(api_user_active) mocker.patch( 'app.organisations_client.get_organisation_by_domain', return_value=None, ) client_request.post( 'main.add_service', _data={'name': 'example'}, ) assert mock_create_service.call_args[1]['organisation_type'] == 'nhs' @pytest.mark.parametrize('organisation_type, free_allowance', [ ('central', 250 * 1000), ('local', 25 * 1000), ('nhs', 25 * 1000), ]) def test_should_add_service_and_redirect_to_dashboard_when_existing_service( app_, client_request, mock_create_service, mock_create_service_template, mock_get_services, mock_get_organisation_by_domain, api_user_active, organisation_type, free_allowance, mock_create_or_update_free_sms_fragment_limit, mock_get_all_email_branding, ): client_request.post( 'main.add_service', _data={ 'name': 'testing the post', 'organisation_type': organisation_type, }, _expected_status=302, _expected_redirect=url_for( 'main.service_dashboard', service_id=101, _external=True, ) ) assert mock_get_services.called mock_create_service.assert_called_once_with( service_name='testing the post', organisation_type=organisation_type, message_limit=app_.config['DEFAULT_SERVICE_LIMIT'], restricted=True, user_id=api_user_active['id'], email_from='testing.the.post', ) mock_create_or_update_free_sms_fragment_limit.assert_called_once_with(101, free_allowance) assert len(mock_create_service_template.call_args_list) == 0 assert session['service_id'] == 101 def test_should_return_form_errors_when_service_name_is_empty( client_request, mock_get_organisation_by_domain, ): page = client_request.post( 'main.add_service', data={}, _expected_status=200, ) assert 'Can’t be empty' in page.text def test_should_return_form_errors_with_duplicate_service_name_regardless_of_case( client_request, mock_create_duplicate_service, mock_get_organisation_by_domain, ): page = client_request.post( 'main.add_service', _data={ 'name': 'SERVICE ONE', 'organisation_type': 'central', }, _expected_status=200, ) assert page.select_one('.error-message').text.strip() == ( 'This service name is already in use' ) def test_non_whitelist_user_cannot_access_create_service_page( client_request, mock_get_non_govuser, api_nongov_user_active, mock_get_organisations, ): assert is_gov_user(api_nongov_user_active['email_address']) is False client_request.get( 'main.add_service', _expected_status=403, ) def test_non_whitelist_user_cannot_create_service( client_request, mock_get_non_govuser, api_nongov_user_active, mock_get_organisations, ): assert is_gov_user(api_nongov_user_active['email_address']) is False client_request.post( 'main.add_service', _data={'name': 'SERVICE TWO'}, _expected_status=403, )