package server import ( "testing" "git.lohmar.co.uk/cclohmar/NextMyDay/internal/core/users" ) // TestTiersRippleDown proves the D-034 role gate: simple tiers, one role per // user, and a role implies every role below it. func TestTiersRippleDown(t *testing.T) { g := NewTiers() // No explicit requirement -> the floor (team): every authenticated role is // admitted. for _, r := range []users.Role{users.RoleTeam, users.RoleManager, users.RoleDirector, users.RoleAdmin} { if !g.Allowed(r, "home", "dashboard") { t.Errorf("%s was denied an unlisted function (floor = team)", r) } } // An invalid/empty role fails closed. if g.Allowed(users.Role("boss"), "home", "dashboard") { t.Error("an invalid role was admitted by the tier gate") } if g.Allowed(users.Role(""), "home", "dashboard") { t.Error("an empty role was admitted by the tier gate") } // A function requiring manager: team is denied, manager and above pass // (ripple-down). g.Require("users", "create", users.RoleManager) if g.Allowed(users.RoleTeam, "users", "create") { t.Error("team was admitted to a manager function") } for _, r := range []users.Role{users.RoleManager, users.RoleDirector, users.RoleAdmin} { if !g.Allowed(r, "users", "create") { t.Errorf("%s was denied a manager function (ripple-down)", r) } } // A director function: only director and admin pass. g.Require("users", "promote", users.RoleDirector) if g.Allowed(users.RoleManager, "users", "promote") { t.Error("manager was admitted to a director function") } if !g.Allowed(users.RoleAdmin, "users", "promote") { t.Error("admin was denied a director function") } }