From 897a21ef0bbb3b987b30f18362086e3bae753e10 Mon Sep 17 00:00:00 2001 From: ashmrtn <3891298+ashmrtn@users.noreply.github.com> Date: Fri, 2 Sep 2022 13:18:05 -0700 Subject: [PATCH] Add path constructor that takes a category (#743) ## Description Will be useful for parts of graph connector code that are abstracted to take a category and return collections. Does not work for exchange events or contacts yet as those paths haven't been defined. ## Type of change Please check the type of change your PR introduces: - [x] :sunflower: Feature - [ ] :bug: Bugfix - [ ] :world_map: Documentation - [ ] :robot: Test - [ ] :hamster: Trivial/Minor ## Issue(s) part of: * #671 * #456 ## Test Plan - [ ] :muscle: Manual - [x] :zap: Unit test - [ ] :green_heart: E2E --- src/internal/path/path.go | 19 ++++++++- src/internal/path/resource_path.go | 24 +++++++---- src/internal/path/resource_path_test.go | 48 ++++++++++++++++++++++ src/internal/path/service_category_test.go | 4 +- 4 files changed, 84 insertions(+), 11 deletions(-) diff --git a/src/internal/path/path.go b/src/internal/path/path.go index 276d84ed3..d70f854b1 100644 --- a/src/internal/path/path.go +++ b/src/internal/path/path.go @@ -198,6 +198,23 @@ func (pb Builder) ToDataLayerExchangeMailPath(tenant, user string, isItem bool) }, nil } +func (pb Builder) ToDataLayerExchangePathForCategory( + tenant, user string, + category CategoryType, + isItem bool, +) (Path, error) { + if err := validateServiceAndCategory(ExchangeService, category); err != nil { + return nil, err + } + + switch category { + case EmailCategory: + return pb.ToDataLayerExchangeMailPath(tenant, user, isItem) + default: + return nil, errors.New("not implemented") + } +} + // FromDataLayerPath parses the escaped path p, validates the elements in p // match a resource-specific path format, and returns a Path struct for that // resource-specific type. If p does not match any resource-specific paths or @@ -219,7 +236,7 @@ func FromDataLayerPath(p string, isItem bool) (Path, error) { return nil, errors.Errorf("path has too few segments: %s", p) } - service, category, err := validateServiceAndCategory( + service, category, err := validateServiceAndCategoryStrings( pb.elements[1], pb.elements[3], ) diff --git a/src/internal/path/resource_path.go b/src/internal/path/resource_path.go index 3539414fb..4af5371f4 100644 --- a/src/internal/path/resource_path.go +++ b/src/internal/path/resource_path.go @@ -4,8 +4,6 @@ import ( "github.com/pkg/errors" ) -const unknownServiceCombination = "unknown service/category combination %q/%q" - type ServiceType int //go:generate stringer -type=ServiceType -linecomment @@ -55,29 +53,39 @@ var serviceCategories = map[ServiceType]map[CategoryType]struct{}{ }, } -func validateServiceAndCategory(s, c string) (ServiceType, CategoryType, error) { - // Validity of service checked on first-level lookup to serviceCategories. +func validateServiceAndCategoryStrings(s, c string) (ServiceType, CategoryType, error) { service := toServiceType(s) + if service == UnknownService { + return UnknownService, UnknownCategory, errors.Errorf("unknown service string %q", s) + } category := ToCategoryType(c) if category == UnknownCategory { return UnknownService, UnknownCategory, errors.Errorf("unknown category string %q", c) } + if err := validateServiceAndCategory(service, category); err != nil { + return UnknownService, UnknownCategory, err + } + + return service, category, nil +} + +func validateServiceAndCategory(service ServiceType, category CategoryType) error { cats, ok := serviceCategories[service] if !ok { - return UnknownService, UnknownCategory, errors.Errorf("unknown service string %q", s) + return errors.New("unsupported service") } if _, ok := cats[category]; !ok { - return UnknownService, UnknownCategory, errors.Errorf( - unknownServiceCombination, + return errors.Errorf( + "unknown service/category combination %q/%q", service, category, ) } - return service, category, nil + return nil } // dataLayerResourcePath allows callers to extract information from a diff --git a/src/internal/path/resource_path_test.go b/src/internal/path/resource_path_test.go index a77e5745c..d28a9c4d0 100644 --- a/src/internal/path/resource_path_test.go +++ b/src/internal/path/resource_path_test.go @@ -122,6 +122,54 @@ func (suite *PopulatedDataLayerResourcePath) SetupSuite() { suite.b = path.Builder{}.Append(rest...) } +func (suite *PopulatedDataLayerResourcePath) TestToExchangeMailPathForCategory() { + table := []struct { + category path.CategoryType + check assert.ErrorAssertionFunc + }{ + { + category: path.UnknownCategory, + check: assert.Error, + }, + { + category: path.CategoryType(-1), + check: assert.Error, + }, + { + category: path.EmailCategory, + check: assert.NoError, + }, + } + + for _, m := range modes { + suite.T().Run(m.name, func(t1 *testing.T) { + for _, test := range table { + t1.Run(test.category.String(), func(t *testing.T) { + p, err := suite.b.ToDataLayerExchangePathForCategory( + testTenant, + testUser, + test.category, + m.isItem, + ) + + test.check(t, err) + + if err != nil { + return + } + + assert.Equal(t, testTenant, p.Tenant()) + assert.Equal(t, path.ExchangeService, p.Service()) + assert.Equal(t, test.category, p.Category()) + assert.Equal(t, testUser, p.ResourceOwner()) + assert.Equal(t, m.expectedFolder, p.Folder()) + assert.Equal(t, m.expectedItem, p.Item()) + }) + } + }) + } +} + func (suite *PopulatedDataLayerResourcePath) TestTenant() { for _, m := range modes { suite.T().Run(m.name, func(t *testing.T) { diff --git a/src/internal/path/service_category_test.go b/src/internal/path/service_category_test.go index bc798cdce..6862bdb32 100644 --- a/src/internal/path/service_category_test.go +++ b/src/internal/path/service_category_test.go @@ -34,7 +34,7 @@ func (suite *ServiceCategoryUnitSuite) TestValidateServiceAndCategoryBadStringEr } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { - _, _, err := validateServiceAndCategory(test.service, test.category) + _, _, err := validateServiceAndCategoryStrings(test.service, test.category) assert.Error(suite.T(), err) }) } @@ -100,7 +100,7 @@ func (suite *ServiceCategoryUnitSuite) TestValidateServiceAndCategory() { } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { - s, c, err := validateServiceAndCategory(test.service, test.category) + s, c, err := validateServiceAndCategoryStrings(test.service, test.category) test.check(t, err) if err != nil {