package bootstrap import ( "bytes" "context" "errors" "strings" "testing" "forge.lclr.dev/AI/mcp-framework/secretstore" ) func withLoginBitwarden(t *testing.T, fn func(secretstore.BitwardenLoginOptions) (string, error)) { t.Helper() previous := loginBitwarden loginBitwarden = fn t.Cleanup(func() { loginBitwarden = previous }) } func TestDefaultLoginHandlerPrintsConfirmation(t *testing.T) { var stdout bytes.Buffer withLoginBitwarden(t, func(opts secretstore.BitwardenLoginOptions) (string, error) { if opts.ServiceName != "my-mcp" { t.Fatalf("ServiceName = %q, want %q", opts.ServiceName, "my-mcp") } return "session-token", nil }) handler := DefaultLoginHandler("my-mcp") err := handler(context.Background(), Invocation{ Command: CommandLogin, Stdout: &stdout, }) if err != nil { t.Fatalf("handler returned error: %v", err) } out := stdout.String() if !strings.Contains(out, `"my-mcp"`) { t.Fatalf("stdout = %q, want mention of binary name", out) } if !strings.Contains(out, "persistée") { t.Fatalf("stdout = %q, want confirmation message", out) } } func TestDefaultLoginHandlerPropagatesError(t *testing.T) { var stdout bytes.Buffer loginErr := errors.New("vault locked") withLoginBitwarden(t, func(_ secretstore.BitwardenLoginOptions) (string, error) { return "", loginErr }) handler := DefaultLoginHandler("my-mcp") err := handler(context.Background(), Invocation{ Command: CommandLogin, Stdout: &stdout, }) if !errors.Is(err, loginErr) { t.Fatalf("err = %v, want %v", err, loginErr) } if stdout.Len() > 0 { t.Fatalf("stdout should be empty on error, got %q", stdout.String()) } } func TestRunUsesDefaultLoginHandlerWhenHookSet(t *testing.T) { var stdout bytes.Buffer withLoginBitwarden(t, func(_ secretstore.BitwardenLoginOptions) (string, error) { return "tok", nil }) err := Run(context.Background(), Options{ BinaryName: "my-mcp", Args: []string{"login"}, Stdout: &stdout, Hooks: Hooks{ Login: DefaultLoginHandler("my-mcp"), }, }) if err != nil { t.Fatalf("Run error = %v", err) } if !strings.Contains(stdout.String(), "persistée") { t.Fatalf("stdout = %q, want confirmation", stdout.String()) } } func TestRunLoginAutoHiddenWithoutHook(t *testing.T) { var stdout bytes.Buffer err := Run(context.Background(), Options{ BinaryName: "my-mcp", Args: []string{"login"}, Stdout: &stdout, }) if !errors.Is(err, ErrUnknownCommand) { t.Fatalf("err = %v, want ErrUnknownCommand", err) } }