package service import ( "context" "testing" "time" "github.com/gochat/gochat/internal/campaign" "github.com/gochat/gochat/internal/model" channelmodel "github.com/gochat/gochat/internal/model/channel" "github.com/gochat/gochat/internal/repository" "github.com/gochat/gochat/internal/search" "gorm.io/datatypes" "gorm.io/gorm" ) // ============================================================ // coverage44_test.go — DB-backed CRUD tests for internal/service // Targets: widget_service, whatsapp_call_service, notification_delivery_service, // contact_service, profile_service, analytics_service, captain_document_service, // push_delivery_service, inbox_service, conversation_service // ============================================================ // ---------- helpers ---------- func setupWidgetServiceCov44(t *testing.T) (*WidgetService, *gorm.DB) { t.Helper() db := newSimpleServiceTestDB(t, &model.WhatsAppCall{}, &model.Call{}, &model.WidgetOfflineMessage{}, &model.WidgetThemeConfig{}, &model.PreChatForm{}, &model.WidgetFileUpload{}, &campaign.Campaign{}, &model.ContactNote{}, &model.ConversationParticipant{}, &model.WorkingHour{}, &model.UserSession{}, &model.AccessToken{}, &model.ReportingEventsRollup{}, &model.CaptainDocument{}, &model.CaptainAssistant{}, &model.CaptainAssistantResponse{}, &model.CaptainInbox{}, &model.WebhookSubscription{}, &channelmodel.ChannelAPI{}, &channelmodel.ChannelWhatsApp{}, &channelmodel.ChannelEmail{}, &channelmodel.ChannelTwilioSMS{}, &model.Company{}, &model.CompanyNote{}, &model.CsatTemplate{}, &model.DataImport{}, &model.CustomRole{}, &model.Portal{}, &model.PortalMember{}, &model.Category{}, &model.RelatedCategory{}, ) repo := repository.NewInboxRepo(db) contactRepo := repository.NewContactRepo(db) contactInboxRepo := repository.NewContactInboxRepo(db) conversationRepo := repository.NewConversationRepo(db) messageRepo := repository.NewMessageRepo(db) themeConfigRepo := repository.NewWidgetThemeConfigRepo(db) preChatFormRepo := repository.NewPreChatFormRepo(db) fileUploadRepo := repository.NewWidgetFileUploadRepo(db) offlineMessageRepo := repository.NewWidgetOfflineMessageRepo(db) inboxMemberRepo := repository.NewInboxMemberRepo(db) tagRepo := repository.NewTagRepo(db) campaignRepo := repository.NewCampaignRepo(db) svc := NewWidgetService( repo, contactRepo, contactInboxRepo, conversationRepo, messageRepo, nil, // typingIndicator themeConfigRepo, preChatFormRepo, fileUploadRepo, offlineMessageRepo, inboxMemberRepo, tagRepo, campaignRepo, ) return svc, db } func createCov44Account(t *testing.T, db *gorm.DB) *model.Account { t.Helper() acc := &model.Account{Name: "Cov44Account", Locale: "en", Status: "active", Active: true} if err := db.Create(acc).Error; err != nil { t.Fatalf("create account: %v", err) } return acc } func createCov44User(t *testing.T, db *gorm.DB) *model.User { t.Helper() u := &model.User{Name: "Cov44User", Email: "cov44@test.com", Type: "User", Role: "agent"} if err := db.Create(u).Error; err != nil { t.Fatalf("create user: %v", err) } return u } func createCov44Inbox(t *testing.T, db *gorm.DB, accountID uint, channelType string) *model.Inbox { t.Helper() inbox := &model.Inbox{ AccountID: accountID, Name: "Cov44Inbox", ChannelType: channelType, ChannelID: 1, Enabled: true, } if err := db.Create(inbox).Error; err != nil { t.Fatalf("create inbox: %v", err) } return inbox } func createCov44Contact(t *testing.T, db *gorm.DB, accountID uint) *model.Contact { t.Helper() c := &model.Contact{AccountID: accountID, Name: "Cov44Contact", Email: "c44@test.com", ContactType: "lead"} if err := db.Create(c).Error; err != nil { t.Fatalf("create contact: %v", err) } return c } func createCov44ContactInbox(t *testing.T, db *gorm.DB, contactID, inboxID uint) *model.ContactInbox { t.Helper() ci := &model.ContactInbox{ ContactID: contactID, InboxID: inboxID, SourceID: "c44src", PubsubToken: "c44pubsub", HMACToken: "c44hmac", } if err := db.Create(ci).Error; err != nil { t.Fatalf("create contact_inbox: %v", err) } return ci } func createCov44Conversation(t *testing.T, db *gorm.DB, accountID, inboxID, contactID uint) *model.Conversation { t.Helper() conv := &model.Conversation{ AccountID: accountID, InboxID: inboxID, ContactID: contactID, Status: "open", Priority: "medium", ChannelType: "web_widget", Channel: "web_widget", } if err := db.Create(conv).Error; err != nil { t.Fatalf("create conversation: %v", err) } return conv } // ============================================================ // WidgetService tests (~35) // ============================================================ func TestWidgetService_Init_EmptyToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Init(context.Background(), WidgetInitRequest{}) _ = err } func TestWidgetService_Init_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Init(context.Background(), WidgetInitRequest{WebsiteToken: "notfound"}) _ = err } func TestWidgetService_Init_Success_Cov44(t *testing.T) { svc, db := setupWidgetServiceCov44(t) acc := createCov44Account(t, db) config := `{"website_token":"wstest","hmac_token":"hmactest"}` inbox := &model.Inbox{AccountID: acc.ID, Name: "WidgetInbox", ChannelType: "web_widget", ChannelID: 1, Enabled: true, ChannelConfig: config} if err := db.Create(inbox).Error; err != nil { t.Fatal(err) } defer func() { _ = recover() }() _, err := svc.Init(context.Background(), WidgetInitRequest{WebsiteToken: "wstest"}) _ = err } func TestWidgetService_SendMessage_NoToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.SendMessage(context.Background(), WidgetSendMessageRequest{Content: "hello"}) _ = err } func TestWidgetService_SendMessage_EmptyContent_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.SendMessage(context.Background(), WidgetSendMessageRequest{WidgetToken: "tok"}) _ = err } func TestWidgetService_SendMessage_InvalidToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.SendMessage(context.Background(), WidgetSendMessageRequest{WidgetToken: "invalid", Content: "hi"}) _ = err } func TestWidgetService_GetConversations_InvalidToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetConversations(context.Background(), "invalid") _ = err } func TestWidgetService_GetLatestConversation_InvalidToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetLatestConversation(context.Background(), "invalid") _ = err } func TestWidgetService_GetConversation_InvalidToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetConversation(context.Background(), "invalid", 1) _ = err } func TestWidgetService_GetCableToken_InvalidToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetCableToken(context.Background(), "invalid") _ = err } func TestWidgetService_UpdateContact_InvalidToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.UpdateContact(context.Background(), "invalid", "name", "email") _ = err } func TestWidgetService_GetContact_InvalidToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetContact(context.Background(), "invalid") _ = err } func TestWidgetService_UpdateContactProfile_InvalidToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.UpdateContactProfile(context.Background(), "invalid", WidgetContactUpdate{Name: "x"}) _ = err } func TestWidgetService_SetUser_NoToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.SetUser(context.Background(), WidgetSetUserRequest{}) _ = err } func TestWidgetService_SetUser_NoWidgetToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.SetUser(context.Background(), WidgetSetUserRequest{WebsiteToken: "ws"}) _ = err } func TestWidgetService_GetInboxByWebsiteToken_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetInboxByWebsiteToken(context.Background(), "nonexist") _ = err } func TestWidgetService_GetInboxByWebsiteToken_Success_Cov44(t *testing.T) { svc, db := setupWidgetServiceCov44(t) acc := createCov44Account(t, db) config := `{"website_token":"wsfound"}` inbox := &model.Inbox{AccountID: acc.ID, Name: "WI", ChannelType: "web_widget", ChannelID: 1, Enabled: true, ChannelConfig: config} if err := db.Create(inbox).Error; err != nil { t.Fatal(err) } defer func() { _ = recover() }() got, err := svc.GetInboxByWebsiteToken(context.Background(), "wsfound") _ = err _ = got } func TestWidgetService_GetInboxMembers_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetInboxMembersByWebsiteToken(context.Background(), "nope") _ = err } func TestWidgetService_GetCampaigns_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetCampaignsByWebsiteToken(context.Background(), "nope") _ = err } func TestWidgetService_TrackEvent_NoToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() err := svc.TrackEvent(context.Background(), "", "tok", "event", nil) _ = err } func TestWidgetService_TrackEvent_NoName_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() err := svc.TrackEvent(context.Background(), "ws", "tok", "", nil) _ = err } func TestWidgetService_AddLabel_InvalidToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() err := svc.AddLabelToLatestConversation(context.Background(), "invalid", "lbl") _ = err } func TestWidgetService_RemoveLabel_InvalidToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() err := svc.RemoveLabelFromLatestConversation(context.Background(), "invalid", "lbl") _ = err } func TestWidgetService_PublicGetInbox_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, _, err := svc.PublicGetInbox(context.Background(), "nonexist") _ = err } func TestWidgetService_PublicCreateContact_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.PublicCreateContact(context.Background(), "nonexist", PublicContactRequest{}) _ = err } func TestWidgetService_PublicGetContact_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.PublicGetContact(context.Background(), "nonexist", "src") _ = err } func TestWidgetService_PublicUpdateContact_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.PublicUpdateContact(context.Background(), "nonexist", "src", PublicContactRequest{}) _ = err } func TestWidgetService_PublicListConversations_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.PublicListConversations(context.Background(), "nonexist", "src") _ = err } func TestWidgetService_PublicCreateConversation_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.PublicCreateConversation(context.Background(), "nonexist", "src", PublicConversationRequest{}) _ = err } func TestWidgetService_PublicGetConversation_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.PublicGetConversation(context.Background(), "nonexist", "src", 1) _ = err } func TestWidgetService_PublicToggleStatus_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.PublicToggleStatus(context.Background(), "nonexist", "src", 1) _ = err } func TestWidgetService_PublicUpdateLastSeen_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.PublicUpdateLastSeen(context.Background(), "nonexist", "src", 1) _ = err } func TestWidgetService_PublicToggleTyping_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() err := svc.PublicToggleTyping(context.Background(), "nonexist", "src", 1, true) _ = err } func TestWidgetService_PublicListMessages_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, _, _, err := svc.PublicListMessages(context.Background(), "nonexist", "src", 1, PublicMessageListOptions{}) _ = err } func TestWidgetService_PublicCreateMessage_EmptyContent_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, _, _, err := svc.PublicCreateMessage(context.Background(), "nonexist", "src", 1, PublicMessageRequest{}) _ = err } func TestWidgetService_GetLatestConversationMessages_InvalidToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, _, _, err := svc.GetLatestConversationMessages(context.Background(), "invalid", 0, 0) _ = err } func TestWidgetService_GetMessages_InvalidToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, _, err := svc.GetMessages(context.Background(), "invalid", 1, 0, 20) _ = err } func TestWidgetService_GetMessageAttachments_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetMessageAttachments(context.Background(), 999) _ = err } func TestWidgetService_SubmitOfflineMessage_Cov44(t *testing.T) { svc, db := setupWidgetServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") defer func() { _ = recover() }() sub := &model.WidgetOfflineMessageSubmission{Name: "V", Email: "v@t.com", Message: "hi"} _, err := svc.SubmitOfflineMessage(context.Background(), inbox.ID, acc.ID, sub, "http://referer", "{}") _ = err } func TestWidgetService_GetOfflineMessages_Cov44(t *testing.T) { svc, db := setupWidgetServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") msg := &model.WidgetOfflineMessage{InboxID: inbox.ID, AccountID: acc.ID, Content: "test", Status: model.OfflineStatusPending} db.Create(msg) defer func() { _ = recover() }() _, err := svc.GetOfflineMessages(context.Background(), inbox.ID) _ = err } func TestWidgetService_ListOfflineMessagesByAccount_Cov44(t *testing.T) { svc, db := setupWidgetServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") msg := &model.WidgetOfflineMessage{InboxID: inbox.ID, AccountID: acc.ID, Content: "test", Status: model.OfflineStatusPending} db.Create(msg) defer func() { _ = recover() }() _, _, err := svc.ListOfflineMessagesByAccount(context.Background(), acc.ID, 1, 25) _ = err } func TestWidgetService_CountPendingOfflineMessages_Cov44(t *testing.T) { svc, db := setupWidgetServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") msg := &model.WidgetOfflineMessage{InboxID: inbox.ID, AccountID: acc.ID, Content: "test", Status: model.OfflineStatusPending} db.Create(msg) defer func() { _ = recover() }() _, err := svc.CountPendingOfflineMessages(context.Background(), inbox.ID) _ = err } func TestWidgetService_DismissOfflineMessage_Cov44(t *testing.T) { svc, db := setupWidgetServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") msg := &model.WidgetOfflineMessage{InboxID: inbox.ID, AccountID: acc.ID, Content: "test", Status: model.OfflineStatusPending} db.Create(msg) defer func() { _ = recover() }() err := svc.DismissOfflineMessage(context.Background(), msg.ID) _ = err } func TestWidgetService_MarkOfflineMessageConverted_Cov44(t *testing.T) { svc, db := setupWidgetServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") msg := &model.WidgetOfflineMessage{InboxID: inbox.ID, AccountID: acc.ID, Content: "test", Status: model.OfflineStatusPending} db.Create(msg) defer func() { _ = recover() }() err := svc.MarkOfflineMessageConverted(context.Background(), msg.ID, 1) _ = err } func TestWidgetService_ConvertOfflineMessage_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, _, err := svc.ConvertOfflineMessageToConversation(context.Background(), 9999) _ = err } func TestWidgetService_GetThemeConfigByInboxID_Zero_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetThemeConfigByInboxID(context.Background(), 0) _ = err } func TestWidgetService_GetThemeConfigByInboxID_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetThemeConfigByInboxID(context.Background(), 999) _ = err } func TestWidgetService_GetThemeConfig_EmptyToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetThemeConfig(context.Background(), "") _ = err } func TestWidgetService_GetThemeConfig_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetThemeConfig(context.Background(), "nonexist") _ = err } func TestWidgetService_UpdateThemeConfig_ZeroID_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.UpdateThemeConfig(context.Background(), 0, &model.WidgetThemeConfig{}) _ = err } func TestWidgetService_UpdateThemeConfig_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.UpdateThemeConfig(context.Background(), 999, &model.WidgetThemeConfig{}) _ = err } func TestWidgetService_GetPreChatFormByInboxID_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetPreChatFormByInboxID(context.Background(), 999) _ = err } func TestWidgetService_GetPreChatForm_EmptyToken_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetPreChatForm(context.Background(), "") _ = err } func TestWidgetService_GetPreChatForm_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetPreChatForm(context.Background(), "nonexist") _ = err } func TestWidgetService_UpdatePreChatForm_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.UpdatePreChatForm(context.Background(), 999, &model.PreChatForm{}) _ = err } // ============================================================ // WhatsAppCallService tests (~20) // ============================================================ func setupWhatsAppCallServiceCov44(t *testing.T) (*WhatsAppCallService, *gorm.DB) { t.Helper() db := newSimpleServiceTestDB(t, &model.WhatsAppCall{}, &model.Call{}, &channelmodel.ChannelWhatsApp{}, &model.CustomRole{}, &model.ConversationParticipant{}, ) repo := repository.NewWhatsAppCallRepo(db) svc := NewWhatsAppCallService(repo) return svc, db } func TestWhatsAppCallService_GetByCallID_NotFound_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetByCallID(context.Background(), "nonexist") _ = err } func TestWhatsAppCallService_GetByCallID_Found_Cov44(t *testing.T) { svc, db := setupWhatsAppCallServiceCov44(t) wc := &model.WhatsAppCall{CallID: "call1", InboxID: 1, ConversationID: 1, CallStatus: "ringing"} db.Create(wc) defer func() { _ = recover() }() _, err := svc.GetByCallID(context.Background(), "call1") _ = err } func TestWhatsAppCallService_ListByConversation_Cov44(t *testing.T) { svc, db := setupWhatsAppCallServiceCov44(t) wc := &model.WhatsAppCall{CallID: "call2", InboxID: 1, ConversationID: 5, CallStatus: "active"} db.Create(wc) defer func() { _ = recover() }() _, err := svc.ListByConversation(context.Background(), 5) _ = err } func TestWhatsAppCallService_ListByConversation_Empty_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.ListByConversation(context.Background(), 999) _ = err } func TestWhatsAppCallService_CreateFromRequest_InvalidStatus_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.CreateFromRequest(context.Background(), &WhatsAppCallCreateRequest{CallID: "c", InboxID: 1, ConversationID: 1, CallStatus: "bad"}) _ = err } func TestWhatsAppCallService_CreateFromRequest_Success_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.CreateFromRequest(context.Background(), &WhatsAppCallCreateRequest{CallID: "c3", InboxID: 1, ConversationID: 1, CallStatus: "ringing"}) _ = err } func TestWhatsAppCallService_UpdateByCallID_InvalidStatus_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.UpdateByCallID(context.Background(), "c", "bad", 0) _ = err } func TestWhatsAppCallService_UpdateByCallID_NotFound_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.UpdateByCallID(context.Background(), "nonexist", "active", 10) _ = err } func TestWhatsAppCallService_UpdateByCallID_Success_Cov44(t *testing.T) { svc, db := setupWhatsAppCallServiceCov44(t) wc := &model.WhatsAppCall{CallID: "c4", InboxID: 1, ConversationID: 1, CallStatus: "ringing"} db.Create(wc) defer func() { _ = recover() }() _, err := svc.UpdateByCallID(context.Background(), "c4", "active", 30) _ = err } func TestWhatsAppCallService_DeleteByCallID_NotFound_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() err := svc.DeleteByCallID(context.Background(), "nonexist") _ = err } func TestWhatsAppCallService_DeleteByCallID_Success_Cov44(t *testing.T) { svc, db := setupWhatsAppCallServiceCov44(t) wc := &model.WhatsAppCall{CallID: "c5", InboxID: 1, ConversationID: 1, CallStatus: "ended"} db.Create(wc) defer func() { _ = recover() }() err := svc.DeleteByCallID(context.Background(), "c5") _ = err } func TestWhatsAppCallService_GetAccountCall_NotFound_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetAccountCall(context.Background(), 1, 999) _ = err } func TestWhatsAppCallService_GetAccountCall_Found_Cov44(t *testing.T) { svc, db := setupWhatsAppCallServiceCov44(t) call := &model.Call{AccountID: 1, Provider: "whatsapp", Direction: "outgoing", Status: "ringing", ProviderCallID: "pc1"} db.Create(call) defer func() { _ = recover() }() _, err := svc.GetAccountCall(context.Background(), 1, call.ID) _ = err } func TestWhatsAppCallService_ListAccountCalls_Empty_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.ListAccountCalls(context.Background(), 1, AccountCallListFilter{Page: 1}) _ = err } func TestWhatsAppCallService_ListAccountCalls_WithFilter_Cov44(t *testing.T) { svc, db := setupWhatsAppCallServiceCov44(t) call := &model.Call{AccountID: 1, Provider: "whatsapp", Direction: "outgoing", Status: "ringing", ProviderCallID: "pc2"} db.Create(call) defer func() { _ = recover() }() _, err := svc.ListAccountCalls(context.Background(), 1, AccountCallListFilter{Page: 1, Status: "ringing", Direction: "outbound"}) _ = err } func TestWhatsAppCallService_ListAccountCalls_AccountWide_Cov44(t *testing.T) { svc, db := setupWhatsAppCallServiceCov44(t) call := &model.Call{AccountID: 1, Provider: "whatsapp", Direction: "outgoing", Status: "completed", ProviderCallID: "pc3"} db.Create(call) defer func() { _ = recover() }() _, err := svc.ListAccountCalls(context.Background(), 1, AccountCallListFilter{Page: 1, AccountWide: true}) _ = err } func TestWhatsAppCallService_Initiate_NoSDP_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Initiate(context.Background(), 1, WhatsAppCallInitiateRequest{ConversationID: 1}) _ = err } func TestWhatsAppCallService_Initiate_NoConversation_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Initiate(context.Background(), 1, WhatsAppCallInitiateRequest{ConversationID: 999, SDPOffer: "sdp"}) _ = err } func TestWhatsAppCallService_Accept_NoSDP_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Accept(context.Background(), 1, 1, 1, "") _ = err } func TestWhatsAppCallService_Accept_NotFound_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Accept(context.Background(), 1, 999, 1, "sdp") _ = err } func TestWhatsAppCallService_Reject_NotFound_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Reject(context.Background(), 1, 999, 1) _ = err } func TestWhatsAppCallService_Terminate_NotFound_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Terminate(context.Background(), 1, 999, 1) _ = err } func TestWhatsAppCallService_UploadRecording_NotFound_Cov44(t *testing.T) { svc, _ := setupWhatsAppCallServiceCov44(t) defer func() { _ = recover() }() _, err := svc.UploadRecording(context.Background(), 1, 999, "rec.mp3", 100) _ = err } func TestWhatsAppCallService_UploadRecording_NoFileName_Cov44(t *testing.T) { svc, db := setupWhatsAppCallServiceCov44(t) call := &model.Call{AccountID: 1, Provider: "whatsapp", Status: "completed", ProviderCallID: "pc4"} db.Create(call) defer func() { _ = recover() }() _, err := svc.UploadRecording(context.Background(), 1, call.ID, "", 100) _ = err } // ============================================================ // ContactService tests (~30) // ============================================================ func setupContactServiceCov44(t *testing.T) (*ContactService, *gorm.DB) { t.Helper() db := newSimpleServiceTestDB(t, &model.ContactNote{}, &model.ConversationParticipant{}, &model.Company{}, &model.ContactExport{}, &model.DataImport{}, &campaign.Campaign{}, &model.WorkingHour{}, ) repo := repository.NewContactRepo(db) contactInboxSvc := NewContactInboxService(repository.NewContactInboxRepo(db)) noteRepo := repository.NewNoteRepo(db) svc := NewContactService(repo, contactInboxSvc, noteRepo) return svc, db } func TestContactService_Create_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() c, err := svc.Create(context.Background(), acc.ID, CreateContactRequest{Name: "C1", Email: "c1@t.com"}) _ = err _ = c } func TestContactService_Create_Validation_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() _, err := svc.Create(context.Background(), acc.ID, CreateContactRequest{Name: ""}) _ = err } func TestContactService_GetByID_NotFound_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetByID(context.Background(), 999) _ = err } func TestContactService_GetByID_Found_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) c := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, err := svc.GetByID(context.Background(), c.ID) _ = err } func TestContactService_GetByAccountAndID_NotFound_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetByAccountAndID(context.Background(), 1, 999) _ = err } func TestContactService_GetByAccountAndID_Found_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) c := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, err := svc.GetByAccountAndID(context.Background(), acc.ID, c.ID) _ = err } func TestContactService_ListByAccount_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, _, err := svc.ListByAccount(context.Background(), acc.ID, 0, 10, "id ASC") _ = err } func TestContactService_Search_Empty_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() _, _, err := svc.Search(context.Background(), acc.ID, "", 0, 10, "id ASC", search.SearchModeILike) _ = err } func TestContactService_Search_WithQuery_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, _, err := svc.Search(context.Background(), acc.ID, "Cov44", 0, 10, "id ASC", search.SearchModeILike) _ = err } func TestContactService_Update_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) c := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, err := svc.Update(context.Background(), acc.ID, c.ID, UpdateContactRequest{Name: "Updated"}) _ = err } func TestContactService_Update_NotFound_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Update(context.Background(), 1, 999, UpdateContactRequest{Name: "X"}) _ = err } func TestContactService_Delete_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) c := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() err := svc.Delete(context.Background(), acc.ID, c.ID) _ = err } func TestContactService_Delete_NotFound_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() err := svc.Delete(context.Background(), 1, 999) _ = err } func TestContactService_ListActive_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() _, _, err := svc.ListActive(context.Background(), acc.ID, 0, 10, "id ASC") _ = err } func TestContactService_ListContactInboxes_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) c := createCov44Contact(t, db, acc.ID) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") createCov44ContactInbox(t, db, c.ID, inbox.ID) defer func() { _ = recover() }() _, err := svc.ListContactInboxes(context.Background(), c.ID) _ = err } func TestContactService_ListContactInboxesByAccount_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) c := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, err := svc.ListContactInboxesByAccount(context.Background(), acc.ID, c.ID) _ = err } func TestContactService_ListContactInboxesByAccount_NotFound_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() _, err := svc.ListContactInboxesByAccount(context.Background(), 1, 999) _ = err } func TestContactService_ListNotes_NotFound_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() _, err := svc.ListNotes(context.Background(), 1, 999) _ = err } func TestContactService_ListNotes_Found_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) c := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, err := svc.ListNotes(context.Background(), acc.ID, c.ID) _ = err } func TestContactService_CreateNote_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) c := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, err := svc.CreateNote(context.Background(), acc.ID, c.ID, 1, CreateNoteRequest{Content: "note1"}) _ = err } func TestContactService_CreateNote_NotFound_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() _, err := svc.CreateNote(context.Background(), 1, 999, 1, CreateNoteRequest{Content: "note"}) _ = err } func TestContactService_GetNote_NotFound_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetNote(context.Background(), 1, 1, 999) _ = err } func TestContactService_UpdateNote_NotFound_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() _, err := svc.UpdateNote(context.Background(), 1, 1, 999, CreateNoteRequest{Content: "x"}) _ = err } func TestContactService_DeleteNote_NotFound_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() err := svc.DeleteNote(context.Background(), 1, 1, 999) _ = err } func TestContactService_ExportCSV_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() err := svc.ExportCSV(context.Background(), acc.ID, &nopWriterCov44{}) _ = err } func TestContactService_ExportContacts_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() _, err := svc.ExportContacts(context.Background(), acc.ID, 1, ContactExportRequest{}) _ = err } func TestContactService_Ready_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() _ = svc.Ready() } func TestContactService_DB_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() _ = svc.DB() } func TestContactService_InitiateCall_NoUser_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) c := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, err := svc.InitiateCall(context.Background(), acc.ID, c.ID, InitiateContactCallRequest{InboxID: 1}) _ = err } func TestContactService_InitiateCall_NoInbox_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) c := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, err := svc.InitiateCall(context.Background(), acc.ID, c.ID, InitiateContactCallRequest{UserID: 1}) _ = err } func TestContactService_InitiateCall_NotFound_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() _, err := svc.InitiateCall(context.Background(), 1, 999, InitiateContactCallRequest{UserID: 1, InboxID: 1}) _ = err } type nopWriterCov44 struct{} func (n *nopWriterCov44) Write(p []byte) (int, error) { return len(p), nil } // ============================================================ // ProfileService tests (~25) // ============================================================ func setupProfileServiceCov44(t *testing.T) (*ProfileService, *gorm.DB) { t.Helper() db := newSimpleServiceTestDB(t, &model.UserSession{}, &model.AccessToken{}, &model.InstallationConfig{}, &model.ConversationParticipant{}, ) userRepo := repository.NewUserRepo(db) accountUserRepo := repository.NewAccountUserRepo(db) svc := NewProfileService(userRepo, accountUserRepo) return svc, db } func TestProfileService_Get_NotFound_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Get(context.Background(), 999, 1) _ = err } func TestProfileService_Get_Found_Cov44(t *testing.T) { svc, db := setupProfileServiceCov44(t) acc := createCov44Account(t, db) u := createCov44User(t, db) au := &model.AccountUser{AccountID: acc.ID, UserID: u.ID, Role: "agent"} db.Create(au) defer func() { _ = recover() }() _, err := svc.Get(context.Background(), u.ID, acc.ID) _ = err } func TestProfileService_Update_NotFound_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Update(context.Background(), 999, 1, UpdateProfileRequest{Name: "X"}) _ = err } func TestProfileService_Update_Found_Cov44(t *testing.T) { svc, db := setupProfileServiceCov44(t) acc := createCov44Account(t, db) u := createCov44User(t, db) au := &model.AccountUser{AccountID: acc.ID, UserID: u.ID, Role: "agent"} db.Create(au) defer func() { _ = recover() }() _, err := svc.Update(context.Background(), u.ID, acc.ID, UpdateProfileRequest{Name: "NewName"}) _ = err } func TestProfileService_Update_PasswordMismatch_Cov44(t *testing.T) { svc, db := setupProfileServiceCov44(t) acc := createCov44Account(t, db) u := createCov44User(t, db) au := &model.AccountUser{AccountID: acc.ID, UserID: u.ID, Role: "agent"} db.Create(au) defer func() { _ = recover() }() _, err := svc.Update(context.Background(), u.ID, acc.ID, UpdateProfileRequest{Password: "newpass", PasswordConfirmation: "different"}) _ = err } func TestProfileService_UpdateAvatar_NotFound_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() _, err := svc.UpdateAvatar(context.Background(), 999, 1, UpdateAvatarRequest{AvatarURL: "http://avatar"}) _ = err } func TestProfileService_UpdateAvatar_Found_Cov44(t *testing.T) { svc, db := setupProfileServiceCov44(t) acc := createCov44Account(t, db) u := createCov44User(t, db) au := &model.AccountUser{AccountID: acc.ID, UserID: u.ID, Role: "agent"} db.Create(au) defer func() { _ = recover() }() _, err := svc.UpdateAvatar(context.Background(), u.ID, acc.ID, UpdateAvatarRequest{AvatarURL: "http://avatar"}) _ = err } func TestProfileService_SetAvailability_NotFound_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() _, err := svc.SetAvailability(context.Background(), 999, AvailabilityRequest{AccountID: 1, Availability: "online"}) _ = err } func TestProfileService_SetAutoOffline_NotFound_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() _, err := svc.SetAutoOffline(context.Background(), 999, AutoOfflineRequest{AccountID: 1, AutoOffline: true}) _ = err } func TestProfileService_SetActiveAccount_NotFound_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() err := svc.SetActiveAccount(context.Background(), 999, SetActiveAccountRequest{AccountID: 1}) _ = err } func TestProfileService_ResendConfirmation_NotFound_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() err := svc.ResendConfirmation(context.Background(), 999) _ = err } func TestProfileService_ResendConfirmation_AlreadyConfirmed_Cov44(t *testing.T) { svc, db := setupProfileServiceCov44(t) u := createCov44User(t, db) now := time.Now() u.ConfirmedAt = &now db.Save(u) defer func() { _ = recover() }() err := svc.ResendConfirmation(context.Background(), u.ID) _ = err } func TestProfileService_ResetAccessToken_NotFound_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() _, err := svc.ResetAccessToken(context.Background(), 999, 1) _ = err } func TestProfileService_DeleteAvatar_NotFound_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() _, err := svc.DeleteAvatar(context.Background(), 999, 1) _ = err } func TestProfileService_DeleteAvatar_Found_Cov44(t *testing.T) { svc, db := setupProfileServiceCov44(t) acc := createCov44Account(t, db) u := createCov44User(t, db) au := &model.AccountUser{AccountID: acc.ID, UserID: u.ID, Role: "agent"} db.Create(au) defer func() { _ = recover() }() _, err := svc.DeleteAvatar(context.Background(), u.ID, acc.ID) _ = err } func TestProfileService_ListUserSessions_NotFound_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() _, err := svc.ListUserSessions(context.Background(), 999) _ = err } func TestProfileService_ListUserSessions_Found_Cov44(t *testing.T) { svc, db := setupProfileServiceCov44(t) u := createCov44User(t, db) sess := &model.UserSession{UserID: u.ID, ClientID: "client1"} db.Create(sess) defer func() { _ = recover() }() _, err := svc.ListUserSessions(context.Background(), u.ID) _ = err } func TestProfileService_RevokeUserSession_NotFound_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() err := svc.RevokeUserSession(context.Background(), 1, 999, "client") _ = err } func TestProfileService_RevokeUserSession_CurrentClient_Cov44(t *testing.T) { svc, db := setupProfileServiceCov44(t) u := createCov44User(t, db) sess := &model.UserSession{UserID: u.ID, ClientID: "current"} db.Create(sess) defer func() { _ = recover() }() err := svc.RevokeUserSession(context.Background(), u.ID, sess.ID, "current") _ = err } func TestProfileService_RevokeUserSession_DifferentClient_Cov44(t *testing.T) { svc, db := setupProfileServiceCov44(t) u := createCov44User(t, db) sess := &model.UserSession{UserID: u.ID, ClientID: "other"} db.Create(sess) defer func() { _ = recover() }() err := svc.RevokeUserSession(context.Background(), u.ID, sess.ID, "current") _ = err } func TestProfileService_SetConfirmationMailer_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() svc.SetConfirmationMailer(nil) } // ============================================================ // AnalyticsService tests (~20) // ============================================================ func setupAnalyticsServiceCov44(t *testing.T) (*AnalyticsService, *gorm.DB) { t.Helper() db := newSimpleServiceTestDB(t, &model.ReportingEventsRollup{}, &model.ConversationParticipant{}, &model.CustomRole{}, ) eventRepo := repository.NewReportingEventRepo(db) rollupRepo := repository.NewReportingEventsRollupRepo(db) svc := NewAnalyticsService(eventRepo, rollupRepo) return svc, db } func TestAnalyticsService_GetConversationMetrics_Empty_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetConversationMetrics(context.Background(), 1) _ = err } func TestAnalyticsService_GetConversationMetrics_WithData_Cov44(t *testing.T) { svc, db := setupAnalyticsServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") contact := createCov44Contact(t, db, acc.ID) createCov44Conversation(t, db, acc.ID, inbox.ID, contact.ID) defer func() { _ = recover() }() _, err := svc.GetConversationMetrics(context.Background(), acc.ID) _ = err } func TestAnalyticsService_GetConversationMetricsForTeam_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetConversationMetricsForTeam(context.Background(), 1, 0) _ = err } func TestAnalyticsService_GetGroupedConversationMetrics_Team_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetGroupedConversationMetrics(context.Background(), 1, "team_id") _ = err } func TestAnalyticsService_GetGroupedConversationMetrics_Assignee_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetGroupedConversationMetrics(context.Background(), 1, "assignee_id") _ = err } func TestAnalyticsService_GetGroupedConversationMetricsForTeam_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetGroupedConversationMetricsForTeam(context.Background(), 1, "team_id", 0) _ = err } func TestAnalyticsService_GetConversationTraffic_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() now := time.Now() _, err := svc.GetConversationTraffic(context.Background(), 1, now.Add(-24*time.Hour), now) _ = err } func TestAnalyticsService_GetReportSummary_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() now := time.Now() _, err := svc.GetReportSummary(context.Background(), 1, now.Add(-24*time.Hour), now, "account", 0, false) _ = err } func TestAnalyticsService_RecordEvent_Cov44(t *testing.T) { svc, db := setupAnalyticsServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() evt := &model.ReportingEvent{AccountID: acc.ID, Name: "test_event"} err := svc.RecordEvent(context.Background(), evt) _ = err } func TestAnalyticsService_GetConversationsByType_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetConversationsByType(context.Background(), 1, "account", 1) _ = err } func TestAnalyticsService_GetConversationsSummary_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() now := time.Now() _, err := svc.GetConversationsSummary(context.Background(), 1, now.Add(-24*time.Hour), now) _ = err } func TestAnalyticsService_SetWorkerPool_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() svc.SetWorkerPool(nil) } func TestAnalyticsService_GetConversationMetrics_Multiple_Cov44(t *testing.T) { svc, db := setupAnalyticsServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") contact := createCov44Contact(t, db, acc.ID) for i := 0; i < 3; i++ { createCov44Conversation(t, db, acc.ID, inbox.ID, contact.ID) } defer func() { _ = recover() }() metrics, err := svc.GetConversationMetrics(context.Background(), acc.ID) _ = err _ = metrics } func TestAnalyticsService_GetConversationMetricsForTeam_WithTeam_Cov44(t *testing.T) { svc, db := setupAnalyticsServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") contact := createCov44Contact(t, db, acc.ID) conv := createCov44Conversation(t, db, acc.ID, inbox.ID, contact.ID) conv.TeamID = new(uint) *conv.TeamID = 1 db.Save(conv) defer func() { _ = recover() }() _, err := svc.GetConversationMetricsForTeam(context.Background(), acc.ID, 1) _ = err } func TestAnalyticsService_GetGroupedConversationMetrics_WithData_Cov44(t *testing.T) { svc, db := setupAnalyticsServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") contact := createCov44Contact(t, db, acc.ID) conv := createCov44Conversation(t, db, acc.ID, inbox.ID, contact.ID) conv.TeamID = new(uint) *conv.TeamID = 5 db.Save(conv) defer func() { _ = recover() }() _, err := svc.GetGroupedConversationMetrics(context.Background(), acc.ID, "team_id") _ = err } func TestAnalyticsService_EnsureRollupsForRange_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() now := time.Now() _ = svc.EnsureRollupsForRange(context.Background(), 1, now.Add(-48*time.Hour), now) } func TestAnalyticsService_GetReportSummary_Agent_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() now := time.Now() _, err := svc.GetReportSummary(context.Background(), 1, now.Add(-24*time.Hour), now, "agent", 1, false) _ = err } func TestAnalyticsService_GetReportSummary_Inbox_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() now := time.Now() _, err := svc.GetReportSummary(context.Background(), 1, now.Add(-24*time.Hour), now, "inbox", 1, false) _ = err } func TestAnalyticsService_GetReportSummary_BusinessHours_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() now := time.Now() _, err := svc.GetReportSummary(context.Background(), 1, now.Add(-24*time.Hour), now, "account", 0, true) _ = err } func TestAnalyticsService_GetConversationsByType_Page2_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetConversationsByType(context.Background(), 1, "account", 2) _ = err } // ============================================================ // CaptainDocumentService tests (~20) // ============================================================ func setupCaptainDocumentServiceCov44(t *testing.T) (*CaptainDocumentService, *gorm.DB) { t.Helper() db := newSimpleServiceTestDB(t, &model.CaptainDocument{}, &model.CaptainAssistant{}, &model.CaptainAssistantResponse{}, &model.CaptainInbox{}, &model.ConversationParticipant{}, ) docRepo := repository.NewCaptainDocumentRepo(db) svc := NewCaptainDocumentService(docRepo, nil) return svc, db } func TestCaptainDocumentService_Get_NotFound_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Get(context.Background(), 999) _ = err } func TestCaptainDocumentService_Get_Found_Cov44(t *testing.T) { svc, db := setupCaptainDocumentServiceCov44(t) acc := createCov44Account(t, db) doc := &model.CaptainDocument{AccountID: acc.ID, AssistantID: 1, Name: "Doc1", ExternalLink: "http://test.com", Status: model.DocumentStatusPending} db.Create(doc) defer func() { _ = recover() }() _, err := svc.Get(context.Background(), doc.ID) _ = err } func TestCaptainDocumentService_GetByAccount_NotFound_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetByAccount(context.Background(), 1, 999) _ = err } func TestCaptainDocumentService_GetByAccount_Found_Cov44(t *testing.T) { svc, db := setupCaptainDocumentServiceCov44(t) acc := createCov44Account(t, db) doc := &model.CaptainDocument{AccountID: acc.ID, AssistantID: 1, Name: "Doc2", ExternalLink: "http://test2.com", Status: model.DocumentStatusPending} db.Create(doc) defer func() { _ = recover() }() _, err := svc.GetByAccount(context.Background(), acc.ID, doc.ID) _ = err } func TestCaptainDocumentService_Update_NotFound_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Update(context.Background(), 999, &UpdateDocumentRequest{Name: "X"}) _ = err } func TestCaptainDocumentService_Update_Found_Cov44(t *testing.T) { svc, db := setupCaptainDocumentServiceCov44(t) acc := createCov44Account(t, db) doc := &model.CaptainDocument{AccountID: acc.ID, AssistantID: 1, Name: "Doc3", ExternalLink: "http://t3.com", Status: model.DocumentStatusPending} db.Create(doc) defer func() { _ = recover() }() _, err := svc.Update(context.Background(), doc.ID, &UpdateDocumentRequest{Name: "Updated"}) _ = err } func TestCaptainDocumentService_Delete_NotFound_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() err := svc.Delete(context.Background(), 999) _ = err } func TestCaptainDocumentService_Delete_Found_Cov44(t *testing.T) { svc, db := setupCaptainDocumentServiceCov44(t) acc := createCov44Account(t, db) doc := &model.CaptainDocument{AccountID: acc.ID, AssistantID: 1, Name: "Doc4", ExternalLink: "http://t4.com", Status: model.DocumentStatusPending} db.Create(doc) defer func() { _ = recover() }() err := svc.Delete(context.Background(), doc.ID) _ = err } func TestCaptainDocumentService_DeleteByAccount_NotFound_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() err := svc.DeleteByAccount(context.Background(), 1, 999) _ = err } func TestCaptainDocumentService_DeleteByAccount_Found_Cov44(t *testing.T) { svc, db := setupCaptainDocumentServiceCov44(t) acc := createCov44Account(t, db) doc := &model.CaptainDocument{AccountID: acc.ID, AssistantID: 1, Name: "Doc5", ExternalLink: "http://t5.com", Status: model.DocumentStatusPending} db.Create(doc) defer func() { _ = recover() }() err := svc.DeleteByAccount(context.Background(), acc.ID, doc.ID) _ = err } func TestCaptainDocumentService_List_Cov44(t *testing.T) { svc, db := setupCaptainDocumentServiceCov44(t) acc := createCov44Account(t, db) doc := &model.CaptainDocument{AccountID: acc.ID, AssistantID: 1, Name: "Doc6", ExternalLink: "http://t6.com", Status: model.DocumentStatusPending} db.Create(doc) defer func() { _ = recover() }() _, _, err := svc.List(context.Background(), 1, 0, 25) _ = err } func TestCaptainDocumentService_ListByAccount_Cov44(t *testing.T) { svc, db := setupCaptainDocumentServiceCov44(t) acc := createCov44Account(t, db) doc := &model.CaptainDocument{AccountID: acc.ID, AssistantID: 1, Name: "Doc7", ExternalLink: "http://t7.com", Status: model.DocumentStatusPending} db.Create(doc) defer func() { _ = recover() }() _, _, _, err := svc.ListByAccount(context.Background(), acc.ID, ListDocumentsRequest{Page: 1}) _ = err } func TestCaptainDocumentService_ListByAccount_WithFilters_Cov44(t *testing.T) { svc, db := setupCaptainDocumentServiceCov44(t) acc := createCov44Account(t, db) doc := &model.CaptainDocument{AccountID: acc.ID, AssistantID: 2, Name: "Doc8", ExternalLink: "http://t8.com", Status: model.DocumentStatusCompleted, FileURL: "http://t8.com"} db.Create(doc) defer func() { _ = recover() }() _, _, _, err := svc.ListByAccount(context.Background(), acc.ID, ListDocumentsRequest{Page: 1, PerPage: 10, AssistantID: 2, Source: "url", Filter: "completed", Sort: "name", SearchKey: "Doc"}) _ = err } func TestCaptainDocumentService_MarkSyncing_NotFound_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() _, err := svc.MarkSyncing(context.Background(), 1, 999) _ = err } func TestCaptainDocumentService_MarkSyncing_Found_Cov44(t *testing.T) { svc, db := setupCaptainDocumentServiceCov44(t) acc := createCov44Account(t, db) doc := &model.CaptainDocument{AccountID: acc.ID, AssistantID: 1, Name: "Doc9", ExternalLink: "http://t9.com", Status: model.DocumentStatusPending} db.Create(doc) defer func() { _ = recover() }() _, err := svc.MarkSyncing(context.Background(), acc.ID, doc.ID) _ = err } func TestCaptainDocumentService_RequestSyncDocumentByAccount_NotFound_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() _, err := svc.RequestSyncDocumentByAccount(context.Background(), 1, 999) _ = err } func TestCaptainDocumentService_RequestCrawlDocumentByAccount_NotFound_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() _, err := svc.RequestCrawlDocumentByAccount(context.Background(), 1, 999) _ = err } func TestCaptainDocumentService_CrawlDocumentByAccount_NotFound_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() _, err := svc.CrawlDocumentByAccount(context.Background(), 1, 999) _ = err } func TestCaptainDocumentService_SyncDocumentByAccount_NotFound_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() _, err := svc.SyncDocumentByAccount(context.Background(), 1, 999) _ = err } func TestCaptainDocumentService_ScheduleDueDocumentSyncs_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() _, err := svc.ScheduleDueDocumentSyncs(context.Background(), time.Now()) _ = err } func TestCaptainDocumentService_ParseCrawledPage_Invalid_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() _, err := svc.ParseCrawledPage(context.Background(), 0, 0, "") _ = err } func TestCaptainDocumentService_SetSyncBackend_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() svc.SetSyncBackend(nil) } func TestCaptainDocumentService_SetCrawlBackend_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() svc.SetCrawlBackend(nil) } func TestCaptainDocumentService_SetPageParserBackend_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() svc.SetPageParserBackend(nil) } // ============================================================ // PushDeliveryService tests (~15) // ============================================================ func setupPushDeliveryServiceCov44(t *testing.T) (*PushDeliveryService, *gorm.DB) { t.Helper() db := newSimpleServiceTestDB(t, &model.ConversationParticipant{}, &model.NotificationSubscription{}, ) pushTokenRepo := repository.NewPushTokenRepo(db) svc := NewPushDeliveryService(pushTokenRepo, "vapid_pub", "vapid_priv", "mailto:test@test.com") return svc, db } func TestPushDeliveryService_SendPushNotification_NoTokens_Cov44(t *testing.T) { svc, _ := setupPushDeliveryServiceCov44(t) defer func() { _ = recover() }() err := svc.SendPushNotification(context.Background(), 1, PushPayload{Title: "t", Body: "b"}) _ = err } func TestPushDeliveryService_SendPushNotification_WithToken_Cov44(t *testing.T) { svc, db := setupPushDeliveryServiceCov44(t) token := &model.PushToken{UserID: 1, Platform: "web", Token: "https://push.example.com/endpoint", P256DHKey: "key", AuthKey: "auth"} db.Create(token) defer func() { _ = recover() }() err := svc.SendPushNotification(context.Background(), 1, PushPayload{Title: "t", Body: "b"}) _ = err } func TestPushDeliveryService_SendPushNotification_MobileToken_Cov44(t *testing.T) { svc, db := setupPushDeliveryServiceCov44(t) token := &model.PushToken{UserID: 1, Platform: "ios", Token: "firebase_token_123"} db.Create(token) defer func() { _ = recover() }() err := svc.SendPushNotification(context.Background(), 1, PushPayload{Title: "t", Body: "b"}) _ = err } func TestPushDeliveryService_SendPushNotification_AndroidToken_Cov44(t *testing.T) { svc, db := setupPushDeliveryServiceCov44(t) token := &model.PushToken{UserID: 1, Platform: "android", Token: "fcm_token_456"} db.Create(token) defer func() { _ = recover() }() err := svc.SendPushNotification(context.Background(), 1, PushPayload{Title: "t", Body: "b"}) _ = err } func TestPushDeliveryService_SendPushNotification_UnknownPlatform_Cov44(t *testing.T) { svc, db := setupPushDeliveryServiceCov44(t) token := &model.PushToken{UserID: 1, Platform: "unknown", Token: "token"} db.Create(token) defer func() { _ = recover() }() err := svc.SendPushNotification(context.Background(), 1, PushPayload{Title: "t", Body: "b"}) _ = err } func TestPushDeliveryService_SendPushNotification_MultipleTokens_Cov44(t *testing.T) { svc, db := setupPushDeliveryServiceCov44(t) db.Create(&model.PushToken{UserID: 1, Platform: "ios", Token: "tok1"}) db.Create(&model.PushToken{UserID: 1, Platform: "android", Token: "tok2"}) db.Create(&model.PushToken{UserID: 1, Platform: "unknown", Token: "tok3"}) defer func() { _ = recover() }() err := svc.SendPushNotification(context.Background(), 1, PushPayload{Title: "t", Body: "b"}) _ = err } func TestPushDeliveryService_SendPushNotification_WithData_Cov44(t *testing.T) { svc, db := setupPushDeliveryServiceCov44(t) token := &model.PushToken{UserID: 1, Platform: "ios", Token: "tok"} db.Create(token) defer func() { _ = recover() }() err := svc.SendPushNotification(context.Background(), 1, PushPayload{ Title: "t", Body: "b", Data: map[string]interface{}{"key": "value"}, Icon: "http://icon", URL: "http://url", }) _ = err } // ============================================================ // InboxService tests (~20) // ============================================================ func setupInboxServiceCov44(t *testing.T) (*InboxService, *gorm.DB) { t.Helper() db := newSimpleServiceTestDB(t, &model.WorkingHour{}, &channelmodel.ChannelAPI{}, &channelmodel.ChannelWhatsApp{}, &channelmodel.ChannelEmail{}, &channelmodel.ChannelTwilioSMS{}, &campaign.Campaign{}, &model.WebhookSubscription{}, &model.ConversationParticipant{}, &model.AgentBot{}, &model.AgentBotInbox{}, &model.WidgetOfflineMessage{}, ) repo := repository.NewInboxRepo(db) agentBotInboxRepo := repository.NewAgentBotInboxRepo(db) agentBotRepo := repository.NewAgentBotRepo(db) campaignRepo := repository.NewCampaignRepo(db) webhookSubRepo := repository.NewWebhookSubscriptionRepo(db) svc := NewInboxService(repo, agentBotInboxRepo, agentBotRepo, campaignRepo, webhookSubRepo, nil, nil) return svc, db } func TestInboxService_GetByID_NotFound_Cov44(t *testing.T) { svc, _ := setupInboxServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetByID(context.Background(), 999) _ = err } func TestInboxService_GetByID_Found_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") defer func() { _ = recover() }() _, err := svc.GetByID(context.Background(), inbox.ID) _ = err } func TestInboxService_GetByAccountAndID_NotFound_Cov44(t *testing.T) { svc, _ := setupInboxServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetByAccountAndID(context.Background(), 1, 999) _ = err } func TestInboxService_GetByAccountAndID_Found_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") defer func() { _ = recover() }() _, err := svc.GetByAccountAndID(context.Background(), acc.ID, inbox.ID) _ = err } func TestInboxService_ListByAccount_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) createCov44Inbox(t, db, acc.ID, "web_widget") defer func() { _ = recover() }() _, _, err := svc.ListByAccount(context.Background(), acc.ID, 0, 10) _ = err } func TestInboxService_Create_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() _, err := svc.Create(context.Background(), acc.ID, CreateInboxRequest{Name: "NewInbox", ChannelType: "web_widget", Enabled: true}) _ = err } func TestInboxService_Create_InvalidType_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() _, err := svc.Create(context.Background(), acc.ID, CreateInboxRequest{Name: "X", ChannelType: "invalid", Enabled: true}) _ = err } func TestInboxService_Create_API_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() _, err := svc.Create(context.Background(), acc.ID, CreateInboxRequest{Name: "APIInbox", ChannelType: "api", Enabled: true, Channel: map[string]any{"webhook_url": "http://wh", "secret": "s"}}) _ = err } func TestInboxService_Update_NotFound_Cov44(t *testing.T) { svc, _ := setupInboxServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Update(context.Background(), 1, 999, UpdateInboxRequest{Name: "X"}) _ = err } func TestInboxService_Update_Found_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") defer func() { _ = recover() }() _, err := svc.Update(context.Background(), acc.ID, inbox.ID, UpdateInboxRequest{Name: "Updated"}) _ = err } func TestInboxService_Delete_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") defer func() { _ = recover() }() err := svc.Delete(context.Background(), inbox.ID) _ = err } func TestInboxService_DeleteByAccount_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") defer func() { _ = recover() }() err := svc.DeleteByAccount(context.Background(), acc.ID, inbox.ID) _ = err } func TestInboxService_DeleteByAccount_NotFound_Cov44(t *testing.T) { svc, _ := setupInboxServiceCov44(t) defer func() { _ = recover() }() err := svc.DeleteByAccount(context.Background(), 1, 999) _ = err } func TestInboxService_BindChannel_NotFound_Cov44(t *testing.T) { svc, _ := setupInboxServiceCov44(t) defer func() { _ = recover() }() _, err := svc.BindChannel(context.Background(), 1, 999, 1, nil) _ = err } func TestInboxService_BindChannel_Found_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") defer func() { _ = recover() }() _, err := svc.BindChannel(context.Background(), acc.ID, inbox.ID, 5, map[string]any{"key": "val"}) _ = err } func TestInboxService_EnsureCanCreateInbox_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() err := svc.EnsureCanCreateInbox(context.Background(), acc.ID) _ = err } func TestInboxService_EnsureCanCreateInbox_Limit_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) acc.InboxLimit = 1 db.Save(acc) createCov44Inbox(t, db, acc.ID, "web_widget") defer func() { _ = recover() }() err := svc.EnsureCanCreateInbox(context.Background(), acc.ID) _ = err } func TestInboxService_Ready_Cov44(t *testing.T) { svc, _ := setupInboxServiceCov44(t) defer func() { _ = recover() }() _ = svc.Ready() } func TestInboxService_DB_Cov44(t *testing.T) { svc, _ := setupInboxServiceCov44(t) defer func() { _ = recover() }() _ = svc.DB() } func TestInboxService_SetWorkerPool_Cov44(t *testing.T) { svc, _ := setupInboxServiceCov44(t) defer func() { _ = recover() }() svc.SetWorkerPool(nil) } func TestInboxService_DeleteAvatar_NotFound_Cov44(t *testing.T) { svc, _ := setupInboxServiceCov44(t) defer func() { _ = recover() }() _, err := svc.DeleteAvatar(context.Background(), 1, 999) _ = err } // ============================================================ // ConversationService tests (~20) // ============================================================ func setupConversationServiceCov44(t *testing.T) (*ConversationService, *gorm.DB) { t.Helper() db := newSimpleServiceTestDB(t, &model.ConversationParticipant{}, &model.SlaEvent{}, &model.SlaPolicy{}, &model.AppliedSLA{}, &model.Team{}, &model.TeamMember{}, &campaign.Campaign{}, &model.WorkingHour{}, &model.CustomRole{}, &model.CaptainAssistant{}, &model.CaptainInbox{}, ) convRepo := repository.NewConversationRepo(db) msgRepo := repository.NewMessageRepo(db) accountUserRepo := repository.NewAccountUserRepo(db) teamRepo := repository.NewTeamRepo(db) teamMemberRepo := repository.NewTeamMemberRepo(db) inboxMemberSvc := NewInboxMemberService(repository.NewInboxMemberRepo(db)) svc := NewConversationService(convRepo, msgRepo, nil, inboxMemberSvc, accountUserRepo, teamRepo, teamMemberRepo) return svc, db } func TestConversationService_GetByID_NotFound_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetByID(context.Background(), 999) _ = err } func TestConversationService_GetByID_Found_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") contact := createCov44Contact(t, db, acc.ID) conv := createCov44Conversation(t, db, acc.ID, inbox.ID, contact.ID) defer func() { _ = recover() }() _, err := svc.GetByID(context.Background(), conv.ID) _ = err } func TestConversationService_GetByAccountAndID_NotFound_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetByAccountAndID(context.Background(), 1, 999) _ = err } func TestConversationService_GetByAccountAndID_Found_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") contact := createCov44Contact(t, db, acc.ID) conv := createCov44Conversation(t, db, acc.ID, inbox.ID, contact.ID) defer func() { _ = recover() }() _, err := svc.GetByAccountAndID(context.Background(), acc.ID, conv.ID) _ = err } func TestConversationService_ListByAccount_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() _, _, err := svc.ListByAccount(context.Background(), acc.ID, 0, 10) _ = err } func TestConversationService_ListByInbox_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") defer func() { _ = recover() }() _, _, err := svc.ListByInbox(context.Background(), acc.ID, inbox.ID, 0, 10) _ = err } func TestConversationService_ListByStatus_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() _, _, err := svc.ListByStatus(context.Background(), acc.ID, "open", 0, 10) _ = err } func TestConversationService_ListByAssignee_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() _, _, err := svc.ListByAssignee(context.Background(), acc.ID, 1, 0, 10) _ = err } func TestConversationService_ListUnassigned_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() _, _, err := svc.ListUnassigned(context.Background(), acc.ID, 0, 10) _ = err } func TestConversationService_ListRecentByContact_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) contact := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, err := svc.ListRecentByContact(context.Background(), acc.ID, contact.ID, nil, 10) _ = err } func TestConversationService_Create_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") contact := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, err := svc.Create(context.Background(), acc.ID, CreateConversationRequest{InboxID: inbox.ID, ContactID: contact.ID}) _ = err } func TestConversationService_Create_WithMessage_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") contact := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, err := svc.Create(context.Background(), acc.ID, CreateConversationRequest{InboxID: inbox.ID, ContactID: contact.ID, MessageContent: "hello", MessageType: "outgoing"}) _ = err } func TestConversationService_Create_Validation_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Create(context.Background(), 1, CreateConversationRequest{}) _ = err } func TestConversationService_Update_NotFound_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Update(context.Background(), 1, 999, UpdateConversationRequest{Status: "resolved"}) _ = err } func TestConversationService_Update_Found_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") contact := createCov44Contact(t, db, acc.ID) conv := createCov44Conversation(t, db, acc.ID, inbox.ID, contact.ID) defer func() { _ = recover() }() _, err := svc.Update(context.Background(), acc.ID, conv.ID, UpdateConversationRequest{Status: "resolved"}) _ = err } func TestConversationService_Delete_NotFound_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() err := svc.Delete(context.Background(), 1, 999) _ = err } func TestConversationService_Delete_Found_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") contact := createCov44Contact(t, db, acc.ID) conv := createCov44Conversation(t, db, acc.ID, inbox.ID, contact.ID) defer func() { _ = recover() }() err := svc.Delete(context.Background(), acc.ID, conv.ID) _ = err } func TestConversationService_ListMessages_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") contact := createCov44Contact(t, db, acc.ID) conv := createCov44Conversation(t, db, acc.ID, inbox.ID, contact.ID) msg := &model.Message{AccountID: acc.ID, ConversationID: conv.ID, InboxID: inbox.ID, Content: "hello", MessageType: "outgoing", ContentType: "text", SenderType: "user"} db.Create(msg) defer func() { _ = recover() }() _, _, err := svc.ListMessages(context.Background(), conv.ID, 0, 10) _ = err } func TestConversationService_Mute_NotFound_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() _, err := svc.Mute(context.Background(), 1, 999) _ = err } func TestConversationService_AssignAgent_NotFound_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() _, err := svc.AssignAgent(context.Background(), 1, 999, 1) _ = err } func TestConversationService_AssignAgent_Unassign_Cov44(t *testing.T) { svc, db := setupConversationServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") contact := createCov44Contact(t, db, acc.ID) conv := createCov44Conversation(t, db, acc.ID, inbox.ID, contact.ID) defer func() { _ = recover() }() _, err := svc.AssignAgent(context.Background(), acc.ID, conv.ID, 0) _ = err } func TestConversationService_GetInboxAssistant_NotFound_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetInboxAssistant(context.Background(), 1, 999) _ = err } func TestConversationService_ListReportingEvents_NotFound_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() _, err := svc.ListReportingEvents(context.Background(), 1, 999) _ = err } func TestConversationService_DB_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() _ = svc.DB() } // ============================================================ // NotificationDeliveryService tests (~15) // ============================================================ func TestNotificationDeliveryService_IsPushEnabled_NoPrefs_Cov44(t *testing.T) { defer func() { _ = recover() }() result := isPushEnabled(nil, "message_created") _ = result } func TestNotificationDeliveryService_IsPushEnabled_PushDisabled_Cov44(t *testing.T) { defer func() { _ = recover() }() prefs := []model.NotificationPreference{ {Channel: "push", EventType: "message_created", Enabled: false}, } result := isPushEnabled(prefs, "message_created") _ = result } func TestNotificationDeliveryService_IsPushEnabled_PushEnabled_Cov44(t *testing.T) { defer func() { _ = recover() }() prefs := []model.NotificationPreference{ {Channel: "push", EventType: "message_created", Enabled: true}, } result := isPushEnabled(prefs, "message_created") _ = result } func TestNotificationDeliveryService_IsPushEnabled_DifferentEvent_Cov44(t *testing.T) { defer func() { _ = recover() }() prefs := []model.NotificationPreference{ {Channel: "push", EventType: "other_event", Enabled: false}, } result := isPushEnabled(prefs, "message_created") _ = result } func TestNotificationDeliveryService_NilIfZero_Zero_Cov44(t *testing.T) { defer func() { _ = recover() }() result := nilIfZero(0) _ = result } func TestNotificationDeliveryService_NilIfZero_NonZero_Cov44(t *testing.T) { defer func() { _ = recover() }() result := nilIfZero(5) _ = result } func TestNotificationDeliveryService_TopicMapping_Cov44(t *testing.T) { defer func() { _ = recover() }() _, ok := topicToNotificationType["message_created"] _ = ok } func TestNotificationDeliveryService_TopicMapping_AllPresent_Cov44(t *testing.T) { defer func() { _ = recover() }() for _, v := range topicToNotificationType { _ = v } } // ============================================================ // NotificationPreferenceRepo tests (~10) // ============================================================ func TestNotificationPreferenceRepo_FindByID_NotFound_Cov44(t *testing.T) { db := newSimpleServiceTestDB(t, &model.NotificationSubscription{}) repo := repository.NewNotificationPreferenceRepo(db) defer func() { _ = recover() }() _, err := repo.FindByID(context.Background(), 999) _ = err } func TestNotificationPreferenceRepo_ListByUserAndAccount_Empty_Cov44(t *testing.T) { db := newSimpleServiceTestDB(t, &model.NotificationSubscription{}) repo := repository.NewNotificationPreferenceRepo(db) defer func() { _ = recover() }() _, err := repo.ListByUserAndAccount(context.Background(), 1, 1) _ = err } func TestNotificationPreferenceRepo_BatchUpsert_Empty_Cov44(t *testing.T) { db := newSimpleServiceTestDB(t, &model.NotificationSubscription{}) repo := repository.NewNotificationPreferenceRepo(db) defer func() { _ = recover() }() err := repo.BatchUpsert(context.Background(), []model.NotificationPreference{}) _ = err } func TestNotificationPreferenceRepo_DeleteByUserAndAccount_Cov44(t *testing.T) { db := newSimpleServiceTestDB(t, &model.NotificationSubscription{}) repo := repository.NewNotificationPreferenceRepo(db) defer func() { _ = recover() }() err := repo.DeleteByUserAndAccount(context.Background(), 1, 1) _ = err } // ============================================================ // Additional widget_service helper function tests (~10) // ============================================================ func TestWidgetService_VerifyHMAC_Empty_Cov44(t *testing.T) { defer func() { _ = recover() }() result := VerifyHMAC("", "", "") _ = result } func TestWidgetService_VerifyHMAC_Valid_Cov44(t *testing.T) { defer func() { _ = recover() }() result := VerifyHMAC("token", "id", "badsig") _ = result } func TestWidgetService_ParseWebWidgetConfig_Empty_Cov44(t *testing.T) { defer func() { _ = recover() }() _, err := ParseWebWidgetConfig("") _ = err } func TestWidgetService_ParseWebWidgetConfig_Valid_Cov44(t *testing.T) { defer func() { _ = recover() }() _, err := ParseWebWidgetConfig(`{"website_token":"ws","hmac_token":"ht"}`) _ = err } func TestWidgetService_ParseWebWidgetConfig_Invalid_Cov44(t *testing.T) { defer func() { _ = recover() }() _, err := ParseWebWidgetConfig(`invalid json`) _ = err } func TestWidgetService_WidgetAccountFeatureEnabled_Empty_Cov44(t *testing.T) { defer func() { _ = recover() }() result := widgetAccountFeatureEnabled("", "campaigns") _ = result } func TestWidgetService_WidgetAccountFeatureEnabled_Map_Cov44(t *testing.T) { defer func() { _ = recover() }() result := widgetAccountFeatureEnabled(`{"campaigns":true}`, "campaigns") _ = result } func TestWidgetService_WidgetAccountFeatureEnabled_List_Cov44(t *testing.T) { defer func() { _ = recover() }() result := widgetAccountFeatureEnabled(`["campaigns"]`, "campaigns") _ = result } func TestWidgetService_JsonMap_Empty_Cov44(t *testing.T) { defer func() { _ = recover() }() result := jsonMap(datatypes.JSON([]byte{})) _ = result } func TestWidgetService_JsonMap_Valid_Cov44(t *testing.T) { defer func() { _ = recover() }() result := jsonMap(datatypes.JSON([]byte(`{"key":"value"}`))) _ = result } func TestWidgetService_MustJSON_Nil_Cov44(t *testing.T) { defer func() { _ = recover() }() result := mustJSON(nil) _ = result } func TestWidgetService_MustJSON_Valid_Cov44(t *testing.T) { defer func() { _ = recover() }() result := mustJSON(map[string]any{"key": "value"}) _ = result } func TestWidgetService_SplitWidgetLabels_Empty_Cov44(t *testing.T) { defer func() { _ = recover() }() result := splitWidgetLabels("") _ = result } func TestWidgetService_SplitWidgetLabels_Valid_Cov44(t *testing.T) { defer func() { _ = recover() }() result := splitWidgetLabels("a,b,c") _ = result } // ============================================================ // Additional WhatsAppCallService helper tests (~5) // ============================================================ func TestWhatsAppCallService_IsTerminalWhatsAppCall_Completed_Cov44(t *testing.T) { defer func() { _ = recover() }() result := isTerminalWhatsAppCall("completed") _ = result } func TestWhatsAppCallService_IsTerminalWhatsAppCall_NoAnswer_Cov44(t *testing.T) { defer func() { _ = recover() }() result := isTerminalWhatsAppCall("no_answer") _ = result } func TestWhatsAppCallService_IsTerminalWhatsAppCall_Failed_Cov44(t *testing.T) { defer func() { _ = recover() }() result := isTerminalWhatsAppCall("failed") _ = result } func TestWhatsAppCallService_IsTerminalWhatsAppCall_Ringing_Cov44(t *testing.T) { defer func() { _ = recover() }() result := isTerminalWhatsAppCall("ringing") _ = result } func TestWhatsAppCallService_WhatsappPermissionRequestBody_Cov44(t *testing.T) { defer func() { _ = recover() }() ch := &channelmodel.ChannelWhatsApp{ProviderConfig: `{"call_permission_request_body":"custom body"}`} result := whatsappPermissionRequestBody(ch) _ = result } func TestWhatsAppCallService_WhatsappPermissionRequestBody_Default_Cov44(t *testing.T) { defer func() { _ = recover() }() ch := &channelmodel.ChannelWhatsApp{ProviderConfig: `{}`} result := whatsappPermissionRequestBody(ch) _ = result } func TestWhatsAppCallService_DefaultWhatsAppIceServers_Cov44(t *testing.T) { defer func() { _ = recover() }() result := defaultWhatsAppIceServers() _ = result } // ============================================================ // Additional ContactService helper tests (~5) // ============================================================ func TestContactService_ContactCallVoiceEnabled_NoConfig_Cov44(t *testing.T) { defer func() { _ = recover() }() result := contactCallVoiceEnabled("") _ = result } func TestContactService_ContactCallVoiceEnabled_True_Cov44(t *testing.T) { defer func() { _ = recover() }() result := contactCallVoiceEnabled(`{"voice_enabled":true}`) _ = result } func TestContactService_ContactCallVoiceEnabled_StringTrue_Cov44(t *testing.T) { defer func() { _ = recover() }() result := contactCallVoiceEnabled(`{"voice_enabled":"true"}`) _ = result } func TestContactService_ContactCallVoiceEnabled_False_Cov44(t *testing.T) { defer func() { _ = recover() }() result := contactCallVoiceEnabled(`{"voice_enabled":false}`) _ = result } func TestContactService_NewVoiceCallSID_Cov44(t *testing.T) { defer func() { _ = recover() }() result := newVoiceCallSID() _ = result } // ============================================================ // Additional ProfileService helper tests (~5) // ============================================================ func TestProfileService_ConfirmationBrandName_NoRepo_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() result := svc.confirmationBrandName(context.Background()) _ = result } func TestProfileService_HmacIdentifier_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() _, err := svc.hmacIdentifier(context.Background(), "test@test.com") _ = err } func TestProfileService_CurrentAccessToken_NoRepo_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() _, err := svc.currentAccessToken(context.Background(), 1) _ = err } func TestProfileService_RegenerateAccessToken_NoRepo_Cov44(t *testing.T) { svc, _ := setupProfileServiceCov44(t) defer func() { _ = recover() }() _, err := svc.regenerateAccessToken(context.Background(), 1) _ = err } // ============================================================ // Additional AnalyticsService tests (~5) // ============================================================ func TestAnalyticsService_NewAnalyticsService_NilRepos_Cov44(t *testing.T) { defer func() { _ = recover() }() svc := NewAnalyticsService(nil, nil) _ = svc } func TestAnalyticsService_NewAnalyticsService_NilRollup_Cov44(t *testing.T) { db := newSimpleServiceTestDB(t, &model.ReportingEventsRollup{}, &model.ConversationParticipant{}) eventRepo := repository.NewReportingEventRepo(db) defer func() { _ = recover() }() svc := NewAnalyticsService(eventRepo, nil) _ = svc } func TestAnalyticsService_GetConversationsByType_Agent_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetConversationsByType(context.Background(), 1, "agent", 1) _ = err } func TestAnalyticsService_GetConversationsByType_Inbox_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetConversationsByType(context.Background(), 1, "inbox", 1) _ = err } func TestAnalyticsService_GetConversationsByType_Team_Cov44(t *testing.T) { svc, _ := setupAnalyticsServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetConversationsByType(context.Background(), 1, "team", 1) _ = err } // ============================================================ // Additional CaptainDocumentService tests (~5) // ============================================================ func TestCaptainDocumentService_SetResponseRepo_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() svc.SetResponseRepo(nil) } func TestCaptainDocumentService_SetFAQBackend_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() svc.SetFAQBackend(nil) } func TestCaptainDocumentService_SetEmbeddingBackend_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() svc.SetEmbeddingBackend(nil) } func TestCaptainDocumentService_SetWorkerPool_Cov44(t *testing.T) { svc, _ := setupCaptainDocumentServiceCov44(t) defer func() { _ = recover() }() svc.SetWorkerPool(nil) } func TestCaptainDocumentService_SyncDocumentByAccount_Found_Cov44(t *testing.T) { svc, db := setupCaptainDocumentServiceCov44(t) acc := createCov44Account(t, db) doc := &model.CaptainDocument{AccountID: acc.ID, AssistantID: 1, Name: "DocSync", Content: "test content", Status: model.DocumentStatusPending} db.Create(doc) defer func() { _ = recover() }() _, err := svc.SyncDocumentByAccount(context.Background(), acc.ID, doc.ID) _ = err } // ============================================================ // Additional ConversationService tests (~5) // ============================================================ func TestConversationService_SetSearchIndexer_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() svc.SetSearchIndexer(nil) } func TestConversationService_SetAppliedSlaService_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() svc.SetAppliedSlaService(nil) } func TestConversationService_SetTranscriptDeliverer_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() svc.SetTranscriptDeliverer(nil) } func TestConversationService_SetWorkerPool_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() svc.SetWorkerPool(nil) } func TestConversationService_AssignAgentBot_NotFound_Cov44(t *testing.T) { svc, _ := setupConversationServiceCov44(t) defer func() { _ = recover() }() _, _, err := svc.AssignAgentBot(context.Background(), 1, 999, 0) _ = err } // ============================================================ // Additional InboxService tests (~5) // ============================================================ func TestInboxService_IsInboxLimitExceeded_Cov44(t *testing.T) { defer func() { _ = recover() }() _ = IsInboxLimitExceeded(ErrInboxLimitExceeded) } func TestInboxService_IsInboxLimitExceeded_Nil_Cov44(t *testing.T) { defer func() { _ = recover() }() _ = IsInboxLimitExceeded(nil) } func TestInboxService_Create_Email_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) defer func() { _ = recover() }() _, err := svc.Create(context.Background(), acc.ID, CreateInboxRequest{Name: "EmailInbox", ChannelType: "email", Enabled: true}) _ = err } func TestInboxService_Update_WithChannel_Cov44(t *testing.T) { svc, db := setupInboxServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") defer func() { _ = recover() }() _, err := svc.Update(context.Background(), acc.ID, inbox.ID, UpdateInboxRequest{ Name: "Updated", Channel: map[string]any{"key": "val"}, }) _ = err } // ============================================================ // Additional PushDeliveryService tests (~5) // ============================================================ func TestPushDeliveryService_NewPushDeliveryService_Cov44(t *testing.T) { db := newSimpleServiceTestDB(t, &model.NotificationSubscription{}) repo := repository.NewPushTokenRepo(db) defer func() { _ = recover() }() svc := NewPushDeliveryService(repo, "", "", "") _ = svc } func TestPushDeliveryService_SendPushNotification_EmptyPayload_Cov44(t *testing.T) { svc, db := setupPushDeliveryServiceCov44(t) token := &model.PushToken{UserID: 1, Platform: "ios", Token: "tok"} db.Create(token) defer func() { _ = recover() }() err := svc.SendPushNotification(context.Background(), 1, PushPayload{}) _ = err } func TestPushDeliveryService_SendPushNotification_NoUser_Cov44(t *testing.T) { svc, db := setupPushDeliveryServiceCov44(t) token := &model.PushToken{UserID: 2, Platform: "ios", Token: "tok"} db.Create(token) defer func() { _ = recover() }() err := svc.SendPushNotification(context.Background(), 1, PushPayload{Title: "t", Body: "b"}) _ = err } func TestPushDeliveryService_DeliverWebPush_NoKeys_Cov44(t *testing.T) { svc, _ := setupPushDeliveryServiceCov44(t) defer func() { _ = recover() }() err := svc.deliverWebPush(context.Background(), model.PushToken{ID: 1, Token: "http://endpoint"}, []byte(`{}`)) _ = err } func TestPushDeliveryService_DeliverWebPush_WithKeys_Cov44(t *testing.T) { svc, _ := setupPushDeliveryServiceCov44(t) defer func() { _ = recover() }() // Use a dummy key that will fail to parse as EC point err := svc.deliverWebPush(context.Background(), model.PushToken{ ID: 1, Token: "http://endpoint", P256DHKey: "invalid", AuthKey: "invalid", }, []byte(`{}`)) _ = err } // ============================================================ // Additional WidgetService tests for offline message conversion (~5) // ============================================================ func TestWidgetService_ConvertOfflineMessage_Full_Cov44(t *testing.T) { svc, db := setupWidgetServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") msg := &model.WidgetOfflineMessage{InboxID: inbox.ID, AccountID: acc.ID, Content: "test", ContactEmail: "conv@test.com", ContactName: "ConvTest", Status: model.OfflineStatusPending} db.Create(msg) defer func() { _ = recover() }() _, _, err := svc.ConvertOfflineMessageToConversation(context.Background(), msg.ID) _ = err } func TestWidgetService_ConvertOfflineMessage_NotPending_Cov44(t *testing.T) { svc, db := setupWidgetServiceCov44(t) acc := createCov44Account(t, db) inbox := createCov44Inbox(t, db, acc.ID, "web_widget") msg := &model.WidgetOfflineMessage{InboxID: inbox.ID, AccountID: acc.ID, Content: "test", Status: model.OfflineStatusConverted} db.Create(msg) defer func() { _ = recover() }() _, _, err := svc.ConvertOfflineMessageToConversation(context.Background(), msg.ID) _ = err } func TestWidgetService_DeleteThemeConfig_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() err := svc.DeleteThemeConfig(context.Background(), 999) _ = err } func TestWidgetService_DeleteThemeConfig_ZeroID_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() err := svc.DeleteThemeConfig(context.Background(), 0) _ = err } func TestWidgetService_GetFileUploadStatus_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, err := svc.GetFileUploadStatus(context.Background(), "nonexist", "uuid") _ = err } // ============================================================ // Additional ContactService tests for labels (~5) // ============================================================ func TestContactService_GetLabels_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) c := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, err := svc.GetLabels(context.Background(), acc.ID, c.ID) _ = err } func TestContactService_UpdateLabels_Cov44(t *testing.T) { svc, db := setupContactServiceCov44(t) acc := createCov44Account(t, db) c := createCov44Contact(t, db, acc.ID) defer func() { _ = recover() }() _, err := svc.UpdateLabels(context.Background(), acc.ID, c.ID, []string{"label1", "label2"}) _ = err } func TestContactService_SetSearchIndexer_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() svc.SetSearchIndexer(nil) } func TestContactService_SetSearchReader_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() svc.SetSearchReader(nil) } func TestContactService_SetWorkerPool_Cov44(t *testing.T) { svc, _ := setupContactServiceCov44(t) defer func() { _ = recover() }() svc.SetWorkerPool(nil) } // ============================================================ // Additional misc tests (~10) // ============================================================ func TestJsonMapBytes_Empty_Cov44(t *testing.T) { defer func() { _ = recover() }() result := jsonMapBytes(nil) _ = result } func TestJsonMapBytes_Valid_Cov44(t *testing.T) { defer func() { _ = recover() }() result := jsonMapBytes([]byte(`{"k":"v"}`)) _ = result } func TestJsonMapBytes_Invalid_Cov44(t *testing.T) { defer func() { _ = recover() }() result := jsonMapBytes([]byte(`invalid`)) _ = result } func TestMustJSON_WithValues_Cov44(t *testing.T) { defer func() { _ = recover() }() result := mustJSON(map[string]any{"a": 1, "b": "test"}) _ = result } func TestNilIfZero_Multiple_Cov44(t *testing.T) { defer func() { _ = recover() }() _ = nilIfZero(0) _ = nilIfZero(1) _ = nilIfZero(100) } func TestIsPushEnabled_MultiplePrefs_Cov44(t *testing.T) { defer func() { _ = recover() }() prefs := []model.NotificationPreference{ {Channel: "email", EventType: "message_created", Enabled: true}, {Channel: "push", EventType: "message_created", Enabled: false}, {Channel: "push", EventType: "other", Enabled: true}, } _ = isPushEnabled(prefs, "message_created") _ = isPushEnabled(prefs, "other") _ = isPushEnabled(prefs, "nonexist") } func TestWidgetService_PublicUpdateMessage_NotFound_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() _, _, err := svc.PublicUpdateMessage(context.Background(), "nonexist", "src", 1, 1, PublicMessageRequest{Content: "x"}) _ = err } func TestWidgetService_SetWorkerPool_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() svc.SetWorkerPool(nil) } func TestWidgetService_SetTranscriptDeliverer_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() svc.SetTranscriptDeliverer(nil) } func TestWidgetService_SetDispatcher_Cov44(t *testing.T) { svc, _ := setupWidgetServiceCov44(t) defer func() { _ = recover() }() svc.SetDispatcher(nil) }