Update broken references to image assets
[chromium-blink-merge.git] / chrome / browser / chromeos / drive / sync / entry_update_performer_unittest.cc
blobd174e56d7804e9564f0c55dc3181e2e76f3684a0
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.
5 #include "chrome/browser/chromeos/drive/sync/entry_update_performer.h"
7 #include "base/callback_helpers.h"
8 #include "base/files/file_util.h"
9 #include "base/md5.h"
10 #include "base/task_runner_util.h"
11 #include "chrome/browser/chromeos/drive/file_system/download_operation.h"
12 #include "chrome/browser/chromeos/drive/file_system/operation_test_base.h"
13 #include "components/drive/drive_api_util.h"
14 #include "components/drive/file_cache.h"
15 #include "components/drive/job_scheduler.h"
16 #include "components/drive/resource_metadata.h"
17 #include "components/drive/service/fake_drive_service.h"
18 #include "content/public/test/test_utils.h"
19 #include "google_apis/drive/drive_api_parser.h"
20 #include "google_apis/drive/test_util.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 namespace drive {
24 namespace internal {
26 class EntryUpdatePerformerTest : public file_system::OperationTestBase {
27 protected:
28 void SetUp() override {
29 OperationTestBase::SetUp();
30 performer_.reset(new EntryUpdatePerformer(blocking_task_runner(),
31 delegate(),
32 scheduler(),
33 metadata(),
34 cache(),
35 loader_controller()));
38 // Stores |content| to the cache and mark it as dirty.
39 FileError StoreAndMarkDirty(const std::string& local_id,
40 const std::string& content) {
41 base::FilePath path;
42 if (!base::CreateTemporaryFileInDir(temp_dir(), &path) ||
43 !google_apis::test_util::WriteStringToFile(path, content))
44 return FILE_ERROR_FAILED;
46 // Store the file to cache.
47 FileError error = FILE_ERROR_FAILED;
48 base::PostTaskAndReplyWithResult(
49 blocking_task_runner(),
50 FROM_HERE,
51 base::Bind(&FileCache::Store,
52 base::Unretained(cache()),
53 local_id, std::string(), path,
54 FileCache::FILE_OPERATION_COPY),
55 google_apis::test_util::CreateCopyResultCallback(&error));
56 content::RunAllBlockingPoolTasksUntilIdle();
57 return error;
60 scoped_ptr<EntryUpdatePerformer> performer_;
63 TEST_F(EntryUpdatePerformerTest, UpdateEntry) {
64 base::FilePath src_path(
65 FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
66 base::FilePath dest_path(
67 FILE_PATH_LITERAL("drive/root/Directory 1/Sub Directory Folder"));
69 ResourceEntry src_entry, dest_entry;
70 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));
71 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(dest_path, &dest_entry));
73 // Update local entry.
74 base::Time new_last_modified = base::Time::FromInternalValue(
75 src_entry.file_info().last_modified()) + base::TimeDelta::FromSeconds(1);
76 base::Time new_last_accessed = base::Time::FromInternalValue(
77 src_entry.file_info().last_accessed()) + base::TimeDelta::FromSeconds(2);
79 src_entry.set_parent_local_id(dest_entry.local_id());
80 src_entry.set_title("Moved" + src_entry.title());
81 src_entry.mutable_file_info()->set_last_modified(
82 new_last_modified.ToInternalValue());
83 src_entry.mutable_file_info()->set_last_accessed(
84 new_last_accessed.ToInternalValue());
85 src_entry.set_metadata_edit_state(ResourceEntry::DIRTY);
87 FileError error = FILE_ERROR_FAILED;
88 base::PostTaskAndReplyWithResult(
89 blocking_task_runner(),
90 FROM_HERE,
91 base::Bind(&ResourceMetadata::RefreshEntry,
92 base::Unretained(metadata()),
93 src_entry),
94 google_apis::test_util::CreateCopyResultCallback(&error));
95 content::RunAllBlockingPoolTasksUntilIdle();
96 EXPECT_EQ(FILE_ERROR_OK, error);
98 // Perform server side update.
99 error = FILE_ERROR_FAILED;
100 performer_->UpdateEntry(
101 src_entry.local_id(),
102 ClientContext(USER_INITIATED),
103 google_apis::test_util::CreateCopyResultCallback(&error));
104 content::RunAllBlockingPoolTasksUntilIdle();
105 EXPECT_EQ(FILE_ERROR_OK, error);
107 // Verify the file is updated on the server.
108 google_apis::DriveApiErrorCode gdata_error = google_apis::DRIVE_OTHER_ERROR;
109 scoped_ptr<google_apis::FileResource> gdata_entry;
110 fake_service()->GetFileResource(
111 src_entry.resource_id(),
112 google_apis::test_util::CreateCopyResultCallback(&gdata_error,
113 &gdata_entry));
114 content::RunAllBlockingPoolTasksUntilIdle();
115 EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
116 ASSERT_TRUE(gdata_entry);
118 EXPECT_EQ(src_entry.title(), gdata_entry->title());
119 EXPECT_EQ(new_last_modified, gdata_entry->modified_date());
120 EXPECT_EQ(new_last_accessed, gdata_entry->last_viewed_by_me_date());
122 ASSERT_FALSE(gdata_entry->parents().empty());
123 EXPECT_EQ(dest_entry.resource_id(), gdata_entry->parents()[0].file_id());
126 TEST_F(EntryUpdatePerformerTest, UpdateEntry_SetProperties) {
127 base::FilePath entry_path(
128 FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
130 ResourceEntry entry;
131 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(entry_path, &entry));
133 Property* const first_property = entry.mutable_new_properties()->Add();
134 first_property->set_key("hello");
135 first_property->set_value("world");
136 first_property->set_visibility(Property_Visibility_PUBLIC);
138 Property* const second_property = entry.mutable_new_properties()->Add();
139 second_property->set_key("this");
140 second_property->set_value("will-change");
141 second_property->set_visibility(Property_Visibility_PUBLIC);
142 entry.set_metadata_edit_state(ResourceEntry::DIRTY);
144 FileError error = FILE_ERROR_FAILED;
145 base::PostTaskAndReplyWithResult(
146 blocking_task_runner(), FROM_HERE,
147 base::Bind(&ResourceMetadata::RefreshEntry, base::Unretained(metadata()),
148 entry),
149 google_apis::test_util::CreateCopyResultCallback(&error));
150 content::RunAllBlockingPoolTasksUntilIdle();
151 EXPECT_EQ(FILE_ERROR_OK, error);
153 // Perform server side update.
154 error = FILE_ERROR_FAILED;
155 performer_->UpdateEntry(
156 entry.local_id(), ClientContext(USER_INITIATED),
157 google_apis::test_util::CreateCopyResultCallback(&error));
159 // Add a new property during an update.
160 Property* const property = entry.mutable_new_properties()->Add();
161 property->set_key("tokyo");
162 property->set_value("kyoto");
163 property->set_visibility(Property_Visibility_PUBLIC);
165 // Modify an existing property during an update.
166 second_property->set_value("changed");
168 // Change the resource entry during an update.
169 base::PostTaskAndReplyWithResult(
170 blocking_task_runner(), FROM_HERE,
171 base::Bind(&ResourceMetadata::RefreshEntry, base::Unretained(metadata()),
172 entry),
173 google_apis::test_util::CreateCopyResultCallback(&error));
175 // Wait until the update is fully completed.
176 content::RunAllBlockingPoolTasksUntilIdle();
177 EXPECT_EQ(FILE_ERROR_OK, error);
179 // List of synced properties should be removed from the proto.
180 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(entry_path, &entry));
181 ASSERT_EQ(2, entry.new_properties().size());
182 EXPECT_EQ("changed", entry.new_properties().Get(0).value());
183 EXPECT_EQ("tokyo", entry.new_properties().Get(1).key());
186 // Tests updating metadata of a file with a non-dirty cache file.
187 TEST_F(EntryUpdatePerformerTest, UpdateEntry_WithNonDirtyCache) {
188 base::FilePath src_path(
189 FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
191 // Download the file content to prepare a non-dirty cache file.
192 file_system::DownloadOperation download_operation(
193 blocking_task_runner(), delegate(), scheduler(), metadata(), cache(),
194 temp_dir());
195 FileError error = FILE_ERROR_FAILED;
196 base::FilePath cache_file_path;
197 scoped_ptr<ResourceEntry> src_entry;
198 download_operation.EnsureFileDownloadedByPath(
199 src_path,
200 ClientContext(USER_INITIATED),
201 GetFileContentInitializedCallback(),
202 google_apis::GetContentCallback(),
203 google_apis::test_util::CreateCopyResultCallback(
204 &error, &cache_file_path, &src_entry));
205 content::RunAllBlockingPoolTasksUntilIdle();
206 EXPECT_EQ(FILE_ERROR_OK, error);
207 ASSERT_TRUE(src_entry);
209 // Update the entry locally.
210 src_entry->set_title("Updated" + src_entry->title());
211 src_entry->set_metadata_edit_state(ResourceEntry::DIRTY);
213 error = FILE_ERROR_FAILED;
214 base::PostTaskAndReplyWithResult(
215 blocking_task_runner(),
216 FROM_HERE,
217 base::Bind(&ResourceMetadata::RefreshEntry,
218 base::Unretained(metadata()),
219 *src_entry),
220 google_apis::test_util::CreateCopyResultCallback(&error));
221 content::RunAllBlockingPoolTasksUntilIdle();
222 EXPECT_EQ(FILE_ERROR_OK, error);
224 // Perform server side update. This shouldn't fail. (crbug.com/358590)
225 error = FILE_ERROR_FAILED;
226 performer_->UpdateEntry(
227 src_entry->local_id(),
228 ClientContext(USER_INITIATED),
229 google_apis::test_util::CreateCopyResultCallback(&error));
230 content::RunAllBlockingPoolTasksUntilIdle();
231 EXPECT_EQ(FILE_ERROR_OK, error);
233 // Verify the file is updated on the server.
234 google_apis::DriveApiErrorCode gdata_error = google_apis::DRIVE_OTHER_ERROR;
235 scoped_ptr<google_apis::FileResource> gdata_entry;
236 fake_service()->GetFileResource(
237 src_entry->resource_id(),
238 google_apis::test_util::CreateCopyResultCallback(&gdata_error,
239 &gdata_entry));
240 content::RunAllBlockingPoolTasksUntilIdle();
241 EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
242 ASSERT_TRUE(gdata_entry);
243 EXPECT_EQ(src_entry->title(), gdata_entry->title());
246 TEST_F(EntryUpdatePerformerTest, UpdateEntry_NotFound) {
247 const std::string id = "this ID should result in NOT_FOUND";
248 FileError error = FILE_ERROR_FAILED;
249 performer_->UpdateEntry(
250 id, ClientContext(USER_INITIATED),
251 google_apis::test_util::CreateCopyResultCallback(&error));
252 content::RunAllBlockingPoolTasksUntilIdle();
253 EXPECT_EQ(FILE_ERROR_NOT_FOUND, error);
256 TEST_F(EntryUpdatePerformerTest, UpdateEntry_ContentUpdate) {
257 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
258 const std::string kResourceId("2_file_resource_id");
260 const std::string local_id = GetLocalId(kFilePath);
261 EXPECT_FALSE(local_id.empty());
263 const std::string kTestFileContent = "I'm being uploaded! Yay!";
264 EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));
266 int64 original_changestamp =
267 fake_service()->about_resource().largest_change_id();
269 // The callback will be called upon completion of UpdateEntry().
270 FileError error = FILE_ERROR_FAILED;
271 performer_->UpdateEntry(
272 local_id,
273 ClientContext(USER_INITIATED),
274 google_apis::test_util::CreateCopyResultCallback(&error));
275 content::RunAllBlockingPoolTasksUntilIdle();
276 EXPECT_EQ(FILE_ERROR_OK, error);
278 // Check that the server has received an update.
279 EXPECT_LT(original_changestamp,
280 fake_service()->about_resource().largest_change_id());
282 // Check that the file size is updated to that of the updated content.
283 google_apis::DriveApiErrorCode gdata_error = google_apis::DRIVE_OTHER_ERROR;
284 scoped_ptr<google_apis::FileResource> server_entry;
285 fake_service()->GetFileResource(
286 kResourceId,
287 google_apis::test_util::CreateCopyResultCallback(&gdata_error,
288 &server_entry));
289 content::RunAllBlockingPoolTasksUntilIdle();
290 EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
291 EXPECT_EQ(static_cast<int64>(kTestFileContent.size()),
292 server_entry->file_size());
294 // Make sure that the cache is no longer dirty.
295 ResourceEntry entry;
296 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
297 EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
300 TEST_F(EntryUpdatePerformerTest, UpdateEntry_ContentUpdateMd5Check) {
301 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
302 const std::string kResourceId("2_file_resource_id");
304 const std::string local_id = GetLocalId(kFilePath);
305 EXPECT_FALSE(local_id.empty());
307 const std::string kTestFileContent = "I'm being uploaded! Yay!";
308 EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));
310 int64 original_changestamp =
311 fake_service()->about_resource().largest_change_id();
313 // The callback will be called upon completion of UpdateEntry().
314 FileError error = FILE_ERROR_FAILED;
315 performer_->UpdateEntry(
316 local_id,
317 ClientContext(USER_INITIATED),
318 google_apis::test_util::CreateCopyResultCallback(&error));
319 content::RunAllBlockingPoolTasksUntilIdle();
320 EXPECT_EQ(FILE_ERROR_OK, error);
322 // Check that the server has received an update.
323 EXPECT_LT(original_changestamp,
324 fake_service()->about_resource().largest_change_id());
326 // Check that the file size is updated to that of the updated content.
327 google_apis::DriveApiErrorCode gdata_error = google_apis::DRIVE_OTHER_ERROR;
328 scoped_ptr<google_apis::FileResource> server_entry;
329 fake_service()->GetFileResource(
330 kResourceId,
331 google_apis::test_util::CreateCopyResultCallback(&gdata_error,
332 &server_entry));
333 content::RunAllBlockingPoolTasksUntilIdle();
334 EXPECT_EQ(google_apis::HTTP_SUCCESS, gdata_error);
335 EXPECT_EQ(static_cast<int64>(kTestFileContent.size()),
336 server_entry->file_size());
338 // Make sure that the cache is no longer dirty.
339 ResourceEntry entry;
340 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
341 EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
343 // Again mark the cache file dirty.
344 scoped_ptr<base::ScopedClosureRunner> file_closer;
345 error = FILE_ERROR_FAILED;
346 base::PostTaskAndReplyWithResult(
347 blocking_task_runner(),
348 FROM_HERE,
349 base::Bind(&FileCache::OpenForWrite,
350 base::Unretained(cache()),
351 local_id,
352 &file_closer),
353 google_apis::test_util::CreateCopyResultCallback(&error));
354 content::RunAllBlockingPoolTasksUntilIdle();
355 EXPECT_EQ(FILE_ERROR_OK, error);
356 file_closer.reset();
358 // And call UpdateEntry again.
359 // In this case, although the file is marked as dirty, but the content
360 // hasn't been changed. Thus, the actual uploading should be skipped.
361 original_changestamp = fake_service()->about_resource().largest_change_id();
362 error = FILE_ERROR_FAILED;
363 performer_->UpdateEntry(
364 local_id,
365 ClientContext(USER_INITIATED),
366 google_apis::test_util::CreateCopyResultCallback(&error));
367 content::RunAllBlockingPoolTasksUntilIdle();
368 EXPECT_EQ(FILE_ERROR_OK, error);
370 EXPECT_EQ(original_changestamp,
371 fake_service()->about_resource().largest_change_id());
373 // Make sure that the cache is no longer dirty.
374 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
375 EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
378 TEST_F(EntryUpdatePerformerTest, UpdateEntry_OpenedForWrite) {
379 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/File 1.txt"));
380 const std::string kResourceId("2_file_resource_id");
382 const std::string local_id = GetLocalId(kFilePath);
383 EXPECT_FALSE(local_id.empty());
385 const std::string kTestFileContent = "I'm being uploaded! Yay!";
386 EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));
388 // Emulate a situation where someone is writing to the file.
389 scoped_ptr<base::ScopedClosureRunner> file_closer;
390 FileError error = FILE_ERROR_FAILED;
391 base::PostTaskAndReplyWithResult(
392 blocking_task_runner(),
393 FROM_HERE,
394 base::Bind(&FileCache::OpenForWrite,
395 base::Unretained(cache()),
396 local_id,
397 &file_closer),
398 google_apis::test_util::CreateCopyResultCallback(&error));
399 content::RunAllBlockingPoolTasksUntilIdle();
400 EXPECT_EQ(FILE_ERROR_OK, error);
402 // Update. This should not clear the dirty bit.
403 error = FILE_ERROR_FAILED;
404 performer_->UpdateEntry(
405 local_id,
406 ClientContext(USER_INITIATED),
407 google_apis::test_util::CreateCopyResultCallback(&error));
408 content::RunAllBlockingPoolTasksUntilIdle();
409 EXPECT_EQ(FILE_ERROR_OK, error);
411 // Make sure that the cache is still dirty.
412 ResourceEntry entry;
413 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
414 EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty());
416 // Close the file.
417 file_closer.reset();
419 // Update. This should clear the dirty bit.
420 error = FILE_ERROR_FAILED;
421 performer_->UpdateEntry(
422 local_id,
423 ClientContext(USER_INITIATED),
424 google_apis::test_util::CreateCopyResultCallback(&error));
425 content::RunAllBlockingPoolTasksUntilIdle();
426 EXPECT_EQ(FILE_ERROR_OK, error);
428 // Make sure that the cache is no longer dirty.
429 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
430 EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
433 TEST_F(EntryUpdatePerformerTest, UpdateEntry_UploadNewFile) {
434 // Create a new file locally.
435 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/New File.txt"));
437 ResourceEntry parent;
438 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath.DirName(), &parent));
440 ResourceEntry entry;
441 entry.set_parent_local_id(parent.local_id());
442 entry.set_title(kFilePath.BaseName().AsUTF8Unsafe());
443 entry.mutable_file_specific_info()->set_content_mime_type("text/plain");
444 entry.set_metadata_edit_state(ResourceEntry::DIRTY);
446 FileError error = FILE_ERROR_FAILED;
447 std::string local_id;
448 base::PostTaskAndReplyWithResult(
449 blocking_task_runner(),
450 FROM_HERE,
451 base::Bind(&internal::ResourceMetadata::AddEntry,
452 base::Unretained(metadata()),
453 entry,
454 &local_id),
455 google_apis::test_util::CreateCopyResultCallback(&error));
456 content::RunAllBlockingPoolTasksUntilIdle();
457 EXPECT_EQ(FILE_ERROR_OK, error);
459 // Update. This should result in creating a new file on the server.
460 error = FILE_ERROR_FAILED;
461 performer_->UpdateEntry(
462 local_id,
463 ClientContext(USER_INITIATED),
464 google_apis::test_util::CreateCopyResultCallback(&error));
465 content::RunAllBlockingPoolTasksUntilIdle();
466 EXPECT_EQ(FILE_ERROR_OK, error);
468 // The entry got a resource ID.
469 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
470 EXPECT_FALSE(entry.resource_id().empty());
471 EXPECT_EQ(ResourceEntry::CLEAN, entry.metadata_edit_state());
473 // Make sure that the cache is no longer dirty.
474 EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
476 // Make sure that we really created a file.
477 google_apis::DriveApiErrorCode status = google_apis::DRIVE_OTHER_ERROR;
478 scoped_ptr<google_apis::FileResource> server_entry;
479 fake_service()->GetFileResource(
480 entry.resource_id(),
481 google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
482 content::RunAllBlockingPoolTasksUntilIdle();
483 EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
484 ASSERT_TRUE(server_entry);
485 EXPECT_FALSE(server_entry->IsDirectory());
488 TEST_F(EntryUpdatePerformerTest, UpdateEntry_NewFileOpendForWrite) {
489 // Create a new file locally.
490 const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root/New File.txt"));
492 ResourceEntry parent;
493 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath.DirName(), &parent));
495 ResourceEntry entry;
496 entry.set_parent_local_id(parent.local_id());
497 entry.set_title(kFilePath.BaseName().AsUTF8Unsafe());
498 entry.mutable_file_specific_info()->set_content_mime_type("text/plain");
499 entry.set_metadata_edit_state(ResourceEntry::DIRTY);
501 FileError error = FILE_ERROR_FAILED;
502 std::string local_id;
503 base::PostTaskAndReplyWithResult(
504 blocking_task_runner(),
505 FROM_HERE,
506 base::Bind(&internal::ResourceMetadata::AddEntry,
507 base::Unretained(metadata()),
508 entry,
509 &local_id),
510 google_apis::test_util::CreateCopyResultCallback(&error));
511 content::RunAllBlockingPoolTasksUntilIdle();
512 EXPECT_EQ(FILE_ERROR_OK, error);
514 const std::string kTestFileContent = "This is a new file.";
515 EXPECT_EQ(FILE_ERROR_OK, StoreAndMarkDirty(local_id, kTestFileContent));
517 // Emulate a situation where someone is writing to the file.
518 scoped_ptr<base::ScopedClosureRunner> file_closer;
519 error = FILE_ERROR_FAILED;
520 base::PostTaskAndReplyWithResult(
521 blocking_task_runner(),
522 FROM_HERE,
523 base::Bind(&FileCache::OpenForWrite,
524 base::Unretained(cache()),
525 local_id,
526 &file_closer),
527 google_apis::test_util::CreateCopyResultCallback(&error));
528 content::RunAllBlockingPoolTasksUntilIdle();
529 EXPECT_EQ(FILE_ERROR_OK, error);
531 // Update, but no update is performed because the file is opened.
532 error = FILE_ERROR_FAILED;
533 performer_->UpdateEntry(
534 local_id,
535 ClientContext(USER_INITIATED),
536 google_apis::test_util::CreateCopyResultCallback(&error));
537 content::RunAllBlockingPoolTasksUntilIdle();
538 EXPECT_EQ(FILE_ERROR_OK, error);
540 // The entry hasn't got a resource ID yet.
541 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
542 EXPECT_TRUE(entry.resource_id().empty());
544 // Close the file.
545 file_closer.reset();
547 // Update. This should result in creating a new file on the server.
548 error = FILE_ERROR_FAILED;
549 performer_->UpdateEntry(
550 local_id,
551 ClientContext(USER_INITIATED),
552 google_apis::test_util::CreateCopyResultCallback(&error));
553 content::RunAllBlockingPoolTasksUntilIdle();
554 EXPECT_EQ(FILE_ERROR_OK, error);
556 // The entry got a resource ID.
557 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kFilePath, &entry));
558 EXPECT_FALSE(entry.resource_id().empty());
559 EXPECT_EQ(ResourceEntry::CLEAN, entry.metadata_edit_state());
562 TEST_F(EntryUpdatePerformerTest, UpdateEntry_CreateDirectory) {
563 // Create a new directory locally.
564 const base::FilePath kPath(FILE_PATH_LITERAL("drive/root/New Directory"));
566 ResourceEntry parent;
567 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kPath.DirName(), &parent));
569 ResourceEntry entry;
570 entry.set_parent_local_id(parent.local_id());
571 entry.set_title(kPath.BaseName().AsUTF8Unsafe());
572 entry.mutable_file_info()->set_is_directory(true);
573 entry.set_metadata_edit_state(ResourceEntry::DIRTY);
575 FileError error = FILE_ERROR_FAILED;
576 std::string local_id;
577 base::PostTaskAndReplyWithResult(
578 blocking_task_runner(),
579 FROM_HERE,
580 base::Bind(&internal::ResourceMetadata::AddEntry,
581 base::Unretained(metadata()),
582 entry,
583 &local_id),
584 google_apis::test_util::CreateCopyResultCallback(&error));
585 content::RunAllBlockingPoolTasksUntilIdle();
586 EXPECT_EQ(FILE_ERROR_OK, error);
588 // Update. This should result in creating a new directory on the server.
589 error = FILE_ERROR_FAILED;
590 performer_->UpdateEntry(
591 local_id,
592 ClientContext(USER_INITIATED),
593 google_apis::test_util::CreateCopyResultCallback(&error));
594 content::RunAllBlockingPoolTasksUntilIdle();
595 EXPECT_EQ(FILE_ERROR_OK, error);
597 // The entry got a resource ID.
598 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(kPath, &entry));
599 EXPECT_FALSE(entry.resource_id().empty());
600 EXPECT_EQ(ResourceEntry::CLEAN, entry.metadata_edit_state());
602 // Make sure that we really created a directory.
603 google_apis::DriveApiErrorCode status = google_apis::DRIVE_OTHER_ERROR;
604 scoped_ptr<google_apis::FileResource> server_entry;
605 fake_service()->GetFileResource(
606 entry.resource_id(),
607 google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
608 content::RunAllBlockingPoolTasksUntilIdle();
609 EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
610 ASSERT_TRUE(server_entry);
611 EXPECT_TRUE(server_entry->IsDirectory());
614 TEST_F(EntryUpdatePerformerTest, UpdateEntry_InsufficientPermission) {
615 base::FilePath src_path(
616 FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
618 ResourceEntry src_entry;
619 EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(src_path, &src_entry));
621 // Update local entry.
622 ResourceEntry updated_entry(src_entry);
623 updated_entry.set_title("Moved" + src_entry.title());
624 updated_entry.set_metadata_edit_state(ResourceEntry::DIRTY);
626 FileError error = FILE_ERROR_FAILED;
627 base::PostTaskAndReplyWithResult(
628 blocking_task_runner(),
629 FROM_HERE,
630 base::Bind(&ResourceMetadata::RefreshEntry,
631 base::Unretained(metadata()),
632 updated_entry),
633 google_apis::test_util::CreateCopyResultCallback(&error));
634 content::RunAllBlockingPoolTasksUntilIdle();
635 EXPECT_EQ(FILE_ERROR_OK, error);
637 // Set user permission to forbid server side update.
638 EXPECT_EQ(google_apis::HTTP_SUCCESS, fake_service()->SetUserPermission(
639 src_entry.resource_id(), google_apis::drive::PERMISSION_ROLE_READER));
641 // Try to perform update.
642 error = FILE_ERROR_FAILED;
643 performer_->UpdateEntry(
644 src_entry.local_id(),
645 ClientContext(USER_INITIATED),
646 google_apis::test_util::CreateCopyResultCallback(&error));
647 content::RunAllBlockingPoolTasksUntilIdle();
648 EXPECT_EQ(FILE_ERROR_OK, error);
650 // This should result in reverting the local change.
651 ResourceEntry result_entry;
652 EXPECT_EQ(FILE_ERROR_OK,
653 GetLocalResourceEntryById(src_entry.local_id(), &result_entry));
654 EXPECT_EQ(src_entry.title(), result_entry.title());
657 } // namespace internal
658 } // namespace drive