1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/local_to_remote_syncer.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/bind.h"
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/callback.h"
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/files/scoped_temp_dir.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/logging.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/run_loop.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/thread_task_runner_handle.h"
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/drive/drive_api_util.h"
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/drive/drive_uploader.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/drive/fake_drive_service.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h"
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/drive_backend_test_util.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/fake_drive_service_helper.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/fake_drive_uploader.h"
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/list_changes_task.h"
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/metadata_database.h"
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/remote_to_local_syncer.h"
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/sync_engine_context.h"
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/sync_engine_initializer.h"
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h"
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/sync_task_token.h"
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/fake_remote_change_processor.h"
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h"
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/drive_api_parser.h"
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/drive/gdata_errorcode.h"
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/leveldatabase/src/include/leveldb/env.h"
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace sync_file_system {
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace drive_backend {
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)storage::FileSystemURL URL(const GURL& origin, const std::string& path) {
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return CreateSyncableFileSystemURL(
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      origin, base::FilePath::FromUTF8Unsafe(path));
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const int kRetryLimit = 100;
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass LocalToRemoteSyncerTest : public testing::Test {
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  LocalToRemoteSyncerTest()
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual ~LocalToRemoteSyncerTest() {}
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_TRUE(database_dir_.CreateUniqueTempDir());
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    in_memory_env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<FakeDriveServiceWrapper>
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        fake_drive_service(new FakeDriveServiceWrapper);
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<drive::DriveUploaderInterface>
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        drive_uploader(new FakeDriveUploader(fake_drive_service.get()));
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    fake_drive_helper_.reset(new FakeDriveServiceHelper(
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        fake_drive_service.get(),
68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        drive_uploader.get(),
69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        kSyncRootFolderTitle));
70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    remote_change_processor_.reset(new FakeRemoteChangeProcessor);
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    context_.reset(new SyncEngineContext(
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        fake_drive_service.PassAs<drive::DriveServiceInterface>(),
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        drive_uploader.Pass(),
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        NULL,
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::ThreadTaskRunnerHandle::Get(),
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::ThreadTaskRunnerHandle::Get()));
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    context_->SetRemoteChangeProcessor(remote_change_processor_.get());
79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    RegisterSyncableFileSystem();
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_.reset(new SyncTaskManager(
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        base::WeakPtr<SyncTaskManager::Client>(),
846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        10 /* maximum_background_task */,
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::ThreadTaskRunnerHandle::Get()));
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_->Initialize(SYNC_STATUS_OK);
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_.reset();
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    RevokeSyncableFileSystem();
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    fake_drive_helper_.reset();
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    context_.reset();
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void InitializeMetadataDatabase() {
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    SyncEngineInitializer* initializer =
99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        new SyncEngineInitializer(context_.get(),
100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                  database_dir_.path(),
101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                  in_memory_env_.get());
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_->ScheduleSyncTask(
105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        FROM_HERE,
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        scoped_ptr<SyncTask>(initializer),
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        SyncTaskManager::PRIORITY_MED,
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        base::Bind(&LocalToRemoteSyncerTest::DidInitializeMetadataDatabase,
109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                   base::Unretained(this), initializer, &status));
110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void DidInitializeMetadataDatabase(SyncEngineInitializer* initializer,
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                     SyncStatusCode* status_out,
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                     SyncStatusCode status) {
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    *status_out = status;
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    context_->SetMetadataDatabase(initializer->PassMetadataDatabase());
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void RegisterApp(const std::string& app_id,
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                   const std::string& app_root_folder_id) {
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SyncStatusCode status = context_->GetMetadataDatabase()->RegisterApp(
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        app_id, app_root_folder_id);
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_OK, status);
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MetadataDatabase* GetMetadataDatabase() {
130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return context_->GetMetadataDatabase();
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected:
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string CreateSyncRoot() {
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    std::string sync_root_folder_id;
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_CREATED,
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              fake_drive_helper_->AddOrphanedFolder(
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  kSyncRootFolderTitle, &sync_root_folder_id));
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return sync_root_folder_id;
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string CreateRemoteFolder(const std::string& parent_folder_id,
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 const std::string& title) {
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    std::string folder_id;
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_CREATED,
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              fake_drive_helper_->AddFolder(
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  parent_folder_id, title, &folder_id));
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return folder_id;
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string CreateRemoteFile(const std::string& parent_folder_id,
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               const std::string& title,
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                               const std::string& content) {
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    std::string file_id;
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_SUCCESS,
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              fake_drive_helper_->AddFile(
157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  parent_folder_id, title, content, &file_id));
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return file_id;
159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void DeleteResource(const std::string& file_id) {
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_NO_CONTENT,
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              fake_drive_helper_->DeleteResource(file_id));
164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SyncStatusCode RunLocalToRemoteSyncer(FileChange file_change,
16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                        const storage::FileSystemURL& url) {
168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::FilePath local_path = base::FilePath::FromUTF8Unsafe("dummy");
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    scoped_ptr<LocalToRemoteSyncer> syncer(new LocalToRemoteSyncer(
171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        context_.get(),
172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        SyncFileMetadata(file_change.file_type(), 0, base::Time()),
173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        file_change, local_path, url));
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    syncer->RunPreflight(SyncTaskToken::CreateForTesting(
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        CreateResultReceiver(&status)));
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return status;
178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SyncStatusCode ListChanges() {
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    sync_task_manager_->ScheduleSyncTask(
183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        FROM_HERE,
184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        scoped_ptr<SyncTask>(new ListChangesTask(context_.get())),
185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        SyncTaskManager::PRIORITY_MED,
186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        CreateResultReceiver(&status));
187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return status;
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SyncStatusCode RunRemoteToLocalSyncer() {
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SyncStatusCode status = SYNC_STATUS_UNKNOWN;
193effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    scoped_ptr<RemoteToLocalSyncer>
194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        syncer(new RemoteToLocalSyncer(context_.get()));
195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    syncer->RunPreflight(SyncTaskToken::CreateForTesting(
196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        CreateResultReceiver(&status)));
197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::RunLoop().RunUntilIdle();
198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return status;
199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SyncStatusCode RunRemoteToLocalSyncerUntilIdle() {
2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    SyncStatusCode status;
2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int retry_count = 0;
2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    do {
2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (retry_count++ > kRetryLimit)
2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        break;
2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      status = RunRemoteToLocalSyncer();
2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } while (status == SYNC_STATUS_OK ||
2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)             status == SYNC_STATUS_RETRY ||
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci             GetMetadataDatabase()->PromoteDemotedTrackers());
2116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC, status);
2126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return status;
2136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
2146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry>
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GetResourceEntriesForParentAndTitle(const std::string& parent_folder_id,
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                      const std::string& title) {
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ScopedVector<google_apis::ResourceEntry> entries;
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_SUCCESS,
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              fake_drive_helper_->SearchByTitle(
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  parent_folder_id, title, &entries));
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return entries.Pass();
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string GetFileIDForParentAndTitle(const std::string& parent_folder_id,
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                         const std::string& title) {
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ScopedVector<google_apis::ResourceEntry> entries =
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        GetResourceEntriesForParentAndTitle(parent_folder_id, title);
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (entries.size() != 1)
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return std::string();
231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return entries[0]->resource_id();
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void VerifyTitleUniqueness(
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const std::string& parent_folder_id,
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const std::string& title,
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      google_apis::ResourceEntry::ResourceEntryKind kind) {
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ScopedVector<google_apis::ResourceEntry> entries;
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_SUCCESS,
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              fake_drive_helper_->SearchByTitle(
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  parent_folder_id, title, &entries));
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_EQ(1u, entries.size());
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(kind, entries[0]->kind());
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void VerifyFileDeletion(const std::string& parent_folder_id,
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          const std::string& title) {
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ScopedVector<google_apis::ResourceEntry> entries;
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_EQ(google_apis::HTTP_SUCCESS,
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              fake_drive_helper_->SearchByTitle(
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                  parent_folder_id, title, &entries));
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    EXPECT_TRUE(entries.empty());
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private:
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  content::TestBrowserThreadBundle thread_bundle_;
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::ScopedTempDir database_dir_;
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<leveldb::Env> in_memory_env_;
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
260effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SyncEngineContext> context_;
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<FakeDriveServiceHelper> fake_drive_helper_;
262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<FakeRemoteChangeProcessor> remote_change_processor_;
263effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SyncTaskManager> sync_task_manager_;
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(LocalToRemoteSyncerTest);
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, CreateFile) {
269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "file1")));
279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_DIRECTORY),
282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder")));
283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder/file2")));
287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string folder_id = GetFileIDForParentAndTitle(app_root, "folder");
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(folder_id.empty());
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      app_root, "file1", google_apis::ResourceEntry::ENTRY_KIND_FILE);
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      app_root, "folder", google_apis::ResourceEntry::ENTRY_KIND_FOLDER);
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      folder_id, "file2", google_apis::ResourceEntry::ENTRY_KIND_FILE);
297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, CreateFileOnMissingPath) {
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Run the syncer 3 times to create missing folder1 and folder2.
307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_RETRY, RunLocalToRemoteSyncer(
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder1/folder2/file")));
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_RETRY, RunLocalToRemoteSyncer(
312a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder1/folder2/file")));
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder1/folder2/file")));
319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
320a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string folder_id1 = GetFileIDForParentAndTitle(app_root, "folder1");
321a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(folder_id1.empty());
322a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string folder_id2 = GetFileIDForParentAndTitle(folder_id1, "folder2");
323a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_FALSE(folder_id2.empty());
324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      app_root, "folder1", google_apis::ResourceEntry::ENTRY_KIND_FOLDER);
327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      folder_id1, "folder2", google_apis::ResourceEntry::ENTRY_KIND_FOLDER);
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      folder_id2, "file", google_apis::ResourceEntry::ENTRY_KIND_FILE);
331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
333a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, DeleteFile) {
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
335a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "file")));
344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_DIRECTORY),
347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder")));
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      app_root, "file", google_apis::ResourceEntry::ENTRY_KIND_FILE);
351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  VerifyTitleUniqueness(
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      app_root, "folder", google_apis::ResourceEntry::ENTRY_KIND_FOLDER);
353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_DELETE,
356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "file")));
358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_DELETE,
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_DIRECTORY),
361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "folder")));
362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyFileDeletion(app_root, "file");
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  VerifyFileDeletion(app_root, "folder");
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, Conflict_CreateFileOnFolder) {
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateRemoteFolder(app_root, "foo");
375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // There should exist both file and folder on remote.
382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry> entries =
383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetResourceEntriesForParentAndTitle(app_root, "foo");
384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2u, entries.size());
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FOLDER, entries[0]->kind());
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FILE, entries[1]->kind());
387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
389a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, Conflict_CreateFolderOnFile) {
390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
391a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateRemoteFile(app_root, "foo", "data");
397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_DIRECTORY),
402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // There should exist both file and folder on remote.
405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry> entries =
406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetResourceEntriesForParentAndTitle(app_root, "foo");
407a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2u, entries.size());
408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FILE, entries[0]->kind());
409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FOLDER, entries[1]->kind());
410a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, Conflict_CreateFileOnFile) {
413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
414a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
415a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
418a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CreateRemoteFile(app_root, "foo", "data");
420a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
424a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
426a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
427a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // There should exist both files on remote.
428a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry> entries =
429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetResourceEntriesForParentAndTitle(app_root, "foo");
430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2u, entries.size());
431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FILE, entries[0]->kind());
432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FILE, entries[1]->kind());
433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, Conflict_UpdateDeleteOnFile) {
436a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
437a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string file_id = CreateRemoteFile(app_root, "foo", "data");
443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC,
4456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            RunRemoteToLocalSyncerUntilIdle());
446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DeleteResource(file_id);
448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_FILE_BUSY, RunLocalToRemoteSyncer(
450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry> entries =
459a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetResourceEntriesForParentAndTitle(app_root, "foo");
460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1u, entries.size());
461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FILE, entries[0]->kind());
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(!entries[0]->deleted());
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_NE(file_id, entries[0]->resource_id());
464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
465a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, Conflict_CreateDeleteOnFile) {
467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string file_id = CreateRemoteFile(app_root, "foo", "data");
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
4756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC,
4766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            RunRemoteToLocalSyncerUntilIdle());
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DeleteResource(file_id);
479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_FILE),
485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry> entries =
488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetResourceEntriesForParentAndTitle(app_root, "foo");
489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(1u, entries.size());
490116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FILE, entries[0]->kind());
491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(!entries[0]->deleted());
492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_NE(file_id, entries[0]->resource_id());
493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, Conflict_CreateFolderOnFolder) {
496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string folder_id = CreateRemoteFolder(app_root, "foo");
503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, RunLocalToRemoteSyncer(
505a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
506a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_DIRECTORY),
507a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
508a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
509a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedVector<google_apis::ResourceEntry> entries =
510a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GetResourceEntriesForParentAndTitle(app_root, "foo");
511a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_EQ(2u, entries.size());
512116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FOLDER, entries[0]->kind());
513116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ(google_apis::ResourceEntry::ENTRY_KIND_FOLDER, entries[1]->kind());
514a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(!entries[0]->deleted());
515a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(!entries[1]->deleted());
516a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(folder_id == entries[0]->resource_id() ||
517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)              folder_id == entries[1]->resource_id());
518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TrackerIDSet trackers;
520a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(GetMetadataDatabase()->FindTrackersByFileID(
521a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      folder_id, &trackers));
522a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(1u, trackers.size());
523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(trackers.has_active());
524a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
525a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
526a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(LocalToRemoteSyncerTest, AppRootDeletion) {
527a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const GURL kOrigin("chrome-extension://example");
528a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string sync_root = CreateSyncRoot();
529a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const std::string app_root = CreateRemoteFolder(sync_root, kOrigin.host());
530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  InitializeMetadataDatabase();
531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RegisterApp(kOrigin.host(), app_root);
532a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DeleteResource(app_root);
534a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_OK, ListChanges());
5356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_NO_CHANGE_TO_SYNC,
5366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            RunRemoteToLocalSyncerUntilIdle());
537a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
538a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ(SYNC_STATUS_UNKNOWN_ORIGIN, RunLocalToRemoteSyncer(
539a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
540a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                 SYNC_FILE_TYPE_DIRECTORY),
541a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      URL(kOrigin, "foo")));
542a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
543a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // SyncEngine will re-register the app and resurrect the app root later.
544a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
545a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
546a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace drive_backend
547a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace sync_file_system
548