1package command
2
3import (
4	"reflect"
5	"strings"
6	"testing"
7
8	"github.com/mitchellh/cli"
9)
10
11func testTokenCreateCommand(tb testing.TB) (*cli.MockUi, *TokenCreateCommand) {
12	tb.Helper()
13
14	ui := cli.NewMockUi()
15	return ui, &TokenCreateCommand{
16		BaseCommand: &BaseCommand{
17			UI: ui,
18		},
19	}
20}
21
22func TestTokenCreateCommand_Run(t *testing.T) {
23	t.Parallel()
24
25	cases := []struct {
26		name string
27		args []string
28		out  string
29		code int
30	}{
31		{
32			"too_many_args",
33			[]string{"abcd1234"},
34			"Too many arguments",
35			1,
36		},
37		{
38			"default",
39			nil,
40			"token",
41			0,
42		},
43		{
44			"metadata",
45			[]string{"-metadata", "foo=bar", "-metadata", "zip=zap"},
46			"token",
47			0,
48		},
49		{
50			"policies",
51			[]string{"-policy", "foo", "-policy", "bar"},
52			"token",
53			0,
54		},
55		{
56			"field",
57			[]string{
58				"-field", "token_renewable",
59			},
60			"false",
61			0,
62		},
63		{
64			"field_not_found",
65			[]string{
66				"-field", "not-a-real-field",
67			},
68			"not present in secret",
69			1,
70		},
71	}
72
73	t.Run("validations", func(t *testing.T) {
74		t.Parallel()
75
76		for _, tc := range cases {
77			tc := tc
78
79			t.Run(tc.name, func(t *testing.T) {
80				t.Parallel()
81
82				client, closer := testVaultServer(t)
83				defer closer()
84
85				ui, cmd := testTokenCreateCommand(t)
86				cmd.client = client
87
88				code := cmd.Run(tc.args)
89				if code != tc.code {
90					t.Errorf("expected %d to be %d", code, tc.code)
91				}
92
93				combined := ui.OutputWriter.String() + ui.ErrorWriter.String()
94				if !strings.Contains(combined, tc.out) {
95					t.Errorf("expected %q to contain %q", combined, tc.out)
96				}
97			})
98		}
99	})
100
101	t.Run("default", func(t *testing.T) {
102		t.Parallel()
103
104		client, closer := testVaultServer(t)
105		defer closer()
106
107		ui, cmd := testTokenCreateCommand(t)
108		cmd.client = client
109
110		code := cmd.Run([]string{
111			"-field", "token",
112		})
113		if exp := 0; code != exp {
114			t.Errorf("expected %d to be %d", code, exp)
115		}
116
117		token := strings.TrimSpace(ui.OutputWriter.String())
118		secret, err := client.Auth().Token().Lookup(token)
119		if secret == nil || err != nil {
120			t.Fatal(err)
121		}
122	})
123
124	t.Run("metadata", func(t *testing.T) {
125		t.Parallel()
126
127		client, closer := testVaultServer(t)
128		defer closer()
129
130		ui, cmd := testTokenCreateCommand(t)
131		cmd.client = client
132
133		code := cmd.Run([]string{
134			"-metadata", "foo=bar",
135			"-metadata", "zip=zap",
136			"-field", "token",
137		})
138		if exp := 0; code != exp {
139			t.Errorf("expected %d to be %d", code, exp)
140		}
141
142		token := strings.TrimSpace(ui.OutputWriter.String())
143		secret, err := client.Auth().Token().Lookup(token)
144		if secret == nil || err != nil {
145			t.Fatal(err)
146		}
147
148		meta, ok := secret.Data["meta"].(map[string]interface{})
149		if !ok {
150			t.Fatalf("missing meta: %#v", secret)
151		}
152		if _, ok := meta["foo"]; !ok {
153			t.Errorf("missing meta.foo: %#v", meta)
154		}
155		if _, ok := meta["zip"]; !ok {
156			t.Errorf("missing meta.bar: %#v", meta)
157		}
158	})
159
160	t.Run("policies", func(t *testing.T) {
161		t.Parallel()
162
163		client, closer := testVaultServer(t)
164		defer closer()
165
166		ui, cmd := testTokenCreateCommand(t)
167		cmd.client = client
168
169		code := cmd.Run([]string{
170			"-policy", "foo",
171			"-policy", "bar",
172			"-field", "token",
173		})
174		if exp := 0; code != exp {
175			t.Errorf("expected %d to be %d", code, exp)
176		}
177
178		token := strings.TrimSpace(ui.OutputWriter.String())
179		secret, err := client.Auth().Token().Lookup(token)
180		if secret == nil || err != nil {
181			t.Fatal(err)
182		}
183
184		raw, ok := secret.Data["policies"].([]interface{})
185		if !ok {
186			t.Fatalf("missing policies: %#v", secret)
187		}
188
189		policies := make([]string, len(raw))
190		for i := range raw {
191			policies[i] = raw[i].(string)
192		}
193
194		expected := []string{"bar", "default", "foo"}
195		if !reflect.DeepEqual(policies, expected) {
196			t.Errorf("expected %q to be %q", policies, expected)
197		}
198	})
199
200	t.Run("communication_failure", func(t *testing.T) {
201		t.Parallel()
202
203		client, closer := testVaultServerBad(t)
204		defer closer()
205
206		ui, cmd := testTokenCreateCommand(t)
207		cmd.client = client
208
209		code := cmd.Run([]string{})
210		if exp := 2; code != exp {
211			t.Errorf("expected %d to be %d", code, exp)
212		}
213
214		expected := "Error creating token: "
215		combined := ui.OutputWriter.String() + ui.ErrorWriter.String()
216		if !strings.Contains(combined, expected) {
217			t.Errorf("expected %q to contain %q", combined, expected)
218		}
219	})
220
221	t.Run("no_tabs", func(t *testing.T) {
222		t.Parallel()
223
224		_, cmd := testTokenCreateCommand(t)
225		assertNoTabs(t, cmd)
226	})
227}
228