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