""" Litecord Copyright (C) 2018-2019 Luna Mendes This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ import secrets import sys import os import socket import pytest # this is very hacky. sys.path.append(os.getcwd()) from tests.common import email, TestClient from run import app as main_app, set_blueprints from litecord.auth import create_user from litecord.blueprints.auth import make_token from litecord.blueprints.users import delete_user @pytest.fixture(name='app') def _test_app(unused_tcp_port, event_loop): set_blueprints(main_app) main_app.config['_testing'] = True # reassign an unused tcp port for websockets # since the config might give a used one. ws_port = unused_tcp_port main_app.config['IS_SSL'] = False main_app.config['WS_PORT'] = ws_port main_app.config['WEBSOCKET_URL'] = f'localhost:{ws_port}' # testing user creations requires hardcoding this to true # on testing main_app.config['REGISTRATIONS'] = True # make sure we're calling the before_serving hooks event_loop.run_until_complete(main_app.startup()) # https://docs.pytest.org/en/latest/fixture.html#fixture-finalization-executing-teardown-code yield main_app # properly teardown event_loop.run_until_complete(main_app.shutdown()) @pytest.fixture(name='test_cli') def _test_cli(app): """Give a test client.""" return app.test_client() # code shamelessly stolen from my elixire mr # https://gitlab.com/elixire/elixire/merge_requests/52 async def _user_fixture_setup(app): username = secrets.token_hex(6) password = secrets.token_hex(6) user_email = email() # TODO context? user_id, pwd_hash = await create_user( username, user_email, password, app.db, app.loop) # generate a token for api access user_token = make_token(user_id, pwd_hash) return {'id': user_id, 'token': user_token, 'email': user_email, 'username': username, 'password': password} async def _user_fixture_teardown(app, udata: dict): await delete_user(udata['id'], db=app.db) @pytest.fixture(name='test_user') async def test_user_fixture(app): """Yield a randomly generated test user.""" udata = await _user_fixture_setup(app) yield udata await _user_fixture_teardown(app, udata) @pytest.fixture async def test_cli_user(test_cli, test_user): """Yield a TestClient instance that contains a randomly generated user.""" yield TestClient(test_cli, test_user) @pytest.fixture async def test_cli_admin(test_cli): """Yield a TestClient referencing an admin. This does not use the test_user because if a given test uses both test_cli_user and test_cli_admin, test_cli_admin will just point to that same test_cli_user, which isn't acceptable. """ test_user = await _user_fixture_setup(test_cli.app) await test_cli.app.db.execute(""" UPDATE users SET admin = true WHERE user_id = $1 """, test_user['id']) await test_cli.app.db.execute(""" INSERT INTO domain_owners (domain_id, user_id) VALUES (0, $1) ON CONFLICT ON CONSTRAINT domain_owners_pkey DO UPDATE SET user_id = $1 WHERE domain_owners.domain_id = 0 """, test_user['id']) yield TestClient(test_cli, test_user) await _user_fixture_teardown(test_cli.app, test_user)