def test_get_all_topics_empty_payload(self): user_test = { "email": "*****@*****.**", "name": "Name", "password": "******" } user = User(**user_test) user.insert() with self.client: login = self.client.post( "/user/login", data=json.dumps({ "email": user.email, "password": "******" }), content_type="application/json", ) login_data = json.loads(login.data.decode()) token = login_data.get("token") get_topics = self.client.get( "/topics", data=json.dumps({}), content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) get_topics_data = json.loads(get_topics.data.decode()) self.assertEqual(get_topics.status_code, 400) self.assertEqual(get_topics_data["message"], "Invalid payload.")
def test_invalid_logout_expired_token(self): """Ensure that a user with expired token cannot log out.""" data_test = { "name": "james", "email": "*****@*****.**", "password": "******", } user = User(**data_test) user.insert() current_app.config['JWT_ACCESS_TOKEN_EXPIRES'] = 1 with self.client: resp_login = self.client.post( "/user/login", data=json.dumps({ "email": data_test["email"], "password": data_test["password"] }), content_type="application/json" ) token = json.loads(resp_login.data.decode()).get("token") time.sleep(3) response = self.client.get( "/user/logout", headers={"Authorization": f"Bearer {token}"} ) data = json.loads(response.data) self.assertTrue( data["message"] == "Signature expired. Please log in again." ) self.assertEqual(response.status_code, 401)
def test_delete_topic_invalid_id(self): user_test = { "email": "*****@*****.**", "name": "Name", "password": "******" } user = User(**user_test) user.insert() with self.client: login = self.client.post( "/user/login", data=json.dumps({ "email": user.email, "password": "******" }), content_type="application/json", ) login_data = json.loads(login.data.decode()) token = login_data.get("token") delete_topic = self.client.delete( f"/topic/{None}", content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) delete_topic_data = json.loads(delete_topic.data.decode()) self.assertEqual(delete_topic.status_code, 400) self.assertEqual("Invalid payload.", delete_topic_data["message"])
def test_get_all_topics(self): user_test = { "email": "*****@*****.**", "name": "Name", "password": "******" } user = User(**user_test) user.insert() with self.client: login = self.client.post( "/user/login", data=json.dumps({ "email": user.email, "password": "******" }), content_type="application/json", ) login_data = json.loads(login.data.decode()) token = login_data.get("token") current_app.config['PAGE_COUNT'] = None get_topics = self.client.get( "/topics", data=json.dumps({"page": 1}), content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) get_topics_data = json.loads(get_topics.data.decode()) self.assertEqual(get_topics.status_code, 200) self.assertIsInstance(get_topics_data["data"], list)
def test_jwt_is_invalid(self): """Ensure that the token provided is in the correct format.""" data_test = { "name": "juan", "email": "*****@*****.**", "password": "******", } user = User(**data_test) user.insert() with self.client: response = self.client.post( "/user/login", data=json.dumps({ "email": data_test["email"], "password": data_test["password"] }), content_type="application/json" ) data = json.loads(response.data) token = data.get("token") with self.assertRaises(Exception) as context: get_jti(token + "something-invalid") self.assertIn( "Signature verification failed", str(context.exception) )
def test_create_topic_invalid_json(self): """Ensure error is thrown if the JSON object is empty.""" user_test = { "email": "*****@*****.**", "name": "Name", "password": "******" } data_test = {} user = User(**user_test) user.insert() with self.client: login = self.client.post( "/user/login", data=json.dumps({ "email": user.email, "password": "******" }), content_type="application/json", ) login_data = json.loads(login.data.decode()) token = login_data.get("token") create_topic = self.client.post( "/topic", data=json.dumps(data_test), content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) create_topic_data = json.loads(create_topic.data) self.assertEqual(create_topic.status_code, 400) self.assertIn( "Invalid payload.", create_topic_data["message"] )
def test_delete_topic_not_exists(self): user_test = { "email": "*****@*****.**", "name": "Name", "password": "******" } user = User(**user_test) user.insert() with self.client: login = self.client.post( "/user/login", data=json.dumps({ "email": user.email, "password": "******" }), content_type="application/json", ) login_data = json.loads(login.data.decode()) token = login_data.get("token") delete_topic = self.client.delete( "/topic/56f58f16-8c87-4855-8fc4-cc1ba7397a18", content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) delete_topic_data = json.loads(delete_topic.data.decode()) self.assertEqual(delete_topic.status_code, 404) self.assertEqual( delete_topic_data["message"], "Topic does not exists." )
def test_create_topic_has_missing_keys(self): user_test = { "email": "*****@*****.**", "name": "Name", "password": "******" } user = User(**user_test) user.insert() with self.client: login = self.client.post( "/user/login", data=json.dumps({ "email": user.email, "password": "******" }), content_type="application/json", ) login_data = json.loads(login.data.decode()) token = login_data.get("token") create_topic = self.client.post( "/topic", data=json.dumps({ "description": "User 1 Description" }), content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) create_topic_data = json.loads( create_topic.data.decode() ) self.assertEqual(create_topic.status_code, 400) self.assertIn( "Invalid payload.", create_topic_data["message"] )
def test_valid_logout(self): """Ensure that a logged in user can log out.""" data_test = { "name": "james", "email": "*****@*****.**", "password": "******", } user = User(**data_test) user.insert() with self.client: resp_login = self.client.post( "/user/login", data=json.dumps({ "email": data_test["email"], "password": data_test["password"] }), content_type="application/json" ) token = json.loads(resp_login.data)["token"] response = self.client.get( "/user/logout", headers={"Authorization": f"Bearer {token}"} ) data = json.loads(response.data.decode()) self.assertTrue(data["message"] == "Successfully logged out.") self.assertEqual(response.status_code, 200)
def test_passwords_are_random(self): user_one = User(name="justatest", email="*****@*****.**", password="******") user_two = User(name="justatest2", email="*****@*****.**", password="******") self.assertNotEqual(user_one.password_hash, user_two.password_hash)
def test_not_allowed_more_than_one_concurrent_user(self): """Ensure that only one token per user is valid. First user logs in using account X: Gets a valid token A. Second user logs in using account X: Gets a valid token B. token A becomes invalid. """ data_test = { "name": "juan", "email": "*****@*****.**", "password": "******", } user = User(**data_test) user.insert() with self.client: first_login = self.client.post( "/user/login", data=json.dumps({ "email": data_test["email"], "password": data_test["password"] }), content_type="application/json" ) second_login = self.client.post( "/user/login", data=json.dumps({ "email": data_test["email"], "password": data_test["password"] }), content_type="application/json" ) data1 = json.loads(first_login.data.decode()) data2 = json.loads(second_login.data.decode()) token1 = data1.get("token") token2 = data2.get("token") # TODO: Change the route to /topic once implemented. logout1 = self.client.get( "/user/logout", headers={"Authorization": f"Bearer {token1}"} ) logout2 = self.client.get( "/user/logout", headers={"Authorization": f"Bearer {token2}"} ) data1 = json.loads(logout1.data.decode()) data2 = json.loads(logout2.data.decode()) self.assertTrue(logout1.status_code == 401) self.assertEqual( data1["message"], "Invalid token. Please log in again." ) self.assertTrue(logout2.status_code == 200) self.assertEqual( data2["message"], "Successfully logged out." )
def test_create_topic_loggedin_user(self): """ Ensure that a logged in user can create a topic to the database. """ user_test = { "email": "*****@*****.**", "name": "Name", "password": "******" } data_test = { "subject": "Topic 1", "description": "This is the description for Topic 1" } user = User(**user_test) user.insert() with self.client: login = self.client.post( "/user/login", data=json.dumps({ "email": user.email, "password": "******" }), content_type="application/json", ) login_data = json.loads(login.data.decode()) token = login_data.get("token") create_topic = self.client.post( "/topic", data=json.dumps(data_test), content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) create_topic_data = json.loads(create_topic.data) self.assertEqual(create_topic.status_code, 201) self.assertTrue(uuid_pattern_matched(create_topic_data["id"])) self.assertEqual( data_test["subject"], create_topic_data["subject"] ) self.assertEqual( data_test["description"], create_topic_data["description"] ) self.assertIsInstance( create_topic_data["created_by"], dict ) self.assertTrue( create_topic_data["updated_by"], dict ) self.assertTrue( iso8601_pattern_matched(create_topic_data["created_at"]) ) self.assertTrue( iso8601_pattern_matched(create_topic_data["updated_at"]) )
def test_add_user_duplicate_email(self): user = User(name="testname", email="*****@*****.**", password="******") user.insert() duplicate_user = User(name="testname", email="*****@*****.**", password="******") db.session.add(duplicate_user) self.assertRaises(IntegrityError, db.session.commit)
def test_topic_message_relationship(self): user = User(name="testname", email="*****@*****.**", password="******") user.insert() topic = Topic(subject="subject", description="description", created_by=user.id.__str__(), updated_by=user.id.__str__()) topic.insert() self.assertIsInstance(topic.messages.all(), list)
def test_topic_json(self): user = User(name="testname", email="*****@*****.**", password="******") user.insert() topic = Topic(subject="subject", description="description", created_by=user.id.__str__(), updated_by=user.id.__str__()) topic.insert() self.assertTrue(isinstance(topic.json(), dict))
def test_topic_user_relationship(self): user = User(name="testname", email="*****@*****.**", password="******") user.insert() topic = Topic(subject="subject", description="description", created_by=user.id.__str__(), updated_by=user.id.__str__()) topic.insert() self.assertEqual(user.id, topic.created_by) self.assertEqual(user.id, topic.updated_by)
def test_add_user(self): user = User(name="testname", email="*****@*****.**", password="******") user.insert() self.assertTrue(user.id) self.assertTrue(uuid_pattern_matched(user.id.__str__())) self.assertEqual(user.name, 'testname') self.assertEqual(user.email, '*****@*****.**') self.assertTrue(user.created_at) self.assertTrue(iso8601_pattern_matched(user.created_at)) self.assertTrue(user.updated_at) self.assertTrue(iso8601_pattern_matched(user.updated_at))
def test_delete_topic_not_owned(self): user_test1 = { "email": "*****@*****.**", "name": "Name", "password": "******" } user_test2 = { "email": "*****@*****.**", "name": "Name2", "password": "******" } user1 = User(**user_test1) user2 = User(**user_test2) user1.insert() user2.insert() with self.client: login = self.client.post( "/user/login", data=json.dumps({ "email": user1.email, "password": "******" }), content_type="application/json", ) login_data = json.loads(login.data.decode()) token = login_data.get("token") create_topic = self.client.post( "/topic", data=json.dumps({ "subject": "User 1 Subject", "description": "User 1 Description" }), content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) create_topic_data = json.loads( create_topic.data.decode() ) topic_id = create_topic_data["id"] login2 = self.client.post( "/user/login", data=json.dumps({ "email": user2.email, "password": "******" }), content_type="application/json", ) login_data2 = json.loads(login2.data.decode()) token_2 = login_data2.get("token") delete_topic = self.client.delete( f"/topic/{topic_id}", content_type="application/json", headers={"Authorization": f"Bearer {token_2}"} ) delete_topic_data = json.loads(delete_topic.data.decode()) self.assertEqual(delete_topic.status_code, 401) self.assertEqual( delete_topic_data["message"], "You do not have permission to do that." )
def test_create_topic_invalid_json_keys(self): """ Ensure error is thrown if the JSON keys are invalid. """ user_test = { "email": "*****@*****.**", "name": "Name", "password": "******" } user = User(**user_test) user.insert() with self.client: login = self.client.post( "/user/login", data=json.dumps({ "email": user.email, "password": "******" }), content_type="application/json", ) login_data = json.loads(login.data.decode()) token = login_data.get("token") one_key_valid = self.client.post( "/topic", data=json.dumps({ "subject": "", "invalid_key": "" }), content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) description_only = self.client.post( "/topic", data=json.dumps({"description": ""}), content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) one_key_valid_data = json.loads(one_key_valid.data) description_only_data = json.loads(description_only.data) self.assertEqual(one_key_valid.status_code, 400) self.assertEqual(description_only.status_code, 400) self.assertIn( "Invalid payload.", one_key_valid_data["message"] ) self.assertIn( "Invalid payload.", description_only_data["message"] )
def test_password_attribute_is_protected(self): user = User(name="justatest", email="*****@*****.**", password="******") with self.assertRaises(Exception) as context: user.password self.assertIn("password is not a readable attribute", str(context.exception))
def test_get_topic(self): user_test = { "email": "*****@*****.**", "name": "Name", "password": "******" } user = User(**user_test) user.insert() with self.client: login = self.client.post( "/user/login", data=json.dumps({ "email": user.email, "password": "******" }), content_type="application/json", ) login_data = json.loads(login.data.decode()) token = login_data.get("token") create_topic = self.client.post( "/topic", data=json.dumps({ "subject": "Something", "description": "User 1 Description" }), content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) create_topic_data = json.loads( create_topic.data.decode() ) get_topic = self.client.get( f"/topic/{create_topic_data['id']}", content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) get_topic_data = json.loads( get_topic.data.decode() ) self.assertEqual(get_topic.status_code, 200) self.assertIsInstance( get_topic_data["data"], dict )
def test_update_topic_invalid_json_keys(self): user_test = { "email": "*****@*****.**", "name": "Name", "password": "******" } user = User(**user_test) user.insert() with self.client: login = self.client.post( "/user/login", data=json.dumps({ "email": user.email, "password": "******" }), content_type="application/json", ) login_data = json.loads(login.data.decode()) token = login_data.get("token") create_topic = self.client.post( "/topic", data=json.dumps({"subject": "subject", "description": "desc"}), content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) create_topic_data = json.loads( create_topic.data.decode() ) test_update_data = { "subjectxsz": "Updated subject", "description": "Updated description" } update_topic = self.client.patch( f"/topic/{create_topic_data['id']}", data=json.dumps(test_update_data), content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) update_topic_data = json.loads(update_topic.data.decode()) self.assertEqual(update_topic.status_code, 400) self.assertEqual( update_topic_data["message"], "Invalid payload." )
def test_registered_user_login(self): """Ensure that a registered user can login.""" data_test = { "name": "juan", "email": "*****@*****.**", "password": "******", } user = User(**data_test) user.insert() with self.client: response = self.client.post( "/user/login", data=json.dumps(data_test), content_type="application/json" ) data = json.loads(response.data) self.assertTrue(data["token"]) self.assertTrue(response.content_type == "application/json") self.assertEqual(response.status_code, 200)
def test_create_topic(self): user = User(name="testname", email="*****@*****.**", password="******") user.insert() topic = Topic(subject="subject", description="description", created_by=user.id.__str__(), updated_by=user.id.__str__()) topic.insert() self.assertTrue(uuid_pattern_matched(topic.id.__str__())) self.assertEqual(topic.subject, 'subject') self.assertEqual(topic.description, 'description') self.assertTrue(topic.created_by) self.assertTrue(uuid_pattern_matched(topic.created_by.__str__())) self.assertTrue(topic.updated_by) self.assertTrue(uuid_pattern_matched(topic.updated_by.__str__())) self.assertTrue(topic.created_at) self.assertTrue(iso8601_pattern_matched(topic.created_at)) self.assertTrue(topic.updated_at) self.assertTrue(iso8601_pattern_matched(topic.updated_at))
def get(self, id): try: user = User.find(id=id) if not user: response_object = {"message": "User does not exist."} return response_object, 404 else: response_object = user.json() return response_object, 200 except Exception: response_object["message"] = "Try again." db.session.rollback() db.session.flush() return response_object, 500
def test_delete_topic(self): user_test = { "email": "*****@*****.**", "name": "Name", "password": "******" } user = User(**user_test) user.insert() with self.client: login = self.client.post( "/user/login", data=json.dumps({ "email": user.email, "password": "******" }), content_type="application/json", ) login_data = json.loads(login.data.decode()) token = login_data.get("token") create_topic = self.client.post( "/topic", data=json.dumps({"subject": "subject", "description": "desc"}), content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) create_topic_data = json.loads( create_topic.data.decode() ) delete_topic = self.client.delete( f"/topic/{create_topic_data['id']}", content_type="application/json", headers={"Authorization": f"Bearer {token}"} ) delete_topic_data = json.loads(delete_topic.data.decode()) self.assertEqual(delete_topic.status_code, 202) self.assertTrue(delete_topic_data["success"])
def post(self): post_data = request.get_json() response_object = {"message": "Invalid payload."} if not post_data: return response_object, 400 email = post_data.get("email") password = post_data.get("password") try: user = User.find(email=email) if user: valid_password = bcrypt.check_password_hash( user.password_hash, password) if valid_password: redis_client.setex( user.id.__str__(), int(current_app.config["JWT_ACCESS_TOKEN_EXPIRES"]), "inactive") token = create_access_token(identity=user.id.__str__(), fresh=True, user_claims=user.avatar) jti = get_jti(token) redis_client.setex( user.id.__str__(), int(current_app.config["JWT_ACCESS_TOKEN_EXPIRES"]), jti) response_object = {"token": token} return response_object, 200 else: response_object["message"] = "Invalid Credentials." return response_object, 401 else: response_object["message"] = "User does not exist." return response_object, 404 except Exception: db.session.rollback() db.session.flush() response_object["message"] = "Try again." return response_object, 500
def post(self): post_data = request.get_json() response_object = {"message": "Invalid payload."} if not post_data: return response_object, 400 email = post_data.get("email") password = post_data.get("password") name = post_data.get("name") try: user = User.find(email=email) if not user: user = User(name=name, email=email, password=password) user.insert() added_user = User.find(email=post_data["email"]) response_object = added_user.json() return response_object, 201 else: response_object["message"] = ( "Sorry. That email already exists.") return response_object, 400 except (exc.IntegrityError, ValueError, TypeError): db.session.rollback() db.session.flush() return response_object, 400
def seed_db(): """Seeds the database.""" import string import json from app.api.rest.users.models import User from app.api.rest.topics.models import Topic from app.api.rest.messages.models import Message user1 = User.find(email="*****@*****.**") user2 = User.find(email="*****@*****.**") if not user1: user1 = User(name="mark", email="*****@*****.**", password="******") user1.insert() user1.id = user1.id.__str__() if not user2: user2 = User(name="juan", email="*****@*****.**", password="******") user2.insert() user2.id = user2.id.__str__() seed_data = json.load(open("seed.json")) alphabet = list(string.ascii_lowercase) alphabet.reverse() for i in alphabet: topic = Topic(subject=f"{i} This is a sample Subject", description=seed_data.get("lorem"), created_by=user2.id, updated_by=user2.id) db.session.add(topic) for i in range(1, 31): topic.messages.append( Message(message=f"Sample Comment {i}", created_by=user2.id, updated_by=user2.id)) for i in range(1, 31): topic.messages.append( Message(message=f"Sample Comment {i}", created_by=user1.id, updated_by=user1.id)) db.session.commit()
def test_user_json(self): user = User(name="testname", email="*****@*****.**", password="******") user.insert() self.assertTrue(isinstance(user.json(), dict))