corso/src/internal/kopia/path_encoder_test.go
ashmrtn 423b6e19f7
Encode paths given to kopia (#892)
## Description

Encode all paths given to kopia with base64URL to ensure no special characters that kopia can't handle end up in there. The encoded paths are not stored in backup details nor are they ever surfaced to the user. This also works around the previous limitation where Corso was unable to properly backup or restore exchange email layouts that had folders containing `/` characters

## Type of change

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

## Issue(s)

* closes #865

## Test Plan

<!-- How will this be tested prior to merging.-->
- [ ] 💪 Manual
- [x]  Unit test
- [x] 💚 E2E
2022-09-19 16:49:33 +00:00

100 lines
2.1 KiB
Go

package kopia
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
type PathEncoderSuite struct {
suite.Suite
}
func TestPathEncoderSuite(t *testing.T) {
suite.Run(t, new(PathEncoderSuite))
}
func (suite *PathEncoderSuite) TestEncodeDecode() {
t := suite.T()
elements := []string{"these", "are", "some", "path", "elements"}
encoded := encodeElements(elements...)
decoded := make([]string, 0, len(elements))
for _, e := range encoded {
dec, err := decodeElement(e)
require.NoError(t, err)
decoded = append(decoded, dec)
}
assert.Equal(t, elements, decoded)
}
func (suite *PathEncoderSuite) TestEncodeAsPathDecode() {
table := []struct {
name string
elements []string
expected []string
}{
{
name: "MultipleElements",
elements: []string{"these", "are", "some", "path", "elements"},
expected: []string{"these", "are", "some", "path", "elements"},
},
{
name: "SingleElement",
elements: []string{"elements"},
expected: []string{"elements"},
},
{
name: "EmptyPath",
elements: []string{""},
expected: []string{""},
},
{
name: "NilPath",
elements: nil,
// Gets "" back because individual elements are decoded and "" is the 0
// value for the decoder.
expected: []string{""},
},
}
for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) {
encoded := encodeAsPath(test.elements...)
// Sanity check, first and last character should not be '/'.
assert.Equal(t, strings.Trim(encoded, "/"), encoded)
decoded := make([]string, 0, len(test.elements))
for _, e := range strings.Split(encoded, "/") {
dec, err := decodeElement(e)
require.NoError(t, err)
decoded = append(decoded, dec)
}
assert.Equal(t, test.expected, decoded)
})
}
}
func FuzzEncodeDecodeSingleString(f *testing.F) {
f.Fuzz(func(t *testing.T, in string) {
encoded := encodeElements(in)
assert.Len(t, encoded, 1)
assert.False(t, strings.ContainsRune(encoded[0], '/'))
decoded, err := decodeElement(encoded[0])
require.NoError(t, err)
assert.Equal(t, in, decoded)
})
}