Files
gochat/backend/internal/service/coverage18_test.go
T

2392 lines
76 KiB
Go

package service
import (
"bytes"
"context"
"errors"
"testing"
"github.com/gochat/gochat/internal/channel"
"github.com/gochat/gochat/internal/model"
channelmodel "github.com/gochat/gochat/internal/model/channel"
"github.com/gochat/gochat/internal/repository"
"github.com/gochat/gochat/internal/search"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
)
// ============================================================
// InboxService tests — targeting 0% methods
// ============================================================
func TestInboxService_Create_WebWidget_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Widget Inbox",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
assert.NotZero(t, inbox.ID)
assert.Equal(t, "web_widget", inbox.ChannelType)
assert.True(t, inbox.Enabled)
}
func TestInboxService_Create_API_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelAPI{})
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "API Inbox",
ChannelType: "api",
Enabled: true,
Channel: map[string]any{"webhook_url": "https://example.com/wh"},
})
require.NoError(t, err)
assert.NotZero(t, inbox.ID)
assert.Equal(t, "api", inbox.ChannelType)
assert.NotEmpty(t, inbox.Secret)
}
func TestInboxService_Create_Email_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Email Inbox",
ChannelType: "email",
Enabled: true,
Channel: map[string]any{"email": "test@example.com"},
})
require.NoError(t, err)
assert.Equal(t, "email", inbox.ChannelType)
}
func TestInboxService_Create_InvalidChannelType_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
_, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Bad",
ChannelType: "invalid_type",
})
require.Error(t, err)
}
func TestInboxService_Create_NameTooShort_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
_, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "A",
ChannelType: "web_widget",
})
require.Error(t, err)
}
func TestInboxService_Create_DefaultName_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
assert.Equal(t, "Website", inbox.Name)
}
func TestInboxService_Create_WithGreeting_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
greetingEnabled := true
greetingMsg := "Hello there!"
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Greeting Inbox",
ChannelType: "web_widget",
GreetingEnabled: &greetingEnabled,
GreetingMessage: &greetingMsg,
})
require.NoError(t, err)
assert.True(t, inbox.GreetingEnabled)
assert.Equal(t, "Hello there!", inbox.GreetingMessage)
}
func TestInboxService_Create_WithWorkingHours_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &model.WorkingHour{})
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "WH Inbox",
ChannelType: "web_widget",
Enabled: true,
WorkingHours: []repository.WorkingHourUpdateParam{
{DayOfWeek: 1, ClosedAllDay: false, OpenAllDay: true},
},
})
require.NoError(t, err)
assert.NotZero(t, inbox.ID)
}
func TestInboxService_GetByAccountAndID_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Test",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
got, err := svc.GetByAccountAndID(context.Background(), 1, inbox.ID)
require.NoError(t, err)
assert.Equal(t, inbox.ID, got.ID)
}
func TestInboxService_GetByAccountAndID_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
_, err := svc.GetByAccountAndID(context.Background(), 1, 99999)
require.Error(t, err)
}
func TestInboxService_Update_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Original",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
enabled := false
updated, err := svc.Update(context.Background(), 1, inbox.ID, UpdateInboxRequest{
Name: "Updated Name",
Enabled: &enabled,
})
require.NoError(t, err)
assert.Equal(t, "Updated Name", updated.Name)
}
func TestInboxService_Update_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
_, err := svc.Update(context.Background(), 1, 99999, UpdateInboxRequest{
Name: "X",
})
require.Error(t, err)
}
func TestInboxService_Update_WithChannel_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelAPI{})
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "API",
ChannelType: "api",
Enabled: true,
})
require.NoError(t, err)
updated, err := svc.Update(context.Background(), 1, inbox.ID, UpdateInboxRequest{
Channel: map[string]any{"webhook_url": "https://new.example.com/wh"},
})
require.NoError(t, err)
assert.Equal(t, "https://new.example.com/wh", updated.WebhookURL)
}
func TestInboxService_Delete_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Del",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
err = svc.Delete(context.Background(), inbox.ID)
require.NoError(t, err)
}
func TestInboxService_DeleteByAccount_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Del",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
err = svc.DeleteByAccount(context.Background(), 1, inbox.ID)
require.NoError(t, err)
}
func TestInboxService_DeleteByAccount_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
err := svc.DeleteByAccount(context.Background(), 1, 99999)
require.Error(t, err)
}
func TestInboxService_EnsureCanCreateInbox_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
err := svc.EnsureCanCreateInbox(context.Background(), 1)
require.NoError(t, err)
}
func TestInboxService_EnsureCanCreateInbox_LimitExceeded_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active", InboxLimit: 1}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
// Create one inbox to fill the limit
_, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "First",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
err = svc.EnsureCanCreateInbox(context.Background(), 1)
require.Error(t, err)
assert.True(t, IsInboxLimitExceeded(err))
}
func TestInboxService_EnsureCanCreateInbox_NilRepo_Cov18(t *testing.T) {
svc := NewInboxService(nil, nil, nil, nil, nil, nil, nil)
err := svc.EnsureCanCreateInbox(context.Background(), 1)
require.NoError(t, err) // nil repo → returns nil
}
func TestInboxService_BindChannel_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Bind",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
updated, err := svc.BindChannel(context.Background(), 1, inbox.ID, 42, map[string]any{"key": "value"})
require.NoError(t, err)
assert.Equal(t, uint(42), updated.ChannelID)
}
func TestInboxService_BindChannel_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
_, err := svc.BindChannel(context.Background(), 1, 99999, 42, nil)
require.Error(t, err)
}
func TestInboxService_CreateWebWidgetInbox_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateWebWidgetInbox(context.Background(), 1, CreateWebWidgetInboxRequest{
Name: "Widget",
WidgetColor: "#ff0000",
})
require.NoError(t, err)
assert.Equal(t, "web_widget", inbox.ChannelType)
assert.NotEmpty(t, inbox.ChannelConfig)
}
func TestInboxService_GetWebWidgetConfig_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateWebWidgetInbox(context.Background(), 1, CreateWebWidgetInboxRequest{
Name: "Widget",
WidgetColor: "#ff0000",
})
require.NoError(t, err)
config, err := svc.GetWebWidgetConfig(context.Background(), 1, inbox.ID)
require.NoError(t, err)
assert.Equal(t, "#ff0000", config.WidgetColor)
}
func TestInboxService_GetWebWidgetConfig_NotWidget_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelAPI{})
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "API",
ChannelType: "api",
Enabled: true,
})
require.NoError(t, err)
_, err = svc.GetWebWidgetConfig(context.Background(), 1, inbox.ID)
require.Error(t, err)
}
func TestInboxService_UpdateWebWidgetConfig_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateWebWidgetInbox(context.Background(), 1, CreateWebWidgetInboxRequest{
Name: "Widget",
})
require.NoError(t, err)
newColor := "#00ff00"
updated, err := svc.UpdateWebWidgetConfig(context.Background(), 1, inbox.ID, UpdateWebWidgetConfigRequest{
WidgetColor: &newColor,
})
require.NoError(t, err)
assert.NotZero(t, updated.ID)
}
func TestInboxService_CreateTelegramInbox_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateTelegramInbox(context.Background(), 1, CreateTelegramInboxRequest{
Name: "Telegram Bot",
BotToken: "123:abc",
})
require.NoError(t, err)
assert.Equal(t, "telegram", inbox.ChannelType)
}
func TestInboxService_GetTelegramInboxConfig_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateTelegramInbox(context.Background(), 1, CreateTelegramInboxRequest{
Name: "Telegram Bot",
BotToken: "123:abc",
})
require.NoError(t, err)
config, _, err := svc.GetTelegramInboxConfig(context.Background(), 1, inbox.ID)
require.NoError(t, err)
assert.Equal(t, "123:abc", config.BotToken)
}
func TestInboxService_UpdateTelegramInbox_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateTelegramInbox(context.Background(), 1, CreateTelegramInboxRequest{
Name: "Telegram Bot",
BotToken: "123:abc",
})
require.NoError(t, err)
newToken := "456:def"
updated, err := svc.UpdateTelegramInbox(context.Background(), 1, inbox.ID, UpdateTelegramInboxRequest{
BotToken: &newToken,
})
require.NoError(t, err)
_ = updated
}
func TestInboxService_DeleteTelegramInbox_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateTelegramInbox(context.Background(), 1, CreateTelegramInboxRequest{
Name: "Telegram Bot",
BotToken: "123:abc",
})
require.NoError(t, err)
err = svc.DeleteTelegramInbox(context.Background(), 1, inbox.ID)
require.NoError(t, err)
}
func TestInboxService_FindTelegramInboxByBotToken_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
_, err := svc.CreateTelegramInbox(context.Background(), 1, CreateTelegramInboxRequest{
Name: "Telegram Bot",
BotToken: "token123",
})
require.NoError(t, err)
inbox, err := svc.FindTelegramInboxByBotToken(context.Background(), "token123")
require.NoError(t, err)
assert.Equal(t, "telegram", inbox.ChannelType)
}
func TestInboxService_FindTelegramInboxByBotToken_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
_, err := svc.FindTelegramInboxByBotToken(context.Background(), "nonexistent")
require.Error(t, err)
}
func TestInboxService_UpdateTelegramConfig_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateTelegramInbox(context.Background(), 1, CreateTelegramInboxRequest{
Name: "Bot",
BotToken: "tok",
})
require.NoError(t, err)
updated, err := svc.UpdateTelegramConfig(context.Background(), 1, inbox.ID, TelegramInboxConfig{
BotToken: "newtok",
WelcomeMessage: "Welcome!",
})
require.NoError(t, err)
_ = updated
}
func TestInboxService_ReauthorizeTelegramInbox_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateTelegramInbox(context.Background(), 1, CreateTelegramInboxRequest{
Name: "Bot",
BotToken: "tok",
})
require.NoError(t, err)
_, err = svc.ReauthorizeTelegramInbox(context.Background(), 1, inbox.ID)
require.NoError(t, err)
}
func TestInboxService_CreateInstagramInbox_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelInstagram{})
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
igRepo := repository.NewChannelInstagramRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateInstagramInbox(context.Background(), 1, CreateInstagramInboxRequest{
Name: "IG Inbox",
InstagramAccountID: "123456",
PageAccessToken: "token",
ConnectedFBPageID: "page1",
}, igRepo)
require.NoError(t, err)
assert.Equal(t, "instagram", inbox.ChannelType)
assert.NotZero(t, inbox.ChannelID)
}
func TestInboxService_GetInstagramInboxConfig_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelInstagram{})
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
igRepo := repository.NewChannelInstagramRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateInstagramInbox(context.Background(), 1, CreateInstagramInboxRequest{
Name: "IG Inbox",
InstagramAccountID: "123456",
PageAccessToken: "token",
ConnectedFBPageID: "page1",
}, igRepo)
require.NoError(t, err)
config, _, err := svc.GetInstagramInboxConfig(context.Background(), 1, inbox.ID)
require.NoError(t, err)
assert.Equal(t, "123456", config.InstagramAccountID)
}
func TestInboxService_UpdateInstagramInbox_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelInstagram{})
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
igRepo := repository.NewChannelInstagramRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateInstagramInbox(context.Background(), 1, CreateInstagramInboxRequest{
Name: "IG Inbox",
InstagramAccountID: "123456",
PageAccessToken: "token",
ConnectedFBPageID: "page1",
}, igRepo)
require.NoError(t, err)
newName := "Updated IG"
updated, err := svc.UpdateInstagramInbox(context.Background(), 1, inbox.ID, UpdateInstagramInboxRequest{
Name: &newName,
})
require.NoError(t, err)
assert.Equal(t, "Updated IG", updated.Name)
}
func TestInboxService_DeleteInstagramInbox_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelInstagram{})
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
igRepo := repository.NewChannelInstagramRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateInstagramInbox(context.Background(), 1, CreateInstagramInboxRequest{
Name: "IG Inbox",
InstagramAccountID: "123456",
PageAccessToken: "token",
ConnectedFBPageID: "page1",
}, igRepo)
require.NoError(t, err)
err = svc.DeleteInstagramInbox(context.Background(), 1, inbox.ID, igRepo)
require.NoError(t, err)
}
func TestInboxService_CreateFacebookInbox_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelFacebook{})
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
fbRepo := repository.NewChannelFacebookRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.CreateFacebookInbox(context.Background(), 1, CreateFacebookInboxRequest{
Name: "FB Inbox",
PageID: "page123",
PageAccessToken: "token",
}, fbRepo)
require.NoError(t, err)
assert.Equal(t, "facebook", inbox.ChannelType)
}
func TestInboxService_DeleteAvatar_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Test",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
updated, err := svc.DeleteAvatar(context.Background(), 1, inbox.ID)
require.NoError(t, err)
assert.Empty(t, updated.AvatarURL)
}
func TestInboxService_DeleteAvatar_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
_, err := svc.DeleteAvatar(context.Background(), 1, 99999)
require.Error(t, err)
}
func TestInboxService_SetWorkerPool_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
svc.SetWorkerPool(nil) // should not panic
}
func TestInboxService_ListCampaigns_InboxNotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
_, err := svc.ListCampaigns(context.Background(), 1, 99999)
require.Error(t, err)
}
func TestInboxService_Health_NonWhatsApp_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Test",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
_, err = svc.Health(context.Background(), 1, inbox.ID)
require.Error(t, err)
}
func TestInboxService_SyncTemplates_NonWhatsApp_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Test",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
err = svc.SyncTemplates(context.Background(), 1, inbox.ID)
require.Error(t, err)
}
func TestInboxService_RegisterWebhook_NonWhatsApp_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
svc := NewInboxService(repo, nil, nil, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Test",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
err = svc.RegisterWebhook(context.Background(), 1, inbox.ID, RegisterWebhookRequest{
URL: "https://example.com/wh",
})
require.Error(t, err)
}
func TestInboxService_SetAgentBot_RemoveBot_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
agentBotInboxRepo := repository.NewAgentBotInboxRepo(db)
agentBotRepo := repository.NewAgentBotRepo(db)
svc := NewInboxService(repo, agentBotInboxRepo, agentBotRepo, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Test",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
_, err = svc.SetAgentBot(context.Background(), 1, inbox.ID, SetAgentBotRequest{})
require.NoError(t, err)
}
func TestInboxService_SetAgentBot_AssignBot_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
agentBotInboxRepo := repository.NewAgentBotInboxRepo(db)
agentBotRepo := repository.NewAgentBotRepo(db)
svc := NewInboxService(repo, agentBotInboxRepo, agentBotRepo, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Test",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
bot, err := NewAgentBotService(agentBotRepo).Create(context.Background(), CreateAgentBotRequest{
Name: "Test Bot",
})
require.NoError(t, err)
binding, err := svc.SetAgentBot(context.Background(), 1, inbox.ID, SetAgentBotRequest{
AgentBotID: &bot.ID,
})
require.NoError(t, err)
assert.NotNil(t, binding)
}
func TestInboxService_GetAgentBot_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
agentBotInboxRepo := repository.NewAgentBotInboxRepo(db)
agentBotRepo := repository.NewAgentBotRepo(db)
svc := NewInboxService(repo, agentBotInboxRepo, agentBotRepo, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Test",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
// No bot assigned → returns nil, nil
bot, err := svc.GetAgentBot(context.Background(), 1, inbox.ID)
require.NoError(t, err)
assert.Nil(t, bot)
}
func TestInboxService_GetAgentBot_WithBot_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewInboxRepo(db)
agentBotInboxRepo := repository.NewAgentBotInboxRepo(db)
agentBotRepo := repository.NewAgentBotRepo(db)
svc := NewInboxService(repo, agentBotInboxRepo, agentBotRepo, nil, nil, nil, nil)
inbox, err := svc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Test",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
bot, err := NewAgentBotService(agentBotRepo).Create(context.Background(), CreateAgentBotRequest{
Name: "Bot",
})
require.NoError(t, err)
_, err = svc.SetAgentBot(context.Background(), 1, inbox.ID, SetAgentBotRequest{
AgentBotID: &bot.ID,
})
require.NoError(t, err)
gotBot, err := svc.GetAgentBot(context.Background(), 1, inbox.ID)
require.NoError(t, err)
assert.NotNil(t, gotBot)
}
// ============================================================
// ConversationService tests — targeting 0% methods
// ============================================================
func setupConvServiceCov18(t *testing.T) (*ConversationService, *gorm.DB) {
t.Helper()
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
require.NoError(t, db.Create(&model.Inbox{AccountID: 1, Name: "Inbox", ChannelType: "web_widget", Enabled: true}).Error)
require.NoError(t, db.Create(&model.Contact{AccountID: 1, Name: "Contact"}).Error)
convRepo := repository.NewConversationRepo(db)
msgRepo := repository.NewMessageRepo(db)
dispatcher := channel.NewDispatcher()
svc := NewConversationService(convRepo, msgRepo, dispatcher, nil, nil, nil, nil)
return svc, db
}
func TestConversationService_Create_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
assert.NotZero(t, conv.ID)
assert.Equal(t, "open", conv.Status)
}
func TestConversationService_Create_WithMessage_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
MessageContent: "Hello!",
MessageType: "outgoing",
})
require.NoError(t, err)
assert.NotZero(t, conv.ID)
}
func TestConversationService_Create_WithPriority_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
Priority: "urgent",
})
require.NoError(t, err)
assert.Equal(t, "urgent", conv.Priority)
}
func TestConversationService_Create_WithStatus_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
Status: "pending",
})
require.NoError(t, err)
assert.Equal(t, "pending", conv.Status)
}
func TestConversationService_GetByID_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
got, err := svc.GetByID(context.Background(), conv.ID)
require.NoError(t, err)
assert.Equal(t, conv.ID, got.ID)
}
func TestConversationService_GetByID_NotFound_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
_, err := svc.GetByID(context.Background(), 99999)
require.Error(t, err)
}
func TestConversationService_GetByAccountAndID_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
got, err := svc.GetByAccountAndID(context.Background(), 1, conv.ID)
require.NoError(t, err)
assert.Equal(t, conv.ID, got.ID)
}
func TestConversationService_GetByAccountAndID_NotFound_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
_, err := svc.GetByAccountAndID(context.Background(), 1, 99999)
require.Error(t, err)
}
func TestConversationService_ListByAccount_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
_, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
convs, total, err := svc.ListByAccount(context.Background(), 1, 0, 10)
require.NoError(t, err)
assert.Equal(t, int64(1), total)
assert.Len(t, convs, 1)
}
func TestConversationService_ListByInbox_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
_, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
convs, total, err := svc.ListByInbox(context.Background(), 1, 1, 0, 10)
require.NoError(t, err)
assert.Equal(t, int64(1), total)
assert.Len(t, convs, 1)
}
func TestConversationService_ListByStatus_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
_, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
Status: "open",
})
require.NoError(t, err)
convs, total, err := svc.ListByStatus(context.Background(), 1, "open", 0, 10)
require.NoError(t, err)
assert.Equal(t, int64(1), total)
assert.Len(t, convs, 1)
}
func TestConversationService_Update_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
updated, err := svc.Update(context.Background(), 1, conv.ID, UpdateConversationRequest{
Status: "resolved",
})
require.NoError(t, err)
assert.Equal(t, "resolved", updated.Status)
}
func TestConversationService_Update_Priority_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
updated, err := svc.Update(context.Background(), 1, conv.ID, UpdateConversationRequest{
Priority: "high",
})
require.NoError(t, err)
assert.Equal(t, "high", updated.Priority)
}
func TestConversationService_Update_NotFound_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
_, err := svc.Update(context.Background(), 1, 99999, UpdateConversationRequest{
Status: "resolved",
})
require.Error(t, err)
}
func TestConversationService_Delete_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
err = svc.Delete(context.Background(), 1, conv.ID)
require.NoError(t, err)
}
func TestConversationService_Delete_NotFound_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
err := svc.Delete(context.Background(), 1, 99999)
require.Error(t, err)
}
func TestConversationService_Mute_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
muted, err := svc.Mute(context.Background(), 1, conv.ID)
require.NoError(t, err)
assert.True(t, muted.Muted)
assert.Equal(t, "resolved", muted.Status)
}
func TestConversationService_Mute_NotFound_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
_, err := svc.Mute(context.Background(), 1, 99999)
require.Error(t, err)
}
func TestConversationService_Unmute_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
_, err = svc.Mute(context.Background(), 1, conv.ID)
require.NoError(t, err)
unmuted, err := svc.Unmute(context.Background(), 1, conv.ID)
require.NoError(t, err)
assert.False(t, unmuted.Muted)
}
func TestConversationService_Unmute_NotFound_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
_, err := svc.Unmute(context.Background(), 1, 99999)
require.Error(t, err)
}
func TestConversationService_ToggleStatus_OpenToResolved_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
updated, err := svc.ToggleStatus(context.Background(), 1, conv.ID, ToggleStatusRequest{
Status: "resolved",
})
require.NoError(t, err)
assert.Equal(t, "resolved", updated.Status)
}
func TestConversationService_ToggleStatus_ResolvedToOpen_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
Status: "resolved",
})
require.NoError(t, err)
updated, err := svc.ToggleStatus(context.Background(), 1, conv.ID, ToggleStatusRequest{
Status: "open",
})
require.NoError(t, err)
assert.Equal(t, "open", updated.Status)
}
func TestConversationService_ToggleStatus_EmptyStatus_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
updated, err := svc.ToggleStatus(context.Background(), 1, conv.ID, ToggleStatusRequest{})
require.NoError(t, err)
assert.Equal(t, "resolved", updated.Status) // open → resolved
}
func TestConversationService_ToggleStatus_NotFound_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
_, err := svc.ToggleStatus(context.Background(), 1, 99999, ToggleStatusRequest{
Status: "resolved",
})
require.Error(t, err)
}
func TestConversationService_ToggleStatus_Snoozed_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
until := int64(9999999999)
updated, err := svc.ToggleStatus(context.Background(), 1, conv.ID, ToggleStatusRequest{
Status: "snoozed",
SnoozedUntil: &until,
})
require.NoError(t, err)
assert.Equal(t, "snoozed", updated.Status)
}
func TestConversationService_UpdatePriority_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
updated, err := svc.UpdatePriority(context.Background(), 1, conv.ID, "urgent")
require.NoError(t, err)
assert.Equal(t, "urgent", updated.Priority)
}
func TestConversationService_UpdatePriority_Empty_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
updated, err := svc.UpdatePriority(context.Background(), 1, conv.ID, "")
require.NoError(t, err)
assert.Equal(t, "none", updated.Priority)
}
func TestConversationService_UpdatePriority_Invalid_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
_, err = svc.UpdatePriority(context.Background(), 1, conv.ID, "invalid")
require.Error(t, err)
}
func TestConversationService_UpdatePriority_NotFound_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
_, err := svc.UpdatePriority(context.Background(), 1, 99999, "urgent")
require.Error(t, err)
}
func TestConversationService_UpdateLabels_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
updated, err := svc.UpdateLabels(context.Background(), 1, conv.ID, []string{"support", "bug"})
require.NoError(t, err)
assert.Contains(t, updated.Labels, "support")
}
func TestConversationService_UpdateLabels_NotFound_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
_, err := svc.UpdateLabels(context.Background(), 1, 99999, []string{"label"})
require.Error(t, err)
}
func TestConversationService_UnassignAgent_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
// Without dispatcher, accountUserRepo, inboxMemberSvc — unassign (id=0) should work
updated, err := svc.UnassignAgent(context.Background(), 1, conv.ID)
require.NoError(t, err)
_ = updated
}
func TestConversationService_AssignAgentBot_RemoveBot_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
_, _, err = svc.AssignAgentBot(context.Background(), 1, conv.ID, 0)
require.NoError(t, err)
}
func TestConversationService_ListMessages_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
msgs, total, err := svc.ListMessages(context.Background(), conv.ID, 0, 10)
require.NoError(t, err)
assert.Equal(t, int64(0), total)
assert.Empty(t, msgs)
}
func TestConversationService_ListRecentByContact_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
_, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
convs, err := svc.ListRecentByContact(context.Background(), 1, 1, nil, 10)
require.NoError(t, err)
assert.Len(t, convs, 1)
}
func TestConversationService_ListUnassigned_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
_, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
convs, total, err := svc.ListUnassigned(context.Background(), 1, 0, 10)
require.NoError(t, err)
assert.Equal(t, int64(1), total)
assert.Len(t, convs, 1)
}
func TestConversationService_DB_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
assert.NotNil(t, svc.DB())
}
func TestConversationService_DB_Nil_Cov18(t *testing.T) {
var svc *ConversationService
assert.Nil(t, svc.DB())
}
func TestConversationService_SetSearchIndexer_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
svc.SetSearchIndexer(nil) // should not panic
}
func TestConversationService_SetAppliedSlaService_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
svc.SetAppliedSlaService(nil) // should not panic
}
func TestConversationService_SetTranscriptDeliverer_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
svc.SetTranscriptDeliverer(nil) // should not panic
}
func TestConversationService_GetByAccountAndDisplayIDOrID_Cov18(t *testing.T) {
svc, _ := setupConvServiceCov18(t)
conv, err := svc.Create(context.Background(), 1, CreateConversationRequest{
InboxID: 1,
ContactID: 1,
})
require.NoError(t, err)
got, err := svc.GetByAccountAndDisplayIDOrID(context.Background(), 1, conv.ID)
require.NoError(t, err)
assert.Equal(t, conv.ID, got.ID)
}
// ============================================================
// WidgetService tests — targeting 0% methods
// ============================================================
func setupWidgetServiceCov18(t *testing.T) (*WidgetService, *gorm.DB) {
t.Helper()
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
inboxRepo := repository.NewInboxRepo(db)
contactRepo := repository.NewContactRepo(db)
contactInboxRepo := repository.NewContactInboxRepo(db)
convRepo := repository.NewConversationRepo(db)
msgRepo := repository.NewMessageRepo(db)
// Create a web_widget inbox with website_token in channel_config
inboxSvc := NewInboxService(inboxRepo, nil, nil, nil, nil, nil, nil)
inbox, err := inboxSvc.Create(context.Background(), 1, CreateInboxRequest{
Name: "Widget",
ChannelType: "web_widget",
Enabled: true,
})
require.NoError(t, err)
_ = inbox
svc := NewWidgetService(inboxRepo, contactRepo, contactInboxRepo, convRepo, msgRepo,
nil, nil, nil, nil, nil, nil, nil, nil)
return svc, db
}
func TestWidgetService_SetWorkerPool_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
svc.SetWorkerPool(nil) // should not panic
}
func TestWidgetService_SetTranscriptDeliverer_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
svc.SetTranscriptDeliverer(nil) // should not panic
}
func TestWidgetService_SetDispatcher_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
svc.SetDispatcher(nil) // should not panic
}
func TestWidgetService_Init_NoToken_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
_, err := svc.Init(context.Background(), WidgetInitRequest{})
require.Error(t, err)
}
func TestWidgetService_Init_InvalidToken_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
_, err := svc.Init(context.Background(), WidgetInitRequest{
WebsiteToken: "invalid_token",
})
require.Error(t, err)
}
func TestWidgetService_Init_ValidToken_Cov18(t *testing.T) {
svc, db := setupWidgetServiceCov18(t)
// Find the inbox we created and extract website_token from channel_config
var inbox model.Inbox
require.NoError(t, db.First(&inbox).Error)
config, err := ParseWebWidgetConfig(inbox.ChannelConfig)
require.NoError(t, err)
require.NotEmpty(t, config.WebsiteToken)
resp, err := svc.Init(context.Background(), WidgetInitRequest{
WebsiteToken: config.WebsiteToken,
})
require.NoError(t, err)
assert.NotEmpty(t, resp.WidgetToken)
assert.NotZero(t, resp.ContactID)
assert.Equal(t, inbox.ID, resp.InboxID)
}
func TestWidgetService_Init_WithContactInfo_Cov18(t *testing.T) {
svc, db := setupWidgetServiceCov18(t)
var inbox model.Inbox
require.NoError(t, db.First(&inbox).Error)
config, err := ParseWebWidgetConfig(inbox.ChannelConfig)
require.NoError(t, err)
resp, err := svc.Init(context.Background(), WidgetInitRequest{
WebsiteToken: config.WebsiteToken,
ContactName: "John",
ContactEmail: "john@example.com",
})
require.NoError(t, err)
assert.Equal(t, "John", resp.Contact.Name)
}
func TestWidgetService_SendMessage_NoToken_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
_, err := svc.SendMessage(context.Background(), WidgetSendMessageRequest{
Content: "Hello",
})
require.Error(t, err)
}
func TestWidgetService_SendMessage_EmptyContent_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
_, err := svc.SendMessage(context.Background(), WidgetSendMessageRequest{
WidgetToken: "token",
})
require.Error(t, err)
}
func TestWidgetService_SendMessage_ContentTooLong_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
longContent := make([]rune, widgetMessageContentLimit+1)
for i := range longContent {
longContent[i] = 'x'
}
_, err := svc.SendMessage(context.Background(), WidgetSendMessageRequest{
WidgetToken: "token",
Content: string(longContent),
})
require.Error(t, err)
assert.True(t, errors.Is(err, ErrWidgetMessageContentTooLong))
}
func TestWidgetService_SendMessage_InvalidToken_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
_, err := svc.SendMessage(context.Background(), WidgetSendMessageRequest{
WidgetToken: "invalid",
Content: "Hello",
})
require.Error(t, err)
}
func TestWidgetService_SendMessage_Valid_Cov18(t *testing.T) {
svc, db := setupWidgetServiceCov18(t)
var inbox model.Inbox
require.NoError(t, db.First(&inbox).Error)
config, err := ParseWebWidgetConfig(inbox.ChannelConfig)
require.NoError(t, err)
resp, err := svc.Init(context.Background(), WidgetInitRequest{
WebsiteToken: config.WebsiteToken,
})
require.NoError(t, err)
msgResp, err := svc.SendMessage(context.Background(), WidgetSendMessageRequest{
WidgetToken: resp.WidgetToken,
Content: "Hello World",
})
require.NoError(t, err)
assert.NotZero(t, msgResp.ConversationID)
assert.Equal(t, "Hello World", msgResp.Message.Content)
}
func TestWidgetService_GetConversations_InvalidToken_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
_, err := svc.GetConversations(context.Background(), "invalid")
require.Error(t, err)
}
func TestWidgetService_GetConversations_Valid_Cov18(t *testing.T) {
svc, db := setupWidgetServiceCov18(t)
var inbox model.Inbox
require.NoError(t, db.First(&inbox).Error)
config, err := ParseWebWidgetConfig(inbox.ChannelConfig)
require.NoError(t, err)
resp, err := svc.Init(context.Background(), WidgetInitRequest{
WebsiteToken: config.WebsiteToken,
})
require.NoError(t, err)
// Send a message to create a conversation
_, err = svc.SendMessage(context.Background(), WidgetSendMessageRequest{
WidgetToken: resp.WidgetToken,
Content: "Test",
})
require.NoError(t, err)
convs, err := svc.GetConversations(context.Background(), resp.WidgetToken)
require.NoError(t, err)
assert.NotEmpty(t, convs)
}
func TestWidgetService_GetLatestConversation_InvalidToken_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
_, err := svc.GetLatestConversation(context.Background(), "invalid")
require.Error(t, err)
}
func TestWidgetService_GetLatestConversation_NoConversation_Cov18(t *testing.T) {
svc, db := setupWidgetServiceCov18(t)
var inbox model.Inbox
require.NoError(t, db.First(&inbox).Error)
config, err := ParseWebWidgetConfig(inbox.ChannelConfig)
require.NoError(t, err)
resp, err := svc.Init(context.Background(), WidgetInitRequest{
WebsiteToken: config.WebsiteToken,
})
require.NoError(t, err)
_, err = svc.GetLatestConversation(context.Background(), resp.WidgetToken)
require.Error(t, err)
assert.True(t, errors.Is(err, ErrWidgetConversationNotFound))
}
func TestWidgetService_GetLatestConversation_Valid_Cov18(t *testing.T) {
svc, db := setupWidgetServiceCov18(t)
var inbox model.Inbox
require.NoError(t, db.First(&inbox).Error)
config, err := ParseWebWidgetConfig(inbox.ChannelConfig)
require.NoError(t, err)
resp, err := svc.Init(context.Background(), WidgetInitRequest{
WebsiteToken: config.WebsiteToken,
})
require.NoError(t, err)
_, err = svc.SendMessage(context.Background(), WidgetSendMessageRequest{
WidgetToken: resp.WidgetToken,
Content: "Test",
})
require.NoError(t, err)
conv, err := svc.GetLatestConversation(context.Background(), resp.WidgetToken)
require.NoError(t, err)
assert.NotZero(t, conv.ID)
}
func TestWidgetService_GetConversation_InvalidToken_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
_, err := svc.GetConversation(context.Background(), "invalid", 1)
require.Error(t, err)
}
func TestWidgetService_GetInboxMembers_NoMembers_Cov18(t *testing.T) {
svc, db := setupWidgetServiceCov18(t)
var inbox model.Inbox
require.NoError(t, db.First(&inbox).Error)
config, err := ParseWebWidgetConfig(inbox.ChannelConfig)
require.NoError(t, err)
members, err := svc.GetInboxMembersByWebsiteToken(context.Background(), config.WebsiteToken)
require.NoError(t, err)
assert.Empty(t, members)
}
func TestWidgetService_GetCampaigns_NoCampaigns_Cov18(t *testing.T) {
svc, db := setupWidgetServiceCov18(t)
var inbox model.Inbox
require.NoError(t, db.First(&inbox).Error)
config, err := ParseWebWidgetConfig(inbox.ChannelConfig)
require.NoError(t, err)
campaigns, err := svc.GetCampaignsByWebsiteToken(context.Background(), config.WebsiteToken)
require.NoError(t, err)
assert.Empty(t, campaigns)
}
func TestWidgetService_TrackEvent_NoToken_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
err := svc.TrackEvent(context.Background(), "", "token", "event", nil)
require.Error(t, err)
}
func TestWidgetService_TrackEvent_NoName_Cov18(t *testing.T) {
svc, db := setupWidgetServiceCov18(t)
var inbox model.Inbox
require.NoError(t, db.First(&inbox).Error)
config, err := ParseWebWidgetConfig(inbox.ChannelConfig)
require.NoError(t, err)
err = svc.TrackEvent(context.Background(), config.WebsiteToken, "token", "", nil)
require.Error(t, err)
}
func TestWidgetService_AddLabel_EmptyLabel_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
err := svc.AddLabelToLatestConversation(context.Background(), "token", "")
require.NoError(t, err) // empty label → no-op
}
func TestWidgetService_RemoveLabel_EmptyLabel_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
err := svc.RemoveLabelFromLatestConversation(context.Background(), "token", "")
require.NoError(t, err) // empty label → no-op
}
func TestWidgetService_PublicGetInbox_InvalidIdentifier_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
_, _, err := svc.PublicGetInbox(context.Background(), "nonexistent")
require.Error(t, err)
}
func TestWidgetService_PublicCreateContact_InvalidIdentifier_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
_, err := svc.PublicCreateContact(context.Background(), "nonexistent", PublicContactRequest{})
require.Error(t, err)
}
func TestWidgetService_PublicGetContact_InvalidIdentifier_Cov18(t *testing.T) {
svc, _ := setupWidgetServiceCov18(t)
_, err := svc.PublicGetContact(context.Background(), "nonexistent", "source")
require.Error(t, err)
}
// ============================================================
// ContactService tests — targeting 0% methods
// ============================================================
func setupContactServiceCov18(t *testing.T) (*ContactService, *gorm.DB) {
t.Helper()
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
repo := repository.NewContactRepo(db)
contactInboxRepo := repository.NewContactInboxRepo(db)
noteRepo := repository.NewNoteRepo(db)
contactInboxSvc := NewContactInboxService(contactInboxRepo)
svc := NewContactService(repo, contactInboxSvc, noteRepo)
return svc, db
}
func TestContactService_Create_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
contact, err := svc.Create(context.Background(), 1, CreateContactRequest{
Name: "John Doe",
Email: "john@example.com",
})
require.NoError(t, err)
assert.NotZero(t, contact.ID)
assert.Equal(t, "John Doe", contact.Name)
}
func TestContactService_Create_WithInbox_Cov18(t *testing.T) {
svc, db := setupContactServiceCov18(t)
require.NoError(t, db.Create(&model.Inbox{AccountID: 1, Name: "Inbox", ChannelType: "web_widget", Enabled: true}).Error)
inboxID := uint(1)
contact, err := svc.Create(context.Background(), 1, CreateContactRequest{
Name: "John",
Email: "john@test.com",
InboxID: &inboxID,
})
require.NoError(t, err)
assert.NotZero(t, contact.ID)
}
func TestContactService_Create_ValidationError_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
_, err := svc.Create(context.Background(), 1, CreateContactRequest{
Name: "", // required
})
require.Error(t, err)
}
func TestContactService_GetByID_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
contact, err := svc.Create(context.Background(), 1, CreateContactRequest{
Name: "John",
})
require.NoError(t, err)
got, err := svc.GetByID(context.Background(), contact.ID)
require.NoError(t, err)
assert.Equal(t, contact.ID, got.ID)
}
func TestContactService_GetByID_NotFound_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
_, err := svc.GetByID(context.Background(), 99999)
require.Error(t, err)
}
func TestContactService_GetByAccountAndID_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
contact, err := svc.Create(context.Background(), 1, CreateContactRequest{
Name: "John",
})
require.NoError(t, err)
got, err := svc.GetByAccountAndID(context.Background(), 1, contact.ID)
require.NoError(t, err)
assert.Equal(t, contact.ID, got.ID)
}
func TestContactService_GetByAccountAndID_NotFound_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
_, err := svc.GetByAccountAndID(context.Background(), 1, 99999)
require.Error(t, err)
}
func TestContactService_ListByAccount_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
_, err := svc.Create(context.Background(), 1, CreateContactRequest{Name: "C1", Email: "c1@test.com"})
require.NoError(t, err)
_, err = svc.Create(context.Background(), 1, CreateContactRequest{Name: "C2", Email: "c2@test.com"})
require.NoError(t, err)
contacts, total, err := svc.ListByAccount(context.Background(), 1, 0, 10, "")
require.NoError(t, err)
assert.Equal(t, int64(2), total)
assert.Len(t, contacts, 2)
}
func TestContactService_Update_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
contact, err := svc.Create(context.Background(), 1, CreateContactRequest{
Name: "Original",
})
require.NoError(t, err)
updated, err := svc.Update(context.Background(), 1, contact.ID, UpdateContactRequest{
Name: "Updated",
Email: "updated@example.com",
})
require.NoError(t, err)
assert.Equal(t, "Updated", updated.Name)
assert.Equal(t, "updated@example.com", updated.Email)
}
func TestContactService_Update_NotFound_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
_, err := svc.Update(context.Background(), 1, 99999, UpdateContactRequest{
Name: "X",
})
require.Error(t, err)
}
func TestContactService_Delete_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
contact, err := svc.Create(context.Background(), 1, CreateContactRequest{
Name: "Delete Me",
})
require.NoError(t, err)
err = svc.Delete(context.Background(), 1, contact.ID)
require.NoError(t, err)
}
func TestContactService_Delete_NotFound_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
err := svc.Delete(context.Background(), 1, 99999)
require.Error(t, err)
}
func TestContactService_Ready_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
assert.True(t, svc.Ready())
}
func TestContactService_Ready_Nil_Cov18(t *testing.T) {
var svc *ContactService
assert.False(t, svc.Ready())
}
func TestContactService_DB_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
assert.NotNil(t, svc.DB())
}
func TestContactService_DB_Nil_Cov18(t *testing.T) {
var svc *ContactService
assert.Nil(t, svc.DB())
}
func TestContactService_Search_EmptyQuery_Cov18(t *testing.T) {
t.Skip("SQLite search issue")
svc, _ := setupContactServiceCov18(t)
_, err := svc.Create(context.Background(), 1, CreateContactRequest{Name: "C1"})
require.NoError(t, err)
contacts, total, err := svc.Search(context.Background(), 1, "", 0, 10, "", search.SearchModeILike)
require.NoError(t, err)
assert.Equal(t, int64(1), total)
assert.Len(t, contacts, 1)
}
func TestContactService_CreateNote_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
contact, err := svc.Create(context.Background(), 1, CreateContactRequest{Name: "C1"})
require.NoError(t, err)
note, err := svc.CreateNote(context.Background(), 1, contact.ID, 1, CreateNoteRequest{
Content: "Test note",
})
require.NoError(t, err)
assert.NotZero(t, note.ID)
assert.Equal(t, "Test note", note.Content)
}
func TestContactService_CreateNote_ContactNotFound_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
_, err := svc.CreateNote(context.Background(), 1, 99999, 1, CreateNoteRequest{
Content: "Test",
})
require.Error(t, err)
}
func TestContactService_ListNotes_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
contact, err := svc.Create(context.Background(), 1, CreateContactRequest{Name: "C1"})
require.NoError(t, err)
_, err = svc.CreateNote(context.Background(), 1, contact.ID, 1, CreateNoteRequest{
Content: "Note 1",
})
require.NoError(t, err)
notes, err := svc.ListNotes(context.Background(), 1, contact.ID)
require.NoError(t, err)
assert.Len(t, notes, 1)
}
func TestContactService_ListNotes_ContactNotFound_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
_, err := svc.ListNotes(context.Background(), 1, 99999)
require.Error(t, err)
}
func TestContactService_UpdateNote_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
contact, err := svc.Create(context.Background(), 1, CreateContactRequest{Name: "C1"})
require.NoError(t, err)
note, err := svc.CreateNote(context.Background(), 1, contact.ID, 1, CreateNoteRequest{
Content: "Original",
})
require.NoError(t, err)
updated, err := svc.UpdateNote(context.Background(), 1, contact.ID, note.ID, CreateNoteRequest{
Content: "Updated",
})
require.NoError(t, err)
assert.Equal(t, "Updated", updated.Content)
}
func TestContactService_DeleteNote_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
contact, err := svc.Create(context.Background(), 1, CreateContactRequest{Name: "C1"})
require.NoError(t, err)
note, err := svc.CreateNote(context.Background(), 1, contact.ID, 1, CreateNoteRequest{
Content: "Delete me",
})
require.NoError(t, err)
err = svc.DeleteNote(context.Background(), 1, contact.ID, note.ID)
require.NoError(t, err)
}
func TestContactService_ExportCSV_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
_, err := svc.Create(context.Background(), 1, CreateContactRequest{
Name: "Export",
Email: "export@test.com",
})
require.NoError(t, err)
var buf bytes.Buffer
err = svc.ExportCSV(context.Background(), 1, &buf)
require.NoError(t, err)
assert.NotEmpty(t, buf.Bytes())
}
func TestContactService_SetSearchIndexer_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
svc.SetSearchIndexer(nil) // should not panic
}
func TestContactService_SetSearchReader_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
svc.SetSearchReader(nil) // should not panic
}
func TestContactService_SetContactExportMailer_Cov18(t *testing.T) {
svc, _ := setupContactServiceCov18(t)
svc.SetContactExportMailer(nil) // should not panic
}
// ============================================================
// AccountService tests — targeting 0% methods
// ============================================================
func TestAccountService_GetByID_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
svc := NewAccountService(repository.NewAccountRepo(db))
account, err := svc.GetByID(context.Background(), 1)
require.NoError(t, err)
assert.Equal(t, "Test", account.Name)
}
func TestAccountService_GetByID_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
svc := NewAccountService(repository.NewAccountRepo(db))
_, err := svc.GetByID(context.Background(), 99999)
require.Error(t, err)
}
func TestAccountService_DB_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
svc := NewAccountService(repository.NewAccountRepo(db))
assert.NotNil(t, svc.DB())
}
func TestAccountService_DB_Nil_Cov18(t *testing.T) {
var svc *AccountService
assert.Nil(t, svc.DB())
}
func TestAccountService_Create_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.User{Name: "User"}).Error)
svc := NewAccountService(repository.NewAccountRepo(db))
account, err := svc.Create(context.Background(), 1, CreateAccountRequest{
Name: "New Account",
})
require.NoError(t, err)
assert.NotZero(t, account.ID)
assert.Equal(t, "New Account", account.Name)
}
func TestAccountService_Create_NoName_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
svc := NewAccountService(repository.NewAccountRepo(db))
_, err := svc.Create(context.Background(), 1, CreateAccountRequest{})
require.Error(t, err)
}
func TestAccountService_Update_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
svc := NewAccountService(repository.NewAccountRepo(db))
updated, err := svc.Update(context.Background(), 1, UpdateAccountRequest{
Name: "Updated Account",
})
require.NoError(t, err)
assert.Equal(t, "Updated Account", updated.Name)
}
func TestAccountService_Update_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
svc := NewAccountService(repository.NewAccountRepo(db))
_, err := svc.Update(context.Background(), 99999, UpdateAccountRequest{
Name: "X",
})
require.Error(t, err)
}
func TestAccountService_Delete_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
svc := NewAccountService(repository.NewAccountRepo(db))
err := svc.Delete(context.Background(), 1)
require.NoError(t, err)
}
func TestAccountService_ListByUser_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.User{Name: "User"}).Error)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
require.NoError(t, db.Create(&model.AccountUser{AccountID: 1, UserID: 1, Role: "administrator"}).Error)
svc := NewAccountService(repository.NewAccountRepo(db))
accounts, total, err := svc.ListByUser(context.Background(), 1, 0, 10)
require.NoError(t, err)
assert.Equal(t, int64(1), total)
assert.Len(t, accounts, 1)
}
func TestAccountService_HelpCenterGenerationStatus_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
require.NoError(t, db.Create(&model.Account{Name: "Test", Status: "active"}).Error)
svc := NewAccountService(repository.NewAccountRepo(db))
status, err := svc.HelpCenterGenerationStatus(context.Background(), 1)
require.NoError(t, err)
assert.NotNil(t, status)
}
func TestAccountService_SetWorkerPool_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
svc := NewAccountService(repository.NewAccountRepo(db))
svc.SetWorkerPool(nil) // should not panic
}
// ============================================================
// WhatsAppCallService tests — targeting 0% methods
// ============================================================
func TestWhatsAppCallService_CreateFromRequest_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &model.WhatsAppCall{})
repo := repository.NewWhatsAppCallRepo(db)
svc := NewWhatsAppCallService(repo)
call, err := svc.CreateFromRequest(context.Background(), &WhatsAppCallCreateRequest{
CallID: "call_123",
InboxID: 1,
ConversationID: 1,
CallStatus: "ringing",
})
require.NoError(t, err)
assert.NotZero(t, call.ID)
assert.Equal(t, "call_123", call.CallID)
}
func TestWhatsAppCallService_CreateFromRequest_InvalidStatus_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &model.WhatsAppCall{})
repo := repository.NewWhatsAppCallRepo(db)
svc := NewWhatsAppCallService(repo)
_, err := svc.CreateFromRequest(context.Background(), &WhatsAppCallCreateRequest{
CallID: "call_123",
CallStatus: "invalid",
})
require.Error(t, err)
}
func TestWhatsAppCallService_GetByCallID_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &model.WhatsAppCall{})
repo := repository.NewWhatsAppCallRepo(db)
svc := NewWhatsAppCallService(repo)
_, err := svc.CreateFromRequest(context.Background(), &WhatsAppCallCreateRequest{
CallID: "call_123",
InboxID: 1,
ConversationID: 1,
CallStatus: "ringing",
})
require.NoError(t, err)
call, err := svc.GetByCallID(context.Background(), "call_123")
require.NoError(t, err)
assert.Equal(t, "call_123", call.CallID)
}
func TestWhatsAppCallService_GetByCallID_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &model.WhatsAppCall{})
repo := repository.NewWhatsAppCallRepo(db)
svc := NewWhatsAppCallService(repo)
_, err := svc.GetByCallID(context.Background(), "nonexistent")
require.Error(t, err)
}
func TestWhatsAppCallService_ListByConversation_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &model.WhatsAppCall{})
repo := repository.NewWhatsAppCallRepo(db)
svc := NewWhatsAppCallService(repo)
_, err := svc.CreateFromRequest(context.Background(), &WhatsAppCallCreateRequest{
CallID: "call_123",
InboxID: 1,
ConversationID: 1,
CallStatus: "ringing",
})
require.NoError(t, err)
calls, err := svc.ListByConversation(context.Background(), 1)
require.NoError(t, err)
assert.Len(t, calls, 1)
}
func TestWhatsAppCallService_UpdateByCallID_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &model.WhatsAppCall{})
repo := repository.NewWhatsAppCallRepo(db)
svc := NewWhatsAppCallService(repo)
_, err := svc.CreateFromRequest(context.Background(), &WhatsAppCallCreateRequest{
CallID: "call_123",
InboxID: 1,
ConversationID: 1,
CallStatus: "ringing",
})
require.NoError(t, err)
call, err := svc.UpdateByCallID(context.Background(), "call_123", "active", 30)
require.NoError(t, err)
assert.Equal(t, "active", call.CallStatus)
assert.Equal(t, 30, call.Duration)
}
func TestWhatsAppCallService_UpdateByCallID_InvalidStatus_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &model.WhatsAppCall{})
repo := repository.NewWhatsAppCallRepo(db)
svc := NewWhatsAppCallService(repo)
_, err := svc.CreateFromRequest(context.Background(), &WhatsAppCallCreateRequest{
CallID: "call_123",
InboxID: 1,
ConversationID: 1,
CallStatus: "ringing",
})
require.NoError(t, err)
_, err = svc.UpdateByCallID(context.Background(), "call_123", "invalid", 0)
require.Error(t, err)
}
func TestWhatsAppCallService_DeleteByCallID_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &model.WhatsAppCall{})
repo := repository.NewWhatsAppCallRepo(db)
svc := NewWhatsAppCallService(repo)
_, err := svc.CreateFromRequest(context.Background(), &WhatsAppCallCreateRequest{
CallID: "call_123",
InboxID: 1,
ConversationID: 1,
CallStatus: "ringing",
})
require.NoError(t, err)
err = svc.DeleteByCallID(context.Background(), "call_123")
require.NoError(t, err)
}
func TestWhatsAppCallService_DeleteByCallID_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &model.WhatsAppCall{})
repo := repository.NewWhatsAppCallRepo(db)
svc := NewWhatsAppCallService(repo)
err := svc.DeleteByCallID(context.Background(), "nonexistent")
require.Error(t, err)
}
func TestWhatsAppCallService_Initiate_NoSDP_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &model.WhatsAppCall{})
repo := repository.NewWhatsAppCallRepo(db)
svc := NewWhatsAppCallService(repo)
_, err := svc.Initiate(context.Background(), 1, WhatsAppCallInitiateRequest{
ConversationID: 1,
SDPOffer: "",
})
require.Error(t, err)
}
func TestWhatsAppCallService_Accept_NoSDP_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &model.WhatsAppCall{})
repo := repository.NewWhatsAppCallRepo(db)
svc := NewWhatsAppCallService(repo)
_, err := svc.Accept(context.Background(), 1, 1, 1, "")
require.Error(t, err)
}
// ============================================================
// ArticleService tests — targeting 0% methods
// ============================================================
func TestArticleService_Create_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
repo := repository.NewArticleRepo(db)
svc := NewArticleService(repo)
article, err := svc.Create(context.Background(), 1, 1, &CreateArticleRequest{
Title: "Test Article",
Content: "Content here",
})
require.NoError(t, err)
assert.NotZero(t, article.ID)
assert.Equal(t, "Test Article", article.Title)
}
func TestArticleService_GetByID_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
repo := repository.NewArticleRepo(db)
svc := NewArticleService(repo)
article, err := svc.Create(context.Background(), 1, 1, &CreateArticleRequest{
Title: "Test",
})
require.NoError(t, err)
got, err := svc.GetByID(context.Background(), article.ID)
require.NoError(t, err)
assert.Equal(t, article.ID, got.ID)
}
func TestArticleService_GetByID_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
repo := repository.NewArticleRepo(db)
svc := NewArticleService(repo)
_, err := svc.GetByID(context.Background(), 99999)
require.Error(t, err)
}
func TestArticleService_Update_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
repo := repository.NewArticleRepo(db)
svc := NewArticleService(repo)
article, err := svc.Create(context.Background(), 1, 1, &CreateArticleRequest{
Title: "Original",
})
require.NoError(t, err)
newTitle := "Updated"
updated, err := svc.Update(context.Background(), article.ID, &UpdateArticleRequest{
Title: &newTitle,
})
require.NoError(t, err)
assert.Equal(t, "Updated", updated.Title)
}
func TestArticleService_Update_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
repo := repository.NewArticleRepo(db)
svc := NewArticleService(repo)
_, err := svc.Update(context.Background(), 99999, &UpdateArticleRequest{})
require.Error(t, err)
}
func TestArticleService_Delete_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
repo := repository.NewArticleRepo(db)
svc := NewArticleService(repo)
article, err := svc.Create(context.Background(), 1, 1, &CreateArticleRequest{
Title: "Delete Me",
})
require.NoError(t, err)
err = svc.Delete(context.Background(), article.ID)
require.NoError(t, err)
}
func TestArticleService_SetSearchIndexer_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
repo := repository.NewArticleRepo(db)
svc := NewArticleService(repo)
svc.SetSearchIndexer(nil) // should not panic
}
func TestArticleService_SetWorkerPool_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
repo := repository.NewArticleRepo(db)
svc := NewArticleService(repo)
svc.SetWorkerPool(nil) // should not panic
}
func TestArticleService_SetArticleTranslationBackend_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
repo := repository.NewArticleRepo(db)
svc := NewArticleService(repo)
svc.SetArticleTranslationBackend(nil) // should not panic
}
func TestArticleService_EmbeddingReindexStatus_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
repo := repository.NewArticleRepo(db)
svc := NewArticleService(repo)
status := svc.EmbeddingReindexStatus()
assert.False(t, status.Running)
}
func TestArticleService_StartEmbeddingReindex_NotConfigured_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
repo := repository.NewArticleRepo(db)
svc := NewArticleService(repo)
_, err := svc.StartEmbeddingReindex()
require.Error(t, err)
}
// ============================================================
// ChannelInstagramService tests — targeting 0% methods
// ============================================================
func TestChannelInstagramService_GetByID_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelInstagram{})
repo := repository.NewChannelInstagramRepo(db)
svc := NewChannelInstagramService(repo, nil)
_, err := svc.GetByID(context.Background(), 99999)
require.Error(t, err)
}
func TestChannelInstagramService_GetByInboxID_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelInstagram{})
repo := repository.NewChannelInstagramRepo(db)
svc := NewChannelInstagramService(repo, nil)
_, err := svc.GetByInboxID(context.Background(), 99999)
require.Error(t, err)
}
func TestChannelInstagramService_GetByAccountAndInboxID_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelInstagram{})
repo := repository.NewChannelInstagramRepo(db)
svc := NewChannelInstagramService(repo, nil)
_, err := svc.GetByAccountAndInboxID(context.Background(), 1, 99999)
require.Error(t, err)
}
func TestChannelInstagramService_FindByInstagramAccountID_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelInstagram{})
repo := repository.NewChannelInstagramRepo(db)
svc := NewChannelInstagramService(repo, nil)
_, err := svc.FindByInstagramAccountID(context.Background(), "nonexistent")
require.Error(t, err)
}
func TestChannelInstagramService_FindByConnectedFBPageID_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelInstagram{})
repo := repository.NewChannelInstagramRepo(db)
svc := NewChannelInstagramService(repo, nil)
_, err := svc.FindByConnectedFBPageID(context.Background(), "nonexistent")
require.Error(t, err)
}
func TestChannelInstagramService_Update_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelInstagram{})
repo := repository.NewChannelInstagramRepo(db)
svc := NewChannelInstagramService(repo, nil)
_, err := svc.Update(context.Background(), 1, 99999, UpdateInstagramChannelRequest{})
require.Error(t, err)
}
func TestChannelInstagramService_ListByAccount_Empty_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelInstagram{})
repo := repository.NewChannelInstagramRepo(db)
svc := NewChannelInstagramService(repo, nil)
channels, err := svc.ListByAccount(context.Background(), 1)
require.NoError(t, err)
assert.Empty(t, channels)
}
func TestChannelInstagramService_MarkReauthorization_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t, &channelmodel.ChannelInstagram{})
repo := repository.NewChannelInstagramRepo(db)
svc := NewChannelInstagramService(repo, nil)
err := svc.MarkReauthorizationRequired(context.Background(), 99999)
require.Error(t, err)
}
// ============================================================
// AppliedSlaService tests — targeting 0% methods
// ============================================================
func TestAppliedSlaService_ValidateSlaPolicy_NotFound_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
repo := repository.NewAppliedSlaRepo(db)
slaEventRepo := repository.NewSlaEventRepo(db)
slaPolicyRepo := repository.NewSlaPolicyRepo(db)
convRepo := repository.NewConversationRepo(db)
svc := NewAppliedSlaService(repo, slaEventRepo, slaPolicyRepo, convRepo)
err := svc.ValidateSlaPolicy(context.Background(), 1, 99999)
require.Error(t, err)
}
// ============================================================
// RBACService tests
// ============================================================
func TestRBACService_New_Cov18(t *testing.T) {
db := newSimpleServiceTestDB(t)
svc := NewRBACService(db)
assert.NotNil(t, svc)
}