Quellcode durchsuchen

tutorial done

master
Johannnes Bürst vor 5 Jahren
Ursprung
Commit
b6b5f0e281
10 geänderte Dateien mit 280 neuen und 0 gelöschten Zeilen
  1. +1
    -0
      .idea/sqldialects.xml
  2. +4
    -0
      MANIFEST.in
  3. +7
    -0
      setup.cfg
  4. +12
    -0
      setup.py
  5. +57
    -0
      tests/conftest.py
  6. +8
    -0
      tests/data.sql
  7. +58
    -0
      tests/test_auth.py
  8. +94
    -0
      tests/test_calender.py
  9. +28
    -0
      tests/test_db.py
  10. +11
    -0
      tests/test_factory.py

+ 1
- 0
.idea/sqldialects.xml Datei anzeigen

@@ -4,5 +4,6 @@
<file url="file://$PROJECT_DIR$/calender/auth.py" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/calender/calender.py" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/calender/schema.sql" dialect="SQLite" />
<file url="file://$PROJECT_DIR$/tests/data.sql" dialect="GenericSQL" />
</component>
</project>

+ 4
- 0
MANIFEST.in Datei anzeigen

@@ -0,0 +1,4 @@
include calender/schema.sql
graft calender/static
graft calender/templates
global-exclude *.pyc

+ 7
- 0
setup.cfg Datei anzeigen

@@ -0,0 +1,7 @@
[tool:pytest]
testpaths = tests

[coverage:run]
branch = True
source =
calender

+ 12
- 0
setup.py Datei anzeigen

@@ -0,0 +1,12 @@
from setuptools import find_packages, setup

setup(
name='calender',
version='3.0.1',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
install_requires=[
'flask',
],
)

+ 57
- 0
tests/conftest.py Datei anzeigen

@@ -0,0 +1,57 @@
import os
import tempfile

import pytest
from calender import create_app
from calender.db import get_db, init_db

with open(os.path.join(os.path.dirname(__file__), 'data.sql'), 'rb') as f:
_data_sql = f.read().decode('utf8')


@pytest.fixture
def app():
db_fd, db_path = tempfile.mkstemp()

app = create_app({
'TESTING': True,
'DATABASE': db_path,
})

with app.app_context():
init_db()
get_db().executescript(_data_sql)

yield app

os.close(db_fd)
os.unlink(db_path)


@pytest.fixture
def client(app):
return app.test_client()


@pytest.fixture
def runner(app):
return app.test_cli_runner()


class AuthActions(object):
def __init__(self, client):
self._client = client

def login(self, username='test', password='test'):
return self._client.post(
'/auth/login',
data={'username': username, 'password': password}
)

def logout(self):
return self._client.get('/auth/logout')


@pytest.fixture
def auth(client):
return AuthActions(client)

+ 8
- 0
tests/data.sql Datei anzeigen

@@ -0,0 +1,8 @@
INSERT INTO user (username, password)
VALUES
('test', 'pbkdf2:sha256:50000$TCI4GzcX$0de171a4f4dac32e3364c7ddc7c14f3e2fa61f2d17574483f7ffbb431b4acb2f'),
('other', 'pbkdf2:sha256:50000$kJPKsz6N$d2d4784f1b030a9761f5ccaeeaca413f27f2ecb76d6168407af962ddce849f79');

INSERT INTO post (title, body, author_id, created)
VALUES
('test title', 'test' || x'0a' || 'body', 1, '2018-01-01 00:00:00');

+ 58
- 0
tests/test_auth.py Datei anzeigen

@@ -0,0 +1,58 @@
import pytest
from flask import g, session

from calender.db import get_db


def test_register(client, app):
assert client.get('/auth/register').status_code == 200
response = client.post(
'/auth/register', data={'username': 'a', 'password': 'a'}
)
assert 'http://localhost/auth/login' == response.headers['Location']

with app.app_context():
assert get_db().execute(
"select * from user where username = 'a'",
).fetchone() is not None


@pytest.mark.parametrize(('username', 'password', 'message'), (
('', '', b'Username is required.'),
('a', '', b'Password is required.'),
('test', 'test', b'already registered'),
))
def test_register_validate_input(client, username, password, message):
response = client.post(
'/auth/register',
data={'username': username, 'password': password}
)
assert message in response.data


def test_login(client, auth):
assert client.get('/auth/login').status_code == 200
response = auth.login()
assert response.headers['Location'] == 'http://localhost/'

with client:
client.get('/')
assert session['user_id'] == 1
assert g.user['username'] == 'test'


@pytest.mark.parametrize(('username', 'password', 'message'), (
('a', 'test', b'Incorrect username.'),
('test', 'a', b'Incorrect password.'),
))
def test_login_validate_input(auth, username, password, message):
response = auth.login(username, password)
assert message in response.data


def test_logout(client, auth):
auth.login()

with client:
auth.logout()
assert 'user_id' not in session

+ 94
- 0
tests/test_calender.py Datei anzeigen

@@ -0,0 +1,94 @@
import pytest

from calender.db import get_db


def test_index(client, auth):
response = client.get('/')
assert b"Log In" in response.data
assert b"Register" in response.data

auth.login()
response = client.get('/')
assert b'Log Out' in response.data
assert b'test title' in response.data
assert b'by test on 2018-01-01' in response.data
assert b'test\nbody' in response.data
assert b'href="/1/update"' in response.data


@pytest.mark.parametrize('path', (
'/create',
'/1/update',
'/1/delete',
))
def test_login_required(client, path):
response = client.post(path)
assert response.headers['Location'] == 'http://localhost/auth/login'


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


@pytest.mark.parametrize('path', (
'/2/update',
'/2/delete',
))
def test_exists_required(client, auth, path):
auth.login()
assert client.post(path).status_code == 404


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


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'


@pytest.mark.parametrize('path', (
'/create',
'/1/update',
))
def test_create_update_validate(client, auth, path):
auth.login()
response = client.post(path, data={'title': '', 'body': ''})
assert b'Title is required.' in response.data


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

+ 28
- 0
tests/test_db.py Datei anzeigen

@@ -0,0 +1,28 @@
import sqlite3

import pytest
from calender.db import get_db


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 test_init_db_command(runner, monkeypatch):
class Recorder(object):
called = False

def fake_init_db():
Recorder.called = True

monkeypatch.setattr('calender.db.init_db', fake_init_db)
result = runner.invoke(args=['init-db'])
assert 'Initialized' in result.output
assert Recorder.called

+ 11
- 0
tests/test_factory.py Datei anzeigen

@@ -0,0 +1,11 @@
from calender import create_app


def test_config():
assert not create_app().testing
assert create_app({'TESTING': True}).testing


def test_hello(client):
response = client.get('/hello')
assert response.data == b'Hello, World!'

Laden…
Abbrechen
Speichern