288 lines
9.5 KiB
Plaintext
288 lines
9.5 KiB
Plaintext
package service
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"testing"
|
||
|
||
"github.com/gochat/gochat/internal/model"
|
||
"github.com/stretchr/testify/assert"
|
||
"github.com/stretchr/testify/require"
|
||
)
|
||
|
||
// ========== Create ==========
|
||
|
||
func TestCaptainScenarioService_Create_成功(t *testing.T) {
|
||
db, _, svc := setupCaptainScenarioService(t)
|
||
account := createTestAccount(t, db)
|
||
assistant := createTestCaptainAssistant(t, db, account.ID)
|
||
|
||
tools := json.RawMessage(`["search","calculate"]`)
|
||
req := &CreateScenarioRequest{
|
||
Title: "客服场景",
|
||
Description: "处理客户咨询",
|
||
Instruction: "首先了解客户需求,然后提供解决方案",
|
||
Enabled: true,
|
||
Tools: tools,
|
||
}
|
||
|
||
scenario, err := svc.Create(context.Background(), account.ID, assistant.ID, req)
|
||
require.NoError(t, err)
|
||
assert.NotZero(t, scenario.ID)
|
||
assert.Equal(t, account.ID, scenario.AccountID)
|
||
assert.Equal(t, assistant.ID, scenario.AssistantID)
|
||
assert.Equal(t, "客服场景", scenario.Title)
|
||
assert.Equal(t, "处理客户咨询", scenario.Description)
|
||
assert.Equal(t, "首先了解客户需求,然后提供解决方案", scenario.Instruction)
|
||
assert.True(t, scenario.Enabled)
|
||
assert.Equal(t, tools, scenario.Tools)
|
||
}
|
||
|
||
func TestCaptainScenarioService_Create_默认Enabled(t *testing.T) {
|
||
db, _, svc := setupCaptainScenarioService(t)
|
||
account := createTestAccount(t, db)
|
||
assistant := createTestCaptainAssistant(t, db, account.ID)
|
||
|
||
// GORM零值bool问题:先创建Enabled=true的场景,再更新为false
|
||
req := &CreateScenarioRequest{
|
||
Title: "启用场景",
|
||
Enabled: true,
|
||
}
|
||
scenario, err := svc.Create(context.Background(), account.ID, assistant.ID, req)
|
||
require.NoError(t, err)
|
||
assert.True(t, scenario.Enabled)
|
||
|
||
// 更新Enabled为false(使用Select强制写入零值)
|
||
require.NoError(t, db.Model(scenario).Select("enabled").Update("enabled", false).Error)
|
||
db.First(scenario, scenario.ID)
|
||
assert.False(t, scenario.Enabled)
|
||
}
|
||
|
||
func TestCaptainScenarioService_Create_空Tools(t *testing.T) {
|
||
db, _, svc := setupCaptainScenarioService(t)
|
||
account := createTestAccount(t, db)
|
||
assistant := createTestCaptainAssistant(t, db, account.ID)
|
||
|
||
req := &CreateScenarioRequest{
|
||
Title: "无工具场景",
|
||
Enabled: true,
|
||
Tools: nil,
|
||
}
|
||
|
||
scenario, err := svc.Create(context.Background(), account.ID, assistant.ID, req)
|
||
require.NoError(t, err)
|
||
assert.Nil(t, scenario.Tools)
|
||
}
|
||
|
||
// ========== GetByID ==========
|
||
|
||
func TestCaptainScenarioService_GetByID_成功(t *testing.T) {
|
||
db, _, svc := setupCaptainScenarioService(t)
|
||
account := createTestAccount(t, db)
|
||
assistant := createTestCaptainAssistant(t, db, account.ID)
|
||
scenario := createTestCaptainScenario(t, db, account.ID, assistant.ID)
|
||
|
||
result, err := svc.GetByID(context.Background(), scenario.ID)
|
||
require.NoError(t, err)
|
||
assert.Equal(t, scenario.ID, result.ID)
|
||
assert.Equal(t, scenario.Title, result.Title)
|
||
assert.Equal(t, scenario.AssistantID, result.AssistantID)
|
||
}
|
||
|
||
func TestCaptainScenarioService_GetByID_不存在(t *testing.T) {
|
||
_, _, svc := setupCaptainScenarioService(t)
|
||
|
||
result, err := svc.GetByID(context.Background(), 99999)
|
||
require.Error(t, err)
|
||
assert.Nil(t, result)
|
||
assert.Contains(t, err.Error(), "get scenario")
|
||
}
|
||
|
||
// ========== Update ==========
|
||
|
||
func TestCaptainScenarioService_Update_成功(t *testing.T) {
|
||
db, _, svc := setupCaptainScenarioService(t)
|
||
account := createTestAccount(t, db)
|
||
assistant := createTestCaptainAssistant(t, db, account.ID)
|
||
scenario := createTestCaptainScenario(t, db, account.ID, assistant.ID)
|
||
|
||
enabled := false
|
||
newTools := json.RawMessage(`["updated_tool"]`)
|
||
req := &UpdateScenarioRequest{
|
||
Title: "更新后的场景",
|
||
Description: "更新后的描述",
|
||
Instruction: "新的操作指令",
|
||
Enabled: &enabled,
|
||
Tools: newTools,
|
||
}
|
||
|
||
updated, err := svc.Update(context.Background(), scenario.ID, req)
|
||
require.NoError(t, err)
|
||
assert.Equal(t, "更新后的场景", updated.Title)
|
||
assert.Equal(t, "更新后的描述", updated.Description)
|
||
assert.Equal(t, "新的操作指令", updated.Instruction)
|
||
assert.False(t, updated.Enabled)
|
||
assert.Equal(t, newTools, updated.Tools)
|
||
}
|
||
|
||
func TestCaptainScenarioService_Update_部分字段(t *testing.T) {
|
||
db, _, svc := setupCaptainScenarioService(t)
|
||
account := createTestAccount(t, db)
|
||
assistant := createTestCaptainAssistant(t, db, account.ID)
|
||
scenario := createTestCaptainScenario(t, db, account.ID, assistant.ID)
|
||
|
||
// 只更新 Title,其他字段保持不变
|
||
req := &UpdateScenarioRequest{
|
||
Title: "只改标题",
|
||
}
|
||
|
||
updated, err := svc.Update(context.Background(), scenario.ID, req)
|
||
require.NoError(t, err)
|
||
assert.Equal(t, "只改标题", updated.Title)
|
||
assert.Equal(t, scenario.Description, updated.Description)
|
||
assert.Equal(t, scenario.Instruction, updated.Instruction)
|
||
assert.Equal(t, scenario.Enabled, updated.Enabled)
|
||
}
|
||
|
||
func TestCaptainScenarioService_Update_不存在(t *testing.T) {
|
||
_, _, svc := setupCaptainScenarioService(t)
|
||
|
||
enabled := true
|
||
req := &UpdateScenarioRequest{
|
||
Title: "不存在",
|
||
Enabled: &enabled,
|
||
}
|
||
|
||
result, err := svc.Update(context.Background(), 99999, req)
|
||
require.Error(t, err)
|
||
assert.Nil(t, result)
|
||
assert.Contains(t, err.Error(), "scenario not found")
|
||
}
|
||
|
||
func TestCaptainScenarioService_Update_Enabled为nullJSON(t *testing.T) {
|
||
db, _, svc := setupCaptainScenarioService(t)
|
||
account := createTestAccount(t, db)
|
||
assistant := createTestCaptainAssistant(t, db, account.ID)
|
||
originalTools := json.RawMessage(`["tool_a"]`)
|
||
scenario := createTestCaptainScenario(t, db, account.ID, assistant.ID, func(s *model.CaptainScenario) {
|
||
s.Tools = originalTools
|
||
})
|
||
|
||
// 传入 "null" JSON,不应更新 Tools
|
||
req := &UpdateScenarioRequest{
|
||
Tools: json.RawMessage(`null`),
|
||
}
|
||
|
||
updated, err := svc.Update(context.Background(), scenario.ID, req)
|
||
require.NoError(t, err)
|
||
assert.Equal(t, originalTools, updated.Tools)
|
||
}
|
||
|
||
// ========== Delete ==========
|
||
|
||
func TestCaptainScenarioService_Delete_成功(t *testing.T) {
|
||
db, _, svc := setupCaptainScenarioService(t)
|
||
account := createTestAccount(t, db)
|
||
assistant := createTestCaptainAssistant(t, db, account.ID)
|
||
scenario := createTestCaptainScenario(t, db, account.ID, assistant.ID)
|
||
|
||
err := svc.Delete(context.Background(), scenario.ID)
|
||
require.NoError(t, err)
|
||
|
||
// 验证已删除(GetByID 应返回错误)
|
||
result, err := svc.GetByID(context.Background(), scenario.ID)
|
||
require.Error(t, err)
|
||
assert.Nil(t, result)
|
||
}
|
||
|
||
func TestCaptainScenarioService_Delete_不存在(t *testing.T) {
|
||
_, _, svc := setupCaptainScenarioService(t)
|
||
|
||
// GORM Delete不存在的ID不返回error(rows affected=0但不报错)
|
||
err := svc.Delete(context.Background(), 99999)
|
||
assert.NoError(t, err)
|
||
}
|
||
|
||
// ========== ListByAssistant ==========
|
||
|
||
func TestCaptainScenarioService_ListByAssistant_成功(t *testing.T) {
|
||
db, _, svc := setupCaptainScenarioService(t)
|
||
account := createTestAccount(t, db)
|
||
assistant := createTestCaptainAssistant(t, db, account.ID)
|
||
|
||
// 创建3个场景
|
||
createTestCaptainScenario(t, db, account.ID, assistant.ID, func(s *model.CaptainScenario) {
|
||
s.Title = "场景A"
|
||
})
|
||
createTestCaptainScenario(t, db, account.ID, assistant.ID, func(s *model.CaptainScenario) {
|
||
s.Title = "场景B"
|
||
})
|
||
createTestCaptainScenario(t, db, account.ID, assistant.ID, func(s *model.CaptainScenario) {
|
||
s.Title = "场景C"
|
||
})
|
||
|
||
scenarios, count, err := svc.ListByAssistant(context.Background(), assistant.ID, 0, 10)
|
||
require.NoError(t, err)
|
||
assert.Equal(t, int64(3), count)
|
||
assert.Len(t, scenarios, 3)
|
||
}
|
||
|
||
func TestCaptainScenarioService_ListByAssistant_分页(t *testing.T) {
|
||
db, _, svc := setupCaptainScenarioService(t)
|
||
account := createTestAccount(t, db)
|
||
assistant := createTestCaptainAssistant(t, db, account.ID)
|
||
|
||
// 创建5个场景
|
||
for i := 0; i < 5; i++ {
|
||
createTestCaptainScenario(t, db, account.ID, assistant.ID)
|
||
}
|
||
|
||
// offset=0, limit=2 应返回前2条,count=5
|
||
scenarios, count, err := svc.ListByAssistant(context.Background(), assistant.ID, 0, 2)
|
||
require.NoError(t, err)
|
||
assert.Equal(t, int64(5), count)
|
||
assert.Len(t, scenarios, 2)
|
||
|
||
// offset=2, limit=2 应返回第3-4条
|
||
scenarios2, count2, err := svc.ListByAssistant(context.Background(), assistant.ID, 2, 2)
|
||
require.NoError(t, err)
|
||
assert.Equal(t, int64(5), count2)
|
||
assert.Len(t, scenarios2, 2)
|
||
}
|
||
|
||
func TestCaptainScenarioService_ListByAssistant_空列表(t *testing.T) {
|
||
db, _, svc := setupCaptainScenarioService(t)
|
||
account := createTestAccount(t, db)
|
||
assistant := createTestCaptainAssistant(t, db, account.ID)
|
||
|
||
scenarios, count, err := svc.ListByAssistant(context.Background(), assistant.ID, 0, 10)
|
||
require.NoError(t, err)
|
||
assert.Equal(t, int64(0), count)
|
||
assert.Len(t, scenarios, 0)
|
||
}
|
||
|
||
func TestCaptainScenarioService_ListByAssistant_不同助手隔离(t *testing.T) {
|
||
db, _, svc := setupCaptainScenarioService(t)
|
||
account := createTestAccount(t, db)
|
||
assistant1 := createTestCaptainAssistant(t, db, account.ID, func(a *model.CaptainAssistant) {
|
||
a.Name = "助手1"
|
||
})
|
||
assistant2 := createTestCaptainAssistant(t, db, account.ID, func(a *model.CaptainAssistant) {
|
||
a.Name = "助手2"
|
||
})
|
||
|
||
// assistant1 有2个场景,assistant2 有1个场景
|
||
createTestCaptainScenario(t, db, account.ID, assistant1.ID)
|
||
createTestCaptainScenario(t, db, account.ID, assistant1.ID)
|
||
createTestCaptainScenario(t, db, account.ID, assistant2.ID)
|
||
|
||
scenarios1, count1, err := svc.ListByAssistant(context.Background(), assistant1.ID, 0, 10)
|
||
require.NoError(t, err)
|
||
assert.Equal(t, int64(2), count1)
|
||
assert.Len(t, scenarios1, 2)
|
||
|
||
scenarios2, count2, err := svc.ListByAssistant(context.Background(), assistant2.ID, 0, 10)
|
||
require.NoError(t, err)
|
||
assert.Equal(t, int64(1), count2)
|
||
assert.Len(t, scenarios2, 1)
|
||
} |