Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / drive / file_system_unittest.cc
index 49380ff..bdd61ff 100644 (file)
@@ -8,8 +8,8 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/file_util.h"
 #include "base/files/file_path.h"
+#include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop_proxy.h"
 #include "chrome/browser/chromeos/drive/change_list_loader.h"
 #include "chrome/browser/chromeos/drive/drive.pb.h"
 #include "chrome/browser/chromeos/drive/fake_free_disk_space_getter.h"
+#include "chrome/browser/chromeos/drive/file_change.h"
 #include "chrome/browser/chromeos/drive/file_system_observer.h"
 #include "chrome/browser/chromeos/drive/file_system_util.h"
 #include "chrome/browser/chromeos/drive/job_scheduler.h"
 #include "chrome/browser/chromeos/drive/sync_client.h"
 #include "chrome/browser/chromeos/drive/test_util.h"
+#include "chrome/browser/drive/drive_api_util.h"
 #include "chrome/browser/drive/event_logger.h"
 #include "chrome/browser/drive/fake_drive_service.h"
+#include "chrome/browser/drive/test_util.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "google_apis/drive/drive_api_parser.h"
 #include "google_apis/drive/test_util.h"
@@ -63,12 +66,19 @@ class MockDirectoryChangeObserver : public FileSystemObserver {
     changed_directories_.push_back(directory_path);
   }
 
+  virtual void OnFileChanged(const FileChange& new_file_change) OVERRIDE {
+    changed_files_.Apply(new_file_change);
+  }
+
   const std::vector<base::FilePath>& changed_directories() const {
     return changed_directories_;
   }
 
+  const FileChange& changed_files() const { return changed_files_; }
+
  private:
   std::vector<base::FilePath> changed_directories_;
+  FileChange changed_files_;
   DISALLOW_COPY_AND_ASSIGN(MockDirectoryChangeObserver);
 };
 
@@ -83,10 +93,7 @@ class FileSystemTest : public testing::Test {
 
     logger_.reset(new EventLogger);
     fake_drive_service_.reset(new FakeDriveService);
-    fake_drive_service_->LoadResourceListForWapi(
-        "gdata/root_feed.json");
-    fake_drive_service_->LoadAccountMetadataForWapi(
-        "gdata/account_metadata.json");
+    test_util::SetUpTestEntries(fake_drive_service_.get());
 
     fake_free_disk_space_getter_.reset(new FakeFreeDiskSpaceGetter);
 
@@ -117,7 +124,8 @@ class FileSystemTest : public testing::Test {
     ASSERT_TRUE(cache_->Initialize());
 
     resource_metadata_.reset(new internal::ResourceMetadata(
-        metadata_storage_.get(), base::MessageLoopProxy::current()));
+        metadata_storage_.get(), cache_.get(),
+        base::MessageLoopProxy::current()));
     ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize());
 
     const base::FilePath temp_file_dir = temp_dir_.path().AppendASCII("tmp");
@@ -141,9 +149,9 @@ class FileSystemTest : public testing::Test {
   // Loads the full resource list via FakeDriveService.
   bool LoadFullResourceList() {
     FileError error = FILE_ERROR_FAILED;
-    file_system_->change_list_loader_for_testing()->LoadForTesting(
+    file_system_->change_list_loader_for_testing()->LoadIfNeeded(
         google_apis::test_util::CreateCopyResultCallback(&error));
-    test_util::RunBlockingPoolTask();
+    content::RunAllBlockingPoolTasksUntilIdle();
     return error == FILE_ERROR_OK;
   }
 
@@ -155,7 +163,7 @@ class FileSystemTest : public testing::Test {
     file_system_->GetResourceEntry(
         file_path,
         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
-    test_util::RunBlockingPoolTask();
+    content::RunAllBlockingPoolTasksUntilIdle();
 
     return entry.Pass();
   }
@@ -165,12 +173,11 @@ class FileSystemTest : public testing::Test {
       const base::FilePath& file_path) {
     FileError error = FILE_ERROR_FAILED;
     scoped_ptr<ResourceEntryVector> entries(new ResourceEntryVector);
-    bool last_has_more = true;
     file_system_->ReadDirectory(
         file_path,
-        base::Bind(&AccumulateReadDirectoryResult,
-                   &error, entries.get(), &last_has_more));
-    test_util::RunBlockingPoolTask();
+        base::Bind(&AccumulateReadDirectoryResult, entries.get()),
+        google_apis::test_util::CreateCopyResultCallback(&error));
+    content::RunAllBlockingPoolTasksUntilIdle();
     if (error != FILE_ERROR_OK)
       entries.reset();
     return entries.Pass();
@@ -178,21 +185,10 @@ class FileSystemTest : public testing::Test {
 
   // Used to implement ReadDirectorySync().
   static void AccumulateReadDirectoryResult(
-      FileError* out_error,
       ResourceEntryVector* out_entries,
-      bool* last_has_more,
-      FileError error,
-      scoped_ptr<ResourceEntryVector> entries,
-      bool has_more) {
-    EXPECT_TRUE(*last_has_more);
-    *out_error = error;
-    *last_has_more = has_more;
-    if (error == FILE_ERROR_OK) {
-      ASSERT_TRUE(entries);
-      out_entries->insert(out_entries->end(), entries->begin(), entries->end());
-    } else {
-      EXPECT_FALSE(has_more);
-    }
+      scoped_ptr<ResourceEntryVector> entries) {
+    ASSERT_TRUE(entries);
+    out_entries->insert(out_entries->end(), entries->begin(), entries->end());
   }
 
   // Returns true if an entry exists at |file_path|.
@@ -209,8 +205,8 @@ class FileSystemTest : public testing::Test {
   // Sets up a filesystem with directories: drive/root, drive/root/Dir1,
   // drive/root/Dir1/SubDir2 and files drive/root/File1, drive/root/Dir1/File2,
   // drive/root/Dir1/SubDir2/File3. If |use_up_to_date_timestamp| is true, sets
-  // the changestamp to 654321, equal to that of "account_metadata.json" test
-  // data, indicating the cache is holding the latest file system info.
+  // the changestamp to that of FakeDriveService, indicating the cache is
+  // holding the latest file system info.
   void SetUpTestFileSystem(SetUpTestFileSystemParam param) {
     // Destroy the existing resource metadata to close DB.
     resource_metadata_.reset();
@@ -222,13 +218,22 @@ class FileSystemTest : public testing::Test {
         new internal::ResourceMetadataStorage(
             metadata_dir, base::MessageLoopProxy::current().get()));
 
+    const base::FilePath cache_dir = temp_dir_.path().AppendASCII("files");
+    scoped_ptr<internal::FileCache, test_util::DestroyHelperForTests> cache(
+        new internal::FileCache(metadata_storage.get(),
+                                cache_dir,
+                                base::MessageLoopProxy::current().get(),
+                                fake_free_disk_space_getter_.get()));
+
     scoped_ptr<internal::ResourceMetadata, test_util::DestroyHelperForTests>
         resource_metadata(new internal::ResourceMetadata(
-            metadata_storage_.get(), base::MessageLoopProxy::current()));
+            metadata_storage_.get(), cache.get(),
+            base::MessageLoopProxy::current()));
 
     ASSERT_EQ(FILE_ERROR_OK, resource_metadata->Initialize());
 
-    const int64 changestamp = param == USE_SERVER_TIMESTAMP ? 654321 : 1;
+    const int64 changestamp = param == USE_SERVER_TIMESTAMP ?
+        fake_drive_service_->about_resource().largest_change_id() : 1;
     ASSERT_EQ(FILE_ERROR_OK,
               resource_metadata->SetLargestChangestamp(changestamp));
 
@@ -313,6 +318,215 @@ class FileSystemTest : public testing::Test {
   scoped_ptr<FileSystem> file_system_;
 };
 
+TEST_F(FileSystemTest, Copy) {
+  base::FilePath src_file_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
+  base::FilePath dest_file_path(FILE_PATH_LITERAL("drive/root/Copied.txt"));
+  EXPECT_TRUE(GetResourceEntrySync(src_file_path));
+  EXPECT_FALSE(GetResourceEntrySync(dest_file_path));
+
+  FileError error = FILE_ERROR_FAILED;
+  file_system_->Copy(src_file_path,
+                     dest_file_path,
+                     false,  // preserve_last_modified,
+                     google_apis::test_util::CreateCopyResultCallback(&error));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(FILE_ERROR_OK, error);
+
+  // Entry is added on the server.
+  scoped_ptr<ResourceEntry> entry = GetResourceEntrySync(dest_file_path);
+  ASSERT_TRUE(entry);
+
+  google_apis::GDataErrorCode status = google_apis::GDATA_OTHER_ERROR;
+  scoped_ptr<google_apis::FileResource> server_entry;
+  fake_drive_service_->GetFileResource(
+      entry->resource_id(),
+      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
+  ASSERT_TRUE(server_entry);
+  EXPECT_EQ(entry->title(), server_entry->title());
+  EXPECT_FALSE(server_entry->IsDirectory());
+}
+
+TEST_F(FileSystemTest, Move) {
+  base::FilePath src_file_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
+  base::FilePath dest_file_path(
+      FILE_PATH_LITERAL("drive/root/Directory 1/Moved.txt"));
+  EXPECT_TRUE(GetResourceEntrySync(src_file_path));
+  EXPECT_FALSE(GetResourceEntrySync(dest_file_path));
+  scoped_ptr<ResourceEntry> parent =
+      GetResourceEntrySync(dest_file_path.DirName());
+  ASSERT_TRUE(parent);
+
+  FileError error = FILE_ERROR_FAILED;
+  file_system_->Move(src_file_path,
+                     dest_file_path,
+                     google_apis::test_util::CreateCopyResultCallback(&error));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(FILE_ERROR_OK, error);
+
+  // Entry is moved on the server.
+  scoped_ptr<ResourceEntry> entry = GetResourceEntrySync(dest_file_path);
+  ASSERT_TRUE(entry);
+
+  google_apis::GDataErrorCode status = google_apis::GDATA_OTHER_ERROR;
+  scoped_ptr<google_apis::FileResource> server_entry;
+  fake_drive_service_->GetFileResource(
+      entry->resource_id(),
+      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
+  ASSERT_TRUE(server_entry);
+  EXPECT_EQ(entry->title(), server_entry->title());
+
+  ASSERT_FALSE(server_entry->parents().empty());
+  EXPECT_EQ(parent->resource_id(), server_entry->parents()[0].file_id());
+}
+
+TEST_F(FileSystemTest, Remove) {
+  base::FilePath file_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
+  scoped_ptr<ResourceEntry> entry = GetResourceEntrySync(file_path);
+  ASSERT_TRUE(entry);
+
+  FileError error = FILE_ERROR_FAILED;
+  file_system_->Remove(
+      file_path,
+      false,  // is_resursive
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(FILE_ERROR_OK, error);
+
+  // Entry is removed on the server.
+  google_apis::GDataErrorCode status = google_apis::GDATA_OTHER_ERROR;
+  scoped_ptr<google_apis::FileResource> server_entry;
+  fake_drive_service_->GetFileResource(
+      entry->resource_id(),
+      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
+  ASSERT_TRUE(server_entry);
+  EXPECT_TRUE(server_entry->labels().is_trashed());
+}
+
+TEST_F(FileSystemTest, CreateDirectory) {
+  base::FilePath directory_path(FILE_PATH_LITERAL("drive/root/New Directory"));
+  EXPECT_FALSE(GetResourceEntrySync(directory_path));
+
+  FileError error = FILE_ERROR_FAILED;
+  file_system_->CreateDirectory(
+      directory_path,
+      true,  // is_exclusive
+      false,  // is_recursive
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(FILE_ERROR_OK, error);
+
+  // Directory is created on the server.
+  scoped_ptr<ResourceEntry> entry = GetResourceEntrySync(directory_path);
+  ASSERT_TRUE(entry);
+
+  google_apis::GDataErrorCode status = google_apis::GDATA_OTHER_ERROR;
+  scoped_ptr<google_apis::FileResource> server_entry;
+  fake_drive_service_->GetFileResource(
+      entry->resource_id(),
+      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
+  ASSERT_TRUE(server_entry);
+  EXPECT_EQ(entry->title(), server_entry->title());
+  EXPECT_TRUE(server_entry->IsDirectory());
+}
+
+TEST_F(FileSystemTest, CreateFile) {
+  base::FilePath file_path(FILE_PATH_LITERAL("drive/root/New File.txt"));
+  EXPECT_FALSE(GetResourceEntrySync(file_path));
+
+  FileError error = FILE_ERROR_FAILED;
+  file_system_->CreateFile(
+      file_path,
+      true,  // is_exclusive
+      "text/plain",
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(FILE_ERROR_OK, error);
+
+  // File is created on the server.
+  scoped_ptr<ResourceEntry> entry = GetResourceEntrySync(file_path);
+  ASSERT_TRUE(entry);
+
+  google_apis::GDataErrorCode status = google_apis::GDATA_OTHER_ERROR;
+  scoped_ptr<google_apis::FileResource> server_entry;
+  fake_drive_service_->GetFileResource(
+      entry->resource_id(),
+      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
+  ASSERT_TRUE(server_entry);
+  EXPECT_EQ(entry->title(), server_entry->title());
+  EXPECT_FALSE(server_entry->IsDirectory());
+}
+
+TEST_F(FileSystemTest, TouchFile) {
+  base::FilePath file_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
+  scoped_ptr<ResourceEntry> entry = GetResourceEntrySync(file_path);
+  ASSERT_TRUE(entry);
+
+  base::Time last_accessed =
+      base::Time::FromInternalValue(entry->file_info().last_accessed()) +
+      base::TimeDelta::FromSeconds(1);
+  base::Time last_modified =
+      base::Time::FromInternalValue(entry->file_info().last_modified()) +
+      base::TimeDelta::FromSeconds(1);
+
+  FileError error = FILE_ERROR_FAILED;
+  file_system_->TouchFile(
+      file_path,
+      last_accessed,
+      last_modified,
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(FILE_ERROR_OK, error);
+
+  // File is touched on the server.
+  google_apis::GDataErrorCode status = google_apis::GDATA_OTHER_ERROR;
+  scoped_ptr<google_apis::FileResource> server_entry;
+  fake_drive_service_->GetFileResource(
+      entry->resource_id(),
+      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
+  ASSERT_TRUE(server_entry);
+  EXPECT_EQ(last_accessed, server_entry->last_viewed_by_me_date());
+  EXPECT_EQ(last_modified, server_entry->modified_date());
+}
+
+TEST_F(FileSystemTest, TruncateFile) {
+  base::FilePath file_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
+  scoped_ptr<ResourceEntry> entry = GetResourceEntrySync(file_path);
+  ASSERT_TRUE(entry);
+
+  const int64 kLength = entry->file_info().size() + 100;
+
+  FileError error = FILE_ERROR_FAILED;
+  file_system_->TruncateFile(
+      file_path,
+      kLength,
+      google_apis::test_util::CreateCopyResultCallback(&error));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(FILE_ERROR_OK, error);
+
+  // File is touched on the server.
+  google_apis::GDataErrorCode status = google_apis::GDATA_OTHER_ERROR;
+  scoped_ptr<google_apis::FileResource> server_entry;
+  fake_drive_service_->GetFileResource(
+      entry->resource_id(),
+      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
+  ASSERT_TRUE(server_entry);
+  EXPECT_EQ(kLength, server_entry->file_size());
+}
+
 TEST_F(FileSystemTest, DuplicatedAsyncInitialization) {
   base::RunLoop loop;
 
@@ -327,7 +541,7 @@ TEST_F(FileSystemTest, DuplicatedAsyncInitialization) {
   loop.Run();  // Wait to get our result
   EXPECT_EQ(2, counter);
 
-  EXPECT_EQ(1, fake_drive_service_->resource_list_load_count());
+  EXPECT_EQ(1, fake_drive_service_->file_list_load_count());
 }
 
 TEST_F(FileSystemTest, GetGrandRootEntry) {
@@ -350,26 +564,24 @@ TEST_F(FileSystemTest, GetMyDriveRoot) {
   ASSERT_TRUE(entry);
   EXPECT_EQ(fake_drive_service_->GetRootResourceId(), entry->resource_id());
 
-  EXPECT_EQ(1, fake_drive_service_->about_resource_load_count());
-
   // After "fast fetch" is done, full resource list is fetched.
-  EXPECT_EQ(1, fake_drive_service_->resource_list_load_count());
+  EXPECT_EQ(1, fake_drive_service_->file_list_load_count());
 }
 
 TEST_F(FileSystemTest, GetExistingFile) {
   // Simulate the situation that full feed fetching takes very long time,
   // to test the recursive "fast fetch" feature is properly working.
-  fake_drive_service_->set_never_return_all_resource_list(true);
+  fake_drive_service_->set_never_return_all_file_list(true);
 
   const base::FilePath kFilePath(
       FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
   scoped_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
   ASSERT_TRUE(entry);
-  EXPECT_EQ("file:subdirectory_file_1_id", entry->resource_id());
+  EXPECT_EQ("subdirectory_file_1_id", entry->resource_id());
 
   EXPECT_EQ(1, fake_drive_service_->about_resource_load_count());
   EXPECT_EQ(2, fake_drive_service_->directory_load_count());
-  EXPECT_EQ(1, fake_drive_service_->blocked_resource_list_load_count());
+  EXPECT_EQ(1, fake_drive_service_->blocked_file_list_load_count());
 }
 
 TEST_F(FileSystemTest, GetExistingDocument) {
@@ -377,7 +589,7 @@ TEST_F(FileSystemTest, GetExistingDocument) {
       FILE_PATH_LITERAL("drive/root/Document 1 excludeDir-test.gdoc"));
   scoped_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
   ASSERT_TRUE(entry);
-  EXPECT_EQ("document:5_document_resource_id", entry->resource_id());
+  EXPECT_EQ("5_document_resource_id", entry->resource_id());
 }
 
 TEST_F(FileSystemTest, GetNonExistingFile) {
@@ -387,24 +599,13 @@ TEST_F(FileSystemTest, GetNonExistingFile) {
   EXPECT_FALSE(entry);
 }
 
-TEST_F(FileSystemTest, GetExistingDirectory) {
-  const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/Directory 1"));
-  scoped_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
-  ASSERT_TRUE(entry);
-  ASSERT_EQ("folder:1_folder_resource_id", entry->resource_id());
-
-  // The changestamp should be propagated to the directory.
-  EXPECT_EQ(fake_drive_service_->about_resource().largest_change_id(),
-            entry->directory_specific_info().changestamp());
-}
-
 TEST_F(FileSystemTest, GetInSubSubdir) {
   const base::FilePath kFilePath(
       FILE_PATH_LITERAL("drive/root/Directory 1/Sub Directory Folder/"
                         "Sub Sub Directory Folder"));
   scoped_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
   ASSERT_TRUE(entry);
-  ASSERT_EQ("folder:sub_sub_directory_folder_id", entry->resource_id());
+  ASSERT_EQ("sub_sub_directory_folder_id", entry->resource_id());
 }
 
 TEST_F(FileSystemTest, GetOrphanFile) {
@@ -415,7 +616,7 @@ TEST_F(FileSystemTest, GetOrphanFile) {
       FILE_PATH_LITERAL("drive/other/Orphan File 1.txt"));
   scoped_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
   ASSERT_TRUE(entry);
-  EXPECT_EQ("file:1_orphanfile_resource_id", entry->resource_id());
+  EXPECT_EQ("1_orphanfile_resource_id", entry->resource_id());
 }
 
 TEST_F(FileSystemTest, ReadDirectory_Root) {
@@ -455,18 +656,20 @@ TEST_F(FileSystemTest, LoadFileSystemFromUpToDateCache) {
   // Kicks loading of cached file system and query for server update.
   EXPECT_TRUE(ReadDirectorySync(util::GetDriveMyDriveRootPath()));
 
-  // SetUpTestFileSystem and "account_metadata.json" have the same
+  // SetUpTestFileSystem and FakeDriveService have the same
   // changestamp (i.e. the local metadata is up-to-date), so no request for
   // new resource list (i.e., call to GetResourceList) should happen.
-  EXPECT_EQ(1, fake_drive_service_->about_resource_load_count());
-  EXPECT_EQ(0, fake_drive_service_->resource_list_load_count());
+  EXPECT_EQ(0, fake_drive_service_->file_list_load_count());
 
   // Since the file system has verified that it holds the latest snapshot,
   // it should change its state to "loaded", which admits periodic refresh.
   // To test it, call CheckForUpdates and verify it does try to check updates.
+  const int about_resource_load_count_before =
+      fake_drive_service_->about_resource_load_count();
   file_system_->CheckForUpdates();
-  test_util::RunBlockingPoolTask();
-  EXPECT_EQ(2, fake_drive_service_->about_resource_load_count());
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_LT(about_resource_load_count_before,
+            fake_drive_service_->about_resource_load_count());
 }
 
 TEST_F(FileSystemTest, LoadFileSystemFromCacheWhileOffline) {
@@ -506,17 +709,17 @@ TEST_F(FileSystemTest, LoadFileSystemFromCacheWhileOffline) {
 
   file_system_->CheckForUpdates();
 
-  test_util::RunBlockingPoolTask();
+  content::RunAllBlockingPoolTasksUntilIdle();
   EXPECT_EQ(1, fake_drive_service_->about_resource_load_count());
   EXPECT_EQ(1, fake_drive_service_->change_list_load_count());
 
-  ASSERT_LE(1u, mock_directory_observer_->changed_directories().size());
+  ASSERT_LE(0u, mock_directory_observer_->changed_directories().size());
+  ASSERT_LE(1u, mock_directory_observer_->changed_files().size());
 }
 
 TEST_F(FileSystemTest, ReadDirectoryWhileRefreshing) {
-  // Enter the "refreshing" state so the fast fetch will be performed.
+  // Use old timestamp so the fast fetch will be performed.
   ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_OLD_TIMESTAMP));
-  file_system_->CheckForUpdates();
 
   // The list of resources in "drive/root/Dir1" should be fetched.
   EXPECT_TRUE(ReadDirectorySync(base::FilePath(
@@ -527,9 +730,8 @@ TEST_F(FileSystemTest, ReadDirectoryWhileRefreshing) {
 }
 
 TEST_F(FileSystemTest, GetResourceEntryNonExistentWhileRefreshing) {
-  // Enter the "refreshing" state so the fast fetch will be performed.
+  // Use old timestamp so the fast fetch will be performed.
   ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_OLD_TIMESTAMP));
-  file_system_->CheckForUpdates();
 
   // If an entry is not found, parent directory's resource list is fetched.
   EXPECT_FALSE(GetResourceEntrySync(base::FilePath(
@@ -551,7 +753,7 @@ TEST_F(FileSystemTest, CreateDirectoryByImplicitLoad) {
       true,  // is_exclusive
       false,  // is_recursive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  test_util::RunBlockingPoolTask();
+  content::RunAllBlockingPoolTasksUntilIdle();
 
   // It should fail because is_exclusive is set to true.
   EXPECT_EQ(FILE_ERROR_EXISTS, error);
@@ -569,7 +771,7 @@ TEST_F(FileSystemTest, CreateDirectoryRecursively) {
       true,  // is_exclusive
       true,  // is_recursive
       google_apis::test_util::CreateCopyResultCallback(&error));
-  test_util::RunBlockingPoolTask();
+  content::RunAllBlockingPoolTasksUntilIdle();
 
   EXPECT_EQ(FILE_ERROR_OK, error);
 
@@ -578,6 +780,57 @@ TEST_F(FileSystemTest, CreateDirectoryRecursively) {
   EXPECT_TRUE(entry->file_info().is_directory());
 }
 
+TEST_F(FileSystemTest, ReadDirectoryAfterUpdateWhileLoading) {
+  // Simulate the situation that full feed fetching takes very long time,
+  // to test the recursive "fast fetch" feature is properly working.
+  fake_drive_service_->set_never_return_all_file_list(true);
+
+  // On the fake server, create the test directory.
+  scoped_ptr<google_apis::FileResource> parent;
+  {
+    google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
+    fake_drive_service_->AddNewDirectory(
+        fake_drive_service_->GetRootResourceId(),
+        "UpdateWhileLoadingTestDir",
+        DriveServiceInterface::AddNewDirectoryOptions(),
+        google_apis::test_util::CreateCopyResultCallback(&error, &parent));
+    base::RunLoop().RunUntilIdle();
+    ASSERT_EQ(google_apis::HTTP_CREATED, error);
+  }
+
+  // Fetch the directory. Currently it is empty.
+  scoped_ptr<ResourceEntryVector> before = ReadDirectorySync(base::FilePath(
+      FILE_PATH_LITERAL("drive/root/UpdateWhileLoadingTestDir")));
+  ASSERT_TRUE(before);
+  EXPECT_EQ(0u, before->size());
+
+  // Create a file in the test directory.
+  scoped_ptr<google_apis::FileResource> entry;
+  {
+    google_apis::GDataErrorCode error = google_apis::GDATA_OTHER_ERROR;
+    fake_drive_service_->AddNewFile(
+        "text/plain",
+        "(dummy data)",
+        parent->file_id(),
+        "TestFile",
+        false,  // shared_with_me
+        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
+    base::RunLoop().RunUntilIdle();
+    ASSERT_EQ(google_apis::HTTP_CREATED, error);
+  }
+
+  // Notify the update to the file system.
+  file_system_->CheckForUpdates();
+
+  // Read the directory once again. Although the full feed fetching is not yet
+  // finished, the "fast fetch" of the directory works and the refreshed content
+  // is returned.
+  scoped_ptr<ResourceEntryVector> after = ReadDirectorySync(base::FilePath(
+      FILE_PATH_LITERAL("drive/root/UpdateWhileLoadingTestDir")));
+  ASSERT_TRUE(after);
+  EXPECT_EQ(1u, after->size());
+}
+
 TEST_F(FileSystemTest, PinAndUnpin) {
   ASSERT_TRUE(LoadFullResourceList());
 
@@ -591,28 +844,31 @@ TEST_F(FileSystemTest, PinAndUnpin) {
   FileError error = FILE_ERROR_FAILED;
   file_system_->Pin(file_path,
                     google_apis::test_util::CreateCopyResultCallback(&error));
-  test_util::RunBlockingPoolTask();
+  content::RunAllBlockingPoolTasksUntilIdle();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
-  FileCacheEntry cache_entry;
-  EXPECT_TRUE(cache_->GetCacheEntry(entry->local_id(), &cache_entry));
-  EXPECT_TRUE(cache_entry.is_pinned());
-  EXPECT_TRUE(cache_entry.is_present());
+  entry = GetResourceEntrySync(file_path);
+  ASSERT_TRUE(entry);
+  EXPECT_TRUE(entry->file_specific_info().cache_state().is_pinned());
+  EXPECT_TRUE(entry->file_specific_info().cache_state().is_present());
 
   // Unpin the file.
   error = FILE_ERROR_FAILED;
   file_system_->Unpin(file_path,
                       google_apis::test_util::CreateCopyResultCallback(&error));
-  test_util::RunBlockingPoolTask();
+  content::RunAllBlockingPoolTasksUntilIdle();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
-  EXPECT_TRUE(cache_->GetCacheEntry(entry->local_id(), &cache_entry));
-  EXPECT_FALSE(cache_entry.is_pinned());
+  entry = GetResourceEntrySync(file_path);
+  ASSERT_TRUE(entry);
+  EXPECT_FALSE(entry->file_specific_info().cache_state().is_pinned());
 
   // Pinned file gets synced and it results in entry state changes.
-  ASSERT_EQ(1u, mock_directory_observer_->changed_directories().size());
-  EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("drive/root")),
-            mock_directory_observer_->changed_directories()[0]);
+  ASSERT_EQ(0u, mock_directory_observer_->changed_directories().size());
+  ASSERT_EQ(1u, mock_directory_observer_->changed_files().size());
+  EXPECT_EQ(1u,
+            mock_directory_observer_->changed_files().CountDirectory(
+                base::FilePath(FILE_PATH_LITERAL("drive/root"))));
 }
 
 TEST_F(FileSystemTest, PinAndUnpin_NotSynced) {
@@ -635,13 +891,14 @@ TEST_F(FileSystemTest, PinAndUnpin_NotSynced) {
       file_path,
       google_apis::test_util::CreateCopyResultCallback(&error_unpin));
 
-  test_util::RunBlockingPoolTask();
+  content::RunAllBlockingPoolTasksUntilIdle();
   EXPECT_EQ(FILE_ERROR_OK, error_pin);
   EXPECT_EQ(FILE_ERROR_OK, error_unpin);
 
   // No cache file available because the sync was cancelled by Unpin().
-  FileCacheEntry cache_entry;
-  EXPECT_FALSE(cache_->GetCacheEntry(entry->local_id(), &cache_entry));
+  entry = GetResourceEntrySync(file_path);
+  ASSERT_TRUE(entry);
+  EXPECT_FALSE(entry->file_specific_info().cache_state().is_present());
 }
 
 TEST_F(FileSystemTest, GetAvailableSpace) {
@@ -651,32 +908,34 @@ TEST_F(FileSystemTest, GetAvailableSpace) {
   file_system_->GetAvailableSpace(
       google_apis::test_util::CreateCopyResultCallback(
           &error, &bytes_total, &bytes_used));
-  test_util::RunBlockingPoolTask();
-  EXPECT_EQ(GG_LONGLONG(6789012345), bytes_used);
-  EXPECT_EQ(GG_LONGLONG(9876543210), bytes_total);
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(6789012345LL, bytes_used);
+  EXPECT_EQ(9876543210LL, bytes_total);
 }
 
 TEST_F(FileSystemTest, MarkCacheFileAsMountedAndUnmounted) {
   ASSERT_TRUE(LoadFullResourceList());
 
   base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));
-  scoped_ptr<ResourceEntry> entry(GetResourceEntrySync(file_in_root));
-  ASSERT_TRUE(entry);
-
-  // Write to cache.
-  ASSERT_EQ(FILE_ERROR_OK, cache_->Store(
-      entry->local_id(),
-      entry->file_specific_info().md5(),
-      google_apis::test_util::GetTestFilePath("gdata/root_feed.json"),
-      internal::FileCache::FILE_OPERATION_COPY));
 
-  // Test for mounting.
+  // Make the file cached.
   FileError error = FILE_ERROR_FAILED;
   base::FilePath file_path;
+  scoped_ptr<ResourceEntry> entry;
+  file_system_->GetFile(
+      file_in_root,
+      google_apis::test_util::CreateCopyResultCallback(
+          &error, &file_path, &entry));
+  content::RunAllBlockingPoolTasksUntilIdle();
+  EXPECT_EQ(FILE_ERROR_OK, error);
+
+  // Test for mounting.
+  error = FILE_ERROR_FAILED;
+  file_path.clear();
   file_system_->MarkCacheFileAsMounted(
       file_in_root,
       google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
-  test_util::RunBlockingPoolTask();
+  content::RunAllBlockingPoolTasksUntilIdle();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Cannot remove a cache entry while it's being mounted.
@@ -687,7 +946,7 @@ TEST_F(FileSystemTest, MarkCacheFileAsMountedAndUnmounted) {
   file_system_->MarkCacheFileAsUnmounted(
       file_path,
       google_apis::test_util::CreateCopyResultCallback(&error));
-  test_util::RunBlockingPoolTask();
+  content::RunAllBlockingPoolTasksUntilIdle();
   EXPECT_EQ(FILE_ERROR_OK, error);
 
   // Now able to remove the cache entry.
@@ -707,33 +966,11 @@ TEST_F(FileSystemTest, GetShareUrl) {
       kFileInRoot,
       kEmbedOrigin,
       google_apis::test_util::CreateCopyResultCallback(&error, &share_url));
-  test_util::RunBlockingPoolTask();
+  content::RunAllBlockingPoolTasksUntilIdle();
 
   // Verify the share url to the sharing dialog.
   EXPECT_EQ(FILE_ERROR_OK, error);
-  EXPECT_EQ(GURL("https://file_link_share/"), share_url);
-}
-
-TEST_F(FileSystemTest, GetShareUrlNotAvailable) {
-  ASSERT_TRUE(LoadFullResourceList());
-
-  const base::FilePath kFileInRoot(
-      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
-  const GURL kEmbedOrigin("chrome-extension://test-id");
-
-  // Try to fetch the URL for the sharing dialog.
-  FileError error = FILE_ERROR_FAILED;
-  GURL share_url;
-
-  file_system_->GetShareUrl(
-      kFileInRoot,
-      kEmbedOrigin,
-      google_apis::test_util::CreateCopyResultCallback(&error, &share_url));
-  test_util::RunBlockingPoolTask();
-
-  // Verify the error and the share url, which should be empty.
-  EXPECT_EQ(FILE_ERROR_FAILED, error);
-  EXPECT_TRUE(share_url.is_empty());
+  EXPECT_TRUE(share_url.is_valid());
 }
 
 }   // namespace drive