from datetime import datetime from flask_jwt_extended import create_access_token from app.model import Roles, User, Application, Applicant from app_common.const import BAD_USER_ROLES, MALFORMED_DATA from .conftest import MOCK_NETWORK_ADMIN_USER, MOCK_USER_1, assert_200, assert_401, assert_404, assert_response_json_equal, assert_in, assert_not_in, assert_400, assert_error_type, \ assert_equal, assert_message def test_user(client): url = f'/api/network_admin/ajax/user/{MOCK_USER_1.user_id}' access_token = create_access_token(MOCK_NETWORK_ADMIN_USER) headers = {'Auth-Token': f'Bearer {access_token}'} resp = client.get(url, headers=headers) expected = { 'user_id': MOCK_USER_1.user_id, 'roles': MOCK_USER_1.roles, 'email': MOCK_USER_1.email, 'join_date': MOCK_USER_1.join_date.strftime('%b %d, %Y'), 'date_of_birth': MOCK_USER_1.date_of_birth.strftime('%b %d, %Y'), 'phone_number': MOCK_USER_1.phone_number, 'first_name': MOCK_USER_1.first_name, 'last_name': MOCK_USER_1.last_name, 'middle_init_or_name': '' } assert_response_json_equal(resp, expected) # we should be able to edit the user data = {k: v for k, v in expected.items()} data.pop('user_id') data['email'] = 'new@email.com' resp = client.post(url, data=data, headers=headers) assert_200(resp) # if we get the user, it should be different resp = client.get(url, headers=headers) assert_200(resp) expected.update(data) assert_response_json_equal(resp, expected) # ONLY the network admin users (or admin users) should be able to call this endpoint bad_access_token = create_access_token(MOCK_USER_1) headers = {'Auth-Token': f'Bearer {bad_access_token}'} for func in [client.get, client.put, client.delete, client.post]: resp = func(url, headers=headers) assert_401(resp) # if we delete the user, it should go away headers = {'Auth-Token': f'Bearer {access_token}'} resp = client.delete(url, headers=headers) assert_200(resp) for func in [client.get, client.delete, client.post]: # trying any call should not result in a 404 resp = func(url, headers=headers) assert_404(resp) # we should now be able to PUT the user data['password'] = 'foobar' resp = client.put(url, headers=headers, data=data) assert_200(resp) # we should now get the expected data to be set now data.pop('password') resp = client.get(url, data=data, headers=headers) assert_200(resp) data['join_date'] = datetime.utcnow().date().strftime('%b %d, %Y') expected.update(data) assert_response_json_equal(resp, expected) def test_user_roles(client): user = User.objects(user_id=MOCK_USER_1.user_id).first() url = f'/api/network_admin/ajax/user/{MOCK_USER_1.user_id}/roles' data = {'roles': Roles.NETWORK_ADMIN} access_token = create_access_token(MOCK_NETWORK_ADMIN_USER) headers = {'Auth-Token': f'Bearer {access_token}'} assert_not_in(Roles.NETWORK_ADMIN, user.roles) # bad roles should produce a "BAD_USER_ROLES" error type data['roles'] = 'invalid_role' resp = client.post(url, headers=headers, data=data) assert_400(resp) assert_error_type(resp, BAD_USER_ROLES) data['roles'] = str(Roles.NETWORK_ADMIN) # The user should not be a network admin resp = client.post(url, headers=headers, data=data) assert_200(resp) user = User.objects(user_id=MOCK_USER_1.user_id).first() assert_in(Roles.NETWORK_ADMIN, user.roles) # if we do a force, any previous roles should be removed data['force_match'] = True resp = client.post(url, headers=headers, data=data) assert_200(resp) user = User.objects(user_id=MOCK_USER_1.user_id).first() assert_equal(user.roles, data['roles'].split(',')) # now that user should be able to call the endpoint to change it's role user_acc_token = create_access_token(user) data = {'roles': Roles.NETWORK_ADMIN} headers = {'Auth-Token': f'Bearer {user_acc_token}'} resp = client.delete(url, headers=headers, data=data) assert_200(resp) user = User.objects(user_id=MOCK_USER_1.user_id).first() assert_not_in(Roles.NETWORK_ADMIN, user.roles) # now the user should no longer be able to access that endpoint user_acc_token = create_access_token(user) headers = {'Auth-Token': f'Bearer {user_acc_token}'} resp = client.post(url, headers=headers, data=data) assert_401(resp) # we should get a 404 if we try to do anything with a non existant user bad_url = f'/api/network_admin/ajax/user/not-a-user/roles' headers = {'Auth-Token': f'Bearer {access_token}'} resp = client.get(bad_url, headers=headers) assert_404(resp) def test_get_users(client): url = 'api/network_admin/users' headers = {'Auth-Token': f'Bearer {create_access_token(MOCK_NETWORK_ADMIN_USER)}'} resp = client.get(url, headers=headers) assert_200(resp) assert_equal(len(resp.json), 3) # now try filtering by only applicants (should return 1 user) data = {'roles': 'applicant'} resp = client.get(url, headers=headers, data=data) assert_200(resp) assert_equal(len(resp.json), 1) # if we also allow network admins, we should get a response of len 2... data['roles'] = 'applicant,network_admin' resp = client.get(url, headers=headers, data=data) assert_equal(len(resp.json), 2) # if we send an invalid role data['roles'] = 'applicant,invalid_role' resp = client.get(url, headers=headers, data=data) assert_400(resp) assert_error_type(resp, BAD_USER_ROLES) def test_get_user_application(client): url = f'api/network_admin/ajax/user/{MOCK_USER_1.user_id}/application' headers = {'Auth-Token': f'Bearer {create_access_token(MOCK_NETWORK_ADMIN_USER)}'} resp = client.get(url, headers=headers) assert_404(resp) assert_in('No application found for user', resp.json['message']) # add an application and see if we get it application = Application(applicants=[Applicant(email=MOCK_USER_1.email)], user_id=MOCK_USER_1.user_id) application.save() resp = client.get(url, headers=headers) assert_200(resp) assert_in('user', resp.json) assert_in('application', resp.json)