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