1 package add
2
3 import (
4 "context"
5 "errors"
6 "fmt"
7 "testing"
8 "time"
9
10 "github.com/stretchr/testify/assert"
11 "github.com/stretchr/testify/require"
12
13 "edge-infra.dev/pkg/edge/api/fake"
14 "edge-infra.dev/pkg/edge/api/graph/model"
15 "edge-infra.dev/pkg/edge/edgeadmin/commands/operatorintervention/add/mocks"
16 "edge-infra.dev/pkg/edge/edgecli"
17 "edge-infra.dev/pkg/edge/edgecli/flagutil"
18 "edge-infra.dev/pkg/lib/cli/rags"
19 )
20
21
22 type helper interface {
23 Helper()
24 }
25
26 func EqualError(message string) assert.ErrorAssertionFunc {
27 return func(t assert.TestingT, err error, i ...interface{}) bool {
28 if help, ok := t.(helper); ok {
29 help.Helper()
30 }
31
32 return assert.EqualError(t, err, message, i...)
33 }
34 }
35
36
37
38
39
40 func testConfig(endpointURL string) *edgecli.Config {
41 future := time.Now().Add(time.Hour * 24)
42 return &edgecli.Config{
43 CurrentBannerContext: "fakeBanner",
44 BannerContexts: map[string]*edgecli.BannerContext{
45 "fakeBanner": {
46 TokenTime: future.Format(time.RFC3339),
47 Token: "fakeToken",
48 Endpoint: endpointURL,
49 },
50 },
51 }
52 }
53
54 func TestSubCommands(t *testing.T) {
55 t.Parallel()
56
57 tests := map[string]struct {
58 subcommand SubCommand
59 callback fake.APIRequestsCallback
60 flagFunc func(rags *rags.RagSet) error
61 errAssert assert.ErrorAssertionFunc
62 }{
63 "Command: One Value": {
64 subcommand: &Command{},
65 callback: mocks.CreateOperatorInterventionCommand,
66 flagFunc: func(rags *rags.RagSet) error {
67 return flagutil.SetFlag(rags, flagutil.OICommand, "val")
68 },
69 errAssert: assert.NoError,
70 },
71 "Command: Multiple Values": {
72 subcommand: &Command{},
73 callback: mocks.CreateOperatorInterventionCommand,
74 flagFunc: func(rags *rags.RagSet) error {
75 return errors.Join(
76 flagutil.SetFlag(rags, flagutil.OICommand, "val1"),
77 flagutil.SetFlag(rags, flagutil.OICommand, "val2"),
78 flagutil.SetFlag(rags, flagutil.OICommand, "val3"),
79 )
80 },
81 errAssert: assert.NoError,
82 },
83 "Command: Nil": {
84 subcommand: &Command{},
85 callback: mocks.CreateOperatorInterventionCommand,
86 flagFunc: func(_ *rags.RagSet) error {
87 return nil
88 },
89 errAssert: EqualError(fmt.Sprintf("Flag '%s' is required", flagutil.OICommand)),
90 },
91 "Privilege: One Value": {
92 subcommand: &Privilege{},
93 callback: mocks.CreateOperatorInterventionPrivilege,
94 flagFunc: func(rags *rags.RagSet) error {
95 return flagutil.SetFlag(rags, flagutil.OIPrivilege, "val")
96 },
97 errAssert: assert.NoError,
98 },
99 "Privilege: Multiple Values": {
100 subcommand: &Privilege{},
101 callback: mocks.CreateOperatorInterventionPrivilege,
102 flagFunc: func(rags *rags.RagSet) error {
103 return errors.Join(
104 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val1"),
105 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val2"),
106 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val3"),
107 )
108 },
109 errAssert: assert.NoError,
110 },
111 "Privilege: Nil": {
112 subcommand: &Privilege{},
113 callback: mocks.CreateOperatorInterventionPrivilege,
114 flagFunc: func(_ *rags.RagSet) error {
115 return nil
116 },
117 errAssert: EqualError(fmt.Sprintf("Flag '%s' is required", flagutil.OIPrivilege)),
118 },
119 "Rule: One Command": {
120 subcommand: &Rule{},
121 callback: mocks.UpdateOperatorInterventionRule,
122 flagFunc: func(rags *rags.RagSet) error {
123 return errors.Join(
124 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val"),
125 flagutil.SetFlag(rags, flagutil.OICommand, "val"),
126 )
127 },
128 errAssert: assert.NoError,
129 },
130 "Rule: Multiple Commands": {
131 subcommand: &Rule{},
132 callback: mocks.UpdateOperatorInterventionRule,
133 flagFunc: func(rags *rags.RagSet) error {
134 return errors.Join(
135 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val"),
136 flagutil.SetFlag(rags, flagutil.OICommand, "val1"),
137 flagutil.SetFlag(rags, flagutil.OICommand, "val2"),
138 flagutil.SetFlag(rags, flagutil.OICommand, "val3"),
139 )
140 },
141 errAssert: assert.NoError,
142 },
143 "Rule: No Privilege": {
144 subcommand: &Rule{},
145 callback: mocks.UpdateOperatorInterventionRule,
146 flagFunc: func(rags *rags.RagSet) error {
147 return flagutil.SetFlag(rags, flagutil.OICommand, "val")
148 },
149 errAssert: EqualError(fmt.Sprintf("Flag '%s' is required", flagutil.OIPrivilege)),
150 },
151 "Rule: No Command": {
152 subcommand: &Rule{},
153 callback: mocks.UpdateOperatorInterventionRule,
154 flagFunc: func(rags *rags.RagSet) error {
155 return flagutil.SetFlag(rags, flagutil.OIPrivilege, "val")
156 },
157 errAssert: EqualError(fmt.Sprintf("Flag '%s' is required", flagutil.OICommand)),
158 },
159 "RoleMapping: One Privilege": {
160 subcommand: &RoleMapping{},
161 callback: mocks.UpdateOperatorInterventionRoleMapping,
162 flagFunc: func(rags *rags.RagSet) error {
163 return errors.Join(
164 flagutil.SetFlag(rags, flagutil.OIRole, "val"),
165 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val"),
166 )
167 },
168 errAssert: assert.NoError,
169 },
170 "RoleMapping: Multiple Privileges": {
171 subcommand: &RoleMapping{},
172 callback: mocks.UpdateOperatorInterventionRoleMapping,
173 flagFunc: func(rags *rags.RagSet) error {
174 return errors.Join(
175 flagutil.SetFlag(rags, flagutil.OIRole, "val"),
176 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val1"),
177 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val2"),
178 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val3"),
179 )
180 },
181 errAssert: assert.NoError,
182 },
183 "RoleMapping: No Role": {
184 subcommand: &RoleMapping{},
185 callback: mocks.UpdateOperatorInterventionRoleMapping,
186 flagFunc: func(rags *rags.RagSet) error {
187 return flagutil.SetFlag(rags, flagutil.OIPrivilege, "val")
188 },
189 errAssert: EqualError(fmt.Sprintf("Flag '%s' is required", flagutil.OIRole)),
190 },
191 "RoleMapping: No Privilege": {
192 subcommand: &RoleMapping{},
193 callback: mocks.UpdateOperatorInterventionRoleMapping,
194 flagFunc: func(rags *rags.RagSet) error {
195 return flagutil.SetFlag(rags, flagutil.OIRole, "val")
196 },
197 errAssert: EqualError(fmt.Sprintf("Flag '%s' is required", flagutil.OIPrivilege)),
198 },
199 }
200
201 for name, tc := range tests {
202 tc := tc
203 t.Run(name, func(t *testing.T) {
204 t.Parallel()
205
206
207 mockServer := fake.GetMockAPIServer(tc.callback)
208 serverURL := mockServer.URL + "/api/v2"
209 defer mockServer.Close()
210
211 cmd := newSubcommand(tc.subcommand, testConfig(serverURL))
212
213 cmd.Command()
214
215
216 require.NoError(t, tc.flagFunc(cmd.Rags))
217
218
219 err := cmd.Command().Exec(context.Background(), nil)
220 tc.errAssert(t, err)
221 })
222 }
223 }
224
225
226 func TestVariables(t *testing.T) {
227 t.Parallel()
228
229 tests := map[string]struct {
230 subcommand SubCommand
231 flagFunc func(rags *rags.RagSet) error
232 expectedVariables map[string]interface{}
233 }{
234 "Command": {
235 subcommand: &Command{},
236 flagFunc: func(rags *rags.RagSet) error {
237 return errors.Join(
238 flagutil.SetFlag(rags, flagutil.OICommand, "val1"),
239 flagutil.SetFlag(rags, flagutil.OICommand, "val2"),
240 flagutil.SetFlag(rags, flagutil.OICommand, "val3"),
241 )
242 },
243 expectedVariables: map[string]interface{}{
244 "commands": []model.OperatorInterventionCommandInput{
245 {Name: "val1"},
246 {Name: "val2"},
247 {Name: "val3"},
248 },
249 },
250 },
251 "Privilege": {
252 subcommand: &Privilege{},
253 flagFunc: func(rags *rags.RagSet) error {
254 return errors.Join(
255 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val1"),
256 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val2"),
257 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val3"),
258 )
259 },
260 expectedVariables: map[string]interface{}{
261 "privileges": []model.OperatorInterventionPrivilegeInput{
262 {Name: "val1"},
263 {Name: "val2"},
264 {Name: "val3"},
265 },
266 },
267 },
268 "Rule": {
269 subcommand: &Rule{},
270 flagFunc: func(rags *rags.RagSet) error {
271 return errors.Join(
272 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val"),
273 flagutil.SetFlag(rags, flagutil.OICommand, "val1"),
274 flagutil.SetFlag(rags, flagutil.OICommand, "val2"),
275 flagutil.SetFlag(rags, flagutil.OICommand, "val3"),
276 )
277 },
278 expectedVariables: map[string]interface{}{
279 "rules": []model.UpdateOperatorInterventionRuleInput{
280 {
281 Privilege: &model.OperatorInterventionPrivilegeInput{Name: "val"},
282 Commands: []*model.OperatorInterventionCommandInput{
283 {Name: "val1"},
284 {Name: "val2"},
285 {Name: "val3"},
286 },
287 },
288 },
289 },
290 },
291 "RoleMapping": {
292 subcommand: &RoleMapping{},
293 flagFunc: func(rags *rags.RagSet) error {
294 return errors.Join(
295 flagutil.SetFlag(rags, flagutil.OIRole, "val"),
296 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val1"),
297 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val2"),
298 flagutil.SetFlag(rags, flagutil.OIPrivilege, "val3"),
299 )
300 },
301 expectedVariables: map[string]interface{}{
302 "roleMappings": []model.UpdateOperatorInterventionRoleMappingInput{
303 {
304 Role: "val",
305 Privileges: []*model.OperatorInterventionPrivilegeInput{
306 {Name: "val1"},
307 {Name: "val2"},
308 {Name: "val3"},
309 },
310 },
311 },
312 },
313 },
314 }
315
316 for name, tc := range tests {
317 tc := tc
318 t.Run(name, func(t *testing.T) {
319 t.Parallel()
320
321 cmd := newSubcommand(tc.subcommand, testConfig(""))
322
323 cmd.Command()
324
325 require.NoError(t, tc.flagFunc(cmd.Rags))
326
327 assert.Equal(t, tc.expectedVariables, tc.subcommand.Variables())
328 })
329 }
330 }
331
View as plain text