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"
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 "testing/gtest/include/gtest/gtest.h"
20 #include "webkit/browser/fileapi/async_file_util.h"
23 namespace file_system_provider {
24 namespace operations {
27 const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
28 const char kFileSystemId[] = "testing-file-system";
29 const int kRequestId = 2;
30 const base::FilePath::CharType kDirectoryPath[] = "/directory";
32 // Callback invocation logger. Acts as a fileapi end-point.
33 class CallbackLogger {
37 Event(base::File::Error result,
38 const fileapi::AsyncFileUtil::EntryList& entry_list,
40 : result_(result), entry_list_(entry_list), has_more_(has_more) {}
43 base::File::Error result() { return result_; }
44 const fileapi::AsyncFileUtil::EntryList& entry_list() {
47 bool has_more() { return has_more_; }
50 base::File::Error result_;
51 fileapi::AsyncFileUtil::EntryList entry_list_;
54 DISALLOW_COPY_AND_ASSIGN(Event);
58 virtual ~CallbackLogger() {}
60 void OnReadDirectory(base::File::Error result,
61 const fileapi::AsyncFileUtil::EntryList& entry_list,
63 events_.push_back(new Event(result, entry_list, has_more));
66 ScopedVector<Event>& events() { return events_; }
69 ScopedVector<Event> events_;
72 DISALLOW_COPY_AND_ASSIGN(CallbackLogger);
77 class FileSystemProviderOperationsReadDirectoryTest : public testing::Test {
79 FileSystemProviderOperationsReadDirectoryTest() {}
80 virtual ~FileSystemProviderOperationsReadDirectoryTest() {}
82 virtual void SetUp() OVERRIDE {
84 ProvidedFileSystemInfo(kExtensionId,
86 "" /* display_name */,
88 base::FilePath() /* mount_path */);
91 ProvidedFileSystemInfo file_system_info_;
94 TEST_F(FileSystemProviderOperationsReadDirectoryTest, Execute) {
95 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
96 CallbackLogger callback_logger;
98 ReadDirectory read_directory(NULL,
100 base::FilePath::FromUTF8Unsafe(kDirectoryPath),
101 base::Bind(&CallbackLogger::OnReadDirectory,
102 base::Unretained(&callback_logger)));
103 read_directory.SetDispatchEventImplForTesting(
104 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
105 base::Unretained(&dispatcher)));
107 EXPECT_TRUE(read_directory.Execute(kRequestId));
109 ASSERT_EQ(1u, dispatcher.events().size());
110 extensions::Event* event = dispatcher.events()[0];
111 EXPECT_EQ(extensions::api::file_system_provider::OnReadDirectoryRequested::
114 base::ListValue* event_args = event->event_args.get();
115 ASSERT_EQ(1u, event_args->GetSize());
117 base::DictionaryValue* options = NULL;
118 ASSERT_TRUE(event_args->GetDictionary(0, &options));
120 std::string event_file_system_id;
121 EXPECT_TRUE(options->GetString("fileSystemId", &event_file_system_id));
122 EXPECT_EQ(kFileSystemId, event_file_system_id);
124 int event_request_id = -1;
125 EXPECT_TRUE(options->GetInteger("requestId", &event_request_id));
126 EXPECT_EQ(kRequestId, event_request_id);
128 std::string event_directory_path;
129 EXPECT_TRUE(options->GetString("directoryPath", &event_directory_path));
130 EXPECT_EQ(kDirectoryPath, event_directory_path);
133 TEST_F(FileSystemProviderOperationsReadDirectoryTest, Execute_NoListener) {
134 util::LoggingDispatchEventImpl dispatcher(false /* dispatch_reply */);
135 CallbackLogger callback_logger;
137 ReadDirectory read_directory(NULL,
139 base::FilePath::FromUTF8Unsafe(kDirectoryPath),
140 base::Bind(&CallbackLogger::OnReadDirectory,
141 base::Unretained(&callback_logger)));
142 read_directory.SetDispatchEventImplForTesting(
143 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
144 base::Unretained(&dispatcher)));
146 EXPECT_FALSE(read_directory.Execute(kRequestId));
149 TEST_F(FileSystemProviderOperationsReadDirectoryTest, OnSuccess) {
150 using extensions::api::file_system_provider_internal::
151 ReadDirectoryRequestedSuccess::Params;
153 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
154 CallbackLogger callback_logger;
156 ReadDirectory read_directory(NULL,
158 base::FilePath::FromUTF8Unsafe(kDirectoryPath),
159 base::Bind(&CallbackLogger::OnReadDirectory,
160 base::Unretained(&callback_logger)));
161 read_directory.SetDispatchEventImplForTesting(
162 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
163 base::Unretained(&dispatcher)));
165 EXPECT_TRUE(read_directory.Execute(kRequestId));
167 // Sample input as JSON. Keep in sync with file_system_provider_api.idl.
168 // As for now, it is impossible to create *::Params class directly, not from
170 const std::string input =
172 " \"testing-file-system\",\n" // kFileSystemId
173 " 2,\n" // kRequestId
176 " \"isDirectory\": false,\n"
177 " \"name\": \"blueberries.txt\",\n"
179 " \"modificationTime\": {\n"
180 " \"value\": \"Thu Apr 24 00:46:52 UTC 2014\"\n"
184 " false,\n" // has_more
185 " 0\n" // execution_time
189 std::string json_error_msg;
190 scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
191 input, base::JSON_PARSE_RFC, &json_error_code, &json_error_msg));
192 ASSERT_TRUE(value.get()) << json_error_msg;
194 base::ListValue* value_as_list;
195 ASSERT_TRUE(value->GetAsList(&value_as_list));
196 scoped_ptr<Params> params(Params::Create(*value_as_list));
197 ASSERT_TRUE(params.get());
198 scoped_ptr<RequestValue> request_value(
199 RequestValue::CreateForReadDirectorySuccess(params.Pass()));
200 ASSERT_TRUE(request_value.get());
202 const bool has_more = false;
203 read_directory.OnSuccess(kRequestId, request_value.Pass(), has_more);
205 ASSERT_EQ(1u, callback_logger.events().size());
206 CallbackLogger::Event* event = callback_logger.events()[0];
207 EXPECT_EQ(base::File::FILE_OK, event->result());
209 ASSERT_EQ(1u, event->entry_list().size());
210 const fileapi::DirectoryEntry entry = event->entry_list()[0];
211 EXPECT_FALSE(entry.is_directory);
212 EXPECT_EQ("blueberries.txt", entry.name);
213 EXPECT_EQ(4096, entry.size);
214 base::Time expected_time;
216 base::Time::FromString("Thu Apr 24 00:46:52 UTC 2014", &expected_time));
217 EXPECT_EQ(expected_time, entry.last_modified_time);
220 TEST_F(FileSystemProviderOperationsReadDirectoryTest, OnError) {
221 util::LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
222 CallbackLogger callback_logger;
224 ReadDirectory read_directory(NULL,
226 base::FilePath::FromUTF8Unsafe(kDirectoryPath),
227 base::Bind(&CallbackLogger::OnReadDirectory,
228 base::Unretained(&callback_logger)));
229 read_directory.SetDispatchEventImplForTesting(
230 base::Bind(&util::LoggingDispatchEventImpl::OnDispatchEventImpl,
231 base::Unretained(&dispatcher)));
233 EXPECT_TRUE(read_directory.Execute(kRequestId));
235 read_directory.OnError(kRequestId,
236 scoped_ptr<RequestValue>(new RequestValue()),
237 base::File::FILE_ERROR_TOO_MANY_OPENED);
239 ASSERT_EQ(1u, callback_logger.events().size());
240 CallbackLogger::Event* event = callback_logger.events()[0];
241 EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED, event->result());
242 ASSERT_EQ(0u, event->entry_list().size());
245 } // namespace operations
246 } // namespace file_system_provider
247 } // namespace chromeos