Logic to validate service/category pairs for paths (#689)
* Logic to validate service/category pairs for paths * convert string to service or category const * check that a given service/category pair is a valid resource type * Add basic tests for validateServiceAndCategory
This commit is contained in:
parent
d1bf2b90a6
commit
34697efbeb
@ -1,5 +1,11 @@
|
||||
package path
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const unknownServiceCombination = "unknown service/category combination %q/%q"
|
||||
|
||||
type ServiceType int
|
||||
|
||||
//go:generate stringer -type=ServiceType -linecomment
|
||||
@ -8,6 +14,15 @@ const (
|
||||
ExchangeService // exchange
|
||||
)
|
||||
|
||||
func toServiceType(service string) ServiceType {
|
||||
switch service {
|
||||
case ExchangeService.String():
|
||||
return ExchangeService
|
||||
default:
|
||||
return UnknownService
|
||||
}
|
||||
}
|
||||
|
||||
type CategoryType int
|
||||
|
||||
//go:generate stringer -type=CategoryType -linecomment
|
||||
@ -16,6 +31,47 @@ const (
|
||||
EmailCategory // email
|
||||
)
|
||||
|
||||
func toCategoryType(category string) CategoryType {
|
||||
switch category {
|
||||
case EmailCategory.String():
|
||||
return EmailCategory
|
||||
default:
|
||||
return UnknownCategory
|
||||
}
|
||||
}
|
||||
|
||||
// serviceCategories is a mapping of all valid service/category pairs.
|
||||
var serviceCategories = map[ServiceType]map[CategoryType]struct{}{
|
||||
ExchangeService: {
|
||||
EmailCategory: {},
|
||||
},
|
||||
}
|
||||
|
||||
func validateServiceAndCategory(s, c string) (ServiceType, CategoryType, error) {
|
||||
// Validity of service checked on first-level lookup to serviceCategories.
|
||||
service := toServiceType(s)
|
||||
|
||||
category := toCategoryType(c)
|
||||
if category == UnknownCategory {
|
||||
return UnknownService, UnknownCategory, errors.Errorf("unknown category string %q", c)
|
||||
}
|
||||
|
||||
cats, ok := serviceCategories[service]
|
||||
if !ok {
|
||||
return UnknownService, UnknownCategory, errors.Errorf("unknown service string %q", s)
|
||||
}
|
||||
|
||||
if _, ok := cats[category]; !ok {
|
||||
return UnknownService, UnknownCategory, errors.Errorf(
|
||||
unknownServiceCombination,
|
||||
service,
|
||||
category,
|
||||
)
|
||||
}
|
||||
|
||||
return service, category, nil
|
||||
}
|
||||
|
||||
// dataLayerResourcePath allows callers to extract information from a
|
||||
// resource-specific path. This struct is unexported so that callers are
|
||||
// forced to use the pre-defined constructors, making it impossible to create a
|
||||
|
||||
98
src/internal/path/service_category_test.go
Normal file
98
src/internal/path/service_category_test.go
Normal file
@ -0,0 +1,98 @@
|
||||
package path
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type ServiceCategoryUnitSuite struct {
|
||||
suite.Suite
|
||||
}
|
||||
|
||||
func TestServiceCategoryUnitSuite(t *testing.T) {
|
||||
suite.Run(t, new(ServiceCategoryUnitSuite))
|
||||
}
|
||||
|
||||
func (suite *ServiceCategoryUnitSuite) TestValidateServiceAndCategoryBadStringErrors() {
|
||||
table := []struct {
|
||||
name string
|
||||
service string
|
||||
category string
|
||||
}{
|
||||
{
|
||||
name: "Service",
|
||||
service: "foo",
|
||||
category: EmailCategory.String(),
|
||||
},
|
||||
{
|
||||
name: "Category",
|
||||
service: ExchangeService.String(),
|
||||
category: "foo",
|
||||
},
|
||||
}
|
||||
for _, test := range table {
|
||||
suite.T().Run(test.name, func(t *testing.T) {
|
||||
_, _, err := validateServiceAndCategory(test.service, test.category)
|
||||
assert.Error(suite.T(), err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *ServiceCategoryUnitSuite) TestValidateServiceAndCategory() {
|
||||
table := []struct {
|
||||
name string
|
||||
service string
|
||||
category string
|
||||
expectedService ServiceType
|
||||
expectedCategory CategoryType
|
||||
check assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "UnknownService",
|
||||
service: UnknownService.String(),
|
||||
category: EmailCategory.String(),
|
||||
check: assert.Error,
|
||||
},
|
||||
{
|
||||
name: "UnknownCategory",
|
||||
service: ExchangeService.String(),
|
||||
category: UnknownCategory.String(),
|
||||
check: assert.Error,
|
||||
},
|
||||
{
|
||||
name: "BadServiceString",
|
||||
service: "foo",
|
||||
category: EmailCategory.String(),
|
||||
check: assert.Error,
|
||||
},
|
||||
{
|
||||
name: "BadCategoryString",
|
||||
service: ExchangeService.String(),
|
||||
category: "foo",
|
||||
check: assert.Error,
|
||||
},
|
||||
{
|
||||
name: "ExchangeEmail",
|
||||
service: ExchangeService.String(),
|
||||
category: EmailCategory.String(),
|
||||
expectedService: ExchangeService,
|
||||
expectedCategory: EmailCategory,
|
||||
check: assert.NoError,
|
||||
},
|
||||
}
|
||||
for _, test := range table {
|
||||
suite.T().Run(test.name, func(t *testing.T) {
|
||||
s, c, err := validateServiceAndCategory(test.service, test.category)
|
||||
test.check(t, err)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(t, test.expectedService, s)
|
||||
assert.Equal(t, test.expectedCategory, c)
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user