1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/chromeos/drive/sync/remove_performer.h" 6 7#include "base/task_runner_util.h" 8#include "chrome/browser/chromeos/drive/file_system/operation_test_base.h" 9#include "chrome/browser/chromeos/drive/file_system_util.h" 10#include "chrome/browser/chromeos/drive/job_scheduler.h" 11#include "chrome/browser/chromeos/drive/resource_metadata.h" 12#include "chrome/browser/drive/fake_drive_service.h" 13#include "content/public/test/test_utils.h" 14#include "google_apis/drive/drive_api_parser.h" 15#include "google_apis/drive/test_util.h" 16 17namespace drive { 18namespace internal { 19 20typedef file_system::OperationTestBase RemovePerformerTest; 21 22TEST_F(RemovePerformerTest, RemoveFile) { 23 RemovePerformer performer(blocking_task_runner(), delegate(), scheduler(), 24 metadata()); 25 26 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt")); 27 base::FilePath file_in_subdir( 28 FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt")); 29 30 // Remove a file in root. 31 ResourceEntry entry; 32 FileError error = FILE_ERROR_FAILED; 33 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &entry)); 34 performer.Remove(entry.local_id(), 35 ClientContext(USER_INITIATED), 36 google_apis::test_util::CreateCopyResultCallback(&error)); 37 content::RunAllBlockingPoolTasksUntilIdle(); 38 EXPECT_EQ(FILE_ERROR_OK, error); 39 40 // Remove a file in subdirectory. 41 error = FILE_ERROR_FAILED; 42 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_subdir, &entry)); 43 const std::string resource_id = entry.resource_id(); 44 45 performer.Remove(entry.local_id(), 46 ClientContext(USER_INITIATED), 47 google_apis::test_util::CreateCopyResultCallback(&error)); 48 content::RunAllBlockingPoolTasksUntilIdle(); 49 EXPECT_EQ(FILE_ERROR_OK, error); 50 51 // Verify the file is indeed removed in the server. 52 google_apis::GDataErrorCode gdata_error = google_apis::GDATA_OTHER_ERROR; 53 scoped_ptr<google_apis::FileResource> gdata_entry; 54 fake_service()->GetFileResource( 55 resource_id, 56 google_apis::test_util::CreateCopyResultCallback(&gdata_error, 57 &gdata_entry)); 58 content::RunAllBlockingPoolTasksUntilIdle(); 59 ASSERT_EQ(google_apis::HTTP_SUCCESS, gdata_error); 60 EXPECT_TRUE(gdata_entry->labels().is_trashed()); 61 62 // Try removing non-existing file. 63 error = FILE_ERROR_FAILED; 64 performer.Remove("non-existing-id", 65 ClientContext(USER_INITIATED), 66 google_apis::test_util::CreateCopyResultCallback(&error)); 67 content::RunAllBlockingPoolTasksUntilIdle(); 68 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error); 69} 70 71TEST_F(RemovePerformerTest, RemoveShared) { 72 RemovePerformer performer(blocking_task_runner(), delegate(), scheduler(), 73 metadata()); 74 75 const base::FilePath kPathInMyDrive(FILE_PATH_LITERAL( 76 "drive/root/shared.txt")); 77 const base::FilePath kPathInOther(FILE_PATH_LITERAL( 78 "drive/other/shared.txt")); 79 80 // Prepare a shared file to the root folder. 81 google_apis::GDataErrorCode gdata_error = google_apis::GDATA_OTHER_ERROR; 82 scoped_ptr<google_apis::FileResource> gdata_entry; 83 fake_service()->AddNewFile( 84 "text/plain", 85 "dummy content", 86 fake_service()->GetRootResourceId(), 87 kPathInMyDrive.BaseName().AsUTF8Unsafe(), 88 true, // shared_with_me, 89 google_apis::test_util::CreateCopyResultCallback(&gdata_error, 90 &gdata_entry)); 91 content::RunAllBlockingPoolTasksUntilIdle(); 92 ASSERT_EQ(google_apis::HTTP_CREATED, gdata_error); 93 CheckForUpdates(); 94 95 // Remove it. Locally, the file should be moved to drive/other. 96 ResourceEntry entry; 97 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kPathInMyDrive, &entry)); 98 FileError error = FILE_ERROR_FAILED; 99 performer.Remove(entry.local_id(), 100 ClientContext(USER_INITIATED), 101 google_apis::test_util::CreateCopyResultCallback(&error)); 102 content::RunAllBlockingPoolTasksUntilIdle(); 103 EXPECT_EQ(FILE_ERROR_OK, error); 104 EXPECT_EQ(FILE_ERROR_NOT_FOUND, 105 GetLocalResourceEntry(kPathInMyDrive, &entry)); 106 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kPathInOther, &entry)); 107 108 // Remotely, the entry should have lost its parent. 109 gdata_error = google_apis::GDATA_OTHER_ERROR; 110 const std::string resource_id = gdata_entry->file_id(); 111 fake_service()->GetFileResource( 112 resource_id, 113 google_apis::test_util::CreateCopyResultCallback(&gdata_error, 114 &gdata_entry)); 115 content::RunAllBlockingPoolTasksUntilIdle(); 116 ASSERT_EQ(google_apis::HTTP_SUCCESS, gdata_error); 117 EXPECT_FALSE(gdata_entry->labels().is_trashed()); // It's not deleted. 118 EXPECT_TRUE(gdata_entry->parents().empty()); 119} 120 121TEST_F(RemovePerformerTest, RemoveLocallyCreatedFile) { 122 RemovePerformer performer(blocking_task_runner(), delegate(), scheduler(), 123 metadata()); 124 125 // Add an entry without resource ID. 126 ResourceEntry entry; 127 entry.set_title("New File.txt"); 128 entry.set_parent_local_id(util::kDriveTrashDirLocalId); 129 130 FileError error = FILE_ERROR_FAILED; 131 std::string local_id; 132 base::PostTaskAndReplyWithResult( 133 blocking_task_runner(), 134 FROM_HERE, 135 base::Bind(&ResourceMetadata::AddEntry, 136 base::Unretained(metadata()), 137 entry, 138 &local_id), 139 google_apis::test_util::CreateCopyResultCallback(&error)); 140 content::RunAllBlockingPoolTasksUntilIdle(); 141 EXPECT_EQ(FILE_ERROR_OK, error); 142 143 // Remove the entry. 144 performer.Remove(local_id, ClientContext(USER_INITIATED), 145 google_apis::test_util::CreateCopyResultCallback(&error)); 146 content::RunAllBlockingPoolTasksUntilIdle(); 147 EXPECT_EQ(FILE_ERROR_OK, error); 148 EXPECT_EQ(FILE_ERROR_NOT_FOUND, GetLocalResourceEntryById(local_id, &entry)); 149} 150 151TEST_F(RemovePerformerTest, Remove_InsufficientPermission) { 152 RemovePerformer performer(blocking_task_runner(), delegate(), scheduler(), 153 metadata()); 154 155 base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt")); 156 157 ResourceEntry src_entry; 158 ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_in_root, &src_entry)); 159 160 // Remove locally. 161 ResourceEntry updated_entry(src_entry); 162 updated_entry.set_parent_local_id(util::kDriveTrashDirLocalId); 163 164 FileError error = FILE_ERROR_FAILED; 165 base::PostTaskAndReplyWithResult( 166 blocking_task_runner(), 167 FROM_HERE, 168 base::Bind(&ResourceMetadata::RefreshEntry, 169 base::Unretained(metadata()), 170 updated_entry), 171 google_apis::test_util::CreateCopyResultCallback(&error)); 172 content::RunAllBlockingPoolTasksUntilIdle(); 173 EXPECT_EQ(FILE_ERROR_OK, error); 174 175 // Set user permission to forbid server side update. 176 EXPECT_EQ(google_apis::HTTP_SUCCESS, fake_service()->SetUserPermission( 177 src_entry.resource_id(), google_apis::drive::PERMISSION_ROLE_READER)); 178 179 // Try to perform remove. 180 error = FILE_ERROR_FAILED; 181 performer.Remove(src_entry.local_id(), 182 ClientContext(USER_INITIATED), 183 google_apis::test_util::CreateCopyResultCallback(&error)); 184 content::RunAllBlockingPoolTasksUntilIdle(); 185 EXPECT_EQ(FILE_ERROR_OK, error); 186 187 // This should result in reverting the local change. 188 ResourceEntry result_entry; 189 EXPECT_EQ(FILE_ERROR_OK, 190 GetLocalResourceEntryById(src_entry.local_id(), &result_entry)); 191 EXPECT_EQ(src_entry.parent_local_id(), result_entry.parent_local_id()); 192 193 ASSERT_EQ(1U, delegate()->drive_sync_errors().size()); 194 EXPECT_EQ(file_system::DRIVE_SYNC_ERROR_DELETE_WITHOUT_PERMISSION, 195 delegate()->drive_sync_errors()[0]); 196} 197 198} // namespace internal 199} // namespace drive 200