pkg/connector/users_test.go
131 linesgo
package connector

import (
	"context"
	"testing"
	"time"

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

func TestBuildUserResource(t *testing.T) {
	tests := []struct {
		name        string
		id          string
		firstName   string
		lastName    string
		email       string
		status      string
		wantDisplay string
		wantStatus  v2.UserTrait_Status_Status
	}{
		{
			name:        "active user with full name",
			id:          "u1",
			firstName:   "Alice",
			lastName:    "Smith",
			email:       "alice@test.com",
			status:      "active",
			wantDisplay: "Alice Smith",
			wantStatus:  v2.UserTrait_Status_STATUS_ENABLED,
		},
		{
			name:        "disabled user",
			id:          "u2",
			firstName:   "Bob",
			lastName:    "Jones",
			email:       "bob@test.com",
			status:      "disabled",
			wantDisplay: "Bob Jones",
			wantStatus:  v2.UserTrait_Status_STATUS_DISABLED,
		},
		{
			name:        "user with email fallback",
			id:          "u3",
			firstName:   "",
			lastName:    "",
			email:       "noname@test.com",
			status:      "active",
			wantDisplay: "noname@test.com",
			wantStatus:  v2.UserTrait_Status_STATUS_ENABLED,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			r, err := resource.NewUserResource(
				displayName(tt.firstName, tt.lastName, tt.email, tt.id),
				userResourceType,
				tt.id,
				[]resource.UserTraitOption{
					resource.WithEmail(tt.email, true),
					resource.WithStatus(mapUserStatus(tt.status)),
				},
				resource.WithAnnotation(&v2.RawId{Id: tt.id}),
			)
			if err != nil {
				t.Fatalf("unexpected error building resource: %v", err)
			}

			if r.DisplayName != tt.wantDisplay {
				t.Errorf("DisplayName = %q, want %q", r.DisplayName, tt.wantDisplay)
			}
			if r.Id.Resource != tt.id {
				t.Errorf("Resource ID = %q, want %q", r.Id.Resource, tt.id)
			}
			if r.Id.ResourceType != userResourceType.Id {
				t.Errorf("ResourceType = %q, want %q", r.Id.ResourceType, userResourceType.Id)
			}
		})
	}
}

func TestBuildUserResourceWithOptionalFields(t *testing.T) {
	t.Run("with created_at and last_login", func(t *testing.T) {
		createdAt := time.Now().Add(-24 * time.Hour)
		lastLogin := time.Now()

		r, err := resource.NewUserResource(
			"Test User",
			userResourceType,
			"u-ts",
			[]resource.UserTraitOption{
				resource.WithEmail("test@test.com", true),
				resource.WithStatus(v2.UserTrait_Status_STATUS_ENABLED),
				resource.WithCreatedAt(createdAt),
				resource.WithLastLogin(lastLogin),
			},
			resource.WithAnnotation(&v2.RawId{Id: "u-ts"}),
		)
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		if r.DisplayName != "Test User" {
			t.Errorf("DisplayName = %q, want %q", r.DisplayName, "Test User")
		}
		if r.Id.Resource != "u-ts" {
			t.Errorf("Resource ID = %q, want %q", r.Id.Resource, "u-ts")
		}

		ut, err := resource.GetUserTrait(r)
		if err != nil {
			t.Fatalf("failed to get user trait: %v", err)
		}
		if ut.GetCreatedAt().AsTime().Unix() != createdAt.Unix() {
			t.Errorf("CreatedAt = %v, want %v", ut.GetCreatedAt().AsTime(), createdAt)
		}
		if ut.GetLastLogin().AsTime().Unix() != lastLogin.Unix() {
			t.Errorf("LastLogin = %v, want %v", ut.GetLastLogin().AsTime(), lastLogin)
		}
	})
}

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