Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / drive / resource_metadata_unittest.cc
blob497d7157697dbaf88810faaf8ddcc8d10975c7df
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/chromeos/drive/resource_metadata.h"
7 #include <algorithm>
8 #include <string>
9 #include <vector>
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/sequenced_task_runner.h"
13 #include "base/threading/sequenced_worker_pool.h"
14 #include "base/threading/thread_restrictions.h"
15 #include "chrome/browser/chromeos/drive/drive.pb.h"
16 #include "chrome/browser/chromeos/drive/file_system_util.h"
17 #include "chrome/browser/chromeos/drive/test_util.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "content/public/test/test_browser_thread_bundle.h"
20 #include "google_apis/drive/test_util.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 namespace drive {
24 namespace internal {
25 namespace {
27 // The changestamp of the resource metadata used in
28 // ResourceMetadataTest.
29 const int64 kTestChangestamp = 100;
31 // Returns the sorted base names from |entries|.
32 std::vector<std::string> GetSortedBaseNames(
33 const ResourceEntryVector& entries) {
34 std::vector<std::string> base_names;
35 for (size_t i = 0; i < entries.size(); ++i)
36 base_names.push_back(entries[i].base_name());
37 std::sort(base_names.begin(), base_names.end());
39 return base_names;
42 // Creates a ResourceEntry for a directory with explicitly set resource_id.
43 ResourceEntry CreateDirectoryEntryWithResourceId(
44 const std::string& title,
45 const std::string& resource_id,
46 const std::string& parent_local_id) {
47 ResourceEntry entry;
48 entry.set_title(title);
49 entry.set_resource_id(resource_id);
50 entry.set_parent_local_id(parent_local_id);
51 entry.mutable_file_info()->set_is_directory(true);
52 entry.mutable_directory_specific_info()->set_changestamp(kTestChangestamp);
53 return entry;
56 // Creates a ResourceEntry for a directory.
57 ResourceEntry CreateDirectoryEntry(const std::string& title,
58 const std::string& parent_local_id) {
59 return CreateDirectoryEntryWithResourceId(
60 title, "id:" + title, parent_local_id);
63 // Creates a ResourceEntry for a file with explicitly set resource_id.
64 ResourceEntry CreateFileEntryWithResourceId(
65 const std::string& title,
66 const std::string& resource_id,
67 const std::string& parent_local_id) {
68 ResourceEntry entry;
69 entry.set_title(title);
70 entry.set_resource_id(resource_id);
71 entry.set_parent_local_id(parent_local_id);
72 entry.mutable_file_info()->set_is_directory(false);
73 entry.mutable_file_info()->set_size(1024);
74 entry.mutable_file_specific_info()->set_md5("md5:" + title);
75 return entry;
78 // Creates a ResourceEntry for a file.
79 ResourceEntry CreateFileEntry(const std::string& title,
80 const std::string& parent_local_id) {
81 return CreateFileEntryWithResourceId(title, "id:" + title, parent_local_id);
84 // Creates the following files/directories
85 // drive/root/dir1/
86 // drive/root/dir2/
87 // drive/root/dir1/dir3/
88 // drive/root/dir1/file4
89 // drive/root/dir1/file5
90 // drive/root/dir2/file6
91 // drive/root/dir2/file7
92 // drive/root/dir2/file8
93 // drive/root/dir1/dir3/file9
94 // drive/root/dir1/dir3/file10
95 void SetUpEntries(ResourceMetadata* resource_metadata) {
96 std::string local_id;
97 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->GetIdByPath(
98 util::GetDriveMyDriveRootPath(), &local_id));
99 const std::string root_local_id = local_id;
101 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
102 CreateDirectoryEntry("dir1", root_local_id), &local_id));
103 const std::string local_id_dir1 = local_id;
105 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
106 CreateDirectoryEntry("dir2", root_local_id), &local_id));
107 const std::string local_id_dir2 = local_id;
109 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
110 CreateDirectoryEntry("dir3", local_id_dir1), &local_id));
111 const std::string local_id_dir3 = local_id;
113 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
114 CreateFileEntry("file4", local_id_dir1), &local_id));
115 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
116 CreateFileEntry("file5", local_id_dir1), &local_id));
118 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
119 CreateFileEntry("file6", local_id_dir2), &local_id));
120 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
121 CreateFileEntry("file7", local_id_dir2), &local_id));
122 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
123 CreateFileEntry("file8", local_id_dir2), &local_id));
125 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
126 CreateFileEntry("file9", local_id_dir3), &local_id));
127 ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(
128 CreateFileEntry("file10", local_id_dir3), &local_id));
130 ASSERT_EQ(FILE_ERROR_OK,
131 resource_metadata->SetLargestChangestamp(kTestChangestamp));
134 } // namespace
136 // Tests for methods invoked from the UI thread.
137 class ResourceMetadataTestOnUIThread : public testing::Test {
138 protected:
139 virtual void SetUp() OVERRIDE {
140 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
142 base::ThreadRestrictions::SetIOAllowed(false); // For strict thread check.
143 scoped_refptr<base::SequencedWorkerPool> pool =
144 content::BrowserThread::GetBlockingPool();
145 blocking_task_runner_ =
146 pool->GetSequencedTaskRunner(pool->GetSequenceToken());
148 metadata_storage_.reset(new ResourceMetadataStorage(
149 temp_dir_.path(), blocking_task_runner_.get()));
150 bool success = false;
151 base::PostTaskAndReplyWithResult(
152 blocking_task_runner_.get(),
153 FROM_HERE,
154 base::Bind(&ResourceMetadataStorage::Initialize,
155 base::Unretained(metadata_storage_.get())),
156 google_apis::test_util::CreateCopyResultCallback(&success));
157 test_util::RunBlockingPoolTask();
158 ASSERT_TRUE(success);
160 resource_metadata_.reset(new ResourceMetadata(metadata_storage_.get(),
161 blocking_task_runner_));
163 FileError error = FILE_ERROR_FAILED;
164 base::PostTaskAndReplyWithResult(
165 blocking_task_runner_.get(),
166 FROM_HERE,
167 base::Bind(&ResourceMetadata::Initialize,
168 base::Unretained(resource_metadata_.get())),
169 google_apis::test_util::CreateCopyResultCallback(&error));
170 test_util::RunBlockingPoolTask();
171 ASSERT_EQ(FILE_ERROR_OK, error);
173 blocking_task_runner_->PostTask(
174 FROM_HERE,
175 base::Bind(&SetUpEntries,
176 base::Unretained(resource_metadata_.get())));
177 test_util::RunBlockingPoolTask();
180 virtual void TearDown() OVERRIDE {
181 metadata_storage_.reset();
182 resource_metadata_.reset();
183 base::ThreadRestrictions::SetIOAllowed(true);
186 content::TestBrowserThreadBundle thread_bundle_;
187 base::ScopedTempDir temp_dir_;
188 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
189 scoped_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
190 metadata_storage_;
191 scoped_ptr<ResourceMetadata, test_util::DestroyHelperForTests>
192 resource_metadata_;
195 TEST_F(ResourceMetadataTestOnUIThread, GetResourceEntryByPath) {
196 // Confirm that an existing file is found.
197 FileError error = FILE_ERROR_FAILED;
198 scoped_ptr<ResourceEntry> entry;
199 resource_metadata_->GetResourceEntryByPathOnUIThread(
200 base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"),
201 google_apis::test_util::CreateCopyResultCallback(&error, &entry));
202 test_util::RunBlockingPoolTask();
203 EXPECT_EQ(FILE_ERROR_OK, error);
204 ASSERT_TRUE(entry.get());
205 EXPECT_EQ("file4", entry->base_name());
207 // Confirm that a non existing file is not found.
208 error = FILE_ERROR_FAILED;
209 entry.reset();
210 resource_metadata_->GetResourceEntryByPathOnUIThread(
211 base::FilePath::FromUTF8Unsafe("drive/root/dir1/non_existing"),
212 google_apis::test_util::CreateCopyResultCallback(&error, &entry));
213 test_util::RunBlockingPoolTask();
214 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
215 EXPECT_FALSE(entry.get());
217 // Confirm that the root is found.
218 error = FILE_ERROR_FAILED;
219 entry.reset();
220 resource_metadata_->GetResourceEntryByPathOnUIThread(
221 base::FilePath::FromUTF8Unsafe("drive"),
222 google_apis::test_util::CreateCopyResultCallback(&error, &entry));
223 test_util::RunBlockingPoolTask();
224 EXPECT_EQ(FILE_ERROR_OK, error);
225 EXPECT_TRUE(entry.get());
227 // Confirm that a non existing file is not found at the root level.
228 error = FILE_ERROR_FAILED;
229 entry.reset();
230 resource_metadata_->GetResourceEntryByPathOnUIThread(
231 base::FilePath::FromUTF8Unsafe("non_existing"),
232 google_apis::test_util::CreateCopyResultCallback(&error, &entry));
233 test_util::RunBlockingPoolTask();
234 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
235 EXPECT_FALSE(entry.get());
237 // Confirm that an entry is not found with a wrong root.
238 error = FILE_ERROR_FAILED;
239 entry.reset();
240 resource_metadata_->GetResourceEntryByPathOnUIThread(
241 base::FilePath::FromUTF8Unsafe("non_existing/root"),
242 google_apis::test_util::CreateCopyResultCallback(&error, &entry));
243 test_util::RunBlockingPoolTask();
244 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
245 EXPECT_FALSE(entry.get());
248 TEST_F(ResourceMetadataTestOnUIThread, ReadDirectoryByPath) {
249 // Confirm that an existing directory is found.
250 FileError error = FILE_ERROR_FAILED;
251 scoped_ptr<ResourceEntryVector> entries;
252 resource_metadata_->ReadDirectoryByPathOnUIThread(
253 base::FilePath::FromUTF8Unsafe("drive/root/dir1"),
254 google_apis::test_util::CreateCopyResultCallback(&error, &entries));
255 test_util::RunBlockingPoolTask();
256 EXPECT_EQ(FILE_ERROR_OK, error);
257 ASSERT_TRUE(entries.get());
258 ASSERT_EQ(3U, entries->size());
259 // The order is not guaranteed so we should sort the base names.
260 std::vector<std::string> base_names = GetSortedBaseNames(*entries);
261 EXPECT_EQ("dir3", base_names[0]);
262 EXPECT_EQ("file4", base_names[1]);
263 EXPECT_EQ("file5", base_names[2]);
265 // Confirm that a non existing directory is not found.
266 error = FILE_ERROR_FAILED;
267 entries.reset();
268 resource_metadata_->ReadDirectoryByPathOnUIThread(
269 base::FilePath::FromUTF8Unsafe("drive/root/non_existing"),
270 google_apis::test_util::CreateCopyResultCallback(&error, &entries));
271 test_util::RunBlockingPoolTask();
272 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
273 EXPECT_FALSE(entries.get());
275 // Confirm that reading a file results in FILE_ERROR_NOT_A_DIRECTORY.
276 error = FILE_ERROR_FAILED;
277 entries.reset();
278 resource_metadata_->ReadDirectoryByPathOnUIThread(
279 base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"),
280 google_apis::test_util::CreateCopyResultCallback(&error, &entries));
281 test_util::RunBlockingPoolTask();
282 EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, error);
283 EXPECT_FALSE(entries.get());
286 // Tests for methods running on the blocking task runner.
287 class ResourceMetadataTest : public testing::Test {
288 protected:
289 virtual void SetUp() OVERRIDE {
290 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
292 metadata_storage_.reset(new ResourceMetadataStorage(
293 temp_dir_.path(), base::MessageLoopProxy::current().get()));
294 ASSERT_TRUE(metadata_storage_->Initialize());
296 resource_metadata_.reset(new ResourceMetadata(
297 metadata_storage_.get(), base::MessageLoopProxy::current()));
299 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize());
301 SetUpEntries(resource_metadata_.get());
304 base::ScopedTempDir temp_dir_;
305 content::TestBrowserThreadBundle thread_bundle_;
306 scoped_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
307 metadata_storage_;
308 scoped_ptr<ResourceMetadata, test_util::DestroyHelperForTests>
309 resource_metadata_;
312 TEST_F(ResourceMetadataTest, LargestChangestamp) {
313 const int64 kChangestamp = 123456;
314 EXPECT_EQ(FILE_ERROR_OK,
315 resource_metadata_->SetLargestChangestamp(kChangestamp));
316 EXPECT_EQ(kChangestamp, resource_metadata_->GetLargestChangestamp());
319 TEST_F(ResourceMetadataTest, RefreshEntry) {
320 base::FilePath drive_file_path;
321 ResourceEntry entry;
323 // Get file9.
324 std::string file_id;
325 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
326 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"), &file_id));
327 EXPECT_EQ(FILE_ERROR_OK,
328 resource_metadata_->GetResourceEntryById(file_id, &entry));
329 EXPECT_EQ("file9", entry.base_name());
330 EXPECT_TRUE(!entry.file_info().is_directory());
331 EXPECT_EQ("md5:file9", entry.file_specific_info().md5());
333 // Rename it.
334 ResourceEntry file_entry(entry);
335 file_entry.set_title("file100");
336 EXPECT_EQ(FILE_ERROR_OK,
337 resource_metadata_->RefreshEntry(file_entry));
339 EXPECT_EQ("drive/root/dir1/dir3/file100",
340 resource_metadata_->GetFilePath(file_id).AsUTF8Unsafe());
341 entry.Clear();
342 EXPECT_EQ(FILE_ERROR_OK,
343 resource_metadata_->GetResourceEntryById(file_id, &entry));
344 EXPECT_EQ("file100", entry.base_name());
345 EXPECT_TRUE(!entry.file_info().is_directory());
346 EXPECT_EQ("md5:file9", entry.file_specific_info().md5());
348 // Update the file md5.
349 const std::string updated_md5("md5:updated");
350 file_entry = entry;
351 file_entry.mutable_file_specific_info()->set_md5(updated_md5);
352 EXPECT_EQ(FILE_ERROR_OK,
353 resource_metadata_->RefreshEntry(file_entry));
355 EXPECT_EQ("drive/root/dir1/dir3/file100",
356 resource_metadata_->GetFilePath(file_id).AsUTF8Unsafe());
357 entry.Clear();
358 EXPECT_EQ(FILE_ERROR_OK,
359 resource_metadata_->GetResourceEntryById(file_id, &entry));
360 EXPECT_EQ("file100", entry.base_name());
361 EXPECT_TRUE(!entry.file_info().is_directory());
362 EXPECT_EQ(updated_md5, entry.file_specific_info().md5());
364 // Make sure we get the same thing from GetResourceEntryByPath.
365 entry.Clear();
366 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
367 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file100"), &entry));
368 EXPECT_EQ("file100", entry.base_name());
369 ASSERT_TRUE(!entry.file_info().is_directory());
370 EXPECT_EQ(updated_md5, entry.file_specific_info().md5());
372 // Get dir2.
373 entry.Clear();
374 std::string dir_id;
375 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
376 base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &dir_id));
377 EXPECT_EQ(FILE_ERROR_OK,
378 resource_metadata_->GetResourceEntryById(dir_id, &entry));
379 EXPECT_EQ("dir2", entry.base_name());
380 ASSERT_TRUE(entry.file_info().is_directory());
382 // Get dir3's ID.
383 std::string dir3_id;
384 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
385 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &dir3_id));
387 // Change the name to dir100 and change the parent to drive/dir1/dir3.
388 ResourceEntry dir_entry(entry);
389 dir_entry.set_title("dir100");
390 dir_entry.set_parent_local_id(dir3_id);
391 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RefreshEntry(dir_entry));
393 EXPECT_EQ("drive/root/dir1/dir3/dir100",
394 resource_metadata_->GetFilePath(dir_id).AsUTF8Unsafe());
395 entry.Clear();
396 EXPECT_EQ(FILE_ERROR_OK,
397 resource_metadata_->GetResourceEntryById(dir_id, &entry));
398 EXPECT_EQ("dir100", entry.base_name());
399 EXPECT_TRUE(entry.file_info().is_directory());
400 EXPECT_EQ("id:dir2", entry.resource_id());
402 // Make sure the children have moved over. Test file6.
403 entry.Clear();
404 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
405 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/dir100/file6"),
406 &entry));
407 EXPECT_EQ("file6", entry.base_name());
409 // Make sure dir2 no longer exists.
410 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath(
411 base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &entry));
413 // Make sure that directory cannot move under a file.
414 dir_entry.set_parent_local_id(file_id);
415 EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY,
416 resource_metadata_->RefreshEntry(dir_entry));
418 // Cannot refresh root.
419 dir_entry.Clear();
420 dir_entry.set_local_id(util::kDriveGrandRootLocalId);
421 dir_entry.set_title("new-root-name");
422 dir_entry.set_parent_local_id(dir3_id);
423 EXPECT_EQ(FILE_ERROR_INVALID_OPERATION,
424 resource_metadata_->RefreshEntry(dir_entry));
427 TEST_F(ResourceMetadataTest, GetSubDirectoriesRecursively) {
428 std::set<base::FilePath> sub_directories;
430 // file9: not a directory, so no children.
431 std::string local_id;
432 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
433 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"), &local_id));
434 resource_metadata_->GetSubDirectoriesRecursively(local_id, &sub_directories);
435 EXPECT_TRUE(sub_directories.empty());
437 // dir2: no child directories.
438 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
439 base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &local_id));
440 resource_metadata_->GetSubDirectoriesRecursively(local_id, &sub_directories);
441 EXPECT_TRUE(sub_directories.empty());
442 const std::string dir2_id = local_id;
444 // dir1: dir3 is the only child
445 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
446 base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &local_id));
447 resource_metadata_->GetSubDirectoriesRecursively(local_id, &sub_directories);
448 EXPECT_EQ(1u, sub_directories.size());
449 EXPECT_EQ(1u, sub_directories.count(
450 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3")));
451 sub_directories.clear();
453 // Add a few more directories to make sure deeper nesting works.
454 // dir2/dir100
455 // dir2/dir101
456 // dir2/dir101/dir102
457 // dir2/dir101/dir103
458 // dir2/dir101/dir104
459 // dir2/dir101/dir104/dir105
460 // dir2/dir101/dir104/dir105/dir106
461 // dir2/dir101/dir104/dir105/dir106/dir107
462 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
463 CreateDirectoryEntry("dir100", dir2_id), &local_id));
464 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
465 CreateDirectoryEntry("dir101", dir2_id), &local_id));
466 const std::string dir101_id = local_id;
467 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
468 CreateDirectoryEntry("dir102", dir101_id), &local_id));
469 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
470 CreateDirectoryEntry("dir103", dir101_id), &local_id));
471 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
472 CreateDirectoryEntry("dir104", dir101_id), &local_id));
473 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
474 CreateDirectoryEntry("dir105", local_id), &local_id));
475 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
476 CreateDirectoryEntry("dir106", local_id), &local_id));
477 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
478 CreateDirectoryEntry("dir107", local_id), &local_id));
480 resource_metadata_->GetSubDirectoriesRecursively(dir2_id, &sub_directories);
481 EXPECT_EQ(8u, sub_directories.size());
482 EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe(
483 "drive/root/dir2/dir101")));
484 EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe(
485 "drive/root/dir2/dir101/dir104")));
486 EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe(
487 "drive/root/dir2/dir101/dir104/dir105/dir106/dir107")));
490 TEST_F(ResourceMetadataTest, AddEntry) {
491 base::FilePath drive_file_path;
493 // Add a file to dir3.
494 std::string local_id;
495 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
496 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &local_id));
497 ResourceEntry file_entry = CreateFileEntry("file100", local_id);
498 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(file_entry, &local_id));
499 EXPECT_EQ("drive/root/dir1/dir3/file100",
500 resource_metadata_->GetFilePath(local_id).AsUTF8Unsafe());
502 // Add a directory.
503 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
504 base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &local_id));
505 ResourceEntry dir_entry = CreateDirectoryEntry("dir101", local_id);
506 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(dir_entry, &local_id));
507 EXPECT_EQ("drive/root/dir1/dir101",
508 resource_metadata_->GetFilePath(local_id).AsUTF8Unsafe());
510 // Add to an invalid parent.
511 ResourceEntry file_entry3 = CreateFileEntry("file103", "id:invalid");
512 EXPECT_EQ(FILE_ERROR_NOT_FOUND,
513 resource_metadata_->AddEntry(file_entry3, &local_id));
515 // Add an existing file.
516 EXPECT_EQ(FILE_ERROR_EXISTS,
517 resource_metadata_->AddEntry(file_entry, &local_id));
520 TEST_F(ResourceMetadataTest, RemoveEntry) {
521 // Make sure file9 is found.
522 std::string file9_local_id;
523 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
524 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"),
525 &file9_local_id));
526 ResourceEntry entry;
527 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
528 file9_local_id, &entry));
529 EXPECT_EQ("file9", entry.base_name());
531 // Remove file9.
532 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RemoveEntry(file9_local_id));
534 // file9 should no longer exist.
535 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById(
536 file9_local_id, &entry));
538 // Look for dir3.
539 std::string dir3_local_id;
540 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
541 base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &dir3_local_id));
542 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
543 dir3_local_id, &entry));
544 EXPECT_EQ("dir3", entry.base_name());
546 // Remove dir3.
547 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RemoveEntry(dir3_local_id));
549 // dir3 should no longer exist.
550 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById(
551 dir3_local_id, &entry));
553 // Remove unknown local_id using RemoveEntry.
554 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->RemoveEntry("foo"));
556 // Try removing root. This should fail.
557 EXPECT_EQ(FILE_ERROR_ACCESS_DENIED, resource_metadata_->RemoveEntry(
558 util::kDriveGrandRootLocalId));
561 TEST_F(ResourceMetadataTest, GetResourceEntryById_RootDirectory) {
562 // Look up the root directory by its ID.
563 ResourceEntry entry;
564 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
565 util::kDriveGrandRootLocalId, &entry));
566 EXPECT_EQ("drive", entry.base_name());
569 TEST_F(ResourceMetadataTest, GetResourceEntryById) {
570 // Get file4 by path.
571 std::string local_id;
572 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
573 base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &local_id));
575 // Confirm that an existing file is found.
576 ResourceEntry entry;
577 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
578 local_id, &entry));
579 EXPECT_EQ("file4", entry.base_name());
581 // Confirm that a non existing file is not found.
582 EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById(
583 "file:non_existing", &entry));
586 TEST_F(ResourceMetadataTest, Iterate) {
587 scoped_ptr<ResourceMetadata::Iterator> it = resource_metadata_->GetIterator();
588 ASSERT_TRUE(it);
590 int file_count = 0, directory_count = 0;
591 for (; !it->IsAtEnd(); it->Advance()) {
592 if (!it->GetValue().file_info().is_directory())
593 ++file_count;
594 else
595 ++directory_count;
598 EXPECT_EQ(7, file_count);
599 EXPECT_EQ(7, directory_count);
602 TEST_F(ResourceMetadataTest, DuplicatedNames) {
603 std::string root_local_id;
604 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
605 base::FilePath::FromUTF8Unsafe("drive/root"), &root_local_id));
607 ResourceEntry entry;
609 // When multiple entries with the same title are added in a single directory,
610 // their base_names are de-duped.
611 // - drive/root/foo
612 // - drive/root/foo (1)
613 std::string dir_id_0;
614 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
615 CreateDirectoryEntryWithResourceId(
616 "foo", "foo0", root_local_id), &dir_id_0));
617 std::string dir_id_1;
618 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
619 CreateDirectoryEntryWithResourceId(
620 "foo", "foo1", root_local_id), &dir_id_1));
622 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
623 dir_id_0, &entry));
624 EXPECT_EQ("foo", entry.base_name());
625 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
626 dir_id_1, &entry));
627 EXPECT_EQ("foo (1)", entry.base_name());
629 // - drive/root/foo/bar.txt
630 // - drive/root/foo/bar (1).txt
631 // - drive/root/foo/bar (2).txt
632 std::string file_id_0;
633 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
634 CreateFileEntryWithResourceId(
635 "bar.txt", "bar0", dir_id_0), &file_id_0));
636 std::string file_id_1;
637 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
638 CreateFileEntryWithResourceId(
639 "bar.txt", "bar1", dir_id_0), &file_id_1));
640 std::string file_id_2;
641 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
642 CreateFileEntryWithResourceId(
643 "bar.txt", "bar2", dir_id_0), &file_id_2));
645 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
646 file_id_0, &entry));
647 EXPECT_EQ("bar.txt", entry.base_name());
648 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
649 file_id_1, &entry));
650 EXPECT_EQ("bar (1).txt", entry.base_name());
651 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
652 file_id_2, &entry));
653 EXPECT_EQ("bar (2).txt", entry.base_name());
655 // Same name but different parent. No renaming.
656 // - drive/root/foo (1)/bar.txt
657 std::string file_id_3;
658 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
659 CreateFileEntryWithResourceId(
660 "bar.txt", "bar3", dir_id_1), &file_id_3));
662 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
663 file_id_3, &entry));
664 EXPECT_EQ("bar.txt", entry.base_name());
666 // Checks that the entries can be looked up by the de-duped paths.
667 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
668 base::FilePath::FromUTF8Unsafe("drive/root/foo/bar (2).txt"), &entry));
669 EXPECT_EQ("bar2", entry.resource_id());
670 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
671 base::FilePath::FromUTF8Unsafe("drive/root/foo (1)/bar.txt"), &entry));
672 EXPECT_EQ("bar3", entry.resource_id());
675 TEST_F(ResourceMetadataTest, EncodedNames) {
676 std::string root_local_id;
677 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath(
678 base::FilePath::FromUTF8Unsafe("drive/root"), &root_local_id));
680 ResourceEntry entry;
682 std::string dir_id;
683 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
684 CreateDirectoryEntry("\\(^o^)/", root_local_id), &dir_id));
685 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
686 dir_id, &entry));
687 EXPECT_EQ("\\(^o^)_", entry.base_name());
689 std::string file_id;
690 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(
691 CreateFileEntryWithResourceId("Slash /.txt", "myfile", dir_id),
692 &file_id));
693 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById(
694 file_id, &entry));
695 EXPECT_EQ("Slash _.txt", entry.base_name());
697 ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath(
698 base::FilePath::FromUTF8Unsafe(
699 "drive/root/\\(^o^)_/Slash _.txt"),
700 &entry));
701 EXPECT_EQ("myfile", entry.resource_id());
704 TEST_F(ResourceMetadataTest, Reset) {
705 // The grand root has "root" which is not empty.
706 std::vector<ResourceEntry> entries;
707 ASSERT_EQ(FILE_ERROR_OK,
708 resource_metadata_->ReadDirectoryByPath(
709 base::FilePath::FromUTF8Unsafe("drive/root"), &entries));
710 ASSERT_FALSE(entries.empty());
712 // Reset.
713 EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->Reset());
715 // change stamp should be reset.
716 EXPECT_EQ(0, resource_metadata_->GetLargestChangestamp());
718 // root should continue to exist.
719 ResourceEntry entry;
720 ASSERT_EQ(FILE_ERROR_OK,
721 resource_metadata_->GetResourceEntryByPath(
722 base::FilePath::FromUTF8Unsafe("drive"), &entry));
723 EXPECT_EQ("drive", entry.base_name());
724 ASSERT_TRUE(entry.file_info().is_directory());
725 EXPECT_EQ(util::kDriveGrandRootLocalId, entry.local_id());
727 // There are "other", "trash" and "root" under "drive".
728 ASSERT_EQ(FILE_ERROR_OK,
729 resource_metadata_->ReadDirectoryByPath(
730 base::FilePath::FromUTF8Unsafe("drive"), &entries));
731 EXPECT_EQ(3U, entries.size());
733 // The "other" directory should be empty.
734 ASSERT_EQ(FILE_ERROR_OK,
735 resource_metadata_->ReadDirectoryByPath(
736 base::FilePath::FromUTF8Unsafe("drive/other"), &entries));
737 EXPECT_TRUE(entries.empty());
739 // The "trash" directory should be empty.
740 ASSERT_EQ(FILE_ERROR_OK,
741 resource_metadata_->ReadDirectoryByPath(
742 base::FilePath::FromUTF8Unsafe("drive/trash"), &entries));
743 EXPECT_TRUE(entries.empty());
746 } // namespace internal
747 } // namespace drive