package imap import ( "log/slog" "testing" "raven/internal/filter" ) func TestConfigAddress(t *testing.T) { tests := []struct { name string cfg Config want string }{ { name: "standard config", cfg: Config{Host: "imap.example.com", Port: "993"}, want: "imap.example.com:993", }, { name: "empty host", cfg: Config{Host: "", Port: "993"}, want: ":993", }, { name: "empty port", cfg: Config{Host: "imap.example.com", Port: ""}, want: "imap.example.com:", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := tt.cfg.Address(); got != tt.want { t.Errorf( "Address() = %q, want %q", got, tt.want, ) } }) } } func TestConfigValidate(t *testing.T) { tests := []struct { name string cfg Config wantErr string }{ { name: "valid config", cfg: Config{ Host: "imap.example.com", Password: "secret", Port: "993", User: "user@example.com", }, wantErr: "", }, { name: "missing host", cfg: Config{ Password: "secret", Port: "993", User: "user@example.com", }, wantErr: "missing host", }, { name: "missing password", cfg: Config{ Host: "imap.example.com", Port: "993", User: "user@example.com", }, wantErr: "missing password", }, { name: "missing port", cfg: Config{ Host: "imap.example.com", Password: "secret", User: "user@example.com", }, wantErr: "missing port", }, { name: "missing user", cfg: Config{ Host: "imap.example.com", Password: "secret", Port: "993", }, wantErr: "missing user", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := tt.cfg.Validate() if tt.wantErr == "" { if err != nil { t.Errorf( "Validate() unexpected error: %v", err, ) } return } if err == nil { t.Errorf( "Validate() expected error containing %q, got nil", tt.wantErr, ) return } if got := err.Error(); got != tt.wantErr { t.Errorf( "Validate() error = %q, want %q", got, tt.wantErr, ) } }) } } func TestNewClient(t *testing.T) { validCfg := Config{ Host: "imap.example.com", Password: "secret", Port: "993", User: "user@example.com", } tests := []struct { name string cfg Config filters filter.Filters wantErr bool }{ { name: "valid config", cfg: validCfg, filters: filter.Filters{}, wantErr: false, }, { name: "valid config with filters", cfg: validCfg, filters: filter.Filters{ Subject: "test", To: "recipient@example.com", Body: []string{"keyword"}, }, wantErr: false, }, { name: "invalid config", cfg: Config{Host: "imap.example.com"}, filters: filter.Filters{}, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { client, err := NewClient( tt.cfg, tt.filters, slog.Default(), ) if tt.wantErr { if err == nil { t.Error( "NewClient() expected error, got nil", ) } return } if err != nil { t.Errorf( "NewClient() unexpected error: %v", err, ) return } if client == nil { t.Error("NewClient() returned nil client") return } // Verify client is not connected. if client.Client() != nil { t.Error( "NewClient() client should not be connected", ) } }) } } func TestClientNotConnected(t *testing.T) { cfg := Config{ Host: "imap.example.com", Password: "secret", Port: "993", User: "user@example.com", } client, err := NewClient(cfg, filter.Filters{}, slog.Default()) if err != nil { t.Fatalf("NewClient() unexpected error: %v", err) } t.Run("Fetch without connection", func(t *testing.T) { _, err := client.Fetch(1, true) if err == nil { t.Error("Fetch() expected error when not connected") } }) t.Run("MarkSeen without connection", func(t *testing.T) { err := client.MarkSeen(1) if err == nil { t.Error("MarkSeen() expected error when not connected") } }) }