2023-03-10 11:05:22 -05:00
|
|
|
import pytest
|
2023-03-10 18:17:03 -05:00
|
|
|
import yaml
|
2023-03-10 13:57:18 -05:00
|
|
|
from sachet.server.users import manage
|
2023-03-10 11:05:22 -05:00
|
|
|
from click.testing import CliRunner
|
2023-04-08 18:35:56 -04:00
|
|
|
from sachet.server import app, db, storage
|
2023-04-01 17:56:25 -04:00
|
|
|
from sachet.server.models import Permissions, User
|
2023-03-27 21:54:20 -04:00
|
|
|
from bitmask import Bitmask
|
2023-04-08 18:35:56 -04:00
|
|
|
from pathlib import Path
|
|
|
|
import random
|
|
|
|
import itertools
|
2023-03-27 21:54:20 -04:00
|
|
|
|
2023-03-30 20:20:09 -04:00
|
|
|
|
2023-03-10 11:05:22 -05:00
|
|
|
@pytest.fixture
|
2023-04-08 18:35:56 -04:00
|
|
|
def rand():
|
|
|
|
"""Deterministic random data generator.
|
|
|
|
|
|
|
|
Be sure to seed 0 with each test!
|
|
|
|
"""
|
|
|
|
r = random.Random()
|
|
|
|
r.seed(0)
|
|
|
|
return r
|
|
|
|
|
2023-04-09 17:49:26 -04:00
|
|
|
|
2023-04-09 15:04:22 -04:00
|
|
|
def clear_filesystem():
|
|
|
|
if app.config["SACHET_STORAGE"] == "filesystem":
|
|
|
|
for file in itertools.chain(
|
|
|
|
storage._meta_directory.iterdir(),
|
|
|
|
storage._files_directory.iterdir(),
|
|
|
|
):
|
|
|
|
if file.is_relative_to(Path(app.instance_path)) and file.is_file():
|
|
|
|
file.unlink()
|
|
|
|
else:
|
2023-04-09 17:49:26 -04:00
|
|
|
raise OSError(f"Attempted to delete {file}: please delete it yourself.")
|
|
|
|
|
2023-04-08 18:35:56 -04:00
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def client(config={}):
|
2023-03-10 11:05:22 -05:00
|
|
|
"""Flask application with DB already set up and ready."""
|
|
|
|
with app.test_client() as client:
|
|
|
|
with app.app_context():
|
2023-04-08 18:35:56 -04:00
|
|
|
for k, v in config.items():
|
|
|
|
app.config[k] = v
|
|
|
|
|
2023-03-10 11:05:22 -05:00
|
|
|
db.drop_all()
|
|
|
|
db.create_all()
|
|
|
|
db.session.commit()
|
2023-04-09 15:04:22 -04:00
|
|
|
clear_filesystem()
|
2023-03-10 13:57:18 -05:00
|
|
|
yield client
|
2023-04-09 15:04:22 -04:00
|
|
|
clear_filesystem()
|
2023-03-10 11:05:22 -05:00
|
|
|
db.session.remove()
|
|
|
|
db.drop_all()
|
2023-03-30 20:20:09 -04:00
|
|
|
|
2023-03-10 11:05:22 -05:00
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def flask_app_bare():
|
|
|
|
"""Flask application with empty DB."""
|
|
|
|
with app.test_client() as client:
|
|
|
|
with app.app_context():
|
|
|
|
yield client
|
|
|
|
db.drop_all()
|
|
|
|
|
|
|
|
|
2023-03-10 13:57:18 -05:00
|
|
|
@pytest.fixture
|
|
|
|
def users(client):
|
|
|
|
"""Creates all the test users.
|
|
|
|
|
|
|
|
Returns a dictionary with all the info for each user.
|
|
|
|
"""
|
2023-03-27 21:54:20 -04:00
|
|
|
userinfo = dict(
|
2023-03-30 20:20:09 -04:00
|
|
|
jeff=dict(password="1234", permissions=Bitmask()),
|
|
|
|
administrator=dict(password="4321", permissions=Bitmask(Permissions.ADMIN)),
|
|
|
|
)
|
2023-03-10 13:57:18 -05:00
|
|
|
|
|
|
|
for user, info in userinfo.items():
|
|
|
|
info["username"] = user
|
2023-03-30 20:20:09 -04:00
|
|
|
manage.create_user(info["permissions"], info["username"], info["password"])
|
2023-03-10 13:57:18 -05:00
|
|
|
|
|
|
|
return userinfo
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def validate_info(users):
|
2023-03-27 21:54:20 -04:00
|
|
|
"""Given a response, deserialize and validate the information against a given user's info."""
|
2023-03-25 17:16:33 -04:00
|
|
|
|
|
|
|
verify_fields = [
|
|
|
|
"username",
|
2023-03-27 21:54:20 -04:00
|
|
|
"permissions",
|
2023-03-25 17:16:33 -04:00
|
|
|
]
|
|
|
|
|
2023-03-10 13:57:18 -05:00
|
|
|
def _validate(user, info):
|
2023-04-01 17:56:25 -04:00
|
|
|
info = User.get_schema(User).load(info)
|
2023-03-27 21:54:20 -04:00
|
|
|
|
2023-03-25 17:16:33 -04:00
|
|
|
for k in verify_fields:
|
|
|
|
assert users[user][k] == info[k]
|
2023-03-10 13:57:18 -05:00
|
|
|
|
|
|
|
return _validate
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def tokens(client, users):
|
|
|
|
"""Logs in all test users.
|
|
|
|
|
|
|
|
Returns a dictionary of auth tokens for all test users.
|
|
|
|
"""
|
|
|
|
|
|
|
|
toks = {}
|
|
|
|
|
|
|
|
for user, creds in users.items():
|
2023-03-30 20:20:09 -04:00
|
|
|
resp = client.post(
|
|
|
|
"/users/login",
|
|
|
|
json={"username": creds["username"], "password": creds["password"]},
|
|
|
|
)
|
2023-03-10 13:57:18 -05:00
|
|
|
resp_json = resp.get_json()
|
|
|
|
token = resp_json.get("auth_token")
|
|
|
|
assert token is not None and token != ""
|
|
|
|
toks[creds["username"]] = token
|
|
|
|
|
|
|
|
return toks
|
|
|
|
|
|
|
|
|
2023-03-10 11:05:22 -05:00
|
|
|
@pytest.fixture
|
|
|
|
def cli():
|
|
|
|
"""click's testing fixture"""
|
|
|
|
return CliRunner()
|