copy elixire test user impl

This commit is contained in:
Luna 2019-07-21 12:30:52 -03:00
parent 13b2bfe242
commit cc4e4c53a9
3 changed files with 119 additions and 12 deletions

View File

@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import secrets
from .credentials import CREDS from .credentials import CREDS
async def login(acc_name: str, test_cli): async def login(acc_name: str, test_cli):
@ -44,3 +45,45 @@ async def get_uid(token, test_cli):
rjson = await resp.json rjson = await resp.json
return rjson['id'] 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)

View File

@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import asyncio import secrets
import sys import sys
import os import os
@ -27,8 +27,14 @@ import pytest
# this is very hacky. # this is very hacky.
sys.path.append(os.getcwd()) sys.path.append(os.getcwd())
from tests.common import email, TestClient
from run import app as main_app, set_blueprints 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') @pytest.fixture(name='app')
def _test_app(unused_tcp_port, event_loop): def _test_app(unused_tcp_port, event_loop):
@ -61,3 +67,68 @@ def _test_app(unused_tcp_port, event_loop):
def _test_cli(app): def _test_cli(app):
"""Give a test client.""" """Give a test client."""
return app.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)

View File

@ -23,19 +23,16 @@ import pytest
from tests.common import login from tests.common import login
@pytest.mark.asyncio @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: """Test the creation of a guild, in three stages:
- creating it - creating it
- checking the list - checking the list
- deleting it - deleting it
""" """
token = await login('normal', test_cli)
g_name = secrets.token_hex(5) g_name = secrets.token_hex(5)
# stage 1: create # stage 1: create
resp = await test_cli.post('/api/v6/guilds', headers={ resp = await test_cli_user.post('/api/v6/guilds', json={
'Authorization': token
}, json={
'name': g_name, 'name': g_name,
'region': None, 'region': None,
}) })
@ -53,9 +50,7 @@ async def test_guild_create(test_cli):
guild_id = created['id'] guild_id = created['id']
# stage 2: test # stage 2: test
resp = await test_cli.get('/api/v6/users/@me/guilds', headers={ resp = await test_cli_user.get('/api/v6/users/@me/guilds')
'Authorization': token
})
assert resp.status_code == 200 assert resp.status_code == 200
rjson = await resp.json rjson = await resp.json
@ -85,8 +80,6 @@ async def test_guild_create(test_cli):
assert our_guild['name'] == created['name'] assert our_guild['name'] == created['name']
# stage 3: deletion # stage 3: deletion
resp = await test_cli.delete(f'/api/v6/guilds/{guild_id}', headers={ resp = await test_cli_user.delete(f'/api/v6/guilds/{guild_id}')
'Authorization': token
})
assert resp.status_code == 204 assert resp.status_code == 204