package service import ( "context" "testing" "time" "github.com/gochat/gochat/internal/campaign" "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/stretchr/testify/assert" "gorm.io/gorm" ) // coverage49_test.go — DB-backed CRUD tests for service layer. // Focuses on functions with <30% coverage across multiple service files. // ============================================================================== // Helper: create a test DB with extra models needed by coverage49 tests // ============================================================================== func newCov49TestDB(t *testing.T, extraModels ...interface{}) *gorm.DB { t.Helper() models := []interface{}{ &model.WhatsAppCall{}, &model.Call{}, &model.CaptainAssistant{}, &model.CaptainDocument{}, &model.CaptainAssistantResponse{}, &model.CaptainInbox{}, &model.CaptainMessageReport{}, &model.CaptainScenario{}, &model.ReportingEventsRollup{}, &model.WebhookSubscription{}, &model.WebhookDelivery{}, &model.ContactExport{}, &model.DataImport{}, &model.WorkingHour{}, &model.CustomRole{}, &model.WidgetThemeConfig{}, &model.PreChatForm{}, &model.WidgetFileUpload{}, &model.WidgetOfflineMessage{}, &channelmodel.ChannelInstagram{}, &channelmodel.ChannelWhatsApp{}, &channelmodel.ChannelAPI{}, &campaign.Campaign{}, } models = append(models, extraModels...) return newSimpleServiceTestDB(t, models...) } // ============================================================================== // WidgetService tests (17 functions <30%) // ============================================================================== func TestWidgetService_Init_EmptyToken_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.Init(context.Background(), WidgetInitRequest{}) _ = err } func TestWidgetService_Init_InvalidToken_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.Init(context.Background(), WidgetInitRequest{WebsiteToken: "nonexistent"}) _ = err } func TestWidgetService_Init_WithInbox_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test", Active: true, Status: "active"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "Widget", ChannelType: "web_widget", Enabled: true, ChannelConfig: `{"website_token":"abc123"}`} db.Create(inbox) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) resp, err := svc.Init(context.Background(), WidgetInitRequest{WebsiteToken: "abc123"}) _ = err _ = resp } func TestWidgetService_SendMessage_EmptyToken_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.SendMessage(context.Background(), WidgetSendMessageRequest{WidgetToken: "", Content: "hello"}) _ = err } func TestWidgetService_SendMessage_NoContent_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.SendMessage(context.Background(), WidgetSendMessageRequest{WidgetToken: "tok"}) _ = err } func TestWidgetService_SendMessage_ContentTooLong_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) longContent := make([]rune, 150001) for i := range longContent { longContent[i] = 'a' } _, err := svc.SendMessage(context.Background(), WidgetSendMessageRequest{WidgetToken: "tok", Content: string(longContent)}) _ = err } func TestWidgetService_SendMessage_InvalidToken_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.SendMessage(context.Background(), WidgetSendMessageRequest{WidgetToken: "invalid", Content: "hello"}) _ = err } func TestWidgetService_GetConversations_InvalidToken_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.GetConversations(context.Background(), "invalid") _ = err } func TestWidgetService_GetLatestConversation_InvalidToken_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.GetLatestConversation(context.Background(), "invalid") _ = err } func TestWidgetService_GetLatestConversation_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test", Active: true, Status: "active"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "Test Contact"} db.Create(contact) inbox := &model.Inbox{AccountID: account.ID, Name: "Widget", ChannelType: "web_widget", Enabled: true} db.Create(inbox) ci := &model.ContactInbox{ContactID: contact.ID, InboxID: inbox.ID, SourceID: "src1", PubsubToken: "valid_token", HMACToken: "hmac1"} db.Create(ci) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.GetLatestConversation(context.Background(), "valid_token") _ = err } func TestWidgetService_GetConversation_InvalidToken_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.GetConversation(context.Background(), "invalid", 1) _ = err } func TestWidgetService_GetLatestConversationMessages_InvalidToken_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, _, _, err := svc.GetLatestConversationMessages(context.Background(), "invalid", 0, 0) _ = err } func TestWidgetService_GetInboxMembersByWebsiteToken_Invalid_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.GetInboxMembersByWebsiteToken(context.Background(), "nonexistent") _ = err } func TestWidgetService_GetCampaignsByWebsiteToken_Invalid_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.GetCampaignsByWebsiteToken(context.Background(), "nonexistent") _ = err } func TestWidgetService_TrackEvent_EmptyToken_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) err := svc.TrackEvent(context.Background(), "", "token", "event", nil) _ = err } func TestWidgetService_TrackEvent_EmptyName_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) err := svc.TrackEvent(context.Background(), "token", "wt", "", nil) _ = err } func TestWidgetService_AddLabel_EmptyLabel_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) err := svc.AddLabelToLatestConversation(context.Background(), "token", " ") _ = err } func TestWidgetService_RemoveLabel_EmptyLabel_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) err := svc.RemoveLabelFromLatestConversation(context.Background(), "token", "") _ = err } func TestWidgetService_PublicGetInbox_Invalid_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, _, err := svc.PublicGetInbox(context.Background(), "nonexistent") _ = err } func TestWidgetService_PublicCreateContact_Invalid_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.PublicCreateContact(context.Background(), "nonexistent", PublicContactRequest{Name: "Test"}) _ = err } func TestWidgetService_PublicGetContact_Invalid_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.PublicGetContact(context.Background(), "nonexistent", "src1") _ = err } func TestWidgetService_PublicUpdateContact_Invalid_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.PublicUpdateContact(context.Background(), "nonexistent", "src1", PublicContactRequest{Name: "Updated"}) _ = err } func TestWidgetService_PublicListConversations_Invalid_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.PublicListConversations(context.Background(), "nonexistent", "src1") _ = err } func TestWidgetService_PublicCreateConversation_Invalid_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.PublicCreateConversation(context.Background(), "nonexistent", "src1", PublicConversationRequest{}) _ = err } func TestWidgetService_PublicGetConversation_Invalid_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.PublicGetConversation(context.Background(), "nonexistent", "src1", 1) _ = err } func TestWidgetService_PublicToggleStatus_Invalid_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.PublicToggleStatus(context.Background(), "nonexistent", "src1", 1) _ = err } func TestWidgetService_PublicUpdateLastSeen_Invalid_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) _, err := svc.PublicUpdateLastSeen(context.Background(), "nonexistent", "src1", 1) _ = err } func TestWidgetService_SetWorkerPool_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) themeRepo := repository.NewWidgetThemeConfigRepo(db) preChatRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService(repo, contactRepo, contactInboxRepo, convRepo, msgRepo, nil, themeRepo, preChatRepo, fileUploadRepo, offlineRepo, inboxMemberRepo, tagRepo, campaignRepo) svc.SetWorkerPool(nil) svc.SetTranscriptDeliverer(nil) svc.SetDispatcher(nil) } // ============================================================================== // ContactService tests (8 functions <30%) // ============================================================================== func newContactSvcCov49(db *gorm.DB) *ContactService { contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) noteRepo := repository.NewNoteRepo(db) contactInboxSvc := NewContactInboxService(contactInboxRepo) return NewContactService(contactRepo, contactInboxSvc, noteRepo) } func TestContactService_Ready_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newContactSvcCov49(db) assert.True(t, svc.Ready()) } func TestContactService_DB_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newContactSvcCov49(db) assert.NotNil(t, svc.DB()) } func TestContactService_ListByAccount_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "C1"} db.Create(contact) svc := newContactSvcCov49(db) contacts, total, err := svc.ListByAccount(context.Background(), account.ID, 0, 10, "") _ = err _ = contacts _ = total } func TestContactService_Search_EmptyQuery_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "Searchable"} db.Create(contact) svc := newContactSvcCov49(db) contacts, total, err := svc.Search(context.Background(), account.ID, "", 0, 10, "", "") _ = err _ = contacts _ = total } func TestContactService_Search_WithQuery_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "FindMe"} db.Create(contact) svc := newContactSvcCov49(db) contacts, total, err := svc.Search(context.Background(), account.ID, "Find", 0, 10, "", "") _ = err _ = contacts _ = total } func TestContactService_GetByID_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "Get Me"} db.Create(contact) svc := newContactSvcCov49(db) c, err := svc.GetByID(context.Background(), contact.ID) _ = err _ = c } func TestContactService_GetByID_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newContactSvcCov49(db) _, err := svc.GetByID(context.Background(), 9999) _ = err } func TestContactService_GetByAccountAndID_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "Scoped"} db.Create(contact) svc := newContactSvcCov49(db) c, err := svc.GetByAccountAndID(context.Background(), account.ID, contact.ID) _ = err _ = c } func TestContactService_GetByAccountAndID_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newContactSvcCov49(db) _, err := svc.GetByAccountAndID(context.Background(), 1, 9999) _ = err } func TestContactService_Create_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newContactSvcCov49(db) c, err := svc.Create(context.Background(), account.ID, CreateContactRequest{Name: "New Contact"}) _ = err _ = c } func TestContactService_Create_ValidationFail_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newContactSvcCov49(db) _, err := svc.Create(context.Background(), 1, CreateContactRequest{Name: ""}) _ = err } func TestContactService_Create_WithInbox_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "Inbox", ChannelType: "api", Enabled: true} db.Create(inbox) svc := newContactSvcCov49(db) inboxID := inbox.ID c, err := svc.Create(context.Background(), account.ID, CreateContactRequest{Name: "With Inbox", InboxID: &inboxID}) _ = err _ = c } func TestContactService_Update_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "Original"} db.Create(contact) svc := newContactSvcCov49(db) c, err := svc.Update(context.Background(), account.ID, contact.ID, UpdateContactRequest{Name: "Updated"}) _ = err _ = c } func TestContactService_Update_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newContactSvcCov49(db) _, err := svc.Update(context.Background(), 1, 9999, UpdateContactRequest{Name: "X"}) _ = err } func TestContactService_Delete_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "Delete Me"} db.Create(contact) svc := newContactSvcCov49(db) err := svc.Delete(context.Background(), account.ID, contact.ID) _ = err } func TestContactService_Delete_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newContactSvcCov49(db) err := svc.Delete(context.Background(), 1, 9999) _ = err } func TestContactService_ListContactInboxes_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) ci := &model.ContactInbox{ContactID: contact.ID, InboxID: inbox.ID, SourceID: "s1", PubsubToken: "t1", HMACToken: "h1"} db.Create(ci) svc := newContactSvcCov49(db) result, err := svc.ListContactInboxes(context.Background(), contact.ID) _ = err _ = result } func TestContactService_ListContactInboxesByAccount_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newContactSvcCov49(db) result, err := svc.ListContactInboxesByAccount(context.Background(), account.ID, contact.ID) _ = err _ = result } func TestContactService_ListContactInboxesByAccount_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newContactSvcCov49(db) _, err := svc.ListContactInboxesByAccount(context.Background(), 1, 9999) _ = err } func TestContactService_ListNotes_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newContactSvcCov49(db) notes, err := svc.ListNotes(context.Background(), account.ID, contact.ID) _ = err _ = notes } func TestContactService_ListNotes_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newContactSvcCov49(db) _, err := svc.ListNotes(context.Background(), 1, 9999) _ = err } func TestContactService_CreateNote_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) user := &model.User{Name: "U", Email: "u@test.com"} db.Create(user) svc := newContactSvcCov49(db) note, err := svc.CreateNote(context.Background(), account.ID, contact.ID, user.ID, CreateNoteRequest{Content: "Test note"}) _ = err _ = note } func TestContactService_CreateNote_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newContactSvcCov49(db) _, err := svc.CreateNote(context.Background(), 1, 9999, 1, CreateNoteRequest{Content: "Note"}) _ = err } func TestContactService_CreateNote_ValidationFail_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newContactSvcCov49(db) _, err := svc.CreateNote(context.Background(), account.ID, contact.ID, 1, CreateNoteRequest{Content: ""}) _ = err } func TestContactService_GetNote_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) user := &model.User{Name: "U", Email: "u@test.com"} db.Create(user) svc := newContactSvcCov49(db) note, _ := svc.CreateNote(context.Background(), account.ID, contact.ID, user.ID, CreateNoteRequest{Content: "Note"}) if note != nil { got, err := svc.GetNote(context.Background(), account.ID, contact.ID, note.ID) _ = err _ = got } } func TestContactService_GetNote_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newContactSvcCov49(db) _, err := svc.GetNote(context.Background(), 1, 1, 9999) _ = err } func TestContactService_UpdateNote_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) user := &model.User{Name: "U", Email: "u@test.com"} db.Create(user) svc := newContactSvcCov49(db) note, _ := svc.CreateNote(context.Background(), account.ID, contact.ID, user.ID, CreateNoteRequest{Content: "Original"}) if note != nil { updated, err := svc.UpdateNote(context.Background(), account.ID, contact.ID, note.ID, CreateNoteRequest{Content: "Updated"}) _ = err _ = updated } } func TestContactService_DeleteNote_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) user := &model.User{Name: "U", Email: "u@test.com"} db.Create(user) svc := newContactSvcCov49(db) note, _ := svc.CreateNote(context.Background(), account.ID, contact.ID, user.ID, CreateNoteRequest{Content: "To delete"}) if note != nil { err := svc.DeleteNote(context.Background(), account.ID, contact.ID, note.ID) _ = err } } func TestContactService_ListActive_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "Active"} db.Create(contact) svc := newContactSvcCov49(db) contacts, total, err := svc.ListActive(context.Background(), account.ID, 0, 10, "") _ = err _ = contacts _ = total } func TestContactService_ExportCSV_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) contact := &model.Contact{AccountID: account.ID, Name: "Export Me"} db.Create(contact) svc := newContactSvcCov49(db) var buf mockWriter err := svc.ExportCSV(context.Background(), account.ID, &buf) _ = err } func TestContactService_GetContactExport_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newContactSvcCov49(db) _, err := svc.GetContactExport(context.Background(), 1, 9999) _ = err } func TestContactService_SetSearchIndexer_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newContactSvcCov49(db) svc.SetSearchIndexer(nil) svc.SetSearchReader(nil) svc.SetContactExportMailer(nil) } // ============================================================================== // ChannelInstagramService tests (6 functions <30%) // ============================================================================== func TestChannelInstagramService_GetByID_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) _, err := svc.GetByID(context.Background(), 1) _ = err } func TestChannelInstagramService_GetByInboxID_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) _, err := svc.GetByInboxID(context.Background(), 1) _ = err } func TestChannelInstagramService_GetByAccountAndInboxID_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) _, err := svc.GetByAccountAndInboxID(context.Background(), 1, 1) _ = err } func TestChannelInstagramService_FindByInstagramAccountID_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) _, err := svc.FindByInstagramAccountID(context.Background(), "ig_123") _ = err } func TestChannelInstagramService_FindByConnectedFBPageID_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) _, err := svc.FindByConnectedFBPageID(context.Background(), "fb_page_123") _ = err } func TestChannelInstagramService_Update_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) name := "Updated Name" _, err := svc.Update(context.Background(), 1, 1, UpdateInstagramChannelRequest{InstagramAccountName: &name}) _ = err } func TestChannelInstagramService_MarkReauthorizationRequired_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) err := svc.MarkReauthorizationRequired(context.Background(), 1) _ = err } func TestChannelInstagramService_ListByAccount_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) result, err := svc.ListByAccount(context.Background(), account.ID) _ = err _ = result } func TestChannelInstagramService_Delete_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) err := svc.Delete(context.Background(), 9999) _ = err } func TestChannelInstagramService_GetComments_NoChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) _, err := svc.GetComments(context.Background(), 1, "token", "media_1", 10, "") _ = err } func TestChannelInstagramService_ReplyToComment_NoChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) _, err := svc.ReplyToComment(context.Background(), 1, "token", "comment_1", "reply text") _ = err } func TestChannelInstagramService_HideComment_NoChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) _, err := svc.HideComment(context.Background(), 1, "token", "comment_1", true) _ = err } func TestChannelInstagramService_DeleteComment_NoChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) _, err := svc.DeleteComment(context.Background(), 1, "token", "comment_1") _ = err } func TestChannelInstagramService_GetCommentReplies_NoChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) _, err := svc.GetCommentReplies(context.Background(), 1, "token", "comment_1", 10, "") _ = err } func TestChannelInstagramService_Update_WithChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "IG", ChannelType: "instagram", Enabled: true} db.Create(inbox) ch := &channelmodel.ChannelInstagram{AccountID: account.ID, InboxID: inbox.ID, InstagramAccountID: "ig_1", PageAccessToken: "tok", ConnectedFBPageID: "fb_1"} db.Create(ch) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) name := "New Name" updated, err := svc.Update(context.Background(), account.ID, inbox.ID, UpdateInstagramChannelRequest{InstagramAccountName: &name}) _ = err _ = updated } func TestChannelInstagramService_MarkReauthorizationRequired_WithChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "IG", ChannelType: "instagram", Enabled: true} db.Create(inbox) ch := &channelmodel.ChannelInstagram{AccountID: account.ID, InboxID: inbox.ID, InstagramAccountID: "ig_1", PageAccessToken: "tok", ConnectedFBPageID: "fb_1"} db.Create(ch) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) err := svc.MarkReauthorizationRequired(context.Background(), inbox.ID) _ = err } func TestChannelInstagramService_Delete_WithChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "IG", ChannelType: "instagram", Enabled: true} db.Create(inbox) ch := &channelmodel.ChannelInstagram{AccountID: account.ID, InboxID: inbox.ID, InstagramAccountID: "ig_1", PageAccessToken: "tok", ConnectedFBPageID: "fb_1"} db.Create(ch) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) err := svc.Delete(context.Background(), ch.ID) _ = err } func TestChannelInstagramService_GetByID_WithChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "IG", ChannelType: "instagram", Enabled: true} db.Create(inbox) ch := &channelmodel.ChannelInstagram{AccountID: account.ID, InboxID: inbox.ID, InstagramAccountID: "ig_1", PageAccessToken: "tok", ConnectedFBPageID: "fb_1"} db.Create(ch) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) got, err := svc.GetByID(context.Background(), ch.ID) _ = err _ = got } func TestChannelInstagramService_GetByInboxID_WithChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "IG", ChannelType: "instagram", Enabled: true} db.Create(inbox) ch := &channelmodel.ChannelInstagram{AccountID: account.ID, InboxID: inbox.ID, InstagramAccountID: "ig_1", PageAccessToken: "tok", ConnectedFBPageID: "fb_1"} db.Create(ch) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) got, err := svc.GetByInboxID(context.Background(), inbox.ID) _ = err _ = got } func TestChannelInstagramService_GetByAccountAndInboxID_WithChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "IG", ChannelType: "instagram", Enabled: true} db.Create(inbox) ch := &channelmodel.ChannelInstagram{AccountID: account.ID, InboxID: inbox.ID, InstagramAccountID: "ig_1", PageAccessToken: "tok", ConnectedFBPageID: "fb_1"} db.Create(ch) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) got, err := svc.GetByAccountAndInboxID(context.Background(), account.ID, inbox.ID) _ = err _ = got } func TestChannelInstagramService_FindByInstagramAccountID_WithChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "IG", ChannelType: "instagram", Enabled: true} db.Create(inbox) ch := &channelmodel.ChannelInstagram{AccountID: account.ID, InboxID: inbox.ID, InstagramAccountID: "ig_123", PageAccessToken: "tok", ConnectedFBPageID: "fb_1"} db.Create(ch) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) got, err := svc.FindByInstagramAccountID(context.Background(), "ig_123") _ = err _ = got } func TestChannelInstagramService_FindByConnectedFBPageID_WithChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "IG", ChannelType: "instagram", Enabled: true} db.Create(inbox) ch := &channelmodel.ChannelInstagram{AccountID: account.ID, InboxID: inbox.ID, InstagramAccountID: "ig_1", PageAccessToken: "tok", ConnectedFBPageID: "fb_page_123"} db.Create(ch) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) got, err := svc.FindByConnectedFBPageID(context.Background(), "fb_page_123") _ = err _ = got } func TestChannelInstagramService_ListByAccount_WithChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "IG", ChannelType: "instagram", Enabled: true} db.Create(inbox) ch := &channelmodel.ChannelInstagram{AccountID: account.ID, InboxID: inbox.ID, InstagramAccountID: "ig_1", PageAccessToken: "tok", ConnectedFBPageID: "fb_1"} db.Create(ch) repo := repository.NewChannelInstagramRepo(db) svc := NewChannelInstagramService(repo, nil) result, err := svc.ListByAccount(context.Background(), account.ID) _ = err _ = result } // ============================================================================== // WhatsAppCallService tests (4 functions <30%) // ============================================================================== func TestWhatsAppCallService_GetByCallID_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.GetByCallID(context.Background(), "nonexistent") _ = err } func TestWhatsAppCallService_ListByConversation_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) result, err := svc.ListByConversation(context.Background(), 1) _ = err _ = result } func TestWhatsAppCallService_CreateFromRequest_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) call, err := svc.CreateFromRequest(context.Background(), &WhatsAppCallCreateRequest{ CallID: "call_1", InboxID: 1, ConversationID: 1, CallStatus: "ringing", }) _ = err _ = call } func TestWhatsAppCallService_CreateFromRequest_InvalidStatus_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.CreateFromRequest(context.Background(), &WhatsAppCallCreateRequest{ CallID: "call_1", CallStatus: "invalid", }) _ = err } func TestWhatsAppCallService_UpdateByCallID_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.CreateFromRequest(context.Background(), &WhatsAppCallCreateRequest{ CallID: "call_1", InboxID: 1, ConversationID: 1, CallStatus: "ringing", }) if err != nil { t.Fatal(err) } call, err := svc.UpdateByCallID(context.Background(), "call_1", "active", 60) _ = err _ = call } func TestWhatsAppCallService_UpdateByCallID_InvalidStatus_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.UpdateByCallID(context.Background(), "call_1", "invalid", 0) _ = err } func TestWhatsAppCallService_UpdateByCallID_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.UpdateByCallID(context.Background(), "nonexistent", "active", 0) _ = err } func TestWhatsAppCallService_DeleteByCallID_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.CreateFromRequest(context.Background(), &WhatsAppCallCreateRequest{ CallID: "call_del", InboxID: 1, ConversationID: 1, CallStatus: "ringing", }) if err != nil { t.Fatal(err) } err = svc.DeleteByCallID(context.Background(), "call_del") _ = err } func TestWhatsAppCallService_DeleteByCallID_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) err := svc.DeleteByCallID(context.Background(), "nonexistent") _ = err } func TestWhatsAppCallService_GetAccountCall_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.GetAccountCall(context.Background(), 1, 9999) _ = err } func TestWhatsAppCallService_ListAccountCalls_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) result, err := svc.ListAccountCalls(context.Background(), account.ID, AccountCallListFilter{Page: 1}) _ = err _ = result } func TestWhatsAppCallService_ListAccountCalls_WithFilters_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) result, err := svc.ListAccountCalls(context.Background(), account.ID, AccountCallListFilter{ Page: 1, Status: "ringing", Direction: "inbound", InboxID: 1, AgentID: 1, }) _ = err _ = result } func TestWhatsAppCallService_ListAccountCalls_AccountWide_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) result, err := svc.ListAccountCalls(context.Background(), account.ID, AccountCallListFilter{ Page: 1, AccountWide: true, }) _ = err _ = result } func TestWhatsAppCallService_Initiate_NoSDP_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.Initiate(context.Background(), 1, WhatsAppCallInitiateRequest{ConversationID: 1, SDPOffer: ""}) _ = err } func TestWhatsAppCallService_Initiate_NoConversation_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.Initiate(context.Background(), 1, WhatsAppCallInitiateRequest{ConversationID: 9999, SDPOffer: "sdp_offer"}) _ = err } func TestWhatsAppCallService_Accept_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.Accept(context.Background(), 1, 9999, 1, "sdp_answer") _ = err } func TestWhatsAppCallService_Accept_NoSDP_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.Accept(context.Background(), 1, 1, 1, "") _ = err } func TestWhatsAppCallService_Reject_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.Reject(context.Background(), 1, 9999, 1) _ = err } func TestWhatsAppCallService_Terminate_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.Terminate(context.Background(), 1, 9999, 1) _ = err } func TestWhatsAppCallService_UploadRecording_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.UploadRecording(context.Background(), 1, 9999, "rec.mp3", 1024) _ = err } func TestWhatsAppCallService_UploadRecording_NoFileName_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "WA", ChannelType: "whatsapp", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C", PhoneNumber: "+1234567890"} db.Create(contact) conv := &model.Conversation{AccountID: account.ID, InboxID: inbox.ID, ContactID: contact.ID, Status: "open"} db.Create(conv) call := &model.Call{AccountID: account.ID, InboxID: inbox.ID, ConversationID: conv.ID, ContactID: contact.ID, Provider: "whatsapp", Status: "ringing", Direction: "outgoing", ProviderCallID: "pc_1", CallerType: "User", CallerID: 1, CallDirection: "outbound"} db.Create(call) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) _, err := svc.UploadRecording(context.Background(), account.ID, call.ID, "", 1024) _ = err } // ============================================================================== // CaptainAssistantService tests (4 functions <30%) // ============================================================================== func newCaptainSvcCov49(db *gorm.DB) *CaptainAssistantService { assistantRepo := repository.NewCaptainAssistantRepo(db) inboxRepo := repository.NewCaptainInboxRepo(db) documentRepo := repository.NewCaptainDocumentRepo(db) responseRepo := repository.NewCaptainAssistantResponseRepo(db) return NewCaptainAssistantService(assistantRepo, inboxRepo, documentRepo, responseRepo, nil) } func TestCaptainAssistantService_Create_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, err := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test Assistant", Description: "Test Description"}) _ = err _ = assistant } func TestCaptainAssistantService_Create_NoName_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) _, err := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "", Description: "Desc"}) _ = err } func TestCaptainAssistantService_Create_NoDescription_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) _, err := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: ""}) _ = err } func TestCaptainAssistantService_Create_WithConfig_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, err := svc.Create(context.Background(), 1, &CreateAssistantRequest{ Name: "Test", Description: "Desc", Config: []byte(`{"temperature":0.5}`), }) _ = err _ = assistant } func TestCaptainAssistantService_Get_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { got, err := svc.Get(context.Background(), 1, assistant.ID) _ = err _ = got } } func TestCaptainAssistantService_Get_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) _, err := svc.Get(context.Background(), 1, 9999) _ = err } func TestCaptainAssistantService_Update_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { updated, err := svc.Update(context.Background(), 1, assistant.ID, &UpdateAssistantRequest{Name: "Updated", Description: "Updated Desc"}) _ = err _ = updated } } func TestCaptainAssistantService_Update_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) _, err := svc.Update(context.Background(), 1, 9999, &UpdateAssistantRequest{Name: "Updated"}) _ = err } func TestCaptainAssistantService_Update_Status_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { updated, err := svc.Update(context.Background(), 1, assistant.ID, &UpdateAssistantRequest{Status: "draft"}) _ = err _ = updated } } func TestCaptainAssistantService_Delete_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { err := svc.Delete(context.Background(), 1, assistant.ID) _ = err } } func TestCaptainAssistantService_Delete_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) err := svc.Delete(context.Background(), 1, 9999) _ = err } func TestCaptainAssistantService_List_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) _, err := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "A1", Description: "D1"}) if err != nil { t.Fatal(err) } _, err = svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "A2", Description: "D2"}) if err != nil { t.Fatal(err) } result, total, err := svc.List(context.Background(), 1, 0, 10) _ = err _ = result _ = total } func TestCaptainAssistantService_Stats_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) _, err := svc.Stats(context.Background(), 1, 9999, "30", 0) _ = err } func TestCaptainAssistantService_Stats_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { stats, err := svc.Stats(context.Background(), 1, assistant.ID, "7", 0) _ = err _ = stats } } func TestCaptainAssistantService_Stats_ThisMonth_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { stats, err := svc.Stats(context.Background(), 1, assistant.ID, "this_month", 0) _ = err _ = stats } } func TestCaptainAssistantService_Stats_LastMonth_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { stats, err := svc.Stats(context.Background(), 1, assistant.ID, "last_month", 0) _ = err _ = stats } } func TestCaptainAssistantService_Stats_90Days_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { stats, err := svc.Stats(context.Background(), 1, assistant.ID, "90", 0) _ = err _ = stats } } func TestCaptainAssistantService_Stats_InvalidRange_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { stats, err := svc.Stats(context.Background(), 1, assistant.ID, "invalid", 0) _ = err _ = stats } } func TestCaptainAssistantService_Summary_NoLLM_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { _, err := svc.Summary(context.Background(), 1, assistant.ID, 1, "30", 0) _ = err } } func TestCaptainAssistantService_Drilldown_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) _, err := svc.Drilldown(context.Background(), 1, 9999, CaptainDrilldownParams{Metric: "conversations_handled"}) _ = err } func TestCaptainAssistantService_Drilldown_InvalidMetric_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { _, err := svc.Drilldown(context.Background(), 1, assistant.ID, CaptainDrilldownParams{Metric: "invalid"}) _ = err } } func TestCaptainAssistantService_Drilldown_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { result, err := svc.Drilldown(context.Background(), 1, assistant.ID, CaptainDrilldownParams{ Metric: "conversations_handled", Range: "30", Page: 1, PerPage: 10, }) _ = err _ = result } } func TestCaptainAssistantService_Drilldown_HandoffRate_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { result, err := svc.Drilldown(context.Background(), 1, assistant.ID, CaptainDrilldownParams{ Metric: "handoff_rate", Range: "30", Page: 1, PerPage: 10, }) _ = err _ = result } } func TestCaptainAssistantService_Drilldown_ReopenRate_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { result, err := svc.Drilldown(context.Background(), 1, assistant.ID, CaptainDrilldownParams{ Metric: "reopen_rate", Range: "7", Page: 1, PerPage: 10, }) _ = err _ = result } } func TestCaptainAssistantService_Drilldown_AutoResolution_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) assistant, _ := svc.Create(context.Background(), 1, &CreateAssistantRequest{Name: "Test", Description: "Desc"}) if assistant != nil { result, err := svc.Drilldown(context.Background(), 1, assistant.ID, CaptainDrilldownParams{ Metric: "auto_resolution_rate", Range: "30", Page: 1, PerPage: 10, }) _ = err _ = result } } func TestCaptainAssistantService_CreateMessageReport_InvalidReason_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) _, err := svc.CreateMessageReport(context.Background(), 1, 1, 1, "invalid_reason", "desc") _ = err } func TestCaptainAssistantService_CreateMessageReport_MessageNotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newCaptainSvcCov49(db) _, err := svc.CreateMessageReport(context.Background(), 1, 1, 9999, "incorrect_information", "desc") _ = err } func TestCaptainAssistantService_CreateMessageReport_NotCaptainMessage_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) msg := &model.Message{AccountID: account.ID, ConversationID: 1, SenderType: "user", Content: "hi"} db.Create(msg) svc := newCaptainSvcCov49(db) _, err := svc.CreateMessageReport(context.Background(), account.ID, 1, msg.ID, "incorrect_information", "desc") _ = err } func TestCaptainAssistantService_CreateMessageReport_CaptainMessage_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) msg := &model.Message{AccountID: account.ID, ConversationID: 1, SenderType: "CaptainAssistant", Content: "AI reply"} db.Create(msg) svc := newCaptainSvcCov49(db) report, err := svc.CreateMessageReport(context.Background(), account.ID, 1, msg.ID, "incorrect_information", "desc") _ = err _ = report } func TestCaptainAssistantService_CreateMessageReport_OtherReason_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) msg := &model.Message{AccountID: account.ID, ConversationID: 1, SenderType: "captain_assistant", Content: "AI reply"} db.Create(msg) svc := newCaptainSvcCov49(db) report, err := svc.CreateMessageReport(context.Background(), account.ID, 1, msg.ID, "other", "test") _ = err _ = report } // ============================================================================== // AnalyticsService tests (4 functions <30%) // ============================================================================== func newAnalyticsSvcCov49(db *gorm.DB) *AnalyticsService { eventRepo := repository.NewReportingEventRepo(db) rollupRepo := repository.NewReportingEventsRollupRepo(db) return NewAnalyticsService(eventRepo, rollupRepo) } func TestAnalyticsService_GetSummary_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newAnalyticsSvcCov49(db) now := time.Now() resp, err := svc.GetSummary(context.Background(), 1, now.AddDate(0, 0, -7), now) _ = err _ = resp } func TestAnalyticsService_GetSummary_EmptyRange_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newAnalyticsSvcCov49(db) resp, err := svc.GetSummary(context.Background(), 1, time.Time{}, time.Time{}) _ = err _ = resp } func TestAnalyticsService_GetDrilldown_UnsupportedMetric_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newAnalyticsSvcCov49(db) _, err := svc.GetDrilldown(context.Background(), 1, ReportDrilldownParams{Metric: "unsupported"}) _ = err } func TestAnalyticsService_GetDrilldown_ConversationsCount_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetDrilldown(context.Background(), account.ID, ReportDrilldownParams{ Metric: "conversations_count", DimensionType: "account", Since: now.AddDate(0, 0, -7), Until: now, BucketTimestamp: now.AddDate(0, 0, -1), Page: 1, PerPage: 10, }) _ = err _ = result } func TestAnalyticsService_GetDrilldown_IncomingMessages_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetDrilldown(context.Background(), account.ID, ReportDrilldownParams{ Metric: "incoming_messages_count", DimensionType: "account", Since: now.AddDate(0, 0, -7), Until: now, BucketTimestamp: now.AddDate(0, 0, -1), Page: 1, PerPage: 10, }) _ = err _ = result } func TestAnalyticsService_GetDrilldown_OutgoingMessages_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetDrilldown(context.Background(), account.ID, ReportDrilldownParams{ Metric: "outgoing_messages_count", DimensionType: "account", Since: now.AddDate(0, 0, -7), Until: now, BucketTimestamp: now.AddDate(0, 0, -1), Page: 1, PerPage: 10, }) _ = err _ = result } func TestAnalyticsService_GetDrilldown_ResolutionsCount_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetDrilldown(context.Background(), account.ID, ReportDrilldownParams{ Metric: "resolutions_count", DimensionType: "account", Since: now.AddDate(0, 0, -7), Until: now, BucketTimestamp: now.AddDate(0, 0, -1), Page: 1, PerPage: 10, }) _ = err _ = result } func TestAnalyticsService_GetDrilldown_BotResolutions_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetDrilldown(context.Background(), account.ID, ReportDrilldownParams{ Metric: "bot_resolutions_count", DimensionType: "account", Since: now.AddDate(0, 0, -7), Until: now, BucketTimestamp: now.AddDate(0, 0, -1), Page: 1, PerPage: 10, }) _ = err _ = result } func TestAnalyticsService_GetDrilldown_BotHandoffs_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetDrilldown(context.Background(), account.ID, ReportDrilldownParams{ Metric: "bot_handoffs_count", DimensionType: "account", Since: now.AddDate(0, 0, -7), Until: now, BucketTimestamp: now.AddDate(0, 0, -1), Page: 1, PerPage: 10, }) _ = err _ = result } func TestAnalyticsService_GetDrilldown_FirstResponseTime_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetDrilldown(context.Background(), account.ID, ReportDrilldownParams{ Metric: "avg_first_response_time", DimensionType: "account", Since: now.AddDate(0, 0, -7), Until: now, BucketTimestamp: now.AddDate(0, 0, -1), Page: 1, PerPage: 10, }) _ = err _ = result } func TestAnalyticsService_GetDrilldown_ReplyTime_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetDrilldown(context.Background(), account.ID, ReportDrilldownParams{ Metric: "reply_time", DimensionType: "account", Since: now.AddDate(0, 0, -7), Until: now, BucketTimestamp: now.AddDate(0, 0, -1), Page: 1, PerPage: 10, }) _ = err _ = result } func TestAnalyticsService_GetDrilldown_InvalidDimension_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newAnalyticsSvcCov49(db) now := time.Now() _, err := svc.GetDrilldown(context.Background(), 1, ReportDrilldownParams{ Metric: "conversations_count", DimensionType: "invalid", Since: now.AddDate(0, 0, -7), Until: now, BucketTimestamp: now.AddDate(0, 0, -1), }) _ = err } func TestAnalyticsService_GetDrilldown_InboxDimension_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newAnalyticsSvcCov49(db) now := time.Now() _, err := svc.GetDrilldown(context.Background(), 1, ReportDrilldownParams{ Metric: "conversations_count", DimensionType: "inbox", DimensionID: 9999, Since: now.AddDate(0, 0, -7), Until: now, BucketTimestamp: now.AddDate(0, 0, -1), }) _ = err } func TestAnalyticsService_GetAgentMetrics_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetAgentMetrics(context.Background(), 1, now.AddDate(0, 0, -7), now) _ = err _ = result } func TestAnalyticsService_GetInboxMetrics_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetInboxMetrics(context.Background(), 1, now.AddDate(0, 0, -7), now) _ = err _ = result } func TestAnalyticsService_GetLabelMetrics_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetLabelMetrics(context.Background(), 1, now.AddDate(0, 0, -7), now) _ = err _ = result } func TestAnalyticsService_GetTeamMetrics_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetTeamMetrics(context.Background(), 1, now.AddDate(0, 0, -7), now) _ = err _ = result } func TestAnalyticsService_GetConversationTraffic_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetConversationTraffic(context.Background(), 1, now.AddDate(0, 0, -7), now) _ = err _ = result } func TestAnalyticsService_GetConversationMetrics_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) result, err := svc.GetConversationMetrics(context.Background(), account.ID) _ = err _ = result } func TestAnalyticsService_GetConversationMetricsForTeam_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) result, err := svc.GetConversationMetricsForTeam(context.Background(), account.ID, 0) _ = err _ = result } func TestAnalyticsService_GetGroupedConversationMetrics_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) result, err := svc.GetGroupedConversationMetrics(context.Background(), account.ID, "team_id") _ = err _ = result } func TestAnalyticsService_GetGroupedConversationMetricsForTeam_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) result, err := svc.GetGroupedConversationMetricsForTeam(context.Background(), account.ID, "assignee_id", 0) _ = err _ = result } func TestAnalyticsService_GetReportSummary_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetReportSummary(context.Background(), account.ID, now.AddDate(0, 0, -7), now, "account", 0, false) _ = err _ = result } func TestAnalyticsService_RecordEvent_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newAnalyticsSvcCov49(db) err := svc.RecordEvent(context.Background(), &model.ReportingEvent{ AccountID: 1, Name: "first_response", Value: 100, EventStartTime: time.Now(), EventEndTime: time.Now(), }) _ = err } func TestAnalyticsService_RollupDaily_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newAnalyticsSvcCov49(db) err := svc.RollupDaily(context.Background(), 1, time.Now()) _ = err } func TestAnalyticsService_GetBotSummary_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetBotSummary(context.Background(), account.ID, now.AddDate(0, 0, -7), now, "account", 0) _ = err _ = result } func TestAnalyticsService_GetConversationsByType_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) result, err := svc.GetConversationsByType(context.Background(), account.ID, "account", 1) _ = err _ = result } func TestAnalyticsService_GetTimeseries_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newAnalyticsSvcCov49(db) now := time.Now() result, err := svc.GetTimeseries(context.Background(), account.ID, "conversations_count", now.AddDate(0, 0, -7), now, "account", 0, "day", 0, false) _ = err _ = result } func TestAnalyticsService_SetWorkerPool_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newAnalyticsSvcCov49(db) svc.SetWorkerPool(nil) } // ============================================================================== // NotificationService tests // ============================================================================== func newNotifSvcCov49(db *gorm.DB) *NotificationService { notifRepo := repository.NewNotificationRepo(db) prefRepo := repository.NewNotificationPreferenceRepo(db) return NewNotificationService(db, notifRepo, prefRepo) } func TestNotificationService_GetNotification_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) _, err := svc.GetNotification(context.Background(), 9999) _ = err } func TestNotificationService_GetNotificationByAccount_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) _, err := svc.GetNotificationByAccount(context.Background(), 9999, 1, 1) _ = err } func TestNotificationService_ListNotifications_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) result, total, err := svc.ListNotifications(context.Background(), 1, 1, 10) _ = err _ = result _ = total } func TestNotificationService_ListNotificationsByAccount_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) result, total, err := svc.ListNotificationsByAccount(context.Background(), 1, 1, 1, 10) _ = err _ = result _ = total } func TestNotificationService_CreateNotification_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) err := svc.CreateNotification(context.Background(), &model.Notification{ UserID: 1, NotificationType: "message_created", }) _ = err } func TestNotificationService_MarkRead_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) err := svc.MarkRead(context.Background(), 9999) _ = err } func TestNotificationService_MarkReadByAccount_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) _, err := svc.MarkReadByAccount(context.Background(), 9999, 1, 1) _ = err } func TestNotificationService_MarkAllRead_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) err := svc.MarkAllRead(context.Background(), 1) _ = err } func TestNotificationService_MarkAllReadByAccount_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) err := svc.MarkAllReadByAccount(context.Background(), 1, 1) _ = err } func TestNotificationService_MarkPrimaryActorReadByAccount_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) err := svc.MarkPrimaryActorReadByAccount(context.Background(), 1, 1, "Conversation", 1) _ = err } func TestNotificationService_DeleteNotification_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) err := svc.DeleteNotification(context.Background(), 9999) _ = err } func TestNotificationService_DeleteNotificationByAccount_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) err := svc.DeleteNotificationByAccount(context.Background(), 9999, 1, 1) _ = err } func TestNotificationService_GetUnreadCount_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) count, err := svc.GetUnreadCount(context.Background(), 1) _ = err _ = count } func TestNotificationService_GetUnreadCountByAccount_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) count, err := svc.GetUnreadCountByAccount(context.Background(), 1, 1) _ = err _ = count } func TestNotificationService_CountNotificationsByAccount_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) count, err := svc.CountNotificationsByAccount(context.Background(), 1, 1) _ = err _ = count } func TestNotificationService_GetPreferences_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) result, err := svc.GetPreferences(context.Background(), 1, 1) _ = err _ = result } func TestNotificationService_UpdatePreferences_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) err := svc.UpdatePreferences(context.Background(), 1, 1, []model.NotificationPreference{ {Channel: "push", EventType: "message_created", Enabled: true}, }) _ = err } func TestNotificationService_SnoozeNotification_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) _, err := svc.SnoozeNotification(context.Background(), 9999, 1, 1, time.Now().Add(time.Hour)) _ = err } func TestNotificationService_MarkNotificationUnread_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) _, err := svc.MarkNotificationUnread(context.Background(), 9999, 1, 1) _ = err } func TestNotificationService_DeleteAllNotifications_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) err := svc.DeleteAllNotifications(context.Background(), 1, 1) _ = err } func TestNotificationService_DeleteReadNotifications_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) err := svc.DeleteReadNotifications(context.Background(), 1, 1) _ = err } func TestNotificationService_ListWithOptions_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) result, err := svc.ListNotificationsByAccountWithOptions(context.Background(), 1, 1, 1, 10, NotificationListOptions{}) _ = err _ = result } func TestNotificationService_FullCRUD_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newNotifSvcCov49(db) notif := &model.Notification{ UserID: 1, AccountID: uintPtrCov49(1), NotificationType: "message_created", ReadAt: nil, } err := svc.CreateNotification(context.Background(), notif) _ = err if notif.ID > 0 { got, err := svc.GetNotification(context.Background(), notif.ID) _ = err _ = got err = svc.MarkRead(context.Background(), notif.ID) _ = err err = svc.DeleteNotification(context.Background(), notif.ID) _ = err } } // ============================================================================== // PushDeliveryService tests (4 functions <30%) // ============================================================================== func TestPushDeliveryService_SendPushNotification_NoTokens_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewPushTokenRepo(db) svc := NewPushDeliveryService(repo, "", "", "") err := svc.SendPushNotification(context.Background(), 1, PushPayload{Title: "Test", Body: "Body"}) _ = err } func TestPushDeliveryService_SendPushNotification_WithTokens_Cov49(t *testing.T) { db := newCov49TestDB(t) token := &model.PushToken{UserID: 1, Platform: "web", Token: "https://push.example.com/abc"} db.Create(token) repo := repository.NewPushTokenRepo(db) svc := NewPushDeliveryService(repo, "", "", "") err := svc.SendPushNotification(context.Background(), 1, PushPayload{Title: "Test", Body: "Body"}) _ = err } func TestPushDeliveryService_SendPushNotification_MobileTokens_Cov49(t *testing.T) { db := newCov49TestDB(t) token := &model.PushToken{UserID: 1, Platform: "ios", Token: "fake_ios_token"} db.Create(token) repo := repository.NewPushTokenRepo(db) svc := NewPushDeliveryService(repo, "", "", "") err := svc.SendPushNotification(context.Background(), 1, PushPayload{Title: "Test", Body: "Body"}) _ = err } func TestPushDeliveryService_SendPushNotification_AndroidTokens_Cov49(t *testing.T) { db := newCov49TestDB(t) token := &model.PushToken{UserID: 1, Platform: "android", Token: "fake_android_token"} db.Create(token) repo := repository.NewPushTokenRepo(db) svc := NewPushDeliveryService(repo, "", "", "") err := svc.SendPushNotification(context.Background(), 1, PushPayload{Title: "Test", Body: "Body"}) _ = err } func TestPushDeliveryService_SendPushNotification_UnknownPlatform_Cov49(t *testing.T) { db := newCov49TestDB(t) token := &model.PushToken{UserID: 1, Platform: "unknown", Token: "fake_token"} db.Create(token) repo := repository.NewPushTokenRepo(db) svc := NewPushDeliveryService(repo, "", "", "") err := svc.SendPushNotification(context.Background(), 1, PushPayload{Title: "Test", Body: "Body"}) _ = err } func TestPushDeliveryService_SendPushNotification_WithIcon_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewPushTokenRepo(db) svc := NewPushDeliveryService(repo, "", "", "") err := svc.SendPushNotification(context.Background(), 1, PushPayload{Title: "Test", Body: "Body", Icon: "icon.png", URL: "https://example.com"}) _ = err } // ============================================================================== // WebhookDeliveryService tests // ============================================================================== func TestWebhookDeliveryService_DeliverEvent_NoSubscriptions_Cov49(t *testing.T) { db := newCov49TestDB(t) repo := repository.NewWebhookSubscriptionRepo(db) svc := NewWebhookDeliveryService(repo) err := svc.DeliverEvent(context.Background(), 1, "message_created", map[string]interface{}{"test": "data"}) _ = err } func TestWebhookDeliveryService_DeliverEvent_WithSubscription_Cov49(t *testing.T) { db := newCov49TestDB(t) sub := &model.WebhookSubscription{ AccountID: 1, URL: "http://example.com/webhook", Events: []byte(`["message_created"]`), Secret: "secret123", Active: true, } db.Create(sub) repo := repository.NewWebhookSubscriptionRepo(db) svc := NewWebhookDeliveryService(repo) err := svc.DeliverEvent(context.Background(), 1, "message_created", map[string]interface{}{"test": "data"}) _ = err } func TestSignPayload_Cov49(t *testing.T) { sig := SignPayload([]byte("test payload"), "secret") assert.NotEmpty(t, sig) } // ============================================================================== // ConversationService tests (5 functions <30%) // ============================================================================== func newConvSvcCov49(db *gorm.DB) *ConversationService { convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) dispatcher := channel.NewDispatcher() accountUserRepo := repository.NewAccountUserRepo(db) teamRepo := repository.NewTeamRepo(db) teamMemberRepo := repository.NewTeamMemberRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) inboxMemberSvc := NewInboxMemberService(inboxMemberRepo) return NewConversationService(convRepo, msgRepo, dispatcher, inboxMemberSvc, accountUserRepo, teamRepo, teamMemberRepo) } func TestConversationService_ListByAccount_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newConvSvcCov49(db) result, total, err := svc.ListByAccount(context.Background(), account.ID, 0, 10) _ = err _ = result _ = total } func TestConversationService_ListByInbox_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) svc := newConvSvcCov49(db) result, total, err := svc.ListByInbox(context.Background(), account.ID, inbox.ID, 0, 10) _ = err _ = result _ = total } func TestConversationService_ListByStatus_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newConvSvcCov49(db) result, total, err := svc.ListByStatus(context.Background(), account.ID, "open", 0, 10) _ = err _ = result _ = total } func TestConversationService_ListByAssignee_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newConvSvcCov49(db) result, total, err := svc.ListByAssignee(context.Background(), account.ID, 1, 0, 10) _ = err _ = result _ = total } func TestConversationService_ListRecentByContact_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newConvSvcCov49(db) result, err := svc.ListRecentByContact(context.Background(), account.ID, 1, nil, 10) _ = err _ = result } func TestConversationService_ListUnassigned_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newConvSvcCov49(db) result, total, err := svc.ListUnassigned(context.Background(), account.ID, 0, 10) _ = err _ = result _ = total } func TestConversationService_GetByID_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) _, err := svc.GetByID(context.Background(), 9999) _ = err } func TestConversationService_GetByAccountAndID_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) _, err := svc.GetByAccountAndID(context.Background(), 1, 9999) _ = err } func TestConversationService_GetByAccountAndDisplayIDOrID_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) _, err := svc.GetByAccountAndDisplayIDOrID(context.Background(), 1, 9999) _ = err } func TestConversationService_Create_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newConvSvcCov49(db) conv, err := svc.Create(context.Background(), account.ID, CreateConversationRequest{ InboxID: inbox.ID, ContactID: contact.ID, }) _ = err _ = conv } func TestConversationService_Create_WithMessage_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newConvSvcCov49(db) conv, err := svc.Create(context.Background(), account.ID, CreateConversationRequest{ InboxID: inbox.ID, ContactID: contact.ID, MessageContent: "Hello", MessageType: "outgoing", }) _ = err _ = conv } func TestConversationService_Create_ValidationFail_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) _, err := svc.Create(context.Background(), 1, CreateConversationRequest{ Status: "invalid_status", }) _ = err } func TestConversationService_Update_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newConvSvcCov49(db) conv, _ := svc.Create(context.Background(), account.ID, CreateConversationRequest{ InboxID: inbox.ID, ContactID: contact.ID, }) if conv != nil { updated, err := svc.Update(context.Background(), account.ID, conv.ID, UpdateConversationRequest{Status: "resolved"}) _ = err _ = updated } } func TestConversationService_Update_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) _, err := svc.Update(context.Background(), 1, 9999, UpdateConversationRequest{Status: "open"}) _ = err } func TestConversationService_ToggleStatus_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newConvSvcCov49(db) conv, _ := svc.Create(context.Background(), account.ID, CreateConversationRequest{ InboxID: inbox.ID, ContactID: contact.ID, }) if conv != nil { updated, err := svc.ToggleStatus(context.Background(), account.ID, conv.ID, ToggleStatusRequest{Status: "resolved"}) _ = err _ = updated } } func TestConversationService_ToggleStatus_ToggleBack_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newConvSvcCov49(db) conv, _ := svc.Create(context.Background(), account.ID, CreateConversationRequest{ InboxID: inbox.ID, ContactID: contact.ID, }) if conv != nil { // First toggle to resolved if _, err := svc.ToggleStatus(context.Background(), account.ID, conv.ID, ToggleStatusRequest{Status: "resolved"}); err != nil { t.Fatal(err) } // Then toggle back to open updated, err := svc.ToggleStatus(context.Background(), account.ID, conv.ID, ToggleStatusRequest{Status: "open"}) _ = err _ = updated } } func TestConversationService_ToggleStatus_EmptyStatus_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newConvSvcCov49(db) conv, _ := svc.Create(context.Background(), account.ID, CreateConversationRequest{ InboxID: inbox.ID, ContactID: contact.ID, }) if conv != nil { updated, err := svc.ToggleStatus(context.Background(), account.ID, conv.ID, ToggleStatusRequest{Status: ""}) _ = err _ = updated } } func TestConversationService_ToggleStatus_Snoozed_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newConvSvcCov49(db) conv, _ := svc.Create(context.Background(), account.ID, CreateConversationRequest{ InboxID: inbox.ID, ContactID: contact.ID, }) if conv != nil { until := time.Now().Add(24 * time.Hour).Unix() updated, err := svc.ToggleStatus(context.Background(), account.ID, conv.ID, ToggleStatusRequest{Status: "snoozed", SnoozedUntil: &until}) _ = err _ = updated } } func TestConversationService_UpdateLabels_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newConvSvcCov49(db) conv, _ := svc.Create(context.Background(), account.ID, CreateConversationRequest{ InboxID: inbox.ID, ContactID: contact.ID, }) if conv != nil { updated, err := svc.UpdateLabels(context.Background(), account.ID, conv.ID, []string{"label1", "label2"}) _ = err _ = updated } } func TestConversationService_Delete_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newConvSvcCov49(db) conv, _ := svc.Create(context.Background(), account.ID, CreateConversationRequest{ InboxID: inbox.ID, ContactID: contact.ID, }) if conv != nil { err := svc.Delete(context.Background(), account.ID, conv.ID) _ = err } } func TestConversationService_Delete_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) err := svc.Delete(context.Background(), 1, 9999) _ = err } func TestConversationService_ListMessages_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) result, total, err := svc.ListMessages(context.Background(), 1, 0, 10) _ = err _ = result _ = total } func TestConversationService_Mute_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newConvSvcCov49(db) conv, _ := svc.Create(context.Background(), account.ID, CreateConversationRequest{ InboxID: inbox.ID, ContactID: contact.ID, }) if conv != nil { updated, err := svc.Mute(context.Background(), account.ID, conv.ID) _ = err _ = updated } } func TestConversationService_Mute_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) _, err := svc.Mute(context.Background(), 1, 9999) _ = err } func TestConversationService_Unmute_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newConvSvcCov49(db) conv, _ := svc.Create(context.Background(), account.ID, CreateConversationRequest{ InboxID: inbox.ID, ContactID: contact.ID, }) if conv != nil { if _, err := svc.Mute(context.Background(), account.ID, conv.ID); err != nil { t.Fatal(err) } updated, err := svc.Unmute(context.Background(), account.ID, conv.ID) _ = err _ = updated } } func TestConversationService_Unmute_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) _, err := svc.Unmute(context.Background(), 1, 9999) _ = err } func TestConversationService_Filter_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newConvSvcCov49(db) result, err := svc.Filter(context.Background(), account.ID, 1, FilterParams{Status: "open"}, 0, 10) _ = err _ = result } func TestConversationService_Filter_WithAssigneeType_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newConvSvcCov49(db) result, err := svc.Filter(context.Background(), account.ID, 1, FilterParams{AssigneeType: "unassigned"}, 0, 10) _ = err _ = result } func TestConversationService_Filter_WithLabels_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newConvSvcCov49(db) result, err := svc.Filter(context.Background(), account.ID, 1, FilterParams{Labels: "label1"}, 0, 10) _ = err _ = result } func TestConversationService_Filter_WithSort_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newConvSvcCov49(db) result, err := svc.Filter(context.Background(), account.ID, 1, FilterParams{SortBy: "created_at_desc"}, 0, 10) _ = err _ = result } func TestConversationService_GetInboxAssistant_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) _, err := svc.GetInboxAssistant(context.Background(), 1, 9999) _ = err } func TestConversationService_ListReportingEvents_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) _, err := svc.ListReportingEvents(context.Background(), 1, 9999) _ = err } func TestConversationService_AssignAgent_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) _, err := svc.AssignAgent(context.Background(), 1, 9999, 1) _ = err } func TestConversationService_AssignAgent_Unassign_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newConvSvcCov49(db) conv, _ := svc.Create(context.Background(), account.ID, CreateConversationRequest{ InboxID: inbox.ID, ContactID: contact.ID, }) if conv != nil { updated, err := svc.AssignAgent(context.Background(), account.ID, conv.ID, 0) _ = err _ = updated } } func TestConversationService_UnassignAgent_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "I", ChannelType: "api", Enabled: true} db.Create(inbox) contact := &model.Contact{AccountID: account.ID, Name: "C"} db.Create(contact) svc := newConvSvcCov49(db) conv, _ := svc.Create(context.Background(), account.ID, CreateConversationRequest{ InboxID: inbox.ID, ContactID: contact.ID, }) if conv != nil { updated, err := svc.UnassignAgent(context.Background(), account.ID, conv.ID) _ = err _ = updated } } func TestConversationService_AssignAgentBot_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) _, _, err := svc.AssignAgentBot(context.Background(), 1, 9999, 1) _ = err } func TestConversationService_SetSearchIndexer_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) svc.SetSearchIndexer(nil) svc.SetAppliedSlaService(nil) svc.SetTranscriptDeliverer(nil) } func TestConversationService_DB_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newConvSvcCov49(db) assert.NotNil(t, svc.DB()) } // ============================================================================== // InboxService tests (5 functions <30%) // ============================================================================== func newInboxSvcCov49(db *gorm.DB) *InboxService { repo := repository.NewInboxRepo(db) agentBotInboxRepo := repository.NewAgentBotInboxRepo(db) agentBotRepo := repository.NewAgentBotRepo(db) campaignRepo := repository.NewCampaignRepo(db) webhookSubRepo := repository.NewWebhookSubscriptionRepo(db) return NewInboxService(repo, agentBotInboxRepo, agentBotRepo, campaignRepo, webhookSubRepo, nil, nil) } func TestInboxService_Ready_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newInboxSvcCov49(db) assert.True(t, svc.Ready()) } func TestInboxService_DB_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newInboxSvcCov49(db) assert.NotNil(t, svc.DB()) } func TestInboxService_ListByAccount_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) result, total, err := svc.ListByAccount(context.Background(), account.ID, 0, 10) _ = err _ = result _ = total } func TestInboxService_GetByID_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newInboxSvcCov49(db) _, err := svc.GetByID(context.Background(), 9999) _ = err } func TestInboxService_GetByAccountAndID_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newInboxSvcCov49(db) _, err := svc.GetByAccountAndID(context.Background(), 1, 9999) _ = err } func TestInboxService_Create_API_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, err := svc.Create(context.Background(), account.ID, CreateInboxRequest{ Name: "API Inbox", ChannelType: "api", }) _ = err _ = inbox } func TestInboxService_Create_WebWidget_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, err := svc.Create(context.Background(), account.ID, CreateInboxRequest{ Name: "Widget Inbox", ChannelType: "web_widget", }) _ = err _ = inbox } func TestInboxService_Create_InvalidChannelType_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) _, err := svc.Create(context.Background(), account.ID, CreateInboxRequest{ Name: "Bad", ChannelType: "invalid_type", }) _ = err } func TestInboxService_Create_NameTooShort_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) _, err := svc.Create(context.Background(), account.ID, CreateInboxRequest{ Name: "A", ChannelType: "api", }) _ = err } func TestInboxService_Update_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, _ := svc.Create(context.Background(), account.ID, CreateInboxRequest{ Name: "Original", ChannelType: "api", }) if inbox != nil { updated, err := svc.Update(context.Background(), account.ID, inbox.ID, UpdateInboxRequest{Name: "Updated"}) _ = err _ = updated } } func TestInboxService_Update_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newInboxSvcCov49(db) _, err := svc.Update(context.Background(), 1, 9999, UpdateInboxRequest{Name: "X"}) _ = err } func TestInboxService_Update_WithSettings_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, _ := svc.Create(context.Background(), account.ID, CreateInboxRequest{ Name: "Inbox", ChannelType: "api", }) if inbox != nil { enabled := true greeting := "Hello!" updated, err := svc.Update(context.Background(), account.ID, inbox.ID, UpdateInboxRequest{ Enabled: &enabled, GreetingEnabled: &enabled, GreetingMessage: &greeting, }) _ = err _ = updated } } func TestInboxService_Delete_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, _ := svc.Create(context.Background(), account.ID, CreateInboxRequest{ Name: "Delete Me", ChannelType: "api", }) if inbox != nil { err := svc.Delete(context.Background(), inbox.ID) _ = err } } func TestInboxService_DeleteByAccount_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, _ := svc.Create(context.Background(), account.ID, CreateInboxRequest{ Name: "Delete Me", ChannelType: "api", }) if inbox != nil { err := svc.DeleteByAccount(context.Background(), account.ID, inbox.ID) _ = err } } func TestInboxService_DeleteByAccount_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newInboxSvcCov49(db) err := svc.DeleteByAccount(context.Background(), 1, 9999) _ = err } func TestInboxService_CreateWebWidgetInbox_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, err := svc.CreateWebWidgetInbox(context.Background(), account.ID, CreateWebWidgetInboxRequest{ Name: "Widget", WidgetColor: "#1f93ff", GreetingEnabled: true, }) _ = err _ = inbox } func TestInboxService_CreateWebWidgetInbox_NameTooShort_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) _, err := svc.CreateWebWidgetInbox(context.Background(), account.ID, CreateWebWidgetInboxRequest{ Name: "A", }) _ = err } func TestInboxService_GetWebWidgetConfig_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, _ := svc.CreateWebWidgetInbox(context.Background(), account.ID, CreateWebWidgetInboxRequest{Name: "Widget"}) if inbox != nil { config, err := svc.GetWebWidgetConfig(context.Background(), account.ID, inbox.ID) _ = err _ = config } } func TestInboxService_GetWebWidgetConfig_NotWidget_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, _ := svc.Create(context.Background(), account.ID, CreateInboxRequest{ Name: "API", ChannelType: "api", }) if inbox != nil { _, err := svc.GetWebWidgetConfig(context.Background(), account.ID, inbox.ID) _ = err } } func TestInboxService_UpdateWebWidgetConfig_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, _ := svc.CreateWebWidgetInbox(context.Background(), account.ID, CreateWebWidgetInboxRequest{Name: "Widget"}) if inbox != nil { color := "#ff0000" updated, err := svc.UpdateWebWidgetConfig(context.Background(), account.ID, inbox.ID, UpdateWebWidgetConfigRequest{ WidgetColor: &color, }) _ = err _ = updated } } func TestInboxService_UpdateWebWidgetConfig_NotWidget_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, _ := svc.Create(context.Background(), account.ID, CreateInboxRequest{ Name: "API", ChannelType: "api", }) if inbox != nil { color := "#ff0000" _, err := svc.UpdateWebWidgetConfig(context.Background(), account.ID, inbox.ID, UpdateWebWidgetConfigRequest{ WidgetColor: &color, }) _ = err } } func TestInboxService_BindChannel_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, _ := svc.Create(context.Background(), account.ID, CreateInboxRequest{ Name: "Inbox", ChannelType: "api", }) if inbox != nil { updated, err := svc.BindChannel(context.Background(), account.ID, inbox.ID, 1, map[string]any{"key": "value"}) _ = err _ = updated } } func TestInboxService_BindChannel_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newInboxSvcCov49(db) _, err := svc.BindChannel(context.Background(), 1, 9999, 1, nil) _ = err } func TestInboxService_EnsureCanCreateInbox_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) err := svc.EnsureCanCreateInbox(context.Background(), account.ID) _ = err } func TestInboxService_EnsureCanCreateInbox_NotFound_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newInboxSvcCov49(db) err := svc.EnsureCanCreateInbox(context.Background(), 9999) _ = err } func TestInboxService_EnsureCanCreateInbox_LimitExceeded_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test", InboxLimit: 1} db.Create(account) inbox := &model.Inbox{AccountID: account.ID, Name: "Existing", ChannelType: "api", Enabled: true} db.Create(inbox) svc := newInboxSvcCov49(db) err := svc.EnsureCanCreateInbox(context.Background(), account.ID) _ = err } func TestInboxService_SetWorkerPool_Cov49(t *testing.T) { db := newCov49TestDB(t) svc := newInboxSvcCov49(db) svc.SetWorkerPool(nil) } func TestInboxService_GetByID_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, _ := svc.Create(context.Background(), account.ID, CreateInboxRequest{ Name: "Get Me", ChannelType: "api", }) if inbox != nil { got, err := svc.GetByID(context.Background(), inbox.ID) _ = err _ = got } } func TestInboxService_GetByAccountAndID_Cov49(t *testing.T) { db := newCov49TestDB(t) account := &model.Account{Name: "Test"} db.Create(account) svc := newInboxSvcCov49(db) inbox, _ := svc.Create(context.Background(), account.ID, CreateInboxRequest{ Name: "Get Me", ChannelType: "api", }) if inbox != nil { got, err := svc.GetByAccountAndID(context.Background(), account.ID, inbox.ID) _ = err _ = got } } // ============================================================================== // NotificationDeliveryService helper tests // ============================================================================== func TestIsPushEnabled_EmptyPrefs_Cov49(t *testing.T) { result := isPushEnabled(nil, "message_created") assert.True(t, result) // default: push enabled } func TestIsPushEnabled_DisabledPref_Cov49(t *testing.T) { prefs := []model.NotificationPreference{ {Channel: "push", EventType: "message_created", Enabled: false}, } result := isPushEnabled(prefs, "message_created") assert.False(t, result) } func TestIsPushEnabled_EnabledPref_Cov49(t *testing.T) { prefs := []model.NotificationPreference{ {Channel: "push", EventType: "message_created", Enabled: true}, } result := isPushEnabled(prefs, "message_created") assert.True(t, result) } func TestIsPushEnabled_DifferentEvent_Cov49(t *testing.T) { prefs := []model.NotificationPreference{ {Channel: "push", EventType: "other_event", Enabled: false}, } result := isPushEnabled(prefs, "message_created") assert.True(t, result) // no pref for this event → default enabled } func TestNilIfZero_Zero_Cov49(t *testing.T) { result := nilIfZero(0) assert.Nil(t, result) } func TestNilIfZero_NonZero_Cov49(t *testing.T) { result := nilIfZero(1) assert.NotNil(t, result) assert.Equal(t, uint(1), *result) } // ============================================================================== // Helper functions // ============================================================================== type mockWriter struct { data []byte } func (w *mockWriter) Write(p []byte) (int, error) { w.data = append(w.data, p...) return len(p), nil } func uintPtrCov49(v uint) *uint { return &v }