1 // Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4
5 #include "include/base/cef_callback.h"
6 #include "include/wrapper/cef_closure_task.h"
7 #include "tests/ceftests/test_handler.h"
8 #include "tests/ceftests/test_util.h"
9 #include "tests/gtest/include/gtest/gtest.h"
10
11 namespace {
12
13 const char* kTestUrl = "http://tests/DialogTestHandler";
14
15 class DialogTestHandler : public TestHandler {
16 public:
17 struct TestConfig {
TestConfig__anon1185eb130111::DialogTestHandler::TestConfig18 explicit TestConfig(FileDialogMode dialog_mode)
19 : mode(dialog_mode),
20 title("Test Title"),
21 default_file_name("Test File Name"),
22 selected_accept_filter(1), // Something other than 0 for testing.
23 callback_async(false),
24 callback_cancel(false) {
25 accept_types.push_back("text/*");
26 accept_types.push_back(".js");
27 accept_types.push_back(".css");
28 }
29
30 FileDialogMode mode;
31 CefString title;
32 CefString default_file_name;
33 std::vector<CefString> accept_types;
34 int selected_accept_filter;
35
36 bool callback_async; // True if the callback should execute asynchronously.
37 bool callback_cancel; // True if the callback should cancel.
38 std::vector<CefString> callback_paths; // Resulting paths if not cancelled.
39 };
40
41 class Callback : public CefRunFileDialogCallback {
42 public:
Callback(DialogTestHandler * handler)43 explicit Callback(DialogTestHandler* handler) : handler_(handler) {}
44
OnFileDialogDismissed(int selected_accept_filter,const std::vector<CefString> & file_paths)45 void OnFileDialogDismissed(
46 int selected_accept_filter,
47 const std::vector<CefString>& file_paths) override {
48 handler_->got_onfiledialogdismissed_.yes();
49
50 if (handler_->config_.callback_cancel) {
51 EXPECT_EQ(0, selected_accept_filter);
52 EXPECT_TRUE(file_paths.empty());
53 } else {
54 EXPECT_EQ(handler_->config_.selected_accept_filter,
55 selected_accept_filter);
56 TestStringVectorEqual(handler_->config_.callback_paths, file_paths);
57 }
58
59 handler_->DestroyTest();
60 handler_ = nullptr;
61 }
62
63 private:
64 DialogTestHandler* handler_;
65
66 IMPLEMENT_REFCOUNTING(Callback);
67 };
68
DialogTestHandler(const TestConfig & config)69 explicit DialogTestHandler(const TestConfig& config) : config_(config) {}
70
RunTest()71 void RunTest() override {
72 AddResource(kTestUrl, "<html><body>TEST</body></html>", "text/html");
73
74 // Create the browser
75 CreateBrowser(kTestUrl);
76
77 // Time out the test after a reasonable period of time.
78 SetTestTimeout();
79 }
80
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int httpStatusCode)81 void OnLoadEnd(CefRefPtr<CefBrowser> browser,
82 CefRefPtr<CefFrame> frame,
83 int httpStatusCode) override {
84 browser->GetHost()->RunFileDialog(
85 config_.mode, config_.title, config_.default_file_name,
86 config_.accept_types, config_.selected_accept_filter,
87 new Callback(this));
88 }
89
ExecuteCallback(CefRefPtr<CefFileDialogCallback> callback)90 void ExecuteCallback(CefRefPtr<CefFileDialogCallback> callback) {
91 if (config_.callback_cancel)
92 callback->Cancel();
93 else
94 callback->Continue(config_.selected_accept_filter,
95 config_.callback_paths);
96 }
97
98 // CefDialogHandler
OnFileDialog(CefRefPtr<CefBrowser> browser,FileDialogMode mode,const CefString & title,const CefString & default_file_name,const std::vector<CefString> & accept_types,int selected_accept_filter,CefRefPtr<CefFileDialogCallback> callback)99 bool OnFileDialog(CefRefPtr<CefBrowser> browser,
100 FileDialogMode mode,
101 const CefString& title,
102 const CefString& default_file_name,
103 const std::vector<CefString>& accept_types,
104 int selected_accept_filter,
105 CefRefPtr<CefFileDialogCallback> callback) override {
106 got_onfiledialog_.yes();
107
108 std::string url = browser->GetMainFrame()->GetURL();
109 EXPECT_STREQ(kTestUrl, url.c_str());
110
111 EXPECT_EQ(config_.mode, mode);
112 EXPECT_STREQ(config_.title.ToString().c_str(), title.ToString().c_str());
113 EXPECT_STREQ(config_.default_file_name.ToString().c_str(),
114 default_file_name.ToString().c_str());
115 TestStringVectorEqual(config_.accept_types, accept_types);
116
117 if (config_.callback_async) {
118 CefPostTask(TID_UI, base::BindOnce(&DialogTestHandler::ExecuteCallback,
119 this, callback));
120 } else {
121 ExecuteCallback(callback);
122 }
123
124 return true;
125 }
126
DestroyTest()127 void DestroyTest() override {
128 EXPECT_TRUE(got_onfiledialog_);
129 EXPECT_TRUE(got_onfiledialogdismissed_);
130
131 TestHandler::DestroyTest();
132 }
133
134 TestConfig config_;
135
136 TrackCallback got_onfiledialog_;
137 TrackCallback got_onfiledialogdismissed_;
138
139 IMPLEMENT_REFCOUNTING(DialogTestHandler);
140 };
141
142 } // namespace
143
144 // Test with all parameters empty.
TEST(DialogTest,FileEmptyParams)145 TEST(DialogTest, FileEmptyParams) {
146 DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN);
147 config.title.clear();
148 config.default_file_name.clear();
149 config.accept_types.clear();
150 config.callback_async = false;
151 config.callback_cancel = false;
152
153 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
154 handler->ExecuteTest();
155 ReleaseAndWaitForDestructor(handler);
156 }
157
TEST(DialogTest,FileAdditionalFlags)158 TEST(DialogTest, FileAdditionalFlags) {
159 DialogTestHandler::TestConfig config(static_cast<cef_file_dialog_mode_t>(
160 FILE_DIALOG_OPEN | FILE_DIALOG_HIDEREADONLY_FLAG |
161 FILE_DIALOG_OVERWRITEPROMPT_FLAG));
162 config.title.clear();
163 config.default_file_name.clear();
164 config.accept_types.clear();
165 config.callback_async = false;
166 config.callback_cancel = false;
167
168 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
169 handler->ExecuteTest();
170 ReleaseAndWaitForDestructor(handler);
171 }
172
TEST(DialogTest,FileOpen)173 TEST(DialogTest, FileOpen) {
174 DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN);
175 config.callback_async = false;
176 config.callback_cancel = false;
177 config.callback_paths.push_back("/path/to/file1.txt");
178
179 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
180 handler->ExecuteTest();
181 ReleaseAndWaitForDestructor(handler);
182 }
183
TEST(DialogTest,FileOpenCancel)184 TEST(DialogTest, FileOpenCancel) {
185 DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN);
186 config.callback_async = false;
187 config.callback_cancel = true;
188
189 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
190 handler->ExecuteTest();
191 ReleaseAndWaitForDestructor(handler);
192 }
193
TEST(DialogTest,FileOpenAsync)194 TEST(DialogTest, FileOpenAsync) {
195 DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN);
196 config.callback_async = true;
197 config.callback_cancel = false;
198 config.callback_paths.push_back("/path/to/file1.txt");
199
200 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
201 handler->ExecuteTest();
202 ReleaseAndWaitForDestructor(handler);
203 }
204
TEST(DialogTest,FileOpenAsyncCancel)205 TEST(DialogTest, FileOpenAsyncCancel) {
206 DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN);
207 config.callback_async = false;
208 config.callback_cancel = true;
209
210 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
211 handler->ExecuteTest();
212 ReleaseAndWaitForDestructor(handler);
213 }
214
TEST(DialogTest,FileOpenMultiple)215 TEST(DialogTest, FileOpenMultiple) {
216 DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN_MULTIPLE);
217 config.callback_async = false;
218 config.callback_cancel = false;
219 config.callback_paths.push_back("/path/to/file1.txt");
220 config.callback_paths.push_back("/path/to/file2.txt");
221
222 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
223 handler->ExecuteTest();
224 ReleaseAndWaitForDestructor(handler);
225 }
226
TEST(DialogTest,FileOpenMultipleCancel)227 TEST(DialogTest, FileOpenMultipleCancel) {
228 DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN_MULTIPLE);
229 config.callback_async = false;
230 config.callback_cancel = true;
231
232 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
233 handler->ExecuteTest();
234 ReleaseAndWaitForDestructor(handler);
235 }
236
TEST(DialogTest,FileOpenMultipleAsync)237 TEST(DialogTest, FileOpenMultipleAsync) {
238 DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN_MULTIPLE);
239 config.callback_async = true;
240 config.callback_cancel = false;
241 config.callback_paths.push_back("/path/to/file1.txt");
242 config.callback_paths.push_back("/path/to/file2.txt");
243
244 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
245 handler->ExecuteTest();
246 ReleaseAndWaitForDestructor(handler);
247 }
248
TEST(DialogTest,FileOpenMultipleAsyncCancel)249 TEST(DialogTest, FileOpenMultipleAsyncCancel) {
250 DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN_MULTIPLE);
251 config.callback_async = false;
252 config.callback_cancel = true;
253
254 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
255 handler->ExecuteTest();
256 ReleaseAndWaitForDestructor(handler);
257 }
258
TEST(DialogTest,FileOpenFolder)259 TEST(DialogTest, FileOpenFolder) {
260 DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN_FOLDER);
261 config.callback_async = false;
262 config.callback_cancel = false;
263 config.callback_paths.push_back("/path/to/folder");
264
265 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
266 handler->ExecuteTest();
267 ReleaseAndWaitForDestructor(handler);
268 }
269
TEST(DialogTest,FileOpenFolderCancel)270 TEST(DialogTest, FileOpenFolderCancel) {
271 DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN_FOLDER);
272 config.callback_async = false;
273 config.callback_cancel = true;
274
275 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
276 handler->ExecuteTest();
277 ReleaseAndWaitForDestructor(handler);
278 }
279
TEST(DialogTest,FileOpenFolderAsync)280 TEST(DialogTest, FileOpenFolderAsync) {
281 DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN_FOLDER);
282 config.callback_async = true;
283 config.callback_cancel = false;
284 config.callback_paths.push_back("/path/to/folder");
285
286 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
287 handler->ExecuteTest();
288 ReleaseAndWaitForDestructor(handler);
289 }
290
TEST(DialogTest,FileOpenFolderAsyncCancel)291 TEST(DialogTest, FileOpenFolderAsyncCancel) {
292 DialogTestHandler::TestConfig config(FILE_DIALOG_OPEN_FOLDER);
293 config.callback_async = false;
294 config.callback_cancel = true;
295
296 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
297 handler->ExecuteTest();
298 ReleaseAndWaitForDestructor(handler);
299 }
300
TEST(DialogTest,FileSave)301 TEST(DialogTest, FileSave) {
302 DialogTestHandler::TestConfig config(FILE_DIALOG_SAVE);
303 config.callback_async = false;
304 config.callback_cancel = false;
305 config.callback_paths.push_back("/path/to/file1.txt");
306
307 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
308 handler->ExecuteTest();
309 ReleaseAndWaitForDestructor(handler);
310 }
311
TEST(DialogTest,FileSaveCancel)312 TEST(DialogTest, FileSaveCancel) {
313 DialogTestHandler::TestConfig config(FILE_DIALOG_SAVE);
314 config.callback_async = false;
315 config.callback_cancel = true;
316
317 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
318 handler->ExecuteTest();
319 ReleaseAndWaitForDestructor(handler);
320 }
321
TEST(DialogTest,FileSaveAsync)322 TEST(DialogTest, FileSaveAsync) {
323 DialogTestHandler::TestConfig config(FILE_DIALOG_SAVE);
324 config.callback_async = true;
325 config.callback_cancel = false;
326 config.callback_paths.push_back("/path/to/file1.txt");
327
328 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
329 handler->ExecuteTest();
330 ReleaseAndWaitForDestructor(handler);
331 }
332
TEST(DialogTest,FileSaveAsyncCancel)333 TEST(DialogTest, FileSaveAsyncCancel) {
334 DialogTestHandler::TestConfig config(FILE_DIALOG_SAVE);
335 config.callback_async = false;
336 config.callback_cancel = true;
337
338 CefRefPtr<DialogTestHandler> handler = new DialogTestHandler(config);
339 handler->ExecuteTest();
340 ReleaseAndWaitForDestructor(handler);
341 }
342