Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / file_system_provider / operations / read_directory_unittest.cc
blobb76399048c18687c7597e57229d955672fee84e8
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/chromeos/file_system_provider/operations/read_directory.h"
7 #include <string>
9 #include "base/files/file.h"
10 #include "base/files/file_path.h"
11 #include "base/json/json_reader.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/scoped_vector.h"
14 #include "base/values.h"
15 #include "chrome/browser/chromeos/file_system_provider/operations/get_metadata.h"
16 #include "chrome/browser/chromeos/file_system_provider/operations/test_util.h"
17 #include "chrome/common/extensions/api/file_system_provider.h"
18 #include "chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.h"
19 #include "chrome/common/extensions/api/file_system_provider_internal.h"
20 #include "extensions/browser/event_router.h"
21 #include "storage/browser/fileapi/async_file_util.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 namespace chromeos {
25 namespace file_system_provider {
26 namespace operations {
27 namespace {
29 const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
30 const char kFileSystemId[] = "testing-file-system";
31 const int kRequestId = 2;
32 const base::FilePath::CharType kDirectoryPath[] =
33 FILE_PATH_LITERAL("/directory");
35 // Callback invocation logger. Acts as a fileapi end-point.
36 class CallbackLogger {
37 public:
38 class Event {
39 public:
40 Event(base::File::Error result,
41 const storage::AsyncFileUtil::EntryList& entry_list,
42 bool has_more)
43 : result_(result), entry_list_(entry_list), has_more_(has_more) {}
44 virtual ~Event() {}
46 base::File::Error result() { return result_; }
47 const storage::AsyncFileUtil::EntryList& entry_list() {
48 return entry_list_;
50 bool has_more() { return has_more_; }
52 private:
53 base::File::Error result_;
54 storage::AsyncFileUtil::EntryList entry_list_;
55 bool has_more_;
57 DISALLOW_COPY_AND_ASSIGN(Event);
60 CallbackLogger() {}
61 virtual ~CallbackLogger() {}
63 void OnReadDirectory(base::File::Error result,
64 const storage::AsyncFileUtil::EntryList& entry_list,
65 bool has_more) {
66 events_.push_back(new Event(result, entry_list, has_more));
69 ScopedVector<Event>& events() { return events_; }
71 private:
72 ScopedVector<Event> events_;
74 DISALLOW_COPY_AND_ASSIGN(CallbackLogger);
77 // Returns the request value as |result| in case of successful parse.
78 void CreateRequestValueFromJSON(const std::string& json,
79 scoped_ptr<RequestValue>* result) {
80 using extensions::api::file_system_provider_internal::
81 ReadDirectoryRequestedSuccess::Params;
83 int json_error_code;
84 std::string json_error_msg;
85 scoped_ptr<base::Value> value = base::JSONReader::ReadAndReturnError(
86 json, base::JSON_PARSE_RFC, &json_error_code, &json_error_msg);
87 ASSERT_TRUE(value.get()) << json_error_msg;
89 base::ListValue* value_as_list;
90 ASSERT_TRUE(value->GetAsList(&value_as_list));
91 scoped_ptr<Params> params(Params::Create(*value_as_list));
92 ASSERT_TRUE(params.get());
93 *result = RequestValue::CreateForReadDirectorySuccess(params.Pass());
94 ASSERT_TRUE(result->get());
97 } // namespace
99 class FileSystemProviderOperationsReadDirectoryTest : public testing::Test {
100 protected:
101 FileSystemProviderOperationsReadDirectoryTest() {}
102 ~FileSystemProviderOperationsReadDirectoryTest() override {}
104 void SetUp() override {
105 file_system_info_ = ProvidedFileSystemInfo(
106 kExtensionId, MountOptions(kFileSystemId, "" /* display_name */),
107 base::FilePath(), false /* configurable */, true /* watchable */,
108 extensions::SOURCE_FILE);
111 ProvidedFileSystemInfo file_system_info_;
114 TEST_F(FileSystemProviderOperationsReadDirectoryTest, Execute) {
115 using extensions::api::file_system_provider::ReadDirectoryRequestedOptions;
117 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
118 CallbackLogger callback_logger;
120 ReadDirectory read_directory(NULL, file_system_info_,
121 base::FilePath(kDirectoryPath),
122 base::Bind(&CallbackLogger::OnReadDirectory,
123 base::Unretained(&callback_logger)));
124 read_directory.SetDispatchEventImplForTesting(
125 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
126 base::Unretained(&dispatcher)));
128 EXPECT_TRUE(read_directory.Execute(kRequestId));
130 ASSERT_EQ(1u, dispatcher.events().size());
131 extensions::Event* event = dispatcher.events()[0];
132 EXPECT_EQ(extensions::api::file_system_provider::OnReadDirectoryRequested::
133 kEventName,
134 event->event_name);
135 base::ListValue* event_args = event->event_args.get();
136 ASSERT_EQ(1u, event_args->GetSize());
138 const base::DictionaryValue* options_as_value = NULL;
139 ASSERT_TRUE(event_args->GetDictionary(0, &options_as_value));
141 ReadDirectoryRequestedOptions options;
142 ASSERT_TRUE(
143 ReadDirectoryRequestedOptions::Populate(*options_as_value, &options));
144 EXPECT_EQ(kFileSystemId, options.file_system_id);
145 EXPECT_EQ(kRequestId, options.request_id);
146 EXPECT_EQ(kDirectoryPath, options.directory_path);
149 TEST_F(FileSystemProviderOperationsReadDirectoryTest, Execute_NoListener) {
150 util::LoggingDispatchEventImpl dispatcher(false /* dispatch_reply */);
151 CallbackLogger callback_logger;
153 ReadDirectory read_directory(NULL, file_system_info_,
154 base::FilePath(kDirectoryPath),
155 base::Bind(&CallbackLogger::OnReadDirectory,
156 base::Unretained(&callback_logger)));
157 read_directory.SetDispatchEventImplForTesting(
158 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
159 base::Unretained(&dispatcher)));
161 EXPECT_FALSE(read_directory.Execute(kRequestId));
164 TEST_F(FileSystemProviderOperationsReadDirectoryTest, OnSuccess) {
165 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
166 CallbackLogger callback_logger;
168 ReadDirectory read_directory(NULL, file_system_info_,
169 base::FilePath(kDirectoryPath),
170 base::Bind(&CallbackLogger::OnReadDirectory,
171 base::Unretained(&callback_logger)));
172 read_directory.SetDispatchEventImplForTesting(
173 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
174 base::Unretained(&dispatcher)));
176 EXPECT_TRUE(read_directory.Execute(kRequestId));
178 // Sample input as JSON. Keep in sync with file_system_provider_api.idl.
179 // As for now, it is impossible to create *::Params class directly, not from
180 // base::Value.
181 const std::string input =
182 "[\n"
183 " \"testing-file-system\",\n" // kFileSystemId
184 " 2,\n" // kRequestId
185 " [\n"
186 " {\n"
187 " \"isDirectory\": false,\n"
188 " \"name\": \"blueberries.txt\",\n"
189 " \"size\": 4096,\n"
190 " \"modificationTime\": {\n"
191 " \"value\": \"Thu Apr 24 00:46:52 UTC 2014\"\n"
192 " }\n"
193 " }\n"
194 " ],\n"
195 " false,\n" // has_more
196 " 0\n" // execution_time
197 "]\n";
198 scoped_ptr<RequestValue> request_value;
199 ASSERT_NO_FATAL_FAILURE(CreateRequestValueFromJSON(input, &request_value));
201 const bool has_more = false;
202 read_directory.OnSuccess(kRequestId, request_value.Pass(), has_more);
204 ASSERT_EQ(1u, callback_logger.events().size());
205 CallbackLogger::Event* event = callback_logger.events()[0];
206 EXPECT_EQ(base::File::FILE_OK, event->result());
208 ASSERT_EQ(1u, event->entry_list().size());
209 const storage::DirectoryEntry entry = event->entry_list()[0];
210 EXPECT_FALSE(entry.is_directory);
211 EXPECT_EQ("blueberries.txt", entry.name);
212 EXPECT_EQ(4096, entry.size);
213 base::Time expected_time;
214 EXPECT_TRUE(
215 base::Time::FromString("Thu Apr 24 00:46:52 UTC 2014", &expected_time));
216 EXPECT_EQ(expected_time, entry.last_modified_time);
219 TEST_F(FileSystemProviderOperationsReadDirectoryTest,
220 OnSuccess_InvalidMetadata) {
221 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
222 CallbackLogger callback_logger;
224 ReadDirectory read_directory(NULL, file_system_info_,
225 base::FilePath(kDirectoryPath),
226 base::Bind(&CallbackLogger::OnReadDirectory,
227 base::Unretained(&callback_logger)));
228 read_directory.SetDispatchEventImplForTesting(
229 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
230 base::Unretained(&dispatcher)));
232 EXPECT_TRUE(read_directory.Execute(kRequestId));
234 // Sample input as JSON. Keep in sync with file_system_provider_api.idl.
235 // As for now, it is impossible to create *::Params class directly, not from
236 // base::Value.
237 const std::string input =
238 "[\n"
239 " \"testing-file-system\",\n" // kFileSystemId
240 " 2,\n" // kRequestId
241 " [\n"
242 " {\n"
243 " \"isDirectory\": false,\n"
244 " \"name\": \"blue/berries.txt\",\n"
245 " \"size\": 4096,\n"
246 " \"modificationTime\": {\n"
247 " \"value\": \"Thu Apr 24 00:46:52 UTC 2014\"\n"
248 " }\n"
249 " }\n"
250 " ],\n"
251 " false,\n" // has_more
252 " 0\n" // execution_time
253 "]\n";
254 scoped_ptr<RequestValue> request_value;
255 ASSERT_NO_FATAL_FAILURE(CreateRequestValueFromJSON(input, &request_value));
257 const bool has_more = false;
258 read_directory.OnSuccess(kRequestId, request_value.Pass(), has_more);
260 ASSERT_EQ(1u, callback_logger.events().size());
261 CallbackLogger::Event* event = callback_logger.events()[0];
262 EXPECT_EQ(base::File::FILE_ERROR_IO, event->result());
264 EXPECT_EQ(0u, event->entry_list().size());
267 TEST_F(FileSystemProviderOperationsReadDirectoryTest, OnError) {
268 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
269 CallbackLogger callback_logger;
271 ReadDirectory read_directory(NULL, file_system_info_,
272 base::FilePath(kDirectoryPath),
273 base::Bind(&CallbackLogger::OnReadDirectory,
274 base::Unretained(&callback_logger)));
275 read_directory.SetDispatchEventImplForTesting(
276 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
277 base::Unretained(&dispatcher)));
279 EXPECT_TRUE(read_directory.Execute(kRequestId));
281 read_directory.OnError(kRequestId,
282 scoped_ptr<RequestValue>(new RequestValue()),
283 base::File::FILE_ERROR_TOO_MANY_OPENED);
285 ASSERT_EQ(1u, callback_logger.events().size());
286 CallbackLogger::Event* event = callback_logger.events()[0];
287 EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED, event->result());
288 ASSERT_EQ(0u, event->entry_list().size());
291 } // namespace operations
292 } // namespace file_system_provider
293 } // namespace chromeos