909 path folders (#910)

## Description

Adds function call to the path package that returns the folder elements present in a path after the path prefix. This is safer than using `strings.Split()` because some paths may have `/` characters in elements.

## Type of change

<!--- Please check the type of change your PR introduces: --->
- [x] 🌻 Feature
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Test
- [ ] 💻 CI/Deployment
- [ ] 🐹 Trivial/Minor

## Issue(s)

* closes #909 

## Test Plan

<!-- How will this be tested prior to merging.-->
- [ ] 💪 Manual
- [x]  Unit test
- [ ] 💚 E2E
This commit is contained in:
ashmrtn 2022-09-20 10:15:46 -07:00 committed by GitHub
parent 8678c0b159
commit acf1837e77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 21 deletions

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"fmt" "fmt"
"io" "io"
"strings"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -35,7 +34,7 @@ type drivePath struct {
} }
func toOneDrivePath(p path.Path) (*drivePath, error) { func toOneDrivePath(p path.Path) (*drivePath, error) {
folders := strings.Split(p.Folder(), "/") folders := p.Folders()
// Must be at least `drives/<driveID>/root:` // Must be at least `drives/<driveID>/root:`
if len(folders) < 3 { if len(folders) < 3 {

View File

@ -70,6 +70,7 @@ type Path interface {
Tenant() string Tenant() string
ResourceOwner() string ResourceOwner() string
Folder() string Folder() string
Folders() []string
Item() string Item() string
// PopFront returns a Builder object with the first element (left-side) // PopFront returns a Builder object with the first element (left-side)
// removed. As the resulting set of elements is no longer a valid resource // removed. As the resulting set of elements is no longer a valid resource

View File

@ -141,20 +141,37 @@ func (rp dataLayerResourcePath) ResourceOwner() string {
return rp.Builder.elements[2] return rp.Builder.elements[2]
} }
// Folder returns the folder segment embedded in the dataLayerResourcePath. func (rp dataLayerResourcePath) lastFolderIdx() int {
func (rp dataLayerResourcePath) Folder() string {
endIdx := len(rp.Builder.elements) endIdx := len(rp.Builder.elements)
if endIdx == 4 {
return ""
}
if rp.hasItem { if rp.hasItem {
endIdx-- endIdx--
} }
return endIdx
}
// Folder returns the folder segment embedded in the dataLayerResourcePath.
func (rp dataLayerResourcePath) Folder() string {
endIdx := rp.lastFolderIdx()
if endIdx == 4 {
return ""
}
return rp.Builder.join(4, endIdx) return rp.Builder.join(4, endIdx)
} }
// Folders returns the individual folder elements embedded in the
// dataLayerResourcePath.
func (rp dataLayerResourcePath) Folders() []string {
endIdx := rp.lastFolderIdx()
if endIdx == 4 {
return nil
}
return append([]string{}, rp.elements[4:endIdx]...)
}
// Item returns the item embedded in the dataLayerResourcePath if the path // Item returns the item embedded in the dataLayerResourcePath if the path
// refers to an item. // refers to an item.
func (rp dataLayerResourcePath) Item() string { func (rp dataLayerResourcePath) Item() string {

View File

@ -49,22 +49,22 @@ var (
} }
modes = []struct { modes = []struct {
name string name string
isItem bool isItem bool
expectedFolder string expectedFolders []string
expectedItem string expectedItem string
}{ }{
{ {
name: "Folder", name: "Folder",
isItem: false, isItem: false,
expectedFolder: strings.Join(rest, "/"), expectedFolders: rest,
expectedItem: "", expectedItem: "",
}, },
{ {
name: "Item", name: "Item",
isItem: true, isItem: true,
expectedFolder: strings.Join(rest[0:len(rest)-1], "/"), expectedFolders: rest[:len(rest)-1],
expectedItem: rest[len(rest)-1], expectedItem: rest[len(rest)-1],
}, },
} }
@ -152,6 +152,7 @@ func (suite *DataLayerResourcePath) TestMailItemNoFolder() {
require.NoError(t, err) require.NoError(t, err)
assert.Empty(t, p.Folder()) assert.Empty(t, p.Folder())
assert.Empty(t, p.Folders())
assert.Equal(t, item, p.Item()) assert.Equal(t, item, p.Item())
}) })
} }
@ -206,6 +207,7 @@ func (suite *DataLayerResourcePath) TestDir() {
expected := path.Builder{}.Append(elements...).Append(rest[:len(rest)-i]...) expected := path.Builder{}.Append(elements...).Append(rest[:len(rest)-i]...)
assert.Equal(t, expected.String(), p.String()) assert.Equal(t, expected.String(), p.String())
assert.Empty(t, p.Item())
}) })
} }
@ -266,7 +268,8 @@ func (suite *DataLayerResourcePath) TestToExchangePathForCategory() {
assert.Equal(t, path.ExchangeService, p.Service()) assert.Equal(t, path.ExchangeService, p.Service())
assert.Equal(t, test.category, p.Category()) assert.Equal(t, test.category, p.Category())
assert.Equal(t, testUser, p.ResourceOwner()) assert.Equal(t, testUser, p.ResourceOwner())
assert.Equal(t, m.expectedFolder, p.Folder()) assert.Equal(t, strings.Join(m.expectedFolders, "/"), p.Folder())
assert.Equal(t, m.expectedFolders, p.Folders())
assert.Equal(t, m.expectedItem, p.Item()) assert.Equal(t, m.expectedItem, p.Item())
}) })
} }
@ -336,7 +339,19 @@ func (suite *PopulatedDataLayerResourcePath) TestResourceOwner() {
func (suite *PopulatedDataLayerResourcePath) TestFolder() { func (suite *PopulatedDataLayerResourcePath) TestFolder() {
for _, m := range modes { for _, m := range modes {
suite.T().Run(m.name, func(t *testing.T) { suite.T().Run(m.name, func(t *testing.T) {
assert.Equal(t, m.expectedFolder, suite.paths[m.isItem].Folder()) assert.Equal(
t,
strings.Join(m.expectedFolders, "/"),
suite.paths[m.isItem].Folder(),
)
})
}
}
func (suite *PopulatedDataLayerResourcePath) TestFolders() {
for _, m := range modes {
suite.T().Run(m.name, func(t *testing.T) {
assert.Equal(t, m.expectedFolders, suite.paths[m.isItem].Folders())
}) })
} }
} }