ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / chromeos / extensions / file_manager / file_browser_handler_api_test.cc
blobfa3a346a7086ac97d8d0ac46da7b9817fc6cb423
1 // Copyright (c) 2012 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 // File contains browser tests for the fileBrowserHandler api.
7 #include "chrome/browser/chromeos/extensions/file_manager/file_browser_handler_api.h"
9 #include <vector>
11 #include "base/bind.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/values.h"
14 #include "chrome/browser/extensions/extension_apitest.h"
15 #include "chrome/browser/extensions/extension_function_test_utils.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/test/base/in_process_browser_test.h"
19 #include "chrome/test/base/ui_test_utils.h"
20 #include "content/public/browser/browser_context.h"
21 #include "extensions/browser/api_test_utils.h"
22 #include "extensions/common/extension.h"
23 #include "extensions/test/result_catcher.h"
24 #include "storage/browser/fileapi/external_mount_points.h"
25 #include "storage/common/fileapi/file_system_types.h"
27 namespace utils = extension_function_test_utils;
29 using content::BrowserContext;
30 using extensions::Extension;
32 namespace {
34 // Data that defines FileSelector behaviour in each test case.
35 struct TestCase {
36 TestCase(const base::FilePath& suggested_name,
37 const std::vector<std::string>& allowed_extensions,
38 bool success,
39 const base::FilePath& selected_path)
40 : suggested_name(suggested_name),
41 allowed_extensions(allowed_extensions),
42 success(success),
43 selected_path(selected_path) {
45 ~TestCase() {}
47 // Path that we expect to be suggested to the file selector.
48 base::FilePath suggested_name;
50 // Extensions that we expect to be allowed to the file selector.
51 std::vector<std::string> allowed_extensions;
53 // Whether file selector should fail.
54 bool success;
55 // The path file selector should return back to the function.
56 base::FilePath selected_path;
59 // Checks that file under path |selected_path| contains |expected_contents|.
60 // Must be called on the file thread.
61 void ExpectFileContentEquals(const base::FilePath& selected_path,
62 const std::string& expected_contents) {
63 std::string test_file_contents;
64 ASSERT_TRUE(base::ReadFileToString(selected_path, &test_file_contents));
65 EXPECT_EQ(expected_contents, test_file_contents);
68 // Mocks FileSelector used by FileBrowserHandlerInternalSelectFileFunction.
69 // When |SelectFile| is called, it will check that file name suggestion is as
70 // expected, and respond to the extension function with specified selection
71 // results.
72 class MockFileSelector : public file_manager::FileSelector {
73 public:
74 MockFileSelector(const base::FilePath& suggested_name,
75 const std::vector<std::string>& allowed_extensions,
76 bool success,
77 const base::FilePath& selected_path)
78 : suggested_name_(suggested_name),
79 allowed_extensions_(allowed_extensions),
80 success_(success),
81 selected_path_(selected_path) {
83 ~MockFileSelector() override {}
85 // file_manager::FileSelector implementation.
86 // |browser| is not used.
87 void SelectFile(
88 const base::FilePath& suggested_name,
89 const std::vector<std::string>& allowed_extensions,
90 Browser* browser,
91 FileBrowserHandlerInternalSelectFileFunction* function) override {
92 // Confirm that the function suggested us the right name.
93 EXPECT_EQ(suggested_name_, suggested_name);
94 // Confirm that the function allowed us the right extensions.
95 EXPECT_EQ(allowed_extensions_.size(), allowed_extensions.size());
96 if (allowed_extensions_.size() == allowed_extensions.size()) {
97 for (size_t i = 0; i < allowed_extensions_.size(); ++i) {
98 EXPECT_EQ(allowed_extensions_[i], allowed_extensions[i]);
102 // Send response to the extension function.
103 // The callback will take a reference to the function and keep it alive.
104 base::MessageLoopProxy::current()->PostTask(FROM_HERE,
105 base::Bind(&FileBrowserHandlerInternalSelectFileFunction::
106 OnFilePathSelected,
107 function, success_, selected_path_));
108 delete this;
111 private:
112 // File name that is expected to be suggested by the function.
113 base::FilePath suggested_name_;
115 // Extensions that is expected to be allowed by the function.
116 std::vector<std::string> allowed_extensions_;
118 // Whether the selection should succeed.
119 bool success_;
120 // File path that should be returned to the function.
121 base::FilePath selected_path_;
123 DISALLOW_COPY_AND_ASSIGN(MockFileSelector);
126 // Mocks file selector factory for the test.
127 // When |CreateFileSelector| is invoked it will create mock file selector for
128 // the extension function with test parameters from the object ctor.
129 class MockFileSelectorFactory : public file_manager::FileSelectorFactory {
130 public:
131 explicit MockFileSelectorFactory(const TestCase& test_case)
132 : suggested_name_(test_case.suggested_name),
133 allowed_extensions_(test_case.allowed_extensions),
134 success_(test_case.success),
135 selected_path_(test_case.selected_path) {
137 ~MockFileSelectorFactory() override {}
139 // file_manager::FileSelectorFactory implementation.
140 file_manager::FileSelector* CreateFileSelector() const override {
141 return new MockFileSelector(suggested_name_,
142 allowed_extensions_,
143 success_,
144 selected_path_);
147 private:
148 // File name that is expected to be suggested by the function.
149 base::FilePath suggested_name_;
150 // Extensions that is expected to be allowed by the function.
151 std::vector<std::string> allowed_extensions_;
152 // Whether the selection should succeed.
153 bool success_;
154 // File path that should be returned to the function.
155 base::FilePath selected_path_;
157 DISALLOW_COPY_AND_ASSIGN(MockFileSelectorFactory);
160 // Extension api test for the fileBrowserHandler extension API.
161 class FileBrowserHandlerExtensionTest : public ExtensionApiTest {
162 protected:
163 void SetUp() override {
164 // Create mount point directory that will be used in the test.
165 // Mount point will be called "tmp", and it will be located in a tmp
166 // directory with an unique name.
167 ASSERT_TRUE(scoped_tmp_dir_.CreateUniqueTempDir());
168 tmp_mount_point_ = scoped_tmp_dir_.path().Append("tmp");
169 base::CreateDirectory(tmp_mount_point_);
171 ExtensionApiTest::SetUp();
174 // Creates new, test mount point.
175 void AddTmpMountPoint(const std::string& extension_id) {
176 BrowserContext::GetMountPoints(browser()->profile())
177 ->RegisterFileSystem("tmp",
178 storage::kFileSystemTypeNativeLocal,
179 storage::FileSystemMountOption(),
180 tmp_mount_point_);
183 base::FilePath GetFullPathOnTmpMountPoint(
184 const base::FilePath& relative_path) {
185 return tmp_mount_point_.Append(relative_path);
188 // Creates a new FileBrowserHandlerInternalSelectFileFunction to be used in
189 // the test. This function will be called from ExtensionFunctinoDispatcher
190 // whenever an extension function for fileBrowserHandlerInternal.selectFile
191 // will be needed.
192 static ExtensionFunction* TestSelectFileFunctionFactory() {
193 EXPECT_TRUE(test_cases_);
194 EXPECT_TRUE(!test_cases_ || current_test_case_ < test_cases_->size());
196 // If this happens, test failed. But, we still don't want to crash, so
197 // return valid extension function.
198 if (!test_cases_ || current_test_case_ >= test_cases_->size())
199 return new FileBrowserHandlerInternalSelectFileFunction();
201 // Create file creator factory for the current test case.
202 MockFileSelectorFactory* mock_factory =
203 new MockFileSelectorFactory(test_cases_->at(current_test_case_));
204 current_test_case_++;
206 return new FileBrowserHandlerInternalSelectFileFunction(
207 mock_factory, false);
210 // Sets up test parameters for extension function invocations that will be
211 // made during the test.
212 void SetTestCases(const std::vector<TestCase>* test_cases) {
213 test_cases_ = test_cases;
214 current_test_case_ = 0;
217 private:
218 // List of test parameters for each extension function invocation that will be
219 // made during a test.
220 // Should be owned by the test code.
221 static const std::vector<TestCase>* test_cases_;
222 static size_t current_test_case_;
224 base::ScopedTempDir scoped_tmp_dir_;
225 // Our test mount point path.
226 base::FilePath tmp_mount_point_;
229 const std::vector<TestCase>* FileBrowserHandlerExtensionTest::test_cases_ =
230 NULL;
231 size_t FileBrowserHandlerExtensionTest::current_test_case_ = 0;
233 // End to end test that verifies that fileBrowserHandler.selectFile works as
234 // expected. It will run test extension under
235 // chrome/test/data/extensions/api_test/file_browser/filehandler_create.
236 // The extension will invoke fileBrowserHandler.selectFile function twice.
237 // Once with suggested name "some_file_name.txt", and once with suggested name
238 // "fail". The file selection should succeed the first time, but fail the second
239 // time. When the file is selected the test extension will verify that it can
240 // create, read and write the file under the selected file path.
241 IN_PROC_BROWSER_TEST_F(FileBrowserHandlerExtensionTest, EndToEnd) {
242 // Path that will be "selected" by file selector.
243 const base::FilePath selected_path =
244 GetFullPathOnTmpMountPoint(base::FilePath("test_file.txt"));
246 std::vector<std::string> allowed_extensions;
247 allowed_extensions.push_back("txt");
248 allowed_extensions.push_back("html");
250 std::vector<TestCase> test_cases;
251 test_cases.push_back(
252 TestCase(base::FilePath("some_file_name.txt"),
253 allowed_extensions,
254 true,
255 selected_path));
256 test_cases.push_back(
257 TestCase(base::FilePath("fail"),
258 std::vector<std::string>(),
259 false,
260 base::FilePath()));
262 SetTestCases(&test_cases);
264 // Override extension function that will be used during the test.
265 ASSERT_TRUE(extensions::ExtensionFunctionDispatcher::OverrideFunction(
266 "fileBrowserHandlerInternal.selectFile",
267 FileBrowserHandlerExtensionTest::TestSelectFileFunctionFactory));
269 // Selected path should still not exist.
270 ASSERT_FALSE(base::PathExists(selected_path));
272 const Extension* extension = LoadExtension(
273 test_data_dir_.AppendASCII("file_browser/filehandler_create"));
274 ASSERT_TRUE(extension) << message_;
276 AddTmpMountPoint(extension->id());
278 extensions::ResultCatcher catcher;
280 GURL url = extension->GetResourceURL("test.html");
281 ui_test_utils::NavigateToURL(browser(), url);
283 ASSERT_TRUE(catcher.GetNextResult()) << message_;
285 // Selected path should have been created by the test extension after the
286 // extension function call.
287 ASSERT_TRUE(base::PathExists(selected_path));
289 // Let's check that the file has the expected content.
290 const std::string expected_contents = "hello from test extension.";
291 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
292 base::Bind(&ExpectFileContentEquals, selected_path, expected_contents));
294 // Make sure test doesn't finish until we check on file thread that the
295 // selected file's content is as expected.
296 content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
298 SetTestCases(NULL);
301 // Tests that verifies the fileBrowserHandlerInternal.selectFile function fails
302 // when invoked without user gesture.
303 IN_PROC_BROWSER_TEST_F(FileBrowserHandlerExtensionTest, NoUserGesture) {
304 scoped_refptr<FileBrowserHandlerInternalSelectFileFunction>
305 select_file_function(
306 new FileBrowserHandlerInternalSelectFileFunction());
308 std::string error =
309 utils::RunFunctionAndReturnError(
310 select_file_function.get(),
311 "[{\"suggestedName\": \"foo\"}]",
312 browser());
314 const std::string expected_error =
315 "This method can only be called in response to user gesture, such as a "
316 "mouse click or key press.";
317 EXPECT_EQ(expected_error, error);
320 // Tests that checks that the fileHandlerInternal.selectFile function returns
321 // dictionary with |success == false| and no file entry when user cancels file
322 // selection.
323 IN_PROC_BROWSER_TEST_F(FileBrowserHandlerExtensionTest, SelectionFailed) {
324 TestCase test_case(base::FilePath("some_file_name.txt"),
325 std::vector<std::string>(),
326 false,
327 base::FilePath());
329 scoped_refptr<FileBrowserHandlerInternalSelectFileFunction>
330 select_file_function(
331 new FileBrowserHandlerInternalSelectFileFunction(
332 new MockFileSelectorFactory(test_case),
333 false));
335 select_file_function->set_has_callback(true);
336 select_file_function->set_user_gesture(true);
338 scoped_ptr<base::DictionaryValue> result(utils::ToDictionary(
339 utils::RunFunctionAndReturnSingleResult(
340 select_file_function.get(),
341 "[{\"suggestedName\": \"some_file_name.txt\"}]",
342 browser())));
344 EXPECT_FALSE(extensions::api_test_utils::GetBoolean(result.get(), "success"));
345 base::DictionaryValue* entry_info;
346 EXPECT_FALSE(result->GetDictionary("entry", &entry_info));
349 // Tests that user cannot be suggested a full file path when selecting a file,
350 // only a file name (i.e. that extension function caller has no influence on
351 // which directory contents will be initially displayed in selection dialog).
352 IN_PROC_BROWSER_TEST_F(FileBrowserHandlerExtensionTest, SuggestedFullPath) {
353 TestCase test_case(base::FilePath("some_file_name.txt"),
354 std::vector<std::string>(),
355 false,
356 base::FilePath());
358 scoped_refptr<FileBrowserHandlerInternalSelectFileFunction>
359 select_file_function(
360 new FileBrowserHandlerInternalSelectFileFunction(
361 new MockFileSelectorFactory(test_case),
362 false));
364 select_file_function->set_has_callback(true);
365 select_file_function->set_user_gesture(true);
367 scoped_ptr<base::DictionaryValue> result(utils::ToDictionary(
368 utils::RunFunctionAndReturnSingleResult(
369 select_file_function.get(),
370 "[{\"suggestedName\": \"/path_to_file/some_file_name.txt\"}]",
371 browser())));
373 EXPECT_FALSE(extensions::api_test_utils::GetBoolean(result.get(), "success"));
374 base::DictionaryValue* entry_info;
375 EXPECT_FALSE(result->GetDictionary("entry", &entry_info));
378 } // namespace