From 328bb368cc08240ef8c995bcc36ba0b694fe79ca Mon Sep 17 00:00:00 2001 From: Marco Paolini Date: Sat, 23 Jul 2016 10:51:13 +0200 Subject: [PATCH] Demo app fixes after #981 refactor (#983) Also added end-to-end testing with tox --- demos/polls/README.rst | 6 +++ demos/polls/aiohttpdemo_polls/main.py | 15 +++---- .../{ => aiohttpdemo_polls}/static/style.css | 0 demos/polls/aiohttpdemo_polls/views.py | 9 ++-- demos/polls/setup.py | 3 ++ demos/polls/sql/install.sh | 2 +- demos/polls/tests/conftest.py | 43 +++++++++++++++++++ demos/polls/tests/test_integration.py | 24 +++++++++++ demos/polls/tox.ini | 9 ++++ 9 files changed, 96 insertions(+), 15 deletions(-) rename demos/polls/{ => aiohttpdemo_polls}/static/style.css (100%) create mode 100644 demos/polls/tests/conftest.py create mode 100644 demos/polls/tests/test_integration.py create mode 100644 demos/polls/tox.ini diff --git a/demos/polls/README.rst b/demos/polls/README.rst index ba7f91d93c7..35bf42c6a24 100644 --- a/demos/polls/README.rst +++ b/demos/polls/README.rst @@ -29,6 +29,12 @@ Open browser:: :align: center +Run integration tests:: + + pip install tox + tox + + Requirements ============ * aiohttp_ diff --git a/demos/polls/aiohttpdemo_polls/main.py b/demos/polls/aiohttpdemo_polls/main.py index 91469d989ab..34469f27b59 100644 --- a/demos/polls/aiohttpdemo_polls/main.py +++ b/demos/polls/aiohttpdemo_polls/main.py @@ -8,11 +8,10 @@ from aiohttpdemo_polls.middlewares import setup_middlewares from aiohttpdemo_polls.routes import setup_routes -from aiohttpdemo_polls.utils import init_postgres, load_config -from aiohttpdemo_polls.views import SiteHandler +from aiohttpdemo_polls.utils import load_config +from aiohttpdemo_polls.db import init_postgres - -PROJ_ROOT = pathlib.Path(__file__).parent.parent +PROJ_ROOT = pathlib.Path(__file__).parent async def close_pg(app): @@ -25,18 +24,16 @@ async def init(loop): app = web.Application(loop=loop) aiohttp_jinja2.setup( app, loader=jinja2.PackageLoader('aiohttpdemo_polls', 'templates')) - # load config from yaml file - conf = load_config(str(PROJ_ROOT / 'config' / 'polls.yaml')) + # load config from yaml file in current dir + conf = load_config(str(pathlib.Path('.') / 'config' / 'polls.yaml')) # create connection to the database db = await init_postgres(conf['postgres'], loop) app['db'] = db app.on_cleanup.append(close_pg) - # setup views and routes - handler = SiteHandler(db) - setup_routes(app, handler, PROJ_ROOT) + setup_routes(app, PROJ_ROOT) setup_middlewares(app) host, port = conf['host'], conf['port'] diff --git a/demos/polls/static/style.css b/demos/polls/aiohttpdemo_polls/static/style.css similarity index 100% rename from demos/polls/static/style.css rename to demos/polls/aiohttpdemo_polls/static/style.css diff --git a/demos/polls/aiohttpdemo_polls/views.py b/demos/polls/aiohttpdemo_polls/views.py index 20bbb9f387b..a0ff6a1cdad 100644 --- a/demos/polls/aiohttpdemo_polls/views.py +++ b/demos/polls/aiohttpdemo_polls/views.py @@ -5,17 +5,16 @@ @aiohttp_jinja2.template('index.html') async def index(request): - async with request['db'].acquire() as conn: + async with request.app['db'].acquire() as conn: cursor = await conn.execute(db.question.select()) records = await cursor.fetchall() - questions = [dict(q) for q in records] return {'questions': questions} @aiohttp_jinja2.template('detail.html') async def poll(request): - async with request['db'].acquire() as conn: + async with request.app['db'].acquire() as conn: question_id = request.match_info['question_id'] try: question, choices = await db.get_question(conn, @@ -30,7 +29,7 @@ async def poll(request): @aiohttp_jinja2.template('results.html') async def results(request): - async with request['db'].acquire() as conn: + async with request.app['db'].acquire() as conn: question_id = request.match_info['question_id'] try: @@ -46,7 +45,7 @@ async def results(request): async def vote(request): - async with request['db'].acquire() as conn: + async with request.app['db'].acquire() as conn: question_id = int(request.match_info['question_id']) data = await request.post() try: diff --git a/demos/polls/setup.py b/demos/polls/setup.py index e5a57736ce5..498a0171abe 100644 --- a/demos/polls/setup.py +++ b/demos/polls/setup.py @@ -29,6 +29,9 @@ def read_version(): description='Polls project example from aiohttp', platforms=['POSIX'], packages=find_packages(), + package_data={ + '': ['templates/*.html', 'static/*.*'] + }, include_package_data=True, install_requires=install_requires, zip_safe=False) diff --git a/demos/polls/sql/install.sh b/demos/polls/sql/install.sh index 0198917bc46..b1207c4eb0c 100755 --- a/demos/polls/sql/install.sh +++ b/demos/polls/sql/install.sh @@ -1,6 +1,6 @@ +sudo -u postgres psql -c "DROP DATABASE IF EXISTS aiohttpdemo_polls" sudo -u postgres psql -c "DROP ROLE IF EXISTS aiohttpdemo_user" sudo -u postgres psql -c "CREATE USER aiohttpdemo_user WITH PASSWORD 'aiohttpdemo_user';" -sudo -u postgres psql -c "DROP DATABASE IF EXISTS aiohttpdemo_polls" sudo -u postgres psql -c "CREATE DATABASE aiohttpdemo_polls ENCODING 'UTF8';" sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE aiohttpdemo_polls TO aiohttpdemo_user;" diff --git a/demos/polls/tests/conftest.py b/demos/polls/tests/conftest.py new file mode 100644 index 00000000000..754ab99d67c --- /dev/null +++ b/demos/polls/tests/conftest.py @@ -0,0 +1,43 @@ +import pathlib +import subprocess + +import aiohttp +import pytest + + +@pytest.yield_fixture +def create_app(event_loop, unused_tcp_port): + app = handler = srv = client_session = None + + async def create(): + nonlocal app, handler, srv, client_session + import aiohttpdemo_polls.main + app, host, port = await aiohttpdemo_polls.main.init(event_loop) + handler = app.make_handler(debug=True, keep_alive_on=False) + srv = await event_loop.create_server(handler, '127.0.0.1', port) + url = "http://127.0.0.1:{}".format(port) + client_session = aiohttp.ClientSession() + return app, url, client_session + + yield create + + async def finish(): + await handler.finish_connections() + await app.finish() + await client_session.close() + srv.close() + await srv.wait_closed() + + event_loop.run_until_complete(finish()) + + +BASE_DIR = pathlib.Path(__file__).parent.parent + + +@pytest.fixture +def app_db(): + subprocess.call( + [(BASE_DIR / 'sql' / 'install.sh').as_posix()], + shell=True, + cwd=BASE_DIR.as_posix() + ) diff --git a/demos/polls/tests/test_integration.py b/demos/polls/tests/test_integration.py new file mode 100644 index 00000000000..c12b64de992 --- /dev/null +++ b/demos/polls/tests/test_integration.py @@ -0,0 +1,24 @@ +""" +Integration tests. They need a running database. + +Beware, they destroy your db using sudo. +""" + +async def _test_index(create_app): + app, url, client_session = await create_app() + async with client_session.get('{}/'.format(url)) as response: + assert response.status == 200, await response.text() + + +def test_index(create_app, event_loop, app_db): + event_loop.run_until_complete(_test_index(create_app)) + + +async def _test_results(create_app): + app, url, client_session = await create_app() + async with client_session.get('{}/results'.format(url)) as response: + assert response.status == 200, await response.text() + + +def test_results(create_app, event_loop, app_db): + event_loop.run_until_complete(_test_results(create_app)) diff --git a/demos/polls/tox.ini b/demos/polls/tox.ini new file mode 100644 index 00000000000..3d51ab854f2 --- /dev/null +++ b/demos/polls/tox.ini @@ -0,0 +1,9 @@ +[tox] +envlist = py35 + +[testenv] +deps = + pytest + pytest-asyncio==0.3.0 +usedevelop = True +commands=py.test tests -s