85 lines
3.5 KiB
Python
85 lines
3.5 KiB
Python
from __future__ import annotations
|
|||
|
|
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
from packetstation import cli
|
||
|
|
from packetstation.auth import groups
|
||
|
|
|
||
|
|
GROUPS_TXT = Path(__file__).resolve().parents[2] / "deploy" / "samba" / "groups.txt"
|
||
|
|
|
||
|
|
|
||
|
|
def test_fifty_names_in_contract_order() -> None:
|
||
|
|
names = groups.group_names()
|
||
|
|
assert len(names) == 50 == len(set(names))
|
||
|
|
assert names[:8] == [
|
||
|
|
"PS-Admins",
|
||
|
|
"PS-Clerical",
|
||
|
|
"PS-Clerical-Supervisor",
|
||
|
|
"PS-Warehouse",
|
||
|
|
"PS-Warehouse-Supervisor",
|
||
|
|
"PS-QC",
|
||
|
|
"PS-QC-Supervisor",
|
||
|
|
"PS-ProjectMgmt",
|
||
|
|
]
|
||
|
|
assert names[8:11] == ["PS-01-Layout-Worker", "PS-01-Layout-Lead", "PS-01-Layout-Supervisor"]
|
||
|
|
assert names[-1] == "PS-14-Electrical-Supervisor"
|
||
|
|
|
||
|
|
|
||
|
|
def test_cli_list_equals_committed_file(capsys: pytest.CaptureFixture[str]) -> None:
|
||
|
|
assert cli.main(["ad-groups", "--list"]) == 0
|
||
|
|
out = capsys.readouterr().out
|
||
|
|
assert out == GROUPS_TXT.read_text(encoding="utf-8")
|
||
|
|
|
||
|
|
|
||
|
|
def test_role_for_group_is_case_insensitive() -> None:
|
||
|
|
assert str(groups.role_for_group("ps-03-weldparts-LEAD")) == "shop:03:lead"
|
||
|
|
assert str(groups.role_for_group("PS-Admins")) == "admin"
|
||
|
|
assert groups.role_for_group("PS-Admins").dept_code is None # type: ignore[union-attr]
|
||
|
|
assert str(groups.role_for_group("PS-QC-Supervisor")) == "qc_supervisor"
|
||
|
|
assert groups.role_for_group("PS-Extra-Legacy") is None
|
||
|
|
assert groups.role_for_group("PS-ProjectMgmt-Supervisor") is None
|
||
|
|
|
||
|
|
|
||
|
|
def test_roles_union_and_highest_shop_level() -> None:
|
||
|
|
assert groups.roles_from_groups(["PS-03-WeldParts-Worker", "PS-03-WeldParts-Supervisor"]) == ["shop:03:supervisor"]
|
||
|
|
assert groups.roles_from_groups(["PS-Clerical", "PS-06-CodeBldg2-Supervisor", "x"]) == [
|
||
|
|
"clerical",
|
||
|
|
"shop:06:supervisor",
|
||
|
|
]
|
||
|
|
assert groups.roles_from_groups(["PS-Clerical", "PS-Clerical-Supervisor"]) == ["clerical", "clerical_supervisor"]
|
||
|
|
assert groups.roles_from_groups(["PS-10-WeldAssembly-Lead", "PS-03-WeldParts-Worker"]) == [
|
||
|
|
"shop:03:worker",
|
||
|
|
"shop:10:lead",
|
||
|
|
]
|
||
|
|
assert groups.roles_from_groups([]) == []
|
||
|
|
assert groups.roles_from_groups(["Domain Users"]) == []
|
||
|
|
|
||
|
|
|
||
|
|
def test_screens() -> None:
|
||
|
|
assert groups.screens_for(["clerical", "shop:03:supervisor"]) == ["clerical", "supervisor", "stall"]
|
||
|
|
assert groups.screens_for(["shop:03:worker"]) == ["stall"]
|
||
|
|
assert groups.screens_for(["shop:03:lead"]) == ["supervisor", "stall"]
|
||
|
|
assert groups.screens_for(["warehouse_supervisor", "qc", "pm"]) == ["warehouse", "qc", "pm"]
|
||
|
|
assert groups.screens_for(["admin"]) == list(groups.SCREENS)
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.parametrize("text", ["admin", "clerical", "qc_supervisor", "pm", "shop:03:worker", "shop:14:supervisor"])
|
||
|
|
def test_parse_role_round_trip(text: str) -> None:
|
||
|
|
assert str(groups.parse_role(text)) == text
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.parametrize("text", ["", "shop:03", "shop:03:boss", "root", "shop::lead"])
|
||
|
|
def test_parse_role_rejects(text: str) -> None:
|
||
|
|
with pytest.raises(ValueError):
|
||
|
|
groups.parse_role(text)
|
||
|
|
|
||
|
|
|
||
|
|
def test_departments_mirror_and_custom_map() -> None:
|
||
|
|
assert [d.code for d in groups.DEPARTMENTS][:4] == ["CL", "WH", "QC", "PM"]
|
||
|
|
custom = groups.GroupMap([*groups.DEPARTMENTS, groups.Department("15", "Machining", "Machining", "shop", 190)])
|
||
|
|
assert custom.names()[-3:] == ["PS-15-Machining-Worker", "PS-15-Machining-Lead", "PS-15-Machining-Supervisor"]
|
||
|
|
assert len(custom.names()) == 53
|
||
|
|
assert groups.is_shop_supervisor(["shop:01:supervisor"]) and not groups.is_shop_supervisor(["shop:01:lead"])
|