|
| 1 | +package root |
| 2 | + |
| 3 | +import ( |
| 4 | + "strings" |
| 5 | + "testing" |
| 6 | + |
| 7 | + "github.com/spf13/cobra" |
| 8 | + |
| 9 | + "github.com/open-cli-collective/google-readonly/internal/keychain" |
| 10 | +) |
| 11 | + |
| 12 | +// TestWireCredentialRefSelection_FlagSet proves a --ref on a real command |
| 13 | +// path is recorded in the override the keychain.open resolver reads. |
| 14 | +func TestWireCredentialRefSelection_FlagSet(t *testing.T) { |
| 15 | + resetState(t) |
| 16 | + t.Setenv(keychain.CredentialRefEnvVar(), "") |
| 17 | + |
| 18 | + probe := newProbeCmd("probe-ref-flagset") |
| 19 | + rootCmd.AddCommand(probe) |
| 20 | + defer removeChild(t, probe) |
| 21 | + rootCmd.SetArgs([]string{"probe-ref-flagset", "--ref", "google-readonly/acct-a"}) |
| 22 | + |
| 23 | + if err := rootCmd.Execute(); err != nil { |
| 24 | + t.Fatalf("Execute: %v", err) |
| 25 | + } |
| 26 | + v, set := keychain.GetCredentialRefOverride() |
| 27 | + if !set { |
| 28 | + t.Fatalf("override flagSet = false, want true") |
| 29 | + } |
| 30 | + if v != "google-readonly/acct-a" { |
| 31 | + t.Errorf("override value = %q, want %q", v, "google-readonly/acct-a") |
| 32 | + } |
| 33 | +} |
| 34 | + |
| 35 | +// TestWireCredentialRefSelection_FlagInvalid asserts a malformed --ref fails |
| 36 | +// up front with a clear "--ref" error, before any keyring work. |
| 37 | +func TestWireCredentialRefSelection_FlagInvalid(t *testing.T) { |
| 38 | + resetState(t) |
| 39 | + |
| 40 | + probe := newProbeCmd("probe-ref-invalid") |
| 41 | + rootCmd.AddCommand(probe) |
| 42 | + defer removeChild(t, probe) |
| 43 | + rootCmd.SetArgs([]string{"probe-ref-invalid", "--ref", "no-slash"}) |
| 44 | + |
| 45 | + err := rootCmd.Execute() |
| 46 | + if err == nil { |
| 47 | + t.Fatal("expected error, got nil") |
| 48 | + } |
| 49 | + if !strings.Contains(err.Error(), "--"+credentialRefFlagName) { |
| 50 | + t.Errorf("error should mention --%s: %v", credentialRefFlagName, err) |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +// TestWireCredentialRefSelection_ShadowingSubcommand regresses the |
| 55 | +// cobra-doesn't-chain-PersistentPreRunE bug for --ref, mirroring the |
| 56 | +// --backend guard. |
| 57 | +func TestWireCredentialRefSelection_ShadowingSubcommand(t *testing.T) { |
| 58 | + resetState(t) |
| 59 | + t.Setenv(keychain.CredentialRefEnvVar(), "") |
| 60 | + |
| 61 | + shadow := &cobra.Command{ |
| 62 | + Use: "shadow-ref", |
| 63 | + PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { |
| 64 | + return WireCredentialRefSelection(cmd) |
| 65 | + }, |
| 66 | + } |
| 67 | + leaf := newProbeCmd("leaf") |
| 68 | + shadow.AddCommand(leaf) |
| 69 | + rootCmd.AddCommand(shadow) |
| 70 | + defer removeChild(t, shadow) |
| 71 | + |
| 72 | + rootCmd.SetArgs([]string{"shadow-ref", "leaf", "--ref", "google-readonly/acct-b"}) |
| 73 | + if err := rootCmd.Execute(); err != nil { |
| 74 | + t.Fatalf("Execute through shadowing PreRunE: %v", err) |
| 75 | + } |
| 76 | + v, set := keychain.GetCredentialRefOverride() |
| 77 | + if !set || v != "google-readonly/acct-b" { |
| 78 | + t.Errorf("override = (%q, %v); want (\"google-readonly/acct-b\", true) — shadower's PreRunE failed to invoke WireCredentialRefSelection", v, set) |
| 79 | + } |
| 80 | +} |
| 81 | + |
| 82 | +// TestCredentialRef_SetCredentialShadowsPersistent documents the intentional |
| 83 | +// exception to the inherit-everywhere rule: `set-credential` keeps its own |
| 84 | +// local --ref (the write target), so it must resolve to a DIFFERENT *pflag.Flag |
| 85 | +// than the root's persistent selector — while a read command inherits the |
| 86 | +// canonical persistent one. A regression that dropped set-credential's local |
| 87 | +// flag (or that made a read command shadow --ref) would flip these. |
| 88 | +func TestCredentialRef_SetCredentialShadowsPersistent(t *testing.T) { |
| 89 | + canonical := rootCmd.PersistentFlags().Lookup(credentialRefFlagName) |
| 90 | + if canonical == nil { |
| 91 | + t.Fatalf("root persistent flag --%s not registered", credentialRefFlagName) |
| 92 | + } |
| 93 | + |
| 94 | + var sc *cobra.Command |
| 95 | + for _, c := range rootCmd.Commands() { |
| 96 | + if c.Name() == "set-credential" { |
| 97 | + sc = c |
| 98 | + break |
| 99 | + } |
| 100 | + } |
| 101 | + if sc == nil { |
| 102 | + t.Fatal("set-credential command not registered on rootCmd") |
| 103 | + } |
| 104 | + if got := sc.Flag(credentialRefFlagName); got == nil { |
| 105 | + t.Fatalf("set-credential has no --%s", credentialRefFlagName) |
| 106 | + } else if got == canonical { |
| 107 | + t.Errorf("set-credential --%s resolved to the persistent flag; expected its own local shadow", credentialRefFlagName) |
| 108 | + } |
| 109 | + |
| 110 | + // A read command (no local --ref) must inherit the canonical persistent flag. |
| 111 | + me := newProbeCmd("probe-ref-inherit") |
| 112 | + rootCmd.AddCommand(me) |
| 113 | + defer removeChild(t, me) |
| 114 | + if got := me.Flag(credentialRefFlagName); got != canonical { |
| 115 | + t.Errorf("read command --%s = %p, want canonical %p (unexpected shadow)", credentialRefFlagName, got, canonical) |
| 116 | + } |
| 117 | +} |
0 commit comments