Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.

Commit e0b037d

Browse files
author
noah
committed
Add unit test for dynamic_payload field
1 parent b9329e6 commit e0b037d

File tree

2 files changed

+118
-28
lines changed

2 files changed

+118
-28
lines changed

Diff for: model/extent/env.go

+31-27
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,12 @@ func (e *Env) IsFreezed(t time.Time) (bool, error) {
126126
return false, nil
127127
}
128128

129-
func (e *Env) EvaluateDynamicPayload(values map[string]interface{}) (map[string]interface{}, error) {
130-
return e.DynamicPayload.Evaluate(values)
129+
func (e *Env) IsDynamicPayloadEnabled() bool {
130+
return (e.DynamicPayload != nil && e.DynamicPayload.Enabled)
131+
}
132+
133+
func (e *Env) ValidateDynamicPayload(values map[string]interface{}) error {
134+
return e.DynamicPayload.Validate(values)
131135
}
132136

133137
// DynamicPayload can be set to dynamically fill in the payload.
@@ -136,9 +140,9 @@ type DynamicPayload struct {
136140
Inputs map[string]Input `json:"inputs" yaml:"inputs"`
137141
}
138142

139-
// Evaluate validates the payload. After that,
140-
// an object containing only the value of the defined field is returned.
141-
func (dp *DynamicPayload) Evaluate(values map[string]interface{}) (output map[string]interface{}, err error) {
143+
// Validate validates the payload.
144+
func (dp *DynamicPayload) Validate(values map[string]interface{}) (err error) {
145+
142146
for key, input := range dp.Inputs {
143147
// If it is a required field, check if the value exists.
144148
value, ok := values[key]
@@ -147,60 +151,60 @@ func (dp *DynamicPayload) Evaluate(values map[string]interface{}) (output map[st
147151
continue
148152
}
149153

150-
return nil, e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, fmt.Sprintf("The '%s' field is required.", key), nil)
154+
return e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, fmt.Sprintf("The '%s' field is required.", key), nil)
151155
}
152156

153-
eval, err := dp.validate(input, value)
157+
err := dp.validate(input, value)
154158
if err != nil {
155-
return nil, err
159+
return err
156160
}
157161

158-
output[key] = eval
159162
}
160163

161-
return output, nil
164+
return nil
162165
}
163166

164-
func (dp *DynamicPayload) validate(input Input, value interface{}) (interface{}, error) {
167+
func (dp *DynamicPayload) validate(input Input, value interface{}) error {
165168
switch input.Type {
166169
case InputTypeSelect:
167170
// Checks if the selected value matches the option,
168171
// and returns the value if it is.
169172
sv, ok := value.(string)
170173
if !ok {
171-
return nil, e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, fmt.Sprintf("The '%v' is not string type.", value), nil)
174+
return e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, fmt.Sprintf("The '%v' is not string type.", value), nil)
172175
}
173176

174177
for _, option := range *input.Options {
175178
if sv == option {
176-
return sv, nil
179+
return nil
177180
}
178181
}
179182

180-
return nil, e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, "The '%s' is not matched with the options.", nil)
183+
return e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, "The '%s' is not matched with the options.", nil)
181184
case InputTypeNumber:
182-
nv, ok := value.(float64)
183-
if !ok {
184-
return nil, e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, fmt.Sprintf("The '%v' is not string type.", value), nil)
185+
if _, ok := value.(float64); ok {
186+
return nil
185187
}
186188

187-
return nv, nil
189+
if _, ok := value.(int); !ok {
190+
return e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, fmt.Sprintf("The '%v' is not number type.", value), nil)
191+
}
192+
193+
return nil
188194
case InputTypeString:
189-
sv, ok := value.(string)
190-
if !ok {
191-
return nil, e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, fmt.Sprintf("The '%v' is not string type.", value), nil)
195+
if _, ok := value.(string); !ok {
196+
return e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, fmt.Sprintf("The '%v' is not string type.", value), nil)
192197
}
193198

194-
return sv, nil
199+
return nil
195200
case InputTypeBoolean:
196-
bv, ok := value.(bool)
197-
if !ok {
198-
return nil, e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, fmt.Sprintf("The '%v' is not string type.", value), nil)
201+
if _, ok := value.(bool); !ok {
202+
return e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, fmt.Sprintf("The '%v' is not string type.", value), nil)
199203
}
200204

201-
return bv, nil
205+
return nil
202206
default:
203-
return nil, e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, "The type must be 'select', 'number', 'string', or 'boolean'.", nil)
207+
return e.NewErrorWithMessage(e.ErrorCodeDeploymentInvalid, "The type must be 'select', 'number', 'string', or 'boolean'.", nil)
204208
}
205209
}
206210

Diff for: model/extent/env_test.go

+87-1
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,90 @@ func TestEnv_IsFreezed(t *testing.T) {
149149
t.Fatalf("IsFreezed = %v, wanted %v", freezed, false)
150150
}
151151
})
152-
}
152+
}
153+
154+
func TestDynamicPayload_Validate(t *testing.T) {
155+
t.Run("Return an error when the required field is not exist.", func(t *testing.T) {
156+
c := DynamicPayload{
157+
Inputs: map[string]Input{
158+
"foo": {
159+
Type: InputTypeString,
160+
Required: pointer.ToBool(true),
161+
},
162+
},
163+
}
164+
165+
err := c.Validate(map[string]interface{}{})
166+
if err == nil {
167+
t.Fatalf("Validate doesn't return an error.")
168+
}
169+
})
170+
171+
t.Run("Skip the optional field if there is no value.", func(t *testing.T) {
172+
c := DynamicPayload{
173+
Inputs: map[string]Input{
174+
"foo": {
175+
Type: InputTypeString,
176+
},
177+
},
178+
}
179+
180+
err := c.Validate(map[string]interface{}{})
181+
if err != nil {
182+
t.Fatalf("Validate return an error: %s", err)
183+
}
184+
})
185+
186+
t.Run("Return an error when the selected value is not in the options.", func(t *testing.T) {
187+
c := DynamicPayload{
188+
Inputs: map[string]Input{
189+
"foo": {
190+
Type: InputTypeSelect,
191+
Required: pointer.ToBool(true),
192+
Options: &[]string{"option1", "option2"},
193+
},
194+
},
195+
}
196+
197+
input := map[string]interface{}{"foo": "value"}
198+
199+
err := c.Validate(input)
200+
if err == nil {
201+
t.Fatalf("Validate doesn't return an error.")
202+
}
203+
})
204+
205+
t.Run("Return nil if validation has succeed.", func(t *testing.T) {
206+
c := DynamicPayload{
207+
Inputs: map[string]Input{
208+
"foo": {
209+
Type: InputTypeSelect,
210+
Required: pointer.ToBool(true),
211+
Options: &[]string{"option1", "option2"},
212+
},
213+
"bar": {
214+
Type: InputTypeNumber,
215+
Required: pointer.ToBool(true),
216+
},
217+
"baz": {
218+
Type: InputTypeNumber,
219+
},
220+
"qux": {
221+
Type: InputTypeBoolean,
222+
},
223+
},
224+
}
225+
226+
input := map[string]interface{}{
227+
"foo": "option1",
228+
"bar": 1,
229+
"baz": 4.2,
230+
"qux": false,
231+
}
232+
233+
err := c.Validate(input)
234+
if err != nil {
235+
t.Fatalf("Evaluate return an error: %s", err)
236+
}
237+
})
238+
}

0 commit comments

Comments
 (0)