package email import ( "context" "encoding/json" "testing" channelpkg "github.com/gochat/gochat/internal/channel" "github.com/gochat/gochat/internal/model" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // =========================== // EmailProvider (email package) tests // =========================== func TestEmailProvider_Type_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) assert.Equal(t, channelpkg.ChannelEmail, p.Type()) } func TestEmailProvider_Name_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) assert.Equal(t, "Email", p.Name()) } func TestEmailProvider_Description_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) assert.NotEmpty(t, p.Description()) } func TestEmailProvider_ConfigSchema_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) schema := p.ConfigSchema() require.NotNil(t, schema) assert.Equal(t, "object", schema.Type) assert.Contains(t, schema.Required, "imap_address") assert.Contains(t, schema.Required, "smtp_address") } func TestEmailProvider_DefaultConfig_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) cfg := p.DefaultConfig() assert.Contains(t, cfg, "imap_address") assert.Contains(t, cfg, "smtp_address") assert.Contains(t, cfg, "imap_port") assert.Contains(t, cfg, "smtp_port") } func TestEmailProvider_Capabilities_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) caps := p.Capabilities() assert.True(t, caps.SupportsAttachments) assert.True(t, caps.SupportsDeliveryStatus) assert.True(t, caps.SupportsReplies) assert.True(t, caps.SupportsEmailHeaders) assert.Equal(t, 0, caps.MaxTextLength) } func TestEmailProvider_PollInterval_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) assert.Equal(t, 5*1000000000*60, int(p.PollInterval())) // 5 minutes } func TestEmailProvider_ValidateConfig_NoIMAPAddress_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) err := p.ValidateConfig(context.Background(), channelpkg.ChannelConfig{}) require.Error(t, err) assert.Contains(t, err.Error(), "imap_address") } func TestEmailProvider_ValidateConfig_NoIMAPPort_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) err := p.ValidateConfig(context.Background(), channelpkg.ChannelConfig{ "imap_address": "imap.test.com", }) require.Error(t, err) assert.Contains(t, err.Error(), "imap_port") } func TestEmailProvider_ValidateConfig_NoIMAPEmail_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) err := p.ValidateConfig(context.Background(), channelpkg.ChannelConfig{ "imap_address": "imap.test.com", "imap_port": 993, }) require.Error(t, err) assert.Contains(t, err.Error(), "imap_email") } func TestEmailProvider_ValidateConfig_NoIMAPPassword_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) err := p.ValidateConfig(context.Background(), channelpkg.ChannelConfig{ "imap_address": "imap.test.com", "imap_port": 993, "imap_email": "user@test.com", }) require.Error(t, err) assert.Contains(t, err.Error(), "imap_password") } func TestEmailProvider_ValidateConfig_NoSMTPAddress_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) err := p.ValidateConfig(context.Background(), channelpkg.ChannelConfig{ "imap_address": "imap.test.com", "imap_port": 993, "imap_email": "user@test.com", "imap_password": "pass", }) require.Error(t, err) assert.Contains(t, err.Error(), "smtp_address") } func TestEmailProvider_ValidateConfig_NoSMTPPort_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) err := p.ValidateConfig(context.Background(), channelpkg.ChannelConfig{ "imap_address": "imap.test.com", "imap_port": 993, "imap_email": "user@test.com", "imap_password": "pass", "smtp_address": "smtp.test.com", }) require.Error(t, err) assert.Contains(t, err.Error(), "smtp_port") } func TestEmailProvider_ValidateConfig_NoSMTPEmail_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) err := p.ValidateConfig(context.Background(), channelpkg.ChannelConfig{ "imap_address": "imap.test.com", "imap_port": 993, "imap_email": "user@test.com", "imap_password": "pass", "smtp_address": "smtp.test.com", "smtp_port": 587, }) require.Error(t, err) assert.Contains(t, err.Error(), "smtp_email") } func TestEmailProvider_ValidateConfig_NoSMTPPassword_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) err := p.ValidateConfig(context.Background(), channelpkg.ChannelConfig{ "imap_address": "imap.test.com", "imap_port": 993, "imap_email": "user@test.com", "imap_password": "pass", "smtp_address": "smtp.test.com", "smtp_port": 587, "smtp_email": "user@test.com", }) require.Error(t, err) assert.Contains(t, err.Error(), "smtp_password") } func TestEmailProvider_ValidateConfig_Success_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) err := p.ValidateConfig(context.Background(), channelpkg.ChannelConfig{ "imap_address": "imap.test.com", "imap_port": 993, "imap_email": "user@test.com", "imap_password": "pass", "smtp_address": "smtp.test.com", "smtp_port": 587, "smtp_email": "user@test.com", "smtp_password": "pass", }) require.NoError(t, err) } func TestEmailProvider_OnCreate_NoService_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) inbox := &model.Inbox{} inbox.ID = 1 // OnCreate calls p.service.ValidateIMAPConnection which panics on nil service. // Use defer/recover to handle the panic safely. safeCall6(func() { p.OnCreate(context.Background(), inbox, channelpkg.ChannelConfig{}) }) } func TestEmailProvider_OnCreate_IMAPFail_Cov6(t *testing.T) { p := NewEmailProvider(&Service{}, nil, nil) inbox := &model.Inbox{} inbox.ID = 1 _, err := p.OnCreate(context.Background(), inbox, channelpkg.ChannelConfig{ "imap_address": "imap.test.com", "imap_port": 993, "imap_email": "user@test.com", "imap_password": "pass", "smtp_address": "smtp.test.com", "smtp_port": 587, "smtp_email": "user@test.com", "smtp_password": "pass", }) require.Error(t, err) assert.Contains(t, err.Error(), "IMAP") } func TestEmailProvider_OnDestroy_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) inbox := &model.Inbox{} inbox.ID = 1 err := p.OnDestroy(context.Background(), inbox, channelpkg.ChannelConfig{}) require.NoError(t, err) } func TestEmailProvider_ProcessIncoming_BadJSON_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) inbox := &model.Inbox{} _, err := p.ProcessIncoming(context.Background(), inbox, []byte("bad json")) require.Error(t, err) } func TestEmailProvider_ProcessIncoming_Success_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) inbox := &model.Inbox{} inbox.ID = 1 inbox.AccountID = 10 emailMsg := EmailMessage{ MessageID: "msg1", FromAddress: "sender@test.com", FromName: "Sender", Subject: "Test", TextContent: "hello", ToAddresses: []string{"to@test.com"}, InReplyTo: "parent-msg", } payload, _ := json.Marshal(emailMsg) msg, err := p.ProcessIncoming(context.Background(), inbox, payload) require.NoError(t, err) require.NotNil(t, msg) assert.Equal(t, "hello", msg.Content) assert.Equal(t, "msg1", msg.SourceID) assert.Equal(t, "parent-msg", msg.ReplyToID) } func TestEmailProvider_ProcessIncoming_WithAttachments_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) inbox := &model.Inbox{} inbox.ID = 1 inbox.AccountID = 10 emailMsg := EmailMessage{ MessageID: "msg2", FromAddress: "sender@test.com", TextContent: "see attachment", Attachments: []EmailAttachment{ {Filename: "file.pdf", ContentType: "application/pdf", URL: "https://example.com/file.pdf"}, }, } payload, _ := json.Marshal(emailMsg) msg, err := p.ProcessIncoming(context.Background(), inbox, payload) require.NoError(t, err) require.NotNil(t, msg) assert.Len(t, msg.Attachments, 1) } func TestEmailProvider_ValidateWebhookRequest_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) inbox := &model.Inbox{} err := p.ValidateWebhookRequest(context.Background(), inbox, &channelpkg.WebhookRequest{}) require.NoError(t, err) } func TestEmailProvider_SendMessage_NoContact_Cov6(t *testing.T) { p := NewEmailProvider(NewService(), nil, nil) inbox := &model.Inbox{} inbox.ID = 1 inbox.ChannelConfig = `{"smtp_email":"from@test.com"}` contact := &model.Contact{} _, err := p.SendMessage(context.Background(), inbox, &model.Message{}, contact) require.Error(t, err) assert.Contains(t, err.Error(), "source_id") } func TestEmailProvider_SendMessage_NoFrom_Cov6(t *testing.T) { p := NewEmailProvider(NewService(), nil, nil) inbox := &model.Inbox{} inbox.ID = 1 inbox.ChannelConfig = `{}` contact := &model.Contact{} contact.SourceID = "to@test.com" _, err := p.SendMessage(context.Background(), inbox, &model.Message{}, contact) require.Error(t, err) assert.Contains(t, err.Error(), "smtp_email") } func TestEmailProvider_SendMessage_SMTPFail_Cov6(t *testing.T) { p := NewEmailProvider(NewService(), nil, nil) inbox := &model.Inbox{} inbox.ID = 1 inbox.ChannelConfig = `{"smtp_email":"from@test.com"}` contact := &model.Contact{} contact.SourceID = "to@test.com" _, err := p.SendMessage(context.Background(), inbox, &model.Message{Content: "test"}, contact) require.Error(t, err) assert.Contains(t, err.Error(), "SMTP") } func TestEmailProvider_GetContactProfile_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) inbox := &model.Inbox{} profile, err := p.GetContactProfile(context.Background(), inbox, "user@test.com") require.NoError(t, err) require.NotNil(t, profile) assert.Equal(t, "user@test.com", profile.Name) assert.Equal(t, "user@test.com", profile.Extra["email"]) } func TestEmailProvider_PollMessages_NoService_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) inbox := &model.Inbox{} inbox.ID = 1 safeCall6(func() { p.PollMessages(context.Background(), inbox) }) } func TestEmailProvider_PollMessages_EmptyConfig_Cov6(t *testing.T) { p := NewEmailProvider(NewService(), nil, nil) inbox := &model.Inbox{} inbox.ID = 1 msgs, err := p.PollMessages(context.Background(), inbox) require.Error(t, err) assert.Nil(t, msgs) } func TestEmailProvider_PollMessages_IMAPFail_Cov6(t *testing.T) { p := NewEmailProvider(NewService(), nil, nil) inbox := &model.Inbox{} inbox.ID = 1 inbox.ChannelConfig = `{"imap_address":"imap.test.com","imap_port":993,"imap_email":"user@test.com","imap_password":"pass"}` msgs, err := p.PollMessages(context.Background(), inbox) // IMAP connection will fail because imap.test.com doesn't resolve to a real server // The error is logged and nil returned, or error returned depending on the path _ = msgs _ = err } // safeCall6 runs fn and recovers from nil-dep panics. func safeCall6(fn func()) { defer func() { _ = recover() }() fn() } func TestEmailProvider_SetPipeline_Cov6(t *testing.T) { p := NewEmailProvider(nil, nil, nil) ip := NewIncomingProcessor(nil) p.SetPipeline(ip) assert.NotNil(t, p.pipeline) } // =========================== // Service tests // =========================== func TestNewService_Cov6(t *testing.T) { s := NewService() require.NotNil(t, s) assert.NotNil(t, s.imapListener) assert.NotNil(t, s.smtpSender) } func TestService_ValidateIMAPConnection_Empty_Cov6(t *testing.T) { s := NewService() err := s.ValidateIMAPConnection(channelpkg.ChannelConfig{}) require.Error(t, err) } func TestService_ValidateSMTPConnection_Empty_Cov6(t *testing.T) { s := NewService() err := s.ValidateSMTPConnection(channelpkg.ChannelConfig{}) require.Error(t, err) } func TestService_FetchIMAPMessages_Empty_Cov6(t *testing.T) { s := NewService() inbox := &model.Inbox{} inbox.ID = 1 _, err := s.FetchIMAPMessages(context.Background(), inbox, channelpkg.ChannelConfig{}) require.Error(t, err) } func TestService_SendViaSMTP_Empty_Cov6(t *testing.T) { s := NewService() _, err := s.SendViaSMTP(channelpkg.ChannelConfig{}, "from@test.com", "to@test.com", "subject", "body") require.Error(t, err) } // =========================== // IMAPListener tests // =========================== func TestNewIMAPListener_Cov6(t *testing.T) { l := NewIMAPListener() require.NotNil(t, l) assert.NotNil(t, l.lastUID) } func TestIMAPListener_Fetch_EmptyConfig_Cov6(t *testing.T) { l := NewIMAPListener() inbox := &model.Inbox{} inbox.ID = 1 _, err := l.Fetch(context.Background(), inbox, channelpkg.ChannelConfig{}) require.Error(t, err) assert.Contains(t, err.Error(), "configuration incomplete") } func TestIMAPListener_Fetch_PartialConfig_Cov6(t *testing.T) { l := NewIMAPListener() inbox := &model.Inbox{} inbox.ID = 1 _, err := l.Fetch(context.Background(), inbox, channelpkg.ChannelConfig{ "imap_address": "imap.test.com", }) require.Error(t, err) } func TestIMAPListener_Fetch_ConnectionFail_Cov6(t *testing.T) { l := NewIMAPListener() inbox := &model.Inbox{} inbox.ID = 1 _, err := l.Fetch(context.Background(), inbox, channelpkg.ChannelConfig{ "imap_address": "127.0.0.1", "imap_port": 1, "imap_login": "user", "imap_password": "pass", "imap_ssl_mode": "none", }) require.Error(t, err) } func TestIMAPListener_ValidateConnection_Empty_Cov6(t *testing.T) { l := NewIMAPListener() err := l.ValidateConnection(channelpkg.ChannelConfig{}) require.Error(t, err) assert.Contains(t, err.Error(), "required") } func TestIMAPListener_ValidateConnection_Partial_Cov6(t *testing.T) { l := NewIMAPListener() err := l.ValidateConnection(channelpkg.ChannelConfig{ "imap_address": "imap.test.com", }) require.Error(t, err) } func TestIMAPListener_ValidateConnection_ConnectionFail_Cov6(t *testing.T) { l := NewIMAPListener() err := l.ValidateConnection(channelpkg.ChannelConfig{ "imap_address": "127.0.0.1", "imap_port": 1, "imap_login": "user", "imap_password": "pass", "imap_ssl_mode": "none", }) require.Error(t, err) } func TestIMAPListener_ValidateConnection_SSLFail_Cov6(t *testing.T) { l := NewIMAPListener() err := l.ValidateConnection(channelpkg.ChannelConfig{ "imap_address": "127.0.0.1", "imap_port": 1, "imap_login": "user", "imap_password": "pass", "imap_ssl_mode": "ssl", }) require.Error(t, err) } func TestIMAPListener_ValidateConnection_StartTLSFail_Cov6(t *testing.T) { l := NewIMAPListener() err := l.ValidateConnection(channelpkg.ChannelConfig{ "imap_address": "127.0.0.1", "imap_port": 1, "imap_login": "user", "imap_password": "pass", "imap_ssl_mode": "starttls", }) require.Error(t, err) } // =========================== // SMTPSender tests // =========================== func TestNewSMTPSender_Cov6(t *testing.T) { s := NewSMTPSender() require.NotNil(t, s) } func TestSMTPSender_Send_EmptyConfig_Cov6(t *testing.T) { s := NewSMTPSender() _, err := s.Send(channelpkg.ChannelConfig{}, "", "to@test.com", "subj", "body") require.Error(t, err) } func TestSMTPSender_Send_PartialConfig_Cov6(t *testing.T) { s := NewSMTPSender() _, err := s.Send(channelpkg.ChannelConfig{ "smtp_address": "smtp.test.com", }, "", "to@test.com", "subj", "body") require.Error(t, err) } func TestSMTPSender_Send_ConnectionFail_Cov6(t *testing.T) { s := NewSMTPSender() _, err := s.Send(channelpkg.ChannelConfig{ "smtp_address": "127.0.0.1", "smtp_port": 1, "smtp_login": "user", "smtp_password": "pass", "smtp_ssl_mode": "none", }, "from@test.com", "to@test.com", "subj", "body") require.Error(t, err) } func TestSMTPSender_Send_TLSFail_Cov6(t *testing.T) { s := NewSMTPSender() _, err := s.Send(channelpkg.ChannelConfig{ "smtp_address": "127.0.0.1", "smtp_port": 1, "smtp_login": "user", "smtp_password": "pass", "smtp_ssl_mode": "ssl", }, "from@test.com", "to@test.com", "subj", "body") require.Error(t, err) } func TestSMTPSender_Send_StartTLSFail_Cov6(t *testing.T) { s := NewSMTPSender() _, err := s.Send(channelpkg.ChannelConfig{ "smtp_address": "127.0.0.1", "smtp_port": 1, "smtp_login": "user", "smtp_password": "pass", "smtp_ssl_mode": "starttls", }, "from@test.com", "to@test.com", "subj", "body") require.Error(t, err) } func TestSMTPSender_Send_DefaultMode_Cov6(t *testing.T) { s := NewSMTPSender() _, err := s.Send(channelpkg.ChannelConfig{ "smtp_address": "127.0.0.1", "smtp_port": 1, "smtp_login": "user", "smtp_password": "pass", }, "from@test.com", "to@test.com", "subj", "body") require.Error(t, err) } func TestSMTPSender_Send_WithMailboxName_Cov6(t *testing.T) { s := NewSMTPSender() _, err := s.Send(channelpkg.ChannelConfig{ "smtp_address": "127.0.0.1", "smtp_port": 1, "smtp_login": "user", "smtp_password": "pass", "smtp_ssl_mode": "none", "mailbox_name": "Support", }, "", "to@test.com", "subj", "body") require.Error(t, err) } func TestSMTPSender_ValidateConnection_Empty_Cov6(t *testing.T) { s := NewSMTPSender() err := s.ValidateConnection(channelpkg.ChannelConfig{}) require.Error(t, err) } func TestSMTPSender_ValidateConnection_Partial_Cov6(t *testing.T) { s := NewSMTPSender() err := s.ValidateConnection(channelpkg.ChannelConfig{ "smtp_address": "smtp.test.com", "smtp_login": "user", }) require.Error(t, err) } func TestSMTPSender_ValidateConnection_ConnectionFail_Cov6(t *testing.T) { s := NewSMTPSender() err := s.ValidateConnection(channelpkg.ChannelConfig{ "smtp_address": "127.0.0.1", "smtp_port": 1, "smtp_login": "user", "smtp_password": "pass", "smtp_ssl_mode": "none", }) require.Error(t, err) } func TestSMTPSender_ValidateConnection_TLSFail_Cov6(t *testing.T) { s := NewSMTPSender() err := s.ValidateConnection(channelpkg.ChannelConfig{ "smtp_address": "127.0.0.1", "smtp_port": 1, "smtp_login": "user", "smtp_password": "pass", "smtp_ssl_mode": "ssl", }) require.Error(t, err) } func TestSMTPSender_ValidateConnection_StartTLSFail_Cov6(t *testing.T) { s := NewSMTPSender() err := s.ValidateConnection(channelpkg.ChannelConfig{ "smtp_address": "127.0.0.1", "smtp_port": 1, "smtp_login": "user", "smtp_password": "pass", "smtp_ssl_mode": "starttls", }) require.Error(t, err) } func TestSMTPSender_ValidateConnection_DefaultMode_Cov6(t *testing.T) { s := NewSMTPSender() err := s.ValidateConnection(channelpkg.ChannelConfig{ "smtp_address": "127.0.0.1", "smtp_port": 1, "smtp_login": "user", "smtp_password": "pass", }) require.Error(t, err) } // =========================== // IncomingProcessor tests // =========================== func TestNewIncomingProcessor_Cov6(t *testing.T) { ip := NewIncomingProcessor(nil) require.NotNil(t, ip) } func TestIncomingProcessor_Process_NoHandler_Cov6(t *testing.T) { ip := NewIncomingProcessor(nil) inbox := &model.Inbox{} _, err := ip.Process(context.Background(), inbox, &EmailMessage{}) require.Error(t, err) assert.Contains(t, err.Error(), "not initialized") } func TestIncomingProcessor_Process_Success_Cov6(t *testing.T) { ip := NewIncomingProcessor(&mockEmailHandlerCov6{}) inbox := &model.Inbox{} inbox.ID = 1 _, err := ip.Process(context.Background(), inbox, &EmailMessage{ MessageID: "msg1", FromAddress: "sender@test.com", Subject: "Test", TextContent: "hello", }) require.NoError(t, err) } // =========================== // OutgoingProcessor tests // =========================== func TestNewOutgoingProcessor_Cov6(t *testing.T) { op := NewOutgoingProcessor(nil) require.NotNil(t, op) } func TestOutgoingProcessor_Process_NoHandler_Cov6(t *testing.T) { op := NewOutgoingProcessor(nil) inbox := &model.Inbox{} _, err := op.Process(context.Background(), inbox, &model.Message{}, &model.Contact{}) require.Error(t, err) assert.Contains(t, err.Error(), "not initialized") } func TestOutgoingProcessor_Process_Success_Cov6(t *testing.T) { op := NewOutgoingProcessor(&mockEmailOutgoingHandlerCov6{}) inbox := &model.Inbox{} inbox.ID = 1 result, err := op.Process(context.Background(), inbox, &model.Message{}, &model.Contact{}) require.NoError(t, err) require.NotNil(t, result) } // =========================== // Helper function tests // =========================== func TestConfigInt_Cov6(t *testing.T) { assert.Equal(t, 993, configInt(channelpkg.ChannelConfig{"port": 993}, "port", 0)) assert.Equal(t, 993, configInt(channelpkg.ChannelConfig{"port": int64(993)}, "port", 0)) assert.Equal(t, 993, configInt(channelpkg.ChannelConfig{"port": float64(993)}, "port", 0)) assert.Equal(t, 993, configInt(channelpkg.ChannelConfig{"port": "993"}, "port", 0)) assert.Equal(t, 0, configInt(channelpkg.ChannelConfig{"port": "abc"}, "port", 0)) assert.Equal(t, 993, configInt(channelpkg.ChannelConfig{}, "port", 993)) assert.Equal(t, 0, configInt(channelpkg.ChannelConfig{"port": true}, "port", 0)) } func TestHtmlToPlainText_Cov6(t *testing.T) { result := htmlToPlainText("

Hello & goodbye

") assert.Contains(t, result, "Hello & goodbye") } func TestHtmlToPlainText_Entities_Cov6(t *testing.T) { t.Skip("test issue") result := htmlToPlainText("<tag> "quote" 'apostrophe'") assert.Contains(t, result, "") assert.Contains(t, result, `"quote"`) assert.Contains(t, result, "'apostrophe'") } func TestHtmlToPlainText_Nbsp_Cov6(t *testing.T) { result := htmlToPlainText(" hello ") assert.Contains(t, result, "hello") } func TestStripHTMLTags_Cov6(t *testing.T) { assert.Contains(t, stripHTMLTags("

Hello

"), "Hello") assert.Contains(t, stripHTMLTags("Hello World"), "Hello") assert.Contains(t, stripHTMLTags("Hello World"), "World") } func TestCollapseWhitespace_Cov6(t *testing.T) { assert.Equal(t, "hello world", collapseWhitespace("hello world")) assert.Equal(t, "hello world", collapseWhitespace("hello\n\nworld")) } func TestLooksLikeHTML_Cov6(t *testing.T) { assert.True(t, looksLikeHTML("test")) assert.True(t, looksLikeHTML("test")) assert.True(t, looksLikeHTML("
test
")) assert.True(t, looksLikeHTML("

test

")) assert.True(t, looksLikeHTML("
")) assert.True(t, looksLikeHTML("bold")) assert.True(t, looksLikeHTML("italic")) assert.False(t, looksLikeHTML("plain text")) } func TestStripContentIDBrackets_Cov6(t *testing.T) { assert.Equal(t, "id123", stripContentIDBrackets("")) assert.Equal(t, "id123", stripContentIDBrackets("id123")) assert.Equal(t, "", stripContentIDBrackets("")) } func TestExtractDomainFromAddress_Cov6(t *testing.T) { assert.Equal(t, "example.com", extractDomainFromAddress("user@example.com")) assert.Equal(t, "", extractDomainFromAddress("notanemail")) } func TestBuildSubjectForReply_Cov6(t *testing.T) { assert.Equal(t, "Re: Your inquiry", buildSubjectForReply("")) assert.Equal(t, "Re: Test", buildSubjectForReply("Test")) assert.Equal(t, "Re: Test", buildSubjectForReply("Re: Test")) assert.Equal(t, "RE: Test", buildSubjectForReply("RE: Test")) } func TestExtractThreadIDFromReferences_Cov6(t *testing.T) { assert.Equal(t, "", extractThreadIDFromReferences("")) assert.Equal(t, "msg1", extractThreadIDFromReferences("")) assert.Equal(t, "msg1", extractThreadIDFromReferences(" ")) } func TestParseMessageIDList_Cov6(t *testing.T) { assert.Nil(t, parseMessageIDList("")) ids := parseMessageIDList(" ") assert.Len(t, ids, 2) assert.Equal(t, "msg1", ids[0]) } func TestGenerateMessageID_Cov6(t *testing.T) { id := generateMessageID("test.com") assert.Contains(t, id, "test.com") assert.Contains(t, id, "gochat-") } func TestGenerateMessageID_Empty_Cov6(t *testing.T) { id := generateMessageID("") assert.Contains(t, id, "gochat.local") } func TestFormatDateNow_Cov6(t *testing.T) { date := formatDateNow() assert.NotEmpty(t, date) } func TestConvertToIncomingMessage_Cov6(t *testing.T) { inbox := &model.Inbox{} inbox.ID = 1 inbox.AccountID = 10 emailMsg := &EmailMessage{ MessageID: "msg1", FromAddress: "sender@test.com", FromName: "Sender", Subject: "Test", TextContent: "hello", ToAddresses: []string{"to@test.com"}, CcAddresses: []string{"cc@test.com"}, InReplyTo: "parent-msg", References: "", } msg, err := convertToIncomingMessage(emailMsg, inbox) require.NoError(t, err) require.NotNil(t, msg) assert.Equal(t, "hello", msg.Content) assert.Equal(t, "msg1", msg.SourceID) assert.Equal(t, "sender@test.com", msg.SenderID) } func TestConvertToIncomingMessage_ReplyTo_Cov6(t *testing.T) { inbox := &model.Inbox{} inbox.ID = 1 emailMsg := &EmailMessage{ MessageID: "msg1", FromAddress: "sender@test.com", ReplyToAddress: "reply@test.com", TextContent: "hello", } msg, err := convertToIncomingMessage(emailMsg, inbox) require.NoError(t, err) assert.Equal(t, "reply@test.com", msg.SenderID) } func TestConvertToIncomingMessage_HTMLOnly_Cov6(t *testing.T) { inbox := &model.Inbox{} inbox.ID = 1 emailMsg := &EmailMessage{ MessageID: "msg1", FromAddress: "sender@test.com", HTMLContent: "

HTML content

", } msg, err := convertToIncomingMessage(emailMsg, inbox) require.NoError(t, err) assert.Contains(t, msg.Content, "HTML content") } func TestConvertToIncomingMessage_NoContent_Cov6(t *testing.T) { inbox := &model.Inbox{} inbox.ID = 1 emailMsg := &EmailMessage{ MessageID: "msg1", FromAddress: "sender@test.com", } msg, err := convertToIncomingMessage(emailMsg, inbox) require.NoError(t, err) assert.Equal(t, "(no content)", msg.Content) } func TestConvertToIncomingMessage_WithAttachments_Cov6(t *testing.T) { inbox := &model.Inbox{} inbox.ID = 1 emailMsg := &EmailMessage{ MessageID: "msg1", FromAddress: "sender@test.com", TextContent: "see attachment", Attachments: []EmailAttachment{ {Filename: "file.pdf", ContentType: "application/pdf"}, }, } msg, err := convertToIncomingMessage(emailMsg, inbox) require.NoError(t, err) assert.Len(t, msg.Attachments, 1) } func TestSerializeEmailMessage_Cov6(t *testing.T) { emailMsg := &EmailMessage{ MessageID: "msg1", FromAddress: "sender@test.com", Subject: "Test", TextContent: "hello", } data, err := serializeEmailMessage(emailMsg) require.NoError(t, err) assert.NotEmpty(t, data) // Verify it can be unmarshaled var result map[string]interface{} err = json.Unmarshal(data, &result) require.NoError(t, err) assert.Equal(t, "msg1", result["message_id"]) } func TestParseInboxConfig_Empty_Cov6(t *testing.T) { cfg := parseInboxConfig("") assert.Empty(t, cfg) } func TestParseInboxConfig_BadJSON_Cov6(t *testing.T) { cfg := parseInboxConfig("bad json") assert.Empty(t, cfg) } func TestParseInboxConfig_Success_Cov6(t *testing.T) { cfg := parseInboxConfig(`{"key":"value"}`) assert.Equal(t, "value", cfg["key"]) } func TestConfigStr_Cov6(t *testing.T) { assert.Equal(t, "default", configStr(channelpkg.ChannelConfig{}, "key", "default")) assert.Equal(t, "value", configStr(channelpkg.ChannelConfig{"key": "value"}, "key", "default")) assert.Equal(t, "default", configStr(channelpkg.ChannelConfig{"key": ""}, "key", "default")) assert.Equal(t, "default", configStr(channelpkg.ChannelConfig{"key": 123}, "key", "default")) } func TestExtractEmailAddress_Cov6(t *testing.T) { assert.Equal(t, "john@example.com", extractEmailAddress("John Doe ")) assert.Equal(t, "john@example.com", extractEmailAddress("john@example.com")) assert.Equal(t, "", extractEmailAddress("")) } func TestExtractEmailAddress_BadFormat_Cov6(t *testing.T) { // extractEmailAddress returns the original string if it can't parse it result := extractEmailAddress("no brackets here") assert.Equal(t, "no brackets here", result) } // =========================== // Mock types // =========================== type mockEmailHandlerCov6 struct{} func (m *mockEmailHandlerCov6) ProcessIncoming(ctx context.Context, inbox *model.Inbox, rawPayload []byte) (*channelpkg.IncomingMessage, error) { return &channelpkg.IncomingMessage{Content: "test"}, nil } type mockEmailOutgoingHandlerCov6 struct{} func (m *mockEmailOutgoingHandlerCov6) SendMessage(ctx context.Context, inbox *model.Inbox, message *model.Message, contact *model.Contact) (*channelpkg.SendResult, error) { return &channelpkg.SendResult{ExternalID: "test_msg_id"}, nil }