Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync_file_system / drive_backend_v1 / drive_file_sync_service_fake_unittest.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/sync_file_system/drive_backend_v1/drive_file_sync_service.h"
6
7 #include <utility>
8
9 #include "base/command_line.h"
10 #include "base/file_util.h"
11 #include "base/message_loop/message_loop_proxy.h"
12 #include "base/run_loop.h"
13 #include "chrome/browser/drive/drive_uploader.h"
14 #include "chrome/browser/drive/fake_drive_service.h"
15 #include "chrome/browser/extensions/test_extension_service.h"
16 #include "chrome/browser/extensions/test_extension_system.h"
17 #include "chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.h"
18 #include "chrome/browser/sync_file_system/drive_backend_v1/api_util.h"
19 #include "chrome/browser/sync_file_system/drive_backend_v1/drive_file_sync_util.h"
20 #include "chrome/browser/sync_file_system/drive_backend_v1/drive_metadata_store.h"
21 #include "chrome/browser/sync_file_system/file_status_observer.h"
22 #include "chrome/browser/sync_file_system/mock_remote_change_processor.h"
23 #include "chrome/browser/sync_file_system/sync_direction.h"
24 #include "chrome/browser/sync_file_system/sync_file_metadata.h"
25 #include "chrome/browser/sync_file_system/sync_file_system.pb.h"
26 #include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
27 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
28 #include "chrome/test/base/testing_browser_process.h"
29 #include "chrome/test/base/testing_profile.h"
30 #include "chrome/test/base/testing_profile_manager.h"
31 #include "content/public/test/test_browser_thread_bundle.h"
32 #include "extensions/common/extension.h"
33 #include "extensions/common/extension_builder.h"
34 #include "extensions/common/id_util.h"
35 #include "google_apis/drive/drive_api_parser.h"
36 #include "google_apis/drive/gdata_errorcode.h"
37 #include "google_apis/drive/gdata_wapi_parser.h"
38 #include "google_apis/drive/test_util.h"
39 #include "testing/gmock/include/gmock/gmock.h"
40 #include "testing/gtest/include/gtest/gtest.h"
41 #include "webkit/common/fileapi/file_system_util.h"
42
43 #if defined(OS_CHROMEOS)
44 #include "chrome/browser/chromeos/login/user_manager.h"
45 #include "chrome/browser/chromeos/settings/cros_settings.h"
46 #include "chrome/browser/chromeos/settings/device_settings_service.h"
47 #endif
48
49 #define FPL(x) FILE_PATH_LITERAL(x)
50
51 using ::testing::StrictMock;
52 using ::testing::_;
53
54 using drive::DriveServiceInterface;
55 using drive::DriveUploader;
56 using drive::DriveUploaderInterface;
57 using drive::FakeDriveService;
58
59 using extensions::Extension;
60 using extensions::DictionaryBuilder;
61 using google_apis::GDataErrorCode;
62 using google_apis::ResourceEntry;
63
64 namespace sync_file_system {
65
66 using drive_backend::APIUtil;
67 using drive_backend::APIUtilInterface;
68 using drive_backend::FakeDriveServiceHelper;
69
70 namespace {
71
72 const char kTestProfileName[] = "test-profile";
73
74 #if !defined(OS_ANDROID)
75 const char kExtensionName1[] = "example1";
76 const char kExtensionName2[] = "example2";
77 #endif
78
79 void DidInitialize(bool* done, SyncStatusCode status, bool created) {
80   EXPECT_FALSE(*done);
81   *done = true;
82   EXPECT_EQ(SYNC_STATUS_OK, status);
83   EXPECT_TRUE(created);
84 }
85
86 // Mocks adding an installed extension to ExtensionService.
87 scoped_refptr<const extensions::Extension> AddTestExtension(
88     ExtensionService* extension_service,
89     const base::FilePath::StringType& extension_name) {
90   std::string id = extensions::id_util::GenerateIdForPath(
91       base::FilePath(extension_name));
92
93   scoped_refptr<const Extension> extension =
94       extensions::ExtensionBuilder().SetManifest(
95           DictionaryBuilder()
96             .Set("name", extension_name)
97             .Set("version", "1.0"))
98           .SetID(id)
99       .Build();
100   extension_service->AddExtension(extension.get());
101   return extension;
102 }
103
104 // Converts extension_name to extension ID.
105 std::string ExtensionNameToId(const std::string& extension_name) {
106   base::FilePath path = base::FilePath::FromUTF8Unsafe(extension_name);
107   return extensions::id_util::GenerateIdForPath(path);
108 }
109
110 // Converts extension_name to GURL version.
111 GURL ExtensionNameToGURL(const std::string& extension_name) {
112   return extensions::Extension::GetBaseURLFromExtensionId(
113       ExtensionNameToId(extension_name));
114 }
115
116 #if !defined(OS_ANDROID)
117 ACTION(InvokeCompletionCallback) {
118   base::MessageLoopProxy::current()->PostTask(FROM_HERE, arg2);
119 }
120
121 ACTION(PrepareForRemoteChange_Busy) {
122   base::MessageLoopProxy::current()->PostTask(
123       FROM_HERE,
124       base::Bind(arg1,
125                  SYNC_STATUS_FILE_BUSY,
126                  SyncFileMetadata(),
127                  FileChangeList()));
128 }
129
130 ACTION(PrepareForRemoteChange_NotFound) {
131   base::MessageLoopProxy::current()->PostTask(
132       FROM_HERE,
133       base::Bind(arg1,
134                  SYNC_STATUS_OK,
135                  SyncFileMetadata(SYNC_FILE_TYPE_UNKNOWN, 0, base::Time()),
136                  FileChangeList()));
137 }
138
139 ACTION(PrepareForRemoteChange_NotModified) {
140   base::MessageLoopProxy::current()->PostTask(
141       FROM_HERE,
142       base::Bind(arg1,
143                  SYNC_STATUS_OK,
144                  SyncFileMetadata(SYNC_FILE_TYPE_FILE, 0, base::Time()),
145                  FileChangeList()));
146 }
147
148 ACTION(InvokeDidApplyRemoteChange) {
149   base::MessageLoopProxy::current()->PostTask(
150       FROM_HERE, base::Bind(arg3, SYNC_STATUS_OK));
151 }
152 #endif  // !defined(OS_ANDROID)
153
154 }  // namespace
155
156 class MockFileStatusObserver: public FileStatusObserver {
157  public:
158   MockFileStatusObserver() {}
159   virtual ~MockFileStatusObserver() {}
160
161   MOCK_METHOD4(OnFileStatusChanged,
162                void(const fileapi::FileSystemURL& url,
163                     SyncFileStatus sync_status,
164                     SyncAction action_taken,
165                     SyncDirection direction));
166 };
167
168 class DriveFileSyncServiceFakeTest : public testing::Test {
169  public:
170   DriveFileSyncServiceFakeTest()
171       : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
172         profile_manager_(TestingBrowserProcess::GetGlobal()),
173         fake_drive_service_(NULL) {
174   }
175
176   virtual void SetUp() OVERRIDE {
177     ASSERT_TRUE(profile_manager_.SetUp());
178     profile_ = profile_manager_.CreateTestingProfile(kTestProfileName);
179
180     // Add TestExtensionSystem with registered ExtensionIds used in tests.
181     extensions::TestExtensionSystem* extension_system(
182         static_cast<extensions::TestExtensionSystem*>(
183             extensions::ExtensionSystem::Get(profile_)));
184     extension_system->CreateExtensionService(
185         CommandLine::ForCurrentProcess(), base::FilePath(), false);
186     extension_service_ = extension_system->Get(
187         profile_)->extension_service();
188
189     AddTestExtension(extension_service_, FPL("example1"));
190     AddTestExtension(extension_service_, FPL("example2"));
191
192     RegisterSyncableFileSystem();
193
194     fake_drive_service_ = new FakeDriveService;
195     DriveUploaderInterface* drive_uploader = new DriveUploader(
196         fake_drive_service_, base::MessageLoopProxy::current().get());
197
198     fake_drive_helper_.reset(new FakeDriveServiceHelper(
199         fake_drive_service_, drive_uploader,
200         APIUtil::GetSyncRootDirectoryName()));
201
202     api_util_ = APIUtil::CreateForTesting(
203         fake_drive_helper_->base_dir_path().AppendASCII("tmp"),
204         scoped_ptr<DriveServiceInterface>(fake_drive_service_),
205         scoped_ptr<DriveUploaderInterface>(drive_uploader)).Pass();
206     metadata_store_.reset(new DriveMetadataStore(
207         fake_drive_helper_->base_dir_path(),
208         base::MessageLoopProxy::current().get()));
209
210     bool done = false;
211     metadata_store_->Initialize(base::Bind(&DidInitialize, &done));
212     base::RunLoop().RunUntilIdle();
213     EXPECT_TRUE(done);
214
215     // Setup the sync root directory.
216     EXPECT_EQ(google_apis::HTTP_CREATED,
217               fake_drive_helper_->AddOrphanedFolder(
218                   APIUtil::GetSyncRootDirectoryName(),
219                   &sync_root_resource_id_));
220     metadata_store()->SetSyncRootDirectory(sync_root_resource_id_);
221   }
222
223   void SetUpDriveSyncService(bool enabled) {
224     sync_service_ = DriveFileSyncService::CreateForTesting(
225         profile_,
226         fake_drive_helper_->base_dir_path(),
227         api_util_.PassAs<APIUtilInterface>(),
228         metadata_store_.Pass()).Pass();
229     sync_service_->AddFileStatusObserver(&mock_file_status_observer_);
230     sync_service_->SetRemoteChangeProcessor(mock_remote_processor());
231     sync_service_->SetSyncEnabled(enabled);
232     base::RunLoop().RunUntilIdle();
233   }
234
235   virtual void TearDown() OVERRIDE {
236     if (sync_service_) {
237       sync_service_.reset();
238     }
239
240     metadata_store_.reset();
241     api_util_.reset();
242     fake_drive_service_ = NULL;
243
244     RevokeSyncableFileSystem();
245
246     extension_service_ = NULL;
247     profile_ = NULL;
248     profile_manager_.DeleteTestingProfile(kTestProfileName);
249     base::RunLoop().RunUntilIdle();
250   }
251
252  protected:
253   void EnableExtension(const std::string& extension_id) {
254     extension_service_->EnableExtension(extension_id);
255   }
256
257   void DisableExtension(const std::string& extension_id) {
258     extension_service_->DisableExtension(
259         extension_id, extensions::Extension::DISABLE_NONE);
260   }
261
262   void UninstallExtension(const std::string& extension_id) {
263     // Call UnloadExtension instead of UninstallExtension since it does
264     // unnecessary cleanup (e.g. deleting extension data) and emits warnings.
265     extension_service_->UnloadExtension(
266         extension_id, extensions::UnloadedExtensionInfo::REASON_UNINSTALL);
267   }
268
269   void UpdateRegisteredOrigins() {
270     sync_service_->UpdateRegisteredOrigins();
271     // Wait for completion of uninstalling origin.
272     base::RunLoop().RunUntilIdle();
273   }
274
275   void VerifySizeOfRegisteredOrigins(size_t b_size,
276                                      size_t i_size,
277                                      size_t d_size) {
278     EXPECT_EQ(b_size, pending_batch_sync_origins()->size());
279     EXPECT_EQ(i_size, metadata_store()->incremental_sync_origins().size());
280     EXPECT_EQ(d_size, metadata_store()->disabled_origins().size());
281   }
282
283   DriveMetadataStore* metadata_store() {
284     if (metadata_store_)
285       return metadata_store_.get();
286     return sync_service_->metadata_store_.get();
287   }
288
289   FakeDriveService* fake_drive_service() {
290     return fake_drive_service_;
291   }
292
293   StrictMock<MockFileStatusObserver>* mock_file_status_observer() {
294     return &mock_file_status_observer_;
295   }
296
297   StrictMock<MockRemoteChangeProcessor>* mock_remote_processor() {
298     return &mock_remote_processor_;
299   }
300
301   DriveFileSyncService* sync_service() { return sync_service_.get(); }
302   std::map<GURL, std::string>* pending_batch_sync_origins() {
303     return &(sync_service()->pending_batch_sync_origins_);
304   }
305
306   const RemoteChangeHandler& remote_change_handler() const {
307     return sync_service_->remote_change_handler_;
308   }
309
310   fileapi::FileSystemURL CreateURL(const GURL& origin,
311                                    const std::string& filename) {
312     return CreateSyncableFileSystemURL(
313         origin, base::FilePath::FromUTF8Unsafe(filename));
314   }
315
316   void ProcessRemoteChange(SyncStatusCode expected_status,
317                            const fileapi::FileSystemURL& expected_url,
318                            SyncFileStatus expected_sync_file_status,
319                            SyncAction expected_sync_action,
320                            SyncDirection expected_sync_direction) {
321     SyncStatusCode actual_status = SYNC_STATUS_UNKNOWN;
322     fileapi::FileSystemURL actual_url;
323
324     if (expected_sync_file_status != SYNC_FILE_STATUS_UNKNOWN) {
325       EXPECT_CALL(*mock_file_status_observer(),
326                   OnFileStatusChanged(expected_url,
327                                       expected_sync_file_status,
328                                       expected_sync_action,
329                                       expected_sync_direction))
330           .Times(1);
331     }
332
333     sync_service_->ProcessRemoteChange(
334         CreateResultReceiver(&actual_status, &actual_url));
335     base::RunLoop().RunUntilIdle();
336
337     EXPECT_EQ(expected_status, actual_status);
338     EXPECT_EQ(expected_url, actual_url);
339   }
340
341   bool AppendIncrementalRemoteChangeByResourceId(
342       const std::string& resource_id,
343       const GURL& origin) {
344     scoped_ptr<ResourceEntry> entry;
345     EXPECT_EQ(google_apis::HTTP_SUCCESS,
346               fake_drive_helper_->GetResourceEntry(resource_id, &entry));
347     return sync_service_->AppendRemoteChange(origin, *entry, 12345);
348   }
349
350   bool AppendIncrementalRemoteChange(
351       const GURL& origin,
352       const base::FilePath& path,
353       bool is_deleted,
354       const std::string& resource_id,
355       int64 changestamp,
356       const std::string& remote_file_md5) {
357     return sync_service_->AppendRemoteChangeInternal(
358         origin, path, is_deleted, resource_id,
359         changestamp, remote_file_md5, base::Time(),
360         SYNC_FILE_TYPE_FILE);
361   }
362
363   std::string SetUpOriginRootDirectory(const char* extension_name) {
364     EXPECT_TRUE(!sync_root_resource_id_.empty());
365
366     std::string origin_root_resource_id;
367     EXPECT_EQ(google_apis::HTTP_CREATED,
368               fake_drive_helper_->AddFolder(
369                   sync_root_resource_id_,
370                   ExtensionNameToId(extension_name),
371                   &origin_root_resource_id));
372
373     metadata_store()->AddIncrementalSyncOrigin(
374         ExtensionNameToGURL(extension_name), origin_root_resource_id);
375     return origin_root_resource_id;
376   }
377
378   void AddNewFile(const GURL& origin,
379                   const std::string& parent_resource_id,
380                   const std::string& title,
381                   const std::string& content,
382                   scoped_ptr<google_apis::ResourceEntry>* entry) {
383     std::string file_id;
384     ASSERT_EQ(google_apis::HTTP_SUCCESS,
385               fake_drive_helper_->AddFile(
386                   parent_resource_id, title, content, &file_id));
387     ASSERT_EQ(google_apis::HTTP_SUCCESS,
388               fake_drive_helper_->GetResourceEntry(
389                   file_id, entry));
390
391     DriveMetadata metadata;
392     metadata.set_resource_id(file_id);
393     metadata.set_md5_checksum((*entry)->file_md5());
394     metadata.set_conflicted(false);
395     metadata.set_to_be_fetched(false);
396     metadata.set_type(DriveMetadata::RESOURCE_TYPE_FILE);
397
398     SyncStatusCode status = SYNC_STATUS_UNKNOWN;
399     metadata_store()->UpdateEntry(
400         CreateURL(origin, title), metadata,
401         CreateResultReceiver(&status));
402     base::RunLoop().RunUntilIdle();
403     ASSERT_EQ(SYNC_STATUS_OK, status);
404   }
405
406   void TestRegisterNewOrigin();
407   void TestRegisterExistingOrigin();
408   void TestRegisterOriginWithSyncDisabled();
409   void TestUninstallOrigin();
410   void TestUpdateRegisteredOrigins();
411   void TestRemoteChange_NoChange();
412   void TestRemoteChange_Busy();
413   void TestRemoteChange_NewFile();
414   void TestRemoteChange_UpdateFile();
415   void TestRemoteChange_Override();
416   void TestRemoteChange_Folder();
417   void TestGetRemoteVersions();
418
419  private:
420   content::TestBrowserThreadBundle thread_bundle_;
421
422   TestingProfileManager profile_manager_;
423   TestingProfile* profile_;
424
425   std::string sync_root_resource_id_;
426
427 #if defined OS_CHROMEOS
428   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
429   chromeos::ScopedTestCrosSettings test_cros_settings_;
430   chromeos::ScopedTestUserManager test_user_manager_;
431 #endif
432
433   scoped_ptr<DriveFileSyncService> sync_service_;
434
435   // Not owned.
436   ExtensionService* extension_service_;
437
438   FakeDriveService* fake_drive_service_;
439   scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
440
441   StrictMock<MockFileStatusObserver> mock_file_status_observer_;
442   StrictMock<MockRemoteChangeProcessor> mock_remote_processor_;
443
444   scoped_ptr<APIUtil> api_util_;
445   scoped_ptr<DriveMetadataStore> metadata_store_;
446
447   DISALLOW_COPY_AND_ASSIGN(DriveFileSyncServiceFakeTest);
448 };
449
450 #if !defined(OS_ANDROID)
451
452 void DriveFileSyncServiceFakeTest::TestRegisterNewOrigin() {
453   SetUpDriveSyncService(true);
454   SyncStatusCode status = SYNC_STATUS_UNKNOWN;
455   sync_service()->RegisterOrigin(
456       ExtensionNameToGURL(kExtensionName1),
457       CreateResultReceiver(&status));
458   base::RunLoop().RunUntilIdle();
459   EXPECT_EQ(SYNC_STATUS_OK, status);
460
461   VerifySizeOfRegisteredOrigins(0u, 1u, 0u);
462   EXPECT_TRUE(!remote_change_handler().HasChanges());
463 }
464
465 void DriveFileSyncServiceFakeTest::TestRegisterExistingOrigin() {
466   const std::string origin_resource_id =
467       SetUpOriginRootDirectory(kExtensionName1);
468
469   std::string file_id;
470   EXPECT_EQ(google_apis::HTTP_SUCCESS,
471             fake_drive_helper_->AddFile(
472                 origin_resource_id, "1.txt", "data1", &file_id));
473   EXPECT_EQ(google_apis::HTTP_SUCCESS,
474             fake_drive_helper_->AddFile(
475                 origin_resource_id, "2.txt", "data2", &file_id));
476   EXPECT_EQ(google_apis::HTTP_SUCCESS,
477             fake_drive_helper_->AddFile(
478                 origin_resource_id, "3.txt", "data3", &file_id));
479
480   SetUpDriveSyncService(true);
481
482   SyncStatusCode status = SYNC_STATUS_UNKNOWN;
483   sync_service()->RegisterOrigin(
484       ExtensionNameToGURL(kExtensionName1),
485       CreateResultReceiver(&status));
486   base::RunLoop().RunUntilIdle();
487   EXPECT_EQ(SYNC_STATUS_OK, status);
488
489   // The origin should be registered as an incremental sync origin.
490   VerifySizeOfRegisteredOrigins(0u, 1u, 0u);
491
492   // There are 3 items to sync.
493   EXPECT_EQ(3u, remote_change_handler().ChangesSize());
494 }
495
496 void DriveFileSyncServiceFakeTest::TestRegisterOriginWithSyncDisabled() {
497   // Usually the sync service starts here, but since we're setting up a drive
498   // service with sync disabled sync doesn't start (while register origin should
499   // still return OK).
500   SetUpDriveSyncService(false);
501
502   SyncStatusCode status = SYNC_STATUS_UNKNOWN;
503   sync_service()->RegisterOrigin(
504       ExtensionNameToGURL(kExtensionName1),
505       CreateResultReceiver(&status));
506   base::RunLoop().RunUntilIdle();
507   EXPECT_EQ(SYNC_STATUS_OK, status);
508
509   // We must not have started batch sync for the newly registered origin,
510   // so it should still be in the batch_sync_origins.
511   VerifySizeOfRegisteredOrigins(1u, 0u, 0u);
512   EXPECT_TRUE(!remote_change_handler().HasChanges());
513 }
514
515 void DriveFileSyncServiceFakeTest::TestUninstallOrigin() {
516   SetUpOriginRootDirectory(kExtensionName1);
517   SetUpOriginRootDirectory(kExtensionName2);
518
519   SetUpDriveSyncService(true);
520
521   VerifySizeOfRegisteredOrigins(0u, 2u, 0u);
522   EXPECT_EQ(0u, remote_change_handler().ChangesSize());
523
524   SyncStatusCode status = SYNC_STATUS_UNKNOWN;
525   sync_service()->UninstallOrigin(
526       ExtensionNameToGURL(kExtensionName1),
527       RemoteFileSyncService::UNINSTALL_AND_PURGE_REMOTE,
528       CreateResultReceiver(&status));
529   base::RunLoop().RunUntilIdle();
530   EXPECT_EQ(SYNC_STATUS_OK, status);
531
532   VerifySizeOfRegisteredOrigins(0u, 1u, 0u);
533   EXPECT_TRUE(!remote_change_handler().HasChanges());
534 }
535
536 void DriveFileSyncServiceFakeTest::TestUpdateRegisteredOrigins() {
537   SetUpOriginRootDirectory(kExtensionName1);
538   SetUpOriginRootDirectory(kExtensionName2);
539   SetUpDriveSyncService(true);
540
541   // [1] Both extensions and origins are enabled. Nothing to do.
542   VerifySizeOfRegisteredOrigins(0u, 2u, 0u);
543   UpdateRegisteredOrigins();
544   VerifySizeOfRegisteredOrigins(0u, 2u, 0u);
545
546   // [2] Extension 1 should move to disabled list.
547   DisableExtension(ExtensionNameToId(kExtensionName1));
548   UpdateRegisteredOrigins();
549   VerifySizeOfRegisteredOrigins(0u, 1u, 1u);
550
551   // [3] Make sure that state remains the same, nothing should change.
552   UpdateRegisteredOrigins();
553   VerifySizeOfRegisteredOrigins(0u, 1u, 1u);
554
555   // [4] Uninstall Extension 2.
556   UninstallExtension(ExtensionNameToId(kExtensionName2));
557   UpdateRegisteredOrigins();
558   VerifySizeOfRegisteredOrigins(0u, 0u, 1u);
559
560   // [5] Re-enable Extension 1. It moves back to batch and not to incremental.
561   EnableExtension(ExtensionNameToId(kExtensionName1));
562   UpdateRegisteredOrigins();
563   VerifySizeOfRegisteredOrigins(1u, 0u, 0u);
564 }
565
566 void DriveFileSyncServiceFakeTest::TestRemoteChange_NoChange() {
567   SetUpDriveSyncService(true);
568
569   ProcessRemoteChange(SYNC_STATUS_NO_CHANGE_TO_SYNC,
570                       fileapi::FileSystemURL(),
571                       SYNC_FILE_STATUS_UNKNOWN,
572                       SYNC_ACTION_NONE,
573                       SYNC_DIRECTION_NONE);
574   VerifySizeOfRegisteredOrigins(0u, 0u, 0u);
575   EXPECT_TRUE(!remote_change_handler().HasChanges());
576 }
577
578 void DriveFileSyncServiceFakeTest::TestRemoteChange_Busy() {
579   const char kFileName[] = "File 1.txt";
580   const GURL origin = ExtensionNameToGURL(kExtensionName1);
581
582   const std::string origin_resource_id =
583       SetUpOriginRootDirectory(kExtensionName1);
584
585   EXPECT_CALL(*mock_remote_processor(),
586               PrepareForProcessRemoteChange(CreateURL(origin, kFileName), _))
587       .WillOnce(PrepareForRemoteChange_Busy());
588   EXPECT_CALL(*mock_remote_processor(),
589               FinalizeRemoteSync(CreateURL(origin, kFileName), _, _))
590       .WillOnce(InvokeCompletionCallback());
591
592   SetUpDriveSyncService(true);
593
594   std::string resource_id;
595   EXPECT_EQ(google_apis::HTTP_SUCCESS,
596             fake_drive_helper_->AddFile(
597                 origin_resource_id, kFileName, "test data", &resource_id));
598   EXPECT_TRUE(AppendIncrementalRemoteChangeByResourceId(resource_id, origin));
599
600   ProcessRemoteChange(SYNC_STATUS_FILE_BUSY,
601                       CreateURL(origin, kFileName),
602                       SYNC_FILE_STATUS_UNKNOWN,
603                       SYNC_ACTION_NONE,
604                       SYNC_DIRECTION_NONE);
605 }
606
607 void DriveFileSyncServiceFakeTest::TestRemoteChange_NewFile() {
608   const char kFileName[] = "File 1.txt";
609   const GURL origin = ExtensionNameToGURL(kExtensionName1);
610
611   const std::string origin_resource_id =
612       SetUpOriginRootDirectory(kExtensionName1);
613
614   EXPECT_CALL(*mock_remote_processor(),
615               PrepareForProcessRemoteChange(CreateURL(origin, kFileName), _))
616       .WillOnce(PrepareForRemoteChange_NotFound());
617   EXPECT_CALL(*mock_remote_processor(),
618               FinalizeRemoteSync(CreateURL(origin, kFileName), _, _))
619       .WillOnce(InvokeCompletionCallback());
620
621   EXPECT_CALL(*mock_remote_processor(),
622               ApplyRemoteChange(_, _, CreateURL(origin, kFileName), _))
623       .WillOnce(InvokeDidApplyRemoteChange());
624
625   SetUpDriveSyncService(true);
626
627   std::string resource_id;
628   EXPECT_EQ(google_apis::HTTP_SUCCESS,
629             fake_drive_helper_->AddFile(
630                 origin_resource_id, kFileName, "test data", &resource_id));
631   EXPECT_TRUE(AppendIncrementalRemoteChangeByResourceId(resource_id, origin));
632
633   ProcessRemoteChange(SYNC_STATUS_OK,
634                       CreateURL(origin, kFileName),
635                       SYNC_FILE_STATUS_SYNCED,
636                       SYNC_ACTION_ADDED,
637                       SYNC_DIRECTION_REMOTE_TO_LOCAL);
638 }
639
640 void DriveFileSyncServiceFakeTest::TestRemoteChange_UpdateFile() {
641   const char kFileName[] = "File 1.txt";
642   const GURL origin = ExtensionNameToGURL(kExtensionName1);
643
644   const std::string origin_resource_id =
645       SetUpOriginRootDirectory(kExtensionName1);
646
647   EXPECT_CALL(*mock_remote_processor(),
648               PrepareForProcessRemoteChange(CreateURL(origin, kFileName), _))
649       .WillOnce(PrepareForRemoteChange_NotModified());
650   EXPECT_CALL(*mock_remote_processor(),
651               FinalizeRemoteSync(CreateURL(origin, kFileName), _, _))
652       .WillOnce(InvokeCompletionCallback());
653
654   EXPECT_CALL(*mock_remote_processor(),
655               ApplyRemoteChange(_, _, CreateURL(origin, kFileName), _))
656       .WillOnce(InvokeDidApplyRemoteChange());
657
658   SetUpDriveSyncService(true);
659
660   std::string resource_id;
661   EXPECT_EQ(google_apis::HTTP_SUCCESS,
662             fake_drive_helper_->AddFile(
663                 origin_resource_id, kFileName, "test data", &resource_id));
664   EXPECT_TRUE(AppendIncrementalRemoteChangeByResourceId(resource_id, origin));
665
666   ProcessRemoteChange(SYNC_STATUS_OK,
667                       CreateURL(origin, kFileName),
668                       SYNC_FILE_STATUS_SYNCED,
669                       SYNC_ACTION_UPDATED,
670                       SYNC_DIRECTION_REMOTE_TO_LOCAL);
671 }
672
673 void DriveFileSyncServiceFakeTest::TestRemoteChange_Override() {
674   const base::FilePath kFilePath(FPL("File 1.txt"));
675   const std::string kFileResourceId("file:2_file_resource_id");
676   const std::string kFileResourceId2("file:2_file_resource_id_2");
677   const GURL origin = ExtensionNameToGURL(kExtensionName1);
678
679   SetUpOriginRootDirectory(kExtensionName1);
680   SetUpDriveSyncService(true);
681
682   EXPECT_TRUE(AppendIncrementalRemoteChange(
683       origin, kFilePath, false /* is_deleted */,
684       kFileResourceId, 2, "remote_file_md5"));
685
686   // Expect to drop this change since there is another newer change on the
687   // queue.
688   EXPECT_FALSE(AppendIncrementalRemoteChange(
689       origin, kFilePath, false /* is_deleted */,
690       kFileResourceId, 1, "remote_file_md5_2"));
691
692   // Expect to drop this change since it has the same md5 with the previous one.
693   EXPECT_FALSE(AppendIncrementalRemoteChange(
694       origin, kFilePath, false /* is_deleted */,
695       kFileResourceId, 4, "remote_file_md5"));
696
697   // This should not cause browser crash.
698   EXPECT_FALSE(AppendIncrementalRemoteChange(
699       origin, kFilePath, false /* is_deleted */,
700       kFileResourceId, 4, "remote_file_md5"));
701
702   // Expect to drop these changes since they have different resource IDs with
703   // the previous ones.
704   EXPECT_FALSE(AppendIncrementalRemoteChange(
705       origin, kFilePath, false /* is_deleted */,
706       kFileResourceId2, 5, "updated_file_md5"));
707   EXPECT_FALSE(AppendIncrementalRemoteChange(
708       origin, kFilePath, true /* is_deleted */,
709       kFileResourceId2, 5, "deleted_file_md5"));
710
711   // Push delete change.
712   EXPECT_TRUE(AppendIncrementalRemoteChange(
713       origin, kFilePath, true /* is_deleted */,
714       kFileResourceId, 6, "deleted_file_md5"));
715
716   // Expect to drop this delete change since it has a different resource ID with
717   // the previous one.
718   EXPECT_FALSE(AppendIncrementalRemoteChange(
719       origin, kFilePath, true /* is_deleted */,
720       kFileResourceId2, 7, "deleted_file_md5"));
721
722   // Expect not to drop this change even if it has a different resource ID with
723   // the previous one.
724   EXPECT_TRUE(AppendIncrementalRemoteChange(
725       origin, kFilePath, false /* is_deleted */,
726       kFileResourceId2, 8, "updated_file_md5"));
727 }
728
729 void DriveFileSyncServiceFakeTest::TestRemoteChange_Folder() {
730   const std::string origin_resource_id =
731       SetUpOriginRootDirectory(kExtensionName1);
732   SetUpDriveSyncService(true);
733
734   std::string resource_id;
735   EXPECT_EQ(google_apis::HTTP_CREATED,
736             fake_drive_helper_->AddFolder(
737                 origin_resource_id, "test_dir", &resource_id));
738
739   // Expect to drop this change for file.
740   EXPECT_FALSE(AppendIncrementalRemoteChangeByResourceId(
741       resource_id, ExtensionNameToGURL(kExtensionName1)));
742 }
743
744 void DriveFileSyncServiceFakeTest::TestGetRemoteVersions() {
745   SetUpDriveSyncService(true);
746   const std::string origin_resource_id =
747       SetUpOriginRootDirectory(kExtensionName1);
748
749   const GURL origin(ExtensionNameToGURL(kExtensionName1));
750   const std::string title("file");
751   const std::string content("data1");
752   const fileapi::FileSystemURL& url(CreateURL(origin, title));
753
754   scoped_ptr<google_apis::ResourceEntry> entry;
755   AddNewFile(origin, origin_resource_id, title, content, &entry);
756
757   SyncStatusCode status = SYNC_STATUS_FAILED;
758   std::vector<RemoteFileSyncService::Version> versions;
759   sync_service_->GetRemoteVersions(
760       url, CreateResultReceiver(&status, &versions));
761   base::RunLoop().RunUntilIdle();
762
763   ASSERT_EQ(SYNC_STATUS_OK, status);
764   ASSERT_FALSE(versions.empty());
765   EXPECT_EQ(1u, versions.size());
766   EXPECT_EQ(static_cast<int64>(content.length()), versions[0].metadata.size);
767   EXPECT_EQ(entry->file_size(), versions[0].metadata.size);
768   EXPECT_EQ(entry->updated_time(), versions[0].metadata.last_modified);
769
770   status = SYNC_STATUS_FAILED;
771   webkit_blob::ScopedFile downloaded;
772   sync_service_->DownloadRemoteVersion(
773       url, versions[0].id, CreateResultReceiver(&status, &downloaded));
774   base::RunLoop().RunUntilIdle();
775
776   ASSERT_EQ(SYNC_STATUS_OK, status);
777
778   std::string downloaded_content;
779   EXPECT_TRUE(base::ReadFileToString(downloaded.path(), &downloaded_content));
780   EXPECT_EQ(content, downloaded_content);
781 }
782
783 TEST_F(DriveFileSyncServiceFakeTest, RegisterNewOrigin) {
784   ASSERT_FALSE(IsDriveAPIDisabled());
785   TestRegisterNewOrigin();
786 }
787
788 TEST_F(DriveFileSyncServiceFakeTest, RegisterNewOrigin_WAPI) {
789   ScopedDisableDriveAPI disable_drive_api;
790   TestRegisterNewOrigin();
791 }
792
793 TEST_F(DriveFileSyncServiceFakeTest, RegisterExistingOrigin) {
794   ASSERT_FALSE(IsDriveAPIDisabled());
795   TestRegisterExistingOrigin();
796 }
797
798 TEST_F(DriveFileSyncServiceFakeTest, RegisterExistingOrigin_WAPI) {
799   ScopedDisableDriveAPI disable_drive_api;
800   TestRegisterExistingOrigin();
801 }
802
803 TEST_F(DriveFileSyncServiceFakeTest, RegisterOriginWithSyncDisabled) {
804   ASSERT_FALSE(IsDriveAPIDisabled());
805   TestRegisterOriginWithSyncDisabled();
806 }
807
808 TEST_F(DriveFileSyncServiceFakeTest, RegisterOriginWithSyncDisabled_WAPI) {
809   ScopedDisableDriveAPI disable_drive_api;
810   TestRegisterOriginWithSyncDisabled();
811 }
812
813 TEST_F(DriveFileSyncServiceFakeTest, UninstallOrigin) {
814   ASSERT_FALSE(IsDriveAPIDisabled());
815   TestUninstallOrigin();
816 }
817
818 TEST_F(DriveFileSyncServiceFakeTest, UninstallOrigin_WAPI) {
819   ScopedDisableDriveAPI disable_drive_api;
820   TestUninstallOrigin();
821 }
822
823 TEST_F(DriveFileSyncServiceFakeTest, UpdateRegisteredOrigins) {
824   ASSERT_FALSE(IsDriveAPIDisabled());
825   TestUpdateRegisteredOrigins();
826 }
827
828 TEST_F(DriveFileSyncServiceFakeTest, UpdateRegisteredOrigins_WAPI) {
829   ScopedDisableDriveAPI disable_drive_api;
830   TestUpdateRegisteredOrigins();
831 }
832
833 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_NoChange) {
834   ASSERT_FALSE(IsDriveAPIDisabled());
835   TestRemoteChange_NoChange();
836 }
837
838 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_NoChange_WAPI) {
839   ScopedDisableDriveAPI disable_drive_api;
840   TestRemoteChange_NoChange();
841 }
842
843 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_Busy) {
844   ASSERT_FALSE(IsDriveAPIDisabled());
845   TestRemoteChange_Busy();
846 }
847
848 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_Busy_WAPI) {
849   ScopedDisableDriveAPI disable_drive_api;
850   TestRemoteChange_Busy();
851 }
852
853 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_NewFile) {
854   ASSERT_FALSE(IsDriveAPIDisabled());
855   TestRemoteChange_NewFile();
856 }
857
858 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_NewFile_WAPI) {
859   ScopedDisableDriveAPI disable_drive_api;
860   TestRemoteChange_NewFile();
861 }
862
863 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_UpdateFile) {
864   ASSERT_FALSE(IsDriveAPIDisabled());
865   TestRemoteChange_UpdateFile();
866 }
867
868 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_UpdateFile_WAPI) {
869   ScopedDisableDriveAPI disable_drive_api;
870   TestRemoteChange_UpdateFile();
871 }
872
873 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_Override) {
874   ASSERT_FALSE(IsDriveAPIDisabled());
875   TestRemoteChange_Override();
876 }
877
878 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_Override_WAPI) {
879   ScopedDisableDriveAPI disable_drive_api;
880   TestRemoteChange_Override();
881 }
882
883 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_Folder) {
884   ASSERT_FALSE(IsDriveAPIDisabled());
885   TestRemoteChange_Folder();
886 }
887
888 TEST_F(DriveFileSyncServiceFakeTest, RemoteChange_Folder_WAPI) {
889   ScopedDisableDriveAPI disable_drive_api;
890   TestRemoteChange_Folder();
891 }
892
893 TEST_F(DriveFileSyncServiceFakeTest, GetRemoteVersions) {
894   ASSERT_FALSE(IsDriveAPIDisabled());
895   TestGetRemoteVersions();
896 }
897
898 TEST_F(DriveFileSyncServiceFakeTest, GetRemoteVersions_WAPI) {
899   ScopedDisableDriveAPI disable_drive_api;
900   TestGetRemoteVersions();
901 }
902
903 #endif  // !defined(OS_ANDROID)
904
905 }  // namespace sync_file_system