pkg/connector/roles_test.go
183 linesgo
package connector

import (
	"context"
	"fmt"
	"testing"

	v2 "github.com/conductorone/baton-sdk/pb/c1/connector/v2"
	"github.com/conductorone/baton-sdk/pkg/types/entitlement"
	"github.com/conductorone/baton-sdk/pkg/types/grant"
	"github.com/conductorone/baton-sdk/pkg/types/resource"
)

func TestBuildRoleResource(t *testing.T) {
	tests := []struct {
		name        string
		id          string
		roleName    string
		description string
	}{
		{"single ride", "r1", "Single Ride", "One-time journey on any standard route"},
		{"standard day", "r2", "Standard Day", "Unlimited standard travel for the day"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			r, err := resource.NewRoleResource(
				tt.roleName,
				roleResourceType,
				tt.id,
				[]resource.RoleTraitOption{
					resource.WithRoleProfile(map[string]interface{}{
						"description": tt.description,
					}),
				},
				resource.WithAnnotation(&v2.RawId{Id: tt.id}),
			)
			if err != nil {
				t.Fatalf("unexpected error: %v", err)
			}
			if r.DisplayName != tt.roleName {
				t.Errorf("DisplayName = %q, want %q", r.DisplayName, tt.roleName)
			}
			if r.Id.Resource != tt.id {
				t.Errorf("Resource ID = %q, want %q", r.Id.Resource, tt.id)
			}
			if r.Id.ResourceType != roleResourceType.Id {
				t.Errorf("ResourceType = %q, want %q", r.Id.ResourceType, roleResourceType.Id)
			}
		})
	}
}

func TestRoleEntitlementCreation(t *testing.T) {
	roleRes, err := resource.NewRoleResource(
		"Single Ride",
		roleResourceType,
		"r1",
		[]resource.RoleTraitOption{},
		resource.WithAnnotation(&v2.RawId{Id: "r1"}),
	)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	e := entitlement.NewAssignmentEntitlement(
		roleRes,
		memberEntitlement,
		entitlement.WithGrantableTo(userResourceType, groupResourceType, roleResourceType),
		entitlement.WithDisplayName(fmt.Sprintf("%s Member", roleRes.DisplayName)),
		entitlement.WithDescription(fmt.Sprintf("Assigned the %s role", roleRes.DisplayName)),
	)

	if e == nil {
		t.Fatal("expected non-nil entitlement")
	}
	if e.DisplayName != "Single Ride Member" {
		t.Errorf("DisplayName = %q, want %q", e.DisplayName, "Single Ride Member")
	}
	if e.Description != "Assigned the Single Ride role" {
		t.Errorf("Description = %q, want %q", e.Description, "Assigned the Single Ride role")
	}
}

func TestRoleGrantCreation(t *testing.T) {
	roleRes, err := resource.NewRoleResource(
		"Standard Day",
		roleResourceType,
		"r2",
		[]resource.RoleTraitOption{},
	)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	t.Run("direct user grant", func(t *testing.T) {
		g := grant.NewGrant(
			roleRes,
			memberEntitlement,
			&v2.ResourceId{
				ResourceType: userResourceType.Id,
				Resource:     "u4",
			},
		)

		if g == nil {
			t.Fatal("expected non-nil grant")
		}
		if g.Principal.Id.Resource != "u4" {
			t.Errorf("principal resource = %q, want %q", g.Principal.Id.Resource, "u4")
		}
		if g.Principal.Id.ResourceType != userResourceType.Id {
			t.Errorf("principal type = %q, want %q", g.Principal.Id.ResourceType, userResourceType.Id)
		}
	})

	t.Run("expandable group grant", func(t *testing.T) {
		g := grant.NewGrant(
			roleRes,
			memberEntitlement,
			&v2.ResourceId{
				ResourceType: groupResourceType.Id,
				Resource:     "g1",
			},
			grant.WithAnnotation(&v2.GrantExpandable{
				EntitlementIds: []string{"group:g1:member"},
			}),
		)

		if g == nil {
			t.Fatal("expected non-nil grant")
		}
		if g.Principal.Id.Resource != "g1" {
			t.Errorf("principal resource = %q, want %q", g.Principal.Id.Resource, "g1")
		}
		if g.Principal.Id.ResourceType != groupResourceType.Id {
			t.Errorf("principal type = %q, want %q", g.Principal.Id.ResourceType, groupResourceType.Id)
		}
	})

	t.Run("expandable role grant", func(t *testing.T) {
		diningRes, err := resource.NewRoleResource(
			"Dining Access",
			roleResourceType,
			"r3",
			[]resource.RoleTraitOption{},
		)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}

		g := grant.NewGrant(
			diningRes,
			memberEntitlement,
			&v2.ResourceId{
				ResourceType: roleResourceType.Id,
				Resource:     "r4",
			},
			grant.WithAnnotation(&v2.GrantExpandable{
				EntitlementIds: []string{"role:r4:member"},
			}),
		)

		if g == nil {
			t.Fatal("expected non-nil grant")
		}
		if g.Principal.Id.Resource != "r4" {
			t.Errorf("principal resource = %q, want %q", g.Principal.Id.Resource, "r4")
		}
		if g.Principal.Id.ResourceType != roleResourceType.Id {
			t.Errorf("principal type = %q, want %q", g.Principal.Id.ResourceType, roleResourceType.Id)
		}
	})
}

func TestRoleBuilderResourceType(t *testing.T) {
	b := newRoleBuilder(nil)
	rt := b.ResourceType(context.TODO())
	if rt != roleResourceType {
		t.Errorf("expected roleResourceType, got %v", rt)
	}
}