Feat v0.9.9 surface access roles (#83)
All checks were successful
CI/CD / detect-changes (push) Successful in 3s
CI/CD / test-runners (push) Has been skipped
CI/CD / e2e-smoke (push) Has been skipped
CI/CD / test-frontend (push) Successful in 5s
CI/CD / test-go-pg (push) Successful in 2m49s
CI/CD / test-sqlite (push) Successful in 2m59s
CI/CD / build-and-deploy (push) Successful in 1m28s
All checks were successful
CI/CD / detect-changes (push) Successful in 3s
CI/CD / test-runners (push) Has been skipped
CI/CD / e2e-smoke (push) Has been skipped
CI/CD / test-frontend (push) Successful in 5s
CI/CD / test-go-pg (push) Successful in 2m49s
CI/CD / test-sqlite (push) Successful in 2m59s
CI/CD / build-and-deploy (push) Successful in 1m28s
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com> Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
This commit was merged in pull request #83.
This commit is contained in:
@@ -259,6 +259,8 @@ func validAccessLevels(access string) bool {
|
||||
return true
|
||||
case strings.HasPrefix(access, "group:"):
|
||||
return strings.TrimPrefix(access, "group:") != ""
|
||||
case strings.HasPrefix(access, "role:"):
|
||||
return strings.TrimPrefix(access, "role:") != ""
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -262,6 +262,93 @@ func TestRequireRole_Denied(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// ── Store: HasRoleInAnyTeam ──────────────────
|
||||
|
||||
func TestHasRoleInAnyTeam_PrimaryRole(t *testing.T) {
|
||||
database.RequireTestDB(t)
|
||||
stores := testStores(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, userID, _ := seedTeamAndMember(t, stores)
|
||||
|
||||
// "member" is the primary role assigned during seedTeamAndMember
|
||||
has, err := stores.Teams.HasRoleInAnyTeam(ctx, userID, "member")
|
||||
if err != nil {
|
||||
t.Fatalf("HasRoleInAnyTeam: %v", err)
|
||||
}
|
||||
if !has {
|
||||
t.Error("expected true for primary role 'member'")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasRoleInAnyTeam_AdditionalRole(t *testing.T) {
|
||||
database.RequireTestDB(t)
|
||||
stores := testStores(t)
|
||||
ctx := context.Background()
|
||||
|
||||
teamID, userID, _ := seedTeamAndMember(t, stores)
|
||||
stores.Teams.AddUserRole(ctx, teamID, userID, "reviewer", userID)
|
||||
|
||||
has, err := stores.Teams.HasRoleInAnyTeam(ctx, userID, "reviewer")
|
||||
if err != nil {
|
||||
t.Fatalf("HasRoleInAnyTeam: %v", err)
|
||||
}
|
||||
if !has {
|
||||
t.Error("expected true for additional role 'reviewer'")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasRoleInAnyTeam_NoMatch(t *testing.T) {
|
||||
database.RequireTestDB(t)
|
||||
stores := testStores(t)
|
||||
ctx := context.Background()
|
||||
|
||||
_, userID, _ := seedTeamAndMember(t, stores)
|
||||
|
||||
has, err := stores.Teams.HasRoleInAnyTeam(ctx, userID, "nonexistent")
|
||||
if err != nil {
|
||||
t.Fatalf("HasRoleInAnyTeam: %v", err)
|
||||
}
|
||||
if has {
|
||||
t.Error("expected false for non-existent role")
|
||||
}
|
||||
}
|
||||
|
||||
// ── Manifest: role access validation ────────
|
||||
|
||||
func TestValidateManifest_SurfaceRoleAccess(t *testing.T) {
|
||||
m := map[string]any{
|
||||
"id": "role-pkg",
|
||||
"title": "Role Gated",
|
||||
"type": "surface",
|
||||
"surfaces": []any{
|
||||
map[string]any{"path": "/", "access": "role:approver"},
|
||||
},
|
||||
}
|
||||
info, err := ValidateManifest(m)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error for role:approver access: %v", err)
|
||||
}
|
||||
if !info.HasSurfaces {
|
||||
t.Error("expected HasSurfaces to be true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateManifest_SurfaceRoleAccessEmpty(t *testing.T) {
|
||||
m := map[string]any{
|
||||
"id": "role-pkg",
|
||||
"title": "Role Gated",
|
||||
"type": "surface",
|
||||
"surfaces": []any{
|
||||
map[string]any{"path": "/", "access": "role:"},
|
||||
},
|
||||
}
|
||||
_, err := ValidateManifest(m)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for empty role name 'role:'")
|
||||
}
|
||||
}
|
||||
|
||||
// ── helpers ──────────────────────────────────
|
||||
|
||||
func seedRoleUser(t *testing.T, username, email string) string {
|
||||
|
||||
Reference in New Issue
Block a user