runbook-tutorials/tests/test_user.py
tegwick 8d62c1fbe8
Some checks failed
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 3s
Work Records / validate (push) Has been cancelled
Active user attribute set, latest activities, guarded changes to used values, artefact links, durations and averages; irreversible showcase step
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 295952@bnt-lap001
Assistant-Session: e93f64ad-516c-46eb-9666-aad8d300c477
2026-09-29 15:50:56 +02:00

51 lines
2.6 KiB
Python

from pathlib import Path
import pytest
import yaml
from rtut import project as J, user
from rtut.attrs import Registry, fold, set_layers
@pytest.fixture(autouse=True)
def cfg(tmp_path, monkeypatch):
monkeypatch.setenv("RTUT_CONFIG_DIR", str(tmp_path / "cfg"))
monkeypatch.delenv("RTUT_USER", raising=False)
def test_operator_comes_from_the_login_until_saved_then_from_the_file_and_the_environment_wins(monkeypatch):
monkeypatch.setattr("getpass.getuser", lambda: "Bernd Worsch")
assert user.current() == {"operator": "Bernd-Worsch", "display_name": "", "source": "login"} # always one word
user.save("bernd", "Bernd W.")
assert user.current() == {"operator": "bernd", "display_name": "Bernd W.", "source": "saved"}
monkeypatch.setenv("RTUT_USER", "alice@example.org")
assert user.current()["operator"] == "alice-example.org" and user.current()["source"] == "environment"
def test_save_validates_and_refuses_secrets():
for bad in ("two words", "", "x" * 41, "-lead"):
with pytest.raises(ValueError):
user.save(bad)
with pytest.raises(ValueError, match="secret"):
user.save("ok", "hvs.ABCDEFGHIJKLMN")
assert not user.user_file().exists()
def test_user_attributes_are_a_reusable_attribute_set_outside_projects(tmp_path):
user.save("bernd")
repo = tmp_path / "repo"
(repo / "runbooks/h").mkdir(parents=True)
(repo / "runbooks/h/pack.yaml").write_text((Path(__file__).resolve().parent.parent / "runbooks/example-hello/pack.yaml").read_text())
reg = Registry([repo], extra_sets={user.USER_SET_ID: user.attribute_set()})
f = fold(set_layers(reg, "user-attributes"))
assert f["operator"]["value"] == "bernd" and f["operator"]["requirement"] == "required"
d = {"spec": "project/v0.1", "id": "p", "title": "Project p", "environment": "rehearsal", "attribute_sets": ["user-attributes"],
"runbooks": [{"pack": "rtut.example-hello"}]}
(repo / "projects/p").mkdir(parents=True)
(repo / "projects/p/project.yaml").write_text(yaml.safe_dump(d))
reg = Registry([repo], extra_sets={user.USER_SET_ID: user.attribute_set()})
assert J.validate(reg, reg.projects["p"]) == [] # a project can reuse the user's attributes
(repo / "attribute-sets").mkdir()
(repo / "attribute-sets/user-attributes.yaml").write_text(yaml.safe_dump({"spec": "attribute-set/v0.1", "id": "user-attributes", "title": "Repo override", "attributes": {"operator": "someone"}}))
reg = Registry([repo], extra_sets={user.USER_SET_ID: user.attribute_set()})
assert fold(set_layers(reg, "user-attributes"))["operator"]["value"] == "someone" # a repository's own set takes precedence