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:
ashmrtn 2022-08-30 16:23:55 -07:00 committed by GitHub
parent d1bf2b90a6
commit 34697efbeb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 154 additions and 0 deletions

View File

@ -1,5 +1,11 @@
package path package path
import (
"github.com/pkg/errors"
)
const unknownServiceCombination = "unknown service/category combination %q/%q"
type ServiceType int type ServiceType int
//go:generate stringer -type=ServiceType -linecomment //go:generate stringer -type=ServiceType -linecomment
@ -8,6 +14,15 @@ const (
ExchangeService // exchange ExchangeService // exchange
) )
func toServiceType(service string) ServiceType {
switch service {
case ExchangeService.String():
return ExchangeService
default:
return UnknownService
}
}
type CategoryType int type CategoryType int
//go:generate stringer -type=CategoryType -linecomment //go:generate stringer -type=CategoryType -linecomment
@ -16,6 +31,47 @@ const (
EmailCategory // email 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 // dataLayerResourcePath allows callers to extract information from a
// resource-specific path. This struct is unexported so that callers are // resource-specific path. This struct is unexported so that callers are
// forced to use the pre-defined constructors, making it impossible to create a // forced to use the pre-defined constructors, making it impossible to create a

View 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)
})
}
}