package cli import ( "bytes" "context" "os" "strings" "testing" "email-mcp/internal/secretstore" ) func TestInteractiveConfigPrompterPromptCredentialCollectsValues(t *testing.T) { input := strings.NewReader("imap.example.com\nalice\nsecret\n") output := &bytes.Buffer{} prompter := NewInteractiveConfigPrompter(input, output) cred, err := prompter.PromptCredential(context.Background(), secretstore.Credential{}, false) if err != nil { t.Fatalf("PromptCredential returned error: %v", err) } if cred.Host != "imap.example.com" || cred.Username != "alice" || cred.Password != "secret" { t.Fatalf("unexpected credential: %#v", cred) } if got := output.String(); got != "IMAP host: Username: Password: " { t.Fatalf("unexpected prompts: %q", got) } } func TestInteractiveConfigPrompterPromptCredentialKeepsStoredPassword(t *testing.T) { input := strings.NewReader("imap.example.com\nalice\n\n") output := &bytes.Buffer{} prompter := NewInteractiveConfigPrompter(input, output) cred, err := prompter.PromptCredential(context.Background(), secretstore.Credential{ Host: "imap.example.com", Username: "alice", Password: "stored-secret", }, true) if err != nil { t.Fatalf("PromptCredential returned error: %v", err) } if cred.Password != "stored-secret" { t.Fatalf("expected stored password to be preserved, got %q", cred.Password) } if got := output.String(); !strings.Contains(got, "Password [stored, leave blank to keep]: ") { t.Fatalf("unexpected prompts: %q", got) } } func TestInteractiveConfigPrompterPromptCredentialUsesSetupEngineWithFileInput(t *testing.T) { input := setupInputFile(t, "imap.example.com\nalice\nsecret\n") output := &bytes.Buffer{} prompter := NewInteractiveConfigPrompter(input, output) cred, err := prompter.PromptCredential(context.Background(), secretstore.Credential{}, false) if err != nil { t.Fatalf("PromptCredential returned error: %v", err) } if cred.Host != "imap.example.com" || cred.Username != "alice" || cred.Password != "secret" { t.Fatalf("unexpected credential: %#v", cred) } if got := output.String(); got != "IMAP host: Username: Password: " { t.Fatalf("unexpected prompts: %q", got) } } func TestInteractiveConfigPrompterPromptCredentialKeepsStoredPasswordWithSetupEngine(t *testing.T) { input := setupInputFile(t, "imap.example.com\nalice\n\n") output := &bytes.Buffer{} prompter := NewInteractiveConfigPrompter(input, output) cred, err := prompter.PromptCredential(context.Background(), secretstore.Credential{ Host: "imap.example.com", Username: "alice", Password: "stored-secret", }, true) if err != nil { t.Fatalf("PromptCredential returned error: %v", err) } if cred.Password != "stored-secret" { t.Fatalf("expected stored password to be preserved, got %q", cred.Password) } if got := output.String(); !strings.Contains(got, "Password [stored, leave blank to keep]: ") { t.Fatalf("unexpected prompts: %q", got) } } func setupInputFile(t *testing.T, content string) *os.File { t.Helper() input, err := os.CreateTemp(t.TempDir(), "setup-input-*.txt") if err != nil { t.Fatalf("CreateTemp returned error: %v", err) } t.Cleanup(func() { _ = input.Close() }) if _, err := input.WriteString(content); err != nil { t.Fatalf("WriteString returned error: %v", err) } if _, err := input.Seek(0, 0); err != nil { t.Fatalf("Seek returned error: %v", err) } return input }