Home | History | Annotate | Download | only in drive_backend
      1 // Copyright 2014 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/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/drive/drive_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 "google_apis/drive/drive_api_parser.h"
     16 #include "google_apis/drive/gdata_wapi_parser.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 #include "webkit/browser/fileapi/file_system_url.h"
     19 
     20 #define FPL(path) FILE_PATH_LITERAL(path)
     21 
     22 using google_apis::AboutResource;
     23 using google_apis::FileList;
     24 using google_apis::FileResource;
     25 using google_apis::GDataErrorCode;
     26 using google_apis::ResourceEntry;
     27 
     28 namespace sync_file_system {
     29 namespace drive_backend {
     30 
     31 namespace {
     32 
     33 void UploadResultCallback(GDataErrorCode* error_out,
     34                           scoped_ptr<FileResource>* entry_out,
     35                           GDataErrorCode error,
     36                           const GURL& upload_location,
     37                           scoped_ptr<FileResource> 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     const std::string& sync_root_folder_title)
     57     : fake_drive_service_(fake_drive_service),
     58       drive_uploader_(drive_uploader),
     59       sync_root_folder_title_(sync_root_folder_title) {
     60   Initialize();
     61 }
     62 
     63 FakeDriveServiceHelper::~FakeDriveServiceHelper() {
     64 }
     65 
     66 GDataErrorCode FakeDriveServiceHelper::AddOrphanedFolder(
     67     const std::string& title,
     68     std::string* folder_id) {
     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 && folder_id)
     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   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
     90   scoped_ptr<FileResource> folder;
     91   fake_drive_service_->AddNewDirectory(
     92       parent_folder_id, title,
     93       drive::DriveServiceInterface::AddNewDirectoryOptions(),
     94       CreateResultReceiver(&error, &folder));
     95   base::RunLoop().RunUntilIdle();
     96 
     97   if (error == google_apis::HTTP_CREATED && folder_id)
     98     *folder_id = folder->file_id();
     99   return error;
    100 }
    101 
    102 GDataErrorCode FakeDriveServiceHelper::AddFile(
    103     const std::string& parent_folder_id,
    104     const std::string& title,
    105     const std::string& content,
    106     std::string* file_id) {
    107   base::FilePath temp_file = WriteToTempFile(content);
    108 
    109   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    110   scoped_ptr<FileResource> file;
    111   drive_uploader_->UploadNewFile(
    112       parent_folder_id, temp_file, title,
    113       "application/octet-stream",
    114       drive::DriveUploader::UploadNewFileOptions(),
    115       base::Bind(&UploadResultCallback, &error, &file),
    116       google_apis::ProgressCallback());
    117   base::RunLoop().RunUntilIdle();
    118 
    119   if (error == google_apis::HTTP_SUCCESS && file_id)
    120     *file_id = file->file_id();
    121   return error;
    122 }
    123 
    124 GDataErrorCode FakeDriveServiceHelper::UpdateFile(
    125     const std::string& file_id,
    126     const std::string& content) {
    127   base::FilePath temp_file = WriteToTempFile(content);
    128   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    129   scoped_ptr<FileResource> file;
    130   drive_uploader_->UploadExistingFile(
    131       file_id, temp_file,
    132       "application/octet-stream",
    133       drive::DriveUploader::UploadExistingFileOptions(),
    134       base::Bind(&UploadResultCallback, &error, &file),
    135       google_apis::ProgressCallback());
    136   base::RunLoop().RunUntilIdle();
    137   return error;
    138 }
    139 
    140 GDataErrorCode FakeDriveServiceHelper::DeleteResource(
    141     const std::string& file_id) {
    142   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    143   fake_drive_service_->DeleteResource(
    144       file_id,
    145       std::string(),  // etag
    146       CreateResultReceiver(&error));
    147   base::RunLoop().RunUntilIdle();
    148   return error;
    149 }
    150 
    151 GDataErrorCode FakeDriveServiceHelper::TrashResource(
    152     const std::string& file_id) {
    153   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    154   fake_drive_service_->TrashResource(
    155       file_id,
    156       CreateResultReceiver(&error));
    157   base::RunLoop().RunUntilIdle();
    158   return error;
    159 }
    160 
    161 GDataErrorCode FakeDriveServiceHelper::UpdateModificationTime(
    162     const std::string& file_id,
    163     const base::Time& modification_time) {
    164   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    165   scoped_ptr<FileResource> entry;
    166   error = GetFileResource(file_id, &entry);
    167   if (error != google_apis::HTTP_SUCCESS)
    168     return error;
    169 
    170   fake_drive_service_->UpdateResource(
    171       file_id, std::string(), entry->title(),
    172       modification_time, entry->last_viewed_by_me_date(),
    173       CreateResultReceiver(&error, &entry));
    174   base::RunLoop().RunUntilIdle();
    175   return error;
    176 }
    177 
    178 GDataErrorCode FakeDriveServiceHelper::RenameResource(
    179     const std::string& file_id,
    180     const std::string& new_title) {
    181   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    182   fake_drive_service_->RenameResource(
    183       file_id, new_title,
    184       CreateResultReceiver(&error));
    185   base::RunLoop().RunUntilIdle();
    186   return error;
    187 }
    188 
    189 GDataErrorCode FakeDriveServiceHelper::AddResourceToDirectory(
    190     const std::string& parent_folder_id,
    191     const std::string& file_id) {
    192   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    193   fake_drive_service_->AddResourceToDirectory(
    194       parent_folder_id, file_id,
    195       CreateResultReceiver(&error));
    196   base::RunLoop().RunUntilIdle();
    197   return error;
    198 }
    199 
    200 GDataErrorCode FakeDriveServiceHelper::RemoveResourceFromDirectory(
    201     const std::string& parent_folder_id,
    202     const std::string& file_id) {
    203   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    204   fake_drive_service_->RemoveResourceFromDirectory(
    205       parent_folder_id, file_id,
    206       CreateResultReceiver(&error));
    207   base::RunLoop().RunUntilIdle();
    208   return error;
    209 }
    210 
    211 GDataErrorCode FakeDriveServiceHelper::GetSyncRootFolderID(
    212     std::string* sync_root_folder_id) {
    213   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    214   scoped_ptr<FileList> resource_list;
    215   fake_drive_service_->SearchByTitle(
    216       sync_root_folder_title_, std::string(),
    217       CreateResultReceiver(&error, &resource_list));
    218   base::RunLoop().RunUntilIdle();
    219   if (error != google_apis::HTTP_SUCCESS)
    220     return error;
    221 
    222   const ScopedVector<FileResource>& items = resource_list->items();
    223   for (ScopedVector<FileResource>::const_iterator itr = items.begin();
    224        itr != items.end(); ++itr) {
    225     const FileResource& item = **itr;
    226     if (item.parents().empty()) {
    227       *sync_root_folder_id = item.file_id();
    228       return google_apis::HTTP_SUCCESS;
    229     }
    230   }
    231   return google_apis::HTTP_NOT_FOUND;
    232 }
    233 
    234 GDataErrorCode FakeDriveServiceHelper::ListFilesInFolder(
    235     const std::string& folder_id,
    236     ScopedVector<ResourceEntry>* entries) {
    237   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    238   scoped_ptr<FileList> list;
    239   fake_drive_service_->GetFileListInDirectory(
    240       folder_id,
    241       CreateResultReceiver(&error, &list));
    242   base::RunLoop().RunUntilIdle();
    243   if (error != google_apis::HTTP_SUCCESS)
    244     return error;
    245 
    246   return CompleteListing(list.Pass(), entries);
    247 }
    248 
    249 GDataErrorCode FakeDriveServiceHelper::SearchByTitle(
    250     const std::string& folder_id,
    251     const std::string& title,
    252     ScopedVector<ResourceEntry>* entries) {
    253   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    254   scoped_ptr<FileList> list;
    255   fake_drive_service_->SearchByTitle(
    256       title, folder_id,
    257       CreateResultReceiver(&error, &list));
    258   base::RunLoop().RunUntilIdle();
    259   if (error != google_apis::HTTP_SUCCESS)
    260     return error;
    261 
    262   return CompleteListing(list.Pass(), entries);
    263 }
    264 
    265 GDataErrorCode FakeDriveServiceHelper::GetFileResource(
    266     const std::string& file_id,
    267     scoped_ptr<FileResource>* entry) {
    268   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    269   fake_drive_service_->GetFileResource(
    270       file_id,
    271       CreateResultReceiver(&error, entry));
    272   base::RunLoop().RunUntilIdle();
    273   return error;
    274 }
    275 
    276 GDataErrorCode FakeDriveServiceHelper::ReadFile(
    277     const std::string& file_id,
    278     std::string* file_content) {
    279   scoped_ptr<google_apis::FileResource> file;
    280   GDataErrorCode error = GetFileResource(file_id, &file);
    281   if (error != google_apis::HTTP_SUCCESS)
    282     return error;
    283   if (!file)
    284     return google_apis::GDATA_PARSE_ERROR;
    285 
    286   error = google_apis::GDATA_OTHER_ERROR;
    287   base::FilePath temp_file;
    288   EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_, &temp_file));
    289   fake_drive_service_->DownloadFile(
    290       temp_file, file->file_id(),
    291       base::Bind(&DownloadResultCallback, &error),
    292       google_apis::GetContentCallback(),
    293       google_apis::ProgressCallback());
    294   base::RunLoop().RunUntilIdle();
    295   if (error != google_apis::HTTP_SUCCESS)
    296     return error;
    297 
    298   return base::ReadFileToString(temp_file, file_content)
    299       ? google_apis::HTTP_SUCCESS : google_apis::GDATA_FILE_ERROR;
    300 }
    301 
    302 GDataErrorCode FakeDriveServiceHelper::GetAboutResource(
    303     scoped_ptr<AboutResource>* about_resource) {
    304   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    305   fake_drive_service_->GetAboutResource(
    306       CreateResultReceiver(&error, about_resource));
    307   base::RunLoop().RunUntilIdle();
    308   return error;
    309 }
    310 
    311 GDataErrorCode FakeDriveServiceHelper::CompleteListing(
    312     scoped_ptr<FileList> list,
    313     ScopedVector<ResourceEntry>* entries) {
    314   while (true) {
    315     entries->reserve(entries->size() + list->items().size());
    316     for (ScopedVector<FileResource>::const_iterator itr =
    317              list->items().begin(); itr != list->items().end(); ++itr) {
    318       entries->push_back(
    319           drive::util::ConvertFileResourceToResourceEntry(**itr).release());
    320     }
    321 
    322     GURL next_feed = list->next_link();
    323     if (next_feed.is_empty())
    324       return google_apis::HTTP_SUCCESS;
    325 
    326     GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    327     list.reset();
    328     fake_drive_service_->GetRemainingFileList(
    329         next_feed,
    330         CreateResultReceiver(&error, &list));
    331     base::RunLoop().RunUntilIdle();
    332     if (error != google_apis::HTTP_SUCCESS)
    333       return error;
    334   }
    335 }
    336 
    337 void FakeDriveServiceHelper::Initialize() {
    338   ASSERT_TRUE(base_dir_.CreateUniqueTempDir());
    339   temp_dir_ = base_dir_.path().Append(FPL("tmp"));
    340   ASSERT_TRUE(base::CreateDirectory(temp_dir_));
    341 }
    342 
    343 base::FilePath FakeDriveServiceHelper::WriteToTempFile(
    344     const std::string& content) {
    345   base::FilePath temp_file;
    346   EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_, &temp_file));
    347   EXPECT_EQ(static_cast<int>(content.size()),
    348             base::WriteFile(temp_file, content.data(), content.size()));
    349   return temp_file;
    350 }
    351 
    352 }  // namespace drive_backend
    353 }  // namespace sync_file_system
    354