Swaps path.Append from a single item method to accept a variadic list of string elements. Since 95% of all calls to path.Append were items, also adds a shorthand AppendItem func to the interface for easy clarity. Finally, adds a Last() method to elements for getting the last element in the slice. --- #### Does this PR need a docs update or release note? - [x] ⛔ No #### Type of change - [x] 🧹 Tech Debt/Cleanup #### Test Plan - [x] ⚡ Unit test - [x] 💚 E2E
836 lines
18 KiB
Go
836 lines
18 KiB
Go
package path
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/alcionai/clues"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
"github.com/alcionai/corso/src/internal/tester"
|
|
)
|
|
|
|
type testData struct {
|
|
name string
|
|
input []string
|
|
expectedString string
|
|
}
|
|
|
|
// Test cases that are the same with and without escaping by the
|
|
// system-under-test.
|
|
var genericCases = []testData{
|
|
{
|
|
name: "SimplePath",
|
|
input: []string{
|
|
`this`,
|
|
`is`,
|
|
`a`,
|
|
`path`,
|
|
},
|
|
expectedString: "this/is/a/path",
|
|
},
|
|
{
|
|
name: "EmptyElement",
|
|
input: []string{
|
|
`this`,
|
|
`is`,
|
|
``,
|
|
`a`,
|
|
`path`,
|
|
},
|
|
expectedString: `this/is/a/path`,
|
|
},
|
|
{
|
|
name: "EmptyInput",
|
|
expectedString: "",
|
|
},
|
|
}
|
|
|
|
// Inputs that should be escaped.
|
|
var basicUnescapedInputs = []testData{
|
|
{
|
|
name: "EscapeSeparator",
|
|
input: []string{
|
|
`this`,
|
|
`is/a`,
|
|
`path`,
|
|
},
|
|
expectedString: `this/is\/a/path`,
|
|
},
|
|
{
|
|
name: "EscapeEscapeChar",
|
|
input: []string{
|
|
`this`,
|
|
`is\`,
|
|
`a`,
|
|
`path`,
|
|
},
|
|
expectedString: `this/is\\/a/path`,
|
|
},
|
|
{
|
|
name: "EscapeEscapeAndSeparator",
|
|
input: []string{
|
|
`this`,
|
|
`is\/a`,
|
|
`path`,
|
|
},
|
|
expectedString: `this/is\\\/a/path`,
|
|
},
|
|
{
|
|
name: "SeparatorAtEndOfElement",
|
|
input: []string{
|
|
`this`,
|
|
`is/`,
|
|
`a`,
|
|
`path`,
|
|
},
|
|
expectedString: `this/is\//a/path`,
|
|
},
|
|
{
|
|
name: "SeparatorAtEndOfPath",
|
|
input: []string{
|
|
`this`,
|
|
`is`,
|
|
`a`,
|
|
`path/`,
|
|
},
|
|
expectedString: `this/is/a/path\/`,
|
|
},
|
|
}
|
|
|
|
// Inputs that are already escaped.
|
|
var basicEscapedInputs = []testData{
|
|
{
|
|
name: "EscapedSeparator",
|
|
input: []string{
|
|
`this`,
|
|
`is\/a`,
|
|
`path`,
|
|
},
|
|
expectedString: `this/is\/a/path`,
|
|
},
|
|
{
|
|
name: "EscapedEscapeChar",
|
|
input: []string{
|
|
`this`,
|
|
`is\\`,
|
|
`a`,
|
|
`path`,
|
|
},
|
|
expectedString: `this/is\\/a/path`,
|
|
},
|
|
{
|
|
name: "EscapedEscapeAndSeparator",
|
|
input: []string{
|
|
`this`,
|
|
`is\\\/a`,
|
|
`path`,
|
|
},
|
|
expectedString: `this/is\\\/a/path`,
|
|
},
|
|
{
|
|
name: "EscapedSeparatorAtEndOfElement",
|
|
input: []string{
|
|
`this`,
|
|
`is\/`,
|
|
`a`,
|
|
`path`,
|
|
},
|
|
expectedString: `this/is\//a/path`,
|
|
},
|
|
{
|
|
name: "EscapedSeparatorAtEndOfPath",
|
|
input: []string{
|
|
`this`,
|
|
`is`,
|
|
`a`,
|
|
`path\/`,
|
|
},
|
|
expectedString: `this/is/a/path\/`,
|
|
},
|
|
{
|
|
name: "ElementOfSeparator",
|
|
input: []string{
|
|
`this`,
|
|
`is`,
|
|
`/`,
|
|
`a`,
|
|
`path`,
|
|
},
|
|
expectedString: `this/is/a/path`,
|
|
},
|
|
{
|
|
name: "TrailingElementSeparator",
|
|
input: []string{
|
|
`this`,
|
|
`is`,
|
|
`a/`,
|
|
`path`,
|
|
},
|
|
expectedString: `this/is/a/path`,
|
|
},
|
|
{
|
|
name: "MultipleTrailingElementSeparator",
|
|
input: []string{
|
|
`this`,
|
|
`is`,
|
|
`a///`,
|
|
`path`,
|
|
},
|
|
expectedString: `this/is/a/path`,
|
|
},
|
|
{
|
|
name: "TrailingSeparatorAtEnd",
|
|
input: []string{
|
|
`this`,
|
|
`is`,
|
|
`a`,
|
|
`path/`,
|
|
},
|
|
expectedString: `this/is/a/path`,
|
|
},
|
|
{
|
|
name: "MultipleTrailingSeparatorAtEnd",
|
|
input: []string{
|
|
`this`,
|
|
`is`,
|
|
`a`,
|
|
`path///`,
|
|
},
|
|
expectedString: `this/is/a/path`,
|
|
},
|
|
{
|
|
name: "TrailingSeparatorWithEmptyElementAtEnd",
|
|
input: []string{
|
|
`this`,
|
|
`is`,
|
|
`a`,
|
|
`path/`,
|
|
``,
|
|
},
|
|
expectedString: `this/is/a/path`,
|
|
},
|
|
}
|
|
|
|
type PathUnitSuite struct {
|
|
tester.Suite
|
|
}
|
|
|
|
func TestPathUnitSuite(t *testing.T) {
|
|
suite.Run(t, &PathUnitSuite{Suite: tester.NewUnitSuite(t)})
|
|
}
|
|
|
|
// set the clues hashing to mask for the span of this suite
|
|
func (suite *PathUnitSuite) SetupSuite() {
|
|
clues.SetHasher(clues.HashCfg{HashAlg: clues.Flatmask})
|
|
}
|
|
|
|
// revert clues hashing to plaintext for all other tests
|
|
func (suite *PathUnitSuite) TeardownSuite() {
|
|
clues.SetHasher(clues.NoHash())
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestAppend() {
|
|
table := append(append([]testData{}, genericCases...), basicUnescapedInputs...)
|
|
for _, test := range table {
|
|
suite.Run(test.name, func() {
|
|
t := suite.T()
|
|
|
|
p := Builder{}.Append(test.input...)
|
|
assert.Equal(t, test.expectedString, p.String())
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestAppendItem() {
|
|
t := suite.T()
|
|
|
|
p, err := Build("t", "ro", ExchangeService, EmailCategory, false, "foo", "bar")
|
|
require.NoError(t, err, clues.ToCore(err))
|
|
|
|
pb := p.ToBuilder()
|
|
assert.Equal(t, pb.String(), p.String())
|
|
|
|
pb = pb.Append("qux")
|
|
|
|
p, err = p.AppendItem("qux")
|
|
|
|
require.NoError(t, err, clues.ToCore(err))
|
|
assert.Equal(t, pb.String(), p.String())
|
|
|
|
_, err = p.AppendItem("fnords")
|
|
require.Error(t, err, clues.ToCore(err))
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestUnescapeAndAppend() {
|
|
table := append(append([]testData{}, genericCases...), basicEscapedInputs...)
|
|
for _, test := range table {
|
|
suite.Run(test.name, func() {
|
|
t := suite.T()
|
|
|
|
p, err := Builder{}.UnescapeAndAppend(test.input...)
|
|
require.NoError(t, err, clues.ToCore(err))
|
|
|
|
assert.Equal(t, test.expectedString, p.String())
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestEscapedFailure() {
|
|
target := "i_s"
|
|
|
|
for c := range charactersToEscape {
|
|
suite.Run(fmt.Sprintf("Unescaped-%c", c), func() {
|
|
tmp := strings.ReplaceAll(target, "_", string(c))
|
|
|
|
_, err := Builder{}.UnescapeAndAppend("this", tmp, "path")
|
|
assert.Errorf(suite.T(), err, "path with unescaped %s did not error", string(c))
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestBadEscapeSequenceErrors() {
|
|
target := `i\_s/a`
|
|
notEscapes := []rune{'a', 'b', '#', '%'}
|
|
|
|
for _, c := range notEscapes {
|
|
suite.Run(fmt.Sprintf("Escaped-%c", c), func() {
|
|
tmp := strings.ReplaceAll(target, "_", string(c))
|
|
|
|
_, err := Builder{}.UnescapeAndAppend("this", tmp, "path")
|
|
assert.Errorf(
|
|
suite.T(),
|
|
err,
|
|
"path with bad escape sequence %c%c did not error",
|
|
escapeCharacter,
|
|
c)
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestTrailingEscapeChar() {
|
|
base := []string{"this", "is", "a", "path"}
|
|
|
|
for i := 0; i < len(base); i++ {
|
|
suite.Run(fmt.Sprintf("Element%v", i), func() {
|
|
path := make([]string, len(base))
|
|
copy(path, base)
|
|
path[i] = path[i] + string(escapeCharacter)
|
|
|
|
_, err := Builder{}.UnescapeAndAppend(path...)
|
|
assert.Error(
|
|
suite.T(),
|
|
err,
|
|
"path with trailing escape character did not error")
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestElements() {
|
|
table := []struct {
|
|
name string
|
|
input []string
|
|
output []string
|
|
pathFunc func(elements []string) (*Builder, error)
|
|
}{
|
|
{
|
|
name: "SimpleEscapedPath",
|
|
input: []string{"this", "is", "a", "path"},
|
|
output: []string{"this", "is", "a", "path"},
|
|
pathFunc: func(elements []string) (*Builder, error) {
|
|
return Builder{}.UnescapeAndAppend(elements...)
|
|
},
|
|
},
|
|
{
|
|
name: "SimpleUnescapedPath",
|
|
input: []string{"this", "is", "a", "path"},
|
|
output: []string{"this", "is", "a", "path"},
|
|
pathFunc: func(elements []string) (*Builder, error) {
|
|
return Builder{}.Append(elements...), nil
|
|
},
|
|
},
|
|
{
|
|
name: "EscapedPath",
|
|
input: []string{"this", `is\/`, "a", "path"},
|
|
output: []string{"this", "is/", "a", "path"},
|
|
pathFunc: func(elements []string) (*Builder, error) {
|
|
return Builder{}.UnescapeAndAppend(elements...)
|
|
},
|
|
},
|
|
}
|
|
for _, test := range table {
|
|
suite.Run(test.name, func() {
|
|
t := suite.T()
|
|
|
|
p, err := test.pathFunc(test.input)
|
|
require.NoError(t, err, clues.ToCore(err))
|
|
|
|
assert.Equal(t, Elements(test.output), p.Elements())
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestPopFront() {
|
|
table := []struct {
|
|
name string
|
|
base *Builder
|
|
expectedString string
|
|
}{
|
|
{
|
|
name: "Empty",
|
|
base: &Builder{},
|
|
expectedString: "",
|
|
},
|
|
{
|
|
name: "OneElement",
|
|
base: Builder{}.Append("something"),
|
|
expectedString: "",
|
|
},
|
|
{
|
|
name: "TwoElements",
|
|
base: Builder{}.Append("something", "else"),
|
|
expectedString: "else",
|
|
},
|
|
}
|
|
for _, test := range table {
|
|
suite.Run(test.name, func() {
|
|
t := suite.T()
|
|
|
|
assert.Equal(t, test.expectedString, test.base.PopFront().String())
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestShortRef() {
|
|
table := []struct {
|
|
name string
|
|
inputElements []string
|
|
expectedLen int
|
|
}{
|
|
{
|
|
name: "PopulatedPath",
|
|
inputElements: []string{"this", "is", "a", "path"},
|
|
expectedLen: shortRefCharacters,
|
|
},
|
|
{
|
|
name: "EmptyPath",
|
|
inputElements: nil,
|
|
expectedLen: 0,
|
|
},
|
|
}
|
|
for _, test := range table {
|
|
suite.Run(test.name, func() {
|
|
pb := Builder{}.Append(test.inputElements...)
|
|
ref := pb.ShortRef()
|
|
assert.Len(suite.T(), ref, test.expectedLen)
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestShortRefIsStable() {
|
|
t := suite.T()
|
|
pb := Builder{}.Append("this", "is", "a", "path")
|
|
prevRef := pb.ShortRef()
|
|
assert.Len(t, prevRef, shortRefCharacters)
|
|
|
|
for i := 0; i < 5; i++ {
|
|
ref := pb.ShortRef()
|
|
assert.Len(t, ref, shortRefCharacters)
|
|
assert.Equal(t, prevRef, ref, "ShortRef changed between calls")
|
|
|
|
prevRef = ref
|
|
}
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestShortRefIsUnique() {
|
|
pb1 := Builder{}.Append("this", "is", "a", "path")
|
|
pb2 := pb1.Append("also")
|
|
|
|
require.NotEqual(suite.T(), pb1, pb2)
|
|
assert.NotEqual(suite.T(), pb1.ShortRef(), pb2.ShortRef())
|
|
}
|
|
|
|
// TestShortRefUniqueWithEscaping tests that two paths that output the same
|
|
// unescaped string but different escaped strings have different shortrefs. This
|
|
// situation can occur when one path has embedded path separators while the
|
|
// other does not but contains the same characters.
|
|
func (suite *PathUnitSuite) TestShortRefUniqueWithEscaping() {
|
|
pb1 := Builder{}.Append(`this`, `is`, `a`, `path`)
|
|
pb2 := Builder{}.Append(`this`, `is/a`, `path`)
|
|
|
|
require.NotEqual(suite.T(), pb1, pb2)
|
|
assert.NotEqual(suite.T(), pb1.ShortRef(), pb2.ShortRef())
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestFromStringErrors() {
|
|
table := []struct {
|
|
name string
|
|
escapedPath string
|
|
}{
|
|
{
|
|
name: "TooFewElements",
|
|
escapedPath: `some/short/path`,
|
|
},
|
|
{
|
|
name: "TooFewElementsEmptyElement",
|
|
escapedPath: `tenant/exchange//email/folder`,
|
|
},
|
|
{
|
|
name: "BadEscapeSequence",
|
|
escapedPath: `tenant/exchange/user/email/folder\a`,
|
|
},
|
|
{
|
|
name: "TrailingEscapeCharacter",
|
|
escapedPath: `tenant/exchange/user/email/folder\`,
|
|
},
|
|
{
|
|
name: "UnknownService",
|
|
escapedPath: `tenant/badService/user/email/folder`,
|
|
},
|
|
{
|
|
name: "UnknownCategory",
|
|
escapedPath: `tenant/exchange/user/badCategory/folder`,
|
|
},
|
|
{
|
|
name: "NoFolderOrItem",
|
|
escapedPath: `tenant/exchange/user/email`,
|
|
},
|
|
{
|
|
name: "EmptyPath",
|
|
escapedPath: ``,
|
|
},
|
|
{
|
|
name: "JustPathSeparator",
|
|
escapedPath: `/`,
|
|
},
|
|
{
|
|
name: "JustMultiplePathSeparators",
|
|
escapedPath: `//`,
|
|
},
|
|
}
|
|
for _, test := range table {
|
|
suite.Run(test.name, func() {
|
|
t := suite.T()
|
|
|
|
_, err := FromDataLayerPath(test.escapedPath, false)
|
|
assert.Error(t, err)
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestFolder() {
|
|
table := []struct {
|
|
name string
|
|
p func(t *testing.T) Path
|
|
escape bool
|
|
expectFolder string
|
|
expectSplit []string
|
|
}{
|
|
{
|
|
name: "clean path",
|
|
p: func(t *testing.T) Path {
|
|
p, err := Builder{}.
|
|
Append("a", "b", "c").
|
|
ToDataLayerExchangePathForCategory("t", "u", EmailCategory, false)
|
|
require.NoError(t, err, clues.ToCore(err))
|
|
|
|
return p
|
|
},
|
|
expectFolder: "a/b/c",
|
|
expectSplit: []string{"a", "b", "c"},
|
|
},
|
|
{
|
|
name: "clean path escaped",
|
|
p: func(t *testing.T) Path {
|
|
p, err := Builder{}.
|
|
Append("a", "b", "c").
|
|
ToDataLayerExchangePathForCategory("t", "u", EmailCategory, false)
|
|
require.NoError(t, err, clues.ToCore(err))
|
|
|
|
return p
|
|
},
|
|
escape: true,
|
|
expectFolder: "a/b/c",
|
|
expectSplit: []string{"a", "b", "c"},
|
|
},
|
|
{
|
|
name: "escapable path",
|
|
p: func(t *testing.T) Path {
|
|
p, err := Builder{}.
|
|
Append("a/", "b", "c").
|
|
ToDataLayerExchangePathForCategory("t", "u", EmailCategory, false)
|
|
require.NoError(t, err, clues.ToCore(err))
|
|
|
|
return p
|
|
},
|
|
expectFolder: "a//b/c",
|
|
expectSplit: []string{"a", "b", "c"},
|
|
},
|
|
{
|
|
name: "escapable path escaped",
|
|
p: func(t *testing.T) Path {
|
|
p, err := Builder{}.
|
|
Append("a/", "b", "c").
|
|
ToDataLayerExchangePathForCategory("t", "u", EmailCategory, false)
|
|
require.NoError(t, err, clues.ToCore(err))
|
|
|
|
return p
|
|
},
|
|
escape: true,
|
|
expectFolder: "a\\//b/c",
|
|
expectSplit: []string{"a\\/", "b", "c"},
|
|
},
|
|
}
|
|
for _, test := range table {
|
|
suite.Run(test.name, func() {
|
|
t := suite.T()
|
|
|
|
p := test.p(t)
|
|
result := p.Folder(test.escape)
|
|
assert.Equal(t, test.expectFolder, result)
|
|
assert.Equal(t, test.expectSplit, Split(result))
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestFromString() {
|
|
const (
|
|
testTenant = "tenant"
|
|
testUser = "user"
|
|
testElement1 = "folder/"
|
|
testElementTrimmed = "folder"
|
|
testElement2 = "folder2"
|
|
testElement3 = "other"
|
|
)
|
|
|
|
isItem := []struct {
|
|
name string
|
|
isItem bool
|
|
}{
|
|
{
|
|
name: "Folder",
|
|
isItem: false,
|
|
},
|
|
{
|
|
name: "Item",
|
|
isItem: true,
|
|
},
|
|
}
|
|
table := []struct {
|
|
name string
|
|
// Should have placeholders of '%s' for service and category.
|
|
unescapedPath string
|
|
// Expected result for Folder() if path is marked as a folder.
|
|
expectedFolder string
|
|
// Expected result for Item() if path is marked as an item.
|
|
// Expected result for Split(Folder()) if path is marked as a folder.
|
|
expectedSplit []string
|
|
expectedItem string
|
|
// Expected result for Folder() if path is marked as an item.
|
|
expectedItemFolder string
|
|
// Expected result for Split(Folder()) if path is marked as an item.
|
|
expectedItemSplit []string
|
|
}{
|
|
{
|
|
name: "BasicPath",
|
|
unescapedPath: fmt.Sprintf(
|
|
"%s/%%s/%s/%%s/%s/%s/%s",
|
|
testTenant,
|
|
testUser,
|
|
testElement1,
|
|
testElement2,
|
|
testElement3,
|
|
),
|
|
expectedFolder: fmt.Sprintf(
|
|
"%s/%s/%s",
|
|
testElementTrimmed,
|
|
testElement2,
|
|
testElement3,
|
|
),
|
|
expectedSplit: []string{
|
|
testElementTrimmed,
|
|
testElement2,
|
|
testElement3,
|
|
},
|
|
expectedItem: testElement3,
|
|
expectedItemFolder: fmt.Sprintf(
|
|
"%s/%s",
|
|
testElementTrimmed,
|
|
testElement2,
|
|
),
|
|
expectedItemSplit: []string{
|
|
testElementTrimmed,
|
|
testElement2,
|
|
},
|
|
},
|
|
{
|
|
name: "PathWithEmptyElements",
|
|
unescapedPath: fmt.Sprintf(
|
|
"/%s//%%s//%s//%%s//%s///%s//%s//",
|
|
testTenant,
|
|
testUser,
|
|
testElementTrimmed,
|
|
testElement2,
|
|
testElement3,
|
|
),
|
|
expectedFolder: fmt.Sprintf(
|
|
"%s/%s/%s",
|
|
testElementTrimmed,
|
|
testElement2,
|
|
testElement3,
|
|
),
|
|
expectedSplit: []string{
|
|
testElementTrimmed,
|
|
testElement2,
|
|
testElement3,
|
|
},
|
|
expectedItem: testElement3,
|
|
expectedItemFolder: fmt.Sprintf(
|
|
"%s/%s",
|
|
testElementTrimmed,
|
|
testElement2,
|
|
),
|
|
expectedItemSplit: []string{
|
|
testElementTrimmed,
|
|
testElement2,
|
|
},
|
|
},
|
|
}
|
|
|
|
for service, cats := range serviceCategories {
|
|
for cat := range cats {
|
|
for _, item := range isItem {
|
|
suite.Run(fmt.Sprintf("%s-%s-%s", service, cat, item.name), func() {
|
|
for _, test := range table {
|
|
suite.Run(test.name, func() {
|
|
t := suite.T()
|
|
testPath := fmt.Sprintf(test.unescapedPath, service, cat)
|
|
|
|
p, err := FromDataLayerPath(testPath, item.isItem)
|
|
require.NoError(t, err, clues.ToCore(err))
|
|
|
|
assert.Equal(t, service, p.Service(), "service")
|
|
assert.Equal(t, cat, p.Category(), "category")
|
|
assert.Equal(t, testTenant, p.Tenant(), "tenant")
|
|
assert.Equal(t, testUser, p.ResourceOwner(), "resource owner")
|
|
|
|
fld := p.Folder(false)
|
|
escfld := p.Folder(true)
|
|
|
|
if item.isItem {
|
|
assert.Equal(t, test.expectedItemFolder, fld, "item folder")
|
|
assert.Equal(t, test.expectedItemSplit, Split(fld), "item split")
|
|
assert.Equal(t, test.expectedItemFolder, escfld, "escaped item folder")
|
|
assert.Equal(t, test.expectedItemSplit, Split(escfld), "escaped item split")
|
|
assert.Equal(t, test.expectedItem, p.Item(), "item")
|
|
} else {
|
|
assert.Equal(t, test.expectedFolder, fld, "dir folder")
|
|
assert.Equal(t, test.expectedSplit, Split(fld), "dir split")
|
|
assert.Equal(t, test.expectedFolder, escfld, "escaped dir folder")
|
|
assert.Equal(t, test.expectedSplit, Split(escfld), "escaped dir split")
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestPath_piiHandling() {
|
|
p, err := Build("t", "ro", ExchangeService, EventsCategory, true, "dir", "item")
|
|
require.NoError(suite.T(), err)
|
|
|
|
table := []struct {
|
|
name string
|
|
p Path
|
|
expect string
|
|
expectPlain string
|
|
}{
|
|
{
|
|
name: "standard path",
|
|
p: p,
|
|
expect: "***/exchange/***/events/***/***",
|
|
expectPlain: "t/exchange/ro/events/dir/item",
|
|
},
|
|
}
|
|
for _, test := range table {
|
|
suite.Run(test.name, func() {
|
|
t := suite.T()
|
|
|
|
assert.Equal(t, test.expect, test.p.Conceal(), "conceal")
|
|
assert.Equal(t, test.expectPlain, test.p.String(), "string")
|
|
assert.Equal(t, test.expect, fmt.Sprintf("%s", test.p), "fmt %%s")
|
|
assert.Equal(t, test.expect, fmt.Sprintf("%+v", test.p), "fmt %%+v")
|
|
assert.Equal(t, test.expectPlain, test.p.PlainString(), "plain")
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *PathUnitSuite) TestToServicePrefix() {
|
|
table := []struct {
|
|
name string
|
|
service ServiceType
|
|
category CategoryType
|
|
tenant string
|
|
owner string
|
|
expect string
|
|
expectErr require.ErrorAssertionFunc
|
|
}{
|
|
{
|
|
name: "ok",
|
|
service: ExchangeService,
|
|
category: ContactsCategory,
|
|
tenant: "t",
|
|
owner: "ro",
|
|
expect: join([]string{"t", ExchangeService.String(), "ro", ContactsCategory.String()}),
|
|
expectErr: require.NoError,
|
|
},
|
|
{
|
|
name: "bad category",
|
|
service: ExchangeService,
|
|
category: FilesCategory,
|
|
tenant: "t",
|
|
owner: "ro",
|
|
expectErr: require.Error,
|
|
},
|
|
{
|
|
name: "bad tenant",
|
|
service: ExchangeService,
|
|
category: ContactsCategory,
|
|
tenant: "",
|
|
owner: "ro",
|
|
expectErr: require.Error,
|
|
},
|
|
{
|
|
name: "bad owner",
|
|
service: ExchangeService,
|
|
category: ContactsCategory,
|
|
tenant: "t",
|
|
owner: "",
|
|
expectErr: require.Error,
|
|
},
|
|
}
|
|
for _, test := range table {
|
|
suite.Run(test.name, func() {
|
|
t := suite.T()
|
|
|
|
r, err := ServicePrefix(test.tenant, test.owner, test.service, test.category)
|
|
test.expectErr(t, err, clues.ToCore(err))
|
|
|
|
if r == nil {
|
|
return
|
|
}
|
|
|
|
assert.Equal(t, test.expect, r.String())
|
|
assert.NotPanics(t, func() {
|
|
r.Folders()
|
|
r.Item()
|
|
}, "runs Folders() and Item()")
|
|
})
|
|
}
|
|
}
|