package command import ( "fmt" "io" "io/ioutil" "os" "strings" "testing" "time" ) func TestParseArgsData(t *testing.T) { t.Parallel() t.Run("stdin_full", func(t *testing.T) { t.Parallel() stdinR, stdinW := io.Pipe() go func() { stdinW.Write([]byte(`{"foo":"bar"}`)) stdinW.Close() }() m, err := parseArgsData(stdinR, []string{"-"}) if err != nil { t.Fatal(err) } if v, ok := m["foo"]; !ok || v != "bar" { t.Errorf("expected %q to be %q", v, "bar") } }) t.Run("stdin_value", func(t *testing.T) { t.Parallel() stdinR, stdinW := io.Pipe() go func() { stdinW.Write([]byte(`bar`)) stdinW.Close() }() m, err := parseArgsData(stdinR, []string{"foo=-"}) if err != nil { t.Fatal(err) } if v, ok := m["foo"]; !ok || v != "bar" { t.Errorf("expected %q to be %q", v, "bar") } }) t.Run("file_full", func(t *testing.T) { t.Parallel() f, err := ioutil.TempFile("", "vault") if err != nil { t.Fatal(err) } f.Write([]byte(`{"foo":"bar"}`)) f.Close() defer os.Remove(f.Name()) m, err := parseArgsData(os.Stdin, []string{"@" + f.Name()}) if err != nil { t.Fatal(err) } if v, ok := m["foo"]; !ok || v != "bar" { t.Errorf("expected %q to be %q", v, "bar") } }) t.Run("file_value", func(t *testing.T) { t.Parallel() f, err := ioutil.TempFile("", "vault") if err != nil { t.Fatal(err) } f.Write([]byte(`bar`)) f.Close() defer os.Remove(f.Name()) m, err := parseArgsData(os.Stdin, []string{"foo=@" + f.Name()}) if err != nil { t.Fatal(err) } if v, ok := m["foo"]; !ok || v != "bar" { t.Errorf("expected %q to be %q", v, "bar") } }) t.Run("file_value_escaped", func(t *testing.T) { t.Parallel() m, err := parseArgsData(os.Stdin, []string{`foo=\@`}) if err != nil { t.Fatal(err) } if v, ok := m["foo"]; !ok || v != "@" { t.Errorf("expected %q to be %q", v, "@") } }) } func TestTruncateToSeconds(t *testing.T) { t.Parallel() cases := []struct { d time.Duration exp int }{ { 10 * time.Nanosecond, 0, }, { 10 * time.Microsecond, 0, }, { 10 * time.Millisecond, 0, }, { 1 * time.Second, 1, }, { 10 * time.Second, 10, }, { 100 * time.Second, 100, }, { 3 * time.Minute, 180, }, { 3 * time.Hour, 10800, }, } for _, tc := range cases { tc := tc t.Run(tc.d.String(), func(t *testing.T) { t.Parallel() act := truncateToSeconds(tc.d) if act != tc.exp { t.Errorf("expected %d to be %d", act, tc.exp) } }) } } func TestParseFlagFile(t *testing.T) { t.Parallel() content := "some raw content" tmpFile, err := ioutil.TempFile(os.TempDir(), "TestParseFlagFile") if err != nil { t.Fatalf("failed to create temporary file: %v", err) } defer os.Remove(tmpFile.Name()) if _, err := tmpFile.WriteString(content); err != nil { t.Fatalf("failed to write to temporary file: %v", err) } cases := []struct { value string exp string }{ { "", "", }, { content, content, }, { fmt.Sprintf("@%s", tmpFile.Name()), content, }, } for _, tc := range cases { tc := tc t.Run(tc.value, func(t *testing.T) { content, err := parseFlagFile(tc.value) if err != nil { t.Fatalf("unexpected error parsing flag value: %v", err) } if content != tc.exp { t.Fatalf("expected %s to be %s", content, tc.exp) } }) } } func TestArgWarnings(t *testing.T) { t.Parallel() cases := []struct { args []string expected string }{ { []string{"a", "b", "c"}, "", }, { []string{"a", "-b"}, "-b", }, { []string{"a", "--b"}, "--b", }, { []string{"a-b", "-c"}, "-c", }, { []string{"a", "-b-c"}, "-b-c", }, { []string{"-a", "b"}, "-a", }, { []string{globalFlagDetailed}, "", }, { []string{"-" + globalFlagOutputCurlString + "=true"}, "", }, { []string{"--" + globalFlagFormat + "=false"}, "", }, { []string{"-x" + globalFlagDetailed}, "-x" + globalFlagDetailed, }, { []string{"--x=" + globalFlagDetailed}, "--x=" + globalFlagDetailed, }, { []string{"policy", "write", "my-policy", "-"}, "", }, } for _, tc := range cases { tc := tc t.Run(tc.expected, func(t *testing.T) { warnings := generateFlagWarnings(tc.args) if !strings.Contains(warnings, tc.expected) { t.Fatalf("expected %s to contain %s", warnings, tc.expected) } }) } }