Skip to content

Commit b827520

Browse files
authored
Redis: Add nil checks and testcases for output functions (#646)
* chore: add nil checks and testcases * chore: Added testcases for nil responses
1 parent 9bd08cb commit b827520

File tree

13 files changed

+349
-53
lines changed

13 files changed

+349
-53
lines changed

internal/cmd/redis/credentials/create/create.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func NewCmd(p *print.Printer) *cobra.Command {
7979
return fmt.Errorf("create Redis credentials: %w", err)
8080
}
8181

82-
return outputResult(p, model, instanceLabel, resp)
82+
return outputResult(p, *model, instanceLabel, resp)
8383
},
8484
}
8585
configureFlags(cmd)
@@ -123,8 +123,20 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *redis.APICl
123123
return req
124124
}
125125

126-
func outputResult(p *print.Printer, model *inputModel, instanceLabel string, resp *redis.CredentialsResponse) error {
126+
func outputResult(p *print.Printer, model inputModel, instanceLabel string, resp *redis.CredentialsResponse) error {
127+
if model.GlobalFlagModel == nil {
128+
return fmt.Errorf("no global flags defined")
129+
}
130+
if resp == nil {
131+
return fmt.Errorf("no response defined")
132+
}
127133
if !model.ShowPassword {
134+
if resp.Raw == nil {
135+
resp.Raw = &redis.RawCredentials{}
136+
}
137+
if resp.Raw.Credentials == nil {
138+
resp.Raw.Credentials = &redis.Credentials{}
139+
}
128140
resp.Raw.Credentials.Password = utils.Ptr("hidden")
129141
}
130142

@@ -146,11 +158,11 @@ func outputResult(p *print.Printer, model *inputModel, instanceLabel string, res
146158

147159
return nil
148160
default:
149-
p.Outputf("Created credentials for instance %q. Credentials ID: %s\n\n", instanceLabel, *resp.Id)
161+
p.Outputf("Created credentials for instance %q. Credentials ID: %s\n\n", instanceLabel, utils.PtrString(resp.Id))
150162
// The username field cannot be set by the user, so we only display it if it's not returned empty
151163
if resp.HasRaw() && resp.Raw.Credentials != nil {
152164
if username := resp.Raw.Credentials.Username; username != nil && *username != "" {
153-
p.Outputf("Username: %s\n", *username)
165+
p.Outputf("Username: %s\n", utils.PtrString(username))
154166
}
155167
if !model.ShowPassword {
156168
p.Outputf("Password: <hidden>\n")

internal/cmd/redis/credentials/create/create_test.go

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ import (
44
"context"
55
"testing"
66

7-
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
8-
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
9-
107
"github.com/google/go-cmp/cmp"
118
"github.com/google/go-cmp/cmp/cmpopts"
129
"github.com/google/uuid"
10+
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
11+
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
1312
"github.com/stackitcloud/stackit-sdk-go/services/redis"
1413
)
1514

@@ -200,3 +199,36 @@ func TestBuildRequest(t *testing.T) {
200199
})
201200
}
202201
}
202+
203+
func Test_outputResult(t *testing.T) {
204+
type args struct {
205+
model inputModel
206+
instanceLabel string
207+
resp *redis.CredentialsResponse
208+
}
209+
tests := []struct {
210+
name string
211+
args args
212+
wantErr bool
213+
}{
214+
{
215+
name: "empty",
216+
args: args{model: inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{}}, resp: &redis.CredentialsResponse{}},
217+
wantErr: false,
218+
},
219+
{
220+
name: "nil response",
221+
args: args{model: inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{}}},
222+
wantErr: true,
223+
},
224+
}
225+
p := print.NewPrinter()
226+
p.Cmd = NewCmd(p)
227+
for _, tt := range tests {
228+
t.Run(tt.name, func(t *testing.T) {
229+
if err := outputResult(p, tt.args.model, tt.args.instanceLabel, tt.args.resp); (err != nil) != tt.wantErr {
230+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
231+
}
232+
})
233+
}
234+
}

internal/cmd/redis/credentials/describe/describe.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *redis.APICl
112112
}
113113

114114
func outputResult(p *print.Printer, outputFormat string, credentials *redis.CredentialsResponse) error {
115+
if credentials == nil {
116+
return fmt.Errorf("no credentials passed")
117+
}
115118
switch outputFormat {
116119
case print.JSONOutputFormat:
117120
details, err := json.MarshalIndent(credentials, "", " ")
@@ -131,7 +134,7 @@ func outputResult(p *print.Printer, outputFormat string, credentials *redis.Cred
131134
return nil
132135
default:
133136
table := tables.NewTable()
134-
table.AddRow("ID", *credentials.Id)
137+
table.AddRow("ID", utils.PtrString(credentials.Id))
135138
table.AddSeparator()
136139
// The username field cannot be set by the user so we only display it if it's not returned empty
137140
if credentials.HasRaw() && credentials.Raw.Credentials != nil {

internal/cmd/redis/credentials/describe/describe_test.go

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ import (
44
"context"
55
"testing"
66

7-
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
8-
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
9-
107
"github.com/google/go-cmp/cmp"
118
"github.com/google/go-cmp/cmp/cmpopts"
129
"github.com/google/uuid"
10+
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
11+
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
1312
"github.com/stackitcloud/stackit-sdk-go/services/redis"
1413
)
1514

@@ -243,3 +242,37 @@ func TestBuildRequest(t *testing.T) {
243242
})
244243
}
245244
}
245+
246+
func Test_outputResult(t *testing.T) {
247+
type args struct {
248+
outputFormat string
249+
credentials *redis.CredentialsResponse
250+
}
251+
tests := []struct {
252+
name string
253+
args args
254+
wantErr bool
255+
}{
256+
{
257+
name: "empty",
258+
args: args{
259+
credentials: &redis.CredentialsResponse{},
260+
},
261+
wantErr: false,
262+
},
263+
{
264+
name: "nil response",
265+
args: args{},
266+
wantErr: true,
267+
},
268+
}
269+
p := print.NewPrinter()
270+
p.Cmd = NewCmd(p)
271+
for _, tt := range tests {
272+
t.Run(tt.name, func(t *testing.T) {
273+
if err := outputResult(p, tt.args.outputFormat, tt.args.credentials); (err != nil) != tt.wantErr {
274+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
275+
}
276+
})
277+
}
278+
}

internal/cmd/redis/credentials/list/list_test.go

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@ import (
44
"context"
55
"testing"
66

7-
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
8-
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
9-
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
10-
117
"github.com/google/go-cmp/cmp"
128
"github.com/google/go-cmp/cmp/cmpopts"
139
"github.com/google/uuid"
10+
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
11+
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
12+
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
1413
"github.com/stackitcloud/stackit-sdk-go/services/redis"
1514
)
1615

@@ -207,3 +206,40 @@ func TestBuildRequest(t *testing.T) {
207206
})
208207
}
209208
}
209+
210+
func Test_outputResult(t *testing.T) {
211+
type args struct {
212+
outputFormat string
213+
credentials []redis.CredentialsListItem
214+
}
215+
tests := []struct {
216+
name string
217+
args args
218+
wantErr bool
219+
}{
220+
{
221+
name: "empty",
222+
args: args{},
223+
wantErr: false,
224+
},
225+
{
226+
name: "slice with empty element",
227+
args: args{
228+
outputFormat: "",
229+
credentials: []redis.CredentialsListItem{
230+
{},
231+
},
232+
},
233+
wantErr: false,
234+
},
235+
}
236+
p := print.NewPrinter()
237+
p.Cmd = NewCmd(p)
238+
for _, tt := range tests {
239+
t.Run(tt.name, func(t *testing.T) {
240+
if err := outputResult(p, tt.args.outputFormat, tt.args.credentials); (err != nil) != tt.wantErr {
241+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
242+
}
243+
})
244+
}
245+
}

internal/cmd/redis/instance/create/create.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,15 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient redisClient)
252252
}
253253

254254
func outputResult(p *print.Printer, model *inputModel, projectLabel, instanceId string, resp *redis.CreateInstanceResponse) error {
255+
if model == nil {
256+
return fmt.Errorf("no model passed")
257+
}
258+
if model.GlobalFlagModel == nil {
259+
return fmt.Errorf("no global flags passed")
260+
}
261+
if resp == nil {
262+
return fmt.Errorf("no response defined")
263+
}
255264
switch model.OutputFormat {
256265
case print.JSONOutputFormat:
257266
details, err := json.MarshalIndent(resp, "", " ")

internal/cmd/redis/instance/create/create_test.go

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@ import (
55
"fmt"
66
"testing"
77

8-
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
9-
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
10-
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
11-
128
"github.com/google/go-cmp/cmp"
139
"github.com/google/go-cmp/cmp/cmpopts"
1410
"github.com/google/uuid"
11+
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
12+
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
13+
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
1514
"github.com/stackitcloud/stackit-sdk-go/services/redis"
1615
)
1716

@@ -463,3 +462,46 @@ func TestBuildRequest(t *testing.T) {
463462
})
464463
}
465464
}
465+
466+
func Test_outputResult(t *testing.T) {
467+
type args struct {
468+
model *inputModel
469+
projectLabel string
470+
instanceId string
471+
resp *redis.CreateInstanceResponse
472+
}
473+
tests := []struct {
474+
name string
475+
args args
476+
wantErr bool
477+
}{
478+
{
479+
name: "empty",
480+
args: args{
481+
model: &inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{}},
482+
projectLabel: "",
483+
instanceId: testMonitoringInstanceId,
484+
resp: &redis.CreateInstanceResponse{},
485+
},
486+
wantErr: false,
487+
},
488+
{
489+
name: "nil response",
490+
args: args{
491+
model: &inputModel{GlobalFlagModel: &globalflags.GlobalFlagModel{}},
492+
projectLabel: "",
493+
instanceId: testMonitoringInstanceId,
494+
},
495+
wantErr: true,
496+
},
497+
}
498+
p := print.NewPrinter()
499+
p.Cmd = NewCmd(p)
500+
for _, tt := range tests {
501+
t.Run(tt.name, func(t *testing.T) {
502+
if err := outputResult(p, tt.args.model, tt.args.projectLabel, tt.args.instanceId, tt.args.resp); (err != nil) != tt.wantErr {
503+
t.Errorf("outputResult() error = %v, wantErr %v", err, tt.wantErr)
504+
}
505+
})
506+
}
507+
}

internal/cmd/redis/instance/describe/describe.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *redis.APICl
100100
}
101101

102102
func outputResult(p *print.Printer, outputFormat string, instance *redis.Instance) error {
103+
if instance == nil {
104+
return fmt.Errorf("no instance passed")
105+
}
103106
switch outputFormat {
104107
case print.JSONOutputFormat:
105108
details, err := json.MarshalIndent(instance, "", " ")
@@ -123,18 +126,22 @@ func outputResult(p *print.Printer, outputFormat string, instance *redis.Instanc
123126
table.AddSeparator()
124127
table.AddRow("NAME", utils.PtrString(instance.Name))
125128
table.AddSeparator()
126-
table.AddRow("LAST OPERATION TYPE", utils.PtrString(instance.LastOperation.Type))
127-
table.AddSeparator()
128-
table.AddRow("LAST OPERATION STATE", utils.PtrString(instance.LastOperation.State))
129-
table.AddSeparator()
129+
if lastOperation := instance.LastOperation; lastOperation != nil {
130+
table.AddRow("LAST OPERATION TYPE", utils.PtrString(instance.LastOperation.Type))
131+
table.AddSeparator()
132+
table.AddRow("LAST OPERATION STATE", utils.PtrString(instance.LastOperation.State))
133+
table.AddSeparator()
134+
}
130135
table.AddRow("PLAN ID", utils.PtrString(instance.PlanId))
131-
// Only show ACL if it's present and not empty
132-
acl := (*instance.Parameters)[aclParameterKey]
133-
aclStr, ok := acl.(string)
134-
if ok {
135-
if aclStr != "" {
136-
table.AddSeparator()
137-
table.AddRow("ACL", aclStr)
136+
if parameters := instance.Parameters; parameters != nil {
137+
// Only show ACL if it's present and not empty
138+
acl := (*parameters)[aclParameterKey]
139+
aclStr, ok := acl.(string)
140+
if ok {
141+
if aclStr != "" {
142+
table.AddSeparator()
143+
table.AddRow("ACL", aclStr)
144+
}
138145
}
139146
}
140147
err := table.Display(p)

0 commit comments

Comments
 (0)