feat(custom-roles): align chatwoot permissions

This commit is contained in:
2026-06-05 11:14:38 +08:00
parent b5f2a47ef8
commit 8b3b532c65
20 changed files with 681 additions and 226 deletions
+43 -44
View File
@@ -89,11 +89,11 @@ func TestAccountUserIsAgent(t *testing.T) {
}
func TestAccountUserHasCustomRole(t *testing.T) {
au := &model.AccountUser{Role: "custom_role", CustomRoleID: 5}
au := &model.AccountUser{Role: "agent", CustomRoleID: 5}
assert.True(t, au.HasCustomRole())
au.Role = "agent"
assert.False(t, au.HasCustomRole())
assert.True(t, au.HasCustomRole())
au.Role = "custom_role"
au.CustomRoleID = 0
@@ -115,13 +115,13 @@ func TestAccountUserIsOnline(t *testing.T) {
func TestCustomRoleGetPermissionMap(t *testing.T) {
cr := &model.CustomRole{
Permissions: `{"conversation_manage":"full","contact_manage":"read","automation_manage":"none"}`,
Permissions: `["conversation_manage","contact_manage"]`,
}
pm, err := cr.GetPermissionMap()
assert.NoError(t, err)
assert.Equal(t, model.PermissionLevelFull, pm[model.DimensionConversationManage])
assert.Equal(t, model.PermissionLevelRead, pm[model.DimensionContactManage])
assert.Equal(t, model.PermissionLevelNone, pm[model.DimensionAutomationManage])
assert.Equal(t, model.PermissionLevelFull, pm[model.DimensionContactManage])
assert.Empty(t, pm[model.DimensionAutomationManage])
}
func TestCustomRoleGetPermissionMapEmpty(t *testing.T) {
@@ -152,20 +152,19 @@ func TestCustomRoleSetPermissionMap(t *testing.T) {
err := cr.SetPermissionMap(pm)
assert.NoError(t, err)
assert.Contains(t, cr.Permissions, "conversation_manage")
assert.Contains(t, cr.Permissions, "full")
assert.Contains(t, cr.Permissions, "contact_manage")
assert.Contains(t, cr.Permissions, "read")
// Verify round-trip
pm2, err := cr.GetPermissionMap()
assert.NoError(t, err)
assert.Equal(t, pm, pm2)
assert.Equal(t, model.PermissionLevelFull, pm2[model.DimensionConversationManage])
assert.Equal(t, model.PermissionLevelFull, pm2[model.DimensionContactManage])
}
func TestCustomRoleValidate(t *testing.T) {
cr := &model.CustomRole{
Name: "Valid Role",
Permissions: `{"conversation_manage":"full","contact_manage":"read"}`,
Name: "Valid Role",
Permissions: `["conversation_manage","contact_manage"]`,
}
assert.NoError(t, cr.Validate())
@@ -175,7 +174,7 @@ func TestCustomRoleValidate(t *testing.T) {
// Invalid permission level
cr.Name = "Invalid Role"
cr.Permissions = `{"conversation_manage":"invalid_level"}`
cr.Permissions = `["conversation_delete"]`
assert.Error(t, cr.Validate())
// Invalid JSON
@@ -275,13 +274,13 @@ func TestPermissionLevelConstants(t *testing.T) {
func TestAccountStructFields(t *testing.T) {
acc := model.Account{
Name: "Test",
Domain: "test.com",
Locale: "en",
Timezone: "UTC",
Active: true,
Status: "active",
FeatureFlags: `{"feature_x":true}`,
Name: "Test",
Domain: "test.com",
Locale: "en",
Timezone: "UTC",
Active: true,
Status: "active",
FeatureFlags: `{"feature_x":true}`,
AutoResolveDuration: 7,
}
assert.Equal(t, "Test", acc.Name)
@@ -296,20 +295,20 @@ func TestAccountStructFields(t *testing.T) {
func TestUserStructFields(t *testing.T) {
user := model.User{
AccountID: 1,
Name: "Agent",
Email: "agent@test.com",
Password: "secret",
Provider: "email",
UID: "ext123",
AvatarURL: "https://img.test.com/avatar.png",
Role: "agent",
Active: true,
Available: false,
TOTPSecret: "otp_secret",
TOTPEnabled: false,
AccountID: 1,
Name: "Agent",
Email: "agent@test.com",
Password: "secret",
Provider: "email",
UID: "ext123",
AvatarURL: "https://img.test.com/avatar.png",
Role: "agent",
Active: true,
Available: false,
TOTPSecret: "otp_secret",
TOTPEnabled: false,
CustomRoleID: nil,
SignInCount: 5,
SignInCount: 5,
}
assert.Equal(t, uint(1), user.AccountID)
assert.Equal(t, "Agent", user.Name)
@@ -359,12 +358,12 @@ func TestMessageStructFields(t *testing.T) {
func TestContactStructFields(t *testing.T) {
contact := model.Contact{
AccountID: 1,
Name: "Alice",
Email: "alice@test.com",
PhoneNumber: "+1234567890",
AvatarURL: "https://img.test.com/alice.png",
Identifier: "ext_id_123",
AccountID: 1,
Name: "Alice",
Email: "alice@test.com",
PhoneNumber: "+1234567890",
AvatarURL: "https://img.test.com/alice.png",
Identifier: "ext_id_123",
}
assert.Equal(t, uint(1), contact.AccountID)
assert.Equal(t, "Alice", contact.Name)
@@ -374,14 +373,14 @@ func TestContactStructFields(t *testing.T) {
func TestInboxStructFields(t *testing.T) {
inbox := model.Inbox{
AccountID: 1,
Name: "Support",
ChannelType: "web_widget",
ChannelID: 5,
AccountID: 1,
Name: "Support",
ChannelType: "web_widget",
ChannelID: 5,
EnableAutoAssignment: true,
AutoAssignmentLimit: 10,
Enabled: true,
ChannelConfig: `{"color":"#1f93ff"}`,
Enabled: true,
ChannelConfig: `{"color":"#1f93ff"}`,
}
assert.Equal(t, uint(1), inbox.AccountID)
assert.Equal(t, "Support", inbox.Name)
@@ -405,4 +404,4 @@ func TestCustomRoleValidationError(t *testing.T) {
assert.Contains(t, err.Error(), "conversation_manage")
assert.Contains(t, err.Error(), "invalid")
assert.Contains(t, err.Error(), "not a valid level")
}
}