Files
gochat/internal/service/rbac_service_test.go_BAK
T
2026-06-04 15:44:48 +08:00

737 lines
25 KiB
Plaintext

package service
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/gochat/gochat/internal/auth"
"github.com/gochat/gochat/internal/model"
)
// ============================================================
// AccountUser Operations — Role Assignment Tests
// ============================================================
// Test1_GetAccountUser_Success verifies retrieving an existing AccountUser.
func Test1_GetAccountUser_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
// Create AccountUser directly
au := &model.AccountUser{
UserID: user.ID,
AccountID: acc.ID,
Role: "agent",
Availability: "offline",
}
require.NoError(t, db.Create(au).Error)
result, err := svc.GetAccountUser(user.ID, acc.ID)
require.NoError(t, err)
assert.Equal(t, user.ID, result.UserID)
assert.Equal(t, acc.ID, result.AccountID)
assert.Equal(t, "agent", result.Role)
}
// Test2_GetAccountUser_NotFound verifies error when AccountUser doesn't exist.
func Test2_GetAccountUser_NotFound(t *testing.T) {
_, svc := setupRBACService(t)
result, err := svc.GetAccountUser(999, 999)
require.Error(t, err)
assert.Nil(t, result)
assert.Contains(t, err.Error(), "is not a member of")
}
// Test3_AddAccountUser_Success verifies adding a user to an account with agent role.
func Test3_AddAccountUser_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
au, err := svc.AddAccountUser(user.ID, acc.ID, "agent", 0, 0)
require.NoError(t, err)
assert.Equal(t, user.ID, au.UserID)
assert.Equal(t, acc.ID, au.AccountID)
assert.Equal(t, "agent", au.Role)
assert.Equal(t, uint(0), au.CustomRoleID)
assert.Equal(t, "offline", au.Availability)
}
// Test4_AddAccountUser_AdministratorRole verifies adding a user with administrator role.
func Test4_AddAccountUser_AdministratorRole(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
au, err := svc.AddAccountUser(user.ID, acc.ID, "administrator", 0, user.ID)
require.NoError(t, err)
assert.Equal(t, "administrator", au.Role)
assert.Equal(t, user.ID, au.InvitedBy)
}
// Test5_AddAccountUser_InvalidRole verifies error when adding with invalid role.
func Test5_AddAccountUser_InvalidRole(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
au, err := svc.AddAccountUser(user.ID, acc.ID, "superadmin", 0, 0)
require.Error(t, err)
assert.Nil(t, au)
assert.Contains(t, err.Error(), "invalid role")
}
// Test6_AddAccountUser_AlreadyMember verifies error when user is already a member.
func Test6_AddAccountUser_AlreadyMember(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
_, err := svc.AddAccountUser(user.ID, acc.ID, "agent", 0, 0)
require.NoError(t, err)
au, err := svc.AddAccountUser(user.ID, acc.ID, "administrator", 0, 0)
require.Error(t, err)
assert.Nil(t, au)
assert.Contains(t, err.Error(), "already a member")
}
// Test7_AddAccountUser_WithCustomRole verifies adding a user with custom_role and customRoleID.
func Test7_AddAccountUser_WithCustomRole(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
// Create a custom role first
perms := auth.PermissionMatrixMap{
auth.DimensionConversationManage: auth.PermissionRead,
auth.DimensionContactManage: auth.PermissionFull,
}
cr, err := svc.CreateCustomRole(acc.ID, "Support Agent", perms, "custom support role")
require.NoError(t, err)
au, err := svc.AddAccountUser(user.ID, acc.ID, "custom_role", cr.ID, 0)
require.NoError(t, err)
assert.Equal(t, "custom_role", au.Role)
assert.Equal(t, cr.ID, au.CustomRoleID)
}
// Test8_UpdateAccountUserRole_Success verifies changing a user's role.
func Test8_UpdateAccountUserRole_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
_, err := svc.AddAccountUser(user.ID, acc.ID, "agent", 0, 0)
require.NoError(t, err)
updated, err := svc.UpdateAccountUserRole(user.ID, acc.ID, "administrator", 0)
require.NoError(t, err)
assert.Equal(t, "administrator", updated.Role)
assert.Equal(t, uint(0), updated.CustomRoleID)
}
// Test9_UpdateAccountUserRole_InvalidRole verifies error when updating to invalid role.
func Test9_UpdateAccountUserRole_InvalidRole(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
_, err := svc.AddAccountUser(user.ID, acc.ID, "agent", 0, 0)
require.NoError(t, err)
updated, err := svc.UpdateAccountUserRole(user.ID, acc.ID, "invalid_role", 0)
require.Error(t, err)
assert.Nil(t, updated)
assert.Contains(t, err.Error(), "invalid role")
}
// Test10_UpdateAccountUserRole_NotFound verifies error when AccountUser doesn't exist.
func Test10_UpdateAccountUserRole_NotFound(t *testing.T) {
_, svc := setupRBACService(t)
updated, err := svc.UpdateAccountUserRole(999, 999, "agent", 0)
require.Error(t, err)
assert.Nil(t, updated)
}
// Test11_RemoveAccountUser_Success verifies removing a user from an account.
func Test11_RemoveAccountUser_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
_, err := svc.AddAccountUser(user.ID, acc.ID, "agent", 0, 0)
require.NoError(t, err)
err = svc.RemoveAccountUser(user.ID, acc.ID)
require.NoError(t, err)
// Verify the user is no longer found
result, err := svc.GetAccountUser(user.ID, acc.ID)
require.Error(t, err)
assert.Nil(t, result)
}
// Test12_RemoveAccountUser_NotMember verifies error when removing a non-member.
func Test12_RemoveAccountUser_NotMember(t *testing.T) {
_, svc := setupRBACService(t)
err := svc.RemoveAccountUser(999, 999)
require.Error(t, err)
assert.Contains(t, err.Error(), "is not a member of")
}
// Test13_ListAccountUsers verifies listing all users in an account.
func Test13_ListAccountUsers(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user1 := createTestUserForRBAC(t, db)
user2 := createTestUserForRBAC(t, db)
_, err := svc.AddAccountUser(user1.ID, acc.ID, "agent", 0, 0)
require.NoError(t, err)
_, err = svc.AddAccountUser(user2.ID, acc.ID, "administrator", 0, 0)
require.NoError(t, err)
users, err := svc.ListAccountUsers(acc.ID)
require.NoError(t, err)
assert.Len(t, users, 2)
}
// Test14_ListUserAccounts verifies listing all accounts a user belongs to.
func Test14_ListUserAccounts(t *testing.T) {
db, svc := setupRBACService(t)
acc1 := createTestAccountForRBAC(t, db)
acc2 := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
_, err := svc.AddAccountUser(user.ID, acc1.ID, "agent", 0, 0)
require.NoError(t, err)
_, err = svc.AddAccountUser(user.ID, acc2.ID, "administrator", 0, 0)
require.NoError(t, err)
accounts, err := svc.ListUserAccounts(user.ID)
require.NoError(t, err)
assert.Len(t, accounts, 2)
}
// Test15_UpdateAvailability_Success verifies updating availability status.
func Test15_UpdateAvailability_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
_, err := svc.AddAccountUser(user.ID, acc.ID, "agent", 0, 0)
require.NoError(t, err)
err = svc.UpdateAvailability(user.ID, acc.ID, "online")
require.NoError(t, err)
au, err := svc.GetAccountUser(user.ID, acc.ID)
require.NoError(t, err)
assert.Equal(t, "online", au.Availability)
}
// Test16_UpdateAvailability_InvalidValue verifies error with invalid availability.
func Test16_UpdateAvailability_InvalidValue(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
_, err := svc.AddAccountUser(user.ID, acc.ID, "agent", 0, 0)
require.NoError(t, err)
err = svc.UpdateAvailability(user.ID, acc.ID, "away")
require.Error(t, err)
assert.Contains(t, err.Error(), "invalid availability")
}
// ============================================================
// Custom Role Operations Tests
// ============================================================
// Test17_CreateCustomRole_Success verifies creating a custom role with permissions.
func Test17_CreateCustomRole_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
perms := auth.PermissionMatrixMap{
auth.DimensionConversationManage: auth.PermissionFull,
auth.DimensionConversationDelete: auth.PermissionRead,
auth.DimensionContactManage: auth.PermissionFull,
auth.DimensionReportManage: auth.PermissionNone,
auth.DimensionKnowledgeBaseManage: auth.PermissionRead,
auth.DimensionAutomationManage: auth.PermissionNone,
}
cr, err := svc.CreateCustomRole(acc.ID, "Team Lead", perms, "team lead role description")
require.NoError(t, err)
assert.Equal(t, acc.ID, cr.AccountID)
assert.Equal(t, "Team Lead", cr.Name)
assert.Equal(t, "team lead role description", cr.Description)
assert.NotZero(t, cr.ID)
}
// Test18_GetCustomRole_Success verifies retrieving a custom role.
func Test18_GetCustomRole_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
perms := auth.PermissionMatrixMap{
auth.DimensionConversationManage: auth.PermissionRead,
}
cr, err := svc.CreateCustomRole(acc.ID, "Viewer", perms, "view-only role")
require.NoError(t, err)
fetched, err := svc.GetCustomRole(cr.ID)
require.NoError(t, err)
assert.Equal(t, cr.Name, fetched.Name)
assert.Equal(t, cr.AccountID, fetched.AccountID)
}
// Test19_GetCustomRole_NotFound verifies error when custom role doesn't exist.
func Test19_GetCustomRole_NotFound(t *testing.T) {
_, svc := setupRBACService(t)
cr, err := svc.GetCustomRole(999)
require.Error(t, err)
assert.Nil(t, cr)
assert.Contains(t, err.Error(), "not found")
}
// Test20_GetCustomRolePermissionMatrix_Success verifies retrieving permission matrix of a custom role.
func Test20_GetCustomRolePermissionMatrix_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
perms := auth.PermissionMatrixMap{
auth.DimensionConversationManage: auth.PermissionFull,
auth.DimensionContactManage: auth.PermissionRead,
auth.DimensionAutomationManage: auth.PermissionNone,
}
cr, err := svc.CreateCustomRole(acc.ID, "Ops Role", perms, "operations role")
require.NoError(t, err)
matrix, err := svc.GetCustomRolePermissionMatrix(cr.ID)
require.NoError(t, err)
assert.Equal(t, auth.PermissionFull, matrix[auth.DimensionConversationManage])
assert.Equal(t, auth.PermissionRead, matrix[auth.DimensionContactManage])
assert.Equal(t, auth.PermissionNone, matrix[auth.DimensionAutomationManage])
}
// Test21_GetCustomRolePermissionMatrix_NotFound verifies error for nonexistent role.
func Test21_GetCustomRolePermissionMatrix_NotFound(t *testing.T) {
_, svc := setupRBACService(t)
matrix, err := svc.GetCustomRolePermissionMatrix(999)
require.Error(t, err)
assert.Nil(t, matrix)
}
// Test22_UpdateCustomRole_Success verifies updating a custom role.
func Test22_UpdateCustomRole_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
perms := auth.PermissionMatrixMap{
auth.DimensionConversationManage: auth.PermissionRead,
}
cr, err := svc.CreateCustomRole(acc.ID, "Initial Role", perms, "initial description")
require.NoError(t, err)
newPerms := auth.PermissionMatrixMap{
auth.DimensionConversationManage: auth.PermissionFull,
auth.DimensionContactManage: auth.PermissionRead,
}
updated, err := svc.UpdateCustomRole(cr.ID, "Updated Role", newPerms, "updated description")
require.NoError(t, err)
assert.Equal(t, "Updated Role", updated.Name)
assert.Equal(t, "updated description", updated.Description)
}
// Test23_UpdateCustomRole_NotFound verifies error when updating nonexistent role.
func Test23_UpdateCustomRole_NotFound(t *testing.T) {
_, svc := setupRBACService(t)
newPerms := auth.PermissionMatrixMap{
auth.DimensionConversationManage: auth.PermissionFull,
}
updated, err := svc.UpdateCustomRole(999, "Name", newPerms, "desc")
require.Error(t, err)
assert.Nil(t, updated)
}
// Test24_DeleteCustomRole_Success verifies deleting a custom role and downgrading users.
func Test24_DeleteCustomRole_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
perms := auth.PermissionMatrixMap{
auth.DimensionConversationManage: auth.PermissionRead,
}
cr, err := svc.CreateCustomRole(acc.ID, "Temp Role", perms, "temporary")
require.NoError(t, err)
// Add user with custom role
au, err := svc.AddAccountUser(user.ID, acc.ID, "custom_role", cr.ID, 0)
require.NoError(t, err)
assert.Equal(t, "custom_role", au.Role)
// Delete the custom role — users should be downgraded to agent
err = svc.DeleteCustomRole(cr.ID)
require.NoError(t, err)
// Verify custom role is gone
fetched, err := svc.GetCustomRole(cr.ID)
require.Error(t, err)
assert.Nil(t, fetched)
// Verify user was downgraded to agent
downgraded, err := svc.GetAccountUser(user.ID, acc.ID)
require.NoError(t, err)
assert.Equal(t, "agent", downgraded.Role)
assert.Equal(t, uint(0), downgraded.CustomRoleID)
}
// Test25_DeleteCustomRole_NotFound verifies error when deleting nonexistent role.
func Test25_DeleteCustomRole_NotFound(t *testing.T) {
_, svc := setupRBACService(t)
err := svc.DeleteCustomRole(999)
require.Error(t, err)
assert.Contains(t, err.Error(), "not found")
}
// Test26_ListCustomRoles verifies listing custom roles for an account.
func Test26_ListCustomRoles(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
perms1 := auth.PermissionMatrixMap{
auth.DimensionConversationManage: auth.PermissionRead,
}
perms2 := auth.PermissionMatrixMap{
auth.DimensionContactManage: auth.PermissionFull,
}
_, err := svc.CreateCustomRole(acc.ID, "Role A", perms1, "role a")
require.NoError(t, err)
_, err = svc.CreateCustomRole(acc.ID, "Role B", perms2, "role b")
require.NoError(t, err)
roles, err := svc.ListCustomRoles(acc.ID)
require.NoError(t, err)
assert.Len(t, roles, 2)
}
// ============================================================
// Permission Checking / PolicyContext Tests
// ============================================================
// Test27_BuildPolicyContext_Administrator verifies building PolicyContext for administrator.
func Test27_BuildPolicyContext_Administrator(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
_, err := svc.AddAccountUser(user.ID, acc.ID, "administrator", 0, 0)
require.NoError(t, err)
pc, err := svc.BuildPolicyContext(user.ID, acc.ID)
require.NoError(t, err)
assert.Equal(t, user.ID, pc.UserID)
assert.Equal(t, acc.ID, pc.AccountID)
assert.Equal(t, "administrator", pc.Role)
// Administrator should have full permissions on all dimensions
assert.Equal(t, auth.PermissionFull, pc.Permissions[auth.DimensionConversationManage])
assert.Equal(t, auth.PermissionFull, pc.Permissions[auth.DimensionContactManage])
}
// Test28_BuildPolicyContext_Agent verifies building PolicyContext for agent.
func Test28_BuildPolicyContext_Agent(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
_, err := svc.AddAccountUser(user.ID, acc.ID, "agent", 0, 0)
require.NoError(t, err)
pc, err := svc.BuildPolicyContext(user.ID, acc.ID)
require.NoError(t, err)
assert.Equal(t, "agent", pc.Role)
// Agent defaults: conversation_manage = read, contact_manage = read
assert.Equal(t, auth.PermissionRead, pc.Permissions[auth.DimensionConversationManage])
assert.Equal(t, auth.PermissionRead, pc.Permissions[auth.DimensionContactManage])
assert.Equal(t, auth.PermissionNone, pc.Permissions[auth.DimensionAutomationManage])
}
// Test29_BuildPolicyContext_CustomRole verifies building PolicyContext for custom_role.
func Test29_BuildPolicyContext_CustomRole(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
perms := auth.PermissionMatrixMap{
auth.DimensionConversationManage: auth.PermissionFull,
auth.DimensionContactManage: auth.PermissionRead,
auth.DimensionAutomationManage: auth.PermissionNone,
}
cr, err := svc.CreateCustomRole(acc.ID, "Custom", perms, "custom role")
require.NoError(t, err)
_, err = svc.AddAccountUser(user.ID, acc.ID, "custom_role", cr.ID, 0)
require.NoError(t, err)
pc, err := svc.BuildPolicyContext(user.ID, acc.ID)
require.NoError(t, err)
assert.Equal(t, "custom_role", pc.Role)
assert.Equal(t, cr.ID, pc.CustomRoleID)
assert.Equal(t, auth.PermissionFull, pc.Permissions[auth.DimensionConversationManage])
assert.Equal(t, auth.PermissionRead, pc.Permissions[auth.DimensionContactManage])
}
// Test30_BuildPolicyContext_NotFound verifies error when AccountUser doesn't exist.
func Test30_BuildPolicyContext_NotFound(t *testing.T) {
_, svc := setupRBACService(t)
pc, err := svc.BuildPolicyContext(999, 999)
require.Error(t, err)
assert.Nil(t, pc)
}
// ============================================================
// PlatformApp Operations Tests
// ============================================================
// Test31_CreatePlatformApp_Success verifies creating a platform app with API key.
func Test31_CreatePlatformApp_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
pa, err := svc.CreatePlatformApp("TestBot", acc.ID, "agent_bot", "test bot description")
require.NoError(t, err)
assert.Equal(t, "TestBot", pa.Name)
assert.NotEmpty(t, pa.APIKey)
assert.Contains(t, pa.APIKey, "gchat_")
assert.Equal(t, acc.ID, pa.AccountID)
assert.Equal(t, "agent_bot", pa.Type)
assert.Equal(t, "active", pa.Status)
}
// Test32_CreatePlatformApp_PlatformLevel verifies creating a platform-level app (accountID=0).
func Test32_CreatePlatformApp_PlatformLevel(t *testing.T) {
_, svc := setupRBACService(t)
pa, err := svc.CreatePlatformApp("GlobalBot", 0, "api", "platform-level bot")
require.NoError(t, err)
assert.Equal(t, uint(0), pa.AccountID)
assert.True(t, pa.IsPlatformLevel())
}
// Test33_GetPlatformApp_Success verifies retrieving a platform app by ID.
func Test33_GetPlatformApp_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
pa, err := svc.CreatePlatformApp("FetchBot", acc.ID, "api", "fetch test")
require.NoError(t, err)
fetched, err := svc.GetPlatformApp(pa.ID)
require.NoError(t, err)
assert.Equal(t, pa.Name, fetched.Name)
assert.Equal(t, pa.APIKey, fetched.APIKey)
}
// Test34_GetPlatformApp_NotFound verifies error for nonexistent platform app.
func Test34_GetPlatformApp_NotFound(t *testing.T) {
_, svc := setupRBACService(t)
pa, err := svc.GetPlatformApp(999)
require.Error(t, err)
assert.Nil(t, pa)
}
// Test35_GetPlatformAppByAPIKey_Success verifies retrieving a platform app by API key.
func Test35_GetPlatformAppByAPIKey_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
pa, err := svc.CreatePlatformApp("KeyBot", acc.ID, "api", "key lookup test")
require.NoError(t, err)
fetched, err := svc.GetPlatformAppByAPIKey(pa.APIKey)
require.NoError(t, err)
assert.Equal(t, pa.ID, fetched.ID)
assert.Equal(t, pa.Name, fetched.Name)
}
// Test36_GetPlatformAppByAPIKey_NotFound verifies error for invalid API key.
func Test36_GetPlatformAppByAPIKey_NotFound(t *testing.T) {
_, svc := setupRBACService(t)
pa, err := svc.GetPlatformAppByAPIKey("gchat_invalid_key")
require.Error(t, err)
assert.Nil(t, pa)
}
// Test37_UpdatePlatformApp_Success verifies updating a platform app.
func Test37_UpdatePlatformApp_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
pa, err := svc.CreatePlatformApp("OldName", acc.ID, "api", "old description")
require.NoError(t, err)
updated, err := svc.UpdatePlatformApp(pa.ID, "NewName", "new description", "")
require.NoError(t, err)
assert.Equal(t, "NewName", updated.Name)
assert.Equal(t, "new description", updated.Description)
// Status unchanged since we passed empty string
assert.Equal(t, "active", updated.Status)
}
// Test38_UpdatePlatformApp_Status verifies updating platform app status.
func Test38_UpdatePlatformApp_Status(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
pa, err := svc.CreatePlatformApp("StatusBot", acc.ID, "api", "status test")
require.NoError(t, err)
updated, err := svc.UpdatePlatformApp(pa.ID, "", "", "disabled")
require.NoError(t, err)
assert.Equal(t, "disabled", updated.Status)
// Name unchanged since we passed empty string
assert.Equal(t, "StatusBot", updated.Name)
}
// Test39_DeletePlatformApp_Success verifies deleting a platform app.
func Test39_DeletePlatformApp_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
pa, err := svc.CreatePlatformApp("DeleteBot", acc.ID, "api", "delete test")
require.NoError(t, err)
err = svc.DeletePlatformApp(pa.ID)
require.NoError(t, err)
// Verify app is gone
fetched, err := svc.GetPlatformApp(pa.ID)
require.Error(t, err)
assert.Nil(t, fetched)
}
// Test40_DeletePlatformApp_NotFound verifies error when deleting nonexistent app.
func Test40_DeletePlatformApp_NotFound(t *testing.T) {
_, svc := setupRBACService(t)
err := svc.DeletePlatformApp(999)
require.Error(t, err)
assert.Contains(t, err.Error(), "not found")
}
// Test41_RegenerateAPIKey_Success verifies regenerating an API key.
func Test41_RegenerateAPIKey_Success(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
pa, err := svc.CreatePlatformApp("RegenBot", acc.ID, "api", "regen test")
require.NoError(t, err)
oldKey := pa.APIKey
newKey, err := svc.RegenerateAPIKey(pa.ID)
require.NoError(t, err)
assert.NotEqual(t, oldKey, newKey)
assert.Contains(t, newKey, "gchat_")
// Verify the new key works for lookup
fetched, err := svc.GetPlatformAppByAPIKey(newKey)
require.NoError(t, err)
assert.Equal(t, pa.ID, fetched.ID)
}
// Test42_RegenerateAPIKey_NotFound verifies error when regenerating for nonexistent app.
func Test42_RegenerateAPIKey_NotFound(t *testing.T) {
_, svc := setupRBACService(t)
newKey, err := svc.RegenerateAPIKey(999)
require.Error(t, err)
assert.Empty(t, newKey)
}
// Test43_ListPlatformApps_WithAccountFilter verifies listing platform apps for an account.
func Test43_ListPlatformApps_WithAccountFilter(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
_, err := svc.CreatePlatformApp("Bot1", acc.ID, "api", "bot1")
require.NoError(t, err)
_, err = svc.CreatePlatformApp("Bot2", acc.ID, "agent_bot", "bot2")
require.NoError(t, err)
apps, err := svc.ListPlatformApps(acc.ID)
require.NoError(t, err)
assert.Len(t, apps, 2)
}
// Test44_ListPlatformApps_All verifies listing all platform apps (accountID=0).
func Test44_ListPlatformApps_All(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
_, err := svc.CreatePlatformApp("Global1", 0, "api", "global1")
require.NoError(t, err)
_, err = svc.CreatePlatformApp("Scoped1", acc.ID, "api", "scoped1")
require.NoError(t, err)
apps, err := svc.ListPlatformApps(0)
require.NoError(t, err)
assert.Len(t, apps, 2) // Returns all apps when accountID=0
}
// ============================================================
// RBACLookup Interface Tests
// ============================================================
// Test45_GetAccountUserRole verifies the RBACLookup interface method.
func Test45_GetAccountUserRole(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
user := createTestUserForRBAC(t, db)
_, err := svc.AddAccountUser(user.ID, acc.ID, "agent", 0, 0)
require.NoError(t, err)
role, err := svc.GetAccountUserRole(user.ID, acc.ID)
require.NoError(t, err)
assert.Equal(t, user.ID, role.UserID)
assert.Equal(t, acc.ID, role.AccountID)
assert.Equal(t, "agent", role.Role)
}
// Test46_GetCustomRolePermissions verifies the RBACLookup interface method.
func Test46_GetCustomRolePermissions(t *testing.T) {
db, svc := setupRBACService(t)
acc := createTestAccountForRBAC(t, db)
perms := auth.PermissionMatrixMap{
auth.DimensionConversationManage: auth.PermissionFull,
auth.DimensionContactManage: auth.PermissionRead,
}
cr, err := svc.CreateCustomRole(acc.ID, "LookupRole", perms, "test lookup")
require.NoError(t, err)
matrix, err := svc.GetCustomRolePermissions(cr.ID)
require.NoError(t, err)
assert.Equal(t, auth.PermissionFull, matrix[auth.DimensionConversationManage])
assert.Equal(t, auth.PermissionRead, matrix[auth.DimensionContactManage])
}