github.com/ncw/rclone@v1.48.1-0.20190724201158-a35aa1360e3e/backend/drive/drive_internal_test.go (about) 1 package drive 2 3 import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "io" 8 "io/ioutil" 9 "mime" 10 "path/filepath" 11 "strings" 12 "testing" 13 14 _ "github.com/ncw/rclone/backend/local" 15 "github.com/ncw/rclone/fs" 16 "github.com/ncw/rclone/fs/operations" 17 "github.com/ncw/rclone/fstest/fstests" 18 "github.com/pkg/errors" 19 "github.com/stretchr/testify/assert" 20 "github.com/stretchr/testify/require" 21 "google.golang.org/api/drive/v3" 22 ) 23 24 func TestDriveScopes(t *testing.T) { 25 for _, test := range []struct { 26 in string 27 want []string 28 wantFlag bool 29 }{ 30 {"", []string{ 31 "https://www.googleapis.com/auth/drive", 32 }, false}, 33 {" drive.file , drive.readonly", []string{ 34 "https://www.googleapis.com/auth/drive.file", 35 "https://www.googleapis.com/auth/drive.readonly", 36 }, false}, 37 {" drive.file , drive.appfolder", []string{ 38 "https://www.googleapis.com/auth/drive.file", 39 "https://www.googleapis.com/auth/drive.appfolder", 40 }, true}, 41 } { 42 got := driveScopes(test.in) 43 assert.Equal(t, test.want, got, test.in) 44 gotFlag := driveScopesContainsAppFolder(got) 45 assert.Equal(t, test.wantFlag, gotFlag, test.in) 46 } 47 } 48 49 /* 50 var additionalMimeTypes = map[string]string{ 51 "application/vnd.ms-excel.sheet.macroenabled.12": ".xlsm", 52 "application/vnd.ms-excel.template.macroenabled.12": ".xltm", 53 "application/vnd.ms-powerpoint.presentation.macroenabled.12": ".pptm", 54 "application/vnd.ms-powerpoint.slideshow.macroenabled.12": ".ppsm", 55 "application/vnd.ms-powerpoint.template.macroenabled.12": ".potm", 56 "application/vnd.ms-powerpoint": ".ppt", 57 "application/vnd.ms-word.document.macroenabled.12": ".docm", 58 "application/vnd.ms-word.template.macroenabled.12": ".dotm", 59 "application/vnd.openxmlformats-officedocument.presentationml.template": ".potx", 60 "application/vnd.openxmlformats-officedocument.spreadsheetml.template": ".xltx", 61 "application/vnd.openxmlformats-officedocument.wordprocessingml.template": ".dotx", 62 "application/vnd.sun.xml.writer": ".sxw", 63 "text/richtext": ".rtf", 64 } 65 */ 66 67 // Load the example export formats into exportFormats for testing 68 func TestInternalLoadExampleFormats(t *testing.T) { 69 fetchFormatsOnce.Do(func() {}) 70 buf, err := ioutil.ReadFile(filepath.FromSlash("test/about.json")) 71 var about struct { 72 ExportFormats map[string][]string `json:"exportFormats,omitempty"` 73 ImportFormats map[string][]string `json:"importFormats,omitempty"` 74 } 75 require.NoError(t, err) 76 require.NoError(t, json.Unmarshal(buf, &about)) 77 _exportFormats = fixMimeTypeMap(about.ExportFormats) 78 _importFormats = fixMimeTypeMap(about.ImportFormats) 79 } 80 81 func TestInternalParseExtensions(t *testing.T) { 82 for _, test := range []struct { 83 in string 84 want []string 85 wantErr error 86 }{ 87 {"doc", []string{".doc"}, nil}, 88 {" docx ,XLSX, pptx,svg", []string{".docx", ".xlsx", ".pptx", ".svg"}, nil}, 89 {"docx,svg,Docx", []string{".docx", ".svg"}, nil}, 90 {"docx,potato,docx", []string{".docx"}, errors.New(`couldn't find MIME type for extension ".potato"`)}, 91 } { 92 extensions, _, gotErr := parseExtensions(test.in) 93 if test.wantErr == nil { 94 assert.NoError(t, gotErr) 95 } else { 96 assert.EqualError(t, gotErr, test.wantErr.Error()) 97 } 98 assert.Equal(t, test.want, extensions) 99 } 100 101 // Test it is appending 102 extensions, _, gotErr := parseExtensions("docx,svg", "docx,svg,xlsx") 103 assert.NoError(t, gotErr) 104 assert.Equal(t, []string{".docx", ".svg", ".xlsx"}, extensions) 105 } 106 107 func TestInternalFindExportFormat(t *testing.T) { 108 item := &drive.File{ 109 Name: "file", 110 MimeType: "application/vnd.google-apps.document", 111 } 112 for _, test := range []struct { 113 extensions []string 114 wantExtension string 115 wantMimeType string 116 }{ 117 {[]string{}, "", ""}, 118 {[]string{".pdf"}, ".pdf", "application/pdf"}, 119 {[]string{".pdf", ".rtf", ".xls"}, ".pdf", "application/pdf"}, 120 {[]string{".xls", ".rtf", ".pdf"}, ".rtf", "application/rtf"}, 121 {[]string{".xls", ".csv", ".svg"}, "", ""}, 122 } { 123 f := new(Fs) 124 f.exportExtensions = test.extensions 125 gotExtension, gotFilename, gotMimeType, gotIsDocument := f.findExportFormat(item) 126 assert.Equal(t, test.wantExtension, gotExtension) 127 if test.wantExtension != "" { 128 assert.Equal(t, item.Name+gotExtension, gotFilename) 129 } else { 130 assert.Equal(t, "", gotFilename) 131 } 132 assert.Equal(t, test.wantMimeType, gotMimeType) 133 assert.Equal(t, true, gotIsDocument) 134 } 135 } 136 137 func TestMimeTypesToExtension(t *testing.T) { 138 for mimeType, extension := range _mimeTypeToExtension { 139 extensions, err := mime.ExtensionsByType(mimeType) 140 assert.NoError(t, err) 141 assert.Contains(t, extensions, extension) 142 } 143 } 144 145 func TestExtensionToMimeType(t *testing.T) { 146 for mimeType, extension := range _mimeTypeToExtension { 147 gotMimeType := mime.TypeByExtension(extension) 148 mediatype, _, err := mime.ParseMediaType(gotMimeType) 149 assert.NoError(t, err) 150 assert.Equal(t, mimeType, mediatype) 151 } 152 } 153 154 func TestExtensionsForExportFormats(t *testing.T) { 155 if _exportFormats == nil { 156 t.Error("exportFormats == nil") 157 } 158 for fromMT, toMTs := range _exportFormats { 159 for _, toMT := range toMTs { 160 if !isInternalMimeType(toMT) { 161 extensions, err := mime.ExtensionsByType(toMT) 162 assert.NoError(t, err, "invalid MIME type %q", toMT) 163 assert.NotEmpty(t, extensions, "No extension found for %q (from: %q)", fromMT, toMT) 164 } 165 } 166 } 167 } 168 169 func TestExtensionsForImportFormats(t *testing.T) { 170 t.Skip() 171 if _importFormats == nil { 172 t.Error("_importFormats == nil") 173 } 174 for fromMT := range _importFormats { 175 if !isInternalMimeType(fromMT) { 176 extensions, err := mime.ExtensionsByType(fromMT) 177 assert.NoError(t, err, "invalid MIME type %q", fromMT) 178 assert.NotEmpty(t, extensions, "No extension found for %q", fromMT) 179 } 180 } 181 } 182 183 func (f *Fs) InternalTestDocumentImport(t *testing.T) { 184 oldAllow := f.opt.AllowImportNameChange 185 f.opt.AllowImportNameChange = true 186 defer func() { 187 f.opt.AllowImportNameChange = oldAllow 188 }() 189 190 testFilesPath, err := filepath.Abs(filepath.FromSlash("test/files")) 191 require.NoError(t, err) 192 193 testFilesFs, err := fs.NewFs(testFilesPath) 194 require.NoError(t, err) 195 196 _, f.importMimeTypes, err = parseExtensions("odt,ods,doc") 197 require.NoError(t, err) 198 199 err = operations.CopyFile(context.Background(), f, testFilesFs, "example2.doc", "example2.doc") 200 require.NoError(t, err) 201 } 202 203 func (f *Fs) InternalTestDocumentUpdate(t *testing.T) { 204 testFilesPath, err := filepath.Abs(filepath.FromSlash("test/files")) 205 require.NoError(t, err) 206 207 testFilesFs, err := fs.NewFs(testFilesPath) 208 require.NoError(t, err) 209 210 _, f.importMimeTypes, err = parseExtensions("odt,ods,doc") 211 require.NoError(t, err) 212 213 err = operations.CopyFile(context.Background(), f, testFilesFs, "example2.xlsx", "example1.ods") 214 require.NoError(t, err) 215 } 216 217 func (f *Fs) InternalTestDocumentExport(t *testing.T) { 218 var buf bytes.Buffer 219 var err error 220 221 f.exportExtensions, _, err = parseExtensions("txt") 222 require.NoError(t, err) 223 224 obj, err := f.NewObject(context.Background(), "example2.txt") 225 require.NoError(t, err) 226 227 rc, err := obj.Open(context.Background()) 228 require.NoError(t, err) 229 defer func() { require.NoError(t, rc.Close()) }() 230 231 _, err = io.Copy(&buf, rc) 232 require.NoError(t, err) 233 text := buf.String() 234 235 for _, excerpt := range []string{ 236 "Lorem ipsum dolor sit amet, consectetur", 237 "porta at ultrices in, consectetur at augue.", 238 } { 239 require.Contains(t, text, excerpt) 240 } 241 } 242 243 func (f *Fs) InternalTestDocumentLink(t *testing.T) { 244 var buf bytes.Buffer 245 var err error 246 247 f.exportExtensions, _, err = parseExtensions("link.html") 248 require.NoError(t, err) 249 250 obj, err := f.NewObject(context.Background(), "example2.link.html") 251 require.NoError(t, err) 252 253 rc, err := obj.Open(context.Background()) 254 require.NoError(t, err) 255 defer func() { require.NoError(t, rc.Close()) }() 256 257 _, err = io.Copy(&buf, rc) 258 require.NoError(t, err) 259 text := buf.String() 260 261 require.True(t, strings.HasPrefix(text, "<html>")) 262 require.True(t, strings.HasSuffix(text, "</html>\n")) 263 for _, excerpt := range []string{ 264 `<meta http-equiv="refresh"`, 265 `Loading <a href="`, 266 } { 267 require.Contains(t, text, excerpt) 268 } 269 } 270 271 func (f *Fs) InternalTest(t *testing.T) { 272 // These tests all depend on each other so run them as nested tests 273 t.Run("DocumentImport", func(t *testing.T) { 274 f.InternalTestDocumentImport(t) 275 t.Run("DocumentUpdate", func(t *testing.T) { 276 f.InternalTestDocumentUpdate(t) 277 t.Run("DocumentExport", func(t *testing.T) { 278 f.InternalTestDocumentExport(t) 279 t.Run("DocumentLink", func(t *testing.T) { 280 f.InternalTestDocumentLink(t) 281 }) 282 }) 283 }) 284 }) 285 } 286 287 var _ fstests.InternalTester = (*Fs)(nil)