Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / file_system_provider / operations / get_metadata_unittest.cc
blobefdd4994eaebf225fe7cafa92f7d72a3b9166025
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/get_metadata.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/test_util.h"
16 #include "chrome/common/extensions/api/file_system_provider.h"
17 #include "chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.h"
18 #include "chrome/common/extensions/api/file_system_provider_internal.h"
19 #include "extensions/browser/event_router.h"
20 #include "storage/browser/fileapi/async_file_util.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 namespace chromeos {
24 namespace file_system_provider {
25 namespace operations {
26 namespace {
28 const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
29 const char kFileSystemId[] = "testing-file-system";
30 const char kMimeType[] = "text/plain";
31 const int kRequestId = 2;
32 const base::FilePath::CharType kDirectoryPath[] =
33 FILE_PATH_LITERAL("/directory");
35 // URLs are case insensitive, so it should pass the sanity check.
36 const char kThumbnail[] = "DaTa:ImAgE/pNg;base64,";
38 // Returns the request value as |result| in case of successful parse.
39 void CreateRequestValueFromJSON(const std::string& json,
40 scoped_ptr<RequestValue>* result) {
41 using extensions::api::file_system_provider_internal::
42 GetMetadataRequestedSuccess::Params;
44 int json_error_code;
45 std::string json_error_msg;
46 scoped_ptr<base::Value> value = base::JSONReader::ReadAndReturnError(
47 json, base::JSON_PARSE_RFC, &json_error_code, &json_error_msg);
48 ASSERT_TRUE(value.get()) << json_error_msg;
50 base::ListValue* value_as_list;
51 ASSERT_TRUE(value->GetAsList(&value_as_list));
52 scoped_ptr<Params> params(Params::Create(*value_as_list));
53 ASSERT_TRUE(params.get());
54 *result = RequestValue::CreateForGetMetadataSuccess(params.Pass());
55 ASSERT_TRUE(result->get());
58 // Callback invocation logger. Acts as a fileapi end-point.
59 class CallbackLogger {
60 public:
61 class Event {
62 public:
63 Event(scoped_ptr<EntryMetadata> metadata, base::File::Error result)
64 : metadata_(metadata.Pass()), result_(result) {}
65 virtual ~Event() {}
67 const EntryMetadata* metadata() const { return metadata_.get(); }
68 base::File::Error result() const { return result_; }
70 private:
71 scoped_ptr<EntryMetadata> metadata_;
72 base::File::Error result_;
74 DISALLOW_COPY_AND_ASSIGN(Event);
77 CallbackLogger() {}
78 virtual ~CallbackLogger() {}
80 void OnGetMetadata(scoped_ptr<EntryMetadata> metadata,
81 base::File::Error result) {
82 events_.push_back(new Event(metadata.Pass(), result));
85 const ScopedVector<Event>& events() const { return events_; }
87 private:
88 ScopedVector<Event> events_;
90 DISALLOW_COPY_AND_ASSIGN(CallbackLogger);
93 } // namespace
95 class FileSystemProviderOperationsGetMetadataTest : public testing::Test {
96 protected:
97 FileSystemProviderOperationsGetMetadataTest() {}
98 ~FileSystemProviderOperationsGetMetadataTest() override {}
100 void SetUp() override {
101 file_system_info_ = ProvidedFileSystemInfo(
102 kExtensionId, MountOptions(kFileSystemId, "" /* display_name */),
103 base::FilePath(), false /* configurable */, true /* watchable */,
104 extensions::SOURCE_FILE);
107 ProvidedFileSystemInfo file_system_info_;
110 TEST_F(FileSystemProviderOperationsGetMetadataTest, ValidateName) {
111 EXPECT_TRUE(ValidateName("hello-world!@#$%^&*()-_=+\"':,.<>?[]{}|\\",
112 false /* root_entry */));
113 EXPECT_FALSE(ValidateName("hello-world!@#$%^&*()-_=+\"':,.<>?[]{}|\\",
114 true /* root_entry */));
115 EXPECT_FALSE(ValidateName("", false /* root_path */));
116 EXPECT_TRUE(ValidateName("", true /* root_path */));
117 EXPECT_FALSE(ValidateName("hello/world", false /* root_path */));
118 EXPECT_FALSE(ValidateName("hello/world", true /* root_path */));
121 TEST_F(FileSystemProviderOperationsGetMetadataTest, ValidateIDLEntryMetadata) {
122 using extensions::api::file_system_provider::EntryMetadata;
123 const std::string kValidFileName = "hello-world";
124 const std::string kValidThumbnailUrl = "data:something";
126 // Correct metadata for non-root.
128 EntryMetadata metadata;
129 metadata.name = kValidFileName;
130 metadata.modification_time.additional_properties.SetString(
131 "value", "invalid-date-time"); // Invalid modification time is OK.
132 metadata.thumbnail.reset(new std::string(kValidThumbnailUrl));
133 EXPECT_TRUE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
136 // Correct metadata for non-root (without thumbnail).
138 EntryMetadata metadata;
139 metadata.name = kValidFileName;
140 metadata.modification_time.additional_properties.SetString(
141 "value", "invalid-date-time"); // Invalid modification time is OK.
142 EXPECT_TRUE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
145 // Correct metadata for root.
147 EntryMetadata metadata;
148 metadata.name = "";
149 metadata.modification_time.additional_properties.SetString(
150 "value", "invalid-date-time"); // Invalid modification time is OK.
151 EXPECT_TRUE(ValidateIDLEntryMetadata(metadata, true /* root_path */));
154 // Invalid characters in the name.
156 EntryMetadata metadata;
157 metadata.name = "hello/world";
158 metadata.modification_time.additional_properties.SetString(
159 "value", "invalid-date-time"); // Invalid modification time is OK.
160 metadata.thumbnail.reset(new std::string(kValidThumbnailUrl));
161 EXPECT_FALSE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
164 // Empty name for non-root.
166 EntryMetadata metadata;
167 metadata.name = "";
168 metadata.modification_time.additional_properties.SetString(
169 "value", "invalid-date-time"); // Invalid modification time is OK.
170 metadata.thumbnail.reset(new std::string(kValidThumbnailUrl));
171 EXPECT_FALSE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
174 // Missing date time.
176 EntryMetadata metadata;
177 metadata.name = kValidFileName;
178 metadata.thumbnail.reset(new std::string(kValidThumbnailUrl));
179 EXPECT_FALSE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
182 // Invalid thumbnail.
184 EntryMetadata metadata;
185 metadata.name = kValidFileName;
186 metadata.modification_time.additional_properties.SetString(
187 "value", "invalid-date-time"); // Invalid modification time is OK.
188 metadata.thumbnail.reset(new std::string("http://invalid-scheme"));
189 EXPECT_FALSE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
193 TEST_F(FileSystemProviderOperationsGetMetadataTest, Execute) {
194 using extensions::api::file_system_provider::GetMetadataRequestedOptions;
196 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
197 CallbackLogger callback_logger;
199 GetMetadata get_metadata(
200 NULL, file_system_info_, base::FilePath(kDirectoryPath),
201 ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
202 base::Bind(&CallbackLogger::OnGetMetadata,
203 base::Unretained(&callback_logger)));
204 get_metadata.SetDispatchEventImplForTesting(
205 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
206 base::Unretained(&dispatcher)));
208 EXPECT_TRUE(get_metadata.Execute(kRequestId));
210 ASSERT_EQ(1u, dispatcher.events().size());
211 extensions::Event* event = dispatcher.events()[0];
212 EXPECT_EQ(
213 extensions::api::file_system_provider::OnGetMetadataRequested::kEventName,
214 event->event_name);
215 base::ListValue* event_args = event->event_args.get();
216 ASSERT_EQ(1u, event_args->GetSize());
218 const base::DictionaryValue* options_as_value = NULL;
219 ASSERT_TRUE(event_args->GetDictionary(0, &options_as_value));
221 GetMetadataRequestedOptions options;
222 ASSERT_TRUE(
223 GetMetadataRequestedOptions::Populate(*options_as_value, &options));
224 EXPECT_EQ(kFileSystemId, options.file_system_id);
225 EXPECT_EQ(kRequestId, options.request_id);
226 EXPECT_EQ(kDirectoryPath, options.entry_path);
227 EXPECT_TRUE(options.thumbnail);
230 TEST_F(FileSystemProviderOperationsGetMetadataTest, Execute_NoListener) {
231 util::LoggingDispatchEventImpl dispatcher(false /* dispatch_reply */);
232 CallbackLogger callback_logger;
234 GetMetadata get_metadata(
235 NULL, file_system_info_, base::FilePath(kDirectoryPath),
236 ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
237 base::Bind(&CallbackLogger::OnGetMetadata,
238 base::Unretained(&callback_logger)));
239 get_metadata.SetDispatchEventImplForTesting(
240 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
241 base::Unretained(&dispatcher)));
243 EXPECT_FALSE(get_metadata.Execute(kRequestId));
246 TEST_F(FileSystemProviderOperationsGetMetadataTest, OnSuccess) {
247 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
248 CallbackLogger callback_logger;
250 GetMetadata get_metadata(
251 NULL, file_system_info_, base::FilePath(kDirectoryPath),
252 ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
253 base::Bind(&CallbackLogger::OnGetMetadata,
254 base::Unretained(&callback_logger)));
255 get_metadata.SetDispatchEventImplForTesting(
256 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
257 base::Unretained(&dispatcher)));
259 EXPECT_TRUE(get_metadata.Execute(kRequestId));
261 // Sample input as JSON. Keep in sync with file_system_provider_api.idl.
262 // As for now, it is impossible to create *::Params class directly, not from
263 // base::Value.
264 const std::string input =
265 "[\n"
266 " \"testing-file-system\",\n" // kFileSystemId
267 " 2,\n" // kRequestId
268 " {\n"
269 " \"isDirectory\": false,\n"
270 " \"name\": \"blueberries.txt\",\n"
271 " \"size\": 4096,\n"
272 " \"modificationTime\": {\n"
273 " \"value\": \"Thu Apr 24 00:46:52 UTC 2014\"\n"
274 " },\n"
275 " \"mimeType\": \"text/plain\",\n" // kMimeType
276 " \"thumbnail\": \"DaTa:ImAgE/pNg;base64,\"\n" // kThumbnail
277 " },\n"
278 " 0\n" // execution_time
279 "]\n";
280 scoped_ptr<RequestValue> request_value;
281 ASSERT_NO_FATAL_FAILURE(CreateRequestValueFromJSON(input, &request_value));
283 const bool has_more = false;
284 get_metadata.OnSuccess(kRequestId, request_value.Pass(), has_more);
286 ASSERT_EQ(1u, callback_logger.events().size());
287 CallbackLogger::Event* event = callback_logger.events()[0];
288 EXPECT_EQ(base::File::FILE_OK, event->result());
290 const EntryMetadata* metadata = event->metadata();
291 EXPECT_FALSE(metadata->is_directory);
292 EXPECT_EQ(4096, metadata->size);
293 base::Time expected_time;
294 EXPECT_TRUE(
295 base::Time::FromString("Thu Apr 24 00:46:52 UTC 2014", &expected_time));
296 EXPECT_EQ(expected_time, metadata->modification_time);
297 EXPECT_EQ(kMimeType, metadata->mime_type);
298 EXPECT_EQ(kThumbnail, metadata->thumbnail);
301 TEST_F(FileSystemProviderOperationsGetMetadataTest, OnSuccess_InvalidMetadata) {
302 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
303 CallbackLogger callback_logger;
305 GetMetadata get_metadata(
306 NULL, file_system_info_, base::FilePath(kDirectoryPath),
307 ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
308 base::Bind(&CallbackLogger::OnGetMetadata,
309 base::Unretained(&callback_logger)));
310 get_metadata.SetDispatchEventImplForTesting(
311 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
312 base::Unretained(&dispatcher)));
314 EXPECT_TRUE(get_metadata.Execute(kRequestId));
316 // Sample input as JSON. Keep in sync with file_system_provider_api.idl.
317 // As for now, it is impossible to create *::Params class directly, not from
318 // base::Value.
319 const std::string input =
320 "[\n"
321 " \"testing-file-system\",\n" // kFileSystemId
322 " 2,\n" // kRequestId
323 " {\n"
324 " \"isDirectory\": false,\n"
325 " \"name\": \"blue/berries.txt\",\n"
326 " \"size\": 4096,\n"
327 " \"modificationTime\": {\n"
328 " \"value\": \"Thu Apr 24 00:46:52 UTC 2014\"\n"
329 " },\n"
330 " \"mimeType\": \"text/plain\",\n" // kMimeType
331 " \"thumbnail\": \"http://www.foobar.com/evil\"\n" // kThumbnail
332 " },\n"
333 " 0\n" // execution_time
334 "]\n";
336 scoped_ptr<RequestValue> request_value;
337 ASSERT_NO_FATAL_FAILURE(CreateRequestValueFromJSON(input, &request_value));
339 const bool has_more = false;
340 get_metadata.OnSuccess(kRequestId, request_value.Pass(), has_more);
342 ASSERT_EQ(1u, callback_logger.events().size());
343 CallbackLogger::Event* event = callback_logger.events()[0];
344 EXPECT_EQ(base::File::FILE_ERROR_IO, event->result());
346 const EntryMetadata* metadata = event->metadata();
347 EXPECT_FALSE(metadata);
350 TEST_F(FileSystemProviderOperationsGetMetadataTest, OnError) {
351 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
352 CallbackLogger callback_logger;
354 GetMetadata get_metadata(
355 NULL, file_system_info_, base::FilePath(kDirectoryPath),
356 ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
357 base::Bind(&CallbackLogger::OnGetMetadata,
358 base::Unretained(&callback_logger)));
359 get_metadata.SetDispatchEventImplForTesting(
360 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
361 base::Unretained(&dispatcher)));
363 EXPECT_TRUE(get_metadata.Execute(kRequestId));
365 get_metadata.OnError(kRequestId,
366 scoped_ptr<RequestValue>(new RequestValue()),
367 base::File::FILE_ERROR_TOO_MANY_OPENED);
369 ASSERT_EQ(1u, callback_logger.events().size());
370 CallbackLogger::Event* event = callback_logger.events()[0];
371 EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED, event->result());
374 } // namespace operations
375 } // namespace file_system_provider
376 } // namespace chromeos