259 lines
7.6 KiB
Go
259 lines
7.6 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/logger"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
"github.com/gochat/gochat/internal/repository"
|
|
)
|
|
|
|
// ========== Test Setup ==========
|
|
|
|
func setupCustomRoleServiceTest(t *testing.T) (*CustomRoleService, *gorm.DB) {
|
|
t.Helper()
|
|
|
|
db, err := gorm.Open(sqlite.Open("file::memory:"), &gorm.Config{
|
|
Logger: logger.Default.LogMode(logger.Silent),
|
|
})
|
|
require.NoError(t, err, "failed to open SQLite test db")
|
|
|
|
require.NoError(t, db.AutoMigrate(
|
|
&model.Account{},
|
|
&model.User{},
|
|
&model.AccountUser{},
|
|
&model.CustomRole{},
|
|
), "failed to auto-migrate")
|
|
|
|
t.Cleanup(func() {
|
|
sqlDB, _ := db.DB()
|
|
sqlDB.Close()
|
|
})
|
|
|
|
repo := repository.NewCustomRoleRepo(db)
|
|
svc := NewCustomRoleService(repo)
|
|
return svc, db
|
|
}
|
|
|
|
func createCRSvcTestAccount(t *testing.T, db *gorm.DB) *model.Account {
|
|
t.Helper()
|
|
account := &model.Account{Name: "CustomRoleSvcOrg", Locale: "en", Active: true}
|
|
require.NoError(t, db.Create(account).Error)
|
|
return account
|
|
}
|
|
|
|
// ========== List ==========
|
|
|
|
func TestCustomRoleService_List(t *testing.T) {
|
|
svc, db := setupCustomRoleServiceTest(t)
|
|
account := createCRSvcTestAccount(t, db)
|
|
|
|
// Create 2 roles
|
|
_, err := svc.Create(context.Background(), account.ID, CreateCustomRoleRequest{
|
|
Name: "Supervisor",
|
|
Permissions: []string{"conversation_manage"},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
_, err = svc.Create(context.Background(), account.ID, CreateCustomRoleRequest{
|
|
Name: "TeamLead",
|
|
Permissions: []string{"conversation_unassigned_manage"},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
roles, total, err := svc.List(context.Background(), account.ID, 1, 25)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, int64(2), total)
|
|
assert.Len(t, roles, 2)
|
|
}
|
|
|
|
func TestCustomRoleService_List_Empty(t *testing.T) {
|
|
svc, db := setupCustomRoleServiceTest(t)
|
|
account := createCRSvcTestAccount(t, db)
|
|
|
|
roles, total, err := svc.List(context.Background(), account.ID, 1, 25)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, int64(0), total)
|
|
assert.Len(t, roles, 0)
|
|
}
|
|
|
|
// ========== Create ==========
|
|
|
|
func TestCustomRoleService_Create(t *testing.T) {
|
|
svc, db := setupCustomRoleServiceTest(t)
|
|
account := createCRSvcTestAccount(t, db)
|
|
|
|
role, err := svc.Create(context.Background(), account.ID, CreateCustomRoleRequest{
|
|
Name: "Supervisor",
|
|
Permissions: []string{"conversation_manage", "contact_manage"},
|
|
})
|
|
assert.NoError(t, err)
|
|
assert.NotZero(t, role.ID)
|
|
assert.Equal(t, "Supervisor", role.Name)
|
|
}
|
|
|
|
func TestCustomRoleService_Create_EmptyPermissions(t *testing.T) {
|
|
svc, db := setupCustomRoleServiceTest(t)
|
|
account := createCRSvcTestAccount(t, db)
|
|
|
|
// Create with nil permissions — should default to "{}"
|
|
role, err := svc.Create(context.Background(), account.ID, CreateCustomRoleRequest{
|
|
Name: "EmptyRole",
|
|
Permissions: nil,
|
|
})
|
|
assert.NoError(t, err)
|
|
assert.NotZero(t, role.ID)
|
|
}
|
|
|
|
func TestCustomRoleService_Create_InvalidPermission(t *testing.T) {
|
|
svc, db := setupCustomRoleServiceTest(t)
|
|
account := createCRSvcTestAccount(t, db)
|
|
|
|
_, err := svc.Create(context.Background(), account.ID, CreateCustomRoleRequest{
|
|
Name: "InvalidRole",
|
|
Permissions: []string{"conversation_delete"},
|
|
})
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
// ========== GetByID ==========
|
|
|
|
func TestCustomRoleService_GetByID(t *testing.T) {
|
|
svc, db := setupCustomRoleServiceTest(t)
|
|
account := createCRSvcTestAccount(t, db)
|
|
|
|
created, err := svc.Create(context.Background(), account.ID, CreateCustomRoleRequest{
|
|
Name: "TeamLead",
|
|
Permissions: []string{"conversation_participating_manage"},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
found, err := svc.GetByID(context.Background(), created.ID, account.ID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, created.ID, found.ID)
|
|
assert.Equal(t, "TeamLead", found.Name)
|
|
}
|
|
|
|
func TestCustomRoleService_GetByID_WrongAccount(t *testing.T) {
|
|
svc, db := setupCustomRoleServiceTest(t)
|
|
account := createCRSvcTestAccount(t, db)
|
|
|
|
created, err := svc.Create(context.Background(), account.ID, CreateCustomRoleRequest{
|
|
Name: "TeamLead",
|
|
Permissions: []string{"conversation_participating_manage"},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Wrong account should fail
|
|
_, err = svc.GetByID(context.Background(), created.ID, 9999)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
// ========== Update ==========
|
|
|
|
func TestCustomRoleService_Update(t *testing.T) {
|
|
svc, db := setupCustomRoleServiceTest(t)
|
|
account := createCRSvcTestAccount(t, db)
|
|
|
|
created, err := svc.Create(context.Background(), account.ID, CreateCustomRoleRequest{
|
|
Name: "Supervisor",
|
|
Permissions: []string{"conversation_manage"},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
updated, err := svc.Update(context.Background(), created.ID, account.ID, UpdateCustomRoleRequest{
|
|
Name: "Senior Supervisor",
|
|
})
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "Senior Supervisor", updated.Name)
|
|
}
|
|
|
|
func TestCustomRoleService_Update_ClearsDescriptionAndPermissions(t *testing.T) {
|
|
svc, db := setupCustomRoleServiceTest(t)
|
|
account := createCRSvcTestAccount(t, db)
|
|
description := "Can manage conversations"
|
|
|
|
created, err := svc.Create(context.Background(), account.ID, CreateCustomRoleRequest{
|
|
Name: "Supervisor",
|
|
Description: description,
|
|
Permissions: []string{"conversation_manage"},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
emptyDescription := ""
|
|
updated, err := svc.Update(context.Background(), created.ID, account.ID, UpdateCustomRoleRequest{
|
|
Description: &emptyDescription,
|
|
Permissions: []string{},
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "", updated.Description)
|
|
permissions, err := updated.GetPermissionKeys()
|
|
require.NoError(t, err)
|
|
assert.Empty(t, permissions)
|
|
}
|
|
|
|
func TestCustomRoleService_Update_NotFound(t *testing.T) {
|
|
svc, _ := setupCustomRoleServiceTest(t)
|
|
|
|
_, err := svc.Update(context.Background(), 9999, 9999, UpdateCustomRoleRequest{
|
|
Name: "Ghost",
|
|
})
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
// ========== Delete ==========
|
|
|
|
func TestCustomRoleService_Delete(t *testing.T) {
|
|
svc, db := setupCustomRoleServiceTest(t)
|
|
account := createCRSvcTestAccount(t, db)
|
|
|
|
created, err := svc.Create(context.Background(), account.ID, CreateCustomRoleRequest{
|
|
Name: "Supervisor",
|
|
Permissions: []string{"conversation_manage"},
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
err = svc.Delete(context.Background(), created.ID, account.ID)
|
|
assert.NoError(t, err)
|
|
|
|
// Should no longer be visible via GetByID
|
|
_, err = svc.GetByID(context.Background(), created.ID, account.ID)
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestCustomRoleService_Delete_NullifiesAccountUsers(t *testing.T) {
|
|
svc, db := setupCustomRoleServiceTest(t)
|
|
account := createCRSvcTestAccount(t, db)
|
|
user := &model.User{AccountID: account.ID, Name: "Role User", Email: "role-user-svc@example.com", Password: "pw", Active: true}
|
|
require.NoError(t, db.Create(user).Error)
|
|
|
|
created, err := svc.Create(context.Background(), account.ID, CreateCustomRoleRequest{
|
|
Name: "Supervisor",
|
|
Permissions: []string{"conversation_manage"},
|
|
})
|
|
require.NoError(t, err)
|
|
require.NoError(t, db.Create(&model.AccountUser{AccountID: account.ID, UserID: user.ID, Role: "agent", CustomRoleID: created.ID}).Error)
|
|
|
|
err = svc.Delete(context.Background(), created.ID, account.ID)
|
|
assert.NoError(t, err)
|
|
|
|
var au model.AccountUser
|
|
require.NoError(t, db.Where("account_id = ? AND user_id = ?", account.ID, user.ID).First(&au).Error)
|
|
assert.Equal(t, uint(0), au.CustomRoleID)
|
|
assert.Equal(t, "agent", au.Role)
|
|
}
|
|
|
|
func TestCustomRoleService_Delete_NotFound(t *testing.T) {
|
|
svc, _ := setupCustomRoleServiceTest(t)
|
|
|
|
err := svc.Delete(context.Background(), 9999, 9999)
|
|
// GORM soft-delete on non-existent returns no error (0 rows)
|
|
assert.NoError(t, err)
|
|
}
|