1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* gvfs - extensions for gio
3 *
4 * Copyright (C) 2019 Mayank Sharma
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 * Author: Mayank Sharma <mayank8019@gmail.com>
22 */
23
24 #include <gio/gio.h>
25 #include <glib.h>
26 #include <locale.h>
27
28 #define GOA_API_IS_SUBJECT_TO_CHANGE
29 #include <gdata/gdata.h>
30 #include <goa/goa.h>
31
32 #define GOOGLE_TEST_DIRECTORY "test-google"
33
34 #define OP_COPY_TEST_DIRECTORY "Test-Copy-Dir"
35 #define OP_MOVE_TEST_DIRECTORY "Test-Move-Dir"
36
37 #define TITLE_DUMMY_FILE "Dummy-File"
38 #define TITLE_COPIED_FILE "Copied-File"
39 #define TITLE_MOVED_FILE "Moved-File"
40
41 typedef struct {
42 GDataDocumentsService *service;
43 GDataDocumentsEntry *test_dir_entry;
44 GDataAuthorizationDomain *domain;
45 GMount *mount;
46 GFile *root; /* GFile corresponding to root-level directory */
47 GFile *test_dir; /* GFile corresponding to test_dir_entry */
48 GFile *test_dummy_file; /* A GFile inside of test_dir which can be used for
49 testing copy/move operations*/
50 } GVfsGoogleTestData ;
51
52 typedef struct
53 {
54 GAsyncResult *res;
55 GMainLoop *loop;
56
57 } MountData;
58
59 /* ---------------------------------------------------------------------------------------------------- */
60 /* Helper functions begin */
61 /* ---------------------------------------------------------------------------------------------------- */
62
63 static gchar *
get_file_attribute(GFile * file,const char * attribute,GError ** error)64 get_file_attribute (GFile *file, const char *attribute, GError **error)
65 {
66 g_autoptr(GFileInfo) info = NULL;
67 g_autoptr(GError) child_error = NULL;
68
69 g_return_val_if_fail (G_IS_FILE (file), NULL);
70 g_return_val_if_fail (error != NULL && *error == NULL, NULL);
71
72 info = g_file_query_info (file,
73 attribute,
74 G_FILE_QUERY_INFO_NONE,
75 NULL,
76 &child_error);
77 if (child_error != NULL)
78 {
79 g_propagate_error (error, g_steal_pointer (&child_error));
80 return FALSE;
81 }
82
83 return g_file_info_get_attribute_as_string (info, attribute);
84 }
85
86 static gboolean
delete_file_recursively(GFile * file)87 delete_file_recursively (GFile *file)
88 {
89 gboolean success;
90 g_autoptr (GError) error = NULL;
91
92 do
93 {
94 g_autoptr (GFileEnumerator) enumerator = NULL;
95
96 success = g_file_delete (file, NULL, &error);
97 if (success ||
98 !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_EMPTY))
99 break;
100
101 g_clear_error (&error);
102 enumerator = g_file_enumerate_children (file,
103 G_FILE_ATTRIBUTE_STANDARD_NAME,
104 G_FILE_QUERY_INFO_NONE,
105 NULL, &error);
106
107 if (enumerator)
108 {
109 GFileInfo *info;
110
111 success = TRUE;
112 info = g_file_enumerator_next_file (enumerator,
113 NULL,
114 &error);
115
116 while (info != NULL)
117 {
118 g_autoptr (GFile) child = NULL;
119
120 child = g_file_enumerator_get_child (enumerator, info);
121 success = success && delete_file_recursively (child);
122 g_object_unref (info);
123
124 info = g_file_enumerator_next_file (enumerator, NULL, &error);
125 }
126 }
127
128 if (error != NULL)
129 success = FALSE;
130 }
131 while (success);
132
133 return success;
134 }
135
136 static gboolean
delete_and_make_new_directory(GFile * folder,GError ** error)137 delete_and_make_new_directory (GFile *folder, GError **error)
138 {
139 gboolean retval = TRUE;
140 g_autoptr(GError) child_error = NULL;
141
142 while (g_file_make_directory (folder, NULL, &child_error) == FALSE)
143 {
144 gboolean needs_delete = FALSE;
145
146 if (child_error != NULL)
147 {
148 if (child_error->code != G_IO_ERROR_EXISTS)
149 {
150 g_propagate_error (error, g_steal_pointer (&child_error));
151 return FALSE;
152 }
153 else
154 needs_delete = TRUE;
155 }
156
157 child_error = NULL;
158 if (needs_delete)
159 {
160 g_file_delete (folder, NULL, &child_error);
161 if (child_error != NULL)
162 {
163 if (child_error->code != G_IO_ERROR_NOT_EMPTY)
164 {
165 retval = FALSE;
166 g_propagate_error (error, g_steal_pointer (&child_error));
167 break;
168 }
169
170 retval = delete_file_recursively (folder);
171 }
172 }
173 }
174
175 return retval;
176 }
177
178 static void
volume_mount_cb(GVolume * volume,GAsyncResult * res,MountData * user_data)179 volume_mount_cb (GVolume *volume,
180 GAsyncResult *res,
181 MountData *user_data)
182 {
183 MountData *data = user_data;
184 data->res = g_object_ref (res);
185 g_main_loop_quit (data->loop);
186 }
187
188 static gboolean
volume_mount_sync(GVolume * volume,GMountMountFlags flags,GCancellable * cancellable,GError ** error)189 volume_mount_sync (GVolume *volume, GMountMountFlags flags, GCancellable *cancellable, GError **error)
190 {
191 g_autoptr (GMainContext) context = NULL;
192 g_autoptr (GMainLoop) loop = NULL;
193 g_autoptr(GError) child_error = NULL;
194 MountData data;
195 gboolean retval = FALSE;
196
197 context = g_main_context_new ();
198 loop = g_main_loop_new (context, FALSE);
199 g_main_context_push_thread_default (context);
200 data.loop = loop;
201
202 g_volume_mount (volume,
203 flags,
204 NULL,
205 cancellable,
206 (GAsyncReadyCallback) volume_mount_cb,
207 (gpointer) &data);
208
209 g_main_loop_run (loop);
210
211 retval = g_volume_mount_finish (volume, data.res, &child_error);
212
213 if (child_error != NULL)
214 g_propagate_error (error, g_steal_pointer (&child_error));
215
216 g_object_unref (data.res);
217 g_main_context_pop_thread_default (context);
218 return retval;
219 }
220
221 static GFile *
create_temporary_duplicate_file(GFile * source_file,GError ** error)222 create_temporary_duplicate_file (GFile *source_file, GError **error)
223 {
224 static int file_num_counter = 0;
225 g_autofree gchar *dest_file_title = NULL;
226 g_autofree gchar *source_file_title = NULL;
227 g_autofree gchar *parent_path = NULL;
228 g_autoptr(GError) child_error = NULL;
229 GFile *dest_file = NULL;
230 g_autoptr(GFile) dummy_dest_file = NULL;
231 g_autoptr(GFile) parent = NULL;
232 gchar rand_int_string[G_ASCII_DTOSTR_BUF_SIZE];
233
234 /* Generate a string (here created using the stringified file_num_counter) and use
235 * this string as the title of the destination file. */
236 g_ascii_dtostr (rand_int_string, G_ASCII_DTOSTR_BUF_SIZE, ++file_num_counter);
237
238 source_file_title = get_file_attribute (source_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &child_error);
239 if (child_error != NULL)
240 {
241 g_propagate_error (error, g_steal_pointer (&child_error));
242 return NULL;
243 }
244
245 dest_file_title = g_strconcat (source_file_title, " (", rand_int_string, ")", NULL);
246
247 parent = g_file_get_parent (source_file);
248 parent_path = g_file_get_path (parent);
249 dummy_dest_file = g_file_new_build_filename (parent_path, dest_file_title, NULL);
250
251 g_file_copy (source_file, dummy_dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &child_error);
252 if (child_error != NULL)
253 {
254 g_propagate_error (error, g_steal_pointer (&child_error));
255 return NULL;
256 }
257
258 dest_file = g_file_get_child_for_display_name (parent, dest_file_title, &child_error);
259 if (child_error != NULL)
260 {
261 g_propagate_error (error, g_steal_pointer (&child_error));
262 return NULL;
263 }
264
265 return dest_file;
266 }
267
268 /* ---------------------------------------------------------------------------------------------------- */
269 /* Test init and cleanup functions begin */
270 /* ---------------------------------------------------------------------------------------------------- */
271
272 static inline void
setup_google_mount_and_libgdata_service(GVfsGoogleTestData * self,GError ** error)273 setup_google_mount_and_libgdata_service (GVfsGoogleTestData *self, GError **error)
274 {
275 GList *l;
276 GoaObject *test_account_goa_object = NULL;
277 g_autofree gchar *mount_email = NULL;
278 g_autofree gchar *volume_uuid = NULL;
279 g_autolist(GoaObject) accounts = NULL;
280 g_autolist(GMount) mounts = NULL;
281 g_autoptr(GDataGoaAuthorizer) authorizer = NULL;
282 g_autoptr(GError) child_error = NULL;
283 g_autoptr(GVolumeMonitor) volume_monitor = NULL;
284 g_autoptr(GVolume) volume = NULL;
285 g_autoptr(GoaClient) client = NULL;
286
287 /* We firstly check if there exists any mount with mount_name ending in
288 * "@gmail.com" */
289 volume_monitor = g_volume_monitor_get ();
290 mounts = g_volume_monitor_get_mounts (volume_monitor);
291 for (l = mounts; l != NULL; l = l->next)
292 {
293 g_autofree gchar *mount_name = NULL;
294 mount_name = g_mount_get_name (G_MOUNT (l->data));
295 if (g_str_has_suffix (mount_name, "@gmail.com"))
296 {
297 mount_email = g_strdup (mount_name);
298 self->mount = g_object_ref (G_MOUNT (l->data));
299 }
300 }
301
302 /* Basic setup pertaining to GOA, and creation of GDataDocumentsService */
303 client = goa_client_new_sync (NULL, &child_error);
304 if (child_error != NULL)
305 {
306 g_propagate_error (error, g_steal_pointer (&child_error));
307 return;
308 }
309
310 accounts = goa_client_get_accounts (client);
311 for (l = accounts; l != NULL; l = l->next)
312 {
313 const gchar *goa_account_email;
314 GoaObject *object;
315 GoaAccount *account;
316
317 object = GOA_OBJECT (l->data);
318 account = goa_object_peek_account (object);
319
320 if (g_strcmp0 (goa_account_get_provider_type (account), "google") == 0)
321 {
322 if (mount_email != NULL)
323 {
324 goa_account_email = goa_account_get_identity (account);
325 if (g_strcmp0 (goa_account_email, mount_email) == 0)
326 {
327 test_account_goa_object = GOA_OBJECT (l->data);
328 break;
329 }
330 }
331 else
332 {
333 test_account_goa_object = GOA_OBJECT (l->data);
334 mount_email = goa_account_dup_identity (account);
335 break;
336 }
337 }
338 }
339
340 if (test_account_goa_object == NULL)
341 {
342 g_error ("No GOA account found with the same email as %s", mount_email);
343 return;
344 }
345
346 /* We've found an email linked to some Google Account, but the GMount hasn't
347 * been mounted yet. So, we manually mount a GMount corresponding to this
348 * mount_email. */
349 if (self->mount == NULL)
350 {
351 g_autoptr(GFile) volume_activation_root = NULL;
352 volume_uuid = g_strconcat ("google-drive://", mount_email, "/", NULL);
353 if ((volume = g_volume_monitor_get_volume_for_uuid (volume_monitor, volume_uuid)) == NULL)
354 {
355 g_error ("No GVolume found corresponding to the UUID: %s", volume_uuid);
356 return;
357 }
358
359 volume_mount_sync (volume, G_MOUNT_MOUNT_NONE, NULL, &child_error);
360 if (child_error != NULL)
361 {
362 g_propagate_error (error, g_steal_pointer (&child_error));
363 return;
364 }
365
366 volume_activation_root = g_volume_get_activation_root (volume);
367 self->mount = g_file_find_enclosing_mount (volume_activation_root, NULL, &child_error);
368 if (child_error != NULL)
369 {
370 g_propagate_error (error, g_steal_pointer (&child_error));
371 return;
372 }
373 }
374
375 authorizer = gdata_goa_authorizer_new (test_account_goa_object);
376 self->service = gdata_documents_service_new (GDATA_AUTHORIZER (authorizer));
377 if (self->service == NULL)
378 {
379 g_error ("Couldn't initialize libgdata service for email: %s", mount_email);
380 return;
381 }
382
383 self->domain = gdata_documents_service_get_primary_authorization_domain ();
384 }
385
386 static void
gvfs_google_test_init(GVfsGoogleTestData ** _self,GError ** error)387 gvfs_google_test_init (GVfsGoogleTestData **_self, GError **error)
388 {
389 gboolean op_done;
390 g_autofree gchar *root_path = NULL;
391 g_autofree gchar *test_dir_path = NULL;
392 g_autofree gchar *test_dir_id = NULL;
393 g_autofree gchar *test_dummy_file_id = NULL;
394 g_autoptr(GError) child_error = NULL;
395 g_autoptr(GFile) root = NULL;
396 g_autoptr(GFile) test_dir = NULL;
397 g_autoptr(GFile) test_dummy_file = NULL;
398 g_autoptr(GFile) copy_test_dir = NULL;
399 g_autoptr(GFile) move_test_dir = NULL;
400 g_autoptr(GFileOutputStream) file_write_stream = NULL;
401 g_autoptr(GDataDocumentsEntry) root_entry = NULL;
402 GVfsGoogleTestData *self;
403
404 *_self = g_new0 (GVfsGoogleTestData, 1);
405 self = *_self;
406 self->mount = NULL;
407
408 setup_google_mount_and_libgdata_service (self, &child_error);
409 if (child_error != NULL)
410 {
411 g_propagate_error (error, g_steal_pointer (&child_error));
412 return;
413 }
414
415 root_entry = GDATA_DOCUMENTS_ENTRY (gdata_service_query_single_entry (GDATA_SERVICE (self->service),
416 self->domain,
417 "root",
418 NULL,
419 GDATA_TYPE_DOCUMENTS_FOLDER,
420 NULL,
421 &child_error));
422 if (child_error != NULL)
423 {
424 g_propagate_error (error, g_steal_pointer (&child_error));
425 return;
426 }
427
428 /* The GFile corresponding to the root_entry we fetched above */
429 root = g_mount_get_root (self->mount);
430 root_path = g_file_get_path (root);
431 test_dir = g_file_new_build_filename (root_path, GOOGLE_TEST_DIRECTORY, NULL);
432
433 /* We create a test directory in the root folder (on Google Drive) where all
434 * the other test files/folders shall be created */
435 g_file_make_directory (test_dir, NULL, &child_error);
436 if (child_error != NULL)
437 {
438 if (child_error->code != G_IO_ERROR_EXISTS)
439 {
440 g_propagate_error (error, g_steal_pointer (&child_error));
441 return;
442 }
443 else
444 child_error = NULL;
445 }
446
447 g_object_unref (test_dir);
448 test_dir = g_file_get_child_for_display_name (root, GOOGLE_TEST_DIRECTORY, &child_error);
449 if (child_error != NULL)
450 {
451 g_propagate_error (error, g_steal_pointer (&child_error));
452 return;
453 }
454
455 self->test_dir = g_object_ref (test_dir);
456
457 test_dir_id = get_file_attribute (self->test_dir, G_FILE_ATTRIBUTE_ID_FILE, &child_error);
458 if (child_error != NULL)
459 {
460 g_propagate_error (error, g_steal_pointer (&child_error));
461 return;
462 }
463
464 self->test_dir_entry = GDATA_DOCUMENTS_ENTRY (gdata_service_query_single_entry (GDATA_SERVICE (self->service),
465 self->domain,
466 test_dir_id,
467 NULL,
468 GDATA_TYPE_DOCUMENTS_FOLDER,
469 NULL,
470 &child_error));
471 if (child_error != NULL)
472 {
473 g_propagate_error (error, g_steal_pointer (&child_error));
474 return;
475 }
476
477 g_test_message ("Test folder GFile ID: %s", test_dir_id);
478 g_test_message ("Test folder Entry ID: %s", gdata_entry_get_id (GDATA_ENTRY (self->test_dir_entry)));
479
480 /* Now we create try to create a dummy file which we'll use for testing
481 * copy/move/delete operations.If the file already exists, an error with
482 * error code G_IO_ERROR_EXISTS is returned, and we simply use that existing
483 * file for testing purposes. */
484 test_dir_path = g_file_get_path (self->test_dir);
485 test_dummy_file = g_file_new_build_filename (test_dir_path, TITLE_DUMMY_FILE, NULL);
486
487 file_write_stream = g_file_create (test_dummy_file, G_FILE_CREATE_NONE, NULL, &child_error);
488 if (child_error != NULL)
489 {
490 if (child_error->code != G_IO_ERROR_EXISTS)
491 {
492 g_propagate_error (error, g_steal_pointer (&child_error));
493 return;
494 }
495 else
496 {
497 /* We simply ignore this because if file already exists, we don't
498 * have any issues for initiating the test. */
499 child_error = NULL;
500 }
501 }
502 else
503 {
504 g_output_stream_write (G_OUTPUT_STREAM (file_write_stream), "SomeRandomText", 14, NULL, &child_error);
505 if (child_error != NULL)
506 {
507 g_propagate_error (error, g_steal_pointer (&child_error));
508 return;
509 }
510
511 g_output_stream_close (G_OUTPUT_STREAM (file_write_stream), NULL, &child_error);
512 if (child_error != NULL)
513 {
514 g_propagate_error (error, g_steal_pointer (&child_error));
515 return;
516 }
517 }
518
519 g_object_unref (test_dummy_file);
520 test_dummy_file = g_file_get_child_for_display_name (self->test_dir, TITLE_DUMMY_FILE, &child_error);
521 if (child_error != NULL)
522 {
523 g_propagate_error (error, g_steal_pointer (&child_error));
524 return;
525 }
526
527 test_dummy_file_id = get_file_attribute (test_dummy_file, G_FILE_ATTRIBUTE_ID_FILE, &child_error);
528 if (child_error != NULL)
529 {
530 g_propagate_error (error, g_steal_pointer (&child_error));
531 return;
532 }
533
534 g_test_message ("Test dummy GFile ID: %s", test_dummy_file_id);
535 self->test_dummy_file = g_object_ref (test_dummy_file);
536
537 copy_test_dir = g_file_new_build_filename (test_dir_path, OP_COPY_TEST_DIRECTORY, NULL);
538 op_done = delete_and_make_new_directory (copy_test_dir, &child_error);
539 if (child_error != NULL)
540 {
541 g_propagate_error (error, g_steal_pointer (&child_error));
542 return;
543 }
544 g_assert_true (op_done);
545
546 move_test_dir = g_file_new_build_filename (test_dir_path, OP_MOVE_TEST_DIRECTORY, NULL);
547 op_done = delete_and_make_new_directory (move_test_dir, &child_error);
548 if (child_error != NULL)
549 {
550 g_propagate_error (error, g_steal_pointer (&child_error));
551 return;
552 }
553 g_assert_true (op_done);
554 }
555
556 static void
gvfs_google_test_exit_cleanup(GVfsGoogleTestData ** _self,GError ** error)557 gvfs_google_test_exit_cleanup (GVfsGoogleTestData **_self, GError **error)
558 {
559 GVfsGoogleTestData *self = *_self;
560
561 g_return_if_fail (GDATA_IS_DOCUMENTS_ENTRY (self->test_dir_entry));
562 g_return_if_fail (GDATA_IS_DOCUMENTS_SERVICE (self->service));
563
564 g_assert_true (delete_file_recursively (self->test_dir));
565
566 g_object_unref (self->service);
567 g_object_unref (self->test_dir_entry);
568 g_object_unref (self->test_dir);
569 g_object_unref (self->test_dummy_file);
570 g_object_unref (self->mount);
571 g_free (self);
572 }
573
574 /* ---------------------------------------------------------------------------------------------------- */
575 /* Actual test functions begin */
576 /* ---------------------------------------------------------------------------------------------------- */
577
578 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~ Make Directory Test Case Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
579 static void
gvfs_google_test_make_directory_using_valid_display_name(gconstpointer user_data)580 gvfs_google_test_make_directory_using_valid_display_name (gconstpointer user_data)
581 {
582 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
583 g_autoptr(GError) error = NULL;
584 g_autoptr(GFile) dummy_new_folder = NULL;
585 g_autofree gchar *parent_path = NULL;
586 const gchar *folder_display_name = "Valid-Display-Name-Dir";
587
588 parent_path = g_file_get_path (self->test_dir);
589 dummy_new_folder = g_file_new_build_filename (parent_path, folder_display_name, NULL);
590
591 g_assert_true (delete_and_make_new_directory (dummy_new_folder, &error));
592 g_assert_no_error (error);
593 g_assert_true (g_file_query_exists (dummy_new_folder, NULL));
594 }
595
596 static void
gvfs_google_test_make_directory_using_valid_id(gconstpointer user_data)597 gvfs_google_test_make_directory_using_valid_id (gconstpointer user_data)
598 {
599 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
600 g_autoptr(GError) error = NULL;
601 g_autoptr(GFile) dummy_new_folder = NULL;
602 g_autoptr(GFile) actual_new_folder1 = NULL;
603 g_autoptr(GFile) actual_new_folder2 = NULL;
604 g_autoptr(GFileInfo) info1 = NULL;
605 g_autoptr(GFileInfo) info2 = NULL;
606 g_autofree gchar *parent_path = NULL;
607 const gchar *intended_folder_title = gdata_entry_get_id (GDATA_ENTRY (self->test_dir_entry));
608 const gchar *actual_folder_title = gdata_entry_get_title (GDATA_ENTRY (self->test_dir_entry));
609
610 parent_path = g_file_get_path (self->test_dir);
611 dummy_new_folder = g_file_new_build_filename (parent_path, intended_folder_title, NULL);
612
613 g_assert_true (delete_and_make_new_directory (dummy_new_folder, &error));
614 g_assert_no_error (error);
615
616 error = NULL;
617 actual_new_folder1 = g_file_get_child_for_display_name (self->test_dir, intended_folder_title, &error);
618 g_assert_nonnull (actual_new_folder1);
619 g_assert_no_error (error);
620
621 error = NULL;
622 actual_new_folder2 = g_file_get_child_for_display_name (self->test_dir, actual_folder_title, &error);
623 g_assert_nonnull (actual_new_folder2);
624 g_assert_no_error (error);
625
626 info1 = g_file_query_info (actual_new_folder1, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, G_FILE_QUERY_INFO_NONE, NULL, &error);
627 g_assert_no_error (error);
628 g_assert_nonnull (info1);
629
630 info2 = g_file_query_info (actual_new_folder2, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, G_FILE_QUERY_INFO_NONE, NULL, &error);
631 g_assert_no_error (error);
632 g_assert_nonnull (info1);
633
634 g_assert_cmpstr (g_file_info_get_display_name (info1), ==, g_file_info_get_display_name (info2));
635 }
636
637 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~ Copy Test Case Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
638
639 static void
gvfs_google_test_copy_file_from_one_parent_to_other_using_same_title(gconstpointer user_data)640 gvfs_google_test_copy_file_from_one_parent_to_other_using_same_title (gconstpointer user_data)
641 {
642 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
643 gboolean op_done;
644 g_autoptr(GError) error = NULL;
645 g_autofree gchar *parent_path = NULL;
646 g_autofree gchar *dest_path = NULL;
647 g_autofree gchar *copy_test_dir_id = NULL;
648 g_autofree gchar *dest_file_actual_display_name = NULL;
649 g_autoptr(GFile) copy_test_dir = NULL;
650 g_autoptr(GFile) dest_file = NULL;
651
652 parent_path = g_file_get_path (self->test_dir);
653 copy_test_dir = g_file_get_child_for_display_name (self->test_dir, OP_COPY_TEST_DIRECTORY, &error);
654 g_assert_no_error (error);
655 g_assert_nonnull (copy_test_dir);
656
657 copy_test_dir_id = get_file_attribute (copy_test_dir, G_FILE_ATTRIBUTE_ID_FILE, &error);
658 g_assert_no_error (error);
659 g_assert_nonnull (copy_test_dir_id);
660
661 dest_path = g_file_get_path (copy_test_dir);
662 dest_file = g_file_new_build_filename (dest_path, TITLE_COPIED_FILE, NULL);
663
664 op_done = g_file_copy (self->test_dummy_file, dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
665 g_assert_no_error (error);
666 g_assert_true (op_done);
667
668 dest_file_actual_display_name = get_file_attribute (dest_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
669 g_assert_no_error (error);
670 g_assert_cmpstr (dest_file_actual_display_name, ==, TITLE_COPIED_FILE);
671 }
672
673 static void
gvfs_google_test_copy_file_from_one_parent_to_other_using_id(gconstpointer user_data)674 gvfs_google_test_copy_file_from_one_parent_to_other_using_id (gconstpointer user_data)
675 {
676 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
677 gboolean op_done;
678 g_autoptr(GError) error = NULL;
679 g_autofree gchar *parent_path = NULL;
680 g_autofree gchar *dest_path = NULL;
681 g_autofree gchar *source_file_id = NULL;
682 g_autofree gchar *source_file_title = NULL;
683 g_autofree gchar *copy_test_dir_id = NULL;
684 g_autofree gchar *dest_file_actual_display_name = NULL;
685 g_autoptr(GFile) copy_test_dir = NULL;
686 g_autoptr(GFile) dest_file = NULL;
687
688 parent_path = g_file_get_path (self->test_dir);
689 copy_test_dir = g_file_get_child_for_display_name (self->test_dir, OP_COPY_TEST_DIRECTORY, &error);
690 g_assert_no_error (error);
691 g_assert_nonnull (copy_test_dir);
692
693 copy_test_dir_id = get_file_attribute (copy_test_dir, G_FILE_ATTRIBUTE_ID_FILE, &error);
694 g_assert_no_error (error);
695 g_assert_nonnull (copy_test_dir_id);
696
697 source_file_id = get_file_attribute (self->test_dummy_file, G_FILE_ATTRIBUTE_ID_FILE, &error);
698 g_assert_no_error (error);
699 g_assert_nonnull (copy_test_dir_id);
700
701 source_file_title = get_file_attribute (self->test_dummy_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
702 g_assert_no_error (error);
703 g_assert_nonnull (source_file_title);
704
705 dest_path = g_file_get_path (copy_test_dir);
706 dest_file = g_file_new_build_filename (dest_path, source_file_id, NULL);
707
708 op_done = g_file_copy (self->test_dummy_file, dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
709 g_assert_no_error (error);
710 g_assert_true (op_done);
711
712 dest_file_actual_display_name = get_file_attribute (dest_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
713 g_assert_no_error (error);
714 g_assert_nonnull (dest_file_actual_display_name);
715
716 g_assert_cmpstr (dest_file_actual_display_name, ==, source_file_title);
717 }
718
719 static void
gvfs_google_test_copy_file_within_same_parent_with_title_change(gconstpointer user_data)720 gvfs_google_test_copy_file_within_same_parent_with_title_change (gconstpointer user_data)
721 {
722 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
723 gboolean op_done;
724 g_autoptr(GError) error = NULL;
725 g_autofree gchar *parent_path = NULL;
726 g_autofree gchar *dest_file_id = NULL;
727 g_autofree gchar *dest_file_title = NULL;
728 g_autofree gchar *dest_file_actual_display_name = NULL;
729 g_autoptr(GFile) source_file = NULL;
730 g_autoptr(GFile) dest_file = NULL;
731
732 source_file = g_file_get_child_for_display_name (self->test_dir, TITLE_DUMMY_FILE, &error);
733 g_assert_no_error (error);
734 g_assert_nonnull (source_file);
735
736 dest_file_title = g_strconcat (TITLE_DUMMY_FILE, " (Copy)", NULL);
737 parent_path = g_file_get_path (self->test_dir);
738 dest_file = g_file_new_build_filename (parent_path, dest_file_title, NULL);
739
740 op_done = g_file_copy (source_file, dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
741 g_assert_no_error (error);
742 g_assert_true (op_done);
743
744 g_clear_object (&dest_file);
745 dest_file = g_file_get_child_for_display_name (self->test_dir, dest_file_title, &error);
746 g_assert_no_error (error);
747 g_assert_nonnull (dest_file);
748
749 dest_file_id = get_file_attribute (dest_file, G_FILE_ATTRIBUTE_ID_FILE, &error);
750 g_assert_no_error (error);
751 g_assert_nonnull (dest_file_id);
752
753 dest_file_actual_display_name = get_file_attribute (dest_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
754 g_assert_no_error (error);
755 g_assert_cmpstr (dest_file_actual_display_name, ==, dest_file_title);
756 }
757
758 static void
gvfs_google_test_copy_file_within_same_parent_with_same_title(gconstpointer user_data)759 gvfs_google_test_copy_file_within_same_parent_with_same_title (gconstpointer user_data)
760 {
761 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
762 gboolean op_done;
763 g_autoptr(GError) error = NULL;
764 g_autofree gchar *parent_path = NULL;
765 g_autofree gchar *source_file_title = NULL;
766 g_autoptr(GFile) source_file = NULL;
767 g_autoptr(GFile) dummy_dest_file = NULL;
768
769 source_file = g_file_get_child_for_display_name (self->test_dir, TITLE_DUMMY_FILE, &error);
770 g_assert_no_error (error);
771 g_assert_nonnull (source_file);
772
773 source_file_title = get_file_attribute (source_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
774 g_assert_no_error (error);
775 g_assert_nonnull (source_file_title);
776
777 parent_path = g_file_get_path (self->test_dir);
778 dummy_dest_file = g_file_new_build_filename (parent_path, source_file_title, NULL);
779
780 op_done = g_file_copy (source_file, dummy_dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
781 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
782 g_assert_true (!op_done);
783 }
784
785 static void
gvfs_google_test_copy_file_within_same_parent_try_overwrite_with_id(gconstpointer user_data)786 gvfs_google_test_copy_file_within_same_parent_try_overwrite_with_id (gconstpointer user_data)
787 {
788 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
789 gboolean op_done;
790 g_autoptr(GError) error = NULL;
791 g_autofree gchar *parent_path = NULL;
792 g_autofree gchar *source_file_id = NULL;
793 g_autoptr(GFile) source_file = NULL;
794 g_autoptr(GFile) dummy_dest_file = NULL;
795
796 source_file = g_file_get_child_for_display_name (self->test_dir, TITLE_DUMMY_FILE, &error);
797 g_assert_no_error (error);
798 g_assert_nonnull (source_file);
799
800 source_file_id = get_file_attribute (source_file, G_FILE_ATTRIBUTE_ID_FILE, &error);
801 g_assert_no_error (error);
802 g_assert_nonnull (source_file_id);
803
804 parent_path = g_file_get_path (self->test_dir);
805 dummy_dest_file = g_file_new_build_filename (parent_path, source_file_id, NULL);
806
807 op_done = g_file_copy (source_file, dummy_dest_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error);
808 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
809 g_assert_true (!op_done);
810 }
811
812 static void
gvfs_google_test_copy_file_within_same_parent_with_source_id_as_destination_basename(gconstpointer user_data)813 gvfs_google_test_copy_file_within_same_parent_with_source_id_as_destination_basename (gconstpointer user_data)
814 {
815 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
816 gboolean op_done;
817 g_autoptr(GError) error = NULL;
818 g_autofree gchar *parent_path = NULL;
819 g_autofree gchar *source_file_id = NULL;
820 g_autoptr(GFile) source_file = NULL;
821 g_autoptr(GFile) dummy_dest_file = NULL;
822
823 source_file = g_file_get_child_for_display_name (self->test_dir, TITLE_DUMMY_FILE, &error);
824 g_assert_no_error (error);
825 g_assert_nonnull (source_file);
826
827 source_file_id = get_file_attribute (source_file, G_FILE_ATTRIBUTE_ID_FILE, &error);
828 g_assert_no_error (error);
829 g_assert_nonnull (source_file_id);
830
831 parent_path = g_file_get_path (self->test_dir);
832 dummy_dest_file = g_file_new_build_filename (parent_path, source_file_id, NULL);
833
834 op_done = g_file_copy (source_file, dummy_dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
835 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
836 g_assert_true (!op_done);
837 }
838
839 static void
gvfs_google_test_copy_file_within_same_parent_try_overwrite_with_same_title(gconstpointer user_data)840 gvfs_google_test_copy_file_within_same_parent_try_overwrite_with_same_title (gconstpointer user_data)
841 {
842 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
843 gboolean op_done;
844 g_autoptr(GError) error = NULL;
845 g_autofree gchar *parent_path = NULL;
846 g_autofree gchar *source_file_title = NULL;
847 g_autoptr(GFile) source_file = NULL;
848 g_autoptr(GFile) dummy_dest_file = NULL;
849
850 source_file = g_file_get_child_for_display_name (self->test_dir, TITLE_DUMMY_FILE, &error);
851 g_assert_no_error (error);
852 g_assert_nonnull (source_file);
853
854 source_file_title = get_file_attribute (source_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
855 g_assert_no_error (error);
856 g_assert_nonnull (source_file_title);
857
858 parent_path = g_file_get_path (self->test_dir);
859 dummy_dest_file = g_file_new_build_filename (parent_path, source_file_title, NULL);
860
861 op_done = g_file_copy (source_file, dummy_dest_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error);
862 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
863 g_assert_true (!op_done);
864 }
865
866 static void
gvfs_google_test_copy_file_from_one_parent_to_other_with_volatile_entry_collision_only(gconstpointer user_data)867 gvfs_google_test_copy_file_from_one_parent_to_other_with_volatile_entry_collision_only (gconstpointer user_data)
868 {
869 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
870 gboolean op_done;
871 gchar rand_int_string[G_ASCII_DTOSTR_BUF_SIZE];
872 g_autoptr(GError) error = NULL;
873 g_autofree gchar *parent_path = NULL;
874 g_autoptr(GFile) source_file = NULL;
875 g_autoptr(GFile) copy_test_dir = NULL;
876 g_autoptr(GFile) dummy_dest_file = NULL;
877
878 copy_test_dir = g_file_get_child_for_display_name (self->test_dir, OP_COPY_TEST_DIRECTORY, &error);
879 g_assert_no_error (error);
880 g_assert_nonnull (copy_test_dir);
881
882 source_file = g_file_get_child_for_display_name (self->test_dir, TITLE_DUMMY_FILE, &error);
883 g_assert_no_error (error);
884 g_assert_nonnull (source_file);
885
886 /* Generate any random string (here created using a random integer) and use
887 * this random string as the title of the destination file. We do this so
888 * that we can cause a collision just on the volatile entry and not on the
889 * title. */
890 g_ascii_dtostr (rand_int_string, G_ASCII_DTOSTR_BUF_SIZE, rand ());
891
892 parent_path = g_file_get_path (copy_test_dir);
893 dummy_dest_file = g_file_new_build_filename (parent_path, rand_int_string, NULL);
894
895 op_done = g_file_copy (source_file, dummy_dest_file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error);
896 g_assert_no_error (error);
897 g_assert_true (op_done);
898 }
899
900 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~ Move Test Case Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
901
902 static void
gvfs_google_test_move_file_within_same_parent_without_title_change(gconstpointer user_data)903 gvfs_google_test_move_file_within_same_parent_without_title_change (gconstpointer user_data)
904 {
905 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
906 gboolean op_done;
907 g_autoptr(GError) error = NULL;
908 g_autofree gchar *parent_path = NULL;
909 g_autofree gchar *dest_file_title = NULL;
910 g_autoptr(GFile) source_file = NULL;
911 g_autoptr(GFile) dest_file = NULL;
912
913 /* We need some file which we can move. So, we use test_dummy_file to create
914 * a copy of that file and move its copy around using its ID. */
915 source_file = create_temporary_duplicate_file (self->test_dummy_file, &error);
916 g_assert_no_error (error);
917 g_assert_nonnull (source_file);
918
919 dest_file_title = get_file_attribute (source_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
920 parent_path = g_file_get_path (self->test_dir);
921 dest_file = g_file_new_build_filename (parent_path, dest_file_title, NULL);
922
923 op_done = g_file_move (source_file, dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
924 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
925 g_assert_false (op_done);
926 }
927
928 static void
gvfs_google_test_move_file_within_same_parent_with_title_change(gconstpointer user_data)929 gvfs_google_test_move_file_within_same_parent_with_title_change (gconstpointer user_data)
930 {
931 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
932 gboolean op_done;
933 g_autoptr(GError) error = NULL;
934 g_autofree gchar *parent_path = NULL;
935 g_autofree gchar *dest_file_title = NULL;
936 g_autofree gchar *dest_file_actual_display_name = NULL;
937 g_autoptr(GFile) source_file = NULL;
938 g_autoptr(GFile) dest_file = NULL;
939
940 /* We need some file which we can move. So, we use test_dummy_file to create
941 * a copy of that file and move its copy around using its ID. */
942 source_file = create_temporary_duplicate_file (self->test_dummy_file, &error);
943 g_assert_no_error (error);
944 g_assert_nonnull (source_file);
945
946 dest_file_title = g_strconcat (TITLE_DUMMY_FILE, "_test_move_file_within_same_parent_with_title_change", NULL);
947 parent_path = g_file_get_path (self->test_dir);
948 dest_file = g_file_new_build_filename (parent_path, dest_file_title, NULL);
949
950 op_done = g_file_move (source_file, dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
951 g_assert_no_error (error);
952 g_assert_true (op_done);
953
954 g_clear_object (&dest_file);
955 dest_file = g_file_get_child_for_display_name (self->test_dir, dest_file_title, &error);
956 g_assert_no_error (error);
957 g_assert_nonnull (dest_file);
958
959 dest_file_actual_display_name = get_file_attribute (dest_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
960 g_assert_no_error (error);
961 g_assert_cmpstr (dest_file_actual_display_name, ==, dest_file_title);
962 }
963
964 static void
gvfs_google_test_move_file_from_one_parent_to_other_without_backup(gconstpointer user_data)965 gvfs_google_test_move_file_from_one_parent_to_other_without_backup (gconstpointer user_data)
966 {
967 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
968 gboolean op_done;
969 g_autoptr(GError) error = NULL;
970 g_autofree gchar *dest_path = NULL;
971 g_autofree gchar *source_file_title = NULL;
972 g_autofree gchar *dest_file_actual_display_name = NULL;
973 g_autoptr(GFile) move_test_dir = NULL;
974 g_autoptr(GFile) source_file = NULL;
975 g_autoptr(GFile) dest_file = NULL;
976
977 move_test_dir = g_file_get_child_for_display_name (self->test_dir, OP_MOVE_TEST_DIRECTORY, &error);
978 g_assert_no_error (error);
979 g_assert_nonnull (move_test_dir);
980
981 dest_path = g_file_get_path (move_test_dir);
982 dest_file = g_file_new_build_filename (dest_path, TITLE_MOVED_FILE, NULL);
983
984 /* We need some file which we can move. So, we use test_dummy_file to create
985 * a copy of that file and move its copy around using its ID. */
986 source_file = create_temporary_duplicate_file (self->test_dummy_file, &error);
987 g_assert_no_error (error);
988 g_assert_nonnull (source_file);
989
990 source_file_title = get_file_attribute (source_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
991 g_assert_no_error (error);
992 g_assert_nonnull (source_file_title);
993
994 dest_path = g_file_get_path (move_test_dir);
995 dest_file = g_file_new_build_filename (dest_path, source_file_title, NULL);
996
997 op_done = g_file_move (source_file, dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
998 g_assert_no_error (error);
999 g_assert_true (op_done);
1000
1001 dest_file_actual_display_name = get_file_attribute (dest_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
1002 g_assert_cmpstr (dest_file_actual_display_name, ==, source_file_title);
1003 }
1004
1005 static void
gvfs_google_test_move_file_from_one_parent_to_other_with_backup(gconstpointer user_data)1006 gvfs_google_test_move_file_from_one_parent_to_other_with_backup (gconstpointer user_data)
1007 {
1008 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
1009 gboolean op_done;
1010 g_autoptr(GError) error = NULL;
1011 g_autofree gchar *parent_path = NULL;
1012 g_autofree gchar *dest_path = NULL;
1013 g_autofree gchar *source_file_title = NULL;
1014 g_autofree gchar *dest_file_actual_display_name = NULL;
1015 g_autoptr(GFile) move_test_dir = NULL;
1016 g_autoptr(GFile) source_file = NULL;
1017 g_autoptr(GFile) dest_file = NULL;
1018
1019 parent_path = g_file_get_path (self->test_dir);
1020 move_test_dir = g_file_get_child_for_display_name (self->test_dir, OP_MOVE_TEST_DIRECTORY, &error);
1021 g_assert_no_error (error);
1022 g_assert_nonnull (move_test_dir);
1023
1024 /* We need some file which we can move. So, we use test_dummy_file to create
1025 * a copy of that file and move its copy around using its ID. */
1026 source_file = create_temporary_duplicate_file (self->test_dummy_file, &error);
1027 g_assert_no_error (error);
1028 g_assert_nonnull (source_file);
1029
1030 source_file_title = get_file_attribute (source_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
1031 g_assert_no_error (error);
1032 g_assert_nonnull (source_file_title);
1033
1034 dest_path = g_file_get_path (move_test_dir);
1035 dest_file = g_file_new_build_filename (dest_path, source_file_title, NULL);
1036
1037 op_done = g_file_move (source_file, dest_file, G_FILE_COPY_BACKUP, NULL, NULL, NULL, &error);
1038 g_assert_no_error (error);
1039 g_assert_true (op_done);
1040
1041 dest_file_actual_display_name = get_file_attribute (dest_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
1042 g_assert_cmpstr (dest_file_actual_display_name, ==, source_file_title);
1043 }
1044
1045 static void
gvfs_google_test_move_file_from_one_parent_to_other_using_same_title(gconstpointer user_data)1046 gvfs_google_test_move_file_from_one_parent_to_other_using_same_title (gconstpointer user_data)
1047 {
1048 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
1049 gboolean op_done;
1050 g_autoptr(GError) error = NULL;
1051 g_autofree gchar *parent_path = NULL;
1052 g_autofree gchar *dest_path = NULL;
1053 g_autofree gchar *source_file_title = NULL;
1054 g_autofree gchar *dest_file_actual_display_name = NULL;
1055 g_autoptr(GFile) move_test_dir = NULL;
1056 g_autoptr(GFile) source_file = NULL;
1057 g_autoptr(GFile) dest_file = NULL;
1058
1059 parent_path = g_file_get_path (self->test_dir);
1060 move_test_dir = g_file_get_child_for_display_name (self->test_dir, OP_MOVE_TEST_DIRECTORY, &error);
1061 g_assert_no_error (error);
1062 g_assert_nonnull (move_test_dir);
1063
1064 /* We need some file which we can move. So, we use test_dummy_file to create
1065 * a copy of that file and move its copy around using its ID. */
1066 source_file = create_temporary_duplicate_file (self->test_dummy_file, &error);
1067 g_assert_no_error (error);
1068 g_assert_nonnull (source_file);
1069
1070 source_file_title = get_file_attribute (source_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
1071 g_assert_no_error (error);
1072 g_assert_nonnull (source_file_title);
1073
1074 dest_path = g_file_get_path (move_test_dir);
1075 dest_file = g_file_new_build_filename (dest_path, source_file_title, NULL);
1076
1077 op_done = g_file_move (source_file, dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
1078 g_assert_no_error (error);
1079 g_assert_true (op_done);
1080
1081 dest_file_actual_display_name = get_file_attribute (dest_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
1082 g_assert_cmpstr (dest_file_actual_display_name, ==, source_file_title);
1083 }
1084
1085 static void
gvfs_google_test_move_file_from_one_parent_to_other_using_new_title(gconstpointer user_data)1086 gvfs_google_test_move_file_from_one_parent_to_other_using_new_title (gconstpointer user_data)
1087 {
1088 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
1089 gboolean op_done;
1090 g_autoptr(GError) error = NULL;
1091 g_autofree gchar *parent_path = NULL;
1092 g_autofree gchar *dest_path = NULL;
1093 g_autofree gchar *source_file_title = NULL;
1094 g_autofree gchar *new_file_title = NULL;
1095 g_autofree gchar *dest_file_actual_display_name = NULL;
1096 g_autoptr(GFile) move_test_dir = NULL;
1097 g_autoptr(GFile) source_file = NULL;
1098 g_autoptr(GFile) dest_file = NULL;
1099
1100 parent_path = g_file_get_path (self->test_dir);
1101 move_test_dir = g_file_get_child_for_display_name (self->test_dir, OP_MOVE_TEST_DIRECTORY, &error);
1102 g_assert_no_error (error);
1103 g_assert_nonnull (move_test_dir);
1104
1105 /* We need some file which we can move. So, we use test_dummy_file to create
1106 * a copy of that file and move its copy around using its ID. */
1107 source_file = create_temporary_duplicate_file (self->test_dummy_file, &error);
1108 g_assert_no_error (error);
1109 g_assert_nonnull (source_file);
1110
1111 source_file_title = get_file_attribute (source_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
1112 g_assert_no_error (error);
1113 g_assert_nonnull (source_file_title);
1114
1115 new_file_title = g_strconcat (source_file_title, " (NewTitle)", NULL);
1116 dest_path = g_file_get_path (move_test_dir);
1117 dest_file = g_file_new_build_filename (dest_path, new_file_title, NULL);
1118
1119 op_done = g_file_move (source_file, dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
1120 g_assert_no_error (error);
1121 g_assert_true (op_done);
1122
1123 dest_file_actual_display_name = get_file_attribute (dest_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
1124 g_assert_cmpstr (dest_file_actual_display_name, ==, new_file_title);
1125 }
1126
1127 static void
gvfs_google_test_move_file_from_one_parent_to_other_using_id(gconstpointer user_data)1128 gvfs_google_test_move_file_from_one_parent_to_other_using_id (gconstpointer user_data)
1129 {
1130 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
1131 gboolean op_done;
1132 g_autoptr(GError) error = NULL;
1133 g_autofree gchar *test_dir_path = NULL;
1134 g_autofree gchar *dest_path = NULL;
1135 g_autofree gchar *source_file_id = NULL;
1136 g_autofree gchar *source_file_title = NULL;
1137 g_autofree gchar *dest_file_actual_display_name = NULL;
1138 g_autoptr(GFile) move_test_dir = NULL;
1139 g_autoptr(GFile) source_file = NULL;
1140 g_autoptr(GFile) dest_file = NULL;
1141
1142 /* We need some file which we can move. So, we use test_dummy_file to create
1143 * a copy of that file and move its copy around using its ID. */
1144 source_file = create_temporary_duplicate_file (self->test_dummy_file, &error);
1145 g_assert_no_error (error);
1146 g_assert_nonnull (source_file);
1147
1148 test_dir_path = g_file_get_path (self->test_dir);
1149 move_test_dir = g_file_get_child_for_display_name (self->test_dir, OP_MOVE_TEST_DIRECTORY, &error);
1150 g_assert_no_error (error);
1151 g_assert_nonnull (move_test_dir);
1152
1153 source_file_title = get_file_attribute (source_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
1154 g_assert_no_error (error);
1155 g_assert_nonnull (source_file_title);
1156
1157 source_file_id = get_file_attribute (source_file, G_FILE_ATTRIBUTE_ID_FILE, &error);
1158 g_assert_no_error (error);
1159 g_assert_nonnull (source_file_id);
1160
1161 dest_path = g_file_get_path (move_test_dir);
1162 dest_file = g_file_new_build_filename (dest_path, source_file_id, NULL);
1163
1164 op_done = g_file_move (source_file, dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
1165 g_assert_no_error (error);
1166 g_assert_true (op_done);
1167
1168 dest_file_actual_display_name = get_file_attribute (dest_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, &error);
1169 g_assert_no_error (error);
1170 g_assert_nonnull (dest_file_actual_display_name);
1171
1172 g_assert_cmpstr (dest_file_actual_display_name, ==, source_file_title);
1173 }
1174
1175 #ifdef HAVE_GDATA_DOCUMENTS_QUERY_SET_ORDER_BY
1176 static void
gvfs_google_test_move_file_from_one_parent_to_other_with_both_title_and_volatile_entry_collision(gconstpointer user_data)1177 gvfs_google_test_move_file_from_one_parent_to_other_with_both_title_and_volatile_entry_collision (gconstpointer user_data)
1178 {
1179 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
1180 gboolean op_done;
1181 g_autoptr(GError) error = NULL;
1182 g_autofree gchar *test_dir_path = NULL;
1183 g_autofree gchar *parent_path = NULL;
1184 g_autofree gchar *source_file_id = NULL;
1185 g_autoptr(GFile) move_test_dir = NULL;
1186 g_autoptr(GFile) source_file = NULL;
1187 g_autoptr(GFile) dest_file = NULL;
1188
1189 /* We need some file which we can firstly copy. So, we use test_dummy_file to create
1190 * a copy of that file and move its copy around using its ID. */
1191 source_file = create_temporary_duplicate_file (self->test_dummy_file, &error);
1192 g_assert_no_error (error);
1193 g_assert_nonnull (source_file);
1194
1195 source_file_id = get_file_attribute (source_file, G_FILE_ATTRIBUTE_ID_FILE, &error);
1196 g_assert_no_error (error);
1197 g_assert_nonnull (source_file_id);
1198
1199 test_dir_path = g_file_get_path (self->test_dir);
1200 move_test_dir = g_file_get_child_for_display_name (self->test_dir, OP_MOVE_TEST_DIRECTORY, &error);
1201 g_assert_no_error (error);
1202 g_assert_nonnull (move_test_dir);
1203
1204 parent_path = g_file_get_path (move_test_dir);
1205 dest_file = g_file_new_build_filename (parent_path, source_file_id, NULL);
1206
1207 /* The copy operation, i.e. `gio copy id1 ./id2/` (which is equivalent to
1208 * `gio copy id1 ./id2/id1`) */
1209 op_done = g_file_copy (source_file, dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
1210 g_assert_no_error (error);
1211 g_assert_true (op_done);
1212
1213 /* The move operation, i.e. `gio move id1 ./id2/` (which is equivalent to
1214 * `gio move id1 ./id2/id1`) */
1215 op_done = g_file_move (source_file, dest_file, G_FILE_COPY_NONE, NULL, NULL, NULL, &error);
1216 g_assert_no_error (error);
1217 g_assert_true (op_done);
1218
1219 /* TODO: Assert here that both the files are present */
1220 }
1221 #endif
1222
1223 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~ Delete Test Case Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
1224
1225 static void
gvfs_google_test_recursive_delete_test_dir_folder(gconstpointer user_data)1226 gvfs_google_test_recursive_delete_test_dir_folder (gconstpointer user_data)
1227 {
1228 GVfsGoogleTestData *self = (GVfsGoogleTestData *) user_data;
1229 gboolean op_done;
1230 g_autoptr(GError) error = NULL;
1231
1232 op_done = delete_and_make_new_directory (self->test_dir, &error);
1233 g_assert_no_error (error);
1234 g_assert_true (op_done);
1235 }
1236
1237 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~ Main Function ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
1238
1239 gint
main(gint argc,gchar * argv[])1240 main (gint argc, gchar *argv [])
1241 {
1242 gint retval = EXIT_SUCCESS;
1243 GVfsGoogleTestData *self;
1244 g_autoptr(GError) error = NULL;
1245
1246 setlocale (LC_ALL, "");
1247
1248 g_test_init (&argc, &argv, NULL);
1249
1250 gvfs_google_test_init (&self, &error);
1251 if (error != NULL)
1252 {
1253 g_warning ("Error (init): %s", error->message);
1254 return 1;
1255 }
1256
1257 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~ Make Dir test cases ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
1258
1259 /* Test Scenario: We try to create a folder with its title set to the string
1260 * "valid_display_name_directory".
1261 *
1262 * Expected Behaviour: The newly created folder has the title
1263 * "valid_display_name_directory".
1264 *
1265 * Actual Behaviour is same as expected behaviour. */
1266 g_test_add_data_func ("/make_directory/using_valid_display_name",
1267 (gconstpointer) self,
1268 gvfs_google_test_make_directory_using_valid_display_name);
1269
1270 /* Test Scenario: We try to create a folder having the title of the folder set
1271 * to some other file/folder's ID. So, we try to create a new folder with
1272 * self->test_dir_entry's ID.
1273 *
1274 * Expected Behaviour: The newly created folder has the same title as
1275 * self->test_dir_entry's ID.
1276 *
1277 * Actual Behaviour: The newly created folder gets its title set to
1278 * self->test_dir_entry's title and *NOT* its ID. The reason is well documented
1279 * in the make_directory function in gvfsbackendgoogle.c */
1280 g_test_add_data_func ("/make_directory/using_valid_id_of_other_directory",
1281 (gconstpointer) self,
1282 gvfs_google_test_make_directory_using_valid_id);
1283
1284 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~ Copy test cases ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
1285
1286 /* The below test case is equivalent to the following commandline operations:
1287 * (Assume that file with ID `id1` has the title $T)
1288 *
1289 * `gio copy id1 ./"$T (copy)"` (where id2 is the ID of a folder)
1290 *
1291 * This operation mimics what nautilus does when we do a Ctrl+C & Ctrl+V
1292 * operation on a file inside same parent directory. It simply appends a
1293 * " (copy)" to the name of the file. */
1294 g_test_add_data_func ("/copy_file/within_same_parent_with_title_change",
1295 (gconstpointer) self,
1296 gvfs_google_test_copy_file_within_same_parent_with_title_change);
1297
1298 /* We try to copy a file within the same parent without changing the title, i.e. this
1299 * operation corresponds to `gio copy -i ./file1_title ./file1_title` but without overwrite.
1300 *
1301 * This operation should supposedly fail with error code `G_IO_ERROR_EXISTS`
1302 * and string "Target file already exists". */
1303 g_test_add_data_func ("/copy_file/within_same_parent_with_same_title",
1304 (gconstpointer) self,
1305 gvfs_google_test_copy_file_within_same_parent_with_same_title);
1306
1307 /* We try to copy a file within the same parent and keeping the title of file
1308 * to be same as the ID of source file, i.e. this operation corresponds to
1309 * `gio copy -i ./id1 ./id1` but without overwrite.
1310 *
1311 * This operation should supposedly fail with error code `G_IO_ERROR_EXISTS`
1312 * and string "Target file already exists". */
1313 g_test_add_data_func ("/copy_file/within_same_parent_with_source_id_as_destination_basename",
1314 (gconstpointer) self,
1315 gvfs_google_test_copy_file_within_same_parent_with_source_id_as_destination_basename);
1316
1317 /* The below test case is equivalent to the following commandline operations:
1318 *
1319 * `gio copy ./id1 ./$Title$` where $Title$ is the title of file with ID `id1`.
1320 *
1321 * This operation should supposedly fail when done over the commandline gio
1322 * tool with error code `G_IO_ERROR_FAILED` and string "Operation Not Supported".
1323 * TODO: Fix the below test-case to use actual overwrite. */
1324 g_test_add_data_func ("/copy_file/within_same_parent_try_overwrite_with_same_title",
1325 (gconstpointer) self,
1326 gvfs_google_test_copy_file_within_same_parent_try_overwrite_with_same_title);
1327
1328 /* The below test case is equivalent to the following commandline operations:
1329 *
1330 * `gio copy id1 ./id1`
1331 *
1332 * This operation should supposedly fail when done over the commandline gio
1333 * tool with error code `G_IO_ERROR_FAILED` and string "Operation Not Supported".
1334 * TODO: Fix the below test-case to use actual overwrite. */
1335 g_test_add_data_func ("/copy_file/within_same_parent_try_overwrite_with_id",
1336 (gconstpointer) self,
1337 gvfs_google_test_copy_file_within_same_parent_try_overwrite_with_id);
1338
1339 /* The below test case is equivalent to the following commandline operations:
1340 * `gio copy id1 id2/$Title$` (where id2 is the ID of a folder, and $Title$
1341 * is the title of file with ID `id1`) */
1342 g_test_add_data_func ("/copy_file/from_one_parent_to_other_using_same_title",
1343 (gconstpointer) self,
1344 gvfs_google_test_copy_file_from_one_parent_to_other_using_same_title);
1345
1346 /* The below test cases causes just a collision on the volatile entry. This
1347 * is because the previously executed test copies a file into the OP_COPY_TEST_DIRECTORY.
1348 * So, one volatile entry was already there because of that file, and we
1349 * change the title here to only cause a collision on the volatile entry (and
1350 * not the title too).
1351 *
1352 * It basically mimics the following case:
1353 * `gio copy id1 id2/some_title`
1354 * `gio copy id1 id2/some_random_title` */
1355 g_test_add_data_func ("/copy_file/from_one_parent_to_other_with_volatile_entry_collision_only",
1356 (gconstpointer) self,
1357 gvfs_google_test_copy_file_from_one_parent_to_other_with_volatile_entry_collision_only);
1358
1359 /* The below test case uses the same function as the test case with
1360 * identifier "/copy_file/from_one_parent_to_other" because copying
1361 * file from source to destination is same as producing both kinds of
1362 * collisions at once.
1363 *
1364 * It basically mimics the following case:
1365 * `gio copy id1 id2/some_title`
1366 * `gio copy id1 id2/some_title`
1367 *
1368 * TODO: Re-enable the below test-case once you have orderBy="modifiedDate" */
1369 #ifdef HAVE_GDATA_DOCUMENTS_QUERY_SET_ORDER_BY
1370 g_test_add_data_func ("/copy_file/from_one_parent_to_other_with_both_title_and_volatile_entry_collision",
1371 (gconstpointer) self,
1372 gvfs_google_test_copy_file_from_one_parent_to_other_using_same_title);
1373 #endif
1374
1375 /* The below test case is equivalent to the following commandline operations:
1376 * `gio copy id1 id2/id1` (where id2 is the ID of a folder) */
1377 g_test_add_data_func ("/copy_file/from_one_parent_to_other_using_id",
1378 (gconstpointer) self,
1379 gvfs_google_test_copy_file_from_one_parent_to_other_using_id);
1380
1381 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~ Move test cases ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
1382
1383 /* The below test case is equivalent to the following commandline operations:
1384 * (Assume that file with ID `id1` has the title "title1")
1385 *
1386 * `gio move ./title1 ./title1`
1387 *
1388 * This operation will fail with an error */
1389 g_test_add_data_func ("/move_file/within_same_parent_without_title_change",
1390 (gconstpointer) self,
1391 gvfs_google_test_move_file_within_same_parent_without_title_change);
1392
1393 /* The below test case is equivalent to the following commandline operations:
1394 * (Assume that file with ID `id1` has the title ${TITLE})
1395 *
1396 * `gio move ./${TITLE} ./SomeOtherTitle`
1397 *
1398 * This is just a normal rename operation in POSIX world, and the backend allows this. */
1399 g_test_add_data_func ("/move_file/within_same_parent_with_title_change",
1400 (gconstpointer) self,
1401 gvfs_google_test_move_file_within_same_parent_with_title_change);
1402
1403 /* The below test case is equivalent to the following commandline operations:
1404 * `gio move ./id1 ./id2/$Title$` (where `id2` is the ID of a folder, and
1405 * $Title$ is the title of file with ID `id1`).
1406 *
1407 * This is simplest case for cross directory file moving. */
1408 g_test_add_data_func ("/move_file/from_one_parent_to_other_without_backup",
1409 (gconstpointer) self,
1410 gvfs_google_test_move_file_from_one_parent_to_other_without_backup);
1411
1412 /* The below test case is equivalent to the following commandline operations
1413 * (with the G_FILE_COPY_BACKUP flag supplied to g_file_move function):
1414 * `gio move ./id1 id2/$Title$` (where `id2` is the ID of a folder, and
1415 * $Title$ is the title of file with ID `id1`)
1416 *
1417 * Although the g_vfs_backend_google_move () will fail with G_IO_ERROR_NOT_SUPPORTED,
1418 * gio will use the fallback (copy + create + read + write + delete) to
1419 * support a backup operation. */
1420 g_test_add_data_func ("/move_file/from_one_parent_to_other_with_backup",
1421 (gconstpointer) self,
1422 gvfs_google_test_move_file_from_one_parent_to_other_with_backup);
1423
1424 /* The below test case is equivalent to the following commandline operations:
1425 * `gio move ./id1 id2/$Title$` (where `id2` is the ID of a folder, and
1426 * $Title$ is the title of file with ID `id1`) */
1427 g_test_add_data_func ("/move_file/from_one_parent_to_other_using_same_title",
1428 (gconstpointer) self,
1429 gvfs_google_test_move_file_from_one_parent_to_other_using_same_title);
1430
1431 /* The below test case is equivalent to the following commandline operations:
1432 * `gio move ./id1 id2/SomeNewTitle` (where `id2` is the ID of a folder, and
1433 * $Title$ is the title of file with ID `id1`) */
1434 g_test_add_data_func ("/move_file/from_one_parent_to_other_using_new_title",
1435 (gconstpointer) self,
1436 gvfs_google_test_move_file_from_one_parent_to_other_using_new_title);
1437
1438 /* The below test case is equivalent to the following commandline operations:
1439 * `gio move ./id1 id2/id1` (where `id2` is the ID of a folder) */
1440 g_test_add_data_func ("/move_file/from_one_parent_to_other_using_id",
1441 (gconstpointer) self,
1442 gvfs_google_test_move_file_from_one_parent_to_other_using_id);
1443
1444 /* The below test case is equivalent to the following commandline operations:
1445 *
1446 * 1. `gio copy ./id1 ./id2/` ("id2" is the real ID of a folder)
1447 * 2. `gio move ./id1 ./id2/`
1448 *
1449 * In this, the copy operation will create a volatile entry i.e. (id1, id2) -> Entry tuple.
1450 * Later, during the move operation, this volatile entry will collide with
1451 * the real ID "id1". We support this operation and the below test should pass.
1452 * TODO: Re-enable the below test-case once you have orderBy="modifiedDate" */
1453 #ifdef HAVE_GDATA_DOCUMENTS_QUERY_SET_ORDER_BY
1454 g_test_add_data_func ("/move_file/from_one_parent_to_other_with_both_title_and_volatile_entry_collision",
1455 (gconstpointer) self,
1456 gvfs_google_test_move_file_from_one_parent_to_other_with_both_title_and_volatile_entry_collision);
1457 #endif
1458
1459 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~ Delete test cases ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
1460
1461 /* We simply delete everything in the below case. If the backend crashes at
1462 * this point, there is some issue with cache. Moreover, delete is the case
1463 * which can be used to ensure the sanity of the cache. If delete wrongly
1464 * removes an entry (or wrongly decreases the ref_count), there's a very high
1465 * chance of getting a segfault sometime later.
1466 *
1467 * Also, beyond the execution of below test case, the GFile corresponding to
1468 * self->test_dummy_file won't be valid since that file will be deleted. As a result,
1469 * any operation done using test_dummy_file will result into an error. The memory
1470 * corresponding to the test_dummy_file GFile will be freed in the cleanup
1471 * function. */
1472 g_test_add_data_func ("/recursive_delete/test_dir_folder",
1473 (gconstpointer) self,
1474 gvfs_google_test_recursive_delete_test_dir_folder);
1475
1476 retval = g_test_run ();
1477
1478 gvfs_google_test_exit_cleanup (&self, &error);
1479 if (error != NULL)
1480 {
1481 g_warning ("Error (cleanup): %s", error->message);
1482 retval = EXIT_FAILURE;
1483 }
1484
1485 return retval;
1486 }
1487