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