Files
silo-server/internal/auth/account_provisioner_test.go
T

212 lines
5.5 KiB
Go

package auth
import (
"context"
"errors"
"testing"
"github.com/Silo-Server/silo-server/internal/models"
"github.com/Silo-Server/silo-server/internal/userstore"
)
type stubAccountUsers struct {
createFn func(context.Context, models.CreateUserInput) (*models.User, error)
deleteFn func(context.Context, int) error
}
func (s stubAccountUsers) Create(ctx context.Context, input models.CreateUserInput) (*models.User, error) {
return s.createFn(ctx, input)
}
func (s stubAccountUsers) Delete(ctx context.Context, id int) error {
if s.deleteFn == nil {
return nil
}
return s.deleteFn(ctx, id)
}
type stubStoreProvider struct {
store userstore.UserStore
err error
}
func (s stubStoreProvider) ForUser(context.Context, int) (userstore.UserStore, error) {
if s.err != nil {
return nil, s.err
}
return s.store, nil
}
func (s stubStoreProvider) Close() error { return nil }
type stubUserStore struct {
userstore.UserStore
createProfileFn func(context.Context, userstore.Profile) error
}
func (s stubUserStore) CreateProfile(ctx context.Context, p userstore.Profile) error {
return s.createProfileFn(ctx, p)
}
func TestAccountProvisionerCreateAccount_SkipsProfileByDefault(t *testing.T) {
var createCalls int
provisioner := NewAccountProvisioner(
stubAccountUsers{
createFn: func(context.Context, models.CreateUserInput) (*models.User, error) {
createCalls++
return &models.User{ID: 42, Username: "alex"}, nil
},
},
nil,
)
user, err := provisioner.CreateAccount(context.Background(), CreateAccountInput{
User: models.CreateUserInput{Username: "alex"},
})
if err != nil {
t.Fatalf("CreateAccount returned error: %v", err)
}
if user == nil || user.ID != 42 {
t.Fatalf("CreateAccount user = %#v, want ID 42", user)
}
if createCalls != 1 {
t.Fatalf("createCalls = %d, want 1", createCalls)
}
}
func TestAccountProvisionerCreateAccount_CreatesDefaultProfile(t *testing.T) {
var createdProfile userstore.Profile
provisioner := NewAccountProvisioner(
stubAccountUsers{
createFn: func(context.Context, models.CreateUserInput) (*models.User, error) {
return &models.User{ID: 7, Username: "alex"}, nil
},
},
stubStoreProvider{
store: stubUserStore{
createProfileFn: func(_ context.Context, p userstore.Profile) error {
createdProfile = p
return nil
},
},
},
)
_, err := provisioner.CreateAccount(context.Background(), CreateAccountInput{
User: models.CreateUserInput{Username: "alex"},
DefaultProfile: DefaultProfileOptions{
Enabled: true,
},
})
if err != nil {
t.Fatalf("CreateAccount returned error: %v", err)
}
if createdProfile.Name != "alex" {
t.Fatalf("created profile name = %q, want alex", createdProfile.Name)
}
if !createdProfile.ShowForcedSubtitles {
t.Fatal("created profile should enable forced subtitles by default")
}
}
func TestAccountProvisionerCreateAccount_UsesExplicitProfileName(t *testing.T) {
var createdProfile userstore.Profile
provisioner := NewAccountProvisioner(
stubAccountUsers{
createFn: func(context.Context, models.CreateUserInput) (*models.User, error) {
return &models.User{ID: 7, Username: "alex"}, nil
},
},
stubStoreProvider{
store: stubUserStore{
createProfileFn: func(_ context.Context, p userstore.Profile) error {
createdProfile = p
return nil
},
},
},
)
_, err := provisioner.CreateAccount(context.Background(), CreateAccountInput{
User: models.CreateUserInput{Username: "alex"},
DefaultProfile: DefaultProfileOptions{
Enabled: true,
Name: " Living Room ",
},
})
if err != nil {
t.Fatalf("CreateAccount returned error: %v", err)
}
if createdProfile.Name != "Living Room" {
t.Fatalf("created profile name = %q, want Living Room", createdProfile.Name)
}
}
func TestAccountProvisionerCreateAccount_BlankExplicitProfileNameFallsBackToUsername(t *testing.T) {
var createdProfile userstore.Profile
provisioner := NewAccountProvisioner(
stubAccountUsers{
createFn: func(context.Context, models.CreateUserInput) (*models.User, error) {
return &models.User{ID: 7, Username: "alex"}, nil
},
},
stubStoreProvider{
store: stubUserStore{
createProfileFn: func(_ context.Context, p userstore.Profile) error {
createdProfile = p
return nil
},
},
},
)
_, err := provisioner.CreateAccount(context.Background(), CreateAccountInput{
User: models.CreateUserInput{Username: "alex"},
DefaultProfile: DefaultProfileOptions{
Enabled: true,
Name: " ",
},
})
if err != nil {
t.Fatalf("CreateAccount returned error: %v", err)
}
if createdProfile.Name != "alex" {
t.Fatalf("created profile name = %q, want alex", createdProfile.Name)
}
}
func TestAccountProvisionerCreateAccount_DeletesUserWhenProfileCreationFails(t *testing.T) {
var deletedUserID int
provisioner := NewAccountProvisioner(
stubAccountUsers{
createFn: func(context.Context, models.CreateUserInput) (*models.User, error) {
return &models.User{ID: 9, Username: "alex"}, nil
},
deleteFn: func(_ context.Context, id int) error {
deletedUserID = id
return nil
},
},
stubStoreProvider{
store: stubUserStore{
createProfileFn: func(context.Context, userstore.Profile) error {
return errors.New("boom")
},
},
},
)
_, err := provisioner.CreateAccount(context.Background(), CreateAccountInput{
User: models.CreateUserInput{Username: "alex"},
DefaultProfile: DefaultProfileOptions{
Enabled: true,
},
})
if err == nil {
t.Fatal("CreateAccount returned nil error, want failure")
}
if deletedUserID != 9 {
t.Fatalf("deletedUserID = %d, want 9", deletedUserID)
}
}