package repository import ( "context" "encoding/json" "fmt" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gorm.io/gorm" "github.com/gochat/gochat/internal/model" ) // Helper: create prerequisite Account for AgentBot tests. func createAgentBotPrereqs(t *testing.T, db *gorm.DB) *model.Account { t.Helper() account := &model.Account{Name: "ABTestOrg", Locale: "en", Active: true} require.NoError(t, db.Create(account).Error) return account } // Helper: create a test AgentBot with all prerequisites. func createTestAgentBot(t *testing.T, db *gorm.DB, accountID uint, name string) *model.AgentBot { t.Helper() bot := &model.AgentBot{ AccountID: &accountID, Name: name, BotType: "default", Secret: fmt.Sprintf("secret-%s-%d", name, time.Now().UnixNano()), AccessToken: fmt.Sprintf("token-%s-%d", name, time.Now().UnixNano()), Config: json.RawMessage(`{"key":"value"}`), } require.NoError(t, db.Create(bot).Error) return bot } // ========== 1. FindByID ========== func TestAgentBotRepo_FindByID(t *testing.T) { db := setupTestDB(t, &model.AgentBot{}, &model.AgentBotInbox{}) repo := NewAgentBotRepo(db) account := createAgentBotPrereqs(t, db) bot := createTestAgentBot(t, db, account.ID, "TestBot") found, err := repo.FindByID(context.Background(), bot.ID) assert.NoError(t, err) assert.Equal(t, bot.ID, found.ID) assert.Equal(t, "TestBot", found.Name) assert.Equal(t, "default", found.BotType) } func TestAgentBotRepo_FindByID_NotFound(t *testing.T) { db := setupTestDB(t, &model.AgentBot{}, &model.AgentBotInbox{}) repo := NewAgentBotRepo(db) found, err := repo.FindByID(context.Background(), 9999) assert.Error(t, err) assert.Nil(t, found) } func TestAgentBotRepo_FindByID_WithInboxes(t *testing.T) { db := setupTestDB(t, &model.AgentBot{}, &model.AgentBotInbox{}) repo := NewAgentBotRepo(db) account := createAgentBotPrereqs(t, db) bot := createTestAgentBot(t, db, account.ID, "BotWithInboxes") // Create an inbox and link it via AgentBotInbox inbox := &model.Inbox{AccountID: account.ID, Name: "BotInbox", ChannelType: "web_widget", ChannelID: 1} require.NoError(t, db.Create(inbox).Error) botInbox := &model.AgentBotInbox{AgentBotID: bot.ID, InboxID: inbox.ID} require.NoError(t, db.Create(botInbox).Error) found, err := repo.FindByID(context.Background(), bot.ID) require.NoError(t, err) require.Len(t, found.Inboxes, 1, "expected bot to have 1 inbox association") assert.Equal(t, inbox.ID, found.Inboxes[0].InboxID) } // ========== 2. FindByAccount ========== func TestAgentBotRepo_FindByAccount(t *testing.T) { db := setupTestDB(t, &model.AgentBot{}, &model.AgentBotInbox{}) repo := NewAgentBotRepo(db) account := createAgentBotPrereqs(t, db) createTestAgentBot(t, db, account.ID, "Bot1") createTestAgentBot(t, db, account.ID, "Bot2") bots, total, err := repo.FindByAccount(context.Background(), account.ID, 0, 10) assert.NoError(t, err) assert.Equal(t, int64(2), total) assert.Len(t, bots, 2) } func TestAgentBotRepo_FindByAccount_Pagination(t *testing.T) { db := setupTestDB(t, &model.AgentBot{}, &model.AgentBotInbox{}) repo := NewAgentBotRepo(db) account := createAgentBotPrereqs(t, db) createTestAgentBot(t, db, account.ID, "Bot1") createTestAgentBot(t, db, account.ID, "Bot2") createTestAgentBot(t, db, account.ID, "Bot3") bots, total, err := repo.FindByAccount(context.Background(), account.ID, 0, 2) assert.NoError(t, err) assert.Equal(t, int64(3), total) assert.Len(t, bots, 2) bots2, total2, err2 := repo.FindByAccount(context.Background(), account.ID, 2, 2) assert.NoError(t, err2) assert.Equal(t, int64(3), total2) assert.Len(t, bots2, 1) } func TestAgentBotRepo_FindByAccount_NoMatches(t *testing.T) { db := setupTestDB(t, &model.AgentBot{}, &model.AgentBotInbox{}) repo := NewAgentBotRepo(db) bots, total, err := repo.FindByAccount(context.Background(), 9999, 0, 10) assert.NoError(t, err) assert.Equal(t, int64(0), total) assert.Len(t, bots, 0) } // ========== 3. Create ========== func TestAgentBotRepo_Create(t *testing.T) { db := setupTestDB(t, &model.AgentBot{}, &model.AgentBotInbox{}) repo := NewAgentBotRepo(db) account := createAgentBotPrereqs(t, db) bot := &model.AgentBot{ AccountID: &account.ID, Name: "NewBot", BotType: "custom", Config: json.RawMessage(`{"url":"https://example.com"}`), } err := repo.Create(context.Background(), bot) assert.NoError(t, err) assert.NotZero(t, bot.ID) } // ========== 4. Update ========== func TestAgentBotRepo_Update(t *testing.T) { db := setupTestDB(t, &model.AgentBot{}, &model.AgentBotInbox{}) repo := NewAgentBotRepo(db) account := createAgentBotPrereqs(t, db) bot := createTestAgentBot(t, db, account.ID, "BeforeUpdate") bot.Name = "AfterUpdate" err := repo.Update(context.Background(), bot) assert.NoError(t, err) found, err := repo.FindByID(context.Background(), bot.ID) assert.NoError(t, err) assert.Equal(t, "AfterUpdate", found.Name) } // ========== 5. Delete ========== func TestAgentBotRepo_Delete(t *testing.T) { db := setupTestDB(t, &model.AgentBot{}, &model.AgentBotInbox{}) repo := NewAgentBotRepo(db) account := createAgentBotPrereqs(t, db) bot := createTestAgentBot(t, db, account.ID, "DeleteBot") err := repo.Delete(context.Background(), bot.ID) assert.NoError(t, err) found, err := repo.FindByID(context.Background(), bot.ID) assert.Error(t, err) assert.Nil(t, found) } func TestAgentBotRepo_Delete_NotFound(t *testing.T) { db := setupTestDB(t, &model.AgentBot{}, &model.AgentBotInbox{}) repo := NewAgentBotRepo(db) err := repo.Delete(context.Background(), 9999) assert.NoError(t, err) // GORM delete on non-existent row is not an error }