From a0e57a6539ea67f6b6f7ea3e97925c958393af3a Mon Sep 17 00:00:00 2001 From: Alexander Dahmen Date: Fri, 21 Feb 2025 09:12:34 +0100 Subject: [PATCH] chore(curl): Add nil pointer checks and tests for the outputResult functions Signed-off-by: Alexander Dahmen --- docs/stackit_curl.md | 2 +- internal/cmd/curl/curl.go | 7 +++-- internal/cmd/curl/curl_test.go | 52 ++++++++++++++++++++++++++++++---- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/docs/stackit_curl.md b/docs/stackit_curl.md index 4dd7f453f..ef387edb5 100644 --- a/docs/stackit_curl.md +++ b/docs/stackit_curl.md @@ -17,7 +17,7 @@ stackit curl URL [flags] $ stackit curl https://dns.api.stackit.cloud/v1/projects/xxx/zones Get all the DNS zones for project with ID xxx via GET request to https://dns.api.stackit.cloud/v1/projects/xxx/zones, write complete response (headers and body) to file "./output.txt" - $ stackit curl https://dns.api.stackit.cloud/v1/projects/xxx/zones -include --output ./output.txt + $ stackit curl https://dns.api.stackit.cloud/v1/projects/xxx/zones --include --output ./output.txt Create a new DNS zone for project with ID xxx via POST request to https://dns.api.stackit.cloud/v1/projects/xxx/zones with payload from file "./payload.json" $ stackit curl https://dns.api.stackit.cloud/v1/projects/xxx/zones -X POST --data @./payload.json diff --git a/internal/cmd/curl/curl.go b/internal/cmd/curl/curl.go index e78accf1a..f52217b73 100644 --- a/internal/cmd/curl/curl.go +++ b/internal/cmd/curl/curl.go @@ -56,7 +56,7 @@ func NewCmd(p *print.Printer) *cobra.Command { ), examples.NewExample( `Get all the DNS zones for project with ID xxx via GET request to https://dns.api.stackit.cloud/v1/projects/xxx/zones, write complete response (headers and body) to file "./output.txt"`, - "$ stackit curl https://dns.api.stackit.cloud/v1/projects/xxx/zones -include --output ./output.txt", + "$ stackit curl https://dns.api.stackit.cloud/v1/projects/xxx/zones --include --output ./output.txt", ), examples.NewExample( `Create a new DNS zone for project with ID xxx via POST request to https://dns.api.stackit.cloud/v1/projects/xxx/zones with payload from file "./payload.json"`, @@ -198,6 +198,9 @@ func buildRequest(model *inputModel, bearerToken string) (*http.Request, error) } func outputResponse(p *print.Printer, model *inputModel, resp *http.Response) error { + if resp == nil { + return fmt.Errorf("http response is empty") + } output := make([]byte, 0) if model.IncludeResponseHeaders { respHeader, err := httputil.DumpResponse(resp, false) @@ -215,7 +218,7 @@ func outputResponse(p *print.Printer, model *inputModel, resp *http.Response) er if model.OutputFile == nil { p.Outputln(string(output)) } else { - err = os.WriteFile(*model.OutputFile, output, 0o600) + err = os.WriteFile(utils.PtrString(model.OutputFile), output, 0o600) if err != nil { return fmt.Errorf("write output to file: %w", err) } diff --git a/internal/cmd/curl/curl_test.go b/internal/cmd/curl/curl_test.go index 62d70e607..372d5663d 100644 --- a/internal/cmd/curl/curl_test.go +++ b/internal/cmd/curl/curl_test.go @@ -5,16 +5,16 @@ import ( "context" "fmt" "net/http" + "os" "testing" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/spf13/viper" "github.com/stackitcloud/stackit-cli/internal/pkg/config" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" - - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" ) var testURL = "https://some-service.api.stackit.cloud/v1/foo?bar=baz" @@ -37,7 +37,7 @@ func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]st dataFlag: "data", includeResponseHeadersFlag: "true", failOnHTTPErrorFlag: "true", - outputFileFlag: "path/to/output.txt", + outputFileFlag: "./output.txt", } for _, mod := range mods { mod(flagValues) @@ -53,7 +53,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { Data: utils.Ptr("data"), IncludeResponseHeaders: true, FailOnHTTPError: true, - OutputFile: utils.Ptr("path/to/output.txt"), + OutputFile: utils.Ptr("./output.txt"), } for _, mod := range mods { mod(model) @@ -403,3 +403,45 @@ func TestBuildRequest(t *testing.T) { }) } } + +func TestOutputResponse(t *testing.T) { + type args struct { + model *inputModel + resp *http.Response + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "empty", + args: args{}, + wantErr: true, + }, + { + name: "http response as argument", + args: args{ + model: fixtureInputModel(), + resp: &http.Response{Body: http.NoBody}, + }, + wantErr: false, + }, + } + p := print.NewPrinter() + p.Cmd = NewCmd(p) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := outputResponse(p, tt.args.model, tt.args.resp); (err != nil) != tt.wantErr { + t.Errorf("outputResponse() error = %v, wantErr %v", err, tt.wantErr) + } + if tt.args.model != nil { + if _, err := os.Stat(*tt.args.model.OutputFile); err == nil { + if err := os.Remove(*tt.args.model.OutputFile); err != nil { + t.Errorf("remove output file error = %v", err) + } + } + } + }) + } +}