def test_register_from_invite( client, fake_uuid, mock_email_is_not_already_in_use, mock_register_user, mock_send_verify_code, mock_accept_invite, ): invited_user = InvitedUser(fake_uuid, fake_uuid, "", "*****@*****.**", ["manage_users"], "pending", datetime.utcnow(), 'sms_auth') with client.session_transaction() as session: session['invited_user'] = invited_user.serialize() response = client.post( url_for('main.register_from_invite'), data={ 'name': 'Registered in another Browser', 'email_address': invited_user.email_address, 'mobile_number': '+4407700900460', 'service': str(invited_user.id), 'password': '******', 'auth_type': 'sms_auth' } ) assert response.status_code == 302 assert response.location == url_for('main.verify', _external=True)
def test_invite_goes_in_session( client_request, mocker, sample_invite, mock_get_service, api_user_active, mock_check_invite_token, mock_get_user_by_email, mock_get_users_by_service, mock_add_user_to_service, mock_accept_invite, ): invite = InvitedUser(**sample_invite) invite.email_address = '*****@*****.**' mocker.patch('app.invite_api_client.check_token', return_value=invite) client_request.get( 'main.accept_invite', token='thisisnotarealtoken', _expected_status=302, _expected_redirect=url_for( 'main.service_dashboard', service_id=SERVICE_ONE_ID, _external=True, ), _follow_redirects=False, ) with client_request.session_transaction() as session: assert session['invited_user']['email_address'] == invite.email_address
def test_register_from_invite_when_user_registers_in_another_browser( client, api_user_active, mock_get_user_by_email, mock_accept_invite, ): invited_user = InvitedUser(api_user_active.id, api_user_active.id, "", api_user_active.email_address, ["manage_users"], "pending", datetime.utcnow(), 'sms_auth') with client.session_transaction() as session: session['invited_user'] = invited_user.serialize() response = client.post( url_for('main.register_from_invite'), data={ 'name': 'Registered in another Browser', 'email_address': api_user_active.email_address, 'mobile_number': api_user_active.mobile_number, 'service': str(api_user_active.id), 'password': '******', 'auth_type': 'sms_auth' } ) assert response.status_code == 302 assert response.location == url_for('main.verify', _external=True)
def test_manage_users_does_not_show_accepted_invite( logged_in_client, mocker, active_user_with_permissions, sample_invite, ): import uuid invited_user_id = uuid.uuid4() sample_invite['id'] = invited_user_id sample_invite['status'] = 'accepted' data = [InvitedUser(**sample_invite)] service = create_sample_service(active_user_with_permissions) mocker.patch('app.user_api_client.get_users_for_service', return_value=[active_user_with_permissions]) mocker.patch('app.invite_api_client.get_invites_for_service', return_value=data) response = logged_in_client.get( url_for('main.manage_users', service_id=service['id'])) assert response.status_code == 200 page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') assert page.h1.string.strip() == 'Team members' user_lists = page.find_all('div', {'class': 'user-list'}) assert len(user_lists) == 1 assert not page.find(text='*****@*****.**')
def test_existing_user_of_service_get_redirected_to_signin( client, mocker, api_user_active, sample_invite, mock_get_service, mock_get_user_by_email, mock_accept_invite, ): mocker.patch('app.main.views.invites.check_token') sample_invite['email_address'] = api_user_active.email_address invite = InvitedUser(**sample_invite) mocker.patch('app.invite_api_client.check_token', return_value=invite) mocker.patch('app.user_api_client.get_users_for_service', return_value=[api_user_active]) response = client.get(url_for('main.accept_invite', token='thisisnotarealtoken'), follow_redirects=True) assert response.status_code == 200 page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') assert ( page.h1.string, page.select('main p')[0].text.strip(), ) == ( 'You need to sign in again', 'We signed you out because you haven’t used Notify for a while.', ) assert mock_accept_invite.call_count == 1
def _get_invites(service_id): data = [] for i in range(0, 5): invite = copy.copy(sample_invite) invite['email_address'] = 'user_{}@testnotify.gov.uk'.format(i) data.append(InvitedUser(**invite)) return data
def _create_invite(from_user, service_id, email_address, permissions): 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)
def test_signed_in_existing_user_cannot_use_anothers_invite( logged_in_client, mocker, api_user_active, sample_invite, mock_get_user, mock_accept_invite, mock_get_service, ): mocker.patch('app.main.views.invites.check_token') invite = InvitedUser(**sample_invite) mocker.patch('app.invite_api_client.check_token', return_value=invite) mocker.patch('app.user_api_client.get_users_for_service', return_value=[api_user_active]) response = logged_in_client.get(url_for('main.accept_invite', token='thisisnotarealtoken'), follow_redirects=True) assert response.status_code == 403 page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') assert page.h1.string.strip() == '403' flash_banners = page.find_all('div', class_='banner-dangerous') assert len(flash_banners) == 1 banner_contents = flash_banners[0].text.strip() assert "You’re signed in as [email protected]." in banner_contents assert "This invite is for another email address." in banner_contents assert "Sign out and click the link again to accept this invite." in banner_contents assert mock_accept_invite.call_count == 0
def test_existing_user_doesnt_get_auth_changed_by_service_without_permission( client_request, api_user_active, service_one, sample_invite, mock_get_user_by_email, mock_get_users_by_service, mock_accept_invite, mock_update_user_attribute, mock_add_user_to_service, mocker): mocker.patch('app.main.views.invites.check_token') sample_invite['email_address'] = api_user_active.email_address assert 'email_auth' not in service_one['permissions'] sample_invite['auth_type'] = 'email_auth' mocker.patch('app.main.views.invites.service_api_client.get_service', return_value={'data': service_one}) mocker.patch('app.invite_api_client.check_token', return_value=InvitedUser(**sample_invite)) client_request.get( 'main.accept_invite', token='thisisnotarealtoken', _expected_status=302, _expected_redirect=url_for('main.service_dashboard', service_id=service_one['id'], _external=True), ) assert not mock_update_user_attribute.called
def test_manage_users_shows_invited_user(app_, mocker, active_user_with_permissions, sample_invite): service = service_1(active_user_with_permissions) data = [InvitedUser(**sample_invite)] with app_.test_request_context(): with app_.test_client() as client: client.login(active_user_with_permissions, mocker, service) mocker.patch('app.invite_api_client.get_invites_for_service', return_value=data) mocker.patch('app.user_api_client.get_users_for_service', return_value=[active_user_with_permissions]) response = client.get( url_for('main.manage_users', service_id=service['id'])) assert response.status_code == 200 page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') assert page.h1.string.strip() == 'Team members' invited_users_list = page.find_all('div', {'class': 'user-list'})[1] assert invited_users_list.find_all( 'h3')[0].text.strip() == '*****@*****.**' assert invited_users_list.find_all( 'a')[0].text.strip() == 'Cancel invitation'
def test_existing_email_auth_user_with_phone_can_set_sms_auth( client_request, api_user_active, service_one, sample_invite, mock_get_users_by_service, mock_accept_invite, mock_update_user_attribute, mock_add_user_to_service, mocker): mocker.patch('app.main.views.invites.check_token') sample_invite['email_address'] = api_user_active.email_address service_one['permissions'].append('email_auth') sample_invite['auth_type'] = 'sms_auth' api_user_active.auth_type = 'email_auth' api_user_active.mobile_number = '07700900001' mocker.patch('app.main.views.invites.user_api_client.get_user_by_email', return_value=api_user_active) mocker.patch('app.main.views.invites.service_api_client.get_service', return_value={'data': service_one}) mocker.patch('app.invite_api_client.check_token', return_value=InvitedUser(**sample_invite)) client_request.get( 'main.accept_invite', token='thisisnotarealtoken', _expected_status=302, _expected_redirect=url_for('main.service_dashboard', service_id=service_one['id'], _external=True), ) mock_update_user_attribute.assert_called_with(api_user_active.id, auth_type='sms_auth')
def test_edit_some_user_permissions( logged_in_client, mocker, active_user_with_permissions, sample_invite, mock_get_invites_for_service, mock_set_user_permissions, ): service = create_sample_service(active_user_with_permissions) data = [InvitedUser(**sample_invite)] service_id = service['id'] mocker.patch('app.invite_api_client.get_invites_for_service', return_value=data) response = logged_in_client.post( url_for('main.edit_user_permissions', service_id=service_id, user_id=active_user_with_permissions.id), data={ 'email_address': active_user_with_permissions.email_address, 'send_messages': 'y', 'manage_service': '', 'manage_api_keys': '' }) assert response.status_code == 302 assert response.location == url_for('main.manage_users', service_id=service_id, _external=True) mock_set_user_permissions.assert_called_with( str(active_user_with_permissions.id), service_id, permissions={'send_messages', 'view_activity'})
def test_invite_user( logged_in_client, active_user_with_permissions, mocker, sample_invite, email_address, gov_user, ): service = create_sample_service(active_user_with_permissions) sample_invite['email_address'] = '*****@*****.**' data = [InvitedUser(**sample_invite)] assert is_gov_user(email_address) == gov_user mocker.patch('app.invite_api_client.get_invites_for_service', return_value=data) mocker.patch('app.user_api_client.get_users_for_service', return_value=[active_user_with_permissions]) mocker.patch('app.invite_api_client.create_invite', return_value=InvitedUser(**sample_invite)) response = logged_in_client.post(url_for('main.invite_user', service_id=service['id']), data={ 'email_address': email_address, 'view_activity': 'y', 'send_messages': 'y', 'manage_templates': 'y', 'manage_service': 'y', 'manage_api_keys': 'y' }, follow_redirects=True) assert response.status_code == 200 page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') assert page.h1.string.strip() == 'Team members' flash_banner = page.find('div', class_='banner-default-with-tick').string.strip() assert flash_banner == 'Invite sent to [email protected]' expected_permissions = { 'manage_api_keys', 'manage_service', 'manage_templates', 'send_messages', 'view_activity' } app.invite_api_client.create_invite.assert_called_once_with( sample_invite['from_user'], sample_invite['service'], email_address, expected_permissions, 'sms_auth')
def _add_invited_user_to_service(invited_user): invitation = InvitedUser(**invited_user) # if invited user add to service and redirect to dashboard user = user_api_client.get_user(session['user_id']) service_id = invited_user['service'] user_api_client.add_user_to_service(service_id, user.id, invitation.permissions) invite_api_client.accept_invite(service_id, invitation.id) return service_id
def create_invite(self, invite_from_id, service_id, email_address, permissions): data = { 'service': str(service_id), 'email_address': email_address, 'from_user': invite_from_id, 'permissions': permissions } data = _attach_current_user(data) resp = self.post(url='/service/{}/invite'.format(service_id), data=data) return InvitedUser(**resp['data'])
def create_invite(self, invite_from_id, service_id, email_address, permissions, auth_type): data = { 'service': str(service_id), 'email_address': email_address, 'from_user': invite_from_id, 'permissions': ','.join(sorted(translate_permissions_from_admin_roles_to_db(permissions))), 'auth_type': auth_type, 'invite_link_host': self.admin_url, } data = _attach_current_user(data) resp = self.post(url='/service/{}/invite'.format(service_id), data=data) return InvitedUser(**resp['data'])
def test_invite_user(app_, active_user_with_permissions, mocker, sample_invite): service = service_1(active_user_with_permissions) email_address = '*****@*****.**' sample_invite['email_address'] = '*****@*****.**' data = [InvitedUser(**sample_invite)] with app_.test_request_context(): with app_.test_client() as client: client.login(active_user_with_permissions, mocker, service) mocker.patch('app.invite_api_client.get_invites_for_service', return_value=data) mocker.patch('app.user_api_client.get_users_for_service', return_value=[active_user_with_permissions]) mocker.patch('app.invite_api_client.create_invite', return_value=InvitedUser(**sample_invite)) response = client.post(url_for('main.invite_user', service_id=service['id']), data={ 'email_address': email_address, 'send_messages': 'y', 'manage_service': 'y', 'manage_api_keys': 'y' }, follow_redirects=True) assert response.status_code == 200 page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') assert page.h1.string.strip() == 'Team members' flash_banner = page.find( 'div', class_='banner-default-with-tick').string.strip() assert flash_banner == 'Invite sent to [email protected]' expected_permissions = 'manage_api_keys,manage_settings,manage_templates,manage_users,send_emails,send_letters,send_texts,view_activity' # noqa app.invite_api_client.create_invite.assert_called_once_with( sample_invite['from_user'], sample_invite['service'], email_address, expected_permissions)
def test_accepting_invite_removes_invite_from_session( client_request, mocker, sample_invite, mock_get_service, service_one, mock_check_invite_token, mock_get_user_by_email, mock_get_users_by_service, mock_add_user_to_service, mock_accept_invite, mock_get_service_templates, mock_get_template_statistics, mock_get_jobs, mock_get_service_statistics, mock_get_usage, mock_get_inbound_sms_summary, fake_uuid, user, landing_page_title, ): invite = InvitedUser(**sample_invite) user = user(fake_uuid) invite.email_address = user.email_address mocker.patch('app.invite_api_client.check_token', return_value=invite) client_request.login(user) page = client_request.get( 'main.accept_invite', token='thisisnotarealtoken', _follow_redirects=True, ) assert page.h1.string == landing_page_title with client_request.session_transaction() as session: assert 'invited_user' not in session
def add_service(): invited_user = session.get('invited_user') if invited_user: invitation = InvitedUser(**invited_user) # if invited user add to service and redirect to dashboard user = user_api_client.get_user(session['user_id']) service_id = invited_user['service'] user_api_client.add_user_to_service(service_id, user.id, invitation.permissions) invite_api_client.accept_invite(service_id, invitation.id) return redirect( url_for('main.service_dashboard', service_id=service_id)) form = AddServiceForm(service_api_client.find_all_service_email_from) heading = 'Which service do you want to set up notifications for?' if form.validate_on_submit(): email_from = email_safe(form.name.data) service_id = service_api_client.create_service( service_name=form.name.data, active=False, message_limit=current_app.config['DEFAULT_SERVICE_LIMIT'], restricted=True, user_id=session['user_id'], email_from=email_from) session['service_id'] = service_id if (len( service_api_client.get_services({ 'user_id': session['user_id'] }).get('data', [])) > 1): return redirect( url_for('main.service_dashboard', service_id=service_id)) example_sms_template = service_api_client.create_service_template( 'Example text message template', 'sms', 'Hey ((name)), I’m trying out Notify. Today is ((day of week)) and my favourite colour is ((colour)).', service_id) return redirect( url_for('main.send_test', service_id=service_id, template_id=example_sms_template['data']['id'], help=1)) else: return render_template('views/add-service.html', form=form, heading=heading)
def test_accept_invite_does_not_treat_email_addresses_as_case_sensitive( logged_in_client, mocker, api_user_active, sample_invite, service_one, mock_accept_invite, mock_get_user_by_email): # the email address of api_user_active is '*****@*****.**' sample_invite['email_address'] = '*****@*****.**' invite = InvitedUser(**sample_invite) mocker.patch('app.invite_api_client.check_token', return_value=invite) mocker.patch('app.user_api_client.get_users_for_service', return_value=[api_user_active]) response = logged_in_client.get( url_for('main.accept_invite', token='thisisnotarealtoken')) assert response.status_code == 302 assert response.location == url_for('main.service_dashboard', service_id=service_one['id'], _external=True)
def test_shows_registration_page_from_invite( client_request, fake_uuid, email_address, expected_value, ): with client_request.session_transaction() as session: session['invited_user'] = InvitedUser( fake_uuid, fake_uuid, "", email_address, ["manage_users"], "pending", datetime.utcnow(), 'sms_auth', ).serialize() page = client_request.get('main.register_from_invite') assert page.select_one('input[name=name]')['value'] == expected_value
def test_manage_users_shows_invited_user( client_request, mocker, active_user_with_permissions, sample_invite, ): data = [InvitedUser(**sample_invite)] mocker.patch('app.invite_api_client.get_invites_for_service', return_value=data) mocker.patch('app.user_api_client.get_users_for_service', return_value=[active_user_with_permissions]) page = client_request.get('main.manage_users', service_id=SERVICE_ONE_ID) assert page.h1.string.strip() == 'Team members' assert normalize_spaces(page.select('.user-list')[1].text) == ( '[email protected] ' 'Can’t Send messages Can’t Add and edit templates Can’t Manage service Can Access API keys ' 'Cancel invitation' )
def test_manage_users_shows_invited_user( client_request, mocker, active_user_with_permissions, sample_invite, invite_status, expected_text, ): sample_invite['status'] = invite_status data = [InvitedUser(**sample_invite)] mocker.patch('app.invite_api_client.get_invites_for_service', return_value=data) mocker.patch('app.user_api_client.get_users_for_service', return_value=[active_user_with_permissions]) page = client_request.get('main.manage_users', service_id=SERVICE_ONE_ID) assert page.h1.string.strip() == 'Team members' assert normalize_spaces( page.select('.user-list-item')[0].text) == expected_text
def test_if_existing_user_accepts_twice_they_redirect_to_sign_in( app_, mocker, sample_invite, mock_get_service): sample_invite['status'] = 'accepted' invite = InvitedUser(**sample_invite) mocker.patch('app.invite_api_client.check_token', return_value=invite) with app_.test_request_context(): with app_.test_client() as client: response = client.get(url_for('main.accept_invite', token='thisisnotarealtoken'), follow_redirects=True) assert response.status_code == 200 page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') assert page.h1.string.strip() == 'Sign in' flash_banners = page.find_all('div', class_='banner-default') assert len(flash_banners) == 1 assert flash_banners[0].text.strip( ) == 'Please log in to access this page.'
def test_if_existing_user_accepts_twice_they_redirect_to_sign_in( client, mocker, sample_invite, mock_get_service, ): sample_invite['status'] = 'accepted' invite = InvitedUser(**sample_invite) mocker.patch('app.invite_api_client.check_token', return_value=invite) response = client.get(url_for('main.accept_invite', token='thisisnotarealtoken'), follow_redirects=True) assert response.status_code == 200 page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') assert ( page.h1.string, page.select('main p')[0].text.strip(), ) == ( 'You need to sign in again', 'We signed you out because you haven’t used Notify for a while.', )
def sample_invited_user(mocker, sample_invite): return InvitedUser(**sample_invite)
def _check_token(token): return InvitedUser(**sample_invite)
def _accept(service_id, invite_id): return InvitedUser(**sample_invite)
def _get_invited_users(self, invites): invited_users = [] for invite in invites: invited_user = InvitedUser(**invite) invited_users.append(invited_user) return invited_users
def check_token(self, token): resp = self.get(url='/invite/service/{}'.format(token)) return InvitedUser(**resp['data'])