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

288 lines
9.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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不返回errorrows 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)
}