コード例 #1
0
ファイル: blog.py プロジェクト: damilarelana/flaskiblog
def index():
    db = open_db()
    posts = db.execute(
        'SELECT p.id, title, body, created, author_id, username'
        ' FROM post p JOIN user u ON author_id = u.id'
        ' ORDER BY created DESC').fetchall()  # query and fetch all
    return render_template('blog/index.html', posts=posts)
コード例 #2
0
ファイル: auth.py プロジェクト: damilarelana/flaskiblog
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        db = open_db()
        error = None

        # validate the user whether it exists or correct
        user = db.execute(
            'SELECT * FROM user WHERE username = ?',
            (username, )).fetchone()  # get the user record from database

        if user is None:  # if username is `None`, just throw an error
            error = 'Incorrect username.'

        elif not check_password_hash(
                user['password'], password
        ):  # validate by hashing new password and comparing with db version
            error = 'Incorrect password.'

        if error is None:  # username and password have been validated
            session.clear()  # clear the current session cookies
            session['user_id'] = user[
                'id']  # add user to session dict - `id` is the unique identifier obtained from the database
            return redirect(
                url_for('index')
            )  # redirect the user to `index page`, after having logged in

        flash(error)  # shows the user the error and store the error

    return render_template(
        'auth/login.html')  # otherwise return the login page again
コード例 #3
0
ファイル: auth.py プロジェクト: damilarelana/flaskiblog
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        db = open_db()
        error = None

        if not username:  # if username is `None`, just throw an error
            error = 'Username is required.'
        elif not password:  # if password is `None`, also throw an error
            error = 'Password is required.'
        elif db.execute(
                'SELECT id FROM user WHERE username = ?', (username, )
        ).fetchone(
        ) is not None:  # use initialized db to check if user already exists
            error = 'User {} is already registered.'.format(username)

        if error is None:  # if there are no errors with username and password input, then hash and store the data in the database
            db.execute('INSERT INTO user (username, password) VALUES (?, ?)',
                       (username, generate_password_hash(password)))
            db.commit(
            )  # make sure the db changes are concreted i.e. save the changes
            return redirect(
                url_for('auth.login')
            )  # redirect the user to `login` for them to now login

        flash(
            error
        )  # shows the user the error and also stores the error for subsequent usage in the template

    return render_template('auth/register.html')
コード例 #4
0
ファイル: auth.py プロジェクト: damilarelana/flaskiblog
def load_logged_in_user():
    user_id = session.get(
        'user_id')  # extract the user_id from the current session cookie
    if user_id is None:  # if there current session cookie is not valid [due to not even having a user_id]
        g.user = None
    else:  # use the user_id to select the user details from the database
        db = open_db()
        g.user = db.execute('SELECT * FROM user WHERE id = ?',
                            (user_id, )).fetchone()
コード例 #5
0
def test_close_db(app):  # to validate the app can be `opened` and `closed` ()
    with app.app_context(
    ):  # this gives access to the current_app [thus access to the attributes - within this block of code]
        db = open_db(
        )  # extracts and assigns the `open_db()` obtained from the app_context()
        assert db is open_db(
        )  # checks to make sure we were able to really get the same db object from app_context()

    with pytest.raises(
            sqlite3.ProgrammingError
    ) as e:  # test if db.execute(`SELECT 1`) raises expected `sqlite3.ProgrammingError` or exception `e` [i.e. string `close`]
        db.execute(
            'SELECT 1'
        )  # `SELECT 1` always returns a `1` if there are rows in the db [] - this also implicitly tests open_db()

    # the returned rows is unimportant, we just want to test if the code returns a `close` value
    assert 'close' in str(
        e.value
    )  # check that if string `close` exists to show that close_db() is working well
コード例 #6
0
def app():  # for the `testing of the application itself: awokogbon`
    db_tempfile, db_tempfilepath = tempfile.mkstemp(
    )  # create temporary file/path needed for the tests database

    app = create_app({  # create an instance of the application
        'TESTING':
        True,  # let's flask know that the application is in testing mode
        'DATABASE':
        db_tempfilepath,  # points to the database path where `_data_sql` would be stored when used
    })

    with app.app_context(
    ):  # initialize the app context e.g. app `in testing mode` to use test database `_data_sql`
        init_db(
        )  # gets the app to use initiliaze the sqlite3 connections [which also gets `schema.sql` initialized BUT not used]
        open_db().executescript(
            _data_sql
        )  # gets the app to open/run `_data_sql`, and initialize it as an `sqlite3 db` at `db_tempfilepath` [i.e. `schema.sql` is not used]

    yield app  # `an alternative to using return` i.e. a more efficient `return` [what works like a generator]

    # close the temporary file and unlink the temporary file path
    os.close(db_tempfile)
    os.unlink(db_tempfilepath)
コード例 #7
0
def test_create(client, authentication, app):
    authentication.login()

    # tests to check if `/create` is accesssible
    assert client.get('/create').status_code == 200

    # add new data via the `/create` endpoint
    client.post('/create', data={'title': 'created', 'body': ''})

    # check if the data was indeed added
    # assuming that we initially had only one entry in the table `post`
    with app.app_context():
        db = open_db()
        count = db.execute('SELECT COUNT(id) FROM post').fetchone()[0]
        assert count == 2
コード例 #8
0
def test_update(client, authentication, app):
    authentication.login()

    # tests to check if `/1/update` is accesssible
    assert client.get('/1/update').status_code == 200

    # update new data via the `/1/update` endpoint
    client.post('/1/update', data={'title': 'updated', 'body': ''})

    # check if the data was indeed added by checking the title
    # assuming that we initially had only one entry in the table `post`
    # app.app_context is being used to simulate that the application code is the one implementing the test
    with app.app_context():
        db = open_db()
        post = db.execute('SELECT  * FROM post WHERE id = 1').fetchone()
        assert post['title'] == 'updated'
コード例 #9
0
def test_logged_in_user(app, client, authentication, path):

    # change the post owner within the test database
    with app.app_context():
        db = open_db()
        db.execute('UPDATE post SET author_id = 2 WHERE id = 1')
        db.commit()

    # ensure current user is logged in and then try to access the `/1/update` and `/1/delete` urls
    authentication.login()

    # test the routes
    assert client.post(path).status_code == 403  # forbidden

    # test visibility to edit link
    response = client.get('/')
    assert b'href="/1/update"' not in response.data
コード例 #10
0
def test_delete(client, authentication, app):
    authentication.login()

    # delete the post
    client.post('/1/delete')
    # response = client.post('/1/delete')

    # check to see if there was indeed redirection to `/` i.e. local host
    # assert response.headers.get('Location') == 'http://localhost/'

    # check if the data was indeed removed by checking the title
    # assuming that we initially had only one entry in the table `post`
    # app.app_context is being used to simulate that the application code is the one implementing the test
    with app.app_context():
        db = open_db()
        post = db.execute('SELECT  * FROM post WHERE id = 1').fetchone()
        assert post is None
コード例 #11
0
ファイル: blog.py プロジェクト: damilarelana/flaskiblog
def update(id):
    post = get_post(id)

    if request.method == 'POST':
        title = request.form['title']
        body = request.form['body']
        error = None

        if not title:  # the blog post needs to have a title, assign an error value
            error = 'Title is required.'

        if error is not None:
            flash(error)
        else:
            db = open_db()
            db.execute('UPDATE post SET title=?, body=? WHERE id = ?', (title, body, id))
            db.commit()  # save the changes
            return redirect(url_for('blog.index'))  # redirect back to index page after the update
    return render_template('blog/update.html', post=post)  # redirect back to update page if it is a `GET` request or there are issues with `initial update`
コード例 #12
0
ファイル: blog.py プロジェクト: damilarelana/flaskiblog
def create():
    if request.method == 'POST':
        title = request.form['title']
        body = request.form['body']
        error = None

        if not title:  # the blog post needs to have a title, assign an error value
            error = 'Title is required.'

        if error is not None:
            flash(error)
        else:
            db = open_db()
            db.execute(
                'INSERT INTO post (title, body, author_id) VALUES (?, ?, ?)', (title, body, g.user['id'])
            )
            db.commit()  # save the data in the database
            return redirect(url_for('blog.index'))  # redirect back to index page after creating the new blog post
    return render_template('blog/create.html')  # redirect back to the create page if it is a `GET` request or there are issues with `title`
コード例 #13
0
ファイル: blog.py プロジェクト: damilarelana/flaskiblog
def get_post(id, check_author=True):

    # connect to the database to retrieve the post [using the provided `id` parameter]
    db = open_db()
    post = db.execute(
        'SELECT p.id, title, body, created, author_id, username'
        ' FROM post p JOIN user u ON p.author_id = u.id'
        ' WHERE p.id = ?', (id,)
        ).fetchone()

    # check if the post exists i.e. in case the db returned a None value
    if post is None:
        abort(404, "Post id {0} doesn't exist").format(id)

    # if the post exists, then check if the author does NOT match the `id` of current user trying to delete the post
    if check_author and post['author_id'] != g.user['id']:
        abort(403)

    # this means it is now okay to delete the post
    return post
コード例 #14
0
def test_register(
        client,
        app):  # the `client` and `app` are feed to this via `conftest.py`
    # check if the '/auth/register' url is a accessible
    assert client.get('/auth/register').status_code == 200

    # use the validated url `/auth/register` to register a sample user `a`, using a post request
    response = client.post('/auth/register',
                           data={
                               'username': '******',
                               'password': '******'
                           })

    # a successful registeration would re-direct the url to `url_for('auth.login')`, hence the `Location` check
    assert 'http://localhost/auth/login' == response.headers['Location']

    # check the database to ensure the data was really inserted for username `a`
    with app.app_context():
        db = open_db()
        assert db.execute(
            "select * from user where username = '******'").fetchone() is not None
コード例 #15
0
ファイル: blog.py プロジェクト: damilarelana/flaskiblog
def delete(id):
    get_post(id)
    db = open_db()
    db.execute('DELETE FROM post WHERE id = ?', (id,))
    db.commit()  # save the data in the database
    return render_template('blog/index.html')  # redirect back to the index page