Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / file_system_provider / operations / get_metadata_unittest.cc
blob60e269a508447308c3d0e9f144ccc9db839fe9dc
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_internal.h"
18 #include "extensions/browser/event_router.h"
19 #include "storage/browser/fileapi/async_file_util.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 namespace chromeos {
23 namespace file_system_provider {
24 namespace operations {
25 namespace {
27 const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
28 const char kFileSystemId[] = "testing-file-system";
29 const char kMimeType[] = "text/plain";
30 const int kRequestId = 2;
31 const base::FilePath::CharType kDirectoryPath[] =
32 FILE_PATH_LITERAL("/directory");
34 // URLs are case insensitive, so it should pass the sanity check.
35 const char kThumbnail[] = "DaTa:ImAgE/pNg;base64,";
37 // Returns the request value as |result| in case of successful parse.
38 void CreateRequestValueFromJSON(const std::string& json,
39 scoped_ptr<RequestValue>* result) {
40 using extensions::api::file_system_provider_internal::
41 GetMetadataRequestedSuccess::Params;
43 int json_error_code;
44 std::string json_error_msg;
45 scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
46 json, base::JSON_PARSE_RFC, &json_error_code, &json_error_msg));
47 ASSERT_TRUE(value.get()) << json_error_msg;
49 base::ListValue* value_as_list;
50 ASSERT_TRUE(value->GetAsList(&value_as_list));
51 scoped_ptr<Params> params(Params::Create(*value_as_list));
52 ASSERT_TRUE(params.get());
53 *result = RequestValue::CreateForGetMetadataSuccess(params.Pass());
54 ASSERT_TRUE(result->get());
57 // Callback invocation logger. Acts as a fileapi end-point.
58 class CallbackLogger {
59 public:
60 class Event {
61 public:
62 Event(scoped_ptr<EntryMetadata> metadata, base::File::Error result)
63 : metadata_(metadata.Pass()), result_(result) {}
64 virtual ~Event() {}
66 const EntryMetadata* metadata() const { return metadata_.get(); }
67 base::File::Error result() const { return result_; }
69 private:
70 scoped_ptr<EntryMetadata> metadata_;
71 base::File::Error result_;
73 DISALLOW_COPY_AND_ASSIGN(Event);
76 CallbackLogger() {}
77 virtual ~CallbackLogger() {}
79 void OnGetMetadata(scoped_ptr<EntryMetadata> metadata,
80 base::File::Error result) {
81 events_.push_back(new Event(metadata.Pass(), result));
84 const ScopedVector<Event>& events() const { return events_; }
86 private:
87 ScopedVector<Event> events_;
89 DISALLOW_COPY_AND_ASSIGN(CallbackLogger);
92 } // namespace
94 class FileSystemProviderOperationsGetMetadataTest : public testing::Test {
95 protected:
96 FileSystemProviderOperationsGetMetadataTest() {}
97 ~FileSystemProviderOperationsGetMetadataTest() override {}
99 void SetUp() override {
100 file_system_info_ = ProvidedFileSystemInfo(
101 kExtensionId,
102 MountOptions(kFileSystemId, "" /* display_name */),
103 base::FilePath());
106 ProvidedFileSystemInfo file_system_info_;
109 TEST_F(FileSystemProviderOperationsGetMetadataTest, ValidateName) {
110 EXPECT_TRUE(ValidateName("hello-world!@#$%^&*()-_=+\"':,.<>?[]{}|\\",
111 false /* root_entry */));
112 EXPECT_FALSE(ValidateName("hello-world!@#$%^&*()-_=+\"':,.<>?[]{}|\\",
113 true /* root_entry */));
114 EXPECT_FALSE(ValidateName("", false /* root_path */));
115 EXPECT_TRUE(ValidateName("", true /* root_path */));
116 EXPECT_FALSE(ValidateName("hello/world", false /* root_path */));
117 EXPECT_FALSE(ValidateName("hello/world", true /* root_path */));
120 TEST_F(FileSystemProviderOperationsGetMetadataTest, ValidateIDLEntryMetadata) {
121 using extensions::api::file_system_provider::EntryMetadata;
122 const std::string kValidFileName = "hello-world";
123 const std::string kValidThumbnailUrl = "data:something";
125 // Correct metadata for non-root.
127 EntryMetadata metadata;
128 metadata.name = kValidFileName;
129 metadata.modification_time.additional_properties.SetString(
130 "value", "invalid-date-time"); // Invalid modification time is OK.
131 metadata.thumbnail.reset(new std::string(kValidThumbnailUrl));
132 EXPECT_TRUE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
135 // Correct metadata for non-root (without thumbnail).
137 EntryMetadata metadata;
138 metadata.name = kValidFileName;
139 metadata.modification_time.additional_properties.SetString(
140 "value", "invalid-date-time"); // Invalid modification time is OK.
141 EXPECT_TRUE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
144 // Correct metadata for root.
146 EntryMetadata metadata;
147 metadata.name = "";
148 metadata.modification_time.additional_properties.SetString(
149 "value", "invalid-date-time"); // Invalid modification time is OK.
150 EXPECT_TRUE(ValidateIDLEntryMetadata(metadata, true /* root_path */));
153 // Invalid characters in the name.
155 EntryMetadata metadata;
156 metadata.name = "hello/world";
157 metadata.modification_time.additional_properties.SetString(
158 "value", "invalid-date-time"); // Invalid modification time is OK.
159 metadata.thumbnail.reset(new std::string(kValidThumbnailUrl));
160 EXPECT_FALSE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
163 // Empty name for non-root.
165 EntryMetadata metadata;
166 metadata.name = "";
167 metadata.modification_time.additional_properties.SetString(
168 "value", "invalid-date-time"); // Invalid modification time is OK.
169 metadata.thumbnail.reset(new std::string(kValidThumbnailUrl));
170 EXPECT_FALSE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
173 // Missing date time.
175 EntryMetadata metadata;
176 metadata.name = kValidFileName;
177 metadata.thumbnail.reset(new std::string(kValidThumbnailUrl));
178 EXPECT_FALSE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
181 // Invalid thumbnail.
183 EntryMetadata metadata;
184 metadata.name = kValidFileName;
185 metadata.modification_time.additional_properties.SetString(
186 "value", "invalid-date-time"); // Invalid modification time is OK.
187 metadata.thumbnail.reset(new std::string("http://invalid-scheme"));
188 EXPECT_FALSE(ValidateIDLEntryMetadata(metadata, false /* root_path */));
192 TEST_F(FileSystemProviderOperationsGetMetadataTest, Execute) {
193 using extensions::api::file_system_provider::GetMetadataRequestedOptions;
195 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
196 CallbackLogger callback_logger;
198 GetMetadata get_metadata(
199 NULL, file_system_info_, base::FilePath(kDirectoryPath),
200 ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
201 base::Bind(&CallbackLogger::OnGetMetadata,
202 base::Unretained(&callback_logger)));
203 get_metadata.SetDispatchEventImplForTesting(
204 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
205 base::Unretained(&dispatcher)));
207 EXPECT_TRUE(get_metadata.Execute(kRequestId));
209 ASSERT_EQ(1u, dispatcher.events().size());
210 extensions::Event* event = dispatcher.events()[0];
211 EXPECT_EQ(
212 extensions::api::file_system_provider::OnGetMetadataRequested::kEventName,
213 event->event_name);
214 base::ListValue* event_args = event->event_args.get();
215 ASSERT_EQ(1u, event_args->GetSize());
217 const base::DictionaryValue* options_as_value = NULL;
218 ASSERT_TRUE(event_args->GetDictionary(0, &options_as_value));
220 GetMetadataRequestedOptions options;
221 ASSERT_TRUE(
222 GetMetadataRequestedOptions::Populate(*options_as_value, &options));
223 EXPECT_EQ(kFileSystemId, options.file_system_id);
224 EXPECT_EQ(kRequestId, options.request_id);
225 EXPECT_EQ(kDirectoryPath, options.entry_path);
226 EXPECT_TRUE(options.thumbnail);
229 TEST_F(FileSystemProviderOperationsGetMetadataTest, Execute_NoListener) {
230 util::LoggingDispatchEventImpl dispatcher(false /* dispatch_reply */);
231 CallbackLogger callback_logger;
233 GetMetadata get_metadata(
234 NULL, file_system_info_, base::FilePath(kDirectoryPath),
235 ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
236 base::Bind(&CallbackLogger::OnGetMetadata,
237 base::Unretained(&callback_logger)));
238 get_metadata.SetDispatchEventImplForTesting(
239 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
240 base::Unretained(&dispatcher)));
242 EXPECT_FALSE(get_metadata.Execute(kRequestId));
245 TEST_F(FileSystemProviderOperationsGetMetadataTest, OnSuccess) {
246 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
247 CallbackLogger callback_logger;
249 GetMetadata get_metadata(
250 NULL, file_system_info_, base::FilePath(kDirectoryPath),
251 ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
252 base::Bind(&CallbackLogger::OnGetMetadata,
253 base::Unretained(&callback_logger)));
254 get_metadata.SetDispatchEventImplForTesting(
255 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
256 base::Unretained(&dispatcher)));
258 EXPECT_TRUE(get_metadata.Execute(kRequestId));
260 // Sample input as JSON. Keep in sync with file_system_provider_api.idl.
261 // As for now, it is impossible to create *::Params class directly, not from
262 // base::Value.
263 const std::string input =
264 "[\n"
265 " \"testing-file-system\",\n" // kFileSystemId
266 " 2,\n" // kRequestId
267 " {\n"
268 " \"isDirectory\": false,\n"
269 " \"name\": \"blueberries.txt\",\n"
270 " \"size\": 4096,\n"
271 " \"modificationTime\": {\n"
272 " \"value\": \"Thu Apr 24 00:46:52 UTC 2014\"\n"
273 " },\n"
274 " \"mimeType\": \"text/plain\",\n" // kMimeType
275 " \"thumbnail\": \"DaTa:ImAgE/pNg;base64,\"\n" // kThumbnail
276 " },\n"
277 " 0\n" // execution_time
278 "]\n";
279 scoped_ptr<RequestValue> request_value;
280 ASSERT_NO_FATAL_FAILURE(CreateRequestValueFromJSON(input, &request_value));
282 const bool has_more = false;
283 get_metadata.OnSuccess(kRequestId, request_value.Pass(), has_more);
285 ASSERT_EQ(1u, callback_logger.events().size());
286 CallbackLogger::Event* event = callback_logger.events()[0];
287 EXPECT_EQ(base::File::FILE_OK, event->result());
289 const EntryMetadata* metadata = event->metadata();
290 EXPECT_FALSE(metadata->is_directory);
291 EXPECT_EQ(4096, metadata->size);
292 base::Time expected_time;
293 EXPECT_TRUE(
294 base::Time::FromString("Thu Apr 24 00:46:52 UTC 2014", &expected_time));
295 EXPECT_EQ(expected_time, metadata->modification_time);
296 EXPECT_EQ(kMimeType, metadata->mime_type);
297 EXPECT_EQ(kThumbnail, metadata->thumbnail);
300 TEST_F(FileSystemProviderOperationsGetMetadataTest, OnSuccess_InvalidMetadata) {
301 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
302 CallbackLogger callback_logger;
304 GetMetadata get_metadata(
305 NULL, file_system_info_, base::FilePath(kDirectoryPath),
306 ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
307 base::Bind(&CallbackLogger::OnGetMetadata,
308 base::Unretained(&callback_logger)));
309 get_metadata.SetDispatchEventImplForTesting(
310 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
311 base::Unretained(&dispatcher)));
313 EXPECT_TRUE(get_metadata.Execute(kRequestId));
315 // Sample input as JSON. Keep in sync with file_system_provider_api.idl.
316 // As for now, it is impossible to create *::Params class directly, not from
317 // base::Value.
318 const std::string input =
319 "[\n"
320 " \"testing-file-system\",\n" // kFileSystemId
321 " 2,\n" // kRequestId
322 " {\n"
323 " \"isDirectory\": false,\n"
324 " \"name\": \"blue/berries.txt\",\n"
325 " \"size\": 4096,\n"
326 " \"modificationTime\": {\n"
327 " \"value\": \"Thu Apr 24 00:46:52 UTC 2014\"\n"
328 " },\n"
329 " \"mimeType\": \"text/plain\",\n" // kMimeType
330 " \"thumbnail\": \"http://www.foobar.com/evil\"\n" // kThumbnail
331 " },\n"
332 " 0\n" // execution_time
333 "]\n";
335 scoped_ptr<RequestValue> request_value;
336 ASSERT_NO_FATAL_FAILURE(CreateRequestValueFromJSON(input, &request_value));
338 const bool has_more = false;
339 get_metadata.OnSuccess(kRequestId, request_value.Pass(), has_more);
341 ASSERT_EQ(1u, callback_logger.events().size());
342 CallbackLogger::Event* event = callback_logger.events()[0];
343 EXPECT_EQ(base::File::FILE_ERROR_IO, event->result());
345 const EntryMetadata* metadata = event->metadata();
346 EXPECT_FALSE(metadata);
349 TEST_F(FileSystemProviderOperationsGetMetadataTest, OnError) {
350 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
351 CallbackLogger callback_logger;
353 GetMetadata get_metadata(
354 NULL, file_system_info_, base::FilePath(kDirectoryPath),
355 ProvidedFileSystemInterface::METADATA_FIELD_THUMBNAIL,
356 base::Bind(&CallbackLogger::OnGetMetadata,
357 base::Unretained(&callback_logger)));
358 get_metadata.SetDispatchEventImplForTesting(
359 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
360 base::Unretained(&dispatcher)));
362 EXPECT_TRUE(get_metadata.Execute(kRequestId));
364 get_metadata.OnError(kRequestId,
365 scoped_ptr<RequestValue>(new RequestValue()),
366 base::File::FILE_ERROR_TOO_MANY_OPENED);
368 ASSERT_EQ(1u, callback_logger.events().size());
369 CallbackLogger::Event* event = callback_logger.events()[0];
370 EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED, event->result());
373 } // namespace operations
374 } // namespace file_system_provider
375 } // namespace chromeos