Files
gochat/pkg/testutil/fixtures.go
T
2026-06-04 15:44:48 +08:00

261 lines
8.3 KiB
Go

package testutil
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"gorm.io/gorm"
"github.com/gochat/gochat/internal/model"
"github.com/gochat/gochat/internal/model/channel"
)
// === Account fixtures ===
// NewAccountFixture returns a test Account without persisting it.
func NewAccountFixture(name string) *model.Account {
return &model.Account{
Name: name,
Locale: "en",
Timezone: "UTC",
Active: true,
}
}
// CreateAccountFixture creates and persists a test Account.
func CreateAccountFixture(t *testing.T, db *gorm.DB, name string) *model.Account {
t.Helper()
acc := NewAccountFixture(name)
if err := db.Create(acc).Error; err != nil {
panic(fmt.Sprintf("failed to create test account: %v", err))
}
return acc
}
// === User fixtures ===
// NewUserFixture returns a test User without persisting it.
func NewUserFixture(accountID uint, name, email string) *model.User {
return &model.User{
AccountID: accountID,
Name: name,
Email: email,
Password: "hashed_password_placeholder",
Provider: "email",
Role: string(model.AccountUserRoleAgent),
Active: true,
}
}
// CreateUserFixture creates and persists a test User.
func CreateUserFixture(t *testing.T, db *gorm.DB, accountID uint, name, email string) *model.User {
t.Helper()
user := NewUserFixture(accountID, name, email)
if err := db.Create(user).Error; err != nil {
panic(fmt.Sprintf("failed to create test user: %v", err))
}
return user
}
// === AccountUser fixtures ===
// NewAccountUserFixture returns a test AccountUser without persisting it.
func NewAccountUserFixture(userID, accountID uint, role string) *model.AccountUser {
return &model.AccountUser{
UserID: userID,
AccountID: accountID,
Role: role,
Availability: "online",
}
}
// CreateAccountUserFixture creates and persists a test AccountUser.
func CreateAccountUserFixture(t *testing.T, db *gorm.DB, userID, accountID uint, role string) *model.AccountUser {
t.Helper()
au := NewAccountUserFixture(userID, accountID, role)
if err := db.Create(au).Error; err != nil {
panic(fmt.Sprintf("failed to create test account_user: %v", err))
}
return au
}
// === Inbox fixtures ===
// NewInboxFixture returns a test Inbox without persisting it.
func NewInboxFixture(accountID uint, name, channelType string) *model.Inbox {
return &model.Inbox{
AccountID: accountID,
Name: name,
ChannelType: channelType,
}
}
// CreateInboxFixture creates and persists a test Inbox.
func CreateInboxFixture(t *testing.T, db *gorm.DB, accountID uint, name, channelType string) *model.Inbox {
t.Helper()
inbox := NewInboxFixture(accountID, name, channelType)
if err := db.Create(inbox).Error; err != nil {
panic(fmt.Sprintf("failed to create test inbox: %v", err))
}
return inbox
}
// === Contact fixtures ===
// NewContactFixture returns a test Contact without persisting it.
func NewContactFixture(accountID uint, name string) *model.Contact {
return &model.Contact{
AccountID: accountID,
Name: name,
}
}
// CreateContactFixture creates and persists a test Contact.
func CreateContactFixture(t *testing.T, db *gorm.DB, accountID uint, name string) *model.Contact {
t.Helper()
contact := NewContactFixture(accountID, name)
if err := db.Create(contact).Error; err != nil {
panic(fmt.Sprintf("failed to create test contact: %v", err))
}
return contact
}
// === Conversation fixtures ===
// NewConversationFixture returns a test Conversation without persisting it.
func NewConversationFixture(accountID, inboxID, contactID uint, status string) *model.Conversation {
return &model.Conversation{
AccountID: accountID,
InboxID: inboxID,
ContactID: contactID,
Status: status,
ChannelType: "web_widget",
}
}
// CreateConversationFixture creates and persists a test Conversation.
func CreateConversationFixture(t *testing.T, db *gorm.DB, accountID, inboxID, contactID uint, status string) *model.Conversation {
t.Helper()
conv := NewConversationFixture(accountID, inboxID, contactID, status)
if err := db.Create(conv).Error; err != nil {
panic(fmt.Sprintf("failed to create test conversation: %v", err))
}
return conv
}
// === Message fixtures ===
// NewMessageFixture returns a test Message without persisting it.
func NewMessageFixture(conversationID, accountID, inboxID uint, content string) *model.Message {
return &model.Message{
ConversationID: conversationID,
AccountID: accountID,
InboxID: inboxID,
Content: content,
ContentType: string(model.MessageContentTypeText),
MessageType: string(model.MessageTypeIncoming),
SenderType: "contact",
}
}
// CreateMessageFixture creates and persists a test Message.
func CreateMessageFixture(t *testing.T, db *gorm.DB, conversationID, accountID, inboxID uint, content string) *model.Message {
t.Helper()
msg := NewMessageFixture(conversationID, accountID, inboxID, content)
if err := db.Create(msg).Error; err != nil {
panic(fmt.Sprintf("failed to create test message: %v", err))
}
return msg
}
// === CustomRole fixtures ===
// NewCustomRoleFixture returns a test CustomRole without persisting it.
func NewCustomRoleFixture(accountID uint, name string) *model.CustomRole {
return &model.CustomRole{
AccountID: accountID,
Name: name,
}
}
// CreateCustomRoleFixture creates and persists a test CustomRole.
func CreateCustomRoleFixture(t *testing.T, db *gorm.DB, accountID uint, name string) *model.CustomRole {
t.Helper()
role := NewCustomRoleFixture(accountID, name)
if err := db.Create(role).Error; err != nil {
panic(fmt.Sprintf("failed to create test custom_role: %v", err))
}
return role
}
// === Channel fixtures ===
// NewChannelTelegramFixture returns a test ChannelTelegram without persisting it.
func NewChannelTelegramFixture(accountID uint, botToken string) *channel.ChannelTelegram {
return &channel.ChannelTelegram{
AccountID: accountID,
BotToken: botToken,
}
}
// CreateChannelTelegramFixture creates and persists a test ChannelTelegram.
func CreateChannelTelegramFixture(t *testing.T, db *gorm.DB, accountID uint, botToken string) *channel.ChannelTelegram {
t.Helper()
ch := NewChannelTelegramFixture(accountID, botToken)
if err := db.Create(ch).Error; err != nil {
panic(fmt.Sprintf("failed to create test channel_telegram: %v", err))
}
return ch
}
// NewChannelWebWidgetFixture returns a test ChannelWebWidget without persisting it.
func NewChannelWebWidgetFixture(inboxID uint, websiteURL string) *channel.ChannelWebWidget {
return &channel.ChannelWebWidget{
InboxID: inboxID,
WebsiteURL: websiteURL,
}
}
// CreateChannelWebWidgetFixture creates and persists a test ChannelWebWidget.
func CreateChannelWebWidgetFixture(t *testing.T, db *gorm.DB, inboxID uint, websiteURL string) *channel.ChannelWebWidget {
t.Helper()
ch := NewChannelWebWidgetFixture(inboxID, websiteURL)
if err := db.Create(ch).Error; err != nil {
panic(fmt.Sprintf("failed to create test channel_web_widget: %v", err))
}
return ch
}
// === Full seed chain ===
// SeedFullAccountChain creates a complete chain: Account → User → AccountUser
// This is the minimal RBAC context needed for most tests.
func SeedFullAccountChain(t *testing.T, db *gorm.DB) (*model.Account, *model.User, *model.AccountUser) {
t.Helper()
acc := CreateAccountFixture(t, db, "Test Account")
user := CreateUserFixture(t, db, acc.ID, "Test User", "test@example.com")
au := CreateAccountUserFixture(t, db, user.ID, acc.ID, string(model.AccountUserRoleAgent))
return acc, user, au
}
// SeedFullConversationChain creates: Account → Inbox → Contact → Conversation
func SeedFullConversationChain(t *testing.T, db *gorm.DB) (*model.Account, *model.Inbox, *model.Contact, *model.Conversation) {
t.Helper()
acc := CreateAccountFixture(t, db, "Test Account")
inbox := CreateInboxFixture(t, db, acc.ID, "Test Inbox", "web_widget")
contact := CreateContactFixture(t, db, acc.ID, "Test Contact")
conv := CreateConversationFixture(t, db, acc.ID, inbox.ID, contact.ID, string(model.ConversationStatusOpen))
return acc, inbox, contact, conv
}
// === Helpers for fixture assertions ===
// AssertFixtureCount asserts that a model table has the expected number of rows.
func AssertFixtureCount(t *testing.T, db *gorm.DB, model interface{}, expected int64) {
t.Helper()
var count int64
err := db.Model(model).Count(&count).Error
assert.NoError(t, err)
assert.Equal(t, expected, count)
}