package cli import ( "bytes" "context" "errors" "fmt" "strings" "testing" "email-mcp/internal/secretstore" "email-mcp/internal/secretstore/kwallet" ) type errorStoreStub struct { err error } func (s errorStoreStub) Save(context.Context, string, secretstore.Credential) error { return s.err } func (s errorStoreStub) Load(context.Context, string) (secretstore.Credential, error) { return secretstore.Credential{}, s.err } func TestAppRunSetupMapsUnavailableWalletError(t *testing.T) { app := NewAppWithDependencies(&promptStub{ credential: secretstore.Credential{ Host: "imap.example.com", Username: "alice", Password: "secret", }, }, errorStoreStub{ err: fmt.Errorf("%w: session bus missing", kwallet.ErrKWalletUnavailable), }, nil, &bytes.Buffer{}) err := app.Run([]string{"setup"}) if err == nil { t.Fatal("expected setup to fail") } if !strings.Contains(strings.ToLower(err.Error()), "kwallet is not available") { t.Fatalf("expected mapped kwallet error, got %v", err) } } func TestMapAppErrorMapsMissingCredentialError(t *testing.T) { err := mapAppError(fmt.Errorf("%w: missing entry", kwallet.ErrCredentialNotFound)) if err == nil { t.Fatal("expected mapped error") } if !strings.Contains(err.Error(), "run `email-mcp setup`") { t.Fatalf("expected setup guidance, got %v", err) } if !errors.Is(err, kwallet.ErrCredentialNotFound) { t.Fatalf("expected typed error to be preserved, got %v", err) } } func TestMapAppErrorPreservesUnavailableTypedError(t *testing.T) { err := mapAppError(fmt.Errorf("%w: session bus missing", kwallet.ErrKWalletUnavailable)) if err == nil { t.Fatal("expected mapped error") } if !errors.Is(err, kwallet.ErrKWalletUnavailable) { t.Fatalf("expected typed error to be preserved, got %v", err) } } func TestMapAppErrorLeavesUnknownErrorsUntouched(t *testing.T) { wantErr := errors.New("boom") err := mapAppError(wantErr) if !errors.Is(err, wantErr) { t.Fatalf("expected original error, got %v", err) } }