diff --git a/commands/cluster/agent/list/agent_list_test.go b/commands/cluster/agent/list/agent_list_test.go index 5763dfbdf1e5e7710ad60e39d2d86c91721538b5..cd41de1b9a2dec73556690c05846ea43586fd794 100644 --- a/commands/cluster/agent/list/agent_list_test.go +++ b/commands/cluster/agent/list/agent_list_test.go @@ -1,58 +1,45 @@ package list import ( - "fmt" - "net/http" "testing" "time" "github.com/MakeNowJust/heredoc/v2" - "gitlab.com/gitlab-org/cli/pkg/httpmock" - "gitlab.com/gitlab-org/cli/test" + "go.uber.org/mock/gomock" "gitlab.com/gitlab-org/cli/commands/cmdtest" "github.com/stretchr/testify/assert" + gitlab "gitlab.com/gitlab-org/api/client-go" ) -func runCommand(rt http.RoundTripper, isTTY bool, cli string, doHyperlinks string) (*test.CmdOut, error) { - ios, _, stdout, stderr := cmdtest.InitIOStreams(isTTY, doHyperlinks) - f := cmdtest.InitFactory(ios, rt) - - // Note: This sets the RoundTripper, which is necessary for stubs to work. - _, _ = f.HttpClient() - - cmd := NewCmdAgentList(f) - - return cmdtest.ExecuteCommand(cmd, cli, stdout, stderr) -} - func TestAgentList(t *testing.T) { - fakeHTTP := httpmock.New() - defer fakeHTTP.Verify(t) - - deterministicCreatedAt := time.Now().Add(-24 * time.Hour).Format(time.RFC3339) - fakeHTTP.RegisterResponder(http.MethodGet, "/projects/OWNER/REPO/cluster_agents", - httpmock.NewStringResponse(http.StatusOK, fmt.Sprintf(` - [ - { - "id": 1, - "name": "local", - "created_at": "%[1]s" - }, - { - "id": 2, - "name": "prd", - "created_at": "%[1]s" - } - ] - `, deterministicCreatedAt))) - - output, err := runCommand(fakeHTTP, true, "", "") + // GIVEN + tc, exec := cmdtest.Setup(t, NewCmdAgentList, true, "") + + tc.MockClusterAgents.EXPECT(). + ListAgents(gomock.Any(), &gitlab.ListAgentsOptions{Page: 1, PerPage: 30}). + Return([]*gitlab.Agent{ + { + ID: 1, + Name: "local", + CreatedAt: gitlab.Ptr(time.Now().Add(-24 * time.Hour)), + }, + { + ID: 2, + Name: "prd", + CreatedAt: gitlab.Ptr(time.Now().Add(-24 * time.Hour)), + }, + }, &gitlab.Response{}, nil). + Times(1) + + // WHEN + output, err := exec("") if err != nil { t.Errorf("error running command `cluster agent list`: %v", err) } + // THEN assert.Equal(t, heredoc.Doc(` Showing 2 agents on OWNER/REPO. (Page 1) @@ -65,37 +52,29 @@ func TestAgentList(t *testing.T) { } func TestAgentList_Pagination(t *testing.T) { - fakeHTTP := httpmock.New() - defer fakeHTTP.Verify(t) - - deterministicCreatedAt := time.Now().Add(-24 * time.Hour).Format(time.RFC3339) - fakeHTTP.RegisterResponder(http.MethodGet, "/projects/OWNER/REPO/cluster_agents", - httpmock.NewStringResponse(http.StatusOK, fmt.Sprintf(` - [ - { - "id": 1, - "name": "local", - "created_at": "%[1]s" - }, - { - "id": 2, - "name": "prd", - "created_at": "%[1]s" - } - ] - `, deterministicCreatedAt))) - - cli := "--page 42 --per-page 10" - output, err := runCommand(fakeHTTP, true, cli, "") + // GIVEN + tc, exec := cmdtest.Setup(t, NewCmdAgentList, true, "") + + tc.MockClusterAgents.EXPECT(). + ListAgents(gomock.Any(), &gitlab.ListAgentsOptions{Page: 2, PerPage: 1}). + Return([]*gitlab.Agent{ + { + ID: 2, + Name: "prd", + CreatedAt: gitlab.Ptr(time.Now().Add(-24 * time.Hour)), + }, + }, &gitlab.Response{NextPage: 0}, nil) + + // WHEN + output, err := exec("--page 2 --per-page 1") if err != nil { t.Errorf("error running command `cluster agent list`: %v", err) } assert.Equal(t, heredoc.Doc(` - Showing 2 agents on OWNER/REPO. (Page 42) + Showing 1 agent on OWNER/REPO. (Page 2) ID Name Created At - 1 local about 1 day ago 2 prd about 1 day ago `), output.String()) diff --git a/commands/cmdtest/helper.go b/commands/cmdtest/helper.go index cc7cb09d099d5e9ff6ae552f9ce7a2e216b11031..a58014570dbde8addde9a176f98392facdcfb0fd 100644 --- a/commands/cmdtest/helper.go +++ b/commands/cmdtest/helper.go @@ -22,6 +22,7 @@ import ( "github.com/otiai10/copy" "github.com/spf13/cobra" gitlab "gitlab.com/gitlab-org/api/client-go" + gitlab_testing "gitlab.com/gitlab-org/api/client-go/testing" "gitlab.com/gitlab-org/cli/commands/cmdutils" "gitlab.com/gitlab-org/cli/internal/config" "gitlab.com/gitlab-org/cli/internal/glrepo" @@ -168,6 +169,39 @@ func InitFactory(ios *iostreams.IOStreams, rt http.RoundTripper) *cmdutils.Facto } } +func InitMockFactory(ios *iostreams.IOStreams, client *gitlab.Client) *cmdutils.Factory { + return &cmdutils.Factory{ + IO: ios, + HttpClient: func() (*gitlab.Client, error) { + return client, nil + }, + Config: func() (config.Config, error) { + return config.NewBlankConfig(), nil + }, + BaseRepo: func() (glrepo.Interface, error) { + return glrepo.New("OWNER", "REPO"), nil + }, + Branch: func() (string, error) { + return "main", nil + }, + } +} + +type CmdExecFunc func(cli string) (*test.CmdOut, error) +type CmdFunc func(f *cmdutils.Factory) *cobra.Command + +func Setup(t *testing.T, cmdFunc CmdFunc, isTTY bool, doHyperlinks string) (*gitlab_testing.TestClient, CmdExecFunc) { + t.Helper() + + ios, _, stdout, stderr := InitIOStreams(isTTY, doHyperlinks) + tc := gitlab_testing.NewTestClient(t) + f := InitMockFactory(ios, tc.Client) + + return tc, func(cli string) (*test.CmdOut, error) { + return ExecuteCommand(cmdFunc(f), cli, stdout, stderr) + } +} + func ExecuteCommand(cmd *cobra.Command, cli string, stdout *bytes.Buffer, stderr *bytes.Buffer) (*test.CmdOut, error) { argv, err := shlex.Split(cli) if err != nil { diff --git a/go.mod b/go.mod index ea347876b20701aea347c8a5a977364d2437e825..2049813c81fd5a5c4c909315f280765119f61035 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module gitlab.com/gitlab-org/cli go 1.24.0 +replace gitlab.com/gitlab-org/api/client-go => /Users/timo/work/gitlab/api/client-go + require ( github.com/AlecAivazis/survey/v2 v2.3.7 github.com/MakeNowJust/heredoc/v2 v2.0.1 @@ -103,7 +105,7 @@ require ( go.uber.org/multierr v1.9.0 // indirect golang.org/x/net v0.33.0 // indirect golang.org/x/sys v0.31.0 // indirect - golang.org/x/time v0.9.0 // indirect + golang.org/x/time v0.10.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect diff --git a/go.sum b/go.sum index 465d4c628fcfe8283a7ff9346896c991adbb399c..56b6d79c0135032c40ea3c6da2e44cca7ca1ee80 100644 --- a/go.sum +++ b/go.sum @@ -237,8 +237,6 @@ github.com/yuin/goldmark-emoji v1.0.3 h1:aLRkLHOuBR2czCY4R8olwMjID+tENfhyFDMCRhb github.com/yuin/goldmark-emoji v1.0.3/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U= github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s= github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI= -gitlab.com/gitlab-org/api/client-go v0.124.0 h1:6i/uAl3QZur0F4S+42d9/k8y1Lf+htPqQ9YgXZJ2oQI= -gitlab.com/gitlab-org/api/client-go v0.124.0/go.mod h1:Jh0qjLILEdbO6z/OY94RD+3NDQRUKiuFSFYozN6cpKM= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -304,8 +302,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= +golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=