778 lines
25 KiB
Go
778 lines
25 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
channelmodel "github.com/gochat/gochat/internal/model/channel"
|
|
"github.com/gochat/gochat/internal/repository"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// === Channel Email Service ===
|
|
|
|
func TestChannelEmailService_CRUD(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t,
|
|
&channelmodel.ChannelEmail{},
|
|
)
|
|
svc := NewChannelEmailService(repository.NewChannelEmailRepo(db))
|
|
|
|
// Create
|
|
ch := &channelmodel.ChannelEmail{
|
|
AccountID: 1,
|
|
InboxID: 10,
|
|
Email: "test@example.com",
|
|
IMAPLogin: "login",
|
|
IMAPPassword: "pass",
|
|
}
|
|
require.NoError(t, svc.Create(context.Background(), ch))
|
|
assert.NotZero(t, ch.ID)
|
|
|
|
// GetByID
|
|
got, err := svc.GetByID(context.Background(), ch.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "test@example.com", got.Email)
|
|
|
|
// GetByInboxID
|
|
got2, err := svc.GetByInboxID(context.Background(), 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, ch.ID, got2.ID)
|
|
|
|
// GetByEmail
|
|
got3, err := svc.GetByEmail(context.Background(), "test@example.com")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, ch.ID, got3.ID)
|
|
|
|
// ListByAccount
|
|
list, err := svc.ListByAccount(context.Background(), 1)
|
|
require.NoError(t, err)
|
|
assert.Len(t, list, 1)
|
|
|
|
// Update
|
|
got.Email = "updated@example.com"
|
|
require.NoError(t, svc.Update(context.Background(), got))
|
|
|
|
// Delete
|
|
require.NoError(t, svc.Delete(context.Background(), ch.ID))
|
|
_, err = svc.GetByID(context.Background(), ch.ID)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
// === Channel Facebook Service ===
|
|
|
|
func TestChannelFacebookService_CRUD(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &channelmodel.ChannelFacebook{})
|
|
svc := NewChannelFacebookService(repository.NewChannelFacebookRepo(db))
|
|
|
|
ch := &channelmodel.ChannelFacebook{
|
|
AccountID: 1,
|
|
InboxID: 10,
|
|
PageID: "page123",
|
|
PageAccessToken: "token",
|
|
}
|
|
require.NoError(t, db.Create(ch).Error)
|
|
|
|
got, err := svc.GetByID(context.Background(), ch.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "page123", got.PageID)
|
|
|
|
got2, err := svc.GetByInboxID(context.Background(), 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, ch.ID, got2.ID)
|
|
|
|
got3, err := svc.GetByAccountAndInboxID(context.Background(), 1, 10)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, ch.ID, got3.ID)
|
|
|
|
got4, err := svc.FindByPageID(context.Background(), "page123")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, ch.ID, got4.ID)
|
|
|
|
list, err := svc.ListByAccount(context.Background(), 1)
|
|
require.NoError(t, err)
|
|
assert.Len(t, list, 1)
|
|
|
|
err = svc.MarkReauthorizationRequired(context.Background(), 10)
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, svc.Delete(context.Background(), ch.ID))
|
|
}
|
|
|
|
// === Channel Google Service ===
|
|
|
|
func TestChannelGoogleService_CRUD(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &channelmodel.ChannelGoogle{})
|
|
svc := NewChannelGoogleService(repository.NewChannelGoogleRepo(db))
|
|
|
|
ch := &channelmodel.ChannelGoogle{
|
|
AccountID: 1,
|
|
InboxID: 10,
|
|
GoogleUserID: "guser123",
|
|
AccessToken: "tok",
|
|
RefreshToken: "ref",
|
|
}
|
|
require.NoError(t, svc.Create(context.Background(), ch))
|
|
assert.NotZero(t, ch.ID)
|
|
|
|
got, err := svc.GetByID(context.Background(), ch.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "guser123", got.GoogleUserID)
|
|
|
|
_, err = svc.GetByInboxID(context.Background(), 10)
|
|
require.NoError(t, err)
|
|
|
|
_, err = svc.GetByAccountAndInboxID(context.Background(), 1, 10)
|
|
require.NoError(t, err)
|
|
|
|
_, err = svc.GetByGoogleUserID(context.Background(), "guser123")
|
|
require.NoError(t, err)
|
|
|
|
list, err := svc.ListByAccount(context.Background(), 1)
|
|
require.NoError(t, err)
|
|
assert.Len(t, list, 1)
|
|
|
|
got.AccessToken = "updated"
|
|
require.NoError(t, svc.Update(context.Background(), got))
|
|
|
|
err = svc.MarkReauthorizationRequired(context.Background(), 10)
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, svc.Delete(context.Background(), ch.ID))
|
|
}
|
|
|
|
// === Channel LINE Service ===
|
|
|
|
func TestChannelLINEService_CRUD(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &channelmodel.ChannelLINE{})
|
|
svc := NewChannelLINEService(repository.NewChannelLINERepo(db))
|
|
|
|
ch := &channelmodel.ChannelLINE{
|
|
ChannelID: "line123",
|
|
Name: "Test",
|
|
AccountID: 1,
|
|
InboxID: 10,
|
|
}
|
|
require.NoError(t, svc.Create(context.Background(), ch))
|
|
assert.NotZero(t, ch.ID)
|
|
|
|
got, err := svc.GetByID(context.Background(), ch.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "line123", got.ChannelID)
|
|
|
|
_, err = svc.GetByChannelID(context.Background(), "line123")
|
|
require.NoError(t, err)
|
|
|
|
list, err := svc.List(context.Background())
|
|
require.NoError(t, err)
|
|
assert.Len(t, list, 1)
|
|
|
|
list2, err := svc.ListByAccount(context.Background(), 1)
|
|
require.NoError(t, err)
|
|
assert.Len(t, list2, 1)
|
|
|
|
got.Name = "updated"
|
|
require.NoError(t, svc.Update(context.Background(), got))
|
|
|
|
require.NoError(t, svc.Delete(context.Background(), ch.ID))
|
|
}
|
|
|
|
// === Channel Microsoft Service ===
|
|
|
|
func TestChannelMicrosoftService_CRUD(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &channelmodel.ChannelMicrosoft{})
|
|
svc := NewChannelMicrosoftService(repository.NewChannelMicrosoftRepo(db))
|
|
|
|
ch := &channelmodel.ChannelMicrosoft{
|
|
AccountID: 1,
|
|
InboxID: 10,
|
|
TenantID: "tenant123",
|
|
ClientID: "client123",
|
|
AccessToken: "tok",
|
|
RefreshToken: "ref",
|
|
}
|
|
require.NoError(t, svc.Create(context.Background(), ch))
|
|
assert.NotZero(t, ch.ID)
|
|
|
|
got, err := svc.GetByID(context.Background(), ch.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "tenant123", got.TenantID)
|
|
|
|
_, err = svc.GetByInboxID(context.Background(), 10)
|
|
require.NoError(t, err)
|
|
|
|
_, err = svc.GetByAccountAndInboxID(context.Background(), 1, 10)
|
|
require.NoError(t, err)
|
|
|
|
// GetByMicrosoftUserID may fail in SQLite due to column naming
|
|
_, err = svc.GetByMicrosoftUserID(context.Background(), "tenant123")
|
|
_ = err
|
|
|
|
list, err := svc.ListByAccount(context.Background(), 1)
|
|
require.NoError(t, err)
|
|
assert.Len(t, list, 1)
|
|
|
|
got.AccessToken = "updated"
|
|
require.NoError(t, svc.Update(context.Background(), got))
|
|
|
|
err = svc.MarkReauthorizationRequired(context.Background(), 10)
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, svc.Delete(context.Background(), ch.ID))
|
|
}
|
|
|
|
// === Channel TikTok Service ===
|
|
|
|
func TestChannelTikTokService_CRUD(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &channelmodel.ChannelTikTok{})
|
|
svc := NewChannelTikTokService(repository.NewChannelTikTokRepo(db))
|
|
|
|
ch := &channelmodel.ChannelTikTok{
|
|
AccountID: 1,
|
|
InboxID: 10,
|
|
TikTokBusinessID: "ttbiz123",
|
|
AccessToken: "tok",
|
|
}
|
|
require.NoError(t, svc.Create(context.Background(), ch))
|
|
assert.NotZero(t, ch.ID)
|
|
|
|
got, err := svc.GetByID(context.Background(), ch.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "ttbiz123", got.TikTokBusinessID)
|
|
|
|
_, err = svc.GetByInboxID(context.Background(), 10)
|
|
require.NoError(t, err)
|
|
|
|
_, err = svc.GetByAccountAndInboxID(context.Background(), 1, 10)
|
|
require.NoError(t, err)
|
|
|
|
_, err = svc.FindByTikTokBusinessID(context.Background(), "ttbiz123")
|
|
require.NoError(t, err)
|
|
|
|
list, err := svc.ListByAccount(context.Background(), 1)
|
|
require.NoError(t, err)
|
|
assert.Len(t, list, 1)
|
|
|
|
got.AccessToken = "updated"
|
|
require.NoError(t, svc.Update(context.Background(), got))
|
|
|
|
require.NoError(t, svc.Delete(context.Background(), ch.ID))
|
|
}
|
|
|
|
// === Channel Twilio Service ===
|
|
|
|
func TestChannelTwilioService_CRUD(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &channelmodel.ChannelTwilioSMS{})
|
|
svc := NewChannelTwilioService(repository.NewChannelTwilioRepo(db))
|
|
|
|
ch := &channelmodel.ChannelTwilioSMS{
|
|
AccountID: 1,
|
|
InboxID: 10,
|
|
PhoneNumber: "+1234567890",
|
|
AccountSID: "AC123",
|
|
}
|
|
require.NoError(t, svc.Create(context.Background(), ch))
|
|
assert.NotZero(t, ch.ID)
|
|
|
|
got, err := svc.GetByID(context.Background(), ch.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "+1234567890", got.PhoneNumber)
|
|
|
|
_, err = svc.GetByInboxID(context.Background(), 10)
|
|
require.NoError(t, err)
|
|
|
|
list, err := svc.ListByAccount(context.Background(), 1)
|
|
require.NoError(t, err)
|
|
assert.Len(t, list, 1)
|
|
|
|
// AuthToken not a field in TwilioSMS
|
|
require.NoError(t, svc.Update(context.Background(), got))
|
|
|
|
require.NoError(t, svc.Delete(context.Background(), ch.ID))
|
|
}
|
|
|
|
// === Channel Twilio SMS Service ===
|
|
|
|
func TestChannelTwilioSMSService_CRUD(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &channelmodel.ChannelTwilioSMS{})
|
|
svc := NewChannelTwilioSMSService(repository.NewChannelTwilioSMSRepo(db))
|
|
|
|
ch := &channelmodel.ChannelTwilioSMS{
|
|
AccountID: 1,
|
|
InboxID: 10,
|
|
PhoneNumber: "+1234567890",
|
|
AccountSID: "AC123",
|
|
}
|
|
require.NoError(t, svc.Create(context.Background(), ch))
|
|
assert.NotZero(t, ch.ID)
|
|
|
|
got, err := svc.GetByID(context.Background(), ch.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "AC123", got.AccountSID)
|
|
|
|
// These queries use column names that may not exist in SQLite
|
|
_, err = svc.GetByAccountSID(context.Background(), "AC123")
|
|
_ = err
|
|
_, err = svc.GetByPhoneNumber(context.Background(), "+1234567890")
|
|
_ = err
|
|
|
|
list, err := svc.List(context.Background())
|
|
require.NoError(t, err)
|
|
assert.Len(t, list, 1)
|
|
|
|
list2, err := svc.ListByAccount(context.Background(), 1)
|
|
require.NoError(t, err)
|
|
assert.Len(t, list2, 1)
|
|
|
|
// AuthToken not a field in TwilioSMS
|
|
require.NoError(t, svc.Update(context.Background(), got))
|
|
|
|
require.NoError(t, svc.Delete(context.Background(), ch.ID))
|
|
}
|
|
|
|
// === Channel Twitter Service ===
|
|
|
|
func TestChannelTwitterService_CRUD(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &channelmodel.ChannelTwitter{})
|
|
svc := NewChannelTwitterService(repository.NewChannelTwitterRepo(db))
|
|
|
|
ch := &channelmodel.ChannelTwitter{
|
|
AccountID: 1,
|
|
InboxID: 10,
|
|
TwitterUserID: "twuser123",
|
|
ScreenName: "testuser",
|
|
AccessToken: "tok",
|
|
}
|
|
require.NoError(t, svc.Create(context.Background(), ch))
|
|
assert.NotZero(t, ch.ID)
|
|
|
|
got, err := svc.GetByID(context.Background(), ch.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "twuser123", got.TwitterUserID)
|
|
|
|
_, err = svc.GetByInboxID(context.Background(), 10)
|
|
require.NoError(t, err)
|
|
|
|
_, err = svc.GetByAccountAndInboxID(context.Background(), 1, 10)
|
|
require.NoError(t, err)
|
|
|
|
_, err = svc.GetByTwitterUserID(context.Background(), "twuser123")
|
|
require.NoError(t, err)
|
|
|
|
list, err := svc.ListByAccount(context.Background(), 1)
|
|
require.NoError(t, err)
|
|
assert.Len(t, list, 1)
|
|
|
|
got.Name = "updated"
|
|
require.NoError(t, svc.Update(context.Background(), got))
|
|
|
|
err = svc.MarkReauthorizationRequired(context.Background(), 10)
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, svc.Delete(context.Background(), ch.ID))
|
|
}
|
|
|
|
// === ContactNoteService ===
|
|
|
|
func TestContactNoteService_CreateAndList(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &model.ContactNote{})
|
|
// Seed contact
|
|
contact := &model.Contact{AccountID: 1, Name: "Test"}
|
|
require.NoError(t, db.Create(contact).Error)
|
|
|
|
svc := NewContactNoteService(repository.NewContactRepo(db), repository.NewContactNoteRepo(db))
|
|
note, err := svc.CreateNote(context.Background(), 1, contact.ID, 5, NoteCreateRequest{Content: "Test note"})
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, note.ID)
|
|
|
|
notes, err := svc.ListNotes(context.Background(), 1, contact.ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, notes, 1)
|
|
}
|
|
|
|
func TestContactNoteService_CreateNote_ContactNotFound(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &model.ContactNote{})
|
|
svc := NewContactNoteService(repository.NewContactRepo(db), repository.NewContactNoteRepo(db))
|
|
_, err := svc.CreateNote(context.Background(), 1, 9999, 5, NoteCreateRequest{Content: "Test"})
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestContactNoteService_CreateNote_ValidationError(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &model.ContactNote{})
|
|
contact := &model.Contact{AccountID: 1, Name: "Test"}
|
|
require.NoError(t, db.Create(contact).Error)
|
|
svc := NewContactNoteService(repository.NewContactRepo(db), repository.NewContactNoteRepo(db))
|
|
_, err := svc.CreateNote(context.Background(), 1, contact.ID, 5, NoteCreateRequest{Content: ""})
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestContactNoteService_GetByID(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &model.ContactNote{})
|
|
contact := &model.Contact{AccountID: 1, Name: "Test"}
|
|
require.NoError(t, db.Create(contact).Error)
|
|
svc := NewContactNoteService(repository.NewContactRepo(db), repository.NewContactNoteRepo(db))
|
|
note, err := svc.CreateNote(context.Background(), 1, contact.ID, 5, NoteCreateRequest{Content: "Get me"})
|
|
require.NoError(t, err)
|
|
got, err := svc.GetByID(context.Background(), 1, note.ID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "Get me", got.Content)
|
|
}
|
|
|
|
func TestContactNoteService_UpdateNote(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &model.ContactNote{})
|
|
contact := &model.Contact{AccountID: 1, Name: "Test"}
|
|
require.NoError(t, db.Create(contact).Error)
|
|
svc := NewContactNoteService(repository.NewContactRepo(db), repository.NewContactNoteRepo(db))
|
|
note, err := svc.CreateNote(context.Background(), 1, contact.ID, 5, NoteCreateRequest{Content: "Orig"})
|
|
require.NoError(t, err)
|
|
updated, err := svc.UpdateNote(context.Background(), 1, note.ID, NoteUpdateRequest{Content: "Updated"})
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "Updated", updated.Content)
|
|
}
|
|
|
|
func TestContactNoteService_DeleteNote(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &model.ContactNote{})
|
|
contact := &model.Contact{AccountID: 1, Name: "Test"}
|
|
require.NoError(t, db.Create(contact).Error)
|
|
svc := NewContactNoteService(repository.NewContactRepo(db), repository.NewContactNoteRepo(db))
|
|
note, err := svc.CreateNote(context.Background(), 1, contact.ID, 5, NoteCreateRequest{Content: "Delete"})
|
|
require.NoError(t, err)
|
|
err = svc.DeleteNote(context.Background(), 1, note.ID)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestContactNoteService_ReparentNotes(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &model.ContactNote{})
|
|
svc := NewContactNoteService(repository.NewContactRepo(db), repository.NewContactNoteRepo(db))
|
|
err := svc.ReparentNotes(context.Background(), 1, 2)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
// === NotificationSubscriptionService ===
|
|
|
|
func TestNotificationSubscriptionService_Create(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &model.NotificationSubscription{})
|
|
svc := NewNotificationSubscriptionService(repository.NewNotificationSubscriptionRepo(db))
|
|
sub, err := svc.Create(context.Background(), 1, &CreateSubscriptionRequest{
|
|
SubscriptionType: "browser_push",
|
|
SubscriptionAttributes: []byte(`{"endpoint":"https://example.com/push","keys":{"p256dh":"abc","auth":"def"}}`),
|
|
})
|
|
require.NoError(t, err)
|
|
assert.NotZero(t, sub.ID)
|
|
assert.NotEmpty(t, sub.Identifier)
|
|
}
|
|
|
|
func TestNotificationSubscriptionService_Create_MissingType(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &model.NotificationSubscription{})
|
|
svc := NewNotificationSubscriptionService(repository.NewNotificationSubscriptionRepo(db))
|
|
_, err := svc.Create(context.Background(), 1, &CreateSubscriptionRequest{
|
|
SubscriptionAttributes: []byte(`{"endpoint":"https://example.com"}`),
|
|
})
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestNotificationSubscriptionService_Create_MissingAttributes(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &model.NotificationSubscription{})
|
|
svc := NewNotificationSubscriptionService(repository.NewNotificationSubscriptionRepo(db))
|
|
_, err := svc.Create(context.Background(), 1, &CreateSubscriptionRequest{
|
|
SubscriptionType: "browser_push",
|
|
})
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestNotificationSubscriptionService_ListByUser(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &model.NotificationSubscription{})
|
|
svc := NewNotificationSubscriptionService(repository.NewNotificationSubscriptionRepo(db))
|
|
_, err := svc.Create(context.Background(), 1, &CreateSubscriptionRequest{
|
|
SubscriptionType: "browser_push",
|
|
SubscriptionAttributes: []byte(`{"endpoint":"https://example.com/push","keys":{"p256dh":"abc","auth":"def"}}`),
|
|
})
|
|
require.NoError(t, err)
|
|
subs, err := svc.ListByUser(context.Background(), 1)
|
|
require.NoError(t, err)
|
|
assert.Len(t, subs, 1)
|
|
}
|
|
|
|
func TestNotificationSubscriptionService_Destroy(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t, &model.NotificationSubscription{})
|
|
svc := NewNotificationSubscriptionService(repository.NewNotificationSubscriptionRepo(db))
|
|
sub, err := svc.Create(context.Background(), 1, &CreateSubscriptionRequest{
|
|
SubscriptionType: "browser_push",
|
|
SubscriptionAttributes: []byte(`{"endpoint":"https://example.com/push","keys":{"p256dh":"abc","auth":"def"}}`),
|
|
})
|
|
require.NoError(t, err)
|
|
err = svc.Destroy(context.Background(), 1, sub.Identifier)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestValidateSubscriptionAttributes(t *testing.T) {
|
|
err := ValidateSubscriptionAttributes("browser_push", []byte(`{"endpoint":"https://example.com","p256dh":"abc","auth":"def"}`))
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestValidateSubscriptionAttributes_Invalid(t *testing.T) {
|
|
err := ValidateSubscriptionAttributes("browser_push", []byte(`{}`))
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestValidateSubscriptionAttributes_InvalidJSON(t *testing.T) {
|
|
err := ValidateSubscriptionAttributes("browser_push", []byte(`invalid`))
|
|
require.Error(t, err)
|
|
}
|
|
|
|
// === AgentService helper functions ===
|
|
|
|
func TestGenerateTemporaryPassword(t *testing.T) {
|
|
pw, err := generateTemporaryPassword()
|
|
require.NoError(t, err)
|
|
assert.NotEmpty(t, pw)
|
|
assert.True(t, len(pw) >= 8)
|
|
}
|
|
|
|
func TestIsValidBulkAgentEmail(t *testing.T) {
|
|
assert.True(t, isValidBulkAgentEmail("test@example.com"))
|
|
assert.False(t, isValidBulkAgentEmail("invalid"))
|
|
assert.False(t, isValidBulkAgentEmail(""))
|
|
}
|
|
|
|
func TestAgentNameFromEmail(t *testing.T) {
|
|
assert.Equal(t, "john", agentNameFromEmail("john@example.com"))
|
|
assert.Equal(t, "john.doe", agentNameFromEmail("john.doe@example.com"))
|
|
assert.Equal(t, "@example.com", agentNameFromEmail("@example.com"))
|
|
}
|
|
|
|
// === Conversation Finder Strategy tests ===
|
|
|
|
func TestStatusFilterStrategy_Name(t *testing.T) {
|
|
s := &StatusFilterStrategy{}
|
|
assert.Equal(t, "status", s.Name())
|
|
}
|
|
|
|
func TestStatusFilterStrategy_Apply(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t)
|
|
require.NoError(t, db.Create(&model.Conversation{AccountID: 1, InboxID: 1, ContactID: 1, ChannelType: "web_widget", Channel: "web_widget", Status: "open"}).Error)
|
|
require.NoError(t, db.Create(&model.Conversation{AccountID: 1, InboxID: 1, ContactID: 1, ChannelType: "web_widget", Channel: "web_widget", Status: "resolved"}).Error)
|
|
|
|
s := &StatusFilterStrategy{
|
|
BaseStrategy: NewBaseStrategy(FilterParams{Status: "open"}, 0, 1, false),
|
|
}
|
|
result := s.Apply(db.Model(&model.Conversation{}))
|
|
var count int64
|
|
require.NoError(t, result.Count(&count).Error)
|
|
assert.Equal(t, int64(1), count)
|
|
}
|
|
|
|
func TestStatusFilterStrategy_Apply_AllStatus(t *testing.T) {
|
|
db := newSimpleServiceTestDB(t)
|
|
require.NoError(t, db.Create(&model.Conversation{AccountID: 1, InboxID: 1, ContactID: 1, ChannelType: "web_widget", Channel: "web_widget", Status: "open"}).Error)
|
|
|
|
s := &StatusFilterStrategy{
|
|
BaseStrategy: NewBaseStrategy(FilterParams{Status: "all"}, 0, 1, false),
|
|
}
|
|
result := s.Apply(db.Model(&model.Conversation{}))
|
|
var count int64
|
|
require.NoError(t, result.Count(&count).Error)
|
|
assert.Equal(t, int64(1), count)
|
|
}
|
|
|
|
func TestAssigneeTypeFilterStrategy_Name(t *testing.T) {
|
|
s := &AssigneeTypeFilterStrategy{}
|
|
assert.Equal(t, "assignee_type", s.Name())
|
|
}
|
|
|
|
func TestSortByFilterStrategy_Name(t *testing.T) {
|
|
s := &SortByFilterStrategy{}
|
|
assert.Equal(t, "sort_by", s.Name())
|
|
}
|
|
|
|
func TestLabelsFilterStrategy_Name(t *testing.T) {
|
|
s := &LabelsFilterStrategy{}
|
|
assert.Equal(t, "labels", s.Name())
|
|
}
|
|
|
|
func TestInboxIDsFilterStrategy_Name(t *testing.T) {
|
|
s := &InboxIDsFilterStrategy{}
|
|
assert.Equal(t, "inbox_ids", s.Name())
|
|
}
|
|
|
|
func TestTagsFilterStrategy_Name(t *testing.T) {
|
|
s := &TagsFilterStrategy{}
|
|
assert.Equal(t, "tags", s.Name())
|
|
}
|
|
|
|
func TestConversationTypeFilterStrategy_Name(t *testing.T) {
|
|
s := &ConversationTypeFilterStrategy{}
|
|
assert.Equal(t, "conversation_type", s.Name())
|
|
}
|
|
|
|
func TestUpdatedWithinFilterStrategy_Name(t *testing.T) {
|
|
s := &UpdatedWithinFilterStrategy{}
|
|
assert.Equal(t, "updated_within", s.Name())
|
|
}
|
|
|
|
func TestTeamFilterStrategy_Name(t *testing.T) {
|
|
s := &TeamFilterStrategy{}
|
|
assert.Equal(t, "team", s.Name())
|
|
}
|
|
|
|
func TestPriorityFilterStrategy_Name(t *testing.T) {
|
|
s := &PriorityFilterStrategy{}
|
|
assert.Equal(t, "priority", s.Name())
|
|
}
|
|
|
|
func TestStrategyChain(t *testing.T) {
|
|
chain := NewStrategyChain()
|
|
chain.Add(&StatusFilterStrategy{}).Add(&InboxIDsFilterStrategy{})
|
|
assert.Len(t, chain.strategies, 2)
|
|
assert.Len(t, chain.Names(), 2)
|
|
}
|
|
|
|
func TestSplitAndTrimLabels(t *testing.T) {
|
|
result := splitAndTrimLabels("a, b ,c")
|
|
assert.Equal(t, []string{"a", "b", "c"}, result)
|
|
assert.Empty(t, splitAndTrimLabels(""))
|
|
}
|
|
|
|
func TestBuildDefaultStrategyChain(t *testing.T) {
|
|
base := NewBaseStrategy(FilterParams{Status: "open"}, 1, 1, false)
|
|
chain := buildDefaultStrategyChain(base)
|
|
assert.NotEmpty(t, chain.Names())
|
|
}
|
|
|
|
// === Campaign helper functions ===
|
|
|
|
func TestCampaignInboxIsOneOff(t *testing.T) {
|
|
assert.True(t, campaignInboxIsOneOff("sms"))
|
|
assert.False(t, campaignInboxIsOneOff("web_widget"))
|
|
}
|
|
|
|
func TestCampaignInboxIsOngoing(t *testing.T) {
|
|
assert.True(t, campaignInboxIsOngoing("web_widget"))
|
|
assert.False(t, campaignInboxIsOngoing("sms"))
|
|
}
|
|
|
|
func TestNormalizeCampaignInboxType(t *testing.T) {
|
|
assert.Equal(t, "webwidget", normalizeCampaignInboxType("web_widget"))
|
|
assert.Equal(t, "webwidget", normalizeCampaignInboxType("Channel::WebWidget"))
|
|
}
|
|
|
|
func TestRawJSONParamString(t *testing.T) {
|
|
assert.Equal(t, "", rawJSONParamString(nil))
|
|
assert.Equal(t, "test", rawJSONParamString([]byte(`"test"`)))
|
|
}
|
|
|
|
// === Assignment Policy helper functions ===
|
|
|
|
func TestAssignmentOrderToValue(t *testing.T) {
|
|
assert.Equal(t, 0, assignmentOrderToValue("round_robin"))
|
|
assert.Equal(t, 1, assignmentOrderToValue("balanced"))
|
|
assert.Equal(t, 0, assignmentOrderToValue("unknown"))
|
|
}
|
|
|
|
func TestAssignmentOrderFromValue(t *testing.T) {
|
|
assert.Equal(t, "round_robin", assignmentOrderFromValue(0))
|
|
assert.Equal(t, "balanced", assignmentOrderFromValue(1))
|
|
}
|
|
|
|
func TestConversationPriorityToValue(t *testing.T) {
|
|
assert.Equal(t, 0, conversationPriorityToValue("earliest_created"))
|
|
assert.Equal(t, 1, conversationPriorityToValue("longest_waiting"))
|
|
}
|
|
|
|
func TestConversationPriorityFromValue(t *testing.T) {
|
|
assert.Equal(t, "earliest_created", conversationPriorityFromValue(0))
|
|
assert.Equal(t, "longest_waiting", conversationPriorityFromValue(1))
|
|
}
|
|
|
|
func TestIsAssignmentPolicyNotFound(t *testing.T) {
|
|
assert.False(t, IsAssignmentPolicyNotFound(nil))
|
|
assert.False(t, IsAssignmentPolicyNotFound(nilErr("some error")))
|
|
}
|
|
|
|
// helper for creating simple errors
|
|
type stringError string
|
|
|
|
func (e stringError) Error() string { return string(e) }
|
|
func nilErr(msg string) error { return stringError(msg) }
|
|
|
|
// === Captain custom tool helpers ===
|
|
|
|
func TestCustomToolSlug(t *testing.T) {
|
|
assert.Equal(t, "custom_my_tool", customToolSlug("My Tool"))
|
|
assert.Equal(t, "custom_hello_world", customToolSlug("Hello, World!"))
|
|
}
|
|
|
|
func TestTruncateString(t *testing.T) {
|
|
assert.Equal(t, "abc", truncateString("abcdef", 3))
|
|
assert.Equal(t, "abcdef", truncateString("abcdef", 10))
|
|
}
|
|
|
|
func TestUniqueStrings(t *testing.T) {
|
|
result := uniqueStrings([]string{"a", "b", "a", "c", "b"})
|
|
assert.Equal(t, []string{"a", "b", "c"}, result)
|
|
}
|
|
|
|
func TestCustomToolFieldLabel(t *testing.T) {
|
|
assert.NotEmpty(t, customToolFieldLabel("name"))
|
|
assert.NotEmpty(t, customToolFieldLabel("unknown_field"))
|
|
}
|
|
|
|
func TestCaptainCustomToolValidationError_Error(t *testing.T) {
|
|
err := &CaptainCustomToolValidationError{Message: "test error"}
|
|
assert.Equal(t, "test error", err.Error())
|
|
}
|
|
|
|
// === UpdateAgentRequest JSON unmarshal ===
|
|
|
|
func TestUpdateAgentRequest_UnmarshalJSON(t *testing.T) {
|
|
var req UpdateAgentRequest
|
|
err := req.UnmarshalJSON([]byte(`{"name":"Test","auto_offline":true}`))
|
|
require.NoError(t, err)
|
|
assert.True(t, req.NameSet())
|
|
assert.True(t, req.AutoOfflineSet())
|
|
assert.False(t, req.CustomRoleIDSet())
|
|
}
|
|
|
|
func TestUpdateAgentRequest_NameSet(t *testing.T) {
|
|
req := UpdateAgentRequest{nameSet: true}
|
|
assert.True(t, req.NameSet())
|
|
}
|
|
|
|
func TestUpdateAgentRequest_AutoOfflineSet(t *testing.T) {
|
|
req := UpdateAgentRequest{autoOfflineSet: true}
|
|
assert.True(t, req.AutoOfflineSet())
|
|
}
|
|
|
|
func TestUpdateAgentRequest_CustomRoleIDSet(t *testing.T) {
|
|
req := UpdateAgentRequest{customRoleSet: true}
|
|
assert.True(t, req.CustomRoleIDSet())
|
|
}
|
|
|
|
// === Campaign UpdateCampaignRequest UnmarshalJSON ===
|
|
|
|
func TestUpdateCampaignRequest_UnmarshalJSON(t *testing.T) {
|
|
var req UpdateCampaignRequest
|
|
err := req.UnmarshalJSON([]byte(`{"inbox_id":1,"title":"Test","scheduled_at":"2024-01-01T00:00:00Z"}`))
|
|
require.NoError(t, err)
|
|
assert.True(t, req.InboxIDSet())
|
|
assert.True(t, req.ScheduledAtSet())
|
|
}
|
|
|
|
// === intersect/union/difference helpers ===
|
|
|
|
func TestIntersect(t *testing.T) {
|
|
result := intersect([]uint{1, 2, 3}, []uint{2, 3, 4})
|
|
assert.Equal(t, []uint{2, 3}, result)
|
|
}
|
|
|
|
func TestUnion(t *testing.T) {
|
|
result := union([]uint{1, 2}, []uint{2, 3})
|
|
assert.Equal(t, []uint{1, 2, 3}, result)
|
|
}
|
|
|
|
func TestDifference(t *testing.T) {
|
|
result := difference([]uint{1, 2, 3}, []uint{2})
|
|
assert.Equal(t, []uint{1, 3}, result)
|
|
}
|