282 lines
7.7 KiB
Go
282 lines
7.7 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"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 setupAgentBotInboxService(t *testing.T) (*AgentBotInboxService, *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.AgentBot{},
|
|
&model.Inbox{},
|
|
&model.AgentBotInbox{},
|
|
), "failed to auto-migrate")
|
|
|
|
t.Cleanup(func() {
|
|
sqlDB, _ := db.DB()
|
|
sqlDB.Close()
|
|
})
|
|
|
|
repo := repository.NewAgentBotInboxRepo(db)
|
|
botRepo := repository.NewAgentBotRepo(db)
|
|
svc := NewAgentBotInboxService(repo, botRepo)
|
|
return svc, db
|
|
}
|
|
|
|
// Helper: create prerequisite Account, AgentBot, and Inbox for service tests.
|
|
func createSvcPrereqs(t *testing.T, db *gorm.DB) (*model.Account, *model.AgentBot, *model.Inbox) {
|
|
t.Helper()
|
|
|
|
account := &model.Account{Name: "SvcTestOrg", Locale: "en", Active: true}
|
|
require.NoError(t, db.Create(account).Error)
|
|
|
|
bot := &model.AgentBot{
|
|
AccountID: &account.ID,
|
|
Name: "SvcTestBot",
|
|
BotType: "default",
|
|
Secret: "secret-svcbot",
|
|
AccessToken: "token-svcbot",
|
|
}
|
|
require.NoError(t, db.Create(bot).Error)
|
|
|
|
inbox := &model.Inbox{
|
|
AccountID: account.ID,
|
|
Name: "SvcTestInbox",
|
|
ChannelType: "web_widget",
|
|
ChannelID: 1,
|
|
}
|
|
require.NoError(t, db.Create(inbox).Error)
|
|
|
|
return account, bot, inbox
|
|
}
|
|
|
|
// Helper: create a second bot with unique secret/token for SQLite UNIQUE constraint.
|
|
func createSvcSecondBot(t *testing.T, db *gorm.DB, accountID uint, suffix string) *model.AgentBot {
|
|
t.Helper()
|
|
|
|
bot := &model.AgentBot{
|
|
AccountID: &accountID,
|
|
Name: "SvcBot-" + suffix,
|
|
BotType: "default",
|
|
Secret: fmt.Sprintf("secret-svc-%s", suffix),
|
|
AccessToken: fmt.Sprintf("token-svc-%s", suffix),
|
|
}
|
|
require.NoError(t, db.Create(bot).Error)
|
|
return bot
|
|
}
|
|
|
|
// ========== 1. Bind ==========
|
|
|
|
func TestAgentBotInboxService_Bind(t *testing.T) {
|
|
svc, db := setupAgentBotInboxService(t)
|
|
_, bot, inbox := createSvcPrereqs(t, db)
|
|
|
|
abi, err := svc.Bind(context.Background(), inbox.AccountID, BindBotToInboxRequest{
|
|
AgentBotID: bot.ID,
|
|
InboxID: inbox.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, abi.ID)
|
|
assert.Equal(t, bot.ID, abi.AgentBotID)
|
|
assert.Equal(t, inbox.ID, abi.InboxID)
|
|
assert.Equal(t, model.AgentBotInboxActive, abi.Status)
|
|
}
|
|
|
|
func TestAgentBotInboxService_Bind_BotNotFound(t *testing.T) {
|
|
svc, _ := setupAgentBotInboxService(t)
|
|
|
|
abi, err := svc.Bind(context.Background(), 1, BindBotToInboxRequest{
|
|
AgentBotID: 9999,
|
|
InboxID: 1,
|
|
})
|
|
assert.Error(t, err)
|
|
assert.Nil(t, abi)
|
|
assert.Contains(t, err.Error(), "agent bot not found")
|
|
}
|
|
|
|
func TestAgentBotInboxService_Bind_Duplicate(t *testing.T) {
|
|
svc, db := setupAgentBotInboxService(t)
|
|
_, bot, inbox := createSvcPrereqs(t, db)
|
|
|
|
// First bind succeeds
|
|
_, err := svc.Bind(context.Background(), inbox.AccountID, BindBotToInboxRequest{
|
|
AgentBotID: bot.ID,
|
|
InboxID: inbox.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Second bind fails (duplicate)
|
|
abi, err := svc.Bind(context.Background(), inbox.AccountID, BindBotToInboxRequest{
|
|
AgentBotID: bot.ID,
|
|
InboxID: inbox.ID,
|
|
})
|
|
assert.Error(t, err)
|
|
assert.Nil(t, abi)
|
|
assert.Contains(t, err.Error(), "already bound")
|
|
}
|
|
|
|
// ========== 2. Unbind ==========
|
|
|
|
func TestAgentBotInboxService_Unbind(t *testing.T) {
|
|
svc, db := setupAgentBotInboxService(t)
|
|
_, bot, inbox := createSvcPrereqs(t, db)
|
|
|
|
abi, err := svc.Bind(context.Background(), inbox.AccountID, BindBotToInboxRequest{
|
|
AgentBotID: bot.ID,
|
|
InboxID: inbox.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
err = svc.Unbind(context.Background(), abi.ID)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify binding is gone
|
|
abis, err := svc.ListByInbox(context.Background(), inbox.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, abis, 0)
|
|
}
|
|
|
|
func TestAgentBotInboxService_Unbind_NotFound(t *testing.T) {
|
|
svc, _ := setupAgentBotInboxService(t)
|
|
|
|
err := svc.Unbind(context.Background(), 9999)
|
|
assert.NoError(t, err) // GORM delete on non-existent row returns no error
|
|
}
|
|
|
|
// ========== 3. UpdateStatus ==========
|
|
|
|
func TestAgentBotInboxService_UpdateStatus(t *testing.T) {
|
|
svc, db := setupAgentBotInboxService(t)
|
|
_, bot, inbox := createSvcPrereqs(t, db)
|
|
|
|
abi, err := svc.Bind(context.Background(), inbox.AccountID, BindBotToInboxRequest{
|
|
AgentBotID: bot.ID,
|
|
InboxID: inbox.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, model.AgentBotInboxActive, abi.Status)
|
|
|
|
// Toggle to inactive
|
|
updated, err := svc.UpdateStatus(context.Background(), abi.ID, UpdateBindingStatusRequest{Status: 1})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, model.AgentBotInboxInactive, updated.Status)
|
|
|
|
// Toggle back to active
|
|
updated2, err := svc.UpdateStatus(context.Background(), abi.ID, UpdateBindingStatusRequest{Status: 0})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, model.AgentBotInboxActive, updated2.Status)
|
|
}
|
|
|
|
func TestAgentBotInboxService_UpdateStatus_NotFound(t *testing.T) {
|
|
svc, _ := setupAgentBotInboxService(t)
|
|
|
|
abi, err := svc.UpdateStatus(context.Background(), 9999, UpdateBindingStatusRequest{Status: 1})
|
|
assert.Error(t, err)
|
|
assert.Nil(t, abi)
|
|
assert.Contains(t, err.Error(), "binding not found")
|
|
}
|
|
|
|
// ========== 4. ListByInbox ==========
|
|
|
|
func TestAgentBotInboxService_ListByInbox(t *testing.T) {
|
|
svc, db := setupAgentBotInboxService(t)
|
|
_, bot, inbox := createSvcPrereqs(t, db)
|
|
|
|
_, err := svc.Bind(context.Background(), inbox.AccountID, BindBotToInboxRequest{
|
|
AgentBotID: bot.ID,
|
|
InboxID: inbox.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
abis, err := svc.ListByInbox(context.Background(), inbox.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, abis, 1)
|
|
assert.Equal(t, bot.ID, abis[0].AgentBotID)
|
|
}
|
|
|
|
func TestAgentBotInboxService_ListByInbox_Empty(t *testing.T) {
|
|
svc, _ := setupAgentBotInboxService(t)
|
|
|
|
abis, err := svc.ListByInbox(context.Background(), 9999)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, abis, 0)
|
|
}
|
|
|
|
// ========== 5. ListActiveByInbox ==========
|
|
|
|
func TestAgentBotInboxService_ListActiveByInbox(t *testing.T) {
|
|
svc, db := setupAgentBotInboxService(t)
|
|
_, bot, inbox := createSvcPrereqs(t, db)
|
|
|
|
abi, err := svc.Bind(context.Background(), inbox.AccountID, BindBotToInboxRequest{
|
|
AgentBotID: bot.ID,
|
|
InboxID: inbox.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
// Initially active
|
|
abis, err := svc.ListActiveByInbox(context.Background(), inbox.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, abis, 1)
|
|
|
|
// Toggle to inactive
|
|
_, err = svc.UpdateStatus(context.Background(), abi.ID, UpdateBindingStatusRequest{Status: 1})
|
|
require.NoError(t, err)
|
|
|
|
// No active bindings now
|
|
abis, err = svc.ListActiveByInbox(context.Background(), inbox.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, abis, 0)
|
|
|
|
// But ListByInbox still shows 1
|
|
allAbis, err := svc.ListByInbox(context.Background(), inbox.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, allAbis, 1)
|
|
}
|
|
|
|
// ========== 6. ListByBot ==========
|
|
|
|
func TestAgentBotInboxService_ListByBot(t *testing.T) {
|
|
svc, db := setupAgentBotInboxService(t)
|
|
_, bot, inbox := createSvcPrereqs(t, db)
|
|
|
|
_, err := svc.Bind(context.Background(), inbox.AccountID, BindBotToInboxRequest{
|
|
AgentBotID: bot.ID,
|
|
InboxID: inbox.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
abis, err := svc.ListByBot(context.Background(), bot.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, abis, 1)
|
|
assert.Equal(t, inbox.ID, abis[0].InboxID)
|
|
}
|
|
|
|
func TestAgentBotInboxService_ListByBot_Empty(t *testing.T) {
|
|
svc, db := setupAgentBotInboxService(t)
|
|
_, bot, _ := createSvcPrereqs(t, db)
|
|
|
|
abis, err := svc.ListByBot(context.Background(), bot.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, abis, 0)
|
|
} |