Files
gochat/internal/repository/auto_reply_rule_repo_test.go
T
2026-06-04 15:44:48 +08:00

221 lines
7.5 KiB
Go

package repository
import (
"context"
"encoding/json"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/gochat/gochat/internal/model"
)
// createTestAutoReplyRule builds a minimal valid CaptainAutoReplyRule.
func createTestAutoReplyRule(accountID, assistantID uint, name string) *model.CaptainAutoReplyRule {
conditions, _ := json.Marshal([]model.AutoReplyCondition{
{Field: "message_content", Operator: "contains", Value: "urgent"},
})
return &model.CaptainAutoReplyRule{
AccountID: accountID,
AssistantID: assistantID,
Name: name,
Description: "A test auto-reply rule",
Status: model.AutoReplyRuleStatusDraft,
Mode: model.AutoReplyRuleModeStatic,
Priority: 10,
Conditions: conditions,
ResponseText: "We will respond to your urgent inquiry shortly.",
}
}
// --- 1. Create ---
func TestCaptainAutoReplyRuleRepo_Create(t *testing.T) {
db := setupTestDB(t, &model.CaptainAutoReplyRule{})
repo := NewCaptainAutoReplyRuleRepo(db)
conditions, _ := json.Marshal([]model.AutoReplyCondition{
{Field: "message_content", Operator: "contains", Value: "refund"},
})
rule := &model.CaptainAutoReplyRule{
AccountID: 1,
AssistantID: 10,
Name: "RefundHandler",
Description: "Auto-reply for refund requests",
Status: model.AutoReplyRuleStatusDraft,
Mode: model.AutoReplyRuleModeStatic,
Priority: 5,
Conditions: conditions,
ResponseText: "We will process your refund request within 48 hours.",
}
err := repo.Create(context.Background(), rule)
require.NoError(t, err)
assert.NotZero(t, rule.ID, "ID should be set after Create")
assert.Equal(t, "RefundHandler", rule.Name)
assert.Equal(t, uint(1), rule.AccountID)
assert.Equal(t, model.AutoReplyRuleStatusDraft, rule.Status)
// Verify Conditions JSON was persisted
var foundConditions []model.AutoReplyCondition
require.NoError(t, json.Unmarshal(rule.Conditions, &foundConditions))
assert.Len(t, foundConditions, 1)
assert.Equal(t, "refund", foundConditions[0].Value)
}
// --- 2. GetByID ---
func TestCaptainAutoReplyRuleRepo_GetByID(t *testing.T) {
db := setupTestDB(t, &model.CaptainAutoReplyRule{})
repo := NewCaptainAutoReplyRuleRepo(db)
rule := createTestAutoReplyRule(1, 10, "TestRule")
require.NoError(t, repo.Create(context.Background(), rule))
found, err := repo.GetByID(context.Background(), rule.ID)
require.NoError(t, err)
assert.Equal(t, rule.ID, found.ID)
assert.Equal(t, "TestRule", found.Name)
assert.Equal(t, model.AutoReplyRuleModeStatic, found.Mode)
}
func TestCaptainAutoReplyRuleRepo_GetByID_NotFound(t *testing.T) {
db := setupTestDB(t, &model.CaptainAutoReplyRule{})
repo := NewCaptainAutoReplyRuleRepo(db)
_, err := repo.GetByID(context.Background(), 999)
assert.Error(t, err)
}
// --- 3. Update ---
func TestCaptainAutoReplyRuleRepo_Update(t *testing.T) {
db := setupTestDB(t, &model.CaptainAutoReplyRule{})
repo := NewCaptainAutoReplyRuleRepo(db)
rule := createTestAutoReplyRule(1, 10, "OriginalName")
require.NoError(t, repo.Create(context.Background(), rule))
rule.Name = "UpdatedName"
rule.Status = model.AutoReplyRuleStatusActive
err := repo.Update(context.Background(), rule)
require.NoError(t, err)
found, err := repo.GetByID(context.Background(), rule.ID)
require.NoError(t, err)
assert.Equal(t, "UpdatedName", found.Name)
assert.Equal(t, model.AutoReplyRuleStatusActive, found.Status)
}
// --- 4. Delete ---
func TestCaptainAutoReplyRuleRepo_Delete(t *testing.T) {
db := setupTestDB(t, &model.CaptainAutoReplyRule{})
repo := NewCaptainAutoReplyRuleRepo(db)
rule := createTestAutoReplyRule(1, 10, "ToDelete")
require.NoError(t, repo.Create(context.Background(), rule))
err := repo.Delete(context.Background(), rule.ID)
require.NoError(t, err)
_, err = repo.GetByID(context.Background(), rule.ID)
assert.Error(t, err)
}
// --- 5. ListByAccount ---
func TestCaptainAutoReplyRuleRepo_ListByAccount(t *testing.T) {
db := setupTestDB(t, &model.CaptainAutoReplyRule{})
repo := NewCaptainAutoReplyRuleRepo(db)
for i := 0; i < 5; i++ {
rule := createTestAutoReplyRule(1, 10, "Rule"+string(rune('A'+i)))
rule.Priority = i * 10
require.NoError(t, repo.Create(context.Background(), rule))
}
// Rules for a different account should not appear
ruleOther := createTestAutoReplyRule(2, 20, "OtherAccountRule")
require.NoError(t, repo.Create(context.Background(), ruleOther))
rules, count, err := repo.ListByAccount(context.Background(), 1, 0, 10)
require.NoError(t, err)
assert.Equal(t, int64(5), count)
assert.Len(t, rules, 5)
}
// --- 6. ListByAssistant ---
func TestCaptainAutoReplyRuleRepo_ListByAssistant(t *testing.T) {
db := setupTestDB(t, &model.CaptainAutoReplyRule{})
repo := NewCaptainAutoReplyRuleRepo(db)
for i := 0; i < 3; i++ {
rule := createTestAutoReplyRule(1, 10, "AssistantRule"+string(rune('A'+i)))
require.NoError(t, repo.Create(context.Background(), rule))
}
// Rules for a different assistant
ruleOther := createTestAutoReplyRule(1, 20, "OtherAssistantRule")
require.NoError(t, repo.Create(context.Background(), ruleOther))
rules, count, err := repo.ListByAssistant(context.Background(), 10, 0, 10)
require.NoError(t, err)
assert.Equal(t, int64(3), count)
assert.Len(t, rules, 3)
}
// --- 7. FindActiveByAssistant ---
func TestCaptainAutoReplyRuleRepo_FindActiveByAssistant(t *testing.T) {
db := setupTestDB(t, &model.CaptainAutoReplyRule{})
repo := NewCaptainAutoReplyRuleRepo(db)
// Create one active and one draft rule for assistant 10
activeRule := createTestAutoReplyRule(1, 10, "ActiveRule")
activeRule.Status = model.AutoReplyRuleStatusActive
require.NoError(t, repo.Create(context.Background(), activeRule))
draftRule := createTestAutoReplyRule(1, 10, "DraftRule")
draftRule.Status = model.AutoReplyRuleStatusDraft
require.NoError(t, repo.Create(context.Background(), draftRule))
rules, err := repo.FindActiveByAssistant(context.Background(), 10)
require.NoError(t, err)
assert.Len(t, rules, 1)
assert.Equal(t, "ActiveRule", rules[0].Name)
}
// --- 8. FindActiveByInbox ---
func TestCaptainAutoReplyRuleRepo_FindActiveByInbox(t *testing.T) {
db := setupTestDB(t, &model.CaptainAutoReplyRule{}, &model.Inbox{})
repo := NewCaptainAutoReplyRuleRepo(db)
inboxID1 := uint(100)
inboxID2 := uint(200)
// Account-wide rule (no inbox)
accountRule := createTestAutoReplyRule(1, 10, "AccountWide")
accountRule.Status = model.AutoReplyRuleStatusActive
require.NoError(t, repo.Create(context.Background(), accountRule))
// Inbox-scoped rule
inboxRule := createTestAutoReplyRule(1, 10, "Inbox100Rule")
inboxRule.Status = model.AutoReplyRuleStatusActive
inboxRule.InboxID = &inboxID1
require.NoError(t, repo.Create(context.Background(), inboxRule))
// Different inbox rule
inbox2Rule := createTestAutoReplyRule(1, 10, "Inbox200Rule")
inbox2Rule.Status = model.AutoReplyRuleStatusActive
inbox2Rule.InboxID = &inboxID2
require.NoError(t, repo.Create(context.Background(), inbox2Rule))
// Draft rule should not appear
draftRule := createTestAutoReplyRule(1, 10, "DraftRule")
draftRule.Status = model.AutoReplyRuleStatusDraft
require.NoError(t, repo.Create(context.Background(), draftRule))
// Find rules for inbox 100: should match Inbox100Rule + AccountWide
rules, err := repo.FindActiveByInbox(context.Background(), 1, inboxID1)
require.NoError(t, err)
assert.Len(t, rules, 2)
// Find rules for inbox 200: should match Inbox200Rule + AccountWide
rules2, err := repo.FindActiveByInbox(context.Background(), 1, inboxID2)
require.NoError(t, err)
assert.Len(t, rules2, 2)
}