// SPDX-License-Identifier: Apache-2.0 // Copyright Authors of K9s package cmd_test import ( "errors" "testing" "github.com/derailed/k9s/internal/view/cmd" "github.com/stretchr/testify/assert" ) func TestRbacCmd(t *testing.T) { uu := map[string]struct { cmd string ok bool args []string }{ "empty": {}, "user": { cmd: "can u:fernand", ok: true, args: []string{"u", "fernand"}, }, "user_spacing": { cmd: "can u: fernand ", ok: true, args: []string{"u", "fernand"}, }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) assert.Equal(t, u.ok, p.IsRBACCmd()) c, s, ok := p.RBACArgs() assert.Equal(t, u.ok, ok) if u.ok { assert.Equal(t, u.args[0], c) assert.Equal(t, u.args[1], s) } }) } } func TestNsCmd(t *testing.T) { uu := map[string]struct { cmd string ok bool ns string }{ "empty": {}, "happy": { cmd: "pod fred", ok: true, ns: "fred", }, "ns-arg-spaced": { cmd: "pod fred ", ok: true, ns: "fred", }, "caps-no-ns": { cmd: "Deploy", }, "caps-with-ns": { cmd: "DEPLOY Fred", ok: true, ns: "fred", }, "no-ns": { cmd: "pod", }, "full-ns": { cmd: "pod app=blee fred @zorg", ok: true, ns: "fred", }, "full-repeat-ns": { cmd: "pod app=blee blee @zorg", ok: true, ns: "blee", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) ns, ok := p.NSArg() assert.Equal(t, u.ok, ok) if u.ok { assert.Equal(t, u.ns, ns) } }) } } func TestSwitchNS(t *testing.T) { uu := map[string]struct { cmd string ns string e string }{ "empty": {}, "blank": { cmd: "pod fred", e: "pod", }, "no-op": { cmd: "pod fred", ns: "fred", e: "pod fred", }, "no-ns": { cmd: "pod", ns: "blee", e: "pod blee", }, "full-ns": { cmd: "pod app=blee fred @zorg", ns: "blee", e: "pod app=blee blee @zorg", }, "full--repeat-ns": { cmd: "pod app=zorg zorg @zorg", ns: "blee", e: "pod app=zorg blee @zorg", }, "full-no-ns": { cmd: "pod app=blee @zorg", ns: "blee", e: "pod app=blee @zorg blee", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) p.SwitchNS(u.ns) assert.Equal(t, u.e, p.GetLine()) }) } } func TestClearNS(t *testing.T) { uu := map[string]struct { cmd string e string }{ "empty": {}, "has-ns": { cmd: "pod fred", e: "pod", }, "no-ns": { cmd: "pod", e: "pod", }, "full-repeat-ns": { cmd: "pod app=blee @zorg zorg", e: "pod app=blee @zorg", }, "full-no-ns": { cmd: "pod app=blee @zorg", e: "pod app=blee @zorg", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) p.ClearNS() assert.Equal(t, u.e, p.GetLine()) }) } } func TestFilterCmd(t *testing.T) { uu := map[string]struct { cmd string ok bool filter string }{ "empty": {}, "normal": { cmd: "pod /fred", ok: true, filter: "fred", }, "caps": { cmd: "POD /FRED", ok: true, filter: "fred", }, "filter+ns": { cmd: "pod /fred ns1", ok: true, filter: "fred", }, "ns+filter": { cmd: "pod ns1 /fred", ok: true, filter: "fred", }, "ns+filter+labels": { cmd: "pod ns1 /fred app=blee,fred=zorg", ok: true, filter: "fred", }, "filtered": { cmd: "pod /cilium kube-system", ok: true, filter: "cilium", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) f, ok := p.FilterArg() assert.Equal(t, u.ok, ok) if u.ok { assert.Equal(t, u.filter, f) } }) } } func TestLabelCmd(t *testing.T) { uu := map[string]struct { cmd string err error labels string }{ "empty": {}, "plain": { cmd: "pod fred=blee", labels: "fred=blee", }, "multi": { cmd: "pod fred=blee,zorg=duh", labels: "fred=blee,zorg=duh", }, "complex-lbls": { cmd: "pod 'fred in (blee,zorg),blee notin (zorg)'", labels: "blee notin (zorg),fred in (blee,zorg)", }, "no-lbls": { cmd: "pod ns-1", }, "multi-ns": { cmd: "pod fred=blee,zorg=duh ns1", labels: "fred=blee,zorg=duh", }, "l-arg-spaced": { cmd: "pod fred=blee ", labels: "fred=blee", }, "l-arg-caps": { cmd: "POD FRED=BLEE ", labels: "fred=blee", }, "toast-labels": { cmd: "pod =blee", err: errors.New("found '=', expected: !, identifier, or 'end of string'"), }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) ll, err := p.LabelsSelector() assert.Equal(t, u.err, err) if err == nil { assert.Equal(t, u.labels, ll.String()) } }) } } func TestXRayCmd(t *testing.T) { uu := map[string]struct { cmd string ok bool res, ns string }{ "empty": {}, "happy": { cmd: "xray po", ok: true, res: "po", }, "happy+ns": { cmd: "xray po ns1", ok: true, res: "po", ns: "ns1", }, "toast": { cmd: "xrayzor po", }, "toast-1": { cmd: "xray", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) res, ns, ok := p.XrayArgs() assert.Equal(t, u.ok, ok) if u.ok { assert.Equal(t, u.res, res) assert.Equal(t, u.ns, ns) } }) } } func TestDirCmd(t *testing.T) { uu := map[string]struct { cmd string ok bool dir string }{ "empty": {}, "happy": { cmd: "dir dir1", ok: true, dir: "dir1", }, "extra-ns": { cmd: "dir dir1 ns1", ok: true, dir: "dir1", }, "toast": { cmd: "dirdel dir1", }, "toast-nodir": { cmd: "dir", }, "caps": { cmd: "dir DirName", ok: true, dir: "DirName", }, "abs": { cmd: "dir /tmp", ok: true, dir: "/tmp", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) dir, ok := p.DirArg() assert.Equal(t, u.ok, ok) assert.Equal(t, u.dir, dir) }) } } func TestRBACCmd(t *testing.T) { uu := map[string]struct { cmd string ok bool cat, sub string }{ "empty": {}, "toast": { cmd: "canopy u:bozo", }, "toast-1": { cmd: "can u:", }, "toast-2": { cmd: "can bozo", }, "user": { cmd: "can u:bozo", ok: true, cat: "u", sub: "bozo", }, "group": { cmd: "can g:bozo", ok: true, cat: "g", sub: "bozo", }, "sa": { cmd: "can s:bozo", ok: true, cat: "s", sub: "bozo", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) cat, sub, ok := p.RBACArgs() assert.Equal(t, u.ok, ok) if u.ok { assert.Equal(t, u.cat, cat) assert.Equal(t, u.sub, sub) } }) } } func TestContextCmd(t *testing.T) { uu := map[string]struct { cmd string ok bool ctx string }{ "empty": {}, "happy-full": { cmd: "context ctx1", ok: true, ctx: "ctx1", }, "happy-alias": { cmd: "ctx ctx1", ok: true, ctx: "ctx1", }, "toast": { cmd: "ctxto ctx1", }, "caps": { cmd: "ctx Dev", ok: true, ctx: "Dev", }, "contains-key": { cmd: "ctx kind-fred", ok: true, ctx: "kind-fred", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) assert.Equal(t, u.ok, p.IsContextCmd()) if u.ok { ctx, ok := p.ContextArg() assert.Equal(t, u.ok, ok) assert.Equal(t, u.ctx, ctx) } }) } } func TestHelpCmd(t *testing.T) { uu := map[string]struct { cmd string ok bool }{ "empty": {}, "plain": { cmd: "help", ok: true, }, "toast": { cmd: "helpme", }, "toast1": { cmd: "hozer", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) assert.Equal(t, u.ok, p.IsHelpCmd()) }) } } func TestBailCmd(t *testing.T) { uu := map[string]struct { cmd string ok bool }{ "empty": {}, "plain": { cmd: "quit", ok: true, }, "q": { cmd: "q", ok: true, }, "q!": { cmd: "q!", ok: true, }, "toast": { cmd: "zorg", }, "toast1": { cmd: "quitter", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) assert.Equal(t, u.ok, p.IsBailCmd()) }) } } func TestAliasCmd(t *testing.T) { uu := map[string]struct { cmd string ok bool }{ "empty": {}, "plain": { cmd: "alias", ok: true, }, "a": { cmd: "a", ok: true, }, "toast": { cmd: "abba", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) assert.Equal(t, u.ok, p.IsAliasCmd()) }) } } func TestCowCmd(t *testing.T) { uu := map[string]struct { cmd string ok bool }{ "empty": {}, "plain": { cmd: "cow", ok: true, }, "msg": { cmd: "cow bumblebeetuna", ok: true, }, "toast": { cmd: "cowdy", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) assert.Equal(t, u.ok, p.IsCowCmd()) }) } } func TestArgs(t *testing.T) { uu := map[string]struct { cmd string ok bool ctx string }{ "empty": {}, "with-plain-context": { cmd: "po @fred", ok: true, ctx: "fred", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) ctx, ok := p.ContextArg() assert.Equal(t, u.ok, ok) if u.ok { assert.Equal(t, u.ctx, ctx) } }) } } func Test_grokLabels(t *testing.T) { uu := map[string]struct { cmd string err error lbls string }{ "empty": {}, "no-labels": { cmd: "po @fred", }, "plain-label": { cmd: "po a=b,b=c @fred", lbls: "a=b,b=c", }, "label-quotes": { cmd: "po 'a=b,b=c' @fred", lbls: "a=b,b=c", }, "partial-quotes-label": { cmd: "po 'a=b @fred", lbls: "", }, "complex": { cmd: "po 'a in (b,c),b notin (c,z)' fred'", lbls: "a in (b,c),b notin (c,z)", }, } for k := range uu { u := uu[k] t.Run(k, func(t *testing.T) { p := cmd.NewInterpreter(u.cmd) sel, err := p.LabelsSelector() assert.Equal(t, u.err, err) if err == nil { assert.Equal(t, u.lbls, sel.String()) } }) } }