Skip to content

Commit

Permalink
fix(configuration): Validate the valuable object when decode it to lo…
Browse files Browse the repository at this point in the history
…okup env variable (#54)
  • Loading branch information
42atomys authored Mar 13, 2022
1 parent 898c5eb commit 84d93fc
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 6 deletions.
27 changes: 23 additions & 4 deletions internal/valuable/valuable.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,50 @@ type ValueFromSource struct {
EnvRef *string `json:"envRef,omitempty"`
}

// Validate validates the Valuable object and returns an error if any
// validation fails. In case of envRef, the env variable must exist.
func (v *Valuable) Validate() error {
if v.ValueFrom != nil && v.ValueFrom.EnvRef != nil {
if _, ok := os.LookupEnv(*v.ValueFrom.EnvRef); !ok {
return fmt.Errorf("enviroment variable %s not found", *v.ValueFrom.EnvRef)
}
}

return nil
}

// SerializeValuable serialize anything to a Valuable
// @param data is the data to serialize
// @return the serialized Valuable
func SerializeValuable(data interface{}) (*Valuable, error) {
var v *Valuable = &Valuable{}
switch t := data.(type) {
case string:
return &Valuable{Value: &t}, nil
v.Value = &t
case int, float32, float64, bool:
str := fmt.Sprint(t)
return &Valuable{Value: &str}, nil
v.Value = &str
case nil:
return &Valuable{}, nil
case map[interface{}]interface{}:
var val *Valuable
if err := mapstructure.Decode(data, &val); err != nil {
return nil, err
}
return val, nil
v = val
default:
valuable := Valuable{}
if err := mapstructure.Decode(data, &valuable); err != nil {
return nil, fmt.Errorf("unimplemented valuable type %s", reflect.TypeOf(data).String())
}
return &valuable, nil
v = &valuable
}

if err := v.Validate(); err != nil {
return nil, err
}

return v, nil
}

// Get returns all values of the Valuable as a slice
Expand Down
25 changes: 25 additions & 0 deletions internal/valuable/valuable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,31 @@ func (suite *TestSuiteValuable) BeforeTest(suiteName, testName string) {
os.Setenv(suite.testEnvName, suite.testValue)
}

func (suite *TestSuiteValuable) TestValidate() {
assert := assert.New(suite.T())

tests := []struct {
name string
input *Valuable
wantErr bool
}{
{"a basic value", &Valuable{Value: &suite.testValue}, false},
{"a basic list of values", &Valuable{Values: suite.testValues}, false},
{"a basic value with a basic list", &Valuable{Value: &suite.testValue, Values: suite.testValues}, false},
{"an empty valueFrom", &Valuable{ValueFrom: &ValueFromSource{}}, false},
{"an environment ref with invalid name", &Valuable{ValueFrom: &ValueFromSource{EnvRef: &suite.testInvalidEnvName}}, true},
{"an environment ref with valid name", &Valuable{ValueFrom: &ValueFromSource{EnvRef: &suite.testEnvName}}, false},
}

for _, test := range tests {
err := test.input.Validate()
if test.wantErr && assert.Error(err, "this test must be crash %s", err) {
} else {
assert.NoError(err, "cannot validate test %s", test.name)
}
}
}

func (suite *TestSuiteValuable) TestSerializeValuable() {
assert := assert.New(suite.T())

Expand Down
6 changes: 5 additions & 1 deletion pkg/factory/mapstructure_decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ func DecodeHook(f reflect.Type, t reflect.Type, data interface{}) (interface{},
}
}

if err != nil {
return nil, err
}

return &InputConfig{
Valuable: *v,
Name: name,
}, err
}, nil
}
2 changes: 1 addition & 1 deletion tests/webhooks.tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ specs:
value: '{{ Outputs.header.value }}'
- name: second
valueFrom:
envRef: SECRET_TOKEN
staticRef: test
storage: []

0 comments on commit 84d93fc

Please sign in to comment.