Feat v0.9.9 surface access via roles
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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