def test_add_user(self): """Ensure a new user can be added to the database.""" add_user('test', '*****@*****.**', 'test') user = User.query.filter_by(email='*****@*****.**').first() user.admin = True db.session.commit() resp_login = self.client.post( '/auth/login', data=json.dumps({ 'email': '*****@*****.**', 'password': '******' }), content_type='application/json', ) token = json.loads(resp_login.data.decode())['auth_token'] with self.client: response = self.client.post( '/users', data=json.dumps({ 'username': '******', 'email': '*****@*****.**', 'password': '******' }), content_type='application/json', headers={'Authorization': f'Bearer {token}'}) data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 201) self.assertIn('[email protected] was added!', data['message']) self.assertIn('success', data['status'])
def test_add_user_inactive(self): add_user('test', '*****@*****.**', 'test') # update user user = User.query.filter_by(email='*****@*****.**').first() user.active = False db.session.commit() with self.client: resp_login = self.client.post('/auth/login', data=json.dumps({ 'email': '*****@*****.**', 'password': '******' }), content_type='application/json') token = json.loads(resp_login.data.decode())['auth_token'] response = self.client.post( '/users', data=json.dumps({ 'username': '******', 'email': '*****@*****.**', 'password': '******' }), content_type='application/json', headers={'Authorization': f'Bearer {token}'}) data = json.loads(response.data.decode()) self.assertTrue(data['status'] == 'fail') self.assertTrue(data['message'] == 'Provide a valid auth token.') self.assertEqual(response.status_code, 401)
def test_add_user_invalid_json_keys(self): """Ensure error is thrown if the JSON object does not have a username key.""" add_user('test', '*****@*****.**', 'test') user = User.query.filter_by(email='*****@*****.**').first() user.admin = True db.session.commit() resp_login = self.client.post('/auth/login', data=json.dumps({ 'email': '*****@*****.**', 'password': '******' }), content_type='application/json') token = json.loads(resp_login.data.decode())['auth_token'] with self.client: response = self.client.post( '/users', data=json.dumps({ 'email': '*****@*****.**', 'password': '******' }), content_type='application/json', headers={'Authorization': f'Bearer {token}'}) data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 400) self.assertIn('Invalid payload.', data['message']) self.assertIn('fail', data['status'])
def test_add_user_not_admin(self): add_user('test', '*****@*****.**', 'test') with self.client: # user login resp_login = self.client.post('/auth/login', data=json.dumps({ 'email': '*****@*****.**', 'password': '******' }), content_type='application/json') token = json.loads(resp_login.data.decode())['auth_token'] response = self.client.post( '/users', data=json.dumps({ 'username': '******', 'email': '*****@*****.**', 'password': '******' }), content_type='application/json', headers={'Authorization': f'Bearer {token}'}) data = json.loads(response.data.decode()) self.assertTrue(data['status'] == 'fail') self.assertTrue( data['message'] == 'You do not have permission to do that.') self.assertEqual(response.status_code, 401)
def test_add_user_duplicate_email(self): """Ensure error is thrown if the email already exists.""" add_user('test', '*****@*****.**', 'test') user = User.query.filter_by(email='*****@*****.**').first() user.admin = True db.session.commit() resp_login = self.client.post('/auth/login', data=json.dumps({ 'email': '*****@*****.**', 'password': '******' }), content_type='application/json') token = json.loads(resp_login.data.decode())['auth_token'] with self.client: self.client.post('/users', data=json.dumps({ 'username': '******', 'email': '*****@*****.**', 'password': '******' }), content_type='application/json', headers={'Authorization': f'Bearer {token}'}) response = self.client.post( '/users', data=json.dumps({ 'username': '******', 'email': '*****@*****.**', 'password': '******' }), content_type='application/json', headers={'Authorization': f'Bearer {token}'}) data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 400) self.assertIn('Sorry. That email already exists.', data['message']) self.assertIn('fail', data['status'])
def post_users(user_id): """ POST /users Adds a new user. model: username, email, password, active, admin, created_at :param user_id: :return: Flask Response """ if not is_admin(user_id): return error_response('You do not have permission to do that.'), 401 data = request.get_json() if not data: return error_response(), 400 username = data.get('username') email = data.get('email') password = data.get('password') # TODO setup validation try: if not User.query.filter( or_(User.username == username, User.email == email)).first(): add_user(username, email, password) return success_response( '{email} was added!'.format(email=email)), 201 return error_response('User already exists.'), 400 except (exc.IntegrityError, ValueError): db.session.rollback() return error_response(), 400
def test_add_user_duplicate_username(self): """ Verify adding a user with a duplicate username raises an error. """ add_user(self.USERNAME, self.EMAIL, self.PASSWORD) duplicate_user = User(username=self.USERNAME, email=self.EMAIL2, password=self.PASSWORD) db.session.add(duplicate_user) self.assertRaises(IntegrityError, db.session.commit)
def test_add_user_duplicate_email(self): """ Verify adding a user with a duplicate email raises an error. """ add_user(USERNAME, EMAIL, PASSWORD) duplicate_user = User(username=USERNAME2, email=EMAIL, password=PASSWORD) db.session.add(duplicate_user) self.assertRaises(IntegrityError, db.session.commit)
def test_main_with_users(self): """Ensure the main route behaves correctly when users have been Jinja Templates added to the database.""" add_user('michael', '*****@*****.**', 'test') add_user('fletcher', '*****@*****.**', 'test') with self.client: response = self.client.get('/') self.assertEqual(response.status_code, 200) self.assertIn(b'All Users', response.data) self.assertNotIn(b'<p>No users!</p>', response.data) self.assertIn(b'michael', response.data) self.assertIn(b'fletcher', response.data)
def test_post_users_duplicate_email(self): """ Verify adding a user with a duplicate email throws an error. """ user = add_user(self.USERNAME, self.EMAIL, self.PASSWORD) with self.client: response = self.client.post( '/users', data=json.dumps({ 'username': self.USERNAME2, 'email': user.email, 'password': self.PASSWORD }), content_type='application/json', headers={ 'Authorization': 'Bearer ' + self.get_jwt(self.admin) } ) data = json.loads(response.data.decode()) self.assertEqual(data['status'], 'error') self.assertEqual( data['message'], 'User already exists.' ) self.assertEqual(response.content_type, 'application/json') self.assert400(response)
def test_all_users(self): """Ensure get all users behaves correctly.""" add_user('michael', '*****@*****.**', 'test') add_user('fletcher', '*****@*****.**', 'test') with self.client: response = self.client.get('/users') data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 200) self.assertEqual(len(data['data']['users']), 2) self.assertIn('michael', data['data']['users'][0]['username']) self.assertIn('*****@*****.**', data['data']['users'][0]['email']) self.assertIn('fletcher', data['data']['users'][1]['username']) self.assertIn('*****@*****.**', data['data']['users'][1]['email']) self.assertIn('success', data['status'])
def post_signup(): """ POST /auth/signup Signs up the new user. requires: { username: '******' email: 'email', password: '******' } :return: flask response """ data = request.get_json() if not data: return error_response(), 400 # TODO validate username = data.get('username') email = data.get('email') password = data.get('password') try: if not User.query.filter( or_(User.username == username, User.email == email)).first(): new_user = add_user(username, email, password) token = new_user.encode_jwt(new_user.id) return success_response('{email} signed up.'.format(email=email), data={'token': token.decode()}), 201 return error_response('User already exists.'), 400 except (exc.IntegrityError, ValueError): db.session.rollback() return error_response(), 400
def test_decode_jwt(self): """ Verify decode_jwt_token decodes a token to an id. """ new_user = add_user(USERNAME, EMAIL, PASSWORD) token = new_user.encode_jwt(new_user.id) self.assertTrue(isinstance(token, bytes)) self.assertEqual(User.decode_jwt(token), new_user.id)
def setUp(self): db.create_all() db.session.commit() self.admin = add_user('admin', '*****@*****.**', 'password') self.admin.admin = True db.session.commit()
def test_add_user_admin(self): user = add_user('justatest', '*****@*****.**', 'test') self.assertTrue(user.id) self.assertEqual(user.username, 'justatest') self.assertEqual(user.email, '*****@*****.**') self.assertTrue(user.active) self.assertTrue(user.password) self.assertFalse(user.admin) # new
def test_single_user(self): """Ensure get single user behaves correctly.""" user = add_user('michael', '*****@*****.**', 'test') with self.client: response = self.client.get(f'/users/{user.id}') data = json.loads(response.data.decode()) self.assertEqual(response.status_code, 200) self.assertIn('michael', data['data']['username']) self.assertIn('*****@*****.**', data['data']['email']) self.assertIn('success', data['status'])
def test_get_users(self): """ Verify GET /users returns users ordered by created_at. """ created = datetime.datetime.utcnow() + datetime.timedelta(-30) user = add_user(self.USERNAME, self.EMAIL, self.PASSWORD, created) user2 = add_user(self.USERNAME2, self.EMAIL2, self.PASSWORD) with self.client: response = self.client.get( '/users' ) data = json.loads(response.data.decode()) self.assertEqual(data['status'], 'success') self.assertEqual(data['message'], 'Users fetched.') self.assertEqual(len(data['data']['users']), 3) self.assertEqual( data['data']['users'][0]['username'], self.admin.username ) self.assertEqual( data['data']['users'][0]['email'], self.admin.email ) self.assertEqual( data['data']['users'][1]['username'], user2.username ) self.assertEqual( data['data']['users'][1]['email'], user2.email ) self.assertEqual( data['data']['users'][2]['username'], user.username ) self.assertEqual( data['data']['users'][2]['email'], user.email ) self.assertIn('created_at', data['data']['users'][1]) self.assertIn('created_at', data['data']['users'][2]) self.assertEqual(response.content_type, 'application/json') self.assert200(response)
def test_add_user(self): """ Verify a new user can be added to the database. """ new_user = add_user(USERNAME, EMAIL, PASSWORD) self.assertTrue(new_user.id) self.assertEqual(new_user.username, USERNAME) self.assertEqual(new_user.email, EMAIL) self.assertTrue(new_user.password) self.assertTrue(new_user.active) self.assertTrue(new_user.created_at) self.assertFalse(new_user.admin)
def test_get_signout(self): """ Verify users can sign out. """ user = add_user(USERNAME, EMAIL, PASSWORD) with self.client: token = get_jwt(self.client, user.email) response = self.client.get( '/auth/signout', headers={'Authorization': 'Bearer ' + token}) data = json.loads(response.data.decode()) self.assertEqual(data['status'], 'success') self.assertEqual(data['message'], '{email} signed out.'.format(email=user.email)) self.assert200(response)
def test_get_signout_user_with_expired_token(self): """ Verify signing out a user with an expired token throws an error. """ user = add_user(USERNAME, EMAIL, PASSWORD) with self.client: token = get_jwt(self.client, user.email) time.sleep(4) response = self.client.get( '/auth/signout', headers={'Authorization': 'Bearer ' + token}) data = json.loads(response.data.decode()) self.assertEqual(data['status'], 'error') self.assertEqual(data['message'], 'Signature expired. Signin again.') self.assert401(response)
def test_get_profile_inactive_user(self): """ Verify getting the profile of an inactive user throws an error. """ user = add_user(USERNAME, EMAIL, PASSWORD) user.active = False db.session.commit() with self.client: token = get_jwt(self.client, user.email) response = self.client.get( '/auth/profile', headers={'Authorization': 'Bearer ' + token}) data = json.loads(response.data.decode()) self.assertEqual(data['status'], 'error') self.assertEqual(data['message'], 'Something went wrong. Please contact us.') self.assert401(response)
def test_get_users_by_id(self): """ Verify GET request to /users/{user_id} fetches a user. """ user = add_user(USERNAME, EMAIL, PASSWORD) with self.client: response = self.client.get( '/users/{user_id}'.format(user_id=user.id)) data = json.loads(response.data.decode()) self.assertEqual(data['status'], 'success') self.assertEqual(data['message'], 'User {user_id} fetched.'.format(user_id=user.id)) self.assertEqual(data['data']['username'], 'test') self.assertEqual(data['data']['email'], '*****@*****.**') self.assertIn('created_at', data['data']) self.assertEqual(response.content_type, 'application/json') self.assert200(response)
def test_get_profile(self): """ Verify user can get profile with valid token. """ user = add_user(USERNAME, EMAIL, PASSWORD) with self.client: token = get_jwt(self.client, user.email) response = self.client.get( '/auth/profile', headers={'Authorization': 'Bearer ' + token}) data = json.loads(response.data.decode()) self.assertEqual(data['status'], 'success') self.assertEqual( data['message'], "Fetched {email}'s profile data.".format(email=user.email)) self.assertEqual(data['data']['username'], user.username) self.assertEqual(data['data']['email'], user.email) self.assertTrue(data['data']['active']) self.assertTrue(data['data']['created_at']) self.assert200(response)
def test_get_profile_expired_token(self): """ Verify user cannot get profile with an expired token. """ current_app.config['TOKEN_EXPIRATION_SECONDS'] = -1 user = add_user(self.USERNAME, self.EMAIL, self.PASSWORD) with self.client: response = self.client.get( '/auth/signout', headers={ 'Authorization': 'Bearer ' + self.get_jwt(user) } ) data = json.loads(response.data.decode()) self.assertEqual(data['status'], 'error') self.assertEqual( data['message'], 'Signature expired. Signin again.' ) self.assert401(response)
def test_post_users_with_not_admin_user_token(self): """ Verify non admins cannot add a new user. """ user = add_user(USERNAME, EMAIL, 'password') with self.client: token = get_jwt(self.client, user.email) response = self.client.post( '/users', data=json.dumps({ 'username': '******', 'email': EMAIL2, 'password': PASSWORD }), content_type='application/json', headers={'Authorization': 'Bearer ' + token}) data = json.loads(response.data.decode()) self.assertEqual(data['status'], 'error') self.assertEqual(data['message'], 'You do not have permission to do that.') self.assert401(response)
def test_get_profile_inactive_user(self): """ Verify an inactive user cannot get profile. """ user = add_user(self.USERNAME, self.EMAIL, self.PASSWORD) user.active = False db.session.commit() with self.client: response = self.client.get( '/auth/profile', headers={ 'Authorization': 'Bearer ' + self.get_jwt(user) } ) data = json.loads(response.data.decode()) self.assertEqual(data['status'], 'error') self.assertEqual( data['message'], 'Something went wrong. Please contact us.' ) self.assert401(response)
def test_post_users_duplicate_username(self): """ Verify adding a user with a duplicate username throws an error. """ admin = add_admin() user = add_user(USERNAME, EMAIL, PASSWORD) with self.client: token = get_jwt(self.client, admin.email) response = self.client.post( '/users', data=json.dumps({ 'username': user.username, 'email': EMAIL2, 'password': PASSWORD }), content_type='application/json', headers={'Authorization': 'Bearer ' + token}) data = json.loads(response.data.decode()) self.assertEqual(data['status'], 'error') self.assertEqual(data['message'], 'User already exists.') self.assertEqual(response.content_type, 'application/json') self.assert400(response)
def test_post_users_inactive_user(self): """ Verify adding an inactive user throws an error. """ user = add_user(USERNAME, EMAIL, PASSWORD) user.active = False db.session.commit() with self.client: token = get_jwt(self.client, user.email) response = self.client.post( '/users', data=json.dumps({ 'username': USERNAME2, 'email': EMAIL2, 'password': PASSWORD }), content_type='application/json', headers={'Authorization': 'Bearer ' + token}) data = json.loads(response.data.decode()) self.assertEqual(data['status'], 'error') self.assertEqual(data['message'], 'Something went wrong. Please contact us.') self.assert401(response)
def test_encode_jwt(self): """ Verify encode_jwt encodes an id to a token. """ new_user = add_user(USERNAME, EMAIL, PASSWORD) token = new_user.encode_jwt(new_user.id) self.assertTrue(isinstance(token, bytes))
def test_passwords_are_random(self): """ Verify passwords are random. """ user1 = add_user(USERNAME, EMAIL, PASSWORD) user2 = add_user(USERNAME2, EMAIL2, PASSWORD) self.assertNotEqual(user1.password, user2.password)