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

671 lines
20 KiB
Plaintext

package service
import (
"context"
"encoding/json"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/gochat/gochat/internal/model"
)
// ========== ListByAccount ==========
func TestInboxService_ListByAccount_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
// 预先创建2个inbox
createTestInbox(t, db, account.ID, "web_widget")
createTestInbox(t, db, account.ID, "api")
inboxes, total, err := svc.ListByAccount(context.Background(), account.ID, 0, 10)
require.NoError(t, err)
assert.Equal(t, int64(2), total)
assert.Len(t, inboxes, 2)
}
func TestInboxService_ListByAccount_空列表(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inboxes, total, err := svc.ListByAccount(context.Background(), account.ID, 0, 10)
require.NoError(t, err)
assert.Equal(t, int64(0), total)
assert.Len(t, inboxes, 0)
}
func TestInboxService_ListByAccount_分页(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
// 创建3个inbox
for i := 0; i < 3; i++ {
inbox := &model.Inbox{
AccountID: account.ID,
Name: "收件箱" + string(rune('A'+i)),
ChannelType: "web_widget",
Enabled: true,
}
require.NoError(t, db.Create(inbox).Error)
}
// 第1页 limit=2
inboxes, total, err := svc.ListByAccount(context.Background(), account.ID, 0, 2)
require.NoError(t, err)
assert.Equal(t, int64(3), total)
assert.Len(t, inboxes, 2)
}
// ========== GetByID ==========
func TestInboxService_GetByID_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "web_widget")
result, err := svc.GetByID(context.Background(), inbox.ID)
require.NoError(t, err)
assert.Equal(t, inbox.ID, result.ID)
assert.Equal(t, "web_widget", result.ChannelType)
}
func TestInboxService_GetByID_不存在(t *testing.T) {
_, _, svc := setupInboxService(t)
result, err := svc.GetByID(context.Background(), 9999)
assert.Error(t, err)
assert.Nil(t, result)
}
// ========== GetByAccountAndID ==========
func TestInboxService_GetByAccountAndID_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "web_widget")
result, err := svc.GetByAccountAndID(context.Background(), account.ID, inbox.ID)
require.NoError(t, err)
assert.Equal(t, inbox.ID, result.ID)
}
func TestInboxService_GetByAccountAndID_账户不匹配(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "web_widget")
otherAccount := createTestAccount(t, db)
result, err := svc.GetByAccountAndID(context.Background(), otherAccount.ID, inbox.ID)
assert.Error(t, err)
assert.Nil(t, result)
}
// ========== Create ==========
func TestInboxService_Create_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateInboxRequest{
Name: "新建收件箱",
ChannelType: "web_widget",
Enabled: true,
EnableAutoAssignment: false,
}
result, err := svc.Create(context.Background(), account.ID, req)
require.NoError(t, err)
assert.Equal(t, "新建收件箱", result.Name)
assert.Equal(t, "web_widget", result.ChannelType)
assert.Equal(t, account.ID, result.AccountID)
assert.True(t, result.Enabled)
assert.NotZero(t, result.ID)
}
func TestInboxService_Create_各种渠道类型(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
channelTypes := []string{"web_widget", "telegram", "facebook", "whatsapp", "email", "api"}
for _, ct := range channelTypes {
req := CreateInboxRequest{
Name: ct + "收件箱",
ChannelType: ct,
Enabled: true,
}
result, err := svc.Create(context.Background(), account.ID, req)
require.NoError(t, err)
assert.Equal(t, ct, result.ChannelType)
}
}
func TestInboxService_Create_验证失败_名称过短(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateInboxRequest{
Name: "a", // min=2 不满足
ChannelType: "web_widget",
}
result, err := svc.Create(context.Background(), account.ID, req)
assert.Error(t, err)
assert.Nil(t, result)
}
func TestInboxService_Create_验证失败_缺少渠道类型(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateInboxRequest{
Name: "有效名称",
ChannelType: "", // required
}
result, err := svc.Create(context.Background(), account.ID, req)
assert.Error(t, err)
assert.Nil(t, result)
}
func TestInboxService_Create_验证失败_无效渠道类型(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateInboxRequest{
Name: "有效名称",
ChannelType: "invalid_channel", // oneof 校验失败
}
result, err := svc.Create(context.Background(), account.ID, req)
assert.Error(t, err)
assert.Nil(t, result)
}
// ========== Update ==========
func TestInboxService_Update_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "web_widget")
enabled := false
req := UpdateInboxRequest{
Name: "更新后的收件箱",
Enabled: &enabled,
}
result, err := svc.Update(context.Background(), account.ID, inbox.ID, req)
require.NoError(t, err)
assert.Equal(t, "更新后的收件箱", result.Name)
assert.False(t, result.Enabled)
}
func TestInboxService_Update_验证失败_名称过短(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "web_widget")
req := UpdateInboxRequest{
Name: "x", // min=2 不满足
}
result, err := svc.Update(context.Background(), account.ID, inbox.ID, req)
assert.Error(t, err)
assert.Nil(t, result)
}
func TestInboxService_Update_不存在(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := UpdateInboxRequest{
Name: "不存在",
}
result, err := svc.Update(context.Background(), account.ID, 9999, req)
assert.Error(t, err)
assert.Nil(t, result)
}
func TestInboxService_Update_账户不匹配(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
otherAccount := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "web_widget")
req := UpdateInboxRequest{
Name: "错误账户",
}
result, err := svc.Update(context.Background(), otherAccount.ID, inbox.ID, req)
assert.Error(t, err)
assert.Nil(t, result)
}
// ========== Delete ==========
func TestInboxService_Delete_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "web_widget")
err := svc.Delete(context.Background(), inbox.ID)
require.NoError(t, err)
// 验证软删除后无法找到
result, err := svc.GetByID(context.Background(), inbox.ID)
assert.Error(t, err)
assert.Nil(t, result)
}
func TestInboxService_Delete_不存在(t *testing.T) {
_, _, svc := setupInboxService(t)
err := svc.Delete(context.Background(), 9999)
assert.NoError(t, err)
}
// ========== DeleteByAccount ==========
func TestInboxService_DeleteByAccount_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "web_widget")
err := svc.DeleteByAccount(context.Background(), account.ID, inbox.ID)
require.NoError(t, err)
result, err := svc.GetByID(context.Background(), inbox.ID)
assert.Error(t, err)
assert.Nil(t, result)
}
func TestInboxService_DeleteByAccount_账户不匹配(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
otherAccount := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "web_widget")
err := svc.DeleteByAccount(context.Background(), otherAccount.ID, inbox.ID)
assert.Error(t, err)
}
// ========== WebWidget 相关 ==========
func TestInboxService_CreateWebWidgetInbox_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateWebWidgetInboxRequest{
Name: "Widget收件箱",
WidgetColor: "#1f73b7",
WelcomeTitle: "你好!",
WelcomeTagline: "欢迎咨询",
GreetingEnabled: true,
GreetingMessage: "有什么可以帮您?",
ReplyTime: "a_few_minutes",
PreChatMessage: "请输入您的姓名",
PreChatFieldsEnabled: true,
AutoAssignmentEnabled: false,
ContinuityViaEmail: true,
EnableAutoAssignment: false,
}
result, err := svc.CreateWebWidgetInbox(context.Background(), account.ID, req)
require.NoError(t, err)
assert.Equal(t, "Widget收件箱", result.Name)
assert.Equal(t, "web_widget", result.ChannelType)
assert.True(t, result.Enabled)
assert.NotZero(t, result.ID)
// 验证 ChannelConfig 包含正确的 JSON 配置
var config WebWidgetConfig
err = json.Unmarshal([]byte(result.ChannelConfig), &config)
require.NoError(t, err)
assert.NotEmpty(t, config.WebsiteToken)
assert.NotEmpty(t, config.HMACToken)
assert.Equal(t, "#1f73b7", config.WidgetColor)
assert.Equal(t, "你好!", config.WelcomeTitle)
}
func TestInboxService_CreateWebWidgetInbox_验证失败(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateWebWidgetInboxRequest{
Name: "a", // min=2 不满足
}
result, err := svc.CreateWebWidgetInbox(context.Background(), account.ID, req)
assert.Error(t, err)
assert.Nil(t, result)
}
func TestInboxService_GetWebWidgetConfig_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
// 先创建一个 web_widget inbox
createReq := CreateWebWidgetInboxRequest{
Name: "WidgetConfig测试",
WidgetColor: "#333",
WelcomeTitle: "Hi",
EnableAutoAssignment: false,
}
inbox, err := svc.CreateWebWidgetInbox(context.Background(), account.ID, createReq)
require.NoError(t, err)
config, err := svc.GetWebWidgetConfig(context.Background(), account.ID, inbox.ID)
require.NoError(t, err)
assert.Equal(t, "#333", config.WidgetColor)
assert.Equal(t, "Hi", config.WelcomeTitle)
assert.NotEmpty(t, config.WebsiteToken)
}
func TestInboxService_GetWebWidgetConfig_非web_widget渠道(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "api")
config, err := svc.GetWebWidgetConfig(context.Background(), account.ID, inbox.ID)
assert.Error(t, err)
assert.Nil(t, config)
assert.Contains(t, err.Error(), "not a web_widget")
}
func TestInboxService_GetWebWidgetConfig_不存在(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
config, err := svc.GetWebWidgetConfig(context.Background(), account.ID, 9999)
assert.Error(t, err)
assert.Nil(t, config)
}
func TestInboxService_UpdateWebWidgetConfig_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
// 先创建
createReq := CreateWebWidgetInboxRequest{
Name: "WidgetConfig更新测试",
WidgetColor: "#000",
EnableAutoAssignment: false,
}
inbox, err := svc.CreateWebWidgetInbox(context.Background(), account.ID, createReq)
require.NoError(t, err)
// 更新
widgetColor := "#fff"
welcomeTitle := "新标题"
updateReq := UpdateWebWidgetConfigRequest{
WidgetColor: &widgetColor,
WelcomeTitle: &welcomeTitle,
}
result, err := svc.UpdateWebWidgetConfig(context.Background(), account.ID, inbox.ID, updateReq)
require.NoError(t, err)
assert.Equal(t, "web_widget", result.ChannelType)
// 验证更新后的配置
var config WebWidgetConfig
err = json.Unmarshal([]byte(result.ChannelConfig), &config)
require.NoError(t, err)
assert.Equal(t, "#fff", config.WidgetColor)
assert.Equal(t, "新标题", config.WelcomeTitle)
}
func TestInboxService_UpdateWebWidgetConfig_非web_widget渠道(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "api")
widgetColor := "#fff"
updateReq := UpdateWebWidgetConfigRequest{
WidgetColor: &widgetColor,
}
result, err := svc.UpdateWebWidgetConfig(context.Background(), account.ID, inbox.ID, updateReq)
assert.Error(t, err)
assert.Nil(t, result)
}
func TestInboxService_UpdateWebWidgetConfig_不存在(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
widgetColor := "#fff"
updateReq := UpdateWebWidgetConfigRequest{
WidgetColor: &widgetColor,
}
result, err := svc.UpdateWebWidgetConfig(context.Background(), account.ID, 9999, updateReq)
assert.Error(t, err)
assert.Nil(t, result)
}
// ========== Telegram 相关 ==========
func TestInboxService_CreateTelegramInbox_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateTelegramInboxRequest{
Name: "Telegram收件箱",
BotToken: "123456:ABC-DEF",
WelcomeMessage: "欢迎!",
EnableAutoAssignment: false,
}
result, err := svc.CreateTelegramInbox(context.Background(), account.ID, req)
require.NoError(t, err)
assert.Equal(t, "Telegram收件箱", result.Name)
assert.Equal(t, "telegram", result.ChannelType)
assert.True(t, result.Enabled)
// 验证 ChannelConfig 包含 Telegram 配置
var config TelegramInboxConfig
err = json.Unmarshal([]byte(result.ChannelConfig), &config)
require.NoError(t, err)
assert.Equal(t, "123456:ABC-DEF", config.BotToken)
assert.Equal(t, "欢迎!", config.WelcomeMessage)
}
func TestInboxService_CreateTelegramInbox_验证失败_缺少BotToken(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateTelegramInboxRequest{
Name: "Telegram收件箱",
BotToken: "", // required
}
result, err := svc.CreateTelegramInbox(context.Background(), account.ID, req)
assert.Error(t, err)
assert.Nil(t, result)
}
func TestInboxService_CreateTelegramInbox_验证失败_名称过短(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateTelegramInboxRequest{
Name: "x",
BotToken: "123:abc",
}
result, err := svc.CreateTelegramInbox(context.Background(), account.ID, req)
assert.Error(t, err)
assert.Nil(t, result)
}
func TestInboxService_GetTelegramInboxConfig_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateTelegramInboxRequest{
Name: "Telegram配置测试",
BotToken: "789:XYZ",
}
inbox, err := svc.CreateTelegramInbox(context.Background(), account.ID, req)
require.NoError(t, err)
config, inboxResult, err := svc.GetTelegramInboxConfig(context.Background(), account.ID, inbox.ID)
require.NoError(t, err)
assert.Equal(t, "789:XYZ", config.BotToken)
assert.Equal(t, inbox.ID, inboxResult.ID)
}
func TestInboxService_GetTelegramInboxConfig_非telegram渠道(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "web_widget")
config, inboxResult, err := svc.GetTelegramInboxConfig(context.Background(), account.ID, inbox.ID)
assert.Error(t, err)
assert.Nil(t, config)
assert.Nil(t, inboxResult)
}
func TestInboxService_DeleteTelegramInbox_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateTelegramInboxRequest{
Name: "Telegram删除测试",
BotToken: "111:DEL",
}
inbox, err := svc.CreateTelegramInbox(context.Background(), account.ID, req)
require.NoError(t, err)
err = svc.DeleteTelegramInbox(context.Background(), account.ID, inbox.ID)
require.NoError(t, err)
result, err := svc.GetByID(context.Background(), inbox.ID)
assert.Error(t, err)
assert.Nil(t, result)
}
func TestInboxService_DeleteTelegramInbox_非telegram渠道(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "api")
err := svc.DeleteTelegramInbox(context.Background(), account.ID, inbox.ID)
assert.Error(t, err)
}
func TestInboxService_UpdateTelegramInbox_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateTelegramInboxRequest{
Name: "Telegram更新测试",
BotToken: "222:UPD",
}
inbox, err := svc.CreateTelegramInbox(context.Background(), account.ID, req)
require.NoError(t, err)
newBotToken := "333:NEWUPD"
newName := "更新名称"
updateReq := UpdateTelegramInboxRequest{
BotToken: &newBotToken,
Name: &newName,
}
result, err := svc.UpdateTelegramInbox(context.Background(), account.ID, inbox.ID, updateReq)
require.NoError(t, err)
assert.Equal(t, "更新名称", result.Name)
var config TelegramInboxConfig
err = json.Unmarshal([]byte(result.ChannelConfig), &config)
require.NoError(t, err)
assert.Equal(t, "333:NEWUPD", config.BotToken)
}
func TestInboxService_UpdateTelegramInbox_非telegram渠道(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "api")
botToken := "123:abc"
updateReq := UpdateTelegramInboxRequest{
BotToken: &botToken,
}
result, err := svc.UpdateTelegramInbox(context.Background(), account.ID, inbox.ID, updateReq)
assert.Error(t, err)
assert.Nil(t, result)
}
func TestInboxService_UpdateTelegramConfig_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateTelegramInboxRequest{
Name: "Telegram配置更新测试",
BotToken: "444:CFGUPD",
}
inbox, err := svc.CreateTelegramInbox(context.Background(), account.ID, req)
require.NoError(t, err)
newConfig := TelegramInboxConfig{
BotToken: "555:NEWCFG",
WelcomeMessage: "新欢迎消息",
WebhookURL: "https://example.com/webhook",
}
result, err := svc.UpdateTelegramConfig(context.Background(), account.ID, inbox.ID, newConfig)
require.NoError(t, err)
var parsedConfig TelegramInboxConfig
err = json.Unmarshal([]byte(result.ChannelConfig), &parsedConfig)
require.NoError(t, err)
assert.Equal(t, "555:NEWCFG", parsedConfig.BotToken)
assert.Equal(t, "新欢迎消息", parsedConfig.WelcomeMessage)
assert.Equal(t, "https://example.com/webhook", parsedConfig.WebhookURL)
}
func TestInboxService_UpdateTelegramConfig_非telegram渠道(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
inbox := createTestInbox(t, db, account.ID, "api")
newConfig := TelegramInboxConfig{
BotToken: "123:abc",
}
result, err := svc.UpdateTelegramConfig(context.Background(), account.ID, inbox.ID, newConfig)
assert.Error(t, err)
assert.Nil(t, result)
}
// ========== FindTelegramInboxByBotToken ==========
func TestInboxService_FindTelegramInboxByBotToken_成功(t *testing.T) {
db, _, svc := setupInboxService(t)
account := createTestAccount(t, db)
req := CreateTelegramInboxRequest{
Name: "Telegram查找测试",
BotToken: "666:FINDME",
}
inbox, err := svc.CreateTelegramInbox(context.Background(), account.ID, req)
require.NoError(t, err)
result, err := svc.FindTelegramInboxByBotToken(context.Background(), "666:FINDME")
require.NoError(t, err)
assert.Equal(t, inbox.ID, result.ID)
assert.Equal(t, "telegram", result.ChannelType)
}
func TestInboxService_FindTelegramInboxByBotToken_不存在(t *testing.T) {
_, _, svc := setupInboxService(t)
result, err := svc.FindTelegramInboxByBotToken(context.Background(), "999:NOTEXIST")
assert.Error(t, err)
assert.Nil(t, result)
}