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#include <vector>
7
8#include "base/files/file.h"
9#include "base/files/file_path.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/memory/scoped_vector.h"
12#include "chrome/browser/chromeos/file_system_provider/operations/unmount.h"
13#include "chrome/browser/chromeos/file_system_provider/provided_file_system_interface.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
19namespace chromeos {
20namespace file_system_provider {
21namespace operations {
22namespace {
23
24const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
25const char kFileSystemId[] = "testing-file-system";
26const int kRequestId = 2;
27
28// Fake event dispatcher implementation with extra logging capability. Acts as
29// a providing extension end-point.
30class LoggingDispatchEventImpl {
31 public:
32  explicit LoggingDispatchEventImpl(bool dispatch_reply)
33      : dispatch_reply_(dispatch_reply) {}
34  virtual ~LoggingDispatchEventImpl() {}
35
36  bool OnDispatchEventImpl(scoped_ptr<extensions::Event> event) {
37    events_.push_back(event->DeepCopy());
38    return dispatch_reply_;
39  }
40
41  ScopedVector<extensions::Event>& events() { return events_; }
42
43 private:
44  ScopedVector<extensions::Event> events_;
45  bool dispatch_reply_;
46
47  DISALLOW_COPY_AND_ASSIGN(LoggingDispatchEventImpl);
48};
49
50// Callback invocation logger. Acts as a fileapi end-point.
51class CallbackLogger {
52 public:
53  CallbackLogger() : weak_ptr_factory_(this) {}
54  virtual ~CallbackLogger() {}
55
56  void OnUnmount(base::File::Error result) { events_.push_back(result); }
57
58  std::vector<base::File::Error>& events() { return events_; }
59
60  base::WeakPtr<CallbackLogger> GetWeakPtr() {
61    return weak_ptr_factory_.GetWeakPtr();
62  }
63
64 private:
65  std::vector<base::File::Error> events_;
66  bool dispatch_reply_;
67  base::WeakPtrFactory<CallbackLogger> weak_ptr_factory_;
68
69  DISALLOW_COPY_AND_ASSIGN(CallbackLogger);
70};
71
72}  // namespace
73
74class FileSystemProviderOperationsUnmountTest : public testing::Test {
75 protected:
76  FileSystemProviderOperationsUnmountTest() {}
77  virtual ~FileSystemProviderOperationsUnmountTest() {}
78
79  virtual void SetUp() OVERRIDE {
80    file_system_info_ =
81        ProvidedFileSystemInfo(kExtensionId,
82                               kFileSystemId,
83                               "" /* file_system_name */,
84                               base::FilePath() /* mount_path */);
85  }
86
87  ProvidedFileSystemInfo file_system_info_;
88};
89
90TEST_F(FileSystemProviderOperationsUnmountTest, Execute) {
91  LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
92  CallbackLogger callback_logger;
93
94  Unmount unmount(
95      NULL,
96      file_system_info_,
97      base::Bind(&CallbackLogger::OnUnmount, callback_logger.GetWeakPtr()));
98  unmount.SetDispatchEventImplForTesting(
99      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
100                 base::Unretained(&dispatcher)));
101
102  EXPECT_TRUE(unmount.Execute(kRequestId));
103
104  ASSERT_EQ(1u, dispatcher.events().size());
105  extensions::Event* event = dispatcher.events()[0];
106  EXPECT_EQ(
107      extensions::api::file_system_provider::OnUnmountRequested::kEventName,
108      event->event_name);
109  base::ListValue* event_args = event->event_args.get();
110  ASSERT_EQ(1u, event_args->GetSize());
111
112  base::DictionaryValue* options = NULL;
113  ASSERT_TRUE(event_args->GetDictionary(0, &options));
114
115  std::string event_file_system_id;
116  EXPECT_TRUE(options->GetString("fileSystemId", &event_file_system_id));
117  EXPECT_EQ(kFileSystemId, event_file_system_id);
118
119  int event_request_id = -1;
120  EXPECT_TRUE(options->GetInteger("requestId", &event_request_id));
121  EXPECT_EQ(kRequestId, event_request_id);
122}
123
124TEST_F(FileSystemProviderOperationsUnmountTest, Execute_NoListener) {
125  LoggingDispatchEventImpl dispatcher(false /* dispatch_reply */);
126  CallbackLogger callback_logger;
127
128  Unmount unmount(
129      NULL,
130      file_system_info_,
131      base::Bind(&CallbackLogger::OnUnmount, callback_logger.GetWeakPtr()));
132  unmount.SetDispatchEventImplForTesting(
133      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
134                 base::Unretained(&dispatcher)));
135
136  EXPECT_FALSE(unmount.Execute(kRequestId));
137}
138
139TEST_F(FileSystemProviderOperationsUnmountTest, OnSuccess) {
140  using extensions::api::file_system_provider_internal::
141      UnmountRequestedSuccess::Params;
142
143  LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
144  CallbackLogger callback_logger;
145
146  Unmount unmount(
147      NULL,
148      file_system_info_,
149      base::Bind(&CallbackLogger::OnUnmount, callback_logger.GetWeakPtr()));
150  unmount.SetDispatchEventImplForTesting(
151      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
152                 base::Unretained(&dispatcher)));
153
154  EXPECT_TRUE(unmount.Execute(kRequestId));
155
156  unmount.OnSuccess(kRequestId,
157                    scoped_ptr<RequestValue>(new RequestValue()),
158                    false /* has_more */);
159  ASSERT_EQ(1u, callback_logger.events().size());
160  base::File::Error event_result = callback_logger.events()[0];
161  EXPECT_EQ(base::File::FILE_OK, event_result);
162}
163
164TEST_F(FileSystemProviderOperationsUnmountTest, OnError) {
165  using extensions::api::file_system_provider_internal::UnmountRequestedError::
166      Params;
167
168  LoggingDispatchEventImpl dispatcher(true /* dispatch_reply */);
169  CallbackLogger callback_logger;
170
171  Unmount unmount(
172      NULL,
173      file_system_info_,
174      base::Bind(&CallbackLogger::OnUnmount, callback_logger.GetWeakPtr()));
175  unmount.SetDispatchEventImplForTesting(
176      base::Bind(&LoggingDispatchEventImpl::OnDispatchEventImpl,
177                 base::Unretained(&dispatcher)));
178
179  EXPECT_TRUE(unmount.Execute(kRequestId));
180
181  unmount.OnError(kRequestId, base::File::FILE_ERROR_NOT_FOUND);
182  ASSERT_EQ(1u, callback_logger.events().size());
183  base::File::Error event_result = callback_logger.events()[0];
184  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, event_result);
185}
186
187}  // namespace operations
188}  // namespace file_system_provider
189}  // namespace chromeos
190