1 // Copyright 2014 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/extensions/api/file_system/entry_watcher_service.h"
10 #include "base/files/file.h"
11 #include "base/files/file_path.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/memory/scoped_vector.h"
14 #include "base/run_loop.h"
15 #include "chrome/common/extensions/api/file_system.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "content/public/test/test_browser_thread_bundle.h"
18 #include "content/public/test/test_file_system_context.h"
19 #include "extensions/browser/event_router.h"
20 #include "storage/browser/fileapi/file_system_url.h"
21 #include "storage/common/fileapi/file_system_types.h"
23 namespace extensions {
26 const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
28 void LogStatus(std::vector<base::File::Error>* log, base::File::Error status) {
29 log->push_back(status);
34 class EntryWatcherServiceTest : public testing::Test {
36 EntryWatcherServiceTest() {}
37 virtual ~EntryWatcherServiceTest() {}
39 virtual void SetUp() OVERRIDE {
40 profile_.reset(new TestingProfile);
41 ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
42 file_system_context_ =
43 content::CreateFileSystemContextForTesting(NULL, data_dir_.path());
44 service_.reset(new EntryWatcherService(profile_.get()));
45 service_->SetDispatchEventImplForTesting(base::Bind(
46 &EntryWatcherServiceTest::DispatchEventImpl, base::Unretained(this)));
47 service_->SetGetFileSystemContextImplForTesting(
48 base::Bind(&EntryWatcherServiceTest::GetFileSystemContextImpl,
49 base::Unretained(this)));
50 testing_url_ = file_system_context_->CreateCrackedFileSystemURL(
51 GURL(std::string("chrome-extension://") + kExtensionId),
52 storage::kFileSystemTypeTest,
53 base::FilePath::FromUTF8Unsafe("/x/y/z"));
56 virtual void TearDown() OVERRIDE {
57 dispatch_event_log_targets_.clear();
58 dispatch_event_log_events_.clear();
61 void DispatchEventImpl(const std::string& extension_id,
62 scoped_ptr<Event> event) {
63 dispatch_event_log_targets_.push_back(extension_id);
64 dispatch_event_log_events_.push_back(event.release());
67 storage::FileSystemContext* GetFileSystemContextImpl(
68 const std::string& extension_id,
69 content::BrowserContext* context) {
70 EXPECT_EQ(kExtensionId, extension_id);
71 EXPECT_EQ(profile_.get(), context);
72 return file_system_context_.get();
75 content::TestBrowserThreadBundle thread_bundle_;
76 scoped_ptr<TestingProfile> profile_;
77 base::ScopedTempDir data_dir_;
78 scoped_refptr<storage::FileSystemContext> file_system_context_;
79 scoped_ptr<EntryWatcherService> service_;
80 storage::FileSystemURL testing_url_;
81 std::vector<std::string> dispatch_event_log_targets_;
82 ScopedVector<Event> dispatch_event_log_events_;
85 TEST_F(EntryWatcherServiceTest, GetWatchedEntries) {
86 std::vector<base::File::Error> log;
88 const bool recursive = false;
89 service_->WatchDirectory(
90 kExtensionId, testing_url_, recursive, base::Bind(&LogStatus, &log));
91 base::RunLoop().RunUntilIdle();
93 ASSERT_EQ(1u, log.size());
94 EXPECT_EQ(base::File::FILE_OK, log[0]);
97 const std::vector<storage::FileSystemURL> watched_entries =
98 service_->GetWatchedEntries(kExtensionId);
99 ASSERT_EQ(1u, watched_entries.size());
100 EXPECT_EQ(testing_url_, watched_entries[0]);
104 const std::string wrong_extension_id = "abcabcabcabcabcabcabcabcabcabcab";
105 const std::vector<storage::FileSystemURL> watched_entries =
106 service_->GetWatchedEntries(wrong_extension_id);
107 EXPECT_EQ(0u, watched_entries.size());
111 TEST_F(EntryWatcherServiceTest, WatchDirectory) {
112 std::vector<base::File::Error> log;
114 const bool recursive = false;
115 service_->WatchDirectory(
116 kExtensionId, testing_url_, recursive, base::Bind(&LogStatus, &log));
117 base::RunLoop().RunUntilIdle();
119 ASSERT_EQ(1u, log.size());
120 EXPECT_EQ(base::File::FILE_OK, log[0]);
122 // The testing WatcherManager implementation emits two hard-coded fake
123 // notifications as soon as the watcher is set properly. See:
124 // TestWatcherManager::WatchDirectory() for details.
125 ASSERT_LE(1u, dispatch_event_log_targets_.size());
126 ASSERT_LE(1u, dispatch_event_log_events_.size());
128 EXPECT_EQ(kExtensionId, dispatch_event_log_targets_[0]);
129 EXPECT_EQ(api::file_system::OnEntryChanged::kEventName,
130 dispatch_event_log_events_[0]->event_name);
132 ASSERT_LE(2u, dispatch_event_log_targets_.size());
133 ASSERT_LE(2u, dispatch_event_log_events_.size());
134 EXPECT_EQ(kExtensionId, dispatch_event_log_targets_[1]);
135 EXPECT_EQ(api::file_system::OnEntryRemoved::kEventName,
136 dispatch_event_log_events_[1]->event_name);
138 // No unexpected events.
139 ASSERT_EQ(2u, dispatch_event_log_targets_.size());
140 ASSERT_EQ(2u, dispatch_event_log_events_.size());
142 const std::vector<storage::FileSystemURL> watched_entries =
143 service_->GetWatchedEntries(kExtensionId);
144 ASSERT_EQ(1u, watched_entries.size());
145 EXPECT_EQ(testing_url_, watched_entries[0]);
148 TEST_F(EntryWatcherServiceTest, WatchDirectory_AlreadyExists) {
149 std::vector<base::File::Error> log;
151 const bool recursive = false;
152 service_->WatchDirectory(
153 kExtensionId, testing_url_, recursive, base::Bind(&LogStatus, &log));
154 base::RunLoop().RunUntilIdle();
156 ASSERT_EQ(1u, log.size());
157 EXPECT_EQ(base::File::FILE_OK, log[0]);
159 ASSERT_EQ(2u, dispatch_event_log_targets_.size());
160 ASSERT_EQ(2u, dispatch_event_log_events_.size());
163 const std::vector<storage::FileSystemURL> watched_entries =
164 service_->GetWatchedEntries(kExtensionId);
165 EXPECT_EQ(1u, watched_entries.size());
168 service_->WatchDirectory(
169 kExtensionId, testing_url_, recursive, base::Bind(&LogStatus, &log));
170 base::RunLoop().RunUntilIdle();
172 ASSERT_EQ(2u, log.size());
173 EXPECT_EQ(base::File::FILE_ERROR_EXISTS, log[1]);
175 // No new unexpected events.
176 ASSERT_EQ(2u, dispatch_event_log_targets_.size());
177 ASSERT_EQ(2u, dispatch_event_log_events_.size());
180 const std::vector<storage::FileSystemURL> watched_entries =
181 service_->GetWatchedEntries(kExtensionId);
182 EXPECT_EQ(1u, watched_entries.size());
186 TEST_F(EntryWatcherServiceTest, WatchDirectory_Recursive) {
187 std::vector<base::File::Error> log;
189 const bool recursive = true;
190 service_->WatchDirectory(
191 kExtensionId, testing_url_, recursive, base::Bind(&LogStatus, &log));
192 base::RunLoop().RunUntilIdle();
194 // Recursive watchers are not supported yet.
195 ASSERT_EQ(1u, log.size());
196 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, log[0]);
198 // No unexpected events.
199 ASSERT_EQ(0u, dispatch_event_log_targets_.size());
200 ASSERT_EQ(0u, dispatch_event_log_events_.size());
202 const std::vector<storage::FileSystemURL> watched_entries =
203 service_->GetWatchedEntries(kExtensionId);
204 EXPECT_EQ(0u, watched_entries.size());
207 TEST_F(EntryWatcherServiceTest, UnwatchEntry) {
208 std::vector<base::File::Error> watch_log;
210 const bool recursive = false;
211 service_->WatchDirectory(kExtensionId,
214 base::Bind(&LogStatus, &watch_log));
215 base::RunLoop().RunUntilIdle();
217 ASSERT_EQ(1u, watch_log.size());
218 EXPECT_EQ(base::File::FILE_OK, watch_log[0]);
220 ASSERT_EQ(2u, dispatch_event_log_targets_.size());
221 ASSERT_EQ(2u, dispatch_event_log_events_.size());
224 const std::vector<storage::FileSystemURL> watched_entries =
225 service_->GetWatchedEntries(kExtensionId);
226 EXPECT_EQ(1u, watched_entries.size());
229 std::vector<base::File::Error> unwatch_log;
230 service_->UnwatchEntry(
231 kExtensionId, testing_url_, base::Bind(&LogStatus, &unwatch_log));
232 base::RunLoop().RunUntilIdle();
234 ASSERT_EQ(1u, unwatch_log.size());
235 EXPECT_EQ(base::File::FILE_OK, unwatch_log[0]);
238 const std::vector<storage::FileSystemURL> watched_entries =
239 service_->GetWatchedEntries(kExtensionId);
240 EXPECT_EQ(0u, watched_entries.size());
244 TEST_F(EntryWatcherServiceTest, UnwatchEntry_NotFound) {
245 std::vector<base::File::Error> log;
246 service_->UnwatchEntry(
247 kExtensionId, testing_url_, base::Bind(&LogStatus, &log));
248 base::RunLoop().RunUntilIdle();
250 ASSERT_EQ(1u, log.size());
251 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, log[0]);
254 } // namespace extensions