From 9781642e506b64bc7256c074eaf1c06264588b7d Mon Sep 17 00:00:00 2001 From: PatrickMenoti <82882574+PatrickMenoti@users.noreply.github.com> Date: Mon, 15 Jul 2024 14:11:22 -0300 Subject: [PATCH] tests: improve unit tests for describe commands --- .../describe/cache_setting/cache_setting.go | 43 +++- .../cache_setting/cache_setting_test.go | 98 ++++++--- pkg/cmd/describe/domains/domains_test.go | 102 +++++----- .../edge_applications_test.go | 100 +++++----- .../edge_function/edge_function_test.go | 92 ++++----- pkg/cmd/describe/edge_storage/object_test.go | 65 ++++++ pkg/cmd/describe/origin/origin.go | 55 ++++-- pkg/cmd/describe/origin/origin_test.go | 115 ++++++----- .../personal_token/personal_token_test.go | 5 +- pkg/cmd/describe/rules_engine/rules_engine.go | 62 ++++-- .../rules_engine/rules_engine_test.go | 187 ++++++++++++++---- pkg/cmd/describe/variables/variables_test.go | 98 +++++---- 12 files changed, 661 insertions(+), 361 deletions(-) create mode 100644 pkg/cmd/describe/edge_storage/object_test.go diff --git a/pkg/cmd/describe/cache_setting/cache_setting.go b/pkg/cmd/describe/cache_setting/cache_setting.go index 662ce6523..d8c26df36 100644 --- a/pkg/cmd/describe/cache_setting/cache_setting.go +++ b/pkg/cmd/describe/cache_setting/cache_setting.go @@ -14,6 +14,7 @@ import ( api "github.com/aziontech/azion-cli/pkg/api/cache_setting" "github.com/aziontech/azion-cli/pkg/cmdutil" "github.com/aziontech/azion-cli/pkg/contracts" + "github.com/aziontech/azion-cli/pkg/iostreams" "github.com/aziontech/azion-cli/pkg/logger" "github.com/aziontech/azion-cli/pkg/output" "github.com/aziontech/azion-cli/utils" @@ -25,9 +26,28 @@ var ( cacheSettingsID int64 ) -func NewCmd(f *cmdutil.Factory) *cobra.Command { +type DescribeCmd struct { + Io *iostreams.IOStreams + AskInput func(string) (string, error) + Get func(context.Context, int64, int64) (api.GetResponse, error) +} + +func NewDescribeCmd(f *cmdutil.Factory) *DescribeCmd { + return &DescribeCmd{ + Io: f.IOStreams, + AskInput: func(prompt string) (string, error) { + return utils.AskInput(prompt) + }, + Get: func(ctx context.Context, appID, cacheID int64) (api.GetResponse, error) { + client := api.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) + return client.Get(ctx, appID, cacheID) + }, + } +} + +func NewCobraCmd(describe *DescribeCmd, f *cmdutil.Factory) *cobra.Command { opts := &contracts.DescribeOptions{} - cmd := &cobra.Command{ + cobraCmd := &cobra.Command{ Use: msg.Usage, Short: msg.DescribeShortDescription, Long: msg.DescribeLongDescription, @@ -41,7 +61,7 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { RunE: func(cmd *cobra.Command, args []string) error { if !cmd.Flags().Changed("application-id") { - answer, err := utils.AskInput(msg.DescibeAskInputApplicationID) + answer, err := describe.AskInput(msg.DescibeAskInputApplicationID) if err != nil { return err } @@ -56,7 +76,7 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { } if !cmd.Flags().Changed("cache-setting-id") { - answer, err := utils.AskInput(msg.DescribeAskInputCacheID) + answer, err := describe.AskInput(msg.DescribeAskInputCacheID) if err != nil { return err } @@ -70,9 +90,8 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { cacheSettingsID = num } - client := api.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) ctx := context.Background() - resp, err := client.Get(ctx, applicationID, cacheSettingsID) + resp, err := describe.Get(ctx, applicationID, cacheSettingsID) if err != nil { return fmt.Errorf(msg.ErrorGetCache.Error(), err) } @@ -107,8 +126,12 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { }, } - cmd.Flags().Int64Var(&applicationID, "application-id", 0, msg.DescribeFlagApplicationID) - cmd.Flags().Int64Var(&cacheSettingsID, "cache-setting-id", 0, msg.DescribeFlagCacheSettingsID) - cmd.Flags().BoolP("help", "h", false, msg.DescribeHelpFlag) - return cmd + cobraCmd.Flags().Int64Var(&applicationID, "application-id", 0, msg.DescribeFlagApplicationID) + cobraCmd.Flags().Int64Var(&cacheSettingsID, "cache-setting-id", 0, msg.DescribeFlagCacheSettingsID) + cobraCmd.Flags().BoolP("help", "h", false, msg.DescribeHelpFlag) + return cobraCmd +} + +func NewCmd(f *cmdutil.Factory) *cobra.Command { + return NewCobraCmd(NewDescribeCmd(f), f) } diff --git a/pkg/cmd/describe/cache_setting/cache_setting_test.go b/pkg/cmd/describe/cache_setting/cache_setting_test.go index 1f33120ce..01a4577d9 100644 --- a/pkg/cmd/describe/cache_setting/cache_setting_test.go +++ b/pkg/cmd/describe/cache_setting/cache_setting_test.go @@ -4,45 +4,85 @@ import ( "net/http" "testing" - "github.com/aziontech/azion-cli/pkg/logger" - "go.uber.org/zap/zapcore" - "github.com/aziontech/azion-cli/pkg/httpmock" + "github.com/aziontech/azion-cli/pkg/logger" "github.com/aziontech/azion-cli/pkg/testutils" "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" ) func TestDescribe(t *testing.T) { logger.New(zapcore.DebugLevel) - t.Run("describe an Cache Settings", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_applications/1673635839/cache_settings/107313"), - httpmock.JSONFromFile("./fixtures/cache_settings.json"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - cmd.SetArgs([]string{"--application-id", "1673635839", "--cache-setting-id", "107313"}) - err := cmd.Execute() - require.NoError(t, err) - }) - t.Run("not found", func(t *testing.T) { - mock := &httpmock.Registry{} + tests := []struct { + name string + request httpmock.Matcher + response httpmock.Responder + args []string + expectErr bool + mockInput func(string) (string, error) + }{ + { + name: "describe a cache setting", + request: httpmock.REST("GET", "edge_applications/1673635839/cache_settings/107313"), + response: httpmock.JSONFromFile("./fixtures/cache_settings.json"), + args: []string{"--application-id", "1673635839", "--cache-setting-id", "107313"}, + expectErr: false, + }, + { + name: "describe a cache setting - no app id", + request: httpmock.REST("GET", "edge_applications/1673635839/cache_settings/107313"), + response: httpmock.JSONFromFile("./fixtures/cache_settings.json"), + args: []string{"--cache-setting-id", "107313"}, + expectErr: false, + mockInput: func(s string) (string, error) { + return "1673635839", nil + }, + }, + { + name: "describe a cache setting - no cache id", + request: httpmock.REST("GET", "edge_applications/1673635839/cache_settings/107313"), + response: httpmock.JSONFromFile("./fixtures/cache_settings.json"), + args: []string{"--application-id", "1673635839"}, + expectErr: false, + mockInput: func(s string) (string, error) { + return "107313", nil + }, + }, + { + name: "not found", + request: httpmock.REST("GET", "edge_applications/1673635839/cache_settings/107313"), + response: httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + args: []string{"--application-id", "1673635839", "--cache-setting-id", "107313"}, + expectErr: true, + }, + { + name: "no id sent", + request: httpmock.REST("GET", "edge_applications/1673635839/cache_settings/0"), + response: httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + args: []string{"--application-id", "1673635839", "--cache-setting-id", "0"}, + expectErr: true, + }, + } - mock.Register( - httpmock.REST("GET", "edge_applications/1673635839/cache_settings/107313"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mock := &httpmock.Registry{} + mock.Register(tt.request, tt.response) - f, _, _ := testutils.NewFactory(mock) + f, _, _ := testutils.NewFactory(mock) + descCmd := NewDescribeCmd(f) + descCmd.AskInput = tt.mockInput + cmd := NewCobraCmd(descCmd, f) + cmd.SetArgs(tt.args) - cmd := NewCmd(f) + err := cmd.Execute() - err := cmd.Execute() - require.Error(t, err) - }) + if tt.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } } diff --git a/pkg/cmd/describe/domains/domains_test.go b/pkg/cmd/describe/domains/domains_test.go index d62cc3cb0..635f8c0d0 100644 --- a/pkg/cmd/describe/domains/domains_test.go +++ b/pkg/cmd/describe/domains/domains_test.go @@ -4,64 +4,62 @@ import ( "net/http" "testing" - "github.com/aziontech/azion-cli/pkg/logger" - "go.uber.org/zap/zapcore" - "github.com/aziontech/azion-cli/pkg/httpmock" + "github.com/aziontech/azion-cli/pkg/logger" "github.com/aziontech/azion-cli/pkg/testutils" "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" ) func TestDescribe(t *testing.T) { logger.New(zapcore.DebugLevel) - t.Run("describe an domains", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "domains/1675272891"), - httpmock.JSONFromFile("./fixtures/domain.json"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - - cmd.SetArgs([]string{"--domain-id", "1675272891"}) - - err := cmd.Execute() - require.NoError(t, err) - }) - t.Run("not found", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "domains/878"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - cmd.SetArgs([]string{"--domain-id", "878"}) - - err := cmd.Execute() - require.Error(t, err) - }) - - t.Run("no id sent", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_applications/1234"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - - err := cmd.Execute() - require.Error(t, err) - }) + tests := []struct { + name string + request httpmock.Matcher + response httpmock.Responder + args []string + expectErr bool + }{ + { + name: "describe a domain", + request: httpmock.REST("GET", "domains/1675272891"), + response: httpmock.JSONFromFile("./fixtures/domain.json"), + args: []string{"--domain-id", "1675272891"}, + expectErr: false, + }, + { + name: "not found", + request: httpmock.REST("GET", "domains/878"), + response: httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + args: []string{"--domain-id", "878"}, + expectErr: true, + }, + { + name: "no id sent", + request: httpmock.REST("GET", "edge_applications/1234"), + response: httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + args: []string{}, + expectErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mock := &httpmock.Registry{} + mock.Register(tt.request, tt.response) + + f, _, _ := testutils.NewFactory(mock) + cmd := NewCmd(f) + cmd.SetArgs(tt.args) + + err := cmd.Execute() + + if tt.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } } diff --git a/pkg/cmd/describe/edge_applications/edge_applications_test.go b/pkg/cmd/describe/edge_applications/edge_applications_test.go index 52eb1df3f..849b3f25d 100644 --- a/pkg/cmd/describe/edge_applications/edge_applications_test.go +++ b/pkg/cmd/describe/edge_applications/edge_applications_test.go @@ -14,56 +14,52 @@ import ( func TestDescribe(t *testing.T) { logger.New(zapcore.DebugLevel) - t.Run("describe an edge application", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_applications/1232132135"), - httpmock.JSONFromFile("./fixtures/response.json"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - - cmd.SetArgs([]string{"--application-id", "1232132135"}) - - err := cmd.Execute() - require.NoError(t, err) - }) - t.Run("not found", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_applications/1234"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - - cmd.SetArgs([]string{"--application-id", "1234"}) - - err := cmd.Execute() - - require.Error(t, err) - }) - - t.Run("no id sent", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_applications/1234"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - - err := cmd.Execute() - - require.Error(t, err) - }) + tests := []struct { + name string + request httpmock.Matcher + response httpmock.Responder + args []string + expectErr bool + }{ + { + name: "describe an edge application", + request: httpmock.REST("GET", "edge_applications/1232132135"), + response: httpmock.JSONFromFile("./fixtures/response.json"), + args: []string{"--application-id", "1232132135"}, + expectErr: false, + }, + { + name: "not found", + request: httpmock.REST("GET", "edge_applications/1234"), + response: httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + args: []string{"--application-id", "1234"}, + expectErr: true, + }, + { + name: "no id sent", + request: httpmock.REST("GET", "edge_applications/1234"), + response: httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + args: []string{}, + expectErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mock := &httpmock.Registry{} + mock.Register(tt.request, tt.response) + + f, _, _ := testutils.NewFactory(mock) + cmd := NewCmd(f) + cmd.SetArgs(tt.args) + + err := cmd.Execute() + + if tt.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } } diff --git a/pkg/cmd/describe/edge_function/edge_function_test.go b/pkg/cmd/describe/edge_function/edge_function_test.go index 905812b09..e3ff8dee4 100644 --- a/pkg/cmd/describe/edge_function/edge_function_test.go +++ b/pkg/cmd/describe/edge_function/edge_function_test.go @@ -4,12 +4,11 @@ import ( "net/http" "testing" - "github.com/aziontech/azion-cli/pkg/logger" - "go.uber.org/zap/zapcore" - "github.com/aziontech/azion-cli/pkg/httpmock" + "github.com/aziontech/azion-cli/pkg/logger" "github.com/aziontech/azion-cli/pkg/testutils" "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" ) var successResponse string = ` @@ -32,59 +31,52 @@ var successResponse string = ` func TestDescribe(t *testing.T) { logger.New(zapcore.DebugLevel) - t.Run("describe a function", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_functions/123"), - httpmock.JSONFromString(successResponse), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - - cmd.SetArgs([]string{"--function-id", "123"}) - - err := cmd.Execute() - require.NoError(t, err) - }) - - t.Run("with code", func(t *testing.T) { - mock := &httpmock.Registry{} - mock.Register( - httpmock.REST("GET", "edge_functions/123"), - httpmock.JSONFromString(successResponse), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - - cmd.SetArgs([]string{"--function-id", "123", "--with-code"}) - - err := cmd.Execute() - require.NoError(t, err) - - t.Run("not found", func(t *testing.T) { + tests := []struct { + name string + request httpmock.Matcher + response httpmock.Responder + args []string + expectErr bool + }{ + { + name: "describe a function", + request: httpmock.REST("GET", "edge_functions/123"), + response: httpmock.JSONFromString(successResponse), + args: []string{"--function-id", "123"}, + expectErr: false, + }, + { + name: "with code", + request: httpmock.REST("GET", "edge_functions/123"), + response: httpmock.JSONFromString(successResponse), + args: []string{"--function-id", "123", "--with-code"}, + expectErr: false, + }, + { + name: "not found", + request: httpmock.REST("GET", "edge_functions/1234"), + response: httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + args: []string{"--function-id", "1234", "--with-code"}, + expectErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_functions/1234"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) + mock.Register(tt.request, tt.response) f, _, _ := testutils.NewFactory(mock) - cmd := NewCmd(f) - - cmd.SetArgs([]string{"--function-id", "1234", "--with-code"}) + cmd.SetArgs(tt.args) err := cmd.Execute() - - require.Error(t, err) + if tt.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } }) - - }) + } } diff --git a/pkg/cmd/describe/edge_storage/object_test.go b/pkg/cmd/describe/edge_storage/object_test.go new file mode 100644 index 000000000..a9f63d1df --- /dev/null +++ b/pkg/cmd/describe/edge_storage/object_test.go @@ -0,0 +1,65 @@ +package edge_storage + +import ( + "net/http" + "testing" + + "github.com/aziontech/azion-cli/pkg/httpmock" + "github.com/aziontech/azion-cli/pkg/logger" + "github.com/aziontech/azion-cli/pkg/testutils" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" +) + +func TestDescribeObject(t *testing.T) { + logger.New(zapcore.DebugLevel) + + tests := []struct { + name string + request httpmock.Matcher + response httpmock.Responder + args []string + expectErr bool + }{ + { + name: "object not found", + request: httpmock.REST("GET", "storage/buckets/unknown/objects/unknown-object"), + response: httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + args: []string{"--bucket-name", "unknown", "--object-key", "unknown-object"}, + expectErr: true, + }, + { + name: "missing bucket name", + request: httpmock.REST("GET", "storage/buckets/missing/objects/test-object"), + response: httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + args: []string{"--object-key", "test-object"}, + expectErr: true, + }, + { + name: "missing object key", + request: httpmock.REST("GET", "storage/buckets/test-bucket/objects/"), + response: httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + args: []string{"--bucket-name", "test-bucket"}, + expectErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mock := &httpmock.Registry{} + mock.Register(tt.request, tt.response) + + factory, _, _ := testutils.NewFactory(mock) + cmd := NewObject(factory) + cmd.SetArgs(tt.args) + + err := cmd.Execute() + + if tt.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/pkg/cmd/describe/origin/origin.go b/pkg/cmd/describe/origin/origin.go index 39d04e63b..b33afaf52 100644 --- a/pkg/cmd/describe/origin/origin.go +++ b/pkg/cmd/describe/origin/origin.go @@ -14,6 +14,7 @@ import ( api "github.com/aziontech/azion-cli/pkg/api/origin" "github.com/aziontech/azion-cli/pkg/cmdutil" "github.com/aziontech/azion-cli/pkg/contracts" + "github.com/aziontech/azion-cli/pkg/iostreams" "github.com/aziontech/azion-cli/pkg/logger" "github.com/aziontech/azion-cli/pkg/output" "github.com/aziontech/azion-cli/utils" @@ -25,9 +26,28 @@ var ( originKey string ) -func NewCmd(f *cmdutil.Factory) *cobra.Command { +type DescribeCmd struct { + Io *iostreams.IOStreams + AskInput func(string) (string, error) + Get func(context.Context, int64, string) (api.GetResponse, error) +} + +func NewDescribeCmd(f *cmdutil.Factory) *DescribeCmd { + return &DescribeCmd{ + Io: f.IOStreams, + AskInput: func(prompt string) (string, error) { + return utils.AskInput(prompt) + }, + Get: func(ctx context.Context, appID int64, key string) (api.GetResponse, error) { + client := api.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) + return client.Get(ctx, appID, key) + }, + } +} + +func NewCobraCmd(describe *DescribeCmd, f *cmdutil.Factory) *cobra.Command { opts := &contracts.DescribeOptions{} - cmd := &cobra.Command{ + cobraCmd := &cobra.Command{ Use: msg.Usage, Short: msg.DescribeShortDescription, Long: msg.DescribeLongDescription, @@ -40,39 +60,38 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { `), RunE: func(cmd *cobra.Command, args []string) error { if !cmd.Flags().Changed("application-id") { - answers, err := utils.AskInput(msg.AskAppID) + answer, err := describe.AskInput(msg.AskAppID) if err != nil { logger.Debug("Error while parsing answer", zap.Error(err)) return utils.ErrorParseResponse } - appID, err := strconv.Atoi(answers) + num, err := strconv.ParseInt(answer, 10, 64) if err != nil { - logger.Debug("Error while parsing string to integer", zap.Error(err)) + logger.Debug("Error while converting answer to int64", zap.Error(err)) return utils.ErrorConvertingStringToInt } - applicationID = int64(appID) + applicationID = num } if !cmd.Flags().Changed("origin-key") { - answers, err := utils.AskInput(msg.AskOriginKey) + answer, err := describe.AskInput(msg.AskOriginKey) if err != nil { logger.Debug("Error while parsing answer", zap.Error(err)) return utils.ErrorParseResponse } - originKey = answers + originKey = answer } - client := api.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) ctx := context.Background() - origin, err := client.Get(ctx, applicationID, originKey) + origin, err := describe.Get(ctx, applicationID, originKey) if err != nil { return fmt.Errorf(msg.ErrorGetOrigin.Error(), err) } - fields := make(map[string]string, 0) + fields := make(map[string]string) fields["OriginId"] = "Origin ID" fields["OriginKey"] = "Origin Key" fields["Name"] = "Name" @@ -92,9 +111,9 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { describeOut := output.DescribeOutput{ GeneralOutput: output.GeneralOutput{ + Out: f.IOStreams.Out, Msg: filepath.Clean(opts.OutPath), Flags: f.Flags, - Out: f.IOStreams.Out, }, Fields: fields, Values: origin, @@ -103,9 +122,13 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { }, } - cmd.Flags().Int64Var(&applicationID, "application-id", 0, msg.FlagEdgeApplicationID) - cmd.Flags().StringVar(&originKey, "origin-key", "", msg.FlagOriginKey) - cmd.Flags().BoolP("help", "h", false, msg.DescribeHelpFlag) + cobraCmd.Flags().Int64Var(&applicationID, "application-id", 0, msg.FlagEdgeApplicationID) + cobraCmd.Flags().StringVar(&originKey, "origin-key", "", msg.FlagOriginKey) + cobraCmd.Flags().BoolP("help", "h", false, msg.DescribeHelpFlag) - return cmd + return cobraCmd +} + +func NewCmd(f *cmdutil.Factory) *cobra.Command { + return NewCobraCmd(NewDescribeCmd(f), f) } diff --git a/pkg/cmd/describe/origin/origin_test.go b/pkg/cmd/describe/origin/origin_test.go index f49f833d5..3ea881705 100644 --- a/pkg/cmd/describe/origin/origin_test.go +++ b/pkg/cmd/describe/origin/origin_test.go @@ -4,60 +4,83 @@ import ( "net/http" "testing" - "github.com/aziontech/azion-cli/pkg/logger" - "go.uber.org/zap/zapcore" - "github.com/aziontech/azion-cli/pkg/httpmock" + "github.com/aziontech/azion-cli/pkg/logger" "github.com/aziontech/azion-cli/pkg/testutils" "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" ) func TestDescribe(t *testing.T) { logger.New(zapcore.DebugLevel) - t.Run("describe an origin", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_applications/123423424/origins/0000000-00000000-00a0a00s0as0-000000"), - httpmock.JSONFromFile("./fixtures/origins.json"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - cmd.SetArgs([]string{"--application-id", "123423424", "--origin-key", "0000000-00000000-00a0a00s0as0-000000"}) - - err := cmd.Execute() - require.NoError(t, err) - }) - t.Run("not found", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_applications/123423424/origin/0000000-00000000-00a0a00s0as0-000000"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - cmd.SetArgs([]string{"--application-id", "123423424", "--origin-key", "0000000-00000000-00a0a00s0as0-000000"}) - err := cmd.Execute() - require.Error(t, err) - }) - t.Run("no id sent", func(t *testing.T) { - mock := &httpmock.Registry{} - mock.Register( - httpmock.REST("GET", "edge_applications/123423424/origins/0000000-00000000-00a0a00s0as0-000000"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) + tests := []struct { + name string + request httpmock.Matcher + response httpmock.Responder + args []string + expectErr bool + mockInput func(string) (string, error) + }{ + { + name: "describe an origin", + request: httpmock.REST("GET", "edge_applications/123423424/origins/0000000-00000000-00a0a00s0as0-000000"), + response: httpmock.JSONFromFile("./fixtures/origins.json"), + args: []string{"--application-id", "123423424", "--origin-key", "0000000-00000000-00a0a00s0as0-000000"}, + expectErr: false, + }, + { + name: "describe an origin - no app id", + request: httpmock.REST("GET", "edge_applications/123423424/origins/0000000-00000000-00a0a00s0as0-000000"), + response: httpmock.JSONFromFile("./fixtures/origins.json"), + args: []string{"--origin-key", "0000000-00000000-00a0a00s0as0-000000"}, + expectErr: false, + mockInput: func(s string) (string, error) { + return "123423424", nil + }, + }, + { + name: "describe an origin - no origin key", + request: httpmock.REST("GET", "edge_applications/123423424/origins/0000000-00000000-00a0a00s0as0-000000"), + response: httpmock.JSONFromFile("./fixtures/origins.json"), + args: []string{"--application-id", "123423424"}, + expectErr: false, + mockInput: func(s string) (string, error) { + return "0000000-00000000-00a0a00s0as0-000000", nil + }, + }, + { + name: "not found", + request: httpmock.REST("GET", "edge_applications/123423424/origins/0000000-00000000-00a0a00s0as0-000000"), + response: httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + args: []string{"--application-id", "123423424", "--origin-key", "0000000-00000000-00a0a00s0as0-000000"}, + expectErr: true, + }, + { + name: "no id sent", + request: httpmock.REST("GET", "edge_applications/123423424/origins/0000000-00000000-00a0a00s0as0-000000"), + response: httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + args: []string{"--application-id", "123423424", "--origin-key", "0000000-00000000-00a0a00s0as0-000000"}, + expectErr: true, + }, + } - f, _, _ := testutils.NewFactory(mock) - cmd := NewCmd(f) - cmd.SetArgs([]string{"--application-id", "123423424", "--origin-key", "0000000-00000000-00a0a00s0as0-000000"}) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mock := &httpmock.Registry{} + mock.Register(tt.request, tt.response) + f, _, _ := testutils.NewFactory(mock) + descCmd := NewDescribeCmd(f) + descCmd.AskInput = tt.mockInput + cmd := NewCobraCmd(descCmd, f) + cmd.SetArgs(tt.args) - err := cmd.Execute() - require.Error(t, err) - }) + err := cmd.Execute() + if tt.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } } diff --git a/pkg/cmd/describe/personal_token/personal_token_test.go b/pkg/cmd/describe/personal_token/personal_token_test.go index 6af387af8..ca59e1744 100644 --- a/pkg/cmd/describe/personal_token/personal_token_test.go +++ b/pkg/cmd/describe/personal_token/personal_token_test.go @@ -24,20 +24,21 @@ func TestNewCmd(t *testing.T) { err string }{ { - name: "Succes Status 200 Ok with struct nil no error", + name: "Success Status 200 Ok with struct nil no error", request: httpmock.REST(http.MethodGet, "iam/personal_tokens/7b026645-e3dc-4d0f-91c5-6f4030996f6c"), response: httpmock.JSONFromString("{}"), args: []string{"--id", "7b026645-e3dc-4d0f-91c5-6f4030996f6c"}, output: "Uuid: null \nName: null \nCreated: null \nExpires At: null \nDescription: null \n", }, { - name: "Succes Status 200 Ok with itens", + name: "Success Status 200 Ok with items", request: httpmock.REST(http.MethodGet, "iam/personal_tokens/7b026645-e3dc-4d0f-91c5-6f4030996f6c"), response: httpmock.JSONFromFile(".fixtures/response.json"), args: []string{"--id", "7b026645-e3dc-4d0f-91c5-6f4030996f6c"}, output: "Uuid: 123e4567-e89b-12d3-a456-426614174000 \nName: MyToken \nCreated: \"2024-07-10T12:34:56Z\" \nExpires At: \"2025-07-10T12:34:56Z\" \nDescription: \"Token for accessing API\" \n", }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { mock := &httpmock.Registry{} diff --git a/pkg/cmd/describe/rules_engine/rules_engine.go b/pkg/cmd/describe/rules_engine/rules_engine.go index 295f1eee3..0b79b8dc2 100644 --- a/pkg/cmd/describe/rules_engine/rules_engine.go +++ b/pkg/cmd/describe/rules_engine/rules_engine.go @@ -3,7 +3,6 @@ package rulesengine import ( "context" "fmt" - "path/filepath" "strconv" "go.uber.org/zap" @@ -13,7 +12,7 @@ import ( api "github.com/aziontech/azion-cli/pkg/api/edge_applications" "github.com/aziontech/azion-cli/pkg/cmdutil" - "github.com/aziontech/azion-cli/pkg/contracts" + "github.com/aziontech/azion-cli/pkg/iostreams" "github.com/aziontech/azion-cli/pkg/logger" "github.com/aziontech/azion-cli/pkg/output" "github.com/aziontech/azion-cli/utils" @@ -26,9 +25,29 @@ var ( phase string ) -func NewCmd(f *cmdutil.Factory) *cobra.Command { - opts := &contracts.DescribeOptions{} - cmd := &cobra.Command{ +type DescribeCmd struct { + Io *iostreams.IOStreams + ReadInput func(string) (string, error) + GetRulesEngine func(context.Context, int64, int64, string) (api.RulesEngineResponse, error) + AskInput func(string) (string, error) +} + +func NewDescribeCmd(f *cmdutil.Factory) *DescribeCmd { + return &DescribeCmd{ + Io: f.IOStreams, + ReadInput: func(prompt string) (string, error) { + return utils.AskInput(prompt) + }, + GetRulesEngine: func(ctx context.Context, appID, ruleID int64, phase string) (api.RulesEngineResponse, error) { + client := api.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) + return client.GetRulesEngine(ctx, appID, ruleID, phase) + }, + AskInput: utils.AskInput, + } +} + +func NewCobraCmd(describe *DescribeCmd, f *cmdutil.Factory) *cobra.Command { + cobraCmd := &cobra.Command{ Use: msg.Usage, Short: msg.ShortDescription, Long: msg.LongDescription, @@ -39,10 +58,11 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { $ azion describe rules-engine --application-id 1673635839 --rule-id 31223 --phase response --format json $ azion describe rules-engine --application-id 1673635839 --rule-id 31223 --phase request --out "./tmp/test.json" `), - RunE: func(cmd *cobra.Command, _ []string) error { - if !cmd.Flags().Changed("rule-id") { + RunE: func(cmd *cobra.Command, args []string) error { + var err error - answer, err := utils.AskInput(msg.AskInputRulesId) + if !cmd.Flags().Changed("rule-id") { + answer, err := describe.AskInput(msg.AskInputRulesId) if err != nil { return err } @@ -57,8 +77,7 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { } if !cmd.Flags().Changed("application-id") { - - answer, err := utils.AskInput(msg.AskInputApplicationId) + answer, err := describe.AskInput(msg.AskInputApplicationId) if err != nil { return err } @@ -73,8 +92,7 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { } if !cmd.Flags().Changed("phase") { - - answer, err := utils.AskInput(msg.AskInputPhase) + answer, err := describe.AskInput(msg.AskInputPhase) if err != nil { return err } @@ -82,14 +100,13 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { phase = answer } - client := api.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) ctx := context.Background() - rules, err := client.GetRulesEngine(ctx, applicationID, ruleID, phase) + rules, err := describe.GetRulesEngine(ctx, applicationID, ruleID, phase) if err != nil { return fmt.Errorf(msg.ErrorGetRulesEngine.Error(), err) } - fields := make(map[string]string, 0) + fields := make(map[string]string) fields["Id"] = "Rules Engine ID" fields["Name"] = "Name" fields["Description"] = "Description" @@ -100,7 +117,6 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { describeOut := output.DescribeOutput{ GeneralOutput: output.GeneralOutput{ - Msg: filepath.Clean(opts.OutPath), Flags: f.Flags, Out: f.IOStreams.Out, }, @@ -111,10 +127,14 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { }, } - cmd.Flags().Int64Var(&applicationID, "application-id", 0, msg.FlagAppID) - cmd.Flags().Int64Var(&ruleID, "rule-id", 0, msg.FlagRuleID) - cmd.Flags().StringVar(&phase, "phase", "request", msg.FlagPhase) - cmd.Flags().BoolP("help", "h", false, msg.HelpFlag) + cobraCmd.Flags().Int64Var(&applicationID, "application-id", 0, msg.FlagAppID) + cobraCmd.Flags().Int64Var(&ruleID, "rule-id", 0, msg.FlagRuleID) + cobraCmd.Flags().StringVar(&phase, "phase", "request", msg.FlagPhase) + cobraCmd.Flags().BoolP("help", "h", false, msg.HelpFlag) + + return cobraCmd +} - return cmd +func NewCmd(f *cmdutil.Factory) *cobra.Command { + return NewCobraCmd(NewDescribeCmd(f), f) } diff --git a/pkg/cmd/describe/rules_engine/rules_engine_test.go b/pkg/cmd/describe/rules_engine/rules_engine_test.go index 949c554b5..02ed6adca 100644 --- a/pkg/cmd/describe/rules_engine/rules_engine_test.go +++ b/pkg/cmd/describe/rules_engine/rules_engine_test.go @@ -1,7 +1,6 @@ package rulesengine import ( - "log" "net/http" "testing" @@ -14,51 +13,155 @@ import ( func TestDescribe(t *testing.T) { logger.New(zapcore.DebugLevel) - t.Run("describe a rule engine", func(t *testing.T) { - mock := &httpmock.Registry{} - mock.Register( - httpmock.REST("GET", "edge_applications/1678743802/rules_engine/request/rules/173617"), - httpmock.JSONFromFile("./fixtures/rules.json"), - ) + tests := []struct { + name string + setupMock func(mock *httpmock.Registry) + args []string + askInput func(s string) (string, error) + expectErr bool + }{ + { + name: "describe a rule engine", + setupMock: func(mock *httpmock.Registry) { + mock.Register( + httpmock.REST("GET", "edge_applications/1678743802/rules_engine/request/rules/173617"), + httpmock.JSONFromFile("./fixtures/rules.json"), + ) + }, + args: []string{"--application-id", "1678743802", "--rule-id", "173617", "--phase", "request"}, + expectErr: false, + }, + { + name: "describe a rule engine - ask for app id", + setupMock: func(mock *httpmock.Registry) { + mock.Register( + httpmock.REST("GET", "edge_applications/1678743802/rules_engine/request/rules/173617"), + httpmock.JSONFromFile("./fixtures/rules.json"), + ) + }, + args: []string{"--rule-id", "173617", "--phase", "request"}, + askInput: func(s string) (string, error) { + return "1678743802", nil + }, + expectErr: false, + }, + { + name: "describe a rule engine - ask for phase", + setupMock: func(mock *httpmock.Registry) { + mock.Register( + httpmock.REST("GET", "edge_applications/1678743802/rules_engine/request/rules/173617"), + httpmock.JSONFromFile("./fixtures/rules.json"), + ) + }, + args: []string{"--application-id", "1678743802", "--rule-id", "173617"}, + askInput: func(s string) (string, error) { + return "request", nil + }, + expectErr: false, + }, + { + name: "describe a rule engine - ask for rule id", + setupMock: func(mock *httpmock.Registry) { + mock.Register( + httpmock.REST("GET", "edge_applications/1678743802/rules_engine/request/rules/173617"), + httpmock.JSONFromFile("./fixtures/rules.json"), + ) + }, + args: []string{"--application-id", "1678743802", "--phase", "request"}, + askInput: func(s string) (string, error) { + return "173617", nil + }, + expectErr: false, + }, + { + name: "not found", + setupMock: func(mock *httpmock.Registry) { + mock.Register( + httpmock.REST("GET", "edge_applications/1678743802/rules_engine/request/rules/666"), + httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + ) + }, + args: []string{"--application-id", "1678743802", "--rule-id", "666", "--phase", "request"}, + expectErr: true, + }, + { + name: "missing mandatory flag", + setupMock: func(mock *httpmock.Registry) { + mock.Register( + httpmock.REST("GET", "edge_applications/1678743802/rules_engine/request/rules/1"), + httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + ) + }, + args: []string{}, + expectErr: true, + }, + { + name: "different phases", + setupMock: func(mock *httpmock.Registry) { + mock.Register( + httpmock.REST("GET", "edge_applications/1678743802/rules_engine/response/rules/173617"), + httpmock.JSONFromFile("./fixtures/rules.json"), + ) + }, + args: []string{"--application-id", "1678743802", "--rule-id", "173617", "--phase", "response"}, + expectErr: false, + }, + { + name: "invalid JSON response", + setupMock: func(mock *httpmock.Registry) { + mock.Register( + httpmock.REST("GET", "edge_applications/1678743802/rules_engine/request/rules/173617"), + httpmock.StringResponse("{invalid json"), + ) + }, + args: []string{"--application-id", "1678743802", "--rule-id", "173617", "--phase", "request"}, + expectErr: true, + }, + { + name: "non-existent application ID", + setupMock: func(mock *httpmock.Registry) { + mock.Register( + httpmock.REST("GET", "edge_applications/999999999/rules_engine/request/rules/173617"), + httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + ) + }, + args: []string{"--application-id", "999999999", "--rule-id", "173617", "--phase", "request"}, + expectErr: true, + }, + { + name: "invalid phase", + setupMock: func(mock *httpmock.Registry) { + // No mock needed for invalid phase + }, + args: []string{"--application-id", "1678743802", "--rule-id", "173617", "--phase", "invalid_phase"}, + expectErr: true, + }, + } - f, _, _ := testutils.NewFactory(mock) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mock := &httpmock.Registry{} + if tt.setupMock != nil { + tt.setupMock(mock) + } - cmd := NewCmd(f) - err := cmd.Execute() - if err != nil { - log.Println("error executing cmd err: ", err.Error()) - } - }) + f, _, _ := testutils.NewFactory(mock) - t.Run("not found", func(t *testing.T) { - mock := &httpmock.Registry{} + descCmd := NewDescribeCmd(f) + if tt.askInput != nil { + descCmd.AskInput = tt.askInput + } - mock.Register( - httpmock.REST("GET", "edge_applications/1678743802/rules_engine/request/rules/666"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) + cmd := NewCobraCmd(descCmd, f) + cmd.SetArgs(tt.args) + err := cmd.Execute() - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - - err := cmd.Execute() - require.Error(t, err) - }) - - t.Run("missing mandatory flag", func(t *testing.T) { - mock := &httpmock.Registry{} - mock.Register( - httpmock.REST("GET", "edge_applications/1678743802/rules_engine/request/rules/1"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) - - f, _, _ := testutils.NewFactory(mock) - cmd := NewCmd(f) - cmd.SetArgs([]string{}) - - err := cmd.Execute() - require.Error(t, err) - }) + if tt.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } } diff --git a/pkg/cmd/describe/variables/variables_test.go b/pkg/cmd/describe/variables/variables_test.go index c9377e1b1..aecee2f92 100644 --- a/pkg/cmd/describe/variables/variables_test.go +++ b/pkg/cmd/describe/variables/variables_test.go @@ -13,50 +13,66 @@ import ( func TestDescribe(t *testing.T) { logger.New(zapcore.DebugLevel) - t.Run("describe an variables", func(t *testing.T) { - mock := &httpmock.Registry{} - mock.Register( - httpmock.REST("GET", "variables/32e8ffca-4021-49a4-971f-330935566af4"), - httpmock.JSONFromFile(".fixtures/variables.json"), - ) + tests := []struct { + name string + setupMock func(mock *httpmock.Registry) + args []string + expectErr bool + }{ + { + name: "describe a variable", + setupMock: func(mock *httpmock.Registry) { + mock.Register( + httpmock.REST("GET", "variables/32e8ffca-4021-49a4-971f-330935566af4"), + httpmock.JSONFromFile(".fixtures/variables.json"), + ) + }, + args: []string{"--variable-id", "32e8ffca-4021-49a4-971f-330935566af4"}, + expectErr: false, + }, + { + name: "not found", + setupMock: func(mock *httpmock.Registry) { + mock.Register( + httpmock.REST("GET", "variables/32e8ffca-4021-49a4-971f-330935566af4"), + httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + ) + }, + args: []string{"--variable-id", "32e8ffca-4021-49a4-971f-330935566af4"}, + expectErr: true, + }, + { + name: "no id sent", + setupMock: func(mock *httpmock.Registry) { + mock.Register( + httpmock.REST("GET", "variables/123423424"), + httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), + ) + }, + args: []string{"--variable-id", "123423424"}, + expectErr: true, + }, + } - f, _, _ := testutils.NewFactory(mock) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mock := &httpmock.Registry{} + if tt.setupMock != nil { + tt.setupMock(mock) + } - cmd := NewCmd(f) - cmd.SetArgs([]string{"--variable-id", "32e8ffca-4021-49a4-971f-330935566af4"}) + f, _, _ := testutils.NewFactory(mock) - err := cmd.Execute() - require.NoError(t, err) - }) - t.Run("not found", func(t *testing.T) { - mock := &httpmock.Registry{} + cmd := NewCmd(f) + cmd.SetArgs(tt.args) + err := cmd.Execute() - mock.Register( - httpmock.REST("GET", "variables/32e8ffca-4021-49a4-971f-330935566af4"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - - err := cmd.Execute() - require.Error(t, err) - }) - - t.Run("no id sent", func(t *testing.T) { - mock := &httpmock.Registry{} - mock.Register( - httpmock.REST("GET", "variables/123423424"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) - - f, _, _ := testutils.NewFactory(mock) - cmd := NewCmd(f) - cmd.SetArgs([]string{"--variable-id", "123423424"}) - - err := cmd.Execute() - require.Error(t, err) - }) + if tt.expectErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } }