def test_get_close_db(app): with app.app_context(): db = get_db() assert db is get_db() with pytest.raises(sqlite3.ProgrammingError) as e: db.execute("SELECT 1") assert "closed" in str(e.value)
def get_method(service_name, method_name, check_author=True): """Get a method by service_name, method_name. Checks that the id exists and optionally that the current user is the author. :param id: id of method to get :param check_author: require the current user to be the author :return: the method with author information :raise 404: if a method with the given id doesn't exist :raise 403: if the current user isn't the author """ method = ( get_db() .execute( "SELECT m.id, m.title, m.body, m.status_code," " m.delay, m.supported_method, m.headers," " m.created, m.author_id, m.service_id, username" " FROM method m JOIN user u ON m.author_id = u.id" " JOIN service s ON m.service_id = s.id" " WHERE m.title = ? AND s.title = ?", (method_name, service_name), ) .fetchone() ) if method is None: abort(404, "Method {0} doesn't exist.".format(method_name)) if check_author and method["author_id"] != g.user["id"]: abort(403) return method
def method(method_name, service_name): """Returns method response""" db = get_db() method = get_method(service_name, method_name, check_author=False) service = get_service_by_title(service_name, check_author=False) method_response = db.execute( "SELECT body, status_code, delay, supported_method, headers" " FROM method" " WHERE service_id = ? AND title = ?", (service["id"], method_name,), ).fetchone() body = method_response['body'] status_code = method_response['status_code'] delay = method_response['delay'] supported_method = method_response['supported_method'] headers = json.loads(method_response['headers']) # seconds to milliseconds delay = delay / 1000 time.sleep(delay) if supported_method != request.method: return render_template("method/method_not_allowed.html", method=method, service_name=service_name, method_name=method_name, current_method=request.method) return Response(body, status=status_code, headers=headers)
def get_service_by_title(title, check_author=True): """Get a service by title. Checks that the id exists and optionally that the current user is the author. :param id: id of service to get :param check_author: require the current user to be the author :return: the service with author information :raise 404: if a service with the given id doesn't exist :raise 403: if the current user isn't the author """ service = (get_db().execute( "SELECT s.id, s.title, s.body, s.created, s.author_id, username" " FROM service s JOIN user u ON s.author_id = u.id" " WHERE s.title = ?", (title, ), ).fetchone()) if service is None: abort(404, "Service '{0}' doesn't exist.".format(title)) if check_author and service["author_id"] != g.user["id"]: abort(403) return service
def register(): """Register a new user. Validates that the username is not already taken. Hashes the password for security. """ if request.method == "POST": username = request.form["username"] password = request.form["password"] db = get_db() error = None if not username: error = "Username is required." elif not password: error = "Password is required." elif (db.execute("SELECT id FROM user WHERE username = ?", (username, )).fetchone() is not None): error = "User {0} is already registered.".format(username) if error is None: # the name is available, store it in the database and go to # the login page db.execute( "INSERT INTO user (username, password) VALUES (?, ?)", (username, generate_password_hash(password)), ) db.commit() return redirect(url_for("auth.login")) flash(error) return render_template("auth/register.html")
def create_method(service_name): """Create a new method for the current user, service.""" if request.method == "POST": title = request.form["title"] body = request.form["body"] status_code = int(request.form["status_code"]) delay = int(request.form["delay"]) supported_method = request.form["supported_method"] headers = get_headers_from_request_form(request.form) error = None if not title: error = "Title is required." if error is not None: flash(error) else: db = get_db() service_id = db.execute( "SELECT id FROM service WHERE title = ?", (service_name,), ).fetchone() db.execute( "INSERT INTO method" " (title, body, status_code, delay, supported_method, headers, author_id, service_id)" " VALUES (?, ?, ?, ?, ?, ?, ?, ?)", (title, body, status_code, delay, supported_method, headers, g.user["id"], service_id['id']), ) db.commit() return redirect(url_for("methods.service", service_name=service_name)) return render_template("method/create_method.html", service_name=service_name)
def app(): """Create and configure a new app instance for each test.""" # create a temporary file to isolate the database for each test db_fd, db_path = tempfile.mkstemp() # create the app with common test config app = create_app({"TESTING": True, "DATABASE": db_path}) # create the database and load test data with app.app_context(): init_db() get_db().executescript(_data_sql) yield app # close and remove the temporary database os.close(db_fd) os.unlink(db_path)
def test_update(client, auth, app): auth.login() assert client.get("/test_service/update").status_code == 200 client.post("/test_service/update", data={"title": "updated", "body": ""}) with app.app_context(): db = get_db() service = db.execute("SELECT * FROM service WHERE id = 1").fetchone() assert service["title"] == "updated"
def test_delete(client, auth, app): auth.login() response = client.post("/test_service/test_method/delete_method") assert response.headers["Location"] == "http://localhost/test_service" with app.app_context(): db = get_db() service = db.execute("SELECT * FROM method WHERE id = 1").fetchone() assert service is None
def test_create(client, auth, app): auth.login() assert client.get("/create").status_code == 200 client.post("/create", data={"title": "created", "body": ""}) with app.app_context(): db = get_db() count = db.execute("SELECT COUNT(id) FROM service").fetchone()[0] assert count == 2
def load_logged_in_user(): """If a user id is stored in the session, load the user object from the database into ``g.user``.""" user_id = session.get("user_id") if user_id is None: g.user = None else: g.user = (get_db().execute("SELECT * FROM user WHERE id = ?", (user_id, )).fetchone())
def delete(service_name): """Delete a service. Ensures that the service exists and that the logged in user is the author of the service. """ get_service_by_title(service_name) db = get_db() db.execute("DELETE FROM service WHERE title = ?", (service_name, )) db.commit() return redirect(url_for("services.index"))
def delete_method(service_name, method_name): """Delete the method. Ensures that the method exists and that the logged in user is the author of the method. """ method_for_delete = get_method(service_name, method_name) db = get_db() db.execute("DELETE FROM method" " WHERE title = ? AND service_id = ?", (method_name, method_for_delete['service_id'])) db.commit() return redirect(url_for("methods.service", service_name=service_name))
def test_author_required(app, client, auth): # change the service author to another user with app.app_context(): db = get_db() db.execute("UPDATE service SET author_id = 2 WHERE id = 1") db.commit() auth.login() # current user can't modify other user's service assert client.post("/test_service/update").status_code == 403 assert client.post("/test_service/delete").status_code == 403 # current user doesn't see edit link assert b'href="/test_service/update"' not in client.get("/").data
def index(): """Show all the services, most recent first.""" # redirect for unauthorized user if g.user is None: return redirect(url_for("auth.login")) db = get_db() services = db.execute( "SELECT s.id, title, body, created, author_id, username" " FROM service s JOIN user u ON s.author_id = u.id" " ORDER BY created DESC").fetchall() return render_template("service/index.html", services=services)
def test_register(client, app): # test that viewing the page renders without template errors assert client.get("/auth/register").status_code == 200 # test that successful registration redirects to the login page response = client.post("/auth/register", data={ "username": "******", "password": "******" }) assert "http://localhost/auth/login" == response.headers["Location"] # test that the user was inserted into the database with app.app_context(): assert (get_db().execute( "select * from user where username = '******'").fetchone() is not None)
def test_create(client, auth, app): auth.login() assert client.get("/test_service/create_method").status_code == 200 client.post("/test_service/create_method", data={ "title": "created", "status_code": 200, "delay": 500, "supported_method": "GET", "body": "", "headers": "" }) with app.app_context(): db = get_db() count = db.execute("SELECT COUNT(id) FROM method").fetchone()[0] assert count == 2
def test_update(client, auth, app): auth.login() assert client.get( "/test_service/test_method/update_method").status_code == 200 client.post("/test_service/test_method/update_method", data={ "title": "updated", "status_code": 201, "delay": 100, "supported_method": "GET", "body": "", "headers": "" }) with app.app_context(): db = get_db() method = db.execute("SELECT * FROM method WHERE id = 1").fetchone() assert method["title"] == "updated"
def service(service_name): """Show all the methods, most recent first.""" # redirect for unauthorized user if g.user is None: return redirect(url_for("auth.login")) methods = [] db = get_db() service = get_service_by_title(service_name, check_author=False) methods = db.execute( "SELECT m.id, title, body, status_code, delay, supported_method, created, author_id, username" " FROM method m JOIN user u ON" " m.author_id = u.id AND" " m.service_id = ?" " ORDER BY created DESC", (service["id"],), ).fetchall() return render_template("method/services.html", methods=methods, service_name=service_name, service=service)
def update(service_name): """Update a service if the current user is the author.""" service = get_service_by_title(service_name) if request.method == "POST": title = request.form["title"].replace(' ', '_') body = request.form["body"] error = None if not title: error = "Title is required." if error is not None: flash(error) else: db = get_db() db.execute("UPDATE service SET title = ?, body = ? WHERE id = ?", (title, body, service["id"])) db.commit() return redirect(url_for("services.index")) return render_template("service/update.html", service=service)
def create(): """Create a new service for the current user.""" if request.method == "POST": title = request.form["title"].replace(' ', '_') body = request.form["body"] error = None if not title: error = "Title is required." if error is not None: flash(error) else: db = get_db() db.execute( "INSERT INTO service (title, body, author_id) VALUES (?, ?, ?)", (title, body, g.user["id"]), ) db.commit() return redirect(url_for("services.index")) return render_template("service/create.html")
def update_method(service_name, method_name): """Update a method if the current user is the author.""" method = get_method(service_name, method_name) if request.method == "POST": title = request.form["title"].replace(' ', '_') body = request.form["body"] status_code = int(request.form["status_code"]) delay = int(request.form["delay"]) supported_method = request.form["supported_method"] headers = get_headers_from_request_form(request.form) error = None if not title: error = "Title is required." if error is not None: flash(error) else: db = get_db() db.execute( "UPDATE method" " SET title = ?, body = ?, status_code = ?," " delay = ?, supported_method = ?, headers = ?" " WHERE id = ?", (title, body, status_code, delay, supported_method, headers, method['id']) ) db.commit() return redirect(url_for("methods.service", service_name=service_name)) method = get_method(service_name, method_name) headers = json.loads(method['headers']) return render_template("method/update_method.html", method=method, service_name=service_name, headers=headers)
def login(): """Log in a registered user by adding the user id to the session.""" if request.method == "POST": username = request.form["username"] password = request.form["password"] db = get_db() error = None user = db.execute("SELECT * FROM user WHERE username = ?", (username, )).fetchone() if user is None: error = "Incorrect username." elif not check_password_hash(user["password"], password): error = "Incorrect password." if error is None: # store the user id in a new session and return to the index session.clear() session["user_id"] = user["id"] return redirect(url_for("index")) flash(error) return render_template("auth/login.html")