diff --git a/config/config_test.go b/config/config_test.go index b521d2d..4906c28 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -200,6 +200,49 @@ func TestConfigGetAccountByEmail(t *testing.T) { } } +// TestAddContactStripsCommas verifies that trailing/leading commas are stripped from email addresses when saving contacts. +func TestAddContactStripsCommas(t *testing.T) { + tempDir := t.TempDir() + t.Setenv("HOME", tempDir) + + testCases := []struct { + name string + inputEmail string + wantEmail string + }{ + {"trailing comma", "friend@example.com,", "friend@example.com"}, + {"leading comma", ",friend@example.com", "friend@example.com"}, + {"both commas", ",friend@example.com,", "friend@example.com"}, + {"no comma", "friend@example.com", "friend@example.com"}, + {"whitespace and comma", " friend@example.com, ", "friend@example.com"}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Use a fresh temp dir per sub-test to avoid state leakage. + subDir := t.TempDir() + t.Setenv("HOME", subDir) + + if err := AddContact("Friend", tc.inputEmail); err != nil { + t.Fatalf("AddContact() failed: %v", err) + } + + cache, err := LoadContactsCache() + if err != nil { + t.Fatalf("LoadContactsCache() failed: %v", err) + } + + if len(cache.Contacts) != 1 { + t.Fatalf("Expected 1 contact, got %d", len(cache.Contacts)) + } + + if cache.Contacts[0].Email != tc.wantEmail { + t.Errorf("Email = %q, want %q", cache.Contacts[0].Email, tc.wantEmail) + } + }) + } +} + // TestConfigHasAccounts tests the HasAccounts method. func TestConfigHasAccounts(t *testing.T) { cfg := &Config{} diff --git a/tui/inbox.go b/tui/inbox.go index 7e1ef7e..e236fa4 100644 --- a/tui/inbox.go +++ b/tui/inbox.go @@ -23,7 +23,7 @@ var ( tabBarStyle = lipgloss.NewStyle().BorderStyle(lipgloss.NormalBorder()).BorderBottom(true).PaddingBottom(1).MarginBottom(1) ) -var dateStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("243")) +var dateStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("243")) var senderStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("250")).Bold(true) type item struct { @@ -183,23 +183,23 @@ type AccountTab struct { } type Inbox struct { - list list.Model - isFetching bool - isRefreshing bool - emailsCount int - accounts []config.Account - emailsByAccount map[string][]fetcher.Email - allEmails []fetcher.Email - tabs []AccountTab - activeTabIndex int - width int - height int - currentAccountID string // Empty means "ALL" - emailCountByAcct map[string]int - mailbox MailboxKind - folderName string // Custom folder name override for title - noMoreByAccount map[string]bool // Per-account: true when pagination returns 0 results - extraShortHelpKeys []key.Binding + list list.Model + isFetching bool + isRefreshing bool + emailsCount int + accounts []config.Account + emailsByAccount map[string][]fetcher.Email + allEmails []fetcher.Email + tabs []AccountTab + activeTabIndex int + width int + height int + currentAccountID string // Empty means "ALL" + emailCountByAcct map[string]int + mailbox MailboxKind + folderName string // Custom folder name override for title + noMoreByAccount map[string]bool // Per-account: true when pagination returns 0 results + extraShortHelpKeys []key.Binding } func NewInbox(emails []fetcher.Email, accounts []config.Account) *Inbox {