Skip to content

Commit

Permalink
Added more validators
Browse files Browse the repository at this point in the history
  • Loading branch information
evg4b authored and Yauheni Abramovich committed Nov 17, 2023
1 parent d1e6f35 commit 22ecb64
Show file tree
Hide file tree
Showing 11 changed files with 405 additions and 33 deletions.
19 changes: 17 additions & 2 deletions internal/config/validators/base/duration.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,27 @@ import (
)

type DurationValidator struct {
Field string
Value time.Duration
Field string
Value time.Duration
AllowZero bool
}

func (d *DurationValidator) IsValid(errors *validate.Errors) {
if d.AllowZero {
d.validateWithZero(errors)
} else {
d.validateWithoutZero(errors)
}
}

func (d *DurationValidator) validateWithoutZero(errors *validate.Errors) {
if d.Value <= 0 {
errors.Add(d.Field, fmt.Sprintf("%s must be greater than 0", d.Field))
}
}

func (d *DurationValidator) validateWithZero(errors *validate.Errors) {
if d.Value < 0 {
errors.Add(d.Field, fmt.Sprintf("%s must be greater than or equal to 0", d.Field))
}
}
45 changes: 30 additions & 15 deletions internal/config/validators/base/duration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,26 @@ func TestDurationValidator(t *testing.T) {

t.Run("should not register errors for", func(t *testing.T) {
tests := []struct {
name string
Value time.Duration
name string
value time.Duration
allowZero bool
}{
{
name: "positive value",
Value: 1 * time.Second,
name: "positive value without allow zero",
value: 1 * time.Second,
},
{
name: "zero value with allow zero",
value: 0,
allowZero: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
errors := validate.Validate(&base.DurationValidator{
Field: field,
Value: tt.Value,
Field: field,
Value: tt.value,
AllowZero: tt.allowZero,
})

assert.False(t, errors.HasAny())
Expand All @@ -38,26 +45,34 @@ func TestDurationValidator(t *testing.T) {

t.Run("should register errors for", func(t *testing.T) {
tests := []struct {
name string
Value time.Duration
error string
name string
value time.Duration
allowZero bool
error string
}{
{
name: "zero value",
Value: 0,
name: "negative value without allow zero",
value: -1 * time.Second,
error: "test-field must be greater than 0",
},
{
name: "negative value",
Value: -1 * time.Second,
name: "zero value without allow zero",
value: 0,
error: "test-field must be greater than 0",
},
{
name: "negative value with allow zero",
value: -1 * time.Second,
error: "test-field must be greater than or equal to 0",
allowZero: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
errors := validate.Validate(&base.DurationValidator{
Field: field,
Value: test.Value,
Field: field,
Value: test.value,
AllowZero: test.allowZero,
})

require.EqualError(t, errors, test.error)
Expand Down
10 changes: 4 additions & 6 deletions internal/config/validators/base/port_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import (
"testing"

"github.com/evg4b/uncors/internal/config/validators/base"

"github.com/stretchr/testify/require"

v "github.com/gobuffalo/validate"
"github.com/gobuffalo/validate"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestIsValid(t *testing.T) {
Expand All @@ -18,7 +16,7 @@ func TestIsValid(t *testing.T) {
t.Run("valid port", func(t *testing.T) {
for _, port := range []int{1, 443, 65535} {
t.Run(fmt.Sprintf("port %d", port), func(t *testing.T) {
errors := v.Validate(&base.PortValidator{
errors := validate.Validate(&base.PortValidator{
Field: field,
Value: port,
})
Expand All @@ -31,7 +29,7 @@ func TestIsValid(t *testing.T) {
t.Run("invalid port", func(t *testing.T) {
for _, port := range []int{-5, 0, 70000} {
t.Run(fmt.Sprintf("port %d", port), func(t *testing.T) {
errors := v.Validate(&base.PortValidator{
errors := validate.Validate(&base.PortValidator{
Field: field,
Value: port,
})
Expand Down
9 changes: 6 additions & 3 deletions internal/config/validators/mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ import (
"github.com/evg4b/uncors/internal/config"
"github.com/evg4b/uncors/internal/config/validators/base"
"github.com/gobuffalo/validate"
"github.com/spf13/afero"
)

type MappingValidator struct {
Field string
Value config.Mapping
Fs afero.Fs
}

func (m *MappingValidator) IsValid(errors *validate.Errors) {
errors.Append(validate.Validate(
&base.HostValidator{Field: "from", Value: m.Value.From},
&base.HostValidator{Field: "to", Value: m.Value.To},
&base.HostValidator{Field: joinPath(m.Field, "from"), Value: m.Value.From},
&base.HostValidator{Field: joinPath(m.Field, "to"), Value: m.Value.To},
))

for i, static := range m.Value.Statics {
Expand All @@ -28,12 +30,13 @@ func (m *MappingValidator) IsValid(errors *validate.Errors) {
errors.Append(validate.Validate(&MockValidator{
Field: joinPath(m.Field, "mocks", index(i)),
Value: mock,
Fs: m.Fs,
}))
}

for i, cache := range m.Value.Cache {
errors.Append(validate.Validate(&CacheValidator{
Field: joinPath(m.Field, cache, index(i)),
Field: joinPath(m.Field, "cache", index(i)),
Value: cache,
}))
}
Expand Down
176 changes: 176 additions & 0 deletions internal/config/validators/mapping_test.go
Original file line number Diff line number Diff line change
@@ -1 +1,177 @@
package validators_test

import (
"net/http"
"testing"

"github.com/stretchr/testify/require"

"github.com/evg4b/uncors/internal/config"
"github.com/evg4b/uncors/internal/config/validators"
"github.com/evg4b/uncors/testing/testutils"
"github.com/gobuffalo/validate"
"github.com/stretchr/testify/assert"
)

func TestMappingValidator_IsValid(t *testing.T) {
const field = "mapping"

t.Run("should not register errors for", func(t *testing.T) {
fs := testutils.FsFromMap(t, map[string]string{
"/tmp/demo.json": "{}",
})

tests := []struct {
name string
value config.Mapping
}{
{
name: "full filled mapping",
value: config.Mapping{
From: "localhost",
To: "github.com",
Statics: []config.StaticDirectory{
{Path: "/", Dir: "/tmp"},
{Path: "/", Dir: "/tmp"},
},
Mocks: []config.Mock{
{
Path: "/api/info",
Method: http.MethodGet,
Response: config.Response{
Code: 200,
Raw: "test",
},
},
{
Path: "/api/info/demo",
Method: http.MethodGet,
Response: config.Response{
Code: 300,
File: "/tmp/demo.json",
},
},
},
Cache: config.CacheGlobs{
"/api/info",
"/**",
},
},
},
{
name: "mapping without mocks and statics and caches",
value: config.Mapping{
From: "localhost",
To: "github.com",
Statics: []config.StaticDirectory{},
Mocks: []config.Mock{},
Cache: config.CacheGlobs{},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
errors := validate.Validate(&validators.MappingValidator{
Field: field,
Value: test.value,
Fs: fs,
})

assert.False(t, errors.HasAny())
})
}
})

t.Run("should register errors for", func(t *testing.T) {
fs := testutils.FsFromMap(t, map[string]string{
"/tmp/demo.json": "{}",
})

tests := []struct {
name string
value config.Mapping
error string
}{
{
name: "mapping without from",
value: config.Mapping{
From: "",
To: "github.com",
Statics: []config.StaticDirectory{},
Mocks: []config.Mock{},
Cache: config.CacheGlobs{},
},
error: "mapping.from must not be empty",
},
{
name: "mapping without to",
value: config.Mapping{
From: "localhost",
To: "",
Statics: []config.StaticDirectory{},
Mocks: []config.Mock{},
Cache: config.CacheGlobs{},
},
error: "mapping.to must not be empty",
},
{
name: "mapping with invalid statics",
value: config.Mapping{
From: "localhost",
To: "github.com",
Statics: []config.StaticDirectory{
{Path: "/", Dir: "/tmp"},
{Path: "/", Dir: ""},
},
Mocks: []config.Mock{},
Cache: config.CacheGlobs{},
},
error: "mapping.statics[1].directory must not be empty",
},
{
name: "mapping with invalid mocks",
value: config.Mapping{
From: "localhost",
To: "github.com",
Statics: []config.StaticDirectory{},
Mocks: []config.Mock{
{
Path: "/api/info",
Method: "invalid",
Response: config.Response{
Code: 200,
Raw: "test",
},
},
},
Cache: config.CacheGlobs{},
},
error: "mapping.mocks[0].method must be one of GET, HEAD, POST, PUT, PATCH, DELETE, CONNECT, OPTIONS, TRACE",
},
{
name: "mapping with invalid mocks",
value: config.Mapping{
From: "localhost",
To: "github.com",
Statics: []config.StaticDirectory{},
Mocks: []config.Mock{},
Cache: config.CacheGlobs{
"/api/info[",
},
},
error: "mapping.cache[0] is not a valid glob pattern",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
errors := validate.Validate(&validators.MappingValidator{
Field: field,
Value: test.value,
Fs: fs,
})

require.EqualError(t, errors, test.error)
})
}
})
}
3 changes: 3 additions & 0 deletions internal/config/validators/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import (
"github.com/evg4b/uncors/internal/config"
"github.com/evg4b/uncors/internal/config/validators/base"
"github.com/gobuffalo/validate"
"github.com/spf13/afero"
)

type MockValidator struct {
Field string
Value config.Mock
Fs afero.Fs
}

func (m *MockValidator) IsValid(errors *validate.Errors) {
Expand All @@ -25,6 +27,7 @@ func (m *MockValidator) IsValid(errors *validate.Errors) {
&ResponseValidator{
Field: joinPath(m.Field, "response"),
Value: m.Value.Response,
Fs: m.Fs,
},
))
}
Loading

0 comments on commit 22ecb64

Please sign in to comment.