github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/backend/seafile/seafile_internal_test.go (about) 1 package seafile 2 3 import ( 4 "context" 5 "path" 6 "testing" 7 8 "github.com/rclone/rclone/fs" 9 "github.com/rclone/rclone/fs/config/configmap" 10 "github.com/rclone/rclone/fs/config/obscure" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 type pathData struct { 16 configLibrary string // Library specified in the config 17 configRoot string // Root directory specified in the config 18 argumentPath string // Path given as an argument in the command line 19 expectedLibrary string 20 expectedPath string 21 } 22 23 // Test the method to split a library name and a path 24 // from a mix of configuration data and path command line argument 25 func TestSplitPath(t *testing.T) { 26 testData := []pathData{ 27 { 28 configLibrary: "", 29 configRoot: "", 30 argumentPath: "", 31 expectedLibrary: "", 32 expectedPath: "", 33 }, 34 { 35 configLibrary: "", 36 configRoot: "", 37 argumentPath: "Library", 38 expectedLibrary: "Library", 39 expectedPath: "", 40 }, 41 { 42 configLibrary: "", 43 configRoot: "", 44 argumentPath: path.Join("Library", "path", "to", "file"), 45 expectedLibrary: "Library", 46 expectedPath: path.Join("path", "to", "file"), 47 }, 48 { 49 configLibrary: "Library", 50 configRoot: "", 51 argumentPath: "", 52 expectedLibrary: "Library", 53 expectedPath: "", 54 }, 55 { 56 configLibrary: "Library", 57 configRoot: "", 58 argumentPath: "path", 59 expectedLibrary: "Library", 60 expectedPath: "path", 61 }, 62 { 63 configLibrary: "Library", 64 configRoot: "", 65 argumentPath: path.Join("path", "to", "file"), 66 expectedLibrary: "Library", 67 expectedPath: path.Join("path", "to", "file"), 68 }, 69 { 70 configLibrary: "Library", 71 configRoot: "root", 72 argumentPath: "", 73 expectedLibrary: "Library", 74 expectedPath: "root", 75 }, 76 { 77 configLibrary: "Library", 78 configRoot: path.Join("root", "path"), 79 argumentPath: "", 80 expectedLibrary: "Library", 81 expectedPath: path.Join("root", "path"), 82 }, 83 { 84 configLibrary: "Library", 85 configRoot: "root", 86 argumentPath: "path", 87 expectedLibrary: "Library", 88 expectedPath: path.Join("root", "path"), 89 }, 90 { 91 configLibrary: "Library", 92 configRoot: "root", 93 argumentPath: path.Join("path", "to", "file"), 94 expectedLibrary: "Library", 95 expectedPath: path.Join("root", "path", "to", "file"), 96 }, 97 { 98 configLibrary: "Library", 99 configRoot: path.Join("root", "path"), 100 argumentPath: path.Join("subpath", "to", "file"), 101 expectedLibrary: "Library", 102 expectedPath: path.Join("root", "path", "subpath", "to", "file"), 103 }, 104 } 105 for _, test := range testData { 106 fs := &Fs{ 107 libraryName: test.configLibrary, 108 rootDirectory: test.configRoot, 109 } 110 libraryName, path := fs.splitPath(test.argumentPath) 111 112 assert.Equal(t, test.expectedLibrary, libraryName) 113 assert.Equal(t, test.expectedPath, path) 114 } 115 } 116 117 func TestSplitPathIntoSlice(t *testing.T) { 118 testData := map[string][]string{ 119 "1": {"1"}, 120 "/1": {"1"}, 121 "/1/": {"1"}, 122 "1/2/3": {"1", "2", "3"}, 123 } 124 for input, expected := range testData { 125 output := splitPath(input) 126 assert.Equal(t, expected, output) 127 } 128 } 129 130 func Test2FAStateMachine(t *testing.T) { 131 fixtures := []struct { 132 name string 133 mapper configmap.Mapper 134 input fs.ConfigIn 135 expectState string 136 expectErrorMessage string 137 expectResult string 138 expectFail bool 139 expectNil bool 140 }{ 141 { 142 name: "no url", 143 mapper: configmap.Simple{}, 144 input: fs.ConfigIn{State: ""}, 145 expectFail: true, 146 }, 147 { 148 name: "unknown state", 149 mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"}, 150 input: fs.ConfigIn{State: "unknown"}, 151 expectFail: true, 152 }, 153 { 154 name: "2fa not set", 155 mapper: configmap.Simple{"url": "http://localhost/"}, 156 input: fs.ConfigIn{State: ""}, 157 expectNil: true, 158 }, 159 { 160 name: "no password in config", 161 mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"}, 162 input: fs.ConfigIn{State: ""}, 163 expectState: "password", 164 }, 165 { 166 name: "config ready for 2fa token", 167 mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username", "pass": obscure.MustObscure("password")}, 168 input: fs.ConfigIn{State: ""}, 169 expectState: "2fa", 170 }, 171 { 172 name: "password not entered", 173 mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"}, 174 input: fs.ConfigIn{State: "password"}, 175 expectState: "", 176 expectErrorMessage: "Password can't be blank", 177 }, 178 { 179 name: "password entered", 180 mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"}, 181 input: fs.ConfigIn{State: "password", Result: "password"}, 182 expectState: "2fa", 183 }, 184 { 185 name: "ask for a 2fa code", 186 mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"}, 187 input: fs.ConfigIn{State: "2fa"}, 188 expectState: "2fa_do", 189 }, 190 { 191 name: "no 2fa code entered", 192 mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"}, 193 input: fs.ConfigIn{State: "2fa_do"}, 194 expectState: "2fa", // ask for a code again 195 expectErrorMessage: "2FA codes can't be blank", 196 }, 197 { 198 name: "2fa error and retry", 199 mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"}, 200 input: fs.ConfigIn{State: "2fa_error", Result: "true"}, 201 expectState: "2fa", // ask for a code again 202 }, 203 { 204 name: "2fa error and fail", 205 mapper: configmap.Simple{"url": "http://localhost/", "2fa": "true", "user": "username"}, 206 input: fs.ConfigIn{State: "2fa_error"}, 207 expectFail: true, 208 }, 209 } 210 211 for _, fixture := range fixtures { 212 t.Run(fixture.name, func(t *testing.T) { 213 output, err := Config(context.Background(), "test", fixture.mapper, fixture.input) 214 if fixture.expectFail { 215 require.Error(t, err) 216 t.Log(err) 217 return 218 } 219 if fixture.expectNil { 220 require.Nil(t, output) 221 return 222 } 223 assert.Equal(t, fixture.expectState, output.State) 224 assert.Equal(t, fixture.expectErrorMessage, output.Error) 225 assert.Equal(t, fixture.expectResult, output.Result) 226 }) 227 } 228 }