diff --git a/config/cache.go b/config/cache.go index 14426b33ca9356d31062f99b9a5062e323710910..8bc4d1a6ebcd4350a682403234ccf0e4a89d4f5b 100644 --- a/config/cache.go +++ b/config/cache.go @@ -148,13 +148,17 @@ func LoadContactsCache() (*ContactsCache, error) { return &cache, nil } +func normalizeContactEmail(email string) string { + return strings.ToLower(strings.Trim(strings.TrimSpace(email), ",")) +} + // AddContact adds or updates a contact in the cache. func AddContact(name, email string) error { if email == "" { return nil } - email = strings.ToLower(strings.Trim(strings.TrimSpace(email), ",")) + email = normalizeContactEmail(email) name = strings.TrimSpace(name) cache, err := LoadContactsCache() @@ -166,7 +170,8 @@ func AddContact(name, email string) error { found := false for i, c := range cache.Contacts { if strings.EqualFold(c.Email, email) { - // Update existing contact + // Normalize the stored email to a canonical lowercase form. + cache.Contacts[i].Email = email cache.Contacts[i].UseCount++ cache.Contacts[i].LastUsed = time.Now() // Update name if we have a better one diff --git a/config/config_test.go b/config/config_test.go index 2b1604b4aad6e42ea3d97d5d7a7389f112f79d02..6c68d92baaad8f830f7f119446a53d39d380faf7 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -201,6 +201,34 @@ func TestConfigGetAccountByEmail(t *testing.T) { } } +func TestAddContactNormalizesEmailAndDeduplicates(t *testing.T) { + t.Setenv("HOME", t.TempDir()) + + if err := AddContact("Alice", "Alice@Example.com"); err != nil { + t.Fatalf("AddContact() failed: %v", err) + } + if err := AddContact("", "alice@example.com"); 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 after deduplication, got %d", len(cache.Contacts)) + } + + contact := cache.Contacts[0] + if contact.Email != "alice@example.com" { + t.Errorf("Expected normalized email alice@example.com, got %s", contact.Email) + } + if contact.UseCount != 2 { + t.Errorf("Expected UseCount 2 after duplicate add, got %d", contact.UseCount) + } +} + // TestConfigHasAccounts tests the HasAccounts method. func TestConfigHasAccounts(t *testing.T) { cfg := &Config{}