1 // Copyright (c) 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/sync_file_system/fake_remote_change_processor.h"
8 #include "base/files/file_path.h"
9 #include "base/location.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "chrome/browser/sync_file_system/file_change.h"
12 #include "chrome/browser/sync_file_system/sync_file_metadata.h"
13 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "webkit/browser/fileapi/file_system_url.h"
16 #include "webkit/common/fileapi/file_system_util.h"
18 namespace sync_file_system
{
20 FakeRemoteChangeProcessor::FakeRemoteChangeProcessor() {
23 FakeRemoteChangeProcessor::~FakeRemoteChangeProcessor() {
26 void FakeRemoteChangeProcessor::PrepareForProcessRemoteChange(
27 const fileapi::FileSystemURL
& url
,
28 const PrepareChangeCallback
& callback
) {
29 SyncFileMetadata local_metadata
;
31 if (fileapi::VirtualPath::IsRootPath(url
.path())) {
32 // Origin root directory case.
33 local_metadata
= SyncFileMetadata(
34 SYNC_FILE_TYPE_DIRECTORY
, 0, base::Time::Now());
37 URLToFileMetadata::iterator found_metadata
= local_file_metadata_
.find(url
);
38 if (found_metadata
!= local_file_metadata_
.end())
39 local_metadata
= found_metadata
->second
;
41 // Override |local_metadata| by applied changes.
42 URLToFileChangesMap::iterator found
= applied_changes_
.find(url
);
43 if (found
!= applied_changes_
.end()) {
44 DCHECK(!found
->second
.empty());
45 const FileChange
& applied_change
= found
->second
.back();
46 if (applied_change
.IsAddOrUpdate()) {
47 local_metadata
= SyncFileMetadata(
48 applied_change
.file_type(),
54 FileChangeList change_list
;
55 URLToFileChangeList::iterator found_list
= local_changes_
.find(url
);
56 if (found_list
!= local_changes_
.end())
57 change_list
= found_list
->second
;
59 base::MessageLoopProxy::current()->PostTask(
61 base::Bind(callback
, SYNC_STATUS_OK
,
62 local_metadata
, change_list
));
65 void FakeRemoteChangeProcessor::ApplyRemoteChange(
66 const FileChange
& change
,
67 const base::FilePath
& local_path
,
68 const fileapi::FileSystemURL
& url
,
69 const SyncStatusCallback
& callback
) {
70 SyncStatusCode status
= SYNC_STATUS_UNKNOWN
;
71 base::FilePath ancestor
= fileapi::VirtualPath::DirName(url
.path());
73 fileapi::FileSystemURL ancestor_url
=
74 CreateSyncableFileSystemURL(url
.origin(), ancestor
);
75 if (!ancestor_url
.is_valid())
78 URLToFileChangeList::iterator found_list
=
79 local_changes_
.find(ancestor_url
);
80 if (found_list
!= local_changes_
.end()) {
81 const FileChange
& local_change
= found_list
->second
.back();
82 if (local_change
.IsAddOrUpdate() &&
83 local_change
.file_type() != SYNC_FILE_TYPE_DIRECTORY
) {
84 status
= SYNC_FILE_ERROR_NOT_A_DIRECTORY
;
89 base::FilePath ancestor_parent
= fileapi::VirtualPath::DirName(ancestor
);
90 if (ancestor
== ancestor_parent
)
92 ancestor
= ancestor_parent
;
94 if (status
== SYNC_STATUS_UNKNOWN
) {
95 applied_changes_
[url
].push_back(change
);
96 status
= SYNC_STATUS_OK
;
98 base::MessageLoopProxy::current()->PostTask(
99 FROM_HERE
, base::Bind(callback
, status
));
102 void FakeRemoteChangeProcessor::FinalizeRemoteSync(
103 const fileapi::FileSystemURL
& url
,
104 bool clear_local_changes
,
105 const base::Closure
& completion_callback
) {
106 base::MessageLoopProxy::current()->PostTask(FROM_HERE
, completion_callback
);
109 void FakeRemoteChangeProcessor::RecordFakeLocalChange(
110 const fileapi::FileSystemURL
& url
,
111 const FileChange
& change
,
112 const SyncStatusCallback
& callback
) {
113 local_changes_
[url
].Update(change
);
114 base::MessageLoopProxy::current()->PostTask(
115 FROM_HERE
, base::Bind(callback
, SYNC_STATUS_OK
));
118 void FakeRemoteChangeProcessor::UpdateLocalFileMetadata(
119 const fileapi::FileSystemURL
& url
,
120 const FileChange
& change
) {
121 if (change
.IsAddOrUpdate()) {
122 local_file_metadata_
[url
] = SyncFileMetadata(
123 change
.file_type(), 100 /* size */, base::Time::Now());
125 local_file_metadata_
.erase(url
);
127 local_changes_
[url
].Update(change
);
130 void FakeRemoteChangeProcessor::ClearLocalChanges(
131 const fileapi::FileSystemURL
& url
) {
132 local_changes_
.erase(url
);
135 const FakeRemoteChangeProcessor::URLToFileChangesMap
&
136 FakeRemoteChangeProcessor::GetAppliedRemoteChanges() const {
137 return applied_changes_
;
140 void FakeRemoteChangeProcessor::VerifyConsistency(
141 const URLToFileChangesMap
& expected_changes
) {
142 EXPECT_EQ(expected_changes
.size(), applied_changes_
.size());
143 for (URLToFileChangesMap::const_iterator itr
= applied_changes_
.begin();
144 itr
!= applied_changes_
.end(); ++itr
) {
145 const fileapi::FileSystemURL
& url
= itr
->first
;
146 URLToFileChangesMap::const_iterator found
= expected_changes
.find(url
);
147 if (found
== expected_changes
.end()) {
148 EXPECT_TRUE(found
!= expected_changes
.end())
149 << "Change not expected for " << url
.DebugString();
153 const std::vector
<FileChange
>& applied
= itr
->second
;
154 const std::vector
<FileChange
>& expected
= found
->second
;
156 if (applied
.empty() || expected
.empty()) {
157 EXPECT_TRUE(!applied
.empty());
158 EXPECT_TRUE(!expected
.empty());
162 EXPECT_EQ(expected
.size(), applied
.size());
164 for (size_t i
= 0; i
< applied
.size() && i
< expected
.size(); ++i
) {
165 EXPECT_EQ(expected
[i
], applied
[i
])
167 << " expected:" << expected
[i
].DebugString()
168 << " applied:" << applied
[i
].DebugString();
173 } // namespace sync_file_system