|
|
|
""" Stub file for testing the project
|
|
|
|
|
|
|
|
There are three predefined ways to run tests:
|
|
|
|
|
|
|
|
make test:
|
|
|
|
runs only unit tests, that are not marked with "fun" (for functional test)
|
|
|
|
in a random order. If a test failed before, only the failed tests will be
|
|
|
|
run. This is intended to be the default testing method while developing.
|
|
|
|
|
|
|
|
make testall:
|
|
|
|
runs unit tests and functional tests in random order. Will give a complete
|
|
|
|
overview of the test suite.
|
|
|
|
|
|
|
|
make coverage:
|
|
|
|
runs only tests marked with "fun" (for functional tests) and generates a
|
|
|
|
coverage report for the test run. The idea is to check the test coverage
|
|
|
|
only on functinal tests to see if a) everything is as much covered as
|
|
|
|
possible and b) to find dead code that is not called in end-to-end tests.
|
|
|
|
|
|
|
|
all three test strategies will run "make lint" before to catch easily made
|
|
|
|
mistakes.
|
|
|
|
"""
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
INFO_RESULT_AD = """
|
|
|
|
User AlexanderDietz is in group 'users':
|
|
|
|
Write access is granted to: AlexanderDietz:/
|
|
|
|
Read access is granted to (nearly) all journals.
|
|
|
|
Labjournal AlexanderDietz:/
|
|
|
|
Write access granted to: @administrators, AlexanderDietz
|
|
|
|
Read access granted to: @users
|
|
|
|
"""
|
|
|
|
|
|
|
|
INFO_RESULT_OP = """
|
|
|
|
User OswaldPrucker is in group 'administrators':
|
|
|
|
Write access is granted to all journals.
|
|
|
|
Read access is granted to all journals.
|
|
|
|
Labjournal OswaldPrucker:/
|
|
|
|
Write access granted to: @administrators, OswaldPrucker
|
|
|
|
Read access granted to: @users
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
INFO_RESULT_AE = """
|
|
|
|
User AndreasEvers is in group 'alumni':
|
|
|
|
Write access is NOT granted to any journals
|
|
|
|
Read access is NOT granted to any journals
|
|
|
|
Labjournal AndreasEvers:/
|
|
|
|
Write access granted to: @administrators
|
|
|
|
Read access granted to: @users, UrmilShah
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
INFO_RESULT_US = """
|
|
|
|
User UrmilShah is in group 'restricted':
|
|
|
|
Write access is granted to: UrmilShah:/
|
|
|
|
Read access is granted to: AndreasEvers:/
|
|
|
|
Labjournal UrmilShah:/
|
|
|
|
Write access granted to: @administrators, UrmilShah
|
|
|
|
Read access granted to: @users
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_get_config(example_authz):
|
|
|
|
from elab_users import get_config
|
|
|
|
from elab_users.authz import AuthzConfigParser
|
|
|
|
|
|
|
|
tmp_dir = example_authz.parent
|
|
|
|
parser = get_config(tmp_dir, "authz")
|
|
|
|
|
|
|
|
assert isinstance(parser, AuthzConfigParser)
|
|
|
|
assert parser.elab_users != {}
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_get_config_missing_file(example_authz):
|
|
|
|
from elab_users import get_config
|
|
|
|
|
|
|
|
tmp_dir = example_authz.parent
|
|
|
|
with pytest.raises(SystemExit):
|
|
|
|
get_config(tmp_dir, "not existent")
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_list_users(example_authz, capsys):
|
|
|
|
from elab_users import list_users
|
|
|
|
|
|
|
|
list_users(example_authz.parent, example_authz.name)
|
|
|
|
captured = capsys.readouterr()
|
|
|
|
|
|
|
|
admins = "Users in group 'administrators':\n JuergenRuehe\n"
|
|
|
|
assert admins in captured.out
|
|
|
|
users = "Users in group 'users':\n AlexanderDietz\n"
|
|
|
|
assert users in captured.out
|
|
|
|
restricted = "Users in group 'restricted':\n BeniPrasser\n"
|
|
|
|
assert restricted in captured.out
|
|
|
|
alumni = "Users in group 'alumni':\n AlexeyKopyshev\n"
|
|
|
|
assert alumni in captured.out
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_show_group_info(example_authz, capsys):
|
|
|
|
from elab_users import show_group_info
|
|
|
|
|
|
|
|
show_group_info("alumni", example_authz.parent, example_authz.name)
|
|
|
|
captured = capsys.readouterr()
|
|
|
|
|
|
|
|
alumni = "Users in group 'alumni':\n AlexeyKopyshev\n"
|
|
|
|
assert captured.out.startswith(alumni)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_show_group_info_unknown_group(example_authz):
|
|
|
|
from elab_users import show_group_info
|
|
|
|
|
|
|
|
with pytest.raises(SystemExit):
|
|
|
|
show_group_info("unknown", example_authz.parent, example_authz.name)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_add_new_user(example_authz, example_htpasswd, stub_handler, capsys):
|
|
|
|
from elab_users import get_config, add_new_user
|
|
|
|
|
|
|
|
add_new_user(
|
|
|
|
"JaneDoe",
|
|
|
|
"users",
|
|
|
|
example_authz.parent,
|
|
|
|
example_authz.name,
|
|
|
|
example_htpasswd.name,
|
|
|
|
handler=stub_handler,
|
|
|
|
)
|
|
|
|
captured = capsys.readouterr()
|
|
|
|
|
|
|
|
assert captured.out.startswith("New password for :")
|
|
|
|
assert "username: JaneDoe" in captured.out
|
|
|
|
url = "https://svn.cpi.imtek.uni-freiburg.de/JaneDoe"
|
|
|
|
assert f"url: {url}" in captured.out
|
|
|
|
|
|
|
|
assert stub_handler.stack[0].args[:2] == ["svnadmin", "create"]
|
|
|
|
assert stub_handler.stack[0].args[2].endswith("/JaneDoe")
|
|
|
|
|
|
|
|
config = get_config(example_authz.parent, example_authz.name)
|
|
|
|
user = config.elab_users["JaneDoe"]
|
|
|
|
assert user.group == "users"
|
|
|
|
assert user.read_acl == set()
|
|
|
|
assert user.write_acl == {"JaneDoe"}
|
|
|
|
|
|
|
|
items = config.items("JaneDoe:/")
|
|
|
|
assert sorted(items) == [
|
|
|
|
("@administrators", "rw"),
|
|
|
|
("@alumni", ""),
|
|
|
|
("@restricted", ""),
|
|
|
|
("@users", "r"),
|
|
|
|
("JaneDoe", "rw"),
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_add_new_user_error_on_existing_user(
|
|
|
|
example_authz, example_htpasswd, stub_handler
|
|
|
|
):
|
|
|
|
from elab_users import add_new_user
|
|
|
|
|
|
|
|
with pytest.raises(SystemExit):
|
|
|
|
add_new_user(
|
|
|
|
"AlexanderDietz",
|
|
|
|
"users",
|
|
|
|
example_authz.parent,
|
|
|
|
example_authz.name,
|
|
|
|
example_htpasswd.name,
|
|
|
|
handler=stub_handler,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_add_new_user_error_on_forbidden_name(
|
|
|
|
example_authz, example_htpasswd, stub_handler
|
|
|
|
):
|
|
|
|
from elab_users import add_new_user
|
|
|
|
|
|
|
|
with pytest.raises(SystemExit):
|
|
|
|
add_new_user(
|
|
|
|
"authz",
|
|
|
|
"users",
|
|
|
|
example_authz.parent,
|
|
|
|
example_authz.name,
|
|
|
|
example_htpasswd.name,
|
|
|
|
handler=stub_handler,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_retire_user(example_authz, example_htpasswd, stub_handler, capsys):
|
|
|
|
|
|
|
|
from elab_users import get_config, retire_user
|
|
|
|
|
|
|
|
retire_user(
|
|
|
|
"AlexanderDietz",
|
|
|
|
example_authz.parent,
|
|
|
|
example_authz.name,
|
|
|
|
example_htpasswd.name,
|
|
|
|
handler=stub_handler,
|
|
|
|
)
|
|
|
|
captured = capsys.readouterr()
|
|
|
|
assert captured.out.startswith("Moved user AlexanderDietz to alumni")
|
|
|
|
|
|
|
|
config = get_config(example_authz.parent, example_authz.name)
|
|
|
|
user = config.elab_users["AlexanderDietz"]
|
|
|
|
assert user.group == "alumni"
|
|
|
|
assert user.read_acl == set()
|
|
|
|
assert user.write_acl == set()
|
|
|
|
|
|
|
|
assert stub_handler.stack[-1].args[:2] == ["htpasswd", "-D"]
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_retire_user_error_unknown_user(
|
|
|
|
example_authz, example_htpasswd, stub_handler
|
|
|
|
):
|
|
|
|
|
|
|
|
from elab_users import retire_user
|
|
|
|
|
|
|
|
with pytest.raises(SystemExit):
|
|
|
|
retire_user(
|
|
|
|
"Unknown",
|
|
|
|
example_authz.parent,
|
|
|
|
example_authz.name,
|
|
|
|
example_htpasswd.name,
|
|
|
|
handler=stub_handler,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_retire_user_error_already_alumni(
|
|
|
|
example_authz, example_htpasswd, stub_handler
|
|
|
|
):
|
|
|
|
|
|
|
|
from elab_users import retire_user
|
|
|
|
|
|
|
|
with pytest.raises(SystemExit):
|
|
|
|
retire_user(
|
|
|
|
"CamillaOestevold",
|
|
|
|
example_authz.parent,
|
|
|
|
example_authz.name,
|
|
|
|
example_htpasswd.name,
|
|
|
|
handler=stub_handler,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_retire_user_error_admin(
|
|
|
|
example_authz, example_htpasswd, stub_handler
|
|
|
|
):
|
|
|
|
|
|
|
|
from elab_users import retire_user
|
|
|
|
|
|
|
|
with pytest.raises(SystemExit):
|
|
|
|
retire_user(
|
|
|
|
"OswaldPrucker",
|
|
|
|
example_authz.parent,
|
|
|
|
example_authz.name,
|
|
|
|
example_htpasswd.name,
|
|
|
|
handler=stub_handler,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_change_password(
|
|
|
|
example_authz, example_htpasswd, stub_handler, capsys
|
|
|
|
):
|
|
|
|
|
|
|
|
from elab_users import change_password
|
|
|
|
|
|
|
|
change_password(
|
|
|
|
"AlexanderDietz",
|
|
|
|
example_authz.parent,
|
|
|
|
example_authz.name,
|
|
|
|
example_htpasswd.name,
|
|
|
|
handler=stub_handler,
|
|
|
|
)
|
|
|
|
captured = capsys.readouterr()
|
|
|
|
assert captured.out.startswith("New password for :")
|
|
|
|
|
|
|
|
assert stub_handler.stack[-1].args[:2] == ["htpasswd", "-b"]
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_change_password_error_unknown_user(
|
|
|
|
example_authz, example_htpasswd, stub_handler
|
|
|
|
):
|
|
|
|
|
|
|
|
from elab_users import change_password
|
|
|
|
|
|
|
|
with pytest.raises(SystemExit):
|
|
|
|
change_password(
|
|
|
|
"Unknown",
|
|
|
|
example_authz.parent,
|
|
|
|
example_authz.name,
|
|
|
|
example_htpasswd.name,
|
|
|
|
handler=stub_handler,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"user, result",
|
|
|
|
[
|
|
|
|
("OswaldPrucker", INFO_RESULT_OP),
|
|
|
|
("AlexanderDietz", INFO_RESULT_AD),
|
|
|
|
("AndreasEvers", INFO_RESULT_AE),
|
|
|
|
("UrmilShah", INFO_RESULT_US),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_show_user_info(user, result, example_authz, capsys):
|
|
|
|
from elab_users import show_user_info
|
|
|
|
|
|
|
|
show_user_info(
|
|
|
|
user,
|
|
|
|
example_authz.parent,
|
|
|
|
example_authz.name,
|
|
|
|
)
|
|
|
|
captured = capsys.readouterr()
|
|
|
|
|
|
|
|
assert captured.out.strip() == result.strip()
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_show_user_info_error_unknown_user(example_authz):
|
|
|
|
from elab_users import show_user_info
|
|
|
|
|
|
|
|
with pytest.raises(SystemExit):
|
|
|
|
show_user_info(
|
|
|
|
"Unknown",
|
|
|
|
example_authz.parent,
|
|
|
|
example_authz.name,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"commands, result",
|
|
|
|
[
|
|
|
|
([], "Users in group 'restricted':"),
|
|
|
|
(["OswaldPrucker"], "granted to all journals"),
|
|
|
|
(["user", "OswaldPrucker"], "granted to all journals"),
|
|
|
|
(["group", "alumni"], "Users in group 'alumni':"),
|
|
|
|
(["add", "JaneDoe"], "url:"),
|
|
|
|
(["restricted", "JaneDoe"], "url:"),
|
|
|
|
(["retire", "AlexanderDietz"], "to alumni"),
|
|
|
|
(["password", "AlexanderDietz"], "username: AlexanderDietz"),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_main(
|
|
|
|
commands, result, example_authz, example_htpasswd, stub_handler, capsys
|
|
|
|
):
|
|
|
|
from elab_users import main
|
|
|
|
|
|
|
|
main(
|
|
|
|
example_authz.parent,
|
|
|
|
example_authz.name,
|
|
|
|
example_htpasswd.name,
|
|
|
|
handler=stub_handler,
|
|
|
|
cli_args=commands,
|
|
|
|
)
|
|
|
|
captured = capsys.readouterr()
|
|
|
|
|
|
|
|
assert result in captured.out
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.fun
|
|
|
|
def test_main_help(example_authz, example_htpasswd, stub_handler, capsys):
|
|
|
|
from elab_users import main
|
|
|
|
|
|
|
|
with pytest.raises(SystemExit):
|
|
|
|
main(
|
|
|
|
example_authz.parent,
|
|
|
|
example_authz.name,
|
|
|
|
example_htpasswd.name,
|
|
|
|
handler=stub_handler,
|
|
|
|
cli_args=["--help"],
|
|
|
|
)
|
|
|
|
captured = capsys.readouterr()
|
|
|
|
|
|
|
|
assert "usage: elab-users [-h] [command] [name]" in captured.out
|