bb93d4bc6c9b653ad0654cc556a67ff866d3c953
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / drive / directory_loader_unittest.cc
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/chromeos/drive/directory_loader.h"
6
7 #include "base/callback_helpers.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/prefs/testing_pref_service.h"
11 #include "base/run_loop.h"
12 #include "chrome/browser/chromeos/drive/change_list_loader.h"
13 #include "chrome/browser/chromeos/drive/change_list_loader_observer.h"
14 #include "chrome/browser/chromeos/drive/file_cache.h"
15 #include "chrome/browser/chromeos/drive/file_system_util.h"
16 #include "chrome/browser/chromeos/drive/job_scheduler.h"
17 #include "chrome/browser/chromeos/drive/resource_metadata.h"
18 #include "chrome/browser/chromeos/drive/test_util.h"
19 #include "chrome/browser/drive/event_logger.h"
20 #include "chrome/browser/drive/fake_drive_service.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "google_apis/drive/drive_api_parser.h"
23 #include "google_apis/drive/test_util.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 namespace drive {
27 namespace internal {
28
29 namespace {
30
31 class TestDirectoryLoaderObserver : public ChangeListLoaderObserver {
32  public:
33   explicit TestDirectoryLoaderObserver(DirectoryLoader* loader)
34       : loader_(loader) {
35     loader_->AddObserver(this);
36   }
37
38   virtual ~TestDirectoryLoaderObserver() {
39     loader_->RemoveObserver(this);
40   }
41
42   const std::set<base::FilePath>& changed_directories() const {
43     return changed_directories_;
44   }
45   void clear_changed_directories() { changed_directories_.clear(); }
46
47   // ChageListObserver overrides:
48   virtual void OnDirectoryChanged(
49       const base::FilePath& directory_path) OVERRIDE {
50     changed_directories_.insert(directory_path);
51   }
52
53  private:
54   DirectoryLoader* loader_;
55   std::set<base::FilePath> changed_directories_;
56
57   DISALLOW_COPY_AND_ASSIGN(TestDirectoryLoaderObserver);
58 };
59
60 void AccumulateReadDirectoryResult(FileError* out_error,
61                                    ResourceEntryVector* out_entries,
62                                    bool* last_has_more,
63                                    FileError error,
64                                    scoped_ptr<ResourceEntryVector> entries,
65                                    bool has_more) {
66   EXPECT_TRUE(*last_has_more);
67   *out_error = error;
68   *last_has_more = has_more;
69   if (error == FILE_ERROR_OK) {
70     ASSERT_TRUE(entries);
71     out_entries->insert(out_entries->end(), entries->begin(), entries->end());
72   } else {
73     EXPECT_FALSE(has_more);
74   }
75 }
76
77 }  // namespace
78
79 class DirectoryLoaderTest : public testing::Test {
80  protected:
81   virtual void SetUp() OVERRIDE {
82     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
83     pref_service_.reset(new TestingPrefServiceSimple);
84     test_util::RegisterDrivePrefs(pref_service_->registry());
85
86     logger_.reset(new EventLogger);
87
88     drive_service_.reset(new FakeDriveService);
89     ASSERT_TRUE(drive_service_->LoadResourceListForWapi(
90         "gdata/root_feed.json"));
91     ASSERT_TRUE(drive_service_->LoadAccountMetadataForWapi(
92         "gdata/account_metadata.json"));
93
94     scheduler_.reset(new JobScheduler(pref_service_.get(),
95                                       logger_.get(),
96                                       drive_service_.get(),
97                                       base::MessageLoopProxy::current().get()));
98     metadata_storage_.reset(new ResourceMetadataStorage(
99         temp_dir_.path(), base::MessageLoopProxy::current().get()));
100     ASSERT_TRUE(metadata_storage_->Initialize());
101
102     metadata_.reset(new ResourceMetadata(
103         metadata_storage_.get(), base::MessageLoopProxy::current().get()));
104     ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize());
105
106     cache_.reset(new FileCache(metadata_storage_.get(),
107                                temp_dir_.path(),
108                                base::MessageLoopProxy::current().get(),
109                                NULL /* free_disk_space_getter */));
110     ASSERT_TRUE(cache_->Initialize());
111
112     about_resource_loader_.reset(new AboutResourceLoader(scheduler_.get()));
113     loader_controller_.reset(new LoaderController);
114     directory_loader_.reset(
115         new DirectoryLoader(logger_.get(),
116                              base::MessageLoopProxy::current().get(),
117                              metadata_.get(),
118                              scheduler_.get(),
119                              drive_service_.get(),
120                              about_resource_loader_.get(),
121                              loader_controller_.get()));
122   }
123
124   // Adds a new file to the root directory of the service.
125   scoped_ptr<google_apis::ResourceEntry> AddNewFile(const std::string& title) {
126     google_apis::GDataErrorCode error = google_apis::GDATA_FILE_ERROR;
127     scoped_ptr<google_apis::ResourceEntry> entry;
128     drive_service_->AddNewFile(
129         "text/plain",
130         "content text",
131         drive_service_->GetRootResourceId(),
132         title,
133         false,  // shared_with_me
134         google_apis::test_util::CreateCopyResultCallback(&error, &entry));
135     base::RunLoop().RunUntilIdle();
136     EXPECT_EQ(google_apis::HTTP_CREATED, error);
137     return entry.Pass();
138   }
139
140   content::TestBrowserThreadBundle thread_bundle_;
141   base::ScopedTempDir temp_dir_;
142   scoped_ptr<TestingPrefServiceSimple> pref_service_;
143   scoped_ptr<EventLogger> logger_;
144   scoped_ptr<FakeDriveService> drive_service_;
145   scoped_ptr<JobScheduler> scheduler_;
146   scoped_ptr<ResourceMetadataStorage,
147              test_util::DestroyHelperForTests> metadata_storage_;
148   scoped_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_;
149   scoped_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
150   scoped_ptr<AboutResourceLoader> about_resource_loader_;
151   scoped_ptr<LoaderController> loader_controller_;
152   scoped_ptr<DirectoryLoader> directory_loader_;
153 };
154
155 TEST_F(DirectoryLoaderTest, ReadDirectory_GrandRoot) {
156   TestDirectoryLoaderObserver observer(directory_loader_.get());
157
158   // Load grand root.
159   FileError error = FILE_ERROR_FAILED;
160   ResourceEntryVector entries;
161   bool last_has_more = true;
162   directory_loader_->ReadDirectory(
163       util::GetDriveGrandRootPath(),
164       base::Bind(&AccumulateReadDirectoryResult,
165                  &error, &entries, &last_has_more));
166   base::RunLoop().RunUntilIdle();
167   EXPECT_EQ(FILE_ERROR_OK, error);
168   EXPECT_FALSE(last_has_more);
169   EXPECT_EQ(0U, observer.changed_directories().size());
170   observer.clear_changed_directories();
171
172   // My Drive has resource ID.
173   ResourceEntry entry;
174   EXPECT_EQ(FILE_ERROR_OK,
175             metadata_->GetResourceEntryByPath(util::GetDriveMyDriveRootPath(),
176                                               &entry));
177   EXPECT_EQ(drive_service_->GetRootResourceId(), entry.resource_id());
178 }
179
180 TEST_F(DirectoryLoaderTest, ReadDirectory_MyDrive) {
181   TestDirectoryLoaderObserver observer(directory_loader_.get());
182
183   // My Drive does not have resource ID yet.
184   ResourceEntry entry;
185   EXPECT_EQ(FILE_ERROR_OK,
186             metadata_->GetResourceEntryByPath(util::GetDriveMyDriveRootPath(),
187                                               &entry));
188   EXPECT_TRUE(entry.resource_id().empty());
189
190   // Load My Drive.
191   FileError error = FILE_ERROR_FAILED;
192   ResourceEntryVector entries;
193   bool last_has_more = true;
194   directory_loader_->ReadDirectory(
195       util::GetDriveMyDriveRootPath(),
196       base::Bind(&AccumulateReadDirectoryResult,
197                  &error, &entries, &last_has_more));
198   base::RunLoop().RunUntilIdle();
199   EXPECT_EQ(FILE_ERROR_OK, error);
200   EXPECT_FALSE(last_has_more);
201   EXPECT_EQ(1U, observer.changed_directories().count(
202       util::GetDriveMyDriveRootPath()));
203
204   // My Drive has resource ID.
205   EXPECT_EQ(FILE_ERROR_OK,
206             metadata_->GetResourceEntryByPath(util::GetDriveMyDriveRootPath(),
207                                               &entry));
208   EXPECT_EQ(drive_service_->GetRootResourceId(), entry.resource_id());
209   EXPECT_EQ(drive_service_->about_resource().largest_change_id(),
210             entry.directory_specific_info().changestamp());
211
212   // My Drive's child is present.
213   base::FilePath file_path =
214       util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt");
215   EXPECT_EQ(FILE_ERROR_OK,
216             metadata_->GetResourceEntryByPath(file_path, &entry));
217 }
218
219 TEST_F(DirectoryLoaderTest, ReadDirectory_MultipleCalls) {
220   TestDirectoryLoaderObserver observer(directory_loader_.get());
221
222   // Load grand root.
223   FileError error = FILE_ERROR_FAILED;
224   ResourceEntryVector entries;
225   bool last_has_more = true;
226   directory_loader_->ReadDirectory(
227       util::GetDriveGrandRootPath(),
228       base::Bind(&AccumulateReadDirectoryResult,
229                  &error, &entries, &last_has_more));
230
231   // Load grand root again without waiting for the result.
232   FileError error2 = FILE_ERROR_FAILED;
233   ResourceEntryVector entries2;
234   bool last_has_more2 = true;
235   directory_loader_->ReadDirectory(
236       util::GetDriveGrandRootPath(),
237       base::Bind(&AccumulateReadDirectoryResult,
238                  &error2, &entries2, &last_has_more2));
239   base::RunLoop().RunUntilIdle();
240
241   // Callback is called for each method call.
242   EXPECT_EQ(FILE_ERROR_OK, error);
243   EXPECT_FALSE(last_has_more);
244   EXPECT_EQ(FILE_ERROR_OK, error2);
245   EXPECT_FALSE(last_has_more2);
246 }
247
248 TEST_F(DirectoryLoaderTest, Lock) {
249   // Lock the loader.
250   scoped_ptr<base::ScopedClosureRunner> lock = loader_controller_->GetLock();
251
252   // Start loading.
253   TestDirectoryLoaderObserver observer(directory_loader_.get());
254   FileError error = FILE_ERROR_FAILED;
255   ResourceEntryVector entries;
256   bool last_has_more = true;
257   directory_loader_->ReadDirectory(
258       util::GetDriveMyDriveRootPath(),
259       base::Bind(&AccumulateReadDirectoryResult,
260                  &error, &entries, &last_has_more));
261   base::RunLoop().RunUntilIdle();
262
263   // Update is pending due to the lock.
264   EXPECT_TRUE(observer.changed_directories().empty());
265
266   // Unlock the loader, this should resume the pending udpate.
267   lock.reset();
268   base::RunLoop().RunUntilIdle();
269   EXPECT_EQ(1U, observer.changed_directories().count(
270       util::GetDriveMyDriveRootPath()));
271 }
272
273 }  // namespace internal
274 }  // namespace drive