2020-04-25 19:55:18 +02:00
|
|
|
package seafile
|
|
|
|
|
|
|
|
import (
|
2021-09-17 23:48:19 +02:00
|
|
|
"context"
|
2020-04-25 19:55:18 +02:00
|
|
|
"path"
|
|
|
|
"testing"
|
|
|
|
|
2021-09-17 23:48:19 +02:00
|
|
|
"github.com/rclone/rclone/fs"
|
|
|
|
"github.com/rclone/rclone/fs/config/configmap"
|
|
|
|
"github.com/rclone/rclone/fs/config/obscure"
|
2020-04-25 19:55:18 +02:00
|
|
|
"github.com/stretchr/testify/assert"
|
2021-09-17 23:48:19 +02:00
|
|
|
"github.com/stretchr/testify/require"
|
2020-04-25 19:55:18 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
type pathData struct {
|
|
|
|
configLibrary string // Library specified in the config
|
|
|
|
configRoot string // Root directory specified in the config
|
|
|
|
argumentPath string // Path given as an argument in the command line
|
|
|
|
expectedLibrary string
|
|
|
|
expectedPath string
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test the method to split a library name and a path
|
|
|
|
// from a mix of configuration data and path command line argument
|
|
|
|
func TestSplitPath(t *testing.T) {
|
|
|
|
testData := []pathData{
|
2021-09-17 23:48:19 +02:00
|
|
|
{
|
2020-04-25 19:55:18 +02:00
|
|
|
configLibrary: "",
|
|
|
|
configRoot: "",
|
|
|
|
argumentPath: "",
|
|
|
|
expectedLibrary: "",
|
|
|
|
expectedPath: "",
|
|
|
|
},
|
2021-09-17 23:48:19 +02:00
|
|
|
{
|
2020-04-25 19:55:18 +02:00
|
|
|
configLibrary: "",
|
|
|
|
configRoot: "",
|
|
|
|
argumentPath: "Library",
|
|
|
|
expectedLibrary: "Library",
|
|
|
|
expectedPath: "",
|
|
|
|
},
|
2021-09-17 23:48:19 +02:00
|
|
|
{
|
2020-04-25 19:55:18 +02:00
|
|
|
configLibrary: "",
|
|
|
|
configRoot: "",
|
|
|
|
argumentPath: path.Join("Library", "path", "to", "file"),
|
|
|
|
expectedLibrary: "Library",
|
|
|
|
expectedPath: path.Join("path", "to", "file"),
|
|
|
|
},
|
2021-09-17 23:48:19 +02:00
|
|
|
{
|
2020-04-25 19:55:18 +02:00
|
|
|
configLibrary: "Library",
|
|
|
|
configRoot: "",
|
|
|
|
argumentPath: "",
|
|
|
|
expectedLibrary: "Library",
|
|
|
|
expectedPath: "",
|
|
|
|
},
|
2021-09-17 23:48:19 +02:00
|
|
|
{
|
2020-04-25 19:55:18 +02:00
|
|
|
configLibrary: "Library",
|
|
|
|
configRoot: "",
|
|
|
|
argumentPath: "path",
|
|
|
|
expectedLibrary: "Library",
|
|
|
|
expectedPath: "path",
|
|
|
|
},
|
2021-09-17 23:48:19 +02:00
|
|
|
{
|
2020-04-25 19:55:18 +02:00
|
|
|
configLibrary: "Library",
|
|
|
|
configRoot: "",
|
|
|
|
argumentPath: path.Join("path", "to", "file"),
|
|
|
|
expectedLibrary: "Library",
|
|
|
|
expectedPath: path.Join("path", "to", "file"),
|
|
|
|
},
|
2021-09-17 23:48:19 +02:00
|
|
|
{
|
2020-04-25 19:55:18 +02:00
|
|
|
configLibrary: "Library",
|
|
|
|
configRoot: "root",
|
|
|
|
argumentPath: "",
|
|
|
|
expectedLibrary: "Library",
|
|
|
|
expectedPath: "root",
|
|
|
|
},
|
2021-09-17 23:48:19 +02:00
|
|
|
{
|
2020-04-25 19:55:18 +02:00
|
|
|
configLibrary: "Library",
|
|
|
|
configRoot: path.Join("root", "path"),
|
|
|
|
argumentPath: "",
|
|
|
|
expectedLibrary: "Library",
|
|
|
|
expectedPath: path.Join("root", "path"),
|
|
|
|
},
|
2021-09-17 23:48:19 +02:00
|
|
|
{
|
2020-04-25 19:55:18 +02:00
|
|
|
configLibrary: "Library",
|
|
|
|
configRoot: "root",
|
|
|
|
argumentPath: "path",
|
|
|
|
expectedLibrary: "Library",
|
|
|
|
expectedPath: path.Join("root", "path"),
|
|
|
|
},
|
2021-09-17 23:48:19 +02:00
|
|
|
{
|
2020-04-25 19:55:18 +02:00
|
|
|
configLibrary: "Library",
|
|
|
|
configRoot: "root",
|
|
|
|
argumentPath: path.Join("path", "to", "file"),
|
|
|
|
expectedLibrary: "Library",
|
|
|
|
expectedPath: path.Join("root", "path", "to", "file"),
|
|
|
|
},
|
2021-09-17 23:48:19 +02:00
|
|
|
{
|
2020-04-25 19:55:18 +02:00
|
|
|
configLibrary: "Library",
|
|
|
|
configRoot: path.Join("root", "path"),
|
|
|
|
argumentPath: path.Join("subpath", "to", "file"),
|
|
|
|
expectedLibrary: "Library",
|
|
|
|
expectedPath: path.Join("root", "path", "subpath", "to", "file"),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, test := range testData {
|
|
|
|
fs := &Fs{
|
|
|
|
libraryName: test.configLibrary,
|
|
|
|
rootDirectory: test.configRoot,
|
|
|
|
}
|
|
|
|
libraryName, path := fs.splitPath(test.argumentPath)
|
|
|
|
|
|
|
|
assert.Equal(t, test.expectedLibrary, libraryName)
|
|
|
|
assert.Equal(t, test.expectedPath, path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSplitPathIntoSlice(t *testing.T) {
|
|
|
|
testData := map[string][]string{
|
|
|
|
"1": {"1"},
|
|
|
|
"/1": {"1"},
|
|
|
|
"/1/": {"1"},
|
|
|
|
"1/2/3": {"1", "2", "3"},
|
|
|
|
}
|
|
|
|
for input, expected := range testData {
|
|
|
|
output := splitPath(input)
|
|
|
|
assert.Equal(t, expected, output)
|
|
|
|
}
|
|
|
|
}
|
2021-09-17 23:48:19 +02:00
|
|
|
|
|
|
|
func Test2FAStateMachine(t *testing.T) {
|
|
|
|
fixtures := []struct {
|
|
|
|
name string
|
|
|
|
mapper configmap.Mapper
|
|
|
|
input fs.ConfigIn
|
|
|
|
expectState string
|
|
|
|
expectErrorMessage string
|
|
|
|
expectResult string
|
|
|
|
expectFail bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "no url",
|
|
|
|
mapper: configmap.Simple{},
|
|
|
|
input: fs.ConfigIn{State: ""},
|
|
|
|
expectFail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "2fa not set",
|
|
|
|
mapper: configmap.Simple{"url": "http://localhost/"},
|
|
|
|
input: fs.ConfigIn{State: ""},
|
|
|
|
expectFail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "unknown state",
|
|
|
|
mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"},
|
|
|
|
input: fs.ConfigIn{State: "unknown"},
|
|
|
|
expectFail: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no password in config",
|
|
|
|
mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"},
|
|
|
|
input: fs.ConfigIn{State: ""},
|
|
|
|
expectState: "password",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "config ready for 2fa token",
|
|
|
|
mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username", "pass": obscure.MustObscure("password")},
|
|
|
|
input: fs.ConfigIn{State: ""},
|
|
|
|
expectState: "2fa",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "password not entered",
|
|
|
|
mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"},
|
|
|
|
input: fs.ConfigIn{State: "password"},
|
|
|
|
expectState: "",
|
|
|
|
expectErrorMessage: "Password can't be blank",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "password entered",
|
|
|
|
mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"},
|
|
|
|
input: fs.ConfigIn{State: "password", Result: "password"},
|
|
|
|
expectState: "2fa",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "ask for a 2fa code",
|
|
|
|
mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"},
|
|
|
|
input: fs.ConfigIn{State: "2fa"},
|
|
|
|
expectState: "2fa_do",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "no 2fa code entered",
|
|
|
|
mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"},
|
|
|
|
input: fs.ConfigIn{State: "2fa_do"},
|
|
|
|
expectState: "2fa", // ask for a code again
|
|
|
|
expectErrorMessage: "2FA codes can't be blank",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "2fa error and retry",
|
|
|
|
mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"},
|
|
|
|
input: fs.ConfigIn{State: "2fa_error", Result: "true"},
|
|
|
|
expectState: "2fa", // ask for a code again
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "2fa error and fail",
|
|
|
|
mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"},
|
|
|
|
input: fs.ConfigIn{State: "2fa_error"},
|
|
|
|
expectFail: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, fixture := range fixtures {
|
|
|
|
t.Run(fixture.name, func(t *testing.T) {
|
|
|
|
output, err := Config(context.Background(), "test", fixture.mapper, fixture.input)
|
|
|
|
if fixture.expectFail {
|
|
|
|
require.Error(t, err)
|
|
|
|
t.Log(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
assert.Equal(t, fixture.expectState, output.State)
|
|
|
|
assert.Equal(t, fixture.expectErrorMessage, output.Error)
|
|
|
|
assert.Equal(t, fixture.expectResult, output.Result)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|