From cc4e4c53a912813af4806ab996f2cbd84e7ed41f Mon Sep 17 00:00:00 2001 From: Luna Date: Sun, 21 Jul 2019 12:30:52 -0300 Subject: [PATCH] copy elixire test user impl --- tests/common.py | 43 ++++++++++++++++++++++++++ tests/conftest.py | 73 ++++++++++++++++++++++++++++++++++++++++++++- tests/test_guild.py | 15 +++------- 3 files changed, 119 insertions(+), 12 deletions(-) diff --git a/tests/common.py b/tests/common.py index a7d5cbe..66d67c6 100644 --- a/tests/common.py +++ b/tests/common.py @@ -17,6 +17,7 @@ along with this program. If not, see . """ +import secrets from .credentials import CREDS async def login(acc_name: str, test_cli): @@ -44,3 +45,45 @@ async def get_uid(token, test_cli): rjson = await resp.json return rjson['id'] + + +def email() -> str: + return f'{secrets.token_hex(5)}@{secrets.token_hex(5)}.com' + + +class TestClient: + """Test client that wraps pytest-sanic's TestClient and a test + user and adds authorization headers to test requests.""" + def __init__(self, test_cli, test_user): + self.cli = test_cli + self.user = test_user + + def __getitem__(self, key): + return self.user[key] + + def _inject_auth(self, kwargs: dict) -> list: + """Inject the test user's API key into the test request before + passing the request on to the underlying TestClient.""" + headers = kwargs.get('headers', {}) + headers['authorization'] = self.user['token'] + return headers + + async def get(self, *args, **kwargs): + """Send a GET request.""" + kwargs['headers'] = self._inject_auth(kwargs) + return await self.cli.get(*args, **kwargs) + + async def post(self, *args, **kwargs): + """Send a POST request.""" + kwargs['headers'] = self._inject_auth(kwargs) + return await self.cli.post(*args, **kwargs) + + async def patch(self, *args, **kwargs): + """Send a PATCH request.""" + kwargs['headers'] = self._inject_auth(kwargs) + return await self.cli.patch(*args, **kwargs) + + async def delete(self, *args, **kwargs): + """Send a DELETE request.""" + kwargs['headers'] = self._inject_auth(kwargs) + return await self.cli.delete(*args, **kwargs) diff --git a/tests/conftest.py b/tests/conftest.py index 48c5726..f12f610 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -17,7 +17,7 @@ along with this program. If not, see . """ -import asyncio +import secrets import sys import os @@ -27,8 +27,14 @@ 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): @@ -61,3 +67,68 @@ def _test_app(unused_tcp_port, event_loop): 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) diff --git a/tests/test_guild.py b/tests/test_guild.py index f4aee70..dcb850e 100644 --- a/tests/test_guild.py +++ b/tests/test_guild.py @@ -23,19 +23,16 @@ import pytest from tests.common import login @pytest.mark.asyncio -async def test_guild_create(test_cli): +async def test_guild_create(test_cli_user): """Test the creation of a guild, in three stages: - creating it - checking the list - deleting it """ - token = await login('normal', test_cli) g_name = secrets.token_hex(5) # stage 1: create - resp = await test_cli.post('/api/v6/guilds', headers={ - 'Authorization': token - }, json={ + resp = await test_cli_user.post('/api/v6/guilds', json={ 'name': g_name, 'region': None, }) @@ -53,9 +50,7 @@ async def test_guild_create(test_cli): guild_id = created['id'] # stage 2: test - resp = await test_cli.get('/api/v6/users/@me/guilds', headers={ - 'Authorization': token - }) + resp = await test_cli_user.get('/api/v6/users/@me/guilds') assert resp.status_code == 200 rjson = await resp.json @@ -85,8 +80,6 @@ async def test_guild_create(test_cli): assert our_guild['name'] == created['name'] # stage 3: deletion - resp = await test_cli.delete(f'/api/v6/guilds/{guild_id}', headers={ - 'Authorization': token - }) + resp = await test_cli_user.delete(f'/api/v6/guilds/{guild_id}') assert resp.status_code == 204