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/sync_file_system/drive_backend_v1/fake_drive_service_helper.h" 6 7 #include "base/bind.h" 8 #include "base/file_util.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/run_loop.h" 11 #include "base/threading/sequenced_worker_pool.h" 12 #include "chrome/browser/sync_file_system/drive_backend_v1/api_util.h" 13 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h" 14 #include "chrome/browser/sync_file_system/sync_status_code.h" 15 #include "content/public/test/test_browser_thread.h" 16 #include "google_apis/drive/drive_api_parser.h" 17 #include "google_apis/drive/gdata_wapi_parser.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 #include "webkit/browser/fileapi/file_system_url.h" 20 21 #define FPL(path) FILE_PATH_LITERAL(path) 22 23 using google_apis::AboutResource; 24 using google_apis::GDataErrorCode; 25 using google_apis::ResourceEntry; 26 using google_apis::ResourceList; 27 28 namespace sync_file_system { 29 namespace drive_backend { 30 31 namespace { 32 33 void UploadResultCallback(GDataErrorCode* error_out, 34 scoped_ptr<ResourceEntry>* entry_out, 35 GDataErrorCode error, 36 const GURL& upload_location, 37 scoped_ptr<ResourceEntry> entry) { 38 ASSERT_TRUE(error_out); 39 ASSERT_TRUE(entry_out); 40 *error_out = error; 41 *entry_out = entry.Pass(); 42 } 43 44 void DownloadResultCallback(GDataErrorCode* error_out, 45 GDataErrorCode error, 46 const base::FilePath& local_file) { 47 ASSERT_TRUE(error_out); 48 *error_out = error; 49 } 50 51 } // namespace 52 53 FakeDriveServiceHelper::FakeDriveServiceHelper( 54 drive::FakeDriveService* fake_drive_service, 55 drive::DriveUploaderInterface* drive_uploader) 56 : fake_drive_service_(fake_drive_service), 57 drive_uploader_(drive_uploader) { 58 Initialize(); 59 } 60 61 FakeDriveServiceHelper::~FakeDriveServiceHelper() { 62 } 63 64 GDataErrorCode FakeDriveServiceHelper::AddOrphanedFolder( 65 const std::string& title, 66 std::string* folder_id) { 67 EXPECT_TRUE(folder_id); 68 69 std::string root_folder_id = fake_drive_service_->GetRootResourceId(); 70 GDataErrorCode error = AddFolder(root_folder_id, title, folder_id); 71 if (error != google_apis::HTTP_CREATED) 72 return error; 73 74 error = google_apis::GDATA_OTHER_ERROR; 75 fake_drive_service_->RemoveResourceFromDirectory( 76 root_folder_id, *folder_id, 77 CreateResultReceiver(&error)); 78 base::RunLoop().RunUntilIdle(); 79 80 if (error != google_apis::HTTP_NO_CONTENT) 81 return error; 82 return google_apis::HTTP_CREATED; 83 } 84 85 GDataErrorCode FakeDriveServiceHelper::AddFolder( 86 const std::string& parent_folder_id, 87 const std::string& title, 88 std::string* folder_id) { 89 EXPECT_TRUE(folder_id); 90 91 GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 92 scoped_ptr<ResourceEntry> folder; 93 fake_drive_service_->AddNewDirectory( 94 parent_folder_id, title, 95 CreateResultReceiver(&error, &folder)); 96 base::RunLoop().RunUntilIdle(); 97 98 if (error == google_apis::HTTP_CREATED) 99 *folder_id = folder->resource_id(); 100 return error; 101 } 102 103 GDataErrorCode FakeDriveServiceHelper::AddFile( 104 const std::string& parent_folder_id, 105 const std::string& title, 106 const std::string& content, 107 std::string* file_id) { 108 EXPECT_TRUE(file_id); 109 base::FilePath temp_file = WriteToTempFile(content); 110 111 GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 112 scoped_ptr<ResourceEntry> file; 113 drive_uploader_->UploadNewFile( 114 parent_folder_id, temp_file, title, 115 "application/octet-stream", 116 base::Bind(&UploadResultCallback, &error, &file), 117 google_apis::ProgressCallback()); 118 base::RunLoop().RunUntilIdle(); 119 120 if (error == google_apis::HTTP_SUCCESS) 121 *file_id = file->resource_id(); 122 return error; 123 } 124 125 GDataErrorCode FakeDriveServiceHelper::UpdateFile( 126 const std::string& file_id, 127 const std::string& content) { 128 base::FilePath temp_file = WriteToTempFile(content); 129 GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 130 scoped_ptr<ResourceEntry> file; 131 drive_uploader_->UploadExistingFile( 132 file_id, temp_file, 133 "application/octet-stream", 134 std::string(), // etag 135 base::Bind(&UploadResultCallback, &error, &file), 136 google_apis::ProgressCallback()); 137 base::RunLoop().RunUntilIdle(); 138 return error; 139 } 140 141 GDataErrorCode FakeDriveServiceHelper::DeleteResource( 142 const std::string& file_id) { 143 GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 144 fake_drive_service_->DeleteResource( 145 file_id, 146 std::string(), // etag 147 CreateResultReceiver(&error)); 148 base::RunLoop().RunUntilIdle(); 149 return error; 150 } 151 152 GDataErrorCode FakeDriveServiceHelper::TrashResource( 153 const std::string& file_id) { 154 GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 155 fake_drive_service_->TrashResource( 156 file_id, 157 CreateResultReceiver(&error)); 158 base::RunLoop().RunUntilIdle(); 159 return error; 160 } 161 162 GDataErrorCode FakeDriveServiceHelper::GetSyncRootFolderID( 163 std::string* sync_root_folder_id) { 164 GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 165 scoped_ptr<ResourceList> resource_list; 166 fake_drive_service_->SearchByTitle( 167 APIUtil::GetSyncRootDirectoryName(), std::string(), 168 CreateResultReceiver(&error, &resource_list)); 169 base::RunLoop().RunUntilIdle(); 170 if (error != google_apis::HTTP_SUCCESS) 171 return error; 172 173 const ScopedVector<ResourceEntry>& entries = resource_list->entries(); 174 for (ScopedVector<ResourceEntry>::const_iterator itr = entries.begin(); 175 itr != entries.end(); ++itr) { 176 const ResourceEntry& entry = **itr; 177 if (!entry.GetLinkByType(google_apis::Link::LINK_PARENT)) { 178 *sync_root_folder_id = entry.resource_id(); 179 return google_apis::HTTP_SUCCESS; 180 } 181 } 182 return google_apis::HTTP_NOT_FOUND; 183 } 184 185 GDataErrorCode FakeDriveServiceHelper::ListFilesInFolder( 186 const std::string& folder_id, 187 ScopedVector<ResourceEntry>* entries) { 188 GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 189 scoped_ptr<ResourceList> list; 190 fake_drive_service_->GetResourceListInDirectory( 191 folder_id, 192 CreateResultReceiver(&error, &list)); 193 base::RunLoop().RunUntilIdle(); 194 if (error != google_apis::HTTP_SUCCESS) 195 return error; 196 197 return CompleteListing(list.Pass(), entries); 198 } 199 200 GDataErrorCode FakeDriveServiceHelper::SearchByTitle( 201 const std::string& folder_id, 202 const std::string& title, 203 ScopedVector<ResourceEntry>* entries) { 204 GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 205 scoped_ptr<ResourceList> list; 206 fake_drive_service_->SearchByTitle( 207 title, folder_id, 208 CreateResultReceiver(&error, &list)); 209 base::RunLoop().RunUntilIdle(); 210 if (error != google_apis::HTTP_SUCCESS) 211 return error; 212 213 return CompleteListing(list.Pass(), entries); 214 } 215 216 GDataErrorCode FakeDriveServiceHelper::GetResourceEntry( 217 const std::string& file_id, 218 scoped_ptr<ResourceEntry>* entry) { 219 GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 220 fake_drive_service_->GetResourceEntry( 221 file_id, 222 CreateResultReceiver(&error, entry)); 223 base::RunLoop().RunUntilIdle(); 224 return error; 225 } 226 227 GDataErrorCode FakeDriveServiceHelper::ReadFile( 228 const std::string& file_id, 229 std::string* file_content) { 230 scoped_ptr<google_apis::ResourceEntry> file; 231 GDataErrorCode error = GetResourceEntry(file_id, &file); 232 if (error != google_apis::HTTP_SUCCESS) 233 return error; 234 if (!file) 235 return google_apis::GDATA_PARSE_ERROR; 236 237 error = google_apis::GDATA_OTHER_ERROR; 238 base::FilePath temp_file; 239 EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_, &temp_file)); 240 fake_drive_service_->DownloadFile( 241 temp_file, file->resource_id(), 242 base::Bind(&DownloadResultCallback, &error), 243 google_apis::GetContentCallback(), 244 google_apis::ProgressCallback()); 245 base::RunLoop().RunUntilIdle(); 246 if (error != google_apis::HTTP_SUCCESS) 247 return error; 248 249 return base::ReadFileToString(temp_file, file_content) 250 ? google_apis::HTTP_SUCCESS : google_apis::GDATA_FILE_ERROR; 251 } 252 253 GDataErrorCode FakeDriveServiceHelper::GetAboutResource( 254 scoped_ptr<AboutResource>* about_resource) { 255 GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 256 fake_drive_service_->GetAboutResource( 257 CreateResultReceiver(&error, about_resource)); 258 base::RunLoop().RunUntilIdle(); 259 return error; 260 } 261 262 GDataErrorCode FakeDriveServiceHelper::CompleteListing( 263 scoped_ptr<ResourceList> list, 264 ScopedVector<ResourceEntry>* entries) { 265 while (true) { 266 entries->reserve(entries->size() + list->entries().size()); 267 for (ScopedVector<ResourceEntry>::iterator itr = 268 list->mutable_entries()->begin(); 269 itr != list->mutable_entries()->end(); ++itr) { 270 entries->push_back(*itr); 271 *itr = NULL; 272 } 273 274 GURL next_feed; 275 if (!list->GetNextFeedURL(&next_feed)) 276 return google_apis::HTTP_SUCCESS; 277 278 GDataErrorCode error = google_apis::GDATA_OTHER_ERROR; 279 list.reset(); 280 fake_drive_service_->GetRemainingFileList( 281 next_feed, 282 CreateResultReceiver(&error, &list)); 283 base::RunLoop().RunUntilIdle(); 284 if (error != google_apis::HTTP_SUCCESS) 285 return error; 286 } 287 } 288 289 void FakeDriveServiceHelper::Initialize() { 290 ASSERT_TRUE(base_dir_.CreateUniqueTempDir()); 291 temp_dir_ = base_dir_.path().Append(FPL("tmp")); 292 ASSERT_TRUE(base::CreateDirectory(temp_dir_)); 293 } 294 295 base::FilePath FakeDriveServiceHelper::WriteToTempFile( 296 const std::string& content) { 297 base::FilePath temp_file; 298 EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_, &temp_file)); 299 EXPECT_EQ(static_cast<int>(content.size()), 300 file_util::WriteFile(temp_file, content.data(), content.size())); 301 return temp_file; 302 } 303 304 } // namespace drive_backend 305 } // namespace sync_file_system 306