Beispiel #1
0
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)
Beispiel #2
0
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")
Beispiel #3
0
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)
Beispiel #4
0
def test_delete(client, auth, app):
    auth.login()
    response = client.post("/1/delete")
    assert response.headers["Location"] == "http://localhost/"

    with app.app_context():
        db = get_db()
        post = db.execute("SELECT * FROM post WHERE id = 1").fetchone()
        assert post is None
Beispiel #5
0
def test_update(client, auth, app):
    auth.login()
    assert client.get("/1/update").status_code == 200
    client.post("/1/update", data={"title": "updated", "body": ""})

    with app.app_context():
        db = get_db()
        post = db.execute("SELECT * FROM post WHERE id = 1").fetchone()
        assert post["title"] == "updated"
Beispiel #6
0
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 post").fetchone()[0]
        assert count == 2
Beispiel #7
0
def update(id):
    part = get_part(id)

    if request.method == "POST":
        ptype = request.form['type']
        manuf = request.form['manuf']
        partnum = request.form['partnum']
        pkg = request.form['pkg']
        description = request.form['description']
        pclass = request.form['class']
        qty = request.form['qty']
        location = request.form['location']
        cost = request.form['cost']
        notes = request.form['notes']
        url = request.form['url']
        if 'datafile' in request.files:
            datafile = request.files['datafile']
        else:
            datafile = None
        error = None

        if not ptype:
            error = "Type is required."
        if not qty:
            error = "Quantity is required."

        if error is not None:
            flash(error)
        else:
            if datafile and datafile.filename != '':
                # copy datasheet to data directory and set URL to resulting location
                src = os.path.join(current_app.config["UPLOAD_DIR"],
                                   datafile.filename)
                dest = os.path.join(current_app.config["DATA_DIR"],
                                    datafile.filename)
                try:
                    datafile.save(src)
                    shutil.move(src, dest)
                    url = url_for('send_datasheet', path=datafile.filename)
                except OSError:
                    flash("File operation failed")
            db = get_db()
            tablename = "parts" + g.user['username']
            db.execute(
                "UPDATE " + tablename +
                " SET type = ?, class = ?, qty = ?, pkg = ?, manuf = ?, partnum = ?, cost = ?, location = ?, description = ?, notes = ?, url = ? WHERE id = ?",
                (ptype, pclass, qty, pkg, manuf, partnum, cost, location,
                 description, notes, url, id))
            db.commit()
            return redirect(url_for("parts.browse"))

    parse_hierarchy_xml('./partridge/static/class.xml')
    class_list = get_linear_class_list()
    return render_template("parts/update.html",
                           part=part,
                           class_list=class_list)
Beispiel #8
0
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())
Beispiel #9
0
def delete(id):
    """Delete a post.

    Ensures that the post exists and that the logged in user is the
    author of the post.
    """
    get_part(id)
    db = get_db()
    tablename = "parts" + g.user['username']
    db.execute("DELETE FROM " + tablename + " WHERE id = ?", (id, ))
    db.commit()
    return redirect(url_for("parts.browse"))
Beispiel #10
0
def test_author_required(app, client, auth):
    # change the post author to another user
    with app.app_context():
        db = get_db()
        db.execute("UPDATE post SET author_id = 2 WHERE id = 1")
        db.commit()

    auth.login()
    # current user can't modify other user's post
    assert client.post("/1/update").status_code == 403
    assert client.post("/1/delete").status_code == 403
    # current user doesn't see edit link
    assert b'href="/1/update"' not in client.get("/").data
Beispiel #11
0
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)
Beispiel #12
0
def index():
    """Give the menu of choices"""
    # Gather summary statistics
    db = get_db()
    tablename = "parts" + g.user['username']
    parts = db.execute("SELECT qty, cost FROM " + tablename, ).fetchall()
    summary = dict()
    num = 0
    value = 0.0
    for part in parts:
        num = num + int(part['qty'])
        if len(part['cost']) > 0:
            value = value + (part['qty'] * float(part['cost']))
    summary['total_num'] = str(num)
    summary['total_value'] = '%.2f' % value
    return render_template("parts/index.html", summary=summary)
Beispiel #13
0
def browse():
    """Show all the posts, most recent first."""
    if 'search' in request.args:
        searchstr = request.args['search']
    else:
        searchstr = lastsearch
    db = get_db()
    tablename = "parts" + g.user['username']
    parts = db.execute(
        "SELECT id, type, class, qty, pkg, manuf, partnum, cost, location, description, notes, url FROM "
        + tablename, ).fetchall()
    # parse the class xml file before get_class_string is called in the template
    parse_hierarchy_xml('./partridge/static/class.xml')
    return render_template("parts/browse.html",
                           parts=parts,
                           str_type=str,
                           get_class_string=get_class_string,
                           lastsearch=searchstr)
Beispiel #14
0
def get_part(id):
    """Get a part by id.

    Checks that the id exists and optionally that the current user is
    the author.

    :param id: id of part to get
    :return: the part
    :raise 404: if a part with the given id doesn't exist
    """
    tablename = "parts" + g.user['username']
    part = (get_db().execute(
        "SELECT id, type, class, qty, pkg, manuf, partnum, cost, location, description, notes, url"
        " FROM " + tablename + " WHERE id = ?",
        (id, ),
    ).fetchone())

    if part is None:
        abort(404, "Part id {0} doesn't exist.".format(id))

    return part
Beispiel #15
0
def add():
    """Add a new part for the current user."""
    if request.method == "POST":
        ptype = request.form['type']
        manuf = request.form['manuf']
        partnum = request.form['partnum']
        pkg = request.form['pkg']
        description = request.form['description']
        pclass = request.form['class']
        qty = request.form['qty']
        location = request.form['location']
        cost = request.form['cost']
        notes = request.form['notes']
        url = request.form['url']
        error = None

        if not ptype:
            error = "Type is required."
        if not qty:
            error = "Quantity is required."

        if error is not None:
            flash(error)
        else:
            db = get_db()
            tablename = "parts" + g.user['username']
            db.execute(
                "INSERT INTO " + tablename +
                " (type, class, qty, pkg, manuf, partnum, cost, location, description, notes, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
                (ptype, pclass, qty, pkg, manuf, partnum, cost, location,
                 description, notes, url),
            )
            db.commit()
            flash("New part added to database.")
            return redirect(url_for("parts.browse"), search='')

    parse_hierarchy_xml('./partridge/static/class.xml')
    class_list = get_linear_class_list()
    return render_template("parts/add.html", class_list=class_list)
Beispiel #16
0
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")