github.com/ncw/rclone@v1.48.1-0.20190724201158-a35aa1360e3e/backend/googlephotos/googlephotos_test.go (about) 1 package googlephotos 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "net/http" 8 "path" 9 "testing" 10 "time" 11 12 _ "github.com/ncw/rclone/backend/local" 13 "github.com/ncw/rclone/fs" 14 "github.com/ncw/rclone/fs/hash" 15 "github.com/ncw/rclone/fstest" 16 "github.com/stretchr/testify/assert" 17 "github.com/stretchr/testify/require" 18 ) 19 20 const ( 21 // We have two different files here as Google Photos will uniq 22 // them otherwise which confuses the tests as the filename is 23 // unexpected. 24 fileNameAlbum = "rclone-test-image1.jpg" 25 fileNameUpload = "rclone-test-image2.jpg" 26 ) 27 28 // Wrapper to override the remote for an object 29 type overrideRemoteObject struct { 30 fs.Object 31 remote string 32 } 33 34 // Remote returns the overridden remote name 35 func (o *overrideRemoteObject) Remote() string { 36 return o.remote 37 } 38 39 func TestIntegration(t *testing.T) { 40 ctx := context.Background() 41 fstest.Initialise() 42 43 // Create Fs 44 if *fstest.RemoteName == "" { 45 *fstest.RemoteName = "TestGooglePhotos:" 46 } 47 f, err := fs.NewFs(*fstest.RemoteName) 48 if err == fs.ErrorNotFoundInConfigFile { 49 t.Skip(fmt.Sprintf("Couldn't create google photos backend - skipping tests: %v", err)) 50 } 51 require.NoError(t, err) 52 53 // Create local Fs pointing at testfiles 54 localFs, err := fs.NewFs("testfiles") 55 require.NoError(t, err) 56 57 t.Run("CreateAlbum", func(t *testing.T) { 58 albumName := "album/rclone-test-" + fstest.RandomString(24) 59 err = f.Mkdir(ctx, albumName) 60 require.NoError(t, err) 61 remote := albumName + "/" + fileNameAlbum 62 63 t.Run("PutFile", func(t *testing.T) { 64 srcObj, err := localFs.NewObject(ctx, fileNameAlbum) 65 require.NoError(t, err) 66 in, err := srcObj.Open(ctx) 67 require.NoError(t, err) 68 dstObj, err := f.Put(ctx, in, &overrideRemoteObject{srcObj, remote}) 69 require.NoError(t, err) 70 assert.Equal(t, remote, dstObj.Remote()) 71 _ = in.Close() 72 remoteWithID := addFileID(remote, dstObj.(*Object).id) 73 74 t.Run("ObjectFs", func(t *testing.T) { 75 assert.Equal(t, f, dstObj.Fs()) 76 }) 77 78 t.Run("ObjectString", func(t *testing.T) { 79 assert.Equal(t, remote, dstObj.String()) 80 assert.Equal(t, "<nil>", (*Object)(nil).String()) 81 }) 82 83 t.Run("ObjectHash", func(t *testing.T) { 84 h, err := dstObj.Hash(ctx, hash.MD5) 85 assert.Equal(t, "", h) 86 assert.Equal(t, hash.ErrUnsupported, err) 87 }) 88 89 t.Run("ObjectSize", func(t *testing.T) { 90 assert.Equal(t, int64(-1), dstObj.Size()) 91 f.(*Fs).opt.ReadSize = true 92 defer func() { 93 f.(*Fs).opt.ReadSize = false 94 }() 95 size := dstObj.Size() 96 assert.True(t, size > 1000, fmt.Sprintf("Size too small %d", size)) 97 }) 98 99 t.Run("ObjectSetModTime", func(t *testing.T) { 100 err := dstObj.SetModTime(ctx, time.Now()) 101 assert.Equal(t, fs.ErrorCantSetModTime, err) 102 }) 103 104 t.Run("ObjectStorable", func(t *testing.T) { 105 assert.True(t, dstObj.Storable()) 106 }) 107 108 t.Run("ObjectOpen", func(t *testing.T) { 109 in, err := dstObj.Open(ctx) 110 require.NoError(t, err) 111 buf, err := ioutil.ReadAll(in) 112 require.NoError(t, err) 113 require.NoError(t, in.Close()) 114 assert.True(t, len(buf) > 1000) 115 contentType := http.DetectContentType(buf[:512]) 116 assert.Equal(t, "image/jpeg", contentType) 117 }) 118 119 t.Run("CheckFileInAlbum", func(t *testing.T) { 120 entries, err := f.List(ctx, albumName) 121 require.NoError(t, err) 122 assert.Equal(t, 1, len(entries)) 123 assert.Equal(t, remote, entries[0].Remote()) 124 assert.Equal(t, "2013-07-26 08:57:21 +0000 UTC", entries[0].ModTime(ctx).String()) 125 }) 126 127 // Check it is there in the date/month/year heirachy 128 // 2013-07-13 is the creation date of the folder 129 checkPresent := func(t *testing.T, objPath string) { 130 entries, err := f.List(ctx, objPath) 131 require.NoError(t, err) 132 found := false 133 for _, entry := range entries { 134 leaf := path.Base(entry.Remote()) 135 if leaf == fileNameAlbum || leaf == remoteWithID { 136 found = true 137 } 138 } 139 assert.True(t, found, fmt.Sprintf("didn't find %q in %q", fileNameAlbum, objPath)) 140 } 141 142 t.Run("CheckInByYear", func(t *testing.T) { 143 checkPresent(t, "media/by-year/2013") 144 }) 145 146 t.Run("CheckInByMonth", func(t *testing.T) { 147 checkPresent(t, "media/by-month/2013/2013-07") 148 }) 149 150 t.Run("CheckInByDay", func(t *testing.T) { 151 checkPresent(t, "media/by-day/2013/2013-07-26") 152 }) 153 154 t.Run("NewObject", func(t *testing.T) { 155 o, err := f.NewObject(ctx, remote) 156 require.NoError(t, err) 157 require.Equal(t, remote, o.Remote()) 158 }) 159 160 t.Run("NewObjectWithID", func(t *testing.T) { 161 o, err := f.NewObject(ctx, remoteWithID) 162 require.NoError(t, err) 163 require.Equal(t, remoteWithID, o.Remote()) 164 }) 165 166 t.Run("NewFsIsFile", func(t *testing.T) { 167 fNew, err := fs.NewFs(*fstest.RemoteName + remote) 168 assert.Equal(t, fs.ErrorIsFile, err) 169 leaf := path.Base(remote) 170 o, err := fNew.NewObject(ctx, leaf) 171 require.NoError(t, err) 172 require.Equal(t, leaf, o.Remote()) 173 }) 174 175 t.Run("RemoveFileFromAlbum", func(t *testing.T) { 176 err = dstObj.Remove(ctx) 177 require.NoError(t, err) 178 179 time.Sleep(time.Second) 180 181 // Check album empty 182 entries, err := f.List(ctx, albumName) 183 require.NoError(t, err) 184 assert.Equal(t, 0, len(entries)) 185 }) 186 }) 187 188 // remove the album 189 err = f.Rmdir(ctx, albumName) 190 require.Error(t, err) // FIXME doesn't work yet 191 }) 192 193 t.Run("UploadMkdir", func(t *testing.T) { 194 assert.NoError(t, f.Mkdir(ctx, "upload/dir")) 195 assert.NoError(t, f.Mkdir(ctx, "upload/dir/subdir")) 196 197 t.Run("List", func(t *testing.T) { 198 entries, err := f.List(ctx, "upload") 199 require.NoError(t, err) 200 assert.Equal(t, 1, len(entries)) 201 assert.Equal(t, "upload/dir", entries[0].Remote()) 202 203 entries, err = f.List(ctx, "upload/dir") 204 require.NoError(t, err) 205 assert.Equal(t, 1, len(entries)) 206 assert.Equal(t, "upload/dir/subdir", entries[0].Remote()) 207 }) 208 209 t.Run("Rmdir", func(t *testing.T) { 210 assert.NoError(t, f.Rmdir(ctx, "upload/dir/subdir")) 211 assert.NoError(t, f.Rmdir(ctx, "upload/dir")) 212 213 }) 214 215 t.Run("ListEmpty", func(t *testing.T) { 216 entries, err := f.List(ctx, "upload") 217 require.NoError(t, err) 218 assert.Equal(t, 0, len(entries)) 219 220 _, err = f.List(ctx, "upload/dir") 221 assert.Equal(t, fs.ErrorDirNotFound, err) 222 }) 223 }) 224 225 t.Run("Upload", func(t *testing.T) { 226 uploadDir := "upload/dir/subdir" 227 remote := path.Join(uploadDir, fileNameUpload) 228 229 srcObj, err := localFs.NewObject(ctx, fileNameUpload) 230 require.NoError(t, err) 231 in, err := srcObj.Open(ctx) 232 require.NoError(t, err) 233 dstObj, err := f.Put(ctx, in, &overrideRemoteObject{srcObj, remote}) 234 require.NoError(t, err) 235 assert.Equal(t, remote, dstObj.Remote()) 236 _ = in.Close() 237 remoteWithID := addFileID(remote, dstObj.(*Object).id) 238 239 t.Run("List", func(t *testing.T) { 240 entries, err := f.List(ctx, uploadDir) 241 require.NoError(t, err) 242 require.Equal(t, 1, len(entries)) 243 assert.Equal(t, remote, entries[0].Remote()) 244 assert.Equal(t, "2013-07-26 08:57:21 +0000 UTC", entries[0].ModTime(ctx).String()) 245 }) 246 247 t.Run("NewObject", func(t *testing.T) { 248 o, err := f.NewObject(ctx, remote) 249 require.NoError(t, err) 250 require.Equal(t, remote, o.Remote()) 251 }) 252 253 t.Run("NewObjectWithID", func(t *testing.T) { 254 o, err := f.NewObject(ctx, remoteWithID) 255 require.NoError(t, err) 256 require.Equal(t, remoteWithID, o.Remote()) 257 }) 258 259 }) 260 261 t.Run("Name", func(t *testing.T) { 262 assert.Equal(t, (*fstest.RemoteName)[:len(*fstest.RemoteName)-1], f.Name()) 263 }) 264 265 t.Run("Root", func(t *testing.T) { 266 assert.Equal(t, "", f.Root()) 267 }) 268 269 t.Run("String", func(t *testing.T) { 270 assert.Equal(t, `Google Photos path ""`, f.String()) 271 }) 272 273 t.Run("Features", func(t *testing.T) { 274 features := f.Features() 275 assert.False(t, features.CaseInsensitive) 276 assert.True(t, features.ReadMimeType) 277 }) 278 279 t.Run("Precision", func(t *testing.T) { 280 assert.Equal(t, fs.ModTimeNotSupported, f.Precision()) 281 }) 282 283 t.Run("Hashes", func(t *testing.T) { 284 assert.Equal(t, hash.Set(hash.None), f.Hashes()) 285 }) 286 287 } 288 289 func TestAddID(t *testing.T) { 290 assert.Equal(t, "potato {123}", addID("potato", "123")) 291 assert.Equal(t, "{123}", addID("", "123")) 292 } 293 294 func TestFileAddID(t *testing.T) { 295 assert.Equal(t, "potato {123}.txt", addFileID("potato.txt", "123")) 296 assert.Equal(t, "potato {123}", addFileID("potato", "123")) 297 assert.Equal(t, "{123}", addFileID("", "123")) 298 } 299 300 func TestFindID(t *testing.T) { 301 assert.Equal(t, "", findID("potato")) 302 ID := "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 303 assert.Equal(t, ID, findID("potato {"+ID+"}.txt")) 304 ID = ID[1:] 305 assert.Equal(t, "", findID("potato {"+ID+"}.txt")) 306 }