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/files/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 "storage/browser/fileapi/file_system_url.h"
     18 #include "testing/gtest/include/gtest/gtest.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   scoped_ptr<FileResource> entry;
    183   fake_drive_service_->UpdateResource(
    184       file_id, std::string(), new_title, base::Time(), base::Time(),
    185       CreateResultReceiver(&error, &entry));
    186   base::RunLoop().RunUntilIdle();
    187   return error;
    188 }
    189 
    190 GDataErrorCode FakeDriveServiceHelper::AddResourceToDirectory(
    191     const std::string& parent_folder_id,
    192     const std::string& file_id) {
    193   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    194   fake_drive_service_->AddResourceToDirectory(
    195       parent_folder_id, file_id,
    196       CreateResultReceiver(&error));
    197   base::RunLoop().RunUntilIdle();
    198   return error;
    199 }
    200 
    201 GDataErrorCode FakeDriveServiceHelper::RemoveResourceFromDirectory(
    202     const std::string& parent_folder_id,
    203     const std::string& file_id) {
    204   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    205   fake_drive_service_->RemoveResourceFromDirectory(
    206       parent_folder_id, file_id,
    207       CreateResultReceiver(&error));
    208   base::RunLoop().RunUntilIdle();
    209   return error;
    210 }
    211 
    212 GDataErrorCode FakeDriveServiceHelper::GetSyncRootFolderID(
    213     std::string* sync_root_folder_id) {
    214   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    215   scoped_ptr<FileList> resource_list;
    216   fake_drive_service_->SearchByTitle(
    217       sync_root_folder_title_, std::string(),
    218       CreateResultReceiver(&error, &resource_list));
    219   base::RunLoop().RunUntilIdle();
    220   if (error != google_apis::HTTP_SUCCESS)
    221     return error;
    222 
    223   const ScopedVector<FileResource>& items = resource_list->items();
    224   for (ScopedVector<FileResource>::const_iterator itr = items.begin();
    225        itr != items.end(); ++itr) {
    226     const FileResource& item = **itr;
    227     if (item.parents().empty()) {
    228       *sync_root_folder_id = item.file_id();
    229       return google_apis::HTTP_SUCCESS;
    230     }
    231   }
    232   return google_apis::HTTP_NOT_FOUND;
    233 }
    234 
    235 GDataErrorCode FakeDriveServiceHelper::ListFilesInFolder(
    236     const std::string& folder_id,
    237     ScopedVector<ResourceEntry>* entries) {
    238   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    239   scoped_ptr<FileList> list;
    240   fake_drive_service_->GetFileListInDirectory(
    241       folder_id,
    242       CreateResultReceiver(&error, &list));
    243   base::RunLoop().RunUntilIdle();
    244   if (error != google_apis::HTTP_SUCCESS)
    245     return error;
    246 
    247   return CompleteListing(list.Pass(), entries);
    248 }
    249 
    250 GDataErrorCode FakeDriveServiceHelper::SearchByTitle(
    251     const std::string& folder_id,
    252     const std::string& title,
    253     ScopedVector<ResourceEntry>* entries) {
    254   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    255   scoped_ptr<FileList> list;
    256   fake_drive_service_->SearchByTitle(
    257       title, folder_id,
    258       CreateResultReceiver(&error, &list));
    259   base::RunLoop().RunUntilIdle();
    260   if (error != google_apis::HTTP_SUCCESS)
    261     return error;
    262 
    263   return CompleteListing(list.Pass(), entries);
    264 }
    265 
    266 GDataErrorCode FakeDriveServiceHelper::GetFileResource(
    267     const std::string& file_id,
    268     scoped_ptr<FileResource>* entry) {
    269   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    270   fake_drive_service_->GetFileResource(
    271       file_id,
    272       CreateResultReceiver(&error, entry));
    273   base::RunLoop().RunUntilIdle();
    274   return error;
    275 }
    276 
    277 GDataErrorCode FakeDriveServiceHelper::ReadFile(
    278     const std::string& file_id,
    279     std::string* file_content) {
    280   scoped_ptr<google_apis::FileResource> file;
    281   GDataErrorCode error = GetFileResource(file_id, &file);
    282   if (error != google_apis::HTTP_SUCCESS)
    283     return error;
    284   if (!file)
    285     return google_apis::GDATA_PARSE_ERROR;
    286 
    287   error = google_apis::GDATA_OTHER_ERROR;
    288   base::FilePath temp_file;
    289   EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_, &temp_file));
    290   fake_drive_service_->DownloadFile(
    291       temp_file, file->file_id(),
    292       base::Bind(&DownloadResultCallback, &error),
    293       google_apis::GetContentCallback(),
    294       google_apis::ProgressCallback());
    295   base::RunLoop().RunUntilIdle();
    296   if (error != google_apis::HTTP_SUCCESS)
    297     return error;
    298 
    299   return base::ReadFileToString(temp_file, file_content)
    300       ? google_apis::HTTP_SUCCESS : google_apis::GDATA_FILE_ERROR;
    301 }
    302 
    303 GDataErrorCode FakeDriveServiceHelper::GetAboutResource(
    304     scoped_ptr<AboutResource>* about_resource) {
    305   GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    306   fake_drive_service_->GetAboutResource(
    307       CreateResultReceiver(&error, about_resource));
    308   base::RunLoop().RunUntilIdle();
    309   return error;
    310 }
    311 
    312 GDataErrorCode FakeDriveServiceHelper::CompleteListing(
    313     scoped_ptr<FileList> list,
    314     ScopedVector<ResourceEntry>* entries) {
    315   while (true) {
    316     entries->reserve(entries->size() + list->items().size());
    317     for (ScopedVector<FileResource>::const_iterator itr =
    318              list->items().begin(); itr != list->items().end(); ++itr) {
    319       entries->push_back(
    320           drive::util::ConvertFileResourceToResourceEntry(**itr).release());
    321     }
    322 
    323     GURL next_feed = list->next_link();
    324     if (next_feed.is_empty())
    325       return google_apis::HTTP_SUCCESS;
    326 
    327     GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
    328     list.reset();
    329     fake_drive_service_->GetRemainingFileList(
    330         next_feed,
    331         CreateResultReceiver(&error, &list));
    332     base::RunLoop().RunUntilIdle();
    333     if (error != google_apis::HTTP_SUCCESS)
    334       return error;
    335   }
    336 }
    337 
    338 void FakeDriveServiceHelper::Initialize() {
    339   ASSERT_TRUE(base_dir_.CreateUniqueTempDir());
    340   temp_dir_ = base_dir_.path().Append(FPL("tmp"));
    341   ASSERT_TRUE(base::CreateDirectory(temp_dir_));
    342 }
    343 
    344 base::FilePath FakeDriveServiceHelper::WriteToTempFile(
    345     const std::string& content) {
    346   base::FilePath temp_file;
    347   EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_, &temp_file));
    348   EXPECT_EQ(static_cast<int>(content.size()),
    349             base::WriteFile(temp_file, content.data(), content.size()));
    350   return temp_file;
    351 }
    352 
    353 }  // namespace drive_backend
    354 }  // namespace sync_file_system
    355