From 0a7954b300cf5f8ab447238514ff83338b870d34 Mon Sep 17 00:00:00 2001 From: ashmrtn Date: Mon, 12 Sep 2022 14:10:02 -0700 Subject: [PATCH] Simplify exchange path constructors (#819) Allows constructing Contacts and Events category type paths for Exchange. They all need user and tenant filled in and only differ in the category given. This makes it easier to call them in more generic situations, so long as the category is known. It also consolidates code for constructing the paths of those types. --- src/internal/path/path.go | 41 ++---- src/internal/path/resource_path_test.go | 173 ++++++++++++++---------- 2 files changed, 118 insertions(+), 96 deletions(-) diff --git a/src/internal/path/path.go b/src/internal/path/path.go index d70f854b1..5f51facaf 100644 --- a/src/internal/path/path.go +++ b/src/internal/path/path.go @@ -176,28 +176,6 @@ func (pb Builder) withPrefix(elements ...string) *Builder { return res } -// ToDataLayerExchangeMailFolder returns a Path for an Exchange mail folder or item -// resource with information useful to the data layer. This includes prefix -// elements of the path such as the tenant ID, user ID, service, and service -// category. -func (pb Builder) ToDataLayerExchangeMailPath(tenant, user string, isItem bool) (Path, error) { - if err := pb.verifyPrefix(tenant, user); err != nil { - return nil, err - } - - return &dataLayerResourcePath{ - Builder: *pb.withPrefix( - tenant, - ExchangeService.String(), - user, - EmailCategory.String(), - ), - service: ExchangeService, - category: EmailCategory, - hasItem: isItem, - }, nil -} - func (pb Builder) ToDataLayerExchangePathForCategory( tenant, user string, category CategoryType, @@ -207,12 +185,21 @@ func (pb Builder) ToDataLayerExchangePathForCategory( return nil, err } - switch category { - case EmailCategory: - return pb.ToDataLayerExchangeMailPath(tenant, user, isItem) - default: - return nil, errors.New("not implemented") + if err := pb.verifyPrefix(tenant, user); err != nil { + return nil, err } + + return &dataLayerResourcePath{ + Builder: *pb.withPrefix( + tenant, + ExchangeService.String(), + user, + category.String(), + ), + service: ExchangeService, + category: category, + hasItem: isItem, + }, nil } // FromDataLayerPath parses the escaped path p, validates the elements in p diff --git a/src/internal/path/resource_path_test.go b/src/internal/path/resource_path_test.go index bd15f6d3b..56d9317f2 100644 --- a/src/internal/path/resource_path_test.go +++ b/src/internal/path/resource_path_test.go @@ -48,28 +48,41 @@ var ( } modes = []struct { - name string - isItem bool - expectedFolder string - expectedItem string - expectedService path.ServiceType - expectedCategory path.CategoryType + name string + isItem bool + expectedFolder string + expectedItem string }{ { - name: "ExchangeMailFolder", - isItem: false, - expectedFolder: strings.Join(rest, "/"), - expectedItem: "", - expectedService: path.ExchangeService, - expectedCategory: path.EmailCategory, + name: "Folder", + isItem: false, + expectedFolder: strings.Join(rest, "/"), + expectedItem: "", }, { - name: "ExchangeMailItem", - isItem: true, - expectedFolder: strings.Join(rest[0:len(rest)-1], "/"), - expectedItem: rest[len(rest)-1], - expectedService: path.ExchangeService, - expectedCategory: path.EmailCategory, + name: "Item", + isItem: true, + expectedFolder: strings.Join(rest[0:len(rest)-1], "/"), + expectedItem: rest[len(rest)-1], + }, + } + + // Set of acceptable service/category mixtures for exchange. + exchangeServiceCategories = []struct { + service path.ServiceType + category path.CategoryType + }{ + { + service: path.ExchangeService, + category: path.EmailCategory, + }, + { + service: path.ExchangeService, + category: path.ContactsCategory, + }, + { + service: path.ExchangeService, + category: path.EventsCategory, }, } ) @@ -83,14 +96,23 @@ func TestDataLayerResourcePath(t *testing.T) { } func (suite *DataLayerResourcePath) TestMissingInfoErrors() { - for _, m := range modes { - suite.T().Run(m.name, func(tOuter *testing.T) { - for _, test := range missingInfo { - tOuter.Run(test.name, func(t *testing.T) { - b := path.Builder{}.Append(test.rest...) + for _, types := range exchangeServiceCategories { + suite.T().Run(types.service.String()+types.category.String(), func(t1 *testing.T) { + for _, m := range modes { + t1.Run(m.name, func(t2 *testing.T) { + for _, test := range missingInfo { + t2.Run(test.name, func(t *testing.T) { + b := path.Builder{}.Append(test.rest...) - _, err := b.ToDataLayerExchangeMailPath(test.tenant, test.user, m.isItem) - assert.Error(t, err) + _, err := b.ToDataLayerExchangePathForCategory( + test.tenant, + test.user, + types.category, + m.isItem, + ) + assert.Error(t, err) + }) + } }) } }) @@ -98,31 +120,27 @@ func (suite *DataLayerResourcePath) TestMissingInfoErrors() { } func (suite *DataLayerResourcePath) TestMailItemNoFolder() { - t := suite.T() item := "item" b := path.Builder{}.Append(item) - p, err := b.ToDataLayerExchangeMailPath(testTenant, testUser, true) - require.NoError(t, err) + for _, types := range exchangeServiceCategories { + suite.T().Run(types.service.String()+types.category.String(), func(t *testing.T) { + p, err := b.ToDataLayerExchangePathForCategory( + testTenant, + testUser, + types.category, + true, + ) + require.NoError(t, err) - assert.Empty(t, p.Folder()) - assert.Equal(t, item, p.Item()) + assert.Empty(t, p.Folder()) + assert.Equal(t, item, p.Item()) + }) + } } -type PopulatedDataLayerResourcePath struct { - suite.Suite - b *path.Builder -} - -func TestPopulatedDataLayerResourcePath(t *testing.T) { - suite.Run(t, new(PopulatedDataLayerResourcePath)) -} - -func (suite *PopulatedDataLayerResourcePath) SetupSuite() { - suite.b = path.Builder{}.Append(rest...) -} - -func (suite *PopulatedDataLayerResourcePath) TestToExchangeMailPathForCategory() { +func (suite *DataLayerResourcePath) TestToExchangePathForCategory() { + b := path.Builder{}.Append(rest...) table := []struct { category path.CategoryType check assert.ErrorAssertionFunc @@ -139,13 +157,21 @@ func (suite *PopulatedDataLayerResourcePath) TestToExchangeMailPathForCategory() category: path.EmailCategory, check: assert.NoError, }, + { + category: path.ContactsCategory, + check: assert.NoError, + }, + { + category: path.EventsCategory, + 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( + p, err := b.ToDataLayerExchangePathForCategory( testTenant, testUser, test.category, @@ -170,13 +196,37 @@ func (suite *PopulatedDataLayerResourcePath) TestToExchangeMailPathForCategory() } } +type PopulatedDataLayerResourcePath struct { + suite.Suite + // Bool value is whether the path is an item path or a folder path. + paths map[bool]path.Path +} + +func TestPopulatedDataLayerResourcePath(t *testing.T) { + suite.Run(t, new(PopulatedDataLayerResourcePath)) +} + +func (suite *PopulatedDataLayerResourcePath) SetupSuite() { + suite.paths = make(map[bool]path.Path, 2) + base := path.Builder{}.Append(rest...) + + for _, t := range []bool{true, false} { + p, err := base.ToDataLayerExchangePathForCategory( + testTenant, + testUser, + path.EmailCategory, + t, + ) + require.NoError(suite.T(), err) + + suite.paths[t] = p + } +} + func (suite *PopulatedDataLayerResourcePath) TestTenant() { for _, m := range modes { suite.T().Run(m.name, func(t *testing.T) { - p, err := suite.b.ToDataLayerExchangeMailPath(testTenant, testUser, m.isItem) - require.NoError(t, err) - - assert.Equal(t, testTenant, p.Tenant()) + assert.Equal(t, testTenant, suite.paths[m.isItem].Tenant()) }) } } @@ -184,10 +234,7 @@ func (suite *PopulatedDataLayerResourcePath) TestTenant() { func (suite *PopulatedDataLayerResourcePath) TestService() { for _, m := range modes { suite.T().Run(m.name, func(t *testing.T) { - p, err := suite.b.ToDataLayerExchangeMailPath(testTenant, testUser, m.isItem) - require.NoError(t, err) - - assert.Equal(t, m.expectedService, p.Service()) + assert.Equal(t, path.ExchangeService, suite.paths[m.isItem].Service()) }) } } @@ -195,10 +242,7 @@ func (suite *PopulatedDataLayerResourcePath) TestService() { func (suite *PopulatedDataLayerResourcePath) TestCategory() { for _, m := range modes { suite.T().Run(m.name, func(t *testing.T) { - p, err := suite.b.ToDataLayerExchangeMailPath(testTenant, testUser, m.isItem) - require.NoError(t, err) - - assert.Equal(t, m.expectedCategory, p.Category()) + assert.Equal(t, path.EmailCategory, suite.paths[m.isItem].Category()) }) } } @@ -206,10 +250,7 @@ func (suite *PopulatedDataLayerResourcePath) TestCategory() { func (suite *PopulatedDataLayerResourcePath) TestResourceOwner() { for _, m := range modes { suite.T().Run(m.name, func(t *testing.T) { - p, err := suite.b.ToDataLayerExchangeMailPath(testTenant, testUser, m.isItem) - require.NoError(t, err) - - assert.Equal(t, testUser, p.ResourceOwner()) + assert.Equal(t, testUser, suite.paths[m.isItem].ResourceOwner()) }) } } @@ -217,10 +258,7 @@ func (suite *PopulatedDataLayerResourcePath) TestResourceOwner() { func (suite *PopulatedDataLayerResourcePath) TestFolder() { for _, m := range modes { suite.T().Run(m.name, func(t *testing.T) { - p, err := suite.b.ToDataLayerExchangeMailPath(testTenant, testUser, m.isItem) - require.NoError(t, err) - - assert.Equal(t, m.expectedFolder, p.Folder()) + assert.Equal(t, m.expectedFolder, suite.paths[m.isItem].Folder()) }) } } @@ -228,10 +266,7 @@ func (suite *PopulatedDataLayerResourcePath) TestFolder() { func (suite *PopulatedDataLayerResourcePath) TestItem() { for _, m := range modes { suite.T().Run(m.name, func(t *testing.T) { - p, err := suite.b.ToDataLayerExchangeMailPath(testTenant, testUser, m.isItem) - require.NoError(t, err) - - assert.Equal(t, m.expectedItem, p.Item()) + assert.Equal(t, m.expectedItem, suite.paths[m.isItem].Item()) }) } }