Test suite: pytest unit and integration tests, node tests, CI workflow

This commit is contained in:
Doudou
2026-09-26 02:17:22 +00:00
parent 82b12c360d
commit 7a5385c46a
14 changed files with 1055 additions and 9 deletions
+133
View File
@@ -0,0 +1,133 @@
"""Folder rules: path normalisation, roles, deletes, moves, browsing."""
import os
import pytest
from helpers import Store
from rigshare_core.workspace import Workspace, norm
ADMIN = {"edit": True, "queue": True, "admin": True}
EDITOR = {"edit": True, "queue": True, "admin": False}
VIEWER = {"edit": False, "queue": False, "admin": False}
@pytest.fixture
def ws(tmp_path):
root = tmp_path / "workflows"
root.mkdir()
return Workspace(Store(str(tmp_path / "data")), str(root))
def touch(ws, rel):
path = os.path.join(ws.root, *rel.split("/"))
os.makedirs(os.path.dirname(path), exist_ok=True)
open(path, "w").write("{}")
@pytest.mark.parametrize("raw,expected", [
("workflows/a.json", "workflows/a.json"),
("workflows%2Fusers%2Fbob%2Fa.json", "workflows/users/bob/a.json"),
("workflows%252Fusers%252Fbob%252Fa.json", "workflows/users/bob/a.json"),
("workflows/shared/../users/bob/a.json", "workflows/users/bob/a.json"),
("../../etc/passwd", "etc/passwd"),
("workflows\\users\\bob", "workflows/users/bob"),
("", ""),
])
def test_norm(raw, expected):
assert norm(raw) == expected
def test_areas():
assert Workspace.area("users/bob/x.json") == ("private", "bob")
assert Workspace.area("shared/Team/x.json") == ("shared", "shared/Team")
assert Workspace.area("x.json") == ("common", None)
assert Workspace.workflows_rel("workflows/a/b.json") == "a/b.json"
assert Workspace.workflows_rel("subgraphs/x.json") is None
def test_private_space(ws):
assert ws.role("users/bob/x.json", "user", "bob", VIEWER) == "edit", "own space even for viewer accounts"
assert ws.role("users/bob/x.json", "user", "alice", EDITOR) is None
assert ws.role("users/bob/x.json", "user", "root", ADMIN) == "edit"
assert ws.can_delete("users/bob/x.json", "user", "bob", VIEWER)
assert not ws.can_delete("users/bob/x.json", "user", "alice", EDITOR)
def test_common_space(ws):
assert ws.role("x.json", "user", "alice", EDITOR) == "edit"
assert ws.role("x.json", "user", "dave", VIEWER) == "view"
assert not ws.can_delete("x.json", "user", "alice", EDITOR), "Common deletes are admin-only"
assert ws.can_delete("x.json", "user", "root", ADMIN)
def test_shared_folder_access_list(ws):
folder = ws.create_folder("Team", "bob")
assert ws.role(f"{folder}/a.json", "user", "alice", EDITOR) == "edit", "open by default"
ws.set_acl(folder, {"members": {"carol": "view", "erin": "edit"}})
assert ws.role(f"{folder}/a.json", "user", "alice", EDITOR) is None
assert ws.role(f"{folder}/a.json", "user", "carol", EDITOR) == "view"
assert ws.role(f"{folder}/a.json", "user", "erin", EDITOR) == "edit"
assert ws.role(f"{folder}/a.json", "user", "erin", VIEWER) == "view", "a role never exceeds account perms"
assert ws.role(f"{folder}/a.json", "user", "bob", EDITOR) == "edit", "owner always"
assert ws.can_delete(f"{folder}/a.json", "user", "bob", EDITOR)
assert not ws.can_delete(f"{folder}/a.json", "user", "erin", EDITOR)
def test_moves(ws):
folder = ws.create_folder("Team", "bob")
assert ws.can_move("users/bob/a.json", f"{folder}/a.json", "user", "bob", EDITOR)
assert ws.can_move(f"{folder}/a.json", f"{folder}/b.json", "user", "alice", EDITOR), "rename in place"
assert not ws.can_move(f"{folder}/a.json", "users/alice/a.json", "user", "alice", EDITOR), "only owner moves out"
assert not ws.can_move("users/bob/a.json", "users/alice/a.json", "user", "bob", EDITOR)
@pytest.mark.parametrize("name", ["", "..", "a/b", "x" * 80, ".hidden"])
def test_bad_folder_names(ws, name):
with pytest.raises(ValueError):
ws.create_folder(name, "bob")
def test_list_dir(ws):
folder = ws.create_folder("Team", "bob")
touch(ws, "common.json")
touch(ws, "users/alice/secret.json")
touch(ws, f"{folder}/plan.json")
shared = ws.list_dir("@shared", "user", "alice", EDITOR)
assert {e["name"] for e in shared["entries"]} == {"Team", "common"}
ws.set_acl(folder, {"members": {}})
shared = ws.list_dir("@shared", "user", "alice", EDITOR)
assert {e["name"] for e in shared["entries"]} == {"common"}
with pytest.raises(PermissionError):
ws.list_dir("users/alice", "user", "bob", EDITOR)
with pytest.raises(PermissionError):
ws.list_dir("users", "user", "bob", EDITOR)
mine = ws.list_dir("users/alice", "user", "alice", EDITOR)
assert [e["name"] for e in mine["entries"]] == ["secret"] and mine["can_mkdir"]
def test_folder_operations(ws):
touch(ws, "users/alice/keep.json")
sub = ws.make_dir("users/alice", "renders", "user", "alice", EDITOR)
assert sub == "users/alice/renders"
with pytest.raises(PermissionError):
ws.make_dir("users/alice", "x", "user", "bob", EDITOR)
with pytest.raises(PermissionError):
ws.rename_dir("users/alice", "hack", "user", "alice", EDITOR)
assert ws.rename_dir(sub, "finals", "user", "alice", EDITOR) == "users/alice/finals"
team = ws.make_dir("@shared", "Team", "user", "bob", EDITOR)
assert team == "shared/Team" and ws.folders[team]["owner"] == "bob"
assert ws.move_dir("users/alice/finals", team, "user", "alice", EDITOR) == "shared/Team/finals"
with pytest.raises(PermissionError):
ws.delete_dir(team, "user", "alice", EDITOR)
ws.delete_dir("shared/Team/finals", "user", "bob", EDITOR)
with pytest.raises(PermissionError):
ws.delete_dir("users/alice", "user", "alice", EDITOR)
def test_rename_user_moves_private_folder(ws):
touch(ws, "users/alice/keep.json")
ws.create_folder("Team", "alice")
ws.rename_user("alice", "alicia")
assert os.path.exists(os.path.join(ws.root, "users", "alicia", "keep.json"))
assert ws.folders["shared/Team"]["owner"] == "alicia"