get_metadata_unittest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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.
4
5#include <string>
6
7#include "base/files/file.h"
8#include "base/files/file_path.h"
9#include "base/json/json_reader.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/memory/scoped_vector.h"
12#include "base/values.h"
13#include "chrome/browser/chromeos/file_system_provider/operations/get_metadata.h"
14#include "chrome/common/extensions/api/file_system_provider.h"
15#include "chrome/common/extensions/api/file_system_provider_internal.h"
16#include "extensions/browser/event_router.h"
17#include "testing/gtest/include/gtest/gtest.h"
18#include "webkit/browser/fileapi/async_file_util.h"
19
20namespace chromeos {
21namespace file_system_provider {
22namespace operations {
23namespace {
24
25const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
26const char kFileSystemId[] = "testing-file-system";
27const int kRequestId = 2;
28const base::FilePath::CharType kDirectoryPath[] = "/directory";
29
30// Fake event dispatcher implementation with extra logging capability. Acts as
31// a providing extension end-point.
32class LoggingDispatchEventImpl {
33 public:
34  explicit LoggingDispatchEventImpl(bool dispatch_reply)
35      : dispatch_reply_(dispatch_reply) {}
36  virtual ~LoggingDispatchEventImpl() {}
37
38  bool OnDispatchEventImpl(scoped_ptr<extensions::Event> event) {
39    events_.push_back(event->DeepCopy());
40    return dispatch_reply_;
41  }
42
43  ScopedVector<extensions::Event>& events() { return events_; }
44
45 private:
46  ScopedVector<extensions::Event> events_;
47  bool dispatch_reply_;
48
49  DISALLOW_COPY_AND_ASSIGN(LoggingDispatchEventImpl);
50};
51
52// Callback invocation logger. Acts as a fileapi end-point.
53class CallbackLogger {
54 public:
55  class Event {
56   public:
57    Event(base::File::Error result, const base::File::Info& file_info)
58        : result_(result), file_info_(file_info) {}
59    virtual ~Event() {}
60
61    base::File::Error result() { return result_; }
62    const base::File::Info& file_info() { return file_info_; }
63
64   private:
65    base::File::Error result_;
66    base::File::Info file_info_;
67
68    DISALLOW_COPY_AND_ASSIGN(Event);
69  };
70
71  CallbackLogger() : weak_ptr_factory_(this) {}
72  virtual ~CallbackLogger() {}
73
74  void OnGetMetadata(base::File::Error result,
75                     const base::File::Info& file_info) {
76    events_.push_back(new Event(result, file_info));
77  }
78
79  ScopedVector<Event>& events() { return events_; }
80
81  base::WeakPtr<CallbackLogger> GetWeakPtr() {
82    return weak_ptr_factory_.GetWeakPtr();
83  }
84
85 private:
86  ScopedVector<Event> events_;
87  bool dispatch_reply_;
88  base::WeakPtrFactory<CallbackLogger> weak_ptr_factory_;
89
90  DISALLOW_COPY_AND_ASSIGN(CallbackLogger);
91};
92
93}  // namespace
94
95class FileSystemProviderOperationsGetMetadataTest : public testing::Test {
96 protected:
97  FileSystemProviderOperationsGetMetadataTest() {}
98  virtual ~FileSystemProviderOperationsGetMetadataTest() {}
99
100  virtual void SetUp() OVERRIDE {
101    file_system_info_ =
102        ProvidedFileSystemInfo(kExtensionId,
103                               kFileSystemId,
104                               "" /* file_system_name */,
105                               base::FilePath() /* mount_path */);
106  }
107
108  ProvidedFileSystemInfo file_system_info_;
109};
110
111TEST_F(FileSystemProviderOperationsGetMetadataTest, Execute) {
112  LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
113  CallbackLogger callback_logger;
114
115  GetMetadata get_metadata(
116      NULL,
117      file_system_info_,
118      base::FilePath::FromUTF8Unsafe(kDirectoryPath),
119      base::Bind(&CallbackLogger::OnGetMetadata, callback_logger.GetWeakPtr()));
120  get_metadata.SetDispatchEventImplForTesting(
121      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
122                 base::Unretained(&dispatcher)));
123
124  EXPECT_TRUE(get_metadata.Execute(kRequestId));
125
126  ASSERT_EQ(1u, dispatcher.events().size());
127  extensions::Event* event = dispatcher.events()[0];
128  EXPECT_EQ(
129      extensions::api::file_system_provider::OnGetMetadataRequested::kEventName,
130      event->event_name);
131  base::ListValue* event_args = event->event_args.get();
132  ASSERT_EQ(3u, event_args->GetSize());
133
134  std::string event_file_system_id;
135  EXPECT_TRUE(event_args->GetString(0, &event_file_system_id));
136  EXPECT_EQ(kFileSystemId, event_file_system_id);
137
138  int event_request_id = -1;
139  EXPECT_TRUE(event_args->GetInteger(1, &event_request_id));
140  EXPECT_EQ(kRequestId, event_request_id);
141
142  std::string event_directory_path;
143  EXPECT_TRUE(event_args->GetString(2, &event_directory_path));
144  EXPECT_EQ(kDirectoryPath, event_directory_path);
145}
146
147TEST_F(FileSystemProviderOperationsGetMetadataTest, Execute_NoListener) {
148  LoggingDispatchEventImpl dispatcher(false /* dispatch_reply */);
149  CallbackLogger callback_logger;
150
151  GetMetadata get_metadata(
152      NULL,
153      file_system_info_,
154      base::FilePath::FromUTF8Unsafe(kDirectoryPath),
155      base::Bind(&CallbackLogger::OnGetMetadata, callback_logger.GetWeakPtr()));
156  get_metadata.SetDispatchEventImplForTesting(
157      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
158                 base::Unretained(&dispatcher)));
159
160  EXPECT_FALSE(get_metadata.Execute(kRequestId));
161}
162
163TEST_F(FileSystemProviderOperationsGetMetadataTest, OnSuccess) {
164  using extensions::api::file_system_provider::EntryMetadata;
165  using extensions::api::file_system_provider_internal::
166      GetMetadataRequestedSuccess::Params;
167
168  LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
169  CallbackLogger callback_logger;
170
171  GetMetadata get_metadata(
172      NULL,
173      file_system_info_,
174      base::FilePath::FromUTF8Unsafe(kDirectoryPath),
175      base::Bind(&CallbackLogger::OnGetMetadata, callback_logger.GetWeakPtr()));
176  get_metadata.SetDispatchEventImplForTesting(
177      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
178                 base::Unretained(&dispatcher)));
179
180  EXPECT_TRUE(get_metadata.Execute(kRequestId));
181
182  // Sample input as JSON. Keep in sync with file_system_provider_api.idl.
183  // As for now, it is impossible to create *::Params class directly, not from
184  // base::Value.
185  const std::string input =
186      "[\n"
187      "  \"testing-file-system\",\n"  // kFileSystemId
188      "  2,\n"                        // kRequestId
189      "  {\n"
190      "    \"isDirectory\": false,\n"
191      "    \"name\": \"blueberries.txt\",\n"
192      "    \"size\": 4096,\n"
193      "    \"modificationTime\": {\n"
194      "      \"value\": \"Thu Apr 24 00:46:52 UTC 2014\"\n"
195      "    }\n"
196      "  }\n"
197      "]\n";
198
199  int json_error_code;
200  std::string json_error_msg;
201  scoped_ptr<base::Value> value(base::JSONReader::ReadAndReturnError(
202      input, base::JSON_PARSE_RFC, &json_error_code, &json_error_msg));
203  ASSERT_TRUE(value.get()) << json_error_msg;
204
205  base::ListValue* value_as_list;
206  ASSERT_TRUE(value->GetAsList(&value_as_list));
207  scoped_ptr<Params> params(Params::Create(*value_as_list));
208  ASSERT_TRUE(params.get());
209  scoped_ptr<RequestValue> request_value(
210      RequestValue::CreateForGetMetadataSuccess(params.Pass()));
211  ASSERT_TRUE(request_value.get());
212
213  const bool has_next = false;
214  get_metadata.OnSuccess(kRequestId, request_value.Pass(), has_next);
215
216  ASSERT_EQ(1u, callback_logger.events().size());
217  CallbackLogger::Event* event = callback_logger.events()[0];
218  EXPECT_EQ(base::File::FILE_OK, event->result());
219
220  const base::File::Info& file_info = event->file_info();
221  EXPECT_FALSE(file_info.is_directory);
222  EXPECT_EQ(4096, file_info.size);
223  base::Time expected_time;
224  EXPECT_TRUE(
225      base::Time::FromString("Thu Apr 24 00:46:52 UTC 2014", &expected_time));
226  EXPECT_EQ(expected_time, file_info.last_modified);
227}
228
229TEST_F(FileSystemProviderOperationsGetMetadataTest, OnError) {
230  using extensions::api::file_system_provider::EntryMetadata;
231  using extensions::api::file_system_provider_internal::
232      GetMetadataRequestedError::Params;
233
234  LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
235  CallbackLogger callback_logger;
236
237  GetMetadata get_metadata(
238      NULL,
239      file_system_info_,
240      base::FilePath::FromUTF8Unsafe(kDirectoryPath),
241      base::Bind(&CallbackLogger::OnGetMetadata, callback_logger.GetWeakPtr()));
242  get_metadata.SetDispatchEventImplForTesting(
243      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
244                 base::Unretained(&dispatcher)));
245
246  EXPECT_TRUE(get_metadata.Execute(kRequestId));
247
248  get_metadata.OnError(kRequestId, base::File::FILE_ERROR_TOO_MANY_OPENED);
249
250  ASSERT_EQ(1u, callback_logger.events().size());
251  CallbackLogger::Event* event = callback_logger.events()[0];
252  EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED, event->result());
253}
254
255}  // namespace operations
256}  // namespace file_system_provider
257}  // namespace chromeos
258