def dummy_user(): """ A fixture that creates and saves a user to the database that is to be used for testing purposes """ user = Users("User", "*****@*****.**", Users.generate_hash("wfnbqk".encode("utf8")).decode("utf8"), True, True) user.save() user.commit() return user
def get_dummy_user(self) -> Users: """ Creates a dummy user to be used in the unit tests for Users :return: a user """ new_user = Users("fullname", '*****@*****.**', Users.generate_hash('top_secret'.encode("utf-8")), True, True) new_user.save() new_user.commit() return new_user
class ForgotPasswordTestCase(unittest.TestCase): """ Test user can reset their password using the forgot password endpoint """ def setUp(self): """ Create testing client version of flask app and persist a temporary user """ self.test_app = create_app(DATABASE_NAME='test_analytics', TESTING=True) self.testing_client = self.test_app.test_client() self.testing_client_context = self.test_app.app_context() self.testing_client_context.push() self.dummy_user = Users("Joey", "*****@*****.**", Users.generate_hash("1234".encode( "utf8")).decode("utf8"), True, True) self.dummy_user.save() self.dummy_user.commit() def tearDown(self): """ Remove temporary user from database""" self.testing_client_context.pop() self.dummy_user.delete() self.dummy_user.commit() def test_forgot_password(self): """ Test forgot password sets user's password to a system generated password """ forgotten_password = self.dummy_user.password response = self.testing_client.post('/forgot_password', data=dict( email=self.dummy_user.email)) self.assertIn(b"success", response.data) self.assertEquals(response.status_code, 200) updated_user = Users.find_by_email(self.dummy_user.email) self.assertNotEqual(updated_user.password, forgotten_password) def test_forgot_password_failure(self): """ Test authentication failure and correct status code """ response = self.testing_client.post('/forgot_password', data=dict( email="*****@*****.**")) self.assertIn(b"cannot find user", response.data) self.assertEquals(response.status_code, 403)
def create_admin_user(self) -> Users: """ Create Admin user :return: an admin user """ password_hash = bcrypt.hashpw("wfnbqk".encode("utf-8"), bcrypt.gensalt()) user = Users.find_by_email("*****@*****.**") if not user: user = Users("Admin", "*****@*****.**", password_hash.decode("utf8"), True, True) try: user.save() user.commit() except Exception as e: pass return user
def dummy_user(): """ Create and save regular user to the database for duration of test and delete it afterwards """ user = Users("Dummy", "*****@*****.**", Users.generate_hash("1234".encode("utf8")).decode("utf8"), True, True) try: user.save() user.commit() except Exception as e: pass yield user db.session.delete(user) db.session.commit()
def admin_user(): """ Create and save admin user to the database for duration of test and delete it afterwards """ user = Users("Admin", "*****@*****.**", Users.generate_hash("wfnbqk".encode("utf8")).decode("utf8"), True, True) try: user.save() user.commit() except Exception as e: pass yield user db.session.delete(user) db.session.commit()
def create_admin_user() -> Users: """ Create an Admin user :return: an Admin user """ password_hash = bcrypt.hashpw("@p@22M0rd#@!".encode("utf-8"), bcrypt.gensalt()) user = Users.find_by_email("test_admin_user@no_an_email.cr") if not user: user = Users("test_admin_user", "test_admin_user@no_an_email.cr", password_hash.decode("utf8"), True, True) try: user.save() user.commit() except Exception as e: pass return user
def post(self) -> (dict, int): """ API resource class which creates a new user and adds it to the database Parameters can be passed using a POST request that contains a JSON with the following fields: :required: valid access JWT where the admin claim has to be true :param email: users email address :param fullname: users fullname :param admin: whether the user will be an admin user or not :param password: users password :type email: str :type fullname: str :type admin: str :type password: str :return: A message indicating a successful or unsuccessful addition of user to the database """ args = self.post_reqparser.parse_args() # User needs admin rights to continue if not get_jwt_claims()['admin']: abort(HTTPStatus.FORBIDDEN.value, error="administration privileges required") # Check email address supplied is actually an email address args["email"].lower() # if not Users.email_regex_checker(args["email"]): # abort(HTTPStatus.BAD_REQUEST.value, error="{} is not a valid email".format(args["email"])) # Is the user email already registered if self._does_user_exsist(args["email"]): abort(HTTPStatus.BAD_REQUEST.value, error='User email exists. email address must be unique') # Create new user database entry in users table try: hashed_password = Users.generate_hash( args["password"].encode("utf-8")).decode("utf-8") new_user = Users(args["fullname"], args["email"], hashed_password, bool(args["admin"]), False) new_user.save() new_user.commit() except Exception as e: abort(HTTPStatus.BAD_REQUEST.value, error=e, admin=get_jwt_claims()['admin']) return ({ "user": "******".format(args["email"]) }), 201
def generate_access_token(self) -> {str, str}: """ Generate admin access JWT. :return: a HTTP authorization header containing a admin access token """ admin_user = Users("Admin user", "*****@*****.**", Users.generate_hash(b"1234").decode("utf8"), True, True) admin_user.save() admin_user.commit() response_login = self.testing_client.post('/login', data=dict( email="*****@*****.**", password="******", remember=True)) response_login_json = response_login.get_json() admin_user.delete() admin_user.commit() return {'Authorization': 'Bearer {}'.format( response_login_json["access_token"])}
def test_user_email_duplication() -> NoReturn: """ test that duplication of a user email is not possible """ json_data = { "email": "*****@*****.**", "fullname": "fullname", "admin": True, "password": "******" } new_user = Users("fullname", '*****@*****.**', Users.generate_hash('top_secret'.encode("utf-8")), True, True) new_user.save() new_user.commit() response = dependencies.client.post('/admin/create_new_user', json=json_data, headers=dependencies.auth_header, follow_redirects=True) assert response.status_code == 400 new_user.delete() new_user.commit()
def generate_access_token(self) -> dict: """ Remove the entries that were persisted in the simulate_importer method :return: a HTTP authorization header containing a admin access token """ admin_user = Users("Admin user", "*****@*****.**", Users.generate_hash(b"1234").decode("utf8"), True, True) admin_user.save() admin_user.commit() response_login = self.testing_client.post('/login', data=dict( email="*****@*****.**", password="******", remember=True)) response_login_json = response_login.get_json() admin_user.delete() admin_user.commit() return { 'Authorization': 'Bearer {}'.format(response_login_json["access_token"]) }
class CelryTestCase(unittest.TestCase): """ Test whether user can request and receive a prediction task asynchronously """ def setUp(self): """ Create testing client version of flask app """ self.test_app = create_app(DATABASE_NAME='test_analytics', TESTING=True) self.testing_client = self.test_app.test_client() self.testing_client_context = self.test_app.app_context() self.testing_client_context.push() self.dummy_user = Users( "Joey", "*****@*****.**", Users.generate_hash("1234".encode("utf8")).decode("utf8"), True, True) self.dummy_user.save() self.dummy_user.commit() def tearDown(self): """ Remove testing client context """ self.testing_client_context.pop() self.dummy_user.delete() self.dummy_user.commit() def test_async_prediction(self): """ Test whether the correct response is sent when a user makes an async requests for a prediction """ response = self.testing_client.get( '/data?limit=100&attributedata=NO2&predictions=True' '&n_predictions=200&per_sensor=True') self.assertIn(b"Forecasting engine making predictions", response.data) self.assertIn(b"task_id", response.data) def test_async_polling_and_reception(self): """ Test whether a user can poll the /predict_status endpoint for the state of their async request """ response = self.testing_client.get( '/data?limit=100&attributedata=NO2&predictions=True' '&n_predictions=200&per_sensor=True') self.assertIn(b"Forecasting engine making predictions", response.data) self.assertIn(b"task_id", response.data) response_json = response.get_json() task_id = response_json[1]["task_id"] response_poll = self.testing_client.get( "/pred_status?task_id={}".format(task_id)) response_poll_json = response_poll.get_json() while response_poll_json["state"] in ["PENDING", "PROGRESS"]: response_poll = self.testing_client.get( "/pred_status?task_id={}".format(task_id)) response_poll_json = response_poll.get_json() self.assertEqual(response_poll_json["state"], "SUCCESS") def test_adding_prediction_per_user(self): """ Test whether a prediction result is associated with a user in the userpredictions table """ response = self.testing_client.get( '/data?limit=3&attributedata=NO2&predictions=True' '&n_predictions=3') self.assertIn(b"Forecasting engine making predictions", response.data) self.assertIn(b"task_id", response.data) response_json = response.get_json() task_id = response_json[1]["task_id"] response_poll = self.testing_client.get( "/pred_status?task_id={}".format(task_id)) response_poll_json = response_poll.get_json() while response_poll_json["state"] in ["PENDING", "PROGRESS"]: response_poll = self.testing_client.get( "/pred_status?task_id={}".format(task_id)) response_poll_json = response_poll.get_json() self.assertEqual(response_poll_json["state"], "SUCCESS") self.assertIsNotNone(response_poll_json["result"]["Prediction_id"])