return path service and resource

Returns the path interface funcs for Service and Resource,
this time as "primaryFoo" funcs, to indicate that these are the
primary service and resource values.  This functionality is
mostly for quality of life.
This commit is contained in:
ryanfkeepers 2023-08-15 15:59:09 -06:00
parent 3d15a0d649
commit f5400f9e31
6 changed files with 393 additions and 188 deletions

View File

@ -724,8 +724,10 @@ func TestKopiaIntegrationSuite(t *testing.T) {
func (suite *KopiaIntegrationSuite) SetupSuite() {
tmp, err := path.Build(
testTenant,
testUser,
path.ExchangeService,
[]path.ServiceResource{{
ProtectedResource: testUser,
Service: path.ExchangeService,
}},
path.EmailCategory,
false,
testInboxDir)
@ -736,8 +738,10 @@ func (suite *KopiaIntegrationSuite) SetupSuite() {
tmp, err = path.Build(
testTenant,
testUser,
path.ExchangeService,
[]path.ServiceResource{{
ProtectedResource: testUser,
Service: path.ExchangeService,
}},
path.EmailCategory,
false,
testArchiveDir)
@ -804,14 +808,14 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections() {
reasons := []identity.Reasoner{
NewReason(
testTenant,
suite.storePath1.ResourceOwner(),
suite.storePath1.Service(),
suite.storePath1.PrimaryProtectedResource(),
suite.storePath1.PrimaryService(),
suite.storePath1.Category(),
),
NewReason(
testTenant,
suite.storePath2.ResourceOwner(),
suite.storePath2.Service(),
suite.storePath2.PrimaryProtectedResource(),
suite.storePath2.PrimaryService(),
suite.storePath2.Category(),
),
}
@ -1052,8 +1056,10 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections() {
func (suite *KopiaIntegrationSuite) TestBackupCollections_NoDetailsForMeta() {
tmp, err := path.Build(
testTenant,
testUser,
path.OneDriveService,
[]path.ServiceResource{{
ProtectedResource: testUser,
Service: path.OneDriveService,
}},
path.FilesCategory,
false,
testInboxDir)
@ -1079,8 +1085,8 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections_NoDetailsForMeta() {
reasons := []identity.Reasoner{
NewReason(
testTenant,
storePath.ResourceOwner(),
storePath.Service(),
storePath.PrimaryProtectedResource(),
storePath.PrimaryService(),
storePath.Category()),
}
@ -1507,8 +1513,10 @@ func TestKopiaSimpleRepoIntegrationSuite(t *testing.T) {
func (suite *KopiaSimpleRepoIntegrationSuite) SetupSuite() {
tmp, err := path.Build(
testTenant,
testUser,
path.ExchangeService,
[]path.ServiceResource{{
ProtectedResource: testUser,
Service: path.ExchangeService,
}},
path.EmailCategory,
false,
testInboxDir)
@ -1518,8 +1526,10 @@ func (suite *KopiaSimpleRepoIntegrationSuite) SetupSuite() {
tmp, err = path.Build(
testTenant,
testUser,
path.ExchangeService,
[]path.ServiceResource{{
ProtectedResource: testUser,
Service: path.ExchangeService,
}},
path.EmailCategory,
false,
testArchiveDir)
@ -1800,8 +1810,10 @@ func (suite *KopiaSimpleRepoIntegrationSuite) TestBackupExcludeItem() {
func (suite *KopiaSimpleRepoIntegrationSuite) TestProduceRestoreCollections() {
doesntExist, err := path.Build(
testTenant,
testUser,
path.ExchangeService,
[]path.ServiceResource{{
ProtectedResource: testUser,
Service: path.ExchangeService,
}},
path.EmailCategory,
true,
"subdir", "foo")
@ -1934,8 +1946,10 @@ func (suite *KopiaSimpleRepoIntegrationSuite) TestProduceRestoreCollections() {
func (suite *KopiaSimpleRepoIntegrationSuite) TestProduceRestoreCollections_PathChanges() {
rp1, err := path.Build(
testTenant,
testUser,
path.ExchangeService,
[]path.ServiceResource{{
ProtectedResource: testUser,
Service: path.ExchangeService,
}},
path.EmailCategory,
false,
"corso_restore", "Inbox")
@ -1943,8 +1957,10 @@ func (suite *KopiaSimpleRepoIntegrationSuite) TestProduceRestoreCollections_Path
rp2, err := path.Build(
testTenant,
testUser,
path.ExchangeService,
[]path.ServiceResource{{
ProtectedResource: testUser,
Service: path.ExchangeService,
}},
path.EmailCategory,
false,
"corso_restore", "Archive")
@ -2057,8 +2073,10 @@ func (suite *KopiaSimpleRepoIntegrationSuite) TestProduceRestoreCollections_Fetc
rp1, err := path.Build(
testTenant,
testUser,
path.ExchangeService,
[]path.ServiceResource{{
ProtectedResource: testUser,
Service: path.ExchangeService,
}},
path.EmailCategory,
false,
"corso_restore", "Inbox")

View File

@ -538,8 +538,8 @@ func consumeBackupCollections(
func matchesReason(reasons []identity.Reasoner, p path.Path) bool {
for _, reason := range reasons {
if p.ResourceOwner() == reason.ProtectedResource() &&
p.Service() == reason.Service() &&
if p.PrimaryProtectedResource() == reason.ProtectedResource() &&
p.PrimaryService() == reason.Service() &&
p.Category() == reason.Category() {
return true
}

View File

@ -617,13 +617,13 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsItems
pathReason1 = kopia.NewReason(
"",
itemPath1.ResourceOwner(),
itemPath1.Service(),
itemPath1.PrimaryProtectedResource(),
itemPath1.PrimaryService(),
itemPath1.Category())
pathReason3 = kopia.NewReason(
"",
itemPath3.ResourceOwner(),
itemPath3.Service(),
itemPath3.PrimaryProtectedResource(),
itemPath3.PrimaryService(),
itemPath3.Category())
time1 = time.Now()
@ -1240,8 +1240,8 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsFolde
pathReason1 = kopia.NewReason(
"",
itemPath1.ResourceOwner(),
itemPath1.Service(),
itemPath1.PrimaryProtectedResource(),
itemPath1.PrimaryService(),
itemPath1.Category())
backup1 = kopia.BackupEntry{

View File

@ -78,47 +78,58 @@ var (
// Resources that don't have the requested information should return an empty
// string.
type Path interface {
String() string
// parts
Tenant() string
// ServiceResources produces all of the services and subservices, along with
// the protected resource paired with the service, as contained in the path,
// in their order of appearance.
ServiceResources() []ServiceResource
// PrimaryService is the first service in ServiceResources()
PrimaryService() ServiceType
// PrimaryProtectedResource is the first ProtectedResource in ServiceResources()
PrimaryProtectedResource() string
Category() CategoryType
Tenant() string
Folder(escaped bool) string
Folders() Elements
Item() string
// UpdateParent updates parent from old to new if the item/folder was
// parented by old path
UpdateParent(prev, cur Path) bool
// PopFront returns a Builder object with the first element (left-side)
// removed. As the resulting set of elements is no longer a valid resource
// path a Builder is returned instead.
PopFront() *Builder
// Dir returns a Path object with the right-most element removed if possible.
// If removing the right-most element would discard one of the required prefix
// elements then an error is returned.
Dir() (Path, error)
// type transformations
// ToBuilder returns a Builder instance that represents the current Path.
ToBuilder() *Builder
// Elements returns all the elements in the path. This is a temporary function
// and will likely be updated to handle encoded elements instead of clear-text
// elements in the future.
Elements() Elements
// Halves breaks the path into its prefix (tenant, services, resources, category)
// and suffix (all parts after the prefix). If either half is empty, that half
// returns an empty, non-nil, value.
Halves() (*Builder, Elements)
// ShortRef returns a short reference representing this path. The short
// reference is guaranteed to be unique. No guarantees are made about whether
// a short reference can be converted back into the Path that generated it.
ShortRef() string
// mutators
// Append returns a new Path object with the given element added to the end of
// the old Path if possible. If the old Path is an item Path then Append
// returns an error.
Append(isItem bool, elems ...string) (Path, error)
// AppendItem is a shorthand for Append(true, someItem)
AppendItem(item string) (Path, error)
// ShortRef returns a short reference representing this path. The short
// reference is guaranteed to be unique. No guarantees are made about whether
// a short reference can be converted back into the Path that generated it.
ShortRef() string
// ToBuilder returns a Builder instance that represents the current Path.
ToBuilder() *Builder
// Halves breaks the path into its prefix (tenant, services, resources, category)
// and suffix (all parts after the prefix). If either half is empty, that half
// returns an empty, non-nil, value.
Halves() (*Builder, Elements)
// Dir returns a Path object with the right-most element removed if possible.
// If removing the right-most element would discard one of the required prefix
// elements then an error is returned.
Dir() (Path, error)
// PopFront returns a Builder object with the first element (left-side)
// removed. As the resulting set of elements is no longer a valid resource
// path a Builder is returned instead.
PopFront() *Builder
// UpdateParent updates parent from old to new if the item/folder was
// parented by old path
UpdateParent(prev, cur Path) bool
// Every path needs to comply with these funcs to ensure that PII
// is appropriately hidden from logging, errors, and other outputs.

View File

@ -51,6 +51,26 @@ func (rp dataLayerResourcePath) ServiceResources() []ServiceResource {
return rp.serviceResources
}
func (rp dataLayerResourcePath) PrimaryService() ServiceType {
srs := rp.serviceResources
if len(srs) == 0 {
return UnknownService
}
return srs[0].Service
}
func (rp dataLayerResourcePath) PrimaryProtectedResource() string {
srs := rp.serviceResources
if len(srs) == 0 {
return ""
}
return srs[0].ProtectedResource
}
// Category returns the CategoryType embedded in the dataLayerResourcePath.
func (rp dataLayerResourcePath) Category() CategoryType {
return rp.category
@ -72,10 +92,16 @@ func (rp dataLayerResourcePath) lastFolderIdx() int {
return endIdx
}
func (rp dataLayerResourcePath) prefixLen() int {
return 2 + 2*len(rp.serviceResources)
}
// Folder returns the folder segment embedded in the dataLayerResourcePath.
func (rp dataLayerResourcePath) Folder(escape bool) string {
endIdx := rp.lastFolderIdx()
if endIdx == 4 {
pfxLen := rp.prefixLen()
if endIdx == pfxLen {
return ""
}
@ -93,11 +119,14 @@ func (rp dataLayerResourcePath) Folder(escape bool) string {
// dataLayerResourcePath.
func (rp dataLayerResourcePath) Folders() Elements {
endIdx := rp.lastFolderIdx()
if endIdx == 4 {
pfxLen := rp.prefixLen()
// if endIdx == prefix length, there are no folders
if endIdx == pfxLen {
return nil
}
return append([]string{}, rp.elements[4:endIdx]...)
return append([]string{}, rp.elements[pfxLen:endIdx]...)
}
// Item returns the item embedded in the dataLayerResourcePath if the path

View File

@ -15,14 +15,34 @@ import (
)
const (
testTenant = "aTenant"
testUser = "aUser"
testTenant = "aTenant"
testProtectedResource = "aProtectedResource"
)
func elemsWithWithoutItem(elems path.Elements) func(isItem bool) path.Elements {
return func(isItem bool) path.Elements {
if isItem {
return elems[:len(elems)-1]
}
return elems
}
}
func itemWithWithoutItem(elems path.Elements) func(isItem bool) string {
return func(isItem bool) string {
if isItem {
return elems[len(elems)-1]
}
return ""
}
}
var (
// Purposely doesn't have characters that need escaping so it can be easily
// computed using strings.Join().
rest = []string{"some", "folder", "path", "with", "possible", "item"}
rest = path.Elements{"some", "folder", "path", "with", "possible", "item"}
missingInfo = []struct {
name string
@ -33,7 +53,7 @@ var (
{
name: "NoTenant",
tenant: "",
user: testUser,
user: testProtectedResource,
rest: rest,
},
{
@ -45,7 +65,7 @@ var (
{
name: "NoFolderOrItem",
tenant: testTenant,
user: testUser,
user: testProtectedResource,
rest: nil,
},
}
@ -70,60 +90,193 @@ var (
},
}
// Set of acceptable service/category mixtures.
// Set of acceptable service[/subservice]/category mixtures.
serviceCategories = []struct {
service path.ServiceType
category path.CategoryType
pathFunc func(pb *path.Builder, tenant, user string, isItem bool) (path.Path, error)
name string
primaryService path.ServiceType
category path.CategoryType
pathFunc func(
tenant, primaryResource string,
isItem bool,
suffix path.Elements,
) (path.Path, error)
expectFolders func(expect path.Elements) func(isItem bool) path.Elements
expectItem func(expect path.Elements) func(isItem bool) string
}{
{
service: path.ExchangeService,
category: path.EmailCategory,
pathFunc: func(pb *path.Builder, tenant, user string, isItem bool) (path.Path, error) {
return pb.ToDataLayerExchangePathForCategory(tenant, user, path.EmailCategory, isItem)
name: path.ExchangeService.String() + path.EmailCategory.String(),
primaryService: path.ExchangeService,
category: path.EmailCategory,
pathFunc: func(
tenant, primaryResource string,
isItem bool,
suffix path.Elements,
) (path.Path, error) {
srs, err := path.NewServiceResources(path.ExchangeService, primaryResource)
if err != nil {
return nil, err
}
return path.Build(tenant, srs, path.PagesCategory, isItem, suffix...)
},
expectFolders: elemsWithWithoutItem,
expectItem: itemWithWithoutItem,
},
{
service: path.ExchangeService,
category: path.ContactsCategory,
pathFunc: func(pb *path.Builder, tenant, user string, isItem bool) (path.Path, error) {
return pb.ToDataLayerExchangePathForCategory(tenant, user, path.ContactsCategory, isItem)
name: path.ExchangeService.String() + path.ContactsCategory.String(),
primaryService: path.ExchangeService,
category: path.ContactsCategory,
pathFunc: func(
tenant, primaryResource string,
isItem bool,
suffix path.Elements,
) (path.Path, error) {
srs, err := path.NewServiceResources(path.ExchangeService, primaryResource)
if err != nil {
return nil, err
}
return path.Build(tenant, srs, path.PagesCategory, isItem, suffix...)
},
expectFolders: elemsWithWithoutItem,
expectItem: itemWithWithoutItem,
},
{
service: path.ExchangeService,
category: path.EventsCategory,
pathFunc: func(pb *path.Builder, tenant, user string, isItem bool) (path.Path, error) {
return pb.ToDataLayerExchangePathForCategory(tenant, user, path.EventsCategory, isItem)
name: path.ExchangeService.String() + path.EventsCategory.String(),
primaryService: path.ExchangeService,
category: path.EventsCategory,
pathFunc: func(
tenant, primaryResource string,
isItem bool,
suffix path.Elements,
) (path.Path, error) {
srs, err := path.NewServiceResources(path.ExchangeService, primaryResource)
if err != nil {
return nil, err
}
return path.Build(tenant, srs, path.PagesCategory, isItem, suffix...)
},
expectFolders: elemsWithWithoutItem,
expectItem: itemWithWithoutItem,
},
{
service: path.OneDriveService,
category: path.FilesCategory,
pathFunc: func(pb *path.Builder, tenant, user string, isItem bool) (path.Path, error) {
return pb.ToDataLayerOneDrivePath(tenant, user, isItem)
name: path.OneDriveService.String() + path.FilesCategory.String(),
primaryService: path.OneDriveService,
category: path.FilesCategory,
pathFunc: func(
tenant, primaryResource string,
isItem bool,
suffix path.Elements,
) (path.Path, error) {
srs, err := path.NewServiceResources(path.OneDriveService, primaryResource)
if err != nil {
return nil, err
}
return path.Build(tenant, srs, path.PagesCategory, isItem, suffix...)
},
expectFolders: elemsWithWithoutItem,
expectItem: itemWithWithoutItem,
},
{
service: path.SharePointService,
category: path.LibrariesCategory,
pathFunc: func(pb *path.Builder, tenant, site string, isItem bool) (path.Path, error) {
return pb.ToDataLayerSharePointPath(tenant, site, path.LibrariesCategory, isItem)
name: path.SharePointService.String() + path.LibrariesCategory.String(),
primaryService: path.SharePointService,
category: path.LibrariesCategory,
pathFunc: func(
tenant, primaryResource string,
isItem bool,
suffix path.Elements,
) (path.Path, error) {
srs, err := path.NewServiceResources(path.SharePointService, primaryResource)
if err != nil {
return nil, err
}
return path.Build(tenant, srs, path.PagesCategory, isItem, suffix...)
},
expectFolders: elemsWithWithoutItem,
expectItem: itemWithWithoutItem,
},
{
service: path.SharePointService,
category: path.ListsCategory,
pathFunc: func(pb *path.Builder, tenant, site string, isItem bool) (path.Path, error) {
return pb.ToDataLayerSharePointPath(tenant, site, path.ListsCategory, isItem)
name: path.SharePointService.String() + path.ListsCategory.String(),
primaryService: path.SharePointService,
category: path.ListsCategory,
pathFunc: func(
tenant, primaryResource string,
isItem bool,
suffix path.Elements,
) (path.Path, error) {
srs, err := path.NewServiceResources(path.SharePointService, primaryResource)
if err != nil {
return nil, err
}
return path.Build(tenant, srs, path.PagesCategory, isItem, suffix...)
},
expectFolders: elemsWithWithoutItem,
expectItem: itemWithWithoutItem,
},
{
service: path.SharePointService,
category: path.PagesCategory,
pathFunc: func(pb *path.Builder, tenant, site string, isItem bool) (path.Path, error) {
return pb.ToDataLayerSharePointPath(tenant, site, path.PagesCategory, isItem)
name: path.SharePointService.String() + path.PagesCategory.String(),
primaryService: path.SharePointService,
category: path.PagesCategory,
pathFunc: func(
tenant, primaryResource string,
isItem bool,
suffix path.Elements,
) (path.Path, error) {
srs, err := path.NewServiceResources(path.SharePointService, primaryResource)
if err != nil {
return nil, err
}
return path.Build(tenant, srs, path.PagesCategory, isItem, suffix...)
},
expectFolders: elemsWithWithoutItem,
expectItem: itemWithWithoutItem,
},
{
name: path.GroupsService.String() + path.UnknownCategory.String(),
primaryService: path.GroupsService,
category: path.UnknownCategory,
pathFunc: func(
tenant, primaryResource string,
isItem bool,
suffix path.Elements,
) (path.Path, error) {
srs, err := path.NewServiceResources(path.GroupsService, primaryResource)
if err != nil {
return nil, err
}
return path.Build(tenant, srs, path.PagesCategory, isItem, suffix...)
},
expectFolders: elemsWithWithoutItem,
expectItem: itemWithWithoutItem,
},
{
name: path.GroupsService.String() + path.SharePointService.String() + path.UnknownCategory.String(),
primaryService: path.GroupsService,
category: path.LibrariesCategory,
pathFunc: func(
tenant, primaryResource string,
isItem bool,
suffix path.Elements,
) (path.Path, error) {
srs, err := path.NewServiceResources(
path.GroupsService,
primaryResource,
path.SharePointService,
"secondaryProtectedResource")
if err != nil {
return nil, err
}
return path.Build(tenant, srs, path.PagesCategory, isItem, suffix...)
},
expectFolders: elemsWithWithoutItem,
expectItem: itemWithWithoutItem,
},
}
)
@ -142,22 +295,13 @@ func (suite *DataLayerResourcePath) SetupSuite() {
func (suite *DataLayerResourcePath) TestMissingInfoErrors() {
for _, types := range serviceCategories {
suite.Run(types.service.String()+types.category.String(), func() {
suite.Run(types.primaryService.String()+types.category.String(), func() {
for _, m := range modes {
suite.Run(m.name, func() {
for _, test := range missingInfo {
suite.Run(test.name, func() {
t := suite.T()
b := path.Builder{}.Append(test.rest...)
_, err := types.pathFunc(
b,
test.tenant,
test.user,
m.isItem,
)
assert.Error(t, err)
_, err := types.pathFunc(test.tenant, test.user, m.isItem, rest)
assert.Error(suite.T(), err, clues.ToCore(err))
})
}
})
@ -167,31 +311,23 @@ func (suite *DataLayerResourcePath) TestMissingInfoErrors() {
}
func (suite *DataLayerResourcePath) TestMailItemNoFolder() {
item := "item"
b := path.Builder{}.Append(item)
for _, types := range serviceCategories {
suite.Run(types.service.String()+types.category.String(), func() {
for _, test := range serviceCategories {
suite.Run(test.name, func() {
t := suite.T()
p, err := types.pathFunc(
b,
testTenant,
testUser,
true,
)
p, err := test.pathFunc(testTenant, testProtectedResource, true, path.Elements{"item"})
require.NoError(t, err, clues.ToCore(err))
assert.Empty(t, p.Folder(false))
assert.Empty(t, p.Folders())
assert.Equal(t, item, p.Item())
assert.Equal(t, test.expectItem(path.Elements{"item"})(true), p.Item())
})
}
}
func (suite *DataLayerResourcePath) TestPopFront() {
expected := path.Builder{}.Append(append(
[]string{path.ExchangeService.String(), testUser, path.EmailCategory.String()},
[]string{path.ExchangeService.String(), testProtectedResource, path.EmailCategory.String()},
rest...,
)...)
@ -202,7 +338,7 @@ func (suite *DataLayerResourcePath) TestPopFront() {
pb := path.Builder{}.Append(rest...)
p, err := pb.ToDataLayerExchangePathForCategory(
testTenant,
testUser,
testProtectedResource,
path.EmailCategory,
m.isItem,
)
@ -218,7 +354,7 @@ func (suite *DataLayerResourcePath) TestDir() {
elements := []string{
testTenant,
path.ExchangeService.String(),
testUser,
testProtectedResource,
path.EmailCategory.String(),
}
@ -227,7 +363,7 @@ func (suite *DataLayerResourcePath) TestDir() {
pb := path.Builder{}.Append(rest...)
p, err := pb.ToDataLayerExchangePathForCategory(
testTenant,
testUser,
testProtectedResource,
path.EmailCategory,
m.isItem,
)
@ -391,7 +527,7 @@ func (suite *DataLayerResourcePath) TestToExchangePathForCategory() {
p, err := b.ToDataLayerExchangePathForCategory(
testTenant,
testUser,
testProtectedResource,
test.category,
m.isItem)
test.check(t, err, clues.ToCore(err))
@ -401,9 +537,9 @@ func (suite *DataLayerResourcePath) TestToExchangePathForCategory() {
}
assert.Equal(t, testTenant, p.Tenant())
assert.Equal(t, path.ExchangeService, p.ServiceResources()[0].Service)
assert.Equal(t, path.ExchangeService, p.PrimaryService())
assert.Equal(t, test.category, p.Category())
assert.Equal(t, testUser, p.ServiceResources()[0].ProtectedResource)
assert.Equal(t, testProtectedResource, p.PrimaryProtectedResource())
assert.Equal(t, strings.Join(m.expectedFolders, "/"), p.Folder(false))
assert.Equal(t, path.Elements(m.expectedFolders), p.Folders())
assert.Equal(t, m.expectedItem, p.Item())
@ -416,7 +552,8 @@ func (suite *DataLayerResourcePath) TestToExchangePathForCategory() {
type PopulatedDataLayerResourcePath struct {
tester.Suite
// Bool value is whether the path is an item path or a folder path.
paths map[bool]path.Path
serviceCategoriesToIsItemToPath map[string]map[bool]path.Path
isItemToPath map[bool]path.Path
}
func TestPopulatedDataLayerResourcePath(t *testing.T) {
@ -424,98 +561,109 @@ func TestPopulatedDataLayerResourcePath(t *testing.T) {
}
func (suite *PopulatedDataLayerResourcePath) SetupSuite() {
suite.paths = make(map[bool]path.Path, 2)
base := path.Builder{}.Append(rest...)
suite.serviceCategoriesToIsItemToPath = map[string]map[bool]path.Path{}
for _, t := range []bool{true, false} {
p, err := base.ToDataLayerExchangePathForCategory(
testTenant,
testUser,
path.EmailCategory,
t,
)
require.NoError(suite.T(), err, clues.ToCore(err))
for _, sc := range serviceCategories {
m := make(map[bool]path.Path, 2)
suite.serviceCategoriesToIsItemToPath[sc.name] = m
suite.paths[t] = p
for _, is := range []bool{true, false} {
p, err := sc.pathFunc(testTenant, testProtectedResource, is, rest)
require.NoError(suite.T(), err, clues.ToCore(err))
suite.serviceCategoriesToIsItemToPath[sc.name][is] = p
suite.isItemToPath[is] = p
}
}
}
func (suite *PopulatedDataLayerResourcePath) TestTenant() {
for _, m := range modes {
suite.Run(m.name, func() {
t := suite.T()
assert.Equal(t, testTenant, suite.paths[m.isItem].Tenant())
for _, test := range serviceCategories {
suite.Run(test.name, func() {
for _, m := range modes {
suite.Run(m.name, func() {
p := suite.serviceCategoriesToIsItemToPath[test.name][m.isItem]
assert.Equal(suite.T(), testTenant, p.Tenant())
})
}
})
}
}
func (suite *PopulatedDataLayerResourcePath) TestService() {
for _, m := range modes {
suite.Run(m.name, func() {
t := suite.T()
assert.Equal(
t,
path.ExchangeService,
suite.paths[m.isItem].ServiceResources()[0].Service)
func (suite *PopulatedDataLayerResourcePath) TestPrimaryService() {
for _, test := range serviceCategories {
suite.Run(test.name, func() {
for _, m := range modes {
suite.Run(m.name, func() {
p := suite.serviceCategoriesToIsItemToPath[test.name][m.isItem]
assert.Equal(suite.T(), test.primaryService, p.PrimaryService())
})
}
})
}
}
func (suite *PopulatedDataLayerResourcePath) TestCategory() {
for _, m := range modes {
suite.Run(m.name, func() {
t := suite.T()
assert.Equal(t, path.EmailCategory, suite.paths[m.isItem].Category())
for _, test := range serviceCategories {
suite.Run(test.name, func() {
for _, m := range modes {
suite.Run(m.name, func() {
p := suite.serviceCategoriesToIsItemToPath[test.name][m.isItem]
assert.Equal(suite.T(), test.category, p.Category())
})
}
})
}
}
func (suite *PopulatedDataLayerResourcePath) TestResourceOwner() {
for _, m := range modes {
suite.Run(m.name, func() {
t := suite.T()
assert.Equal(
t,
testUser,
suite.paths[m.isItem].ServiceResources()[0].ProtectedResource)
func (suite *PopulatedDataLayerResourcePath) TestPrimaryProtectedResource() {
for _, test := range serviceCategories {
suite.Run(test.name, func() {
for _, m := range modes {
suite.Run(m.name, func() {
p := suite.serviceCategoriesToIsItemToPath[test.name][m.isItem]
assert.Equal(suite.T(), testProtectedResource, p.PrimaryProtectedResource())
})
}
})
}
}
func (suite *PopulatedDataLayerResourcePath) TestFolder() {
for _, m := range modes {
suite.Run(m.name, func() {
t := suite.T()
assert.Equal(
t,
strings.Join(m.expectedFolders, "/"),
suite.paths[m.isItem].Folder(false),
)
for _, test := range serviceCategories {
suite.Run(test.name, func() {
for _, m := range modes {
suite.Run(m.name, func() {
p := suite.serviceCategoriesToIsItemToPath[test.name][m.isItem]
assert.Equal(suite.T(), test.expectFolders(rest)(m.isItem).String(), p.Folder(true))
})
}
})
}
}
func (suite *PopulatedDataLayerResourcePath) TestFolders() {
for _, m := range modes {
suite.Run(m.name, func() {
t := suite.T()
assert.Equal(t, path.Elements(m.expectedFolders), suite.paths[m.isItem].Folders())
for _, test := range serviceCategories {
suite.Run(test.name, func() {
for _, m := range modes {
suite.Run(m.name, func() {
p := suite.serviceCategoriesToIsItemToPath[test.name][m.isItem]
assert.Equal(suite.T(), test.expectFolders(rest)(m.isItem), p.Folders())
})
}
})
}
}
func (suite *PopulatedDataLayerResourcePath) TestItem() {
for _, m := range modes {
suite.Run(m.name, func() {
t := suite.T()
assert.Equal(t, m.expectedItem, suite.paths[m.isItem].Item())
for _, test := range serviceCategories {
suite.Run(test.name, func() {
for _, m := range modes {
suite.Run(m.name, func() {
p := suite.serviceCategoriesToIsItemToPath[test.name][m.isItem]
assert.Equal(suite.T(), test.expectItem(rest)(m.isItem), p.Item())
})
}
})
}
}
@ -540,8 +688,7 @@ func (suite *PopulatedDataLayerResourcePath) TestAppend() {
hasItem: false,
expectedFolder: strings.Join(
append(append([]string{}, rest...), newElement),
"/",
),
"/"),
expectedItem: "",
},
}
@ -552,7 +699,7 @@ func (suite *PopulatedDataLayerResourcePath) TestAppend() {
suite.Run(test.name, func() {
t := suite.T()
newPath, err := suite.paths[m.isItem].Append(test.hasItem, newElement)
newPath, err := suite.isItemToPath[m.isItem].Append(test.hasItem, newElement)
// Items don't allow appending.
if m.isItem {