OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/json/json_reader.h" | |
9 #include "base/json/json_writer.h" | |
10 #include "base/message_loop.h" | |
8 #include "base/scoped_temp_dir.h" | 11 #include "base/scoped_temp_dir.h" |
12 #include "base/stl_util.h" | |
9 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
10 #include "chrome/browser/download/download_extension_api.h" | 14 #include "chrome/browser/download/download_extension_api.h" |
11 #include "chrome/browser/download/download_file_icon_extractor.h" | 15 #include "chrome/browser/download/download_file_icon_extractor.h" |
12 #include "chrome/browser/download/download_service.h" | 16 #include "chrome/browser/download/download_service.h" |
13 #include "chrome/browser/download/download_service_factory.h" | 17 #include "chrome/browser/download/download_service_factory.h" |
14 #include "chrome/browser/download/download_test_observer.h" | 18 #include "chrome/browser/download/download_test_observer.h" |
19 #include "chrome/browser/extensions/extension_apitest.h" | |
20 #include "chrome/browser/extensions/extension_event_names.h" | |
15 #include "chrome/browser/extensions/extension_function_test_utils.h" | 21 #include "chrome/browser/extensions/extension_function_test_utils.h" |
16 #include "chrome/browser/net/url_request_mock_util.h" | 22 #include "chrome/browser/net/url_request_mock_util.h" |
17 #include "chrome/browser/prefs/pref_service.h" | 23 #include "chrome/browser/prefs/pref_service.h" |
18 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/browser/ui/browser.h" | 25 #include "chrome/browser/ui/browser.h" |
26 #include "chrome/browser/ui/tab_contents/tab_contents.h" | |
27 #include "chrome/common/chrome_notification_types.h" | |
20 #include "chrome/common/pref_names.h" | 28 #include "chrome/common/pref_names.h" |
21 #include "chrome/test/base/in_process_browser_test.h" | 29 #include "chrome/test/base/in_process_browser_test.h" |
22 #include "chrome/test/base/ui_test_utils.h" | 30 #include "chrome/test/base/ui_test_utils.h" |
31 #include "content/public/browser/browser_context.h" | |
23 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
33 #include "content/public/browser/download_item.h" | |
24 #include "content/public/browser/download_manager.h" | 34 #include "content/public/browser/download_manager.h" |
25 #include "content/public/browser/download_persistent_store_info.h" | 35 #include "content/public/browser/download_persistent_store_info.h" |
36 #include "content/public/browser/notification_service.h" | |
37 #include "content/public/browser/web_contents.h" | |
38 #include "content/public/common/page_transition_types.h" | |
26 #include "content/test/net/url_request_slow_download_job.h" | 39 #include "content/test/net/url_request_slow_download_job.h" |
27 #include "net/base/data_url.h" | 40 #include "net/base/data_url.h" |
28 #include "net/base/net_util.h" | 41 #include "net/base/net_util.h" |
29 #include "ui/gfx/codec/png_codec.h" | 42 #include "ui/gfx/codec/png_codec.h" |
43 #include "webkit/fileapi/file_system_context.h" | |
44 #include "webkit/fileapi/file_system_operation_interface.h" | |
30 | 45 |
31 using content::BrowserContext; | 46 using content::BrowserContext; |
32 using content::BrowserThread; | 47 using content::BrowserThread; |
33 using content::DownloadItem; | 48 using content::DownloadItem; |
34 using content::DownloadManager; | 49 using content::DownloadManager; |
35 using content::DownloadPersistentStoreInfo; | 50 using content::DownloadPersistentStoreInfo; |
36 | 51 |
37 namespace { | 52 namespace { |
38 | 53 |
39 // Comparator that orders download items by their ID. Can be used with | 54 // Comparator that orders download items by their ID. Can be used with |
40 // std::sort. | 55 // std::sort. |
41 struct DownloadIdComparator { | 56 struct DownloadIdComparator { |
42 bool operator() (DownloadItem* first, DownloadItem* second) { | 57 bool operator() (DownloadItem* first, DownloadItem* second) { |
43 return first->GetId() < second->GetId(); | 58 return first->GetId() < second->GetId(); |
44 } | 59 } |
45 }; | 60 }; |
46 | 61 |
47 class DownloadExtensionTest : public InProcessBrowserTest { | 62 class DownloadsEventsListener : public content::NotificationObserver { |
63 public: | |
64 // If positive, WaitFor() gives up after this many milliseconds, figuring that | |
65 // the event it wants will never happen so that a failing test doesn't take | |
66 // too long to fail. If negative, WaitFor() never gives you up, never lets you | |
67 // down... The problem is that on very busy machines, the event can take more | |
68 // than a few seconds. On very very busy machines, it can take more than many | |
69 // seconds. I'd set it at 44 seconds, but there are multiple WaitFor()s per | |
70 // TEST_F. I could make it keep track of how long the current TEST_F has been | |
71 // running, but if a machine is so busy that a normally instantaneous event is | |
72 // taking half a minute, then this soft timeout mechanism probably won't work | |
73 // anyway. So this mechanism is really only good for debugging on otherwise | |
74 // unloaded machines. Maybe at some point I'll figure out a way to safely set | |
75 // this to a sensible number that it won't cause too many timeouts on the | |
76 // bots. | |
Randy Smith (Not in Mondays)
2012/06/19 19:23:23
This comment is targeted at the WaitFor() routine.
benjhayden
2012/06/21 17:50:48
Done.
| |
77 static const int kTimeOutMs = -1; | |
78 | |
79 DownloadsEventsListener() | |
80 : waiting_(false) { | |
81 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | |
82 content::NotificationService::AllSources()); | |
83 } | |
84 virtual ~DownloadsEventsListener() { | |
85 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | |
86 content::NotificationService::AllSources()); | |
87 STLDeleteElements(&events_); | |
88 } | |
89 | |
90 class Event { | |
91 public: | |
92 Event(Profile* profile, | |
93 const std::string& event_name, | |
94 const std::string& json_args, | |
95 base::Time caught) | |
96 : profile_(profile), | |
97 event_name_(event_name), | |
98 json_args_(json_args), | |
99 args_(base::JSONReader::Read(json_args)), | |
100 caught_(caught) { | |
101 } | |
102 | |
103 const base::Time& caught() { return caught_; } | |
104 | |
105 bool Equals(const Event& other) { | |
106 if ((profile_ != other.profile_) || | |
107 (event_name_ != other.event_name_)) | |
108 return false; | |
109 if ((event_name_ == extension_event_names::kOnDownloadCreated || | |
110 event_name_ == extension_event_names::kOnDownloadChanged) && | |
111 args_.get() && | |
112 other.args_.get()) { | |
113 base::ListValue* left_list = NULL; | |
114 base::DictionaryValue* left_dict = NULL; | |
115 base::ListValue* right_list = NULL; | |
116 base::DictionaryValue* right_dict = NULL; | |
117 if (!args_->GetAsList(&left_list) || | |
118 !other.args_->GetAsList(&right_list) || | |
119 !left_list->GetDictionary(0, &left_dict) || | |
120 !right_list->GetDictionary(0, &right_dict)) | |
121 return false; | |
122 for (base::DictionaryValue::Iterator iter(*left_dict); | |
123 iter.HasNext(); iter.Advance()) { | |
124 base::Value* right_value = NULL; | |
125 if (right_dict->HasKey(iter.key()) && | |
126 right_dict->Get(iter.key(), &right_value) && | |
127 !iter.value().Equals(right_value)) { | |
128 return false; | |
129 } | |
130 } | |
131 return true; | |
132 } else if ((event_name_ == extension_event_names::kOnDownloadErased) && | |
133 args_.get() && | |
134 other.args_.get()) { | |
135 int my_id = -1, other_id = -1; | |
136 return (args_->GetAsInteger(&my_id) && | |
137 other.args_->GetAsInteger(&other_id) && | |
138 my_id == other_id); | |
139 } | |
140 return json_args_ == other.json_args_; | |
141 } | |
142 | |
143 std::string Debug() { | |
144 return base::StringPrintf("Event(%p, %s, %s, %f)", | |
145 profile_, | |
146 event_name_.c_str(), | |
147 json_args_.c_str(), | |
148 caught_.ToJsTime()); | |
149 } | |
150 | |
151 private: | |
152 Profile* profile_; | |
153 std::string event_name_; | |
154 std::string json_args_; | |
155 scoped_ptr<base::Value> args_; | |
156 base::Time caught_; | |
157 | |
158 DISALLOW_COPY_AND_ASSIGN(Event); | |
159 }; | |
160 | |
161 typedef ExtensionDownloadsEventRouter::DownloadsNotificationSource | |
162 DownloadsNotificationSource; | |
163 | |
164 void Observe(int type, const content::NotificationSource& source, | |
165 const content::NotificationDetails& details) { | |
166 switch (type) { | |
167 case chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT: | |
168 { | |
169 DownloadsNotificationSource* dns = | |
170 content::Source<DownloadsNotificationSource>(source).ptr(); | |
171 Event* new_event = new Event( | |
172 dns->profile, | |
173 dns->event_name, | |
174 *content::Details<std::string>(details).ptr(), base::Time::Now()); | |
175 events_.push_back(new_event); | |
176 if (waiting_ && | |
177 waiting_for_.get() && | |
178 waiting_for_->Equals(*new_event)) { | |
179 waiting_ = false; | |
180 MessageLoopForUI::current()->Quit(); | |
181 } | |
182 break; | |
183 } | |
184 default: | |
185 NOTREACHED(); | |
186 } | |
187 } | |
188 | |
189 bool WaitFor(int timeout_ms, | |
190 Profile* profile, | |
191 const std::string& event_name, | |
192 const std::string& json_args) { | |
193 waiting_for_.reset(new Event(profile, event_name, json_args, base::Time())); | |
194 for (std::deque<Event*>::const_iterator iter = events_.begin(); | |
195 iter != events_.end(); ++iter) { | |
196 if ((*iter)->Equals(*waiting_for_.get())) | |
197 return true; | |
198 } | |
199 waiting_ = true; | |
200 if (timeout_ms > 0) { | |
201 MessageLoop::current()->PostDelayedTask( | |
202 FROM_HERE, base::Bind( | |
203 &DownloadsEventsListener::TimedOut, base::Unretained(this)), | |
204 timeout_ms); | |
205 } | |
206 ui_test_utils::RunMessageLoop(); | |
207 bool success = !waiting_; | |
208 if (waiting_) { | |
209 // Print the events that were caught since the last WaitFor() call to help | |
210 // find the erroneous event. | |
211 // TODO(benjhayden) Fuzzy-match and highlight the erroneous event. | |
212 for (std::deque<Event*>::const_iterator iter = events_.begin(); | |
213 iter != events_.end(); ++iter) { | |
214 if ((*iter)->caught() > last_wait_) { | |
215 LOG(INFO) << "Caught " << (*iter)->Debug(); | |
216 } | |
217 } | |
218 if (waiting_for_.get()) { | |
219 LOG(INFO) << "Timed out waiting for " << waiting_for_->Debug(); | |
220 } | |
221 waiting_ = false; | |
222 } | |
223 waiting_for_.reset(); | |
224 last_wait_ = base::Time::Now(); | |
225 return success; | |
226 } | |
227 | |
228 bool WaitFor(Profile* profile, | |
229 const std::string& event_name, | |
230 const std::string& json_args) { | |
231 return WaitFor(kTimeOutMs, profile, event_name, json_args); | |
232 } | |
233 | |
234 private: | |
235 void TimedOut() { | |
236 if (!waiting_for_.get()) | |
237 return; | |
238 MessageLoopForUI::current()->Quit(); | |
239 } | |
240 | |
241 bool waiting_; | |
242 base::Time last_wait_; | |
243 scoped_ptr<Event> waiting_for_; | |
244 content::NotificationRegistrar registrar_; | |
245 std::deque<Event*> events_; | |
246 | |
247 DISALLOW_COPY_AND_ASSIGN(DownloadsEventsListener); | |
248 }; | |
249 | |
250 class DownloadExtensionTest : public ExtensionApiTest { | |
251 public: | |
252 DownloadExtensionTest() | |
253 : extension_(NULL), | |
254 incognito_browser_(NULL), | |
255 current_browser_(NULL) { | |
256 } | |
257 | |
48 protected: | 258 protected: |
49 // Used with CreateHistoryDownloads | 259 // Used with CreateHistoryDownloads |
50 struct HistoryDownloadInfo { | 260 struct HistoryDownloadInfo { |
51 // Filename to use. CreateHistoryDownloads will append this filename to the | 261 // Filename to use. CreateHistoryDownloads will append this filename to the |
52 // temporary downloads directory specified by downloads_directory(). | 262 // temporary downloads directory specified by downloads_directory(). |
53 const FilePath::CharType* filename; | 263 const FilePath::CharType* filename; |
54 | 264 |
55 // State for the download. Note that IN_PROGRESS downloads will be created | 265 // State for the download. Note that IN_PROGRESS downloads will be created |
56 // as CANCELLED. | 266 // as CANCELLED. |
57 DownloadItem::DownloadState state; | 267 DownloadItem::DownloadState state; |
58 | 268 |
59 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS | 269 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS |
60 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT. | 270 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT. |
61 content::DownloadDangerType danger_type; | 271 content::DownloadDangerType danger_type; |
62 }; | 272 }; |
63 | 273 |
64 virtual Browser* current_browser() { return browser(); } | 274 void LoadExtension(const char* name) { |
275 // Store the created Extension object so that we can attach it to | |
276 // ExtensionFunctions. Also load the extension in incognito profiles for | |
277 // testing incognito. | |
278 extension_ = LoadExtensionIncognito(test_data_dir_.AppendASCII(name)); | |
279 CHECK(extension_); | |
280 } | |
281 | |
282 Browser* current_browser() { return current_browser_; } | |
65 | 283 |
66 // InProcessBrowserTest | 284 // InProcessBrowserTest |
67 virtual void SetUpOnMainThread() OVERRIDE { | 285 virtual void SetUpOnMainThread() OVERRIDE { |
68 BrowserThread::PostTask( | 286 BrowserThread::PostTask( |
69 BrowserThread::IO, FROM_HERE, | 287 BrowserThread::IO, FROM_HERE, |
70 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); | 288 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); |
71 InProcessBrowserTest::SetUpOnMainThread(); | 289 InProcessBrowserTest::SetUpOnMainThread(); |
290 GoOnTheRecord(); | |
72 CreateAndSetDownloadsDirectory(); | 291 CreateAndSetDownloadsDirectory(); |
73 current_browser()->profile()->GetPrefs()->SetBoolean( | 292 current_browser()->profile()->GetPrefs()->SetBoolean( |
74 prefs::kPromptForDownload, false); | 293 prefs::kPromptForDownload, false); |
75 GetDownloadManager()->RemoveAllDownloads(); | 294 GetOnRecordManager()->RemoveAllDownloads(); |
295 events_listener_.reset(new DownloadsEventsListener()); | |
76 } | 296 } |
77 | 297 |
78 virtual DownloadManager* GetDownloadManager() { | 298 void GoOnTheRecord() { current_browser_ = browser(); } |
79 return BrowserContext::GetDownloadManager(current_browser()->profile()); | 299 |
300 void GoOffTheRecord() { | |
301 if (!incognito_browser_) { | |
302 incognito_browser_ = CreateIncognitoBrowser(); | |
303 GetOffRecordManager()->RemoveAllDownloads(); | |
304 } | |
305 current_browser_ = incognito_browser_; | |
306 } | |
307 | |
308 bool WaitFor(int timeout_ms, const std::string& event_name, | |
309 const std::string& json_args) { | |
310 return events_listener_->WaitFor( | |
311 timeout_ms, current_browser()->profile(), event_name, json_args); | |
312 } | |
313 | |
314 bool WaitFor(const std::string& event_name, const std::string& json_args) { | |
315 return events_listener_->WaitFor( | |
316 current_browser()->profile(), event_name, json_args); | |
317 } | |
318 | |
319 bool WaitForInterruption(DownloadItem* item, int expected_error, | |
320 const std::string& on_created_event) { | |
321 if (!WaitFor(extension_event_names::kOnDownloadCreated, on_created_event)) | |
322 return false; | |
323 // The item may or may not be interrupted before the onCreated event fires. | |
324 if (item->IsInterrupted()) { | |
325 scoped_ptr<base::Value> args(base::JSONReader::Read(on_created_event)); | |
326 base::ListValue* args_list = NULL; | |
327 base::DictionaryValue* args_dict = NULL; | |
328 if (!args->GetAsList(&args_list) || | |
329 !args_list->GetDictionary(0, &args_dict)) | |
330 return false; | |
331 args_dict->SetString("state", "interrupted"); | |
332 args_dict->SetInteger("error", expected_error); | |
333 std::string created_error; | |
334 base::JSONWriter::Write(args_list, &created_error); | |
335 // This is not waiting for a different event, it's refining the | |
336 // expectations on the onCreated event that was just caught. Specifically, | |
337 // if a DownloadItem is already interrupted by the time the onCreated | |
338 // event fires, then the onCreated event should already describe the | |
339 // error. | |
340 return WaitFor(extension_event_names::kOnDownloadCreated, created_error); | |
341 } else { | |
342 return WaitFor(extension_event_names::kOnDownloadChanged, | |
343 base::StringPrintf("[{\"id\": %d," | |
344 " \"error\": {\"new\": %d}," | |
345 " \"state\": {" | |
346 " \"old\": \"in_progress\"," | |
347 " \"new\": \"interrupted\"}}]", | |
348 item->GetId(), | |
349 expected_error)); | |
350 } | |
351 } | |
352 | |
353 std::string GetURL(const char* path) { | |
354 return test_server()->GetURL(path).spec(); | |
Randy Smith (Not in Mondays)
2012/06/19 19:23:23
Personal preference would be to expand this inline
benjhayden
2012/06/21 17:50:48
Done.
| |
355 } | |
356 | |
357 std::string GetExtensionURL() { | |
358 return extension_->url().spec(); | |
359 } | |
360 | |
361 std::string GetFilename(const char* path) { | |
362 return downloads_directory_.path().AppendASCII(path).AsUTF8Unsafe(); | |
363 } | |
364 | |
365 DownloadManager* GetOnRecordManager() { | |
366 return BrowserContext::GetDownloadManager(browser()->profile()); | |
367 } | |
368 DownloadManager* GetOffRecordManager() { | |
369 return BrowserContext::GetDownloadManager( | |
370 browser()->profile()->GetOffTheRecordProfile()); | |
371 } | |
372 DownloadManager* GetCurrentManager() { | |
373 return (current_browser_ == incognito_browser_) ? | |
374 GetOffRecordManager() : GetOnRecordManager(); | |
80 } | 375 } |
81 | 376 |
82 // Creates a set of history downloads based on the provided |history_info| | 377 // Creates a set of history downloads based on the provided |history_info| |
83 // array. |count| is the number of elements in |history_info|. On success, | 378 // array. |count| is the number of elements in |history_info|. On success, |
84 // |items| will contain |count| DownloadItems in the order that they were | 379 // |items| will contain |count| DownloadItems in the order that they were |
85 // specified in |history_info|. Returns true on success and false otherwise. | 380 // specified in |history_info|. Returns true on success and false otherwise. |
86 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info, | 381 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info, |
87 size_t count, | 382 size_t count, |
88 DownloadManager::DownloadVector* items) { | 383 DownloadManager::DownloadVector* items) { |
89 DownloadIdComparator download_id_comparator; | 384 DownloadIdComparator download_id_comparator; |
90 base::Time current = base::Time::Now(); | 385 base::Time current = base::Time::Now(); |
91 std::vector<DownloadPersistentStoreInfo> entries; | 386 std::vector<DownloadPersistentStoreInfo> entries; |
92 entries.reserve(count); | 387 entries.reserve(count); |
93 for (size_t i = 0; i < count; ++i) { | 388 for (size_t i = 0; i < count; ++i) { |
94 DownloadPersistentStoreInfo entry( | 389 DownloadPersistentStoreInfo entry( |
95 downloads_directory().Append(history_info[i].filename), | 390 downloads_directory().Append(history_info[i].filename), |
96 GURL(), GURL(), // URL, referrer | 391 GURL(), GURL(), // URL, referrer |
97 current, current, // start_time, end_time | 392 current, current, // start_time, end_time |
98 1, 1, // received_bytes, total_bytes | 393 1, 1, // received_bytes, total_bytes |
99 history_info[i].state, // state | 394 history_info[i].state, // state |
100 i + 1, // db_handle | 395 i + 1, // db_handle |
101 false); // opened | 396 false); // opened |
102 entries.push_back(entry); | 397 entries.push_back(entry); |
103 } | 398 } |
104 GetDownloadManager()->OnPersistentStoreQueryComplete(&entries); | 399 GetOnRecordManager()->OnPersistentStoreQueryComplete(&entries); |
105 GetDownloadManager()->GetAllDownloads(FilePath(), items); | 400 GetOnRecordManager()->GetAllDownloads(FilePath(), items); |
106 EXPECT_EQ(count, items->size()); | 401 EXPECT_EQ(count, items->size()); |
107 if (count != items->size()) | 402 if (count != items->size()) |
108 return false; | 403 return false; |
109 | 404 |
110 // Order by ID so that they are in the order that we created them. | 405 // Order by ID so that they are in the order that we created them. |
111 std::sort(items->begin(), items->end(), download_id_comparator); | 406 std::sort(items->begin(), items->end(), download_id_comparator); |
112 // Set the danger type if necessary. | 407 // Set the danger type if necessary. |
113 for (size_t i = 0; i < count; ++i) { | 408 for (size_t i = 0; i < count; ++i) { |
114 if (history_info[i].danger_type != | 409 if (history_info[i].danger_type != |
115 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) { | 410 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) { |
(...skipping 13 matching lines...) Expand all Loading... | |
129 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); | 424 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); |
130 ui_test_utils::NavigateToURLWithDisposition( | 425 ui_test_utils::NavigateToURLWithDisposition( |
131 current_browser(), slow_download_url, CURRENT_TAB, | 426 current_browser(), slow_download_url, CURRENT_TAB, |
132 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 427 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
133 observer->WaitForFinished(); | 428 observer->WaitForFinished(); |
134 EXPECT_EQ( | 429 EXPECT_EQ( |
135 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS)); | 430 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS)); |
136 // We don't expect a select file dialog. | 431 // We don't expect a select file dialog. |
137 ASSERT_FALSE(observer->select_file_dialog_seen()); | 432 ASSERT_FALSE(observer->select_file_dialog_seen()); |
138 } | 433 } |
139 GetDownloadManager()->GetAllDownloads(FilePath(), items); | 434 GetCurrentManager()->GetAllDownloads(FilePath(), items); |
140 ASSERT_EQ(count, items->size()); | 435 ASSERT_EQ(count, items->size()); |
141 } | 436 } |
142 | 437 |
143 DownloadItem* CreateSlowTestDownload() { | 438 DownloadItem* CreateSlowTestDownload() { |
144 scoped_ptr<DownloadTestObserver> observer( | 439 scoped_ptr<DownloadTestObserver> observer( |
145 CreateInProgressDownloadObserver(1)); | 440 CreateInProgressDownloadObserver(1)); |
146 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); | 441 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); |
147 DownloadManager* manager = GetDownloadManager(); | 442 DownloadManager* manager = GetCurrentManager(); |
148 | 443 |
149 EXPECT_EQ(0, manager->InProgressCount()); | 444 EXPECT_EQ(0, manager->InProgressCount()); |
150 if (manager->InProgressCount() != 0) | 445 if (manager->InProgressCount() != 0) |
151 return NULL; | 446 return NULL; |
152 | 447 |
153 ui_test_utils::NavigateToURLWithDisposition( | 448 ui_test_utils::NavigateToURLWithDisposition( |
154 current_browser(), slow_download_url, CURRENT_TAB, | 449 current_browser(), slow_download_url, CURRENT_TAB, |
155 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 450 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
156 | 451 |
157 observer->WaitForFinished(); | 452 observer->WaitForFinished(); |
(...skipping 23 matching lines...) Expand all Loading... | |
181 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl); | 476 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl); |
182 ui_test_utils::NavigateToURLWithDisposition( | 477 ui_test_utils::NavigateToURLWithDisposition( |
183 current_browser(), finish_url, NEW_FOREGROUND_TAB, | 478 current_browser(), finish_url, NEW_FOREGROUND_TAB, |
184 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 479 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
185 observer->WaitForFinished(); | 480 observer->WaitForFinished(); |
186 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); | 481 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); |
187 } | 482 } |
188 | 483 |
189 DownloadTestObserver* CreateDownloadObserver(size_t download_count) { | 484 DownloadTestObserver* CreateDownloadObserver(size_t download_count) { |
190 return new DownloadTestObserverTerminal( | 485 return new DownloadTestObserverTerminal( |
191 GetDownloadManager(), download_count, true, | 486 GetCurrentManager(), download_count, true, |
192 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); | 487 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); |
193 } | 488 } |
194 | 489 |
195 DownloadTestObserver* CreateInProgressDownloadObserver( | 490 DownloadTestObserver* CreateInProgressDownloadObserver( |
196 size_t download_count) { | 491 size_t download_count) { |
197 return new DownloadTestObserverInProgress(GetDownloadManager(), | 492 return new DownloadTestObserverInProgress( |
198 download_count, | 493 GetCurrentManager(), download_count, true); |
199 true); | 494 } |
495 | |
496 bool RunFunction(UIThreadExtensionFunction* function, | |
497 const std::string& args) { | |
498 scoped_refptr<UIThreadExtensionFunction> delete_function(function); | |
499 SetUpExtensionFunction(function); | |
500 return extension_function_test_utils::RunFunction( | |
501 function, args, browser(), GetFlags()); | |
200 } | 502 } |
201 | 503 |
202 extension_function_test_utils::RunFunctionFlags GetFlags() { | 504 extension_function_test_utils::RunFunctionFlags GetFlags() { |
203 return current_browser()->profile()->IsOffTheRecord() ? | 505 return current_browser()->profile()->IsOffTheRecord() ? |
204 extension_function_test_utils::INCLUDE_INCOGNITO : | 506 extension_function_test_utils::INCLUDE_INCOGNITO : |
205 extension_function_test_utils::NONE; | 507 extension_function_test_utils::NONE; |
206 } | 508 } |
207 | 509 |
208 // extension_function_test_utils::RunFunction*() only uses browser for its | 510 // extension_function_test_utils::RunFunction*() only uses browser for its |
209 // profile(), so pass it the on-record browser so that it always uses the | 511 // profile(), so pass it the on-record browser so that it always uses the |
210 // on-record profile. | 512 // on-record profile to match real-life behavior. |
211 | |
212 bool RunFunction(UIThreadExtensionFunction* function, | |
213 const std::string& args) { | |
214 // extension_function_test_utils::RunFunction() does not take | |
215 // ownership of |function|. | |
216 scoped_refptr<ExtensionFunction> function_owner(function); | |
217 return extension_function_test_utils::RunFunction( | |
218 function, args, browser(), GetFlags()); | |
219 } | |
220 | 513 |
221 base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function, | 514 base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function, |
222 const std::string& args) { | 515 const std::string& args) { |
516 SetUpExtensionFunction(function); | |
223 return extension_function_test_utils::RunFunctionAndReturnResult( | 517 return extension_function_test_utils::RunFunctionAndReturnResult( |
224 function, args, browser(), GetFlags()); | 518 function, args, browser(), GetFlags()); |
225 } | 519 } |
226 | 520 |
227 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, | 521 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, |
228 const std::string& args) { | 522 const std::string& args) { |
523 SetUpExtensionFunction(function); | |
229 return extension_function_test_utils::RunFunctionAndReturnError( | 524 return extension_function_test_utils::RunFunctionAndReturnError( |
230 function, args, browser(), GetFlags()); | 525 function, args, browser(), GetFlags()); |
231 } | 526 } |
232 | 527 |
233 bool RunFunctionAndReturnString(UIThreadExtensionFunction* function, | 528 bool RunFunctionAndReturnString(UIThreadExtensionFunction* function, |
234 const std::string& args, | 529 const std::string& args, |
235 std::string* result_string) { | 530 std::string* result_string) { |
531 SetUpExtensionFunction(function); | |
236 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args)); | 532 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args)); |
237 EXPECT_TRUE(result.get()); | 533 EXPECT_TRUE(result.get()); |
238 return result.get() && result->GetAsString(result_string); | 534 return result.get() && result->GetAsString(result_string); |
239 } | 535 } |
240 | 536 |
241 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) { | 537 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) { |
242 return base::StringPrintf("[%d]", download_item->GetId()); | 538 return base::StringPrintf("[%d]", download_item->GetId()); |
243 } | 539 } |
244 | 540 |
245 // Checks if a data URL encoded image is a PNG of a given size. | 541 // Checks if a data URL encoded image is a PNG of a given size. |
(...skipping 17 matching lines...) Expand all Loading... | |
263 &width, &height)); | 559 &width, &height)); |
264 EXPECT_EQ(expected_size, width); | 560 EXPECT_EQ(expected_size, width); |
265 EXPECT_EQ(expected_size, height); | 561 EXPECT_EQ(expected_size, height); |
266 } | 562 } |
267 | 563 |
268 const FilePath& downloads_directory() { | 564 const FilePath& downloads_directory() { |
269 return downloads_directory_.path(); | 565 return downloads_directory_.path(); |
270 } | 566 } |
271 | 567 |
272 private: | 568 private: |
569 void SetUpExtensionFunction(UIThreadExtensionFunction* function) { | |
570 if (extension_) { | |
571 // Recreate the tab each time for insulation. | |
572 TabContents* tab = current_browser()->AddSelectedTabWithURL( | |
573 extension_->GetResourceURL("empty.html"), | |
574 content::PAGE_TRANSITION_LINK); | |
575 function->set_extension(extension_); | |
576 function->SetRenderViewHost(tab->web_contents()->GetRenderViewHost()); | |
577 } | |
578 } | |
579 | |
273 void CreateAndSetDownloadsDirectory() { | 580 void CreateAndSetDownloadsDirectory() { |
274 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); | 581 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); |
275 current_browser()->profile()->GetPrefs()->SetFilePath( | 582 current_browser()->profile()->GetPrefs()->SetFilePath( |
276 prefs::kDownloadDefaultDirectory, | 583 prefs::kDownloadDefaultDirectory, |
277 downloads_directory_.path()); | 584 downloads_directory_.path()); |
278 } | 585 } |
279 | 586 |
280 ScopedTempDir downloads_directory_; | 587 ScopedTempDir downloads_directory_; |
281 }; | 588 const extensions::Extension* extension_; |
282 | |
283 class DownloadExtensionTestIncognito : public DownloadExtensionTest { | |
284 public: | |
285 virtual Browser* current_browser() OVERRIDE { return current_browser_; } | |
286 | |
287 virtual void SetUpOnMainThread() OVERRIDE { | |
288 GoOnTheRecord(); | |
289 DownloadExtensionTest::SetUpOnMainThread(); | |
290 incognito_browser_ = CreateIncognitoBrowser(); | |
291 GoOffTheRecord(); | |
292 GetDownloadManager()->RemoveAllDownloads(); | |
293 } | |
294 | |
295 void GoOnTheRecord() { current_browser_ = browser(); } | |
296 void GoOffTheRecord() { current_browser_ = incognito_browser_; } | |
297 | |
298 private: | |
299 Browser* incognito_browser_; | 589 Browser* incognito_browser_; |
300 Browser* current_browser_; | 590 Browser* current_browser_; |
591 scoped_ptr<DownloadsEventsListener> events_listener_; | |
592 | |
593 DISALLOW_COPY_AND_ASSIGN(DownloadExtensionTest); | |
301 }; | 594 }; |
302 | 595 |
303 class MockIconExtractorImpl : public DownloadFileIconExtractor { | 596 class MockIconExtractorImpl : public DownloadFileIconExtractor { |
304 public: | 597 public: |
305 MockIconExtractorImpl(const FilePath& path, IconLoader::IconSize icon_size, | 598 MockIconExtractorImpl(const FilePath& path, IconLoader::IconSize icon_size, |
306 const std::string& response) | 599 const std::string& response) |
307 : expected_path_(path), | 600 : expected_path_(path), |
308 expected_icon_size_(icon_size), | 601 expected_icon_size_(icon_size), |
309 response_(response) { | 602 response_(response) { |
310 } | 603 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
369 if ((*item)->IsInProgress()) | 662 if ((*item)->IsInProgress()) |
370 (*item)->Cancel(true); | 663 (*item)->Cancel(true); |
371 } | 664 } |
372 } | 665 } |
373 | 666 |
374 private: | 667 private: |
375 DownloadManager::DownloadVector* items_; | 668 DownloadManager::DownloadVector* items_; |
376 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller); | 669 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller); |
377 }; | 670 }; |
378 | 671 |
379 } // namespace | 672 |
673 // Tests may create HTML5 FileSystem Files for testing. | |
674 // fileapi::FileSystemContext::OpenFileSystem() calls OpenFileSystemCallback() | |
675 // below, which runs CreateFileOnIOThread, which calls | |
676 // fileapi::FileSystemOperationInterface::CreateFile(), which calls | |
677 // FileCreated() below, which runs FileCreatedOnUIThread. | |
678 | |
679 static const char* kHTML5FileCreated = "html5_file_created"; | |
680 | |
681 void FileCreatedOnUIThread(Profile* profile, std::string filename) { | |
682 DownloadsEventsListener::DownloadsNotificationSource notification_source; | |
683 notification_source.event_name = kHTML5FileCreated; | |
684 notification_source.profile = profile; | |
685 content::NotificationService::current()->Notify( | |
686 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | |
687 content::Source<DownloadsEventsListener::DownloadsNotificationSource>( | |
688 ¬ification_source), | |
689 content::Details<std::string>(&filename)); | |
690 } | |
691 | |
692 void FileCreated(Profile* profile, const std::string& filename, | |
693 base::PlatformFileError result) { | |
694 CHECK(BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( | |
695 &FileCreatedOnUIThread, profile, filename))); | |
696 } | |
697 | |
698 void CreateFileOnIOThread(fileapi::FileSystemOperationInterface* operation, | |
699 Profile* profile, | |
700 const std::string& filename, | |
701 const std::string& url) { | |
702 operation->CreateFile(GURL(url + filename), | |
703 true/*exclusive*/, | |
704 base::Bind(&FileCreated, profile, filename)); | |
705 } | |
706 | |
707 void OpenFileSystemCallback(fileapi::FileSystemContext* fs, | |
708 const std::string& filename, | |
709 Profile* profile, | |
710 base::PlatformFileError result, | |
711 const std::string& fs_name, | |
712 const GURL& root) { | |
713 fileapi::FileSystemOperationInterface* operation = | |
714 fs->CreateFileSystemOperation(root); | |
715 CHECK(BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | |
716 &CreateFileOnIOThread, operation, profile, filename, root.spec()))); | |
717 } | |
718 | |
719 } // namespace | |
380 | 720 |
381 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_PauseResumeCancel) { | 721 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_PauseResumeCancel) { |
382 DownloadItem* download_item = CreateSlowTestDownload(); | 722 DownloadItem* download_item = CreateSlowTestDownload(); |
383 ASSERT_TRUE(download_item); | 723 ASSERT_TRUE(download_item); |
384 | 724 |
385 // Call pause(). It should succeed and the download should be paused on | 725 // Call pause(). It should succeed and the download should be paused on |
386 // return. | 726 // return. |
387 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), | 727 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), |
388 DownloadItemIdAsArgList(download_item))); | 728 DownloadItemIdAsArgList(download_item))); |
389 EXPECT_TRUE(download_item->IsPaused()); | 729 EXPECT_TRUE(download_item->IsPaused()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
423 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item)); | 763 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item)); |
424 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 764 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
425 error.c_str()); | 765 error.c_str()); |
426 | 766 |
427 // Calling resume on a non-active download yields kInvalidOperationError | 767 // Calling resume on a non-active download yields kInvalidOperationError |
428 error = RunFunctionAndReturnError( | 768 error = RunFunctionAndReturnError( |
429 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item)); | 769 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item)); |
430 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 770 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
431 error.c_str()); | 771 error.c_str()); |
432 | 772 |
433 // Calling pause()/resume()/cancel() with invalid download Ids is | 773 // Calling paused on a non-existent download yields kInvalidOperationError. |
434 // tested in the API test (DownloadsApiTest). | 774 error = RunFunctionAndReturnError( |
775 new DownloadsPauseFunction(), "[-42]"); | |
776 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
777 error.c_str()); | |
778 | |
779 // Calling resume on a non-existent download yields kInvalidOperationError | |
780 error = RunFunctionAndReturnError( | |
781 new DownloadsResumeFunction(), "[-42]"); | |
782 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
783 error.c_str()); | |
435 } | 784 } |
436 | 785 |
437 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted | 786 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted |
438 // download items. | 787 // download items. |
439 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_Active) { | 788 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_Active) { |
440 DownloadItem* download_item = CreateSlowTestDownload(); | 789 DownloadItem* download_item = CreateSlowTestDownload(); |
441 ASSERT_TRUE(download_item); | 790 ASSERT_TRUE(download_item); |
442 | 791 |
443 // Get the icon for the in-progress download. This call should succeed even | 792 // Get the icon for the in-progress download. This call should succeed even |
444 // if the file type isn't registered. | 793 // if the file type isn't registered. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
519 expected_path, IconLoader::NORMAL, "")); | 868 expected_path, IconLoader::NORMAL, "")); |
520 std::string error = RunFunctionAndReturnError(function.release(), args); | 869 std::string error = RunFunctionAndReturnError(function.release(), args); |
521 EXPECT_STREQ(download_extension_errors::kIconNotFoundError, | 870 EXPECT_STREQ(download_extension_errors::kIconNotFoundError, |
522 error.c_str()); | 871 error.c_str()); |
523 | 872 |
524 // Once the download item is deleted, we should return kInvalidOperationError. | 873 // Once the download item is deleted, we should return kInvalidOperationError. |
525 download_item->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); | 874 download_item->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); |
526 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args); | 875 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args); |
527 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 876 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
528 error.c_str()); | 877 error.c_str()); |
529 | |
530 // Asking for icons of other (invalid) sizes is tested in the API test | |
531 // (DownloadsApiTest). | |
532 } | 878 } |
533 | 879 |
534 // Test that we can acquire file icons for history downloads regardless of | 880 // Test that we can acquire file icons for history downloads regardless of |
535 // whether they exist or not. If the file doesn't exist we should receive a | 881 // whether they exist or not. If the file doesn't exist we should receive a |
536 // generic icon from the OS/toolkit that may or may not be specific to the file | 882 // generic icon from the OS/toolkit that may or may not be specific to the file |
537 // type. | 883 // type. |
538 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_History) { | 884 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_History) { |
539 const HistoryDownloadInfo kHistoryInfo[] = { | 885 const HistoryDownloadInfo kHistoryInfo[] = { |
540 { FILE_PATH_LITERAL("real.txt"), | 886 { FILE_PATH_LITERAL("real.txt"), |
541 DownloadItem::COMPLETE, | 887 DownloadItem::COMPLETE, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
576 function->SetIconExtractorForTesting(new MockIconExtractorImpl( | 922 function->SetIconExtractorForTesting(new MockIconExtractorImpl( |
577 (*iter)->GetFullPath(), IconLoader::NORMAL, "hello")); | 923 (*iter)->GetFullPath(), IconLoader::NORMAL, "hello")); |
578 EXPECT_TRUE(RunFunctionAndReturnString(function.release(), args, | 924 EXPECT_TRUE(RunFunctionAndReturnString(function.release(), args, |
579 &result_string)); | 925 &result_string)); |
580 EXPECT_STREQ("hello", result_string.c_str()); | 926 EXPECT_STREQ("hello", result_string.c_str()); |
581 } | 927 } |
582 | 928 |
583 // The temporary files should be cleaned up when the ScopedTempDir is removed. | 929 // The temporary files should be cleaned up when the ScopedTempDir is removed. |
584 } | 930 } |
585 | 931 |
932 // Test passing the empty query to search(). | |
586 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchEmptyQuery) { | 933 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchEmptyQuery) { |
587 ScopedCancellingItem item(CreateSlowTestDownload()); | 934 ScopedCancellingItem item(CreateSlowTestDownload()); |
588 ASSERT_TRUE(item.get()); | 935 ASSERT_TRUE(item.get()); |
589 | 936 |
590 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 937 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
591 new DownloadsSearchFunction(), "[{}]")); | 938 new DownloadsSearchFunction(), "[{}]")); |
592 ASSERT_TRUE(result.get()); | 939 ASSERT_TRUE(result.get()); |
593 base::ListValue* result_list = NULL; | 940 base::ListValue* result_list = NULL; |
594 ASSERT_TRUE(result->GetAsList(&result_list)); | 941 ASSERT_TRUE(result->GetAsList(&result_list)); |
595 ASSERT_EQ(1UL, result_list->GetSize()); | 942 ASSERT_EQ(1UL, result_list->GetSize()); |
596 } | 943 } |
597 | 944 |
945 // Test the |filenameRegex| parameter for search(). | |
598 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 946 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
599 DownloadsApi_SearchFilenameRegex) { | 947 DownloadsApi_SearchFilenameRegex) { |
600 const HistoryDownloadInfo kHistoryInfo[] = { | 948 const HistoryDownloadInfo kHistoryInfo[] = { |
601 { FILE_PATH_LITERAL("foobar"), | 949 { FILE_PATH_LITERAL("foobar"), |
602 DownloadItem::COMPLETE, | 950 DownloadItem::COMPLETE, |
603 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | 951 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, |
604 { FILE_PATH_LITERAL("baz"), | 952 { FILE_PATH_LITERAL("baz"), |
605 DownloadItem::COMPLETE, | 953 DownloadItem::COMPLETE, |
606 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | 954 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } |
607 }; | 955 }; |
608 DownloadManager::DownloadVector all_downloads; | 956 DownloadManager::DownloadVector all_downloads; |
609 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), | 957 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), |
610 &all_downloads)); | 958 &all_downloads)); |
611 | 959 |
612 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 960 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
613 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]")); | 961 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]")); |
614 ASSERT_TRUE(result.get()); | 962 ASSERT_TRUE(result.get()); |
615 base::ListValue* result_list = NULL; | 963 base::ListValue* result_list = NULL; |
616 ASSERT_TRUE(result->GetAsList(&result_list)); | 964 ASSERT_TRUE(result->GetAsList(&result_list)); |
617 ASSERT_EQ(1UL, result_list->GetSize()); | 965 ASSERT_EQ(1UL, result_list->GetSize()); |
618 base::DictionaryValue* item_value = NULL; | 966 base::DictionaryValue* item_value = NULL; |
619 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); | 967 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); |
620 int item_id = -1; | 968 int item_id = -1; |
621 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); | 969 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); |
622 ASSERT_EQ(0, item_id); | 970 ASSERT_EQ(0, item_id); |
623 } | 971 } |
624 | 972 |
973 // Test the |id| parameter for search(). | |
625 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchId) { | 974 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchId) { |
626 DownloadManager::DownloadVector items; | 975 DownloadManager::DownloadVector items; |
627 CreateSlowTestDownloads(2, &items); | 976 CreateSlowTestDownloads(2, &items); |
628 ScopedItemVectorCanceller delete_items(&items); | 977 ScopedItemVectorCanceller delete_items(&items); |
629 | 978 |
630 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 979 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
631 new DownloadsSearchFunction(), "[{\"id\": 0}]")); | 980 new DownloadsSearchFunction(), "[{\"id\": 0}]")); |
632 ASSERT_TRUE(result.get()); | 981 ASSERT_TRUE(result.get()); |
633 base::ListValue* result_list = NULL; | 982 base::ListValue* result_list = NULL; |
634 ASSERT_TRUE(result->GetAsList(&result_list)); | 983 ASSERT_TRUE(result->GetAsList(&result_list)); |
635 ASSERT_EQ(1UL, result_list->GetSize()); | 984 ASSERT_EQ(1UL, result_list->GetSize()); |
636 base::DictionaryValue* item_value = NULL; | 985 base::DictionaryValue* item_value = NULL; |
637 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); | 986 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); |
638 int item_id = -1; | 987 int item_id = -1; |
639 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); | 988 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); |
640 ASSERT_EQ(0, item_id); | 989 ASSERT_EQ(0, item_id); |
641 } | 990 } |
642 | 991 |
992 // Test specifying both the |id| and |filename| parameters for search(). | |
643 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 993 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
644 DownloadsApi_SearchIdAndFilename) { | 994 DownloadsApi_SearchIdAndFilename) { |
645 DownloadManager::DownloadVector items; | 995 DownloadManager::DownloadVector items; |
646 CreateSlowTestDownloads(2, &items); | 996 CreateSlowTestDownloads(2, &items); |
647 ScopedItemVectorCanceller delete_items(&items); | 997 ScopedItemVectorCanceller delete_items(&items); |
648 | 998 |
649 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 999 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
650 new DownloadsSearchFunction(), "[{\"id\": 0,\"filename\": \"foobar\"}]")); | 1000 new DownloadsSearchFunction(), |
1001 "[{\"id\": 0, \"filename\": \"foobar\"}]")); | |
651 ASSERT_TRUE(result.get()); | 1002 ASSERT_TRUE(result.get()); |
652 base::ListValue* result_list = NULL; | 1003 base::ListValue* result_list = NULL; |
653 ASSERT_TRUE(result->GetAsList(&result_list)); | 1004 ASSERT_TRUE(result->GetAsList(&result_list)); |
654 ASSERT_EQ(0UL, result_list->GetSize()); | 1005 ASSERT_EQ(0UL, result_list->GetSize()); |
655 } | 1006 } |
656 | 1007 |
1008 // Test a single |orderBy| parameter for search(). | |
657 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchOrderBy) { | 1009 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchOrderBy) { |
658 const HistoryDownloadInfo kHistoryInfo[] = { | 1010 const HistoryDownloadInfo kHistoryInfo[] = { |
659 { FILE_PATH_LITERAL("zzz"), | 1011 { FILE_PATH_LITERAL("zzz"), |
660 DownloadItem::COMPLETE, | 1012 DownloadItem::COMPLETE, |
661 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | 1013 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, |
662 { FILE_PATH_LITERAL("baz"), | 1014 { FILE_PATH_LITERAL("baz"), |
663 DownloadItem::COMPLETE, | 1015 DownloadItem::COMPLETE, |
664 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | 1016 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } |
665 }; | 1017 }; |
666 DownloadManager::DownloadVector items; | 1018 DownloadManager::DownloadVector items; |
(...skipping 10 matching lines...) Expand all Loading... | |
677 base::DictionaryValue* item1_value = NULL; | 1029 base::DictionaryValue* item1_value = NULL; |
678 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); | 1030 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); |
679 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); | 1031 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); |
680 std::string item0_name, item1_name; | 1032 std::string item0_name, item1_name; |
681 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); | 1033 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); |
682 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); | 1034 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); |
683 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); | 1035 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); |
684 ASSERT_LT(item0_name, item1_name); | 1036 ASSERT_LT(item0_name, item1_name); |
685 } | 1037 } |
686 | 1038 |
1039 // Test specifying an empty |orderBy| parameter for search(). | |
687 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchOrderByEmpty) { | 1040 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchOrderByEmpty) { |
688 const HistoryDownloadInfo kHistoryInfo[] = { | 1041 const HistoryDownloadInfo kHistoryInfo[] = { |
689 { FILE_PATH_LITERAL("zzz"), | 1042 { FILE_PATH_LITERAL("zzz"), |
690 DownloadItem::COMPLETE, | 1043 DownloadItem::COMPLETE, |
691 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | 1044 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, |
692 { FILE_PATH_LITERAL("baz"), | 1045 { FILE_PATH_LITERAL("baz"), |
693 DownloadItem::COMPLETE, | 1046 DownloadItem::COMPLETE, |
694 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | 1047 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } |
695 }; | 1048 }; |
696 DownloadManager::DownloadVector items; | 1049 DownloadManager::DownloadVector items; |
(...skipping 10 matching lines...) Expand all Loading... | |
707 base::DictionaryValue* item1_value = NULL; | 1060 base::DictionaryValue* item1_value = NULL; |
708 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); | 1061 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); |
709 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); | 1062 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); |
710 std::string item0_name, item1_name; | 1063 std::string item0_name, item1_name; |
711 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); | 1064 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); |
712 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); | 1065 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); |
713 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); | 1066 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); |
714 ASSERT_GT(item0_name, item1_name); | 1067 ASSERT_GT(item0_name, item1_name); |
715 } | 1068 } |
716 | 1069 |
1070 // Test the |danger| option for search(). | |
717 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchDanger) { | 1071 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchDanger) { |
718 const HistoryDownloadInfo kHistoryInfo[] = { | 1072 const HistoryDownloadInfo kHistoryInfo[] = { |
719 { FILE_PATH_LITERAL("zzz"), | 1073 { FILE_PATH_LITERAL("zzz"), |
720 DownloadItem::COMPLETE, | 1074 DownloadItem::COMPLETE, |
721 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, | 1075 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, |
722 { FILE_PATH_LITERAL("baz"), | 1076 { FILE_PATH_LITERAL("baz"), |
723 DownloadItem::COMPLETE, | 1077 DownloadItem::COMPLETE, |
724 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | 1078 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } |
725 }; | 1079 }; |
726 DownloadManager::DownloadVector items; | 1080 DownloadManager::DownloadVector items; |
727 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), | 1081 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), |
728 &items)); | 1082 &items)); |
729 | 1083 |
730 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 1084 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
731 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]")); | 1085 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]")); |
732 ASSERT_TRUE(result.get()); | 1086 ASSERT_TRUE(result.get()); |
733 base::ListValue* result_list = NULL; | 1087 base::ListValue* result_list = NULL; |
734 ASSERT_TRUE(result->GetAsList(&result_list)); | 1088 ASSERT_TRUE(result->GetAsList(&result_list)); |
735 ASSERT_EQ(1UL, result_list->GetSize()); | 1089 ASSERT_EQ(1UL, result_list->GetSize()); |
736 } | 1090 } |
737 | 1091 |
1092 // Test the |state| option for search(). | |
738 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchState) { | 1093 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchState) { |
739 DownloadManager::DownloadVector items; | 1094 DownloadManager::DownloadVector items; |
740 CreateSlowTestDownloads(2, &items); | 1095 CreateSlowTestDownloads(2, &items); |
741 ScopedItemVectorCanceller delete_items(&items); | 1096 ScopedItemVectorCanceller delete_items(&items); |
742 | 1097 |
743 items[0]->Cancel(true); | 1098 items[0]->Cancel(true); |
744 | 1099 |
745 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 1100 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
746 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]")); | 1101 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]")); |
747 ASSERT_TRUE(result.get()); | 1102 ASSERT_TRUE(result.get()); |
748 base::ListValue* result_list = NULL; | 1103 base::ListValue* result_list = NULL; |
749 ASSERT_TRUE(result->GetAsList(&result_list)); | 1104 ASSERT_TRUE(result->GetAsList(&result_list)); |
750 ASSERT_EQ(1UL, result_list->GetSize()); | 1105 ASSERT_EQ(1UL, result_list->GetSize()); |
751 } | 1106 } |
752 | 1107 |
1108 // Test the |limit| option for search(). | |
753 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchLimit) { | 1109 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchLimit) { |
754 DownloadManager::DownloadVector items; | 1110 DownloadManager::DownloadVector items; |
755 CreateSlowTestDownloads(2, &items); | 1111 CreateSlowTestDownloads(2, &items); |
756 ScopedItemVectorCanceller delete_items(&items); | 1112 ScopedItemVectorCanceller delete_items(&items); |
757 | 1113 |
758 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 1114 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
759 new DownloadsSearchFunction(), "[{\"limit\": 1}]")); | 1115 new DownloadsSearchFunction(), "[{\"limit\": 1}]")); |
760 ASSERT_TRUE(result.get()); | 1116 ASSERT_TRUE(result.get()); |
761 base::ListValue* result_list = NULL; | 1117 base::ListValue* result_list = NULL; |
762 ASSERT_TRUE(result->GetAsList(&result_list)); | 1118 ASSERT_TRUE(result->GetAsList(&result_list)); |
763 ASSERT_EQ(1UL, result_list->GetSize()); | 1119 ASSERT_EQ(1UL, result_list->GetSize()); |
764 } | 1120 } |
765 | 1121 |
1122 // Test invalid search parameters. | |
766 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchInvalid) { | 1123 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchInvalid) { |
767 std::string error = RunFunctionAndReturnError( | 1124 std::string error = RunFunctionAndReturnError( |
768 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]"); | 1125 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]"); |
769 EXPECT_STREQ(download_extension_errors::kInvalidFilterError, | 1126 EXPECT_STREQ(download_extension_errors::kInvalidFilterError, |
770 error.c_str()); | 1127 error.c_str()); |
771 error = RunFunctionAndReturnError( | 1128 error = RunFunctionAndReturnError( |
772 new DownloadsSearchFunction(), "[{\"danger\": \"goat\"}]"); | 1129 new DownloadsSearchFunction(), "[{\"danger\": \"goat\"}]"); |
773 EXPECT_STREQ(download_extension_errors::kInvalidDangerTypeError, | 1130 EXPECT_STREQ(download_extension_errors::kInvalidDangerTypeError, |
774 error.c_str()); | 1131 error.c_str()); |
775 error = RunFunctionAndReturnError( | 1132 error = RunFunctionAndReturnError( |
776 new DownloadsSearchFunction(), "[{\"state\": \"goat\"}]"); | 1133 new DownloadsSearchFunction(), "[{\"state\": \"goat\"}]"); |
777 EXPECT_STREQ(download_extension_errors::kInvalidStateError, | 1134 EXPECT_STREQ(download_extension_errors::kInvalidStateError, |
778 error.c_str()); | 1135 error.c_str()); |
779 error = RunFunctionAndReturnError( | 1136 error = RunFunctionAndReturnError( |
780 new DownloadsSearchFunction(), "[{\"orderBy\": \"goat\"}]"); | 1137 new DownloadsSearchFunction(), "[{\"orderBy\": \"goat\"}]"); |
781 EXPECT_STREQ(download_extension_errors::kInvalidOrderByError, | 1138 EXPECT_STREQ(download_extension_errors::kInvalidOrderByError, |
782 error.c_str()); | 1139 error.c_str()); |
783 error = RunFunctionAndReturnError( | 1140 error = RunFunctionAndReturnError( |
784 new DownloadsSearchFunction(), "[{\"limit\": -1}]"); | 1141 new DownloadsSearchFunction(), "[{\"limit\": -1}]"); |
785 EXPECT_STREQ(download_extension_errors::kInvalidQueryLimit, | 1142 EXPECT_STREQ(download_extension_errors::kInvalidQueryLimit, |
786 error.c_str()); | 1143 error.c_str()); |
787 } | 1144 } |
788 | 1145 |
1146 // Test searching using multiple conditions through multiple downloads. | |
789 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchPlural) { | 1147 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchPlural) { |
790 const HistoryDownloadInfo kHistoryInfo[] = { | 1148 const HistoryDownloadInfo kHistoryInfo[] = { |
791 { FILE_PATH_LITERAL("aaa"), | 1149 { FILE_PATH_LITERAL("aaa"), |
792 DownloadItem::CANCELLED, | 1150 DownloadItem::CANCELLED, |
793 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | 1151 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, |
794 { FILE_PATH_LITERAL("zzz"), | 1152 { FILE_PATH_LITERAL("zzz"), |
795 DownloadItem::COMPLETE, | 1153 DownloadItem::COMPLETE, |
796 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, | 1154 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, |
797 { FILE_PATH_LITERAL("baz"), | 1155 { FILE_PATH_LITERAL("baz"), |
798 DownloadItem::COMPLETE, | 1156 DownloadItem::COMPLETE, |
(...skipping 13 matching lines...) Expand all Loading... | |
812 base::ListValue* result_list = NULL; | 1170 base::ListValue* result_list = NULL; |
813 ASSERT_TRUE(result->GetAsList(&result_list)); | 1171 ASSERT_TRUE(result->GetAsList(&result_list)); |
814 ASSERT_EQ(1UL, result_list->GetSize()); | 1172 ASSERT_EQ(1UL, result_list->GetSize()); |
815 base::DictionaryValue* item_value = NULL; | 1173 base::DictionaryValue* item_value = NULL; |
816 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); | 1174 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); |
817 FilePath::StringType item_name; | 1175 FilePath::StringType item_name; |
818 ASSERT_TRUE(item_value->GetString("filename", &item_name)); | 1176 ASSERT_TRUE(item_value->GetString("filename", &item_name)); |
819 ASSERT_EQ(items[2]->GetFullPath().value(), item_name); | 1177 ASSERT_EQ(items[2]->GetFullPath().value(), item_name); |
820 } | 1178 } |
821 | 1179 |
822 IN_PROC_BROWSER_TEST_F(DownloadExtensionTestIncognito, | 1180 // Test that incognito downloads are only visible in incognito contexts, and |
823 DownloadsApi_SearchIncognito) { | 1181 // test that on-record downloads are visible in both incognito and on-record |
1182 // contexts, for DownloadsSearchFunction, DownloadsPauseFunction, | |
1183 // DownloadsResumeFunction, and DownloadsCancelFunction. | |
1184 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1185 DownloadExtensionTest_SearchIncognito) { | |
824 scoped_ptr<base::Value> result_value; | 1186 scoped_ptr<base::Value> result_value; |
825 base::ListValue* result_list = NULL; | 1187 base::ListValue* result_list = NULL; |
826 base::DictionaryValue* result_dict = NULL; | 1188 base::DictionaryValue* result_dict = NULL; |
827 FilePath::StringType filename; | 1189 FilePath::StringType filename; |
828 bool is_incognito = false; | 1190 bool is_incognito = false; |
829 std::string error; | 1191 std::string error; |
830 std::string on_item_arg; | 1192 std::string on_item_arg; |
831 std::string off_item_arg; | 1193 std::string off_item_arg; |
832 std::string result_string; | 1194 std::string result_string; |
833 | 1195 |
834 // Set up one on-record item and one off-record item. | 1196 // Set up one on-record item and one off-record item. |
1197 // Set up the off-record item first because otherwise there are mysteriously 3 | |
1198 // items total instead of 2. | |
1199 // TODO(benjhayden): Figure out where the third item comes from. | |
1200 GoOffTheRecord(); | |
1201 DownloadItem* off_item = CreateSlowTestDownload(); | |
1202 ASSERT_TRUE(off_item); | |
1203 ASSERT_TRUE(off_item->IsOtr()); | |
1204 off_item_arg = DownloadItemIdAsArgList(off_item); | |
835 | 1205 |
836 GoOnTheRecord(); | 1206 GoOnTheRecord(); |
837 DownloadItem* on_item = CreateSlowTestDownload(); | 1207 DownloadItem* on_item = CreateSlowTestDownload(); |
838 ASSERT_TRUE(on_item); | 1208 ASSERT_TRUE(on_item); |
839 ASSERT_FALSE(on_item->IsOtr()); | 1209 ASSERT_FALSE(on_item->IsOtr()); |
840 on_item_arg = DownloadItemIdAsArgList(on_item); | 1210 on_item_arg = DownloadItemIdAsArgList(on_item); |
841 | |
842 GoOffTheRecord(); | |
843 DownloadItem* off_item = CreateSlowTestDownload(); | |
844 ASSERT_TRUE(off_item); | |
845 ASSERT_TRUE(off_item->IsOtr()); | |
846 ASSERT_TRUE(on_item->GetFullPath() != off_item->GetFullPath()); | 1211 ASSERT_TRUE(on_item->GetFullPath() != off_item->GetFullPath()); |
847 off_item_arg = DownloadItemIdAsArgList(off_item); | |
848 | 1212 |
849 // Extensions running in the incognito window should have access to both | 1213 // Extensions running in the incognito window should have access to both |
850 // items because the Test extension is in spanning mode. | 1214 // items because the Test extension is in spanning mode. |
1215 GoOffTheRecord(); | |
851 result_value.reset(RunFunctionAndReturnResult( | 1216 result_value.reset(RunFunctionAndReturnResult( |
852 new DownloadsSearchFunction(), "[{}]")); | 1217 new DownloadsSearchFunction(), "[{}]")); |
853 ASSERT_TRUE(result_value.get()); | 1218 ASSERT_TRUE(result_value.get()); |
854 ASSERT_TRUE(result_value->GetAsList(&result_list)); | 1219 ASSERT_TRUE(result_value->GetAsList(&result_list)); |
855 ASSERT_EQ(2UL, result_list->GetSize()); | 1220 ASSERT_EQ(2UL, result_list->GetSize()); |
856 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict)); | 1221 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict)); |
857 ASSERT_TRUE(result_dict->GetString("filename", &filename)); | 1222 ASSERT_TRUE(result_dict->GetString("filename", &filename)); |
858 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito)); | 1223 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito)); |
859 EXPECT_TRUE(on_item->GetFullPath() == FilePath(filename)); | 1224 EXPECT_TRUE(on_item->GetFullPath() == FilePath(filename)); |
860 EXPECT_FALSE(is_incognito); | 1225 EXPECT_FALSE(is_incognito); |
(...skipping 25 matching lines...) Expand all Loading... | |
886 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), | 1251 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), |
887 off_item_arg); | 1252 off_item_arg); |
888 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 1253 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
889 error.c_str()); | 1254 error.c_str()); |
890 error = RunFunctionAndReturnError( | 1255 error = RunFunctionAndReturnError( |
891 new DownloadsGetFileIconFunction(), | 1256 new DownloadsGetFileIconFunction(), |
892 base::StringPrintf("[%d, {}]", off_item->GetId())); | 1257 base::StringPrintf("[%d, {}]", off_item->GetId())); |
893 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 1258 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
894 error.c_str()); | 1259 error.c_str()); |
895 | 1260 |
896 // TODO(benjhayden): Test incognito_split_mode() extension. | |
897 // TODO(benjhayden): Test download(), onCreated, onChanged, onErased. | |
898 | |
899 GoOffTheRecord(); | 1261 GoOffTheRecord(); |
900 | 1262 |
901 // Do the FileIcon test for both the on- and off-items while off the record. | 1263 // Do the FileIcon test for both the on- and off-items while off the record. |
902 // NOTE(benjhayden): This does not include the FileIcon test from history, | 1264 // NOTE(benjhayden): This does not include the FileIcon test from history, |
903 // just active downloads. This shouldn't be a problem. | 1265 // just active downloads. This shouldn't be a problem. |
904 EXPECT_TRUE(RunFunctionAndReturnString( | 1266 EXPECT_TRUE(RunFunctionAndReturnString( |
905 new DownloadsGetFileIconFunction(), | 1267 new DownloadsGetFileIconFunction(), |
906 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string)); | 1268 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string)); |
907 EXPECT_TRUE(RunFunctionAndReturnString( | 1269 EXPECT_TRUE(RunFunctionAndReturnString( |
908 new DownloadsGetFileIconFunction(), | 1270 new DownloadsGetFileIconFunction(), |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
946 EXPECT_TRUE(off_item->IsCancelled()); | 1308 EXPECT_TRUE(off_item->IsCancelled()); |
947 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), | 1309 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), |
948 off_item_arg); | 1310 off_item_arg); |
949 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 1311 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
950 error.c_str()); | 1312 error.c_str()); |
951 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), | 1313 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), |
952 off_item_arg); | 1314 off_item_arg); |
953 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 1315 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
954 error.c_str()); | 1316 error.c_str()); |
955 } | 1317 } |
1318 | |
1319 // Test that DownloadsEventsListener times out quickly enough for an event | |
1320 // that isn't going to happen. | |
1321 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1322 DownloadExtensionTest_DownloadsEventsListener) { | |
1323 ASSERT_FALSE(WaitFor(100, extension_event_names::kOnDownloadErased, "-1")); | |
1324 } | |
1325 | |
1326 // Test that we can start a download and that the correct sequence of events is | |
1327 // fired for it. | |
1328 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1329 DownloadExtensionTest_Download_Basic) { | |
1330 LoadExtension("downloads_split"); | |
1331 CHECK(StartTestServer()); | |
1332 std::string download_url = GetURL("slow?0"); | |
1333 GoOnTheRecord(); | |
1334 | |
1335 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1336 new DownloadsDownloadFunction(), base::StringPrintf( | |
1337 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
1338 ASSERT_TRUE(result.get()); | |
1339 int result_id = -1; | |
1340 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1341 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1342 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1343 ASSERT_TRUE(item); | |
1344 ScopedCancellingItem canceller(item); | |
1345 ASSERT_EQ(download_url, item->GetURL().spec()); | |
1346 | |
1347 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1348 base::StringPrintf("[{\"danger\": \"safe\"," | |
1349 " \"filename\": \"%s\"," | |
1350 " \"incognito\": false," | |
1351 " \"mime\": \"text/plain\"," | |
1352 " \"paused\": false," | |
1353 " \"url\": \"%s\"}]", | |
1354 GetFilename("slow.txt.crdownload").c_str(), | |
1355 download_url.c_str()))); | |
1356 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1357 base::StringPrintf("[{\"id\": %d," | |
1358 " \"filename\": {" | |
1359 " \"old\": \"%s\"," | |
1360 " \"new\": \"%s\"}," | |
1361 " \"state\": {" | |
1362 " \"old\": \"in_progress\"," | |
1363 " \"new\": \"complete\"}}]", | |
1364 result_id, | |
1365 GetFilename("slow.txt.crdownload").c_str(), | |
1366 GetFilename("slow.txt").c_str()))); | |
1367 } | |
1368 | |
1369 // Test that we can start a download from an incognito context, and that the | |
1370 // download knows that it's incognito. | |
1371 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1372 DownloadExtensionTest_Download_Incognito) { | |
1373 LoadExtension("downloads_split"); | |
1374 CHECK(StartTestServer()); | |
1375 GoOffTheRecord(); | |
1376 std::string download_url = GetURL("slow?0"); | |
1377 | |
1378 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1379 new DownloadsDownloadFunction(), base::StringPrintf( | |
1380 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
1381 ASSERT_TRUE(result.get()); | |
1382 int result_id = -1; | |
1383 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1384 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1385 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1386 ASSERT_TRUE(item); | |
1387 ScopedCancellingItem canceller(item); | |
1388 ASSERT_EQ(download_url, item->GetURL().spec()); | |
1389 | |
1390 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1391 base::StringPrintf("[{\"danger\": \"safe\"," | |
1392 " \"filename\": \"%s\"," | |
1393 " \"incognito\": true," | |
1394 " \"mime\": \"text/plain\"," | |
1395 " \"paused\": false," | |
1396 " \"url\": \"%s\"}]", | |
1397 GetFilename("slow.txt.crdownload").c_str(), | |
1398 download_url.c_str()))); | |
1399 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1400 base::StringPrintf("[{\"id\":%d," | |
1401 " \"filename\": {" | |
1402 " \"old\": \"%s\"," | |
1403 " \"new\": \"%s\"}," | |
1404 " \"state\": {" | |
1405 " \"new\": \"complete\"," | |
1406 " \"old\": \"in_progress\"}}]", | |
1407 result_id, | |
1408 GetFilename("slow.txt.crdownload").c_str(), | |
1409 GetFilename("slow.txt").c_str()))); | |
1410 } | |
1411 | |
1412 // Test that we disallow certain headers case-insensitively. | |
1413 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1414 DownloadExtensionTest_Download_UnsafeHeaders) { | |
1415 LoadExtension("downloads_split"); | |
1416 CHECK(StartTestServer()); | |
1417 GoOnTheRecord(); | |
1418 | |
1419 static const char* kUnsafeHeaders[] = { | |
1420 "Accept-chArsEt", | |
1421 "accept-eNcoding", | |
1422 "coNNection", | |
1423 "coNteNt-leNgth", | |
1424 "cooKIE", | |
1425 "cOOkie2", | |
1426 "coNteNt-traNsfer-eNcodiNg", | |
1427 "dAtE", | |
1428 "ExpEcT", | |
1429 "hOsT", | |
1430 "kEEp-aLivE", | |
1431 "rEfErEr", | |
1432 "tE", | |
1433 "trAilER", | |
1434 "trANsfer-eNcodiNg", | |
1435 "upGRAde", | |
1436 "usER-agENt", | |
1437 "viA", | |
1438 "pRoxY-", | |
1439 "sEc-", | |
1440 "pRoxY-probably-not-evil", | |
1441 "sEc-probably-not-evil", | |
1442 "oRiGiN", | |
1443 "Access-Control-Request-Headers", | |
1444 "Access-Control-Request-Method", | |
1445 }; | |
1446 | |
1447 for (size_t index = 0; index < arraysize(kUnsafeHeaders); ++index) { | |
1448 std::string download_url = GetURL("slow?0"); | |
1449 EXPECT_STREQ(download_extension_errors::kGenericError, | |
1450 RunFunctionAndReturnError(new DownloadsDownloadFunction(), | |
1451 base::StringPrintf( | |
1452 "[{\"url\": \"%s\"," | |
1453 " \"filename\": \"unsafe-header-%lu.txt\"," | |
1454 " \"headers\": [{" | |
1455 " \"name\": \"%s\"," | |
1456 " \"value\": \"unsafe\"}]}]", | |
1457 download_url.c_str(), index, kUnsafeHeaders[index])).c_str()); | |
1458 } | |
1459 } | |
1460 | |
1461 // Test that subdirectories (slashes) are disallowed in filenames. | |
1462 // TODO(benjhayden) Update this when subdirectories are supported. | |
1463 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1464 DownloadExtensionTest_Download_Subdirectory) { | |
1465 LoadExtension("downloads_split"); | |
1466 CHECK(StartTestServer()); | |
1467 std::string download_url = GetURL("slow?0"); | |
1468 GoOnTheRecord(); | |
1469 | |
1470 EXPECT_STREQ(download_extension_errors::kGenericError, | |
1471 RunFunctionAndReturnError(new DownloadsDownloadFunction(), | |
1472 base::StringPrintf( | |
1473 "[{\"url\": \"%s\"," | |
1474 " \"filename\": \"sub/dir/ect/ory.txt\"}]", | |
1475 download_url.c_str())).c_str()); | |
1476 } | |
1477 | |
1478 // Test that invalid filenames are disallowed. | |
1479 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1480 DownloadExtensionTest_Download_InvalidFilename) { | |
1481 LoadExtension("downloads_split"); | |
1482 CHECK(StartTestServer()); | |
1483 std::string download_url = GetURL("slow?0"); | |
1484 GoOnTheRecord(); | |
1485 | |
1486 EXPECT_STREQ(download_extension_errors::kGenericError, | |
1487 RunFunctionAndReturnError(new DownloadsDownloadFunction(), | |
1488 base::StringPrintf( | |
1489 "[{\"url\": \"%s\"," | |
1490 " \"filename\": \"../../../../../etc/passwd\"}]", | |
1491 download_url.c_str())).c_str()); | |
1492 } | |
1493 | |
1494 // Test that downloading invalid URLs immediately returns kInvalidURLError. | |
1495 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1496 DownloadExtensionTest_Download_InvalidURLs) { | |
1497 LoadExtension("downloads_split"); | |
1498 GoOnTheRecord(); | |
1499 | |
1500 static const char* kInvalidURLs[] = { | |
1501 "foo bar", | |
1502 "../hello", | |
1503 "/hello", | |
1504 "google.com/", | |
1505 "http://", | |
1506 "#frag", | |
1507 "foo/bar.html#frag", | |
1508 "javascript:document.write(\\\"hello\\\");", | |
1509 "javascript:return false;", | |
1510 "ftp://example.com/example.txt", | |
1511 }; | |
1512 | |
1513 for (size_t index = 0; index < arraysize(kInvalidURLs); ++index) { | |
1514 EXPECT_STREQ(download_extension_errors::kInvalidURLError, | |
1515 RunFunctionAndReturnError(new DownloadsDownloadFunction(), | |
1516 base::StringPrintf( | |
1517 "[{\"url\": \"%s\"}]", kInvalidURLs[index])).c_str()); | |
1518 } | |
1519 } | |
1520 | |
1521 // TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to | |
1522 // permissions, test downloading from ftp. | |
1523 | |
1524 // Valid URLs plus fragments are still valid URLs. | |
1525 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1526 DownloadExtensionTest_Download_URLFragment) { | |
1527 LoadExtension("downloads_split"); | |
1528 CHECK(StartTestServer()); | |
1529 std::string download_url = GetURL("slow?0#fragment"); | |
1530 GoOnTheRecord(); | |
1531 | |
1532 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1533 new DownloadsDownloadFunction(), base::StringPrintf( | |
1534 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
1535 ASSERT_TRUE(result.get()); | |
1536 int result_id = -1; | |
1537 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1538 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1539 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1540 ASSERT_TRUE(item); | |
1541 ScopedCancellingItem canceller(item); | |
1542 ASSERT_EQ(download_url, item->GetURL().spec()); | |
1543 | |
1544 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1545 base::StringPrintf("[{\"danger\": \"safe\"," | |
1546 " \"filename\": \"%s\"," | |
1547 " \"incognito\": false," | |
1548 " \"mime\": \"text/plain\"," | |
1549 " \"paused\": false," | |
1550 " \"url\": \"%s\"}]", | |
1551 GetFilename("slow.txt.crdownload").c_str(), | |
1552 download_url.c_str()))); | |
1553 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1554 base::StringPrintf("[{\"id\": %d," | |
1555 " \"filename\": {" | |
1556 " \"old\": \"%s\"," | |
1557 " \"new\": \"%s\"}," | |
1558 " \"state\": {" | |
1559 " \"old\": \"in_progress\"," | |
1560 " \"new\": \"complete\"}}]", | |
1561 result_id, | |
1562 GetFilename("slow.txt.crdownload").c_str(), | |
1563 GetFilename("slow.txt").c_str()))); | |
1564 } | |
1565 | |
1566 // Valid data URLs are valid URLs. | |
1567 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1568 DownloadExtensionTest_Download_DataURL) { | |
1569 LoadExtension("downloads_split"); | |
1570 CHECK(StartTestServer()); | |
1571 std::string download_url = "data:text/plain,hello"; | |
1572 GoOnTheRecord(); | |
1573 | |
1574 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1575 new DownloadsDownloadFunction(), base::StringPrintf( | |
1576 "[{\"url\": \"%s\"," | |
1577 " \"filename\": \"data.txt\"}]", download_url.c_str()))); | |
1578 ASSERT_TRUE(result.get()); | |
1579 int result_id = -1; | |
1580 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1581 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1582 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1583 ASSERT_TRUE(item); | |
1584 ScopedCancellingItem canceller(item); | |
1585 ASSERT_EQ(download_url, item->GetURL().spec()); | |
1586 | |
1587 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1588 base::StringPrintf("[{\"danger\": \"safe\"," | |
1589 " \"filename\": \"%s\"," | |
1590 " \"incognito\": false," | |
1591 " \"mime\": \"text/plain\"," | |
1592 " \"paused\": false," | |
1593 " \"url\": \"%s\"}]", | |
1594 GetFilename("data.txt.crdownload").c_str(), | |
1595 download_url.c_str()))); | |
1596 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1597 base::StringPrintf("[{\"id\": %d," | |
1598 " \"filename\": {" | |
1599 " \"old\": \"%s\"," | |
1600 " \"new\": \"%s\"}," | |
1601 " \"state\": {" | |
1602 " \"old\": \"in_progress\"," | |
1603 " \"new\": \"complete\"}}]", | |
1604 result_id, | |
1605 GetFilename("data.txt.crdownload").c_str(), | |
1606 GetFilename("data.txt").c_str()))); | |
1607 } | |
1608 | |
1609 // Valid file URLs are valid URLs. | |
1610 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1611 DownloadExtensionTest_Download_File) { | |
1612 LoadExtension("downloads_split"); | |
1613 CHECK(StartTestServer()); | |
1614 std::string download_url = "file:///"; | |
1615 GoOnTheRecord(); | |
1616 | |
1617 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1618 new DownloadsDownloadFunction(), base::StringPrintf( | |
1619 "[{\"url\": \"%s\"," | |
1620 " \"filename\": \"file.txt\"}]", download_url.c_str()))); | |
1621 ASSERT_TRUE(result.get()); | |
1622 int result_id = -1; | |
1623 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1624 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1625 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1626 ASSERT_TRUE(item); | |
1627 ScopedCancellingItem canceller(item); | |
1628 #if defined(OS_WIN) | |
1629 download_url += "/"; | |
1630 #endif | |
1631 ASSERT_EQ(download_url, item->GetURL().spec()); | |
1632 | |
1633 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1634 base::StringPrintf("[{\"danger\": \"safe\"," | |
1635 " \"filename\": \"%s\"," | |
1636 " \"incognito\": false," | |
1637 " \"mime\": \"text/html\"," | |
1638 " \"paused\": false," | |
1639 " \"url\": \"%s\"}]", | |
1640 GetFilename("file.txt.crdownload").c_str(), | |
1641 download_url.c_str()))); | |
1642 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1643 base::StringPrintf("[{\"id\": %d," | |
1644 " \"filename\": {" | |
1645 " \"old\": \"%s\"," | |
1646 " \"new\": \"%s\"}," | |
1647 " \"state\": {" | |
1648 " \"old\": \"in_progress\"," | |
1649 " \"new\": \"complete\"}}]", | |
1650 result_id, | |
1651 GetFilename("file.txt.crdownload").c_str(), | |
1652 GetFilename("file.txt").c_str()))); | |
1653 } | |
1654 | |
1655 // Test that auth-basic-succeed would fail if the resource requires the | |
1656 // Authorization header and chrome fails to propagate it back to the server. | |
1657 // This tests both that testserver.py does not succeed when it should fail as | |
1658 // well as how the downloads extension API exposes the failure to extensions. | |
1659 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1660 DownloadExtensionTest_Download_AuthBasic_Fail) { | |
1661 LoadExtension("downloads_split"); | |
1662 CHECK(StartTestServer()); | |
1663 std::string download_url = GetURL("auth-basic"); | |
1664 GoOnTheRecord(); | |
1665 | |
1666 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1667 new DownloadsDownloadFunction(), base::StringPrintf( | |
1668 "[{\"url\": \"%s\"," | |
1669 " \"filename\": \"auth-basic-fail.txt\"}]", | |
1670 download_url.c_str()))); | |
1671 ASSERT_TRUE(result.get()); | |
1672 int result_id = -1; | |
1673 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1674 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1675 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1676 ASSERT_TRUE(item); | |
1677 ScopedCancellingItem canceller(item); | |
1678 ASSERT_EQ(download_url, item->GetURL().spec()); | |
1679 | |
1680 ASSERT_TRUE(WaitForInterruption(item, 30, base::StringPrintf( | |
1681 "[{\"danger\": \"safe\"," | |
1682 " \"incognito\": false," | |
1683 " \"mime\": \"text/html\"," | |
1684 " \"paused\": false," | |
1685 " \"url\": \"%s\"}]", | |
1686 download_url.c_str()))); | |
1687 } | |
1688 | |
1689 // Test that DownloadsDownloadFunction propagates |headers| to the URLRequest. | |
1690 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1691 DownloadExtensionTest_Download_Headers) { | |
1692 LoadExtension("downloads_split"); | |
1693 CHECK(StartTestServer()); | |
1694 std::string download_url = GetURL("files/downloads/a_zip_file.zip?" | |
1695 "expected_headers=Foo:bar&expected_headers=Qx:yo"); | |
1696 GoOnTheRecord(); | |
1697 | |
1698 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1699 new DownloadsDownloadFunction(), base::StringPrintf( | |
1700 "[{\"url\": \"%s\"," | |
1701 " \"filename\": \"headers-succeed.txt\"," | |
1702 " \"headers\": [" | |
1703 " {\"name\": \"Foo\", \"value\": \"bar\"}," | |
1704 " {\"name\": \"Qx\", \"value\":\"yo\"}]}]", | |
1705 download_url.c_str()))); | |
1706 ASSERT_TRUE(result.get()); | |
1707 int result_id = -1; | |
1708 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1709 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1710 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1711 ASSERT_TRUE(item); | |
1712 ScopedCancellingItem canceller(item); | |
1713 ASSERT_EQ(download_url, item->GetURL().spec()); | |
1714 | |
1715 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1716 base::StringPrintf("[{\"danger\": \"safe\"," | |
1717 " \"incognito\": false," | |
1718 " \"mime\": \"application/octet-stream\"," | |
1719 " \"paused\": false," | |
1720 " \"url\": \"%s\"}]", | |
1721 download_url.c_str()))); | |
1722 std::string incomplete_filename = GetFilename( | |
1723 "headers-succeed.txt.crdownload"); | |
1724 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1725 base::StringPrintf("[{\"id\": %d," | |
1726 " \"filename\": {" | |
1727 " \"old\": \"%s\"," | |
1728 " \"new\": \"%s\"}," | |
1729 " \"state\": {" | |
1730 " \"old\": \"in_progress\"," | |
1731 " \"new\": \"complete\"}}]", | |
1732 result_id, | |
1733 incomplete_filename.c_str(), | |
1734 GetFilename("headers-succeed.txt").c_str()))); | |
1735 } | |
1736 | |
1737 // Test that headers-succeed would fail if the resource requires the headers and | |
1738 // chrome fails to propagate them back to the server. This tests both that | |
1739 // testserver.py does not succeed when it should fail as well as how the | |
1740 // downloads extension api exposes the failure to extensions. | |
1741 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1742 DownloadExtensionTest_Download_Headers_Fail) { | |
1743 LoadExtension("downloads_split"); | |
1744 CHECK(StartTestServer()); | |
1745 std::string download_url = GetURL("files/downloads/a_zip_file.zip?" | |
1746 "expected_headers=Foo:bar&expected_headers=Qx:yo"); | |
1747 GoOnTheRecord(); | |
1748 | |
1749 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1750 new DownloadsDownloadFunction(), base::StringPrintf( | |
1751 "[{\"url\": \"%s\"," | |
1752 " \"filename\": \"headers-fail.txt\"}]", | |
1753 download_url.c_str()))); | |
1754 ASSERT_TRUE(result.get()); | |
1755 int result_id = -1; | |
1756 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1757 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1758 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1759 ASSERT_TRUE(item); | |
1760 ScopedCancellingItem canceller(item); | |
1761 ASSERT_EQ(download_url, item->GetURL().spec()); | |
1762 | |
1763 ASSERT_TRUE(WaitForInterruption(item, 33, base::StringPrintf( | |
1764 "[{\"danger\": \"safe\"," | |
1765 " \"incognito\": false," | |
1766 " \"bytesReceived\": 0," | |
1767 " \"mime\": \"\"," | |
1768 " \"paused\": false," | |
1769 " \"url\": \"%s\"}]", | |
1770 download_url.c_str()))); | |
1771 } | |
1772 | |
1773 // Test that DownloadsDownloadFunction propagates the Authorization header | |
1774 // correctly. | |
1775 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1776 DownloadExtensionTest_Download_AuthBasic) { | |
1777 LoadExtension("downloads_split"); | |
1778 CHECK(StartTestServer()); | |
1779 std::string download_url = GetURL("auth-basic"); | |
1780 // This is just base64 of 'username:secret'. | |
1781 static const char* kAuthorization = "dXNlcm5hbWU6c2VjcmV0"; | |
1782 GoOnTheRecord(); | |
1783 | |
1784 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1785 new DownloadsDownloadFunction(), base::StringPrintf( | |
1786 "[{\"url\": \"%s\"," | |
1787 " \"filename\": \"auth-basic-succeed.txt\"," | |
1788 " \"headers\": [{" | |
1789 " \"name\": \"Authorization\"," | |
1790 " \"value\": \"Basic %s\"}]}]", | |
1791 download_url.c_str(), kAuthorization))); | |
1792 ASSERT_TRUE(result.get()); | |
1793 int result_id = -1; | |
1794 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1795 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1796 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1797 ASSERT_TRUE(item); | |
1798 ScopedCancellingItem canceller(item); | |
1799 ASSERT_EQ(download_url, item->GetURL().spec()); | |
1800 | |
1801 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1802 base::StringPrintf("[{\"danger\": \"safe\"," | |
1803 " \"incognito\": false," | |
1804 " \"mime\": \"text/html\"," | |
1805 " \"paused\": false," | |
1806 " \"url\": \"%s\"}]", download_url.c_str()))); | |
1807 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1808 base::StringPrintf("[{\"id\": %d," | |
1809 " \"state\": {" | |
1810 " \"old\": \"in_progress\"," | |
1811 " \"new\": \"complete\"}}]", result_id))); | |
1812 } | |
1813 | |
1814 // Test that DownloadsDownloadFunction propagates the |method| and |body| | |
1815 // parameters to the URLRequest. | |
1816 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1817 DownloadExtensionTest_Download_Post) { | |
1818 LoadExtension("downloads_split"); | |
1819 CHECK(StartTestServer()); | |
1820 std::string download_url = GetURL("files/post/downloads/a_zip_file.zip?" | |
1821 "expected_body=BODY"); | |
1822 GoOnTheRecord(); | |
1823 | |
1824 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1825 new DownloadsDownloadFunction(), base::StringPrintf( | |
1826 "[{\"url\": \"%s\"," | |
1827 " \"filename\": \"post-succeed.txt\"," | |
1828 " \"method\": \"POST\"," | |
1829 " \"body\": \"BODY\"}]", | |
1830 download_url.c_str()))); | |
1831 ASSERT_TRUE(result.get()); | |
1832 int result_id = -1; | |
1833 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1834 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1835 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1836 ASSERT_TRUE(item); | |
1837 ScopedCancellingItem canceller(item); | |
1838 ASSERT_EQ(download_url, item->GetURL().spec()); | |
1839 | |
1840 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1841 base::StringPrintf("[{\"danger\": \"safe\"," | |
1842 " \"incognito\": false," | |
1843 " \"mime\": \"application/octet-stream\"," | |
1844 " \"paused\": false," | |
1845 " \"bytesReceived\": 164," | |
1846 " \"url\": \"%s\"}]", download_url.c_str()))); | |
1847 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1848 base::StringPrintf("[{\"id\": %d," | |
1849 " \"state\": {" | |
1850 " \"old\": \"in_progress\"," | |
1851 " \"new\": \"complete\"}}]", result_id))); | |
1852 } | |
1853 | |
1854 // Test that downloadPostSuccess would fail if the resource requires the POST | |
1855 // method, and chrome fails to propagate the |method| parameter back to the | |
1856 // server. This tests both that testserver.py does not succeed when it should | |
1857 // fail, and this tests how the downloads extension api exposes the failure to | |
1858 // extensions. | |
1859 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1860 DownloadExtensionTest_Download_Post_Get) { | |
1861 LoadExtension("downloads_split"); | |
1862 CHECK(StartTestServer()); | |
1863 std::string download_url = GetURL("files/post/downloads/a_zip_file.zip?" | |
1864 "expected_body=BODY"); | |
1865 GoOnTheRecord(); | |
1866 | |
1867 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1868 new DownloadsDownloadFunction(), base::StringPrintf( | |
1869 "[{\"url\": \"%s\"," | |
1870 " \"body\": \"BODY\"," | |
1871 " \"filename\": \"post-get.txt\"}]", | |
1872 download_url.c_str()))); | |
1873 ASSERT_TRUE(result.get()); | |
1874 int result_id = -1; | |
1875 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1876 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1877 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1878 ASSERT_TRUE(item); | |
1879 ScopedCancellingItem canceller(item); | |
1880 ASSERT_EQ(download_url, item->GetURL().spec()); | |
1881 | |
1882 ASSERT_TRUE(WaitForInterruption(item, 33, base::StringPrintf( | |
1883 "[{\"danger\": \"safe\"," | |
1884 " \"incognito\": false," | |
1885 " \"mime\": \"\"," | |
1886 " \"paused\": false," | |
1887 " \"id\": %d," | |
1888 " \"url\": \"%s\"}]", | |
1889 result_id, | |
1890 download_url.c_str()))); | |
1891 } | |
1892 | |
1893 // Test that downloadPostSuccess would fail if the resource requires the POST | |
1894 // method, and chrome fails to propagate the |body| parameter back to the | |
1895 // server. This tests both that testserver.py does not succeed when it should | |
1896 // fail, and this tests how the downloads extension api exposes the failure to | |
1897 // extensions. | |
1898 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1899 DownloadExtensionTest_Download_Post_NoBody) { | |
1900 LoadExtension("downloads_split"); | |
1901 CHECK(StartTestServer()); | |
1902 std::string download_url = GetURL("files/post/downloads/a_zip_file.zip?" | |
1903 "expected_body=BODY"); | |
1904 GoOnTheRecord(); | |
1905 | |
1906 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1907 new DownloadsDownloadFunction(), base::StringPrintf( | |
1908 "[{\"url\": \"%s\"," | |
1909 " \"method\": \"POST\"," | |
1910 " \"filename\": \"post-nobody.txt\"}]", | |
1911 download_url.c_str()))); | |
1912 ASSERT_TRUE(result.get()); | |
1913 int result_id = -1; | |
1914 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1915 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1916 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1917 ASSERT_TRUE(item); | |
1918 ScopedCancellingItem canceller(item); | |
1919 ASSERT_EQ(download_url, item->GetURL().spec()); | |
1920 | |
1921 ASSERT_TRUE(WaitForInterruption(item, 33, base::StringPrintf( | |
1922 "[{\"danger\": \"safe\"," | |
1923 " \"incognito\": false," | |
1924 " \"mime\": \"\"," | |
1925 " \"paused\": false," | |
1926 " \"id\": %d," | |
1927 " \"url\": \"%s\"}]", | |
1928 result_id, | |
1929 download_url.c_str()))); | |
1930 } | |
1931 | |
1932 // Test that cancel()ing an in-progress download causes its state to transition | |
1933 // to interrupted, and test that that state transition is detectable by an | |
1934 // onChanged event listener. TODO(benjhayden): Test other sources of | |
1935 // interruptions such as server death. | |
1936 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1937 DownloadExtensionTest_Download_Cancel) { | |
1938 LoadExtension("downloads_split"); | |
1939 CHECK(StartTestServer()); | |
1940 std::string download_url = GetURL("download-known-size"); | |
1941 GoOnTheRecord(); | |
1942 | |
1943 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1944 new DownloadsDownloadFunction(), base::StringPrintf( | |
1945 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
1946 ASSERT_TRUE(result.get()); | |
1947 int result_id = -1; | |
1948 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1949 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1950 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1951 ASSERT_TRUE(item); | |
1952 ScopedCancellingItem canceller(item); | |
1953 ASSERT_EQ(download_url, item->GetURL().spec()); | |
1954 | |
1955 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1956 base::StringPrintf("[{\"danger\": \"safe\"," | |
1957 " \"incognito\": false," | |
1958 " \"mime\": \"application/octet-stream\"," | |
1959 " \"paused\": false," | |
1960 " \"id\": %d," | |
1961 " \"url\": \"%s\"}]", | |
1962 result_id, | |
1963 download_url.c_str()))); | |
1964 item->Cancel(true); | |
1965 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1966 base::StringPrintf("[{\"id\": %d," | |
1967 " \"error\": {\"new\": 40}," | |
1968 " \"state\": {" | |
1969 " \"old\": \"in_progress\"," | |
1970 " \"new\": \"interrupted\"}}]", | |
1971 result_id))); | |
1972 } | |
1973 | |
1974 // Test downloading filesystem: URLs. | |
1975 // NOTE: chrome disallows creating HTML5 FileSystem Files in incognito. | |
1976 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1977 DownloadExtensionTest_Download_FileSystemURL) { | |
1978 static const char* kHTML5FileCreated = "html5_file_created"; | |
1979 LoadExtension("downloads_split"); | |
1980 fileapi::FileSystemContext* fs = BrowserContext::GetFileSystemContext( | |
1981 browser()->profile()); | |
1982 fileapi::FileSystemContext::OpenFileSystemCallback fs_opened = base::Bind( | |
1983 &OpenFileSystemCallback, | |
1984 base::Unretained(fs), | |
1985 "on_record.txt", | |
1986 browser()->profile()); | |
1987 fs->OpenFileSystem(GURL(GetExtensionURL()), | |
1988 fileapi::kFileSystemTypeTemporary, | |
1989 true/*create*/, | |
1990 fs_opened); | |
1991 ASSERT_TRUE(WaitFor(kHTML5FileCreated, "on_record.txt")); | |
1992 | |
1993 std::string download_url = "filesystem:" + GetExtensionURL() + | |
1994 "temporary/on_record.txt"; | |
1995 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1996 new DownloadsDownloadFunction(), base::StringPrintf( | |
1997 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
1998 ASSERT_TRUE(result.get()); | |
1999 int result_id = -1; | |
2000 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
2001 | |
2002 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
2003 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
2004 ASSERT_TRUE(item); | |
2005 ScopedCancellingItem canceller(item); | |
2006 ASSERT_EQ(download_url, item->GetURL().spec()); | |
2007 | |
2008 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
2009 base::StringPrintf("[{\"danger\": \"safe\"," | |
2010 " \"filename\": \"%s\"," | |
2011 " \"incognito\": false," | |
2012 " \"mime\": \"text/plain\"," | |
2013 " \"paused\": false," | |
2014 " \"url\": \"%s\"}]", | |
2015 GetFilename("on_record.txt.crdownload").c_str(), | |
2016 download_url.c_str()))); | |
2017 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
2018 base::StringPrintf("[{\"id\": %d," | |
2019 " \"filename\": {" | |
2020 " \"old\": \"%s\"," | |
2021 " \"new\": \"%s\"}," | |
2022 " \"state\": {" | |
2023 " \"old\": \"in_progress\"," | |
2024 " \"new\": \"complete\"}}]", | |
2025 result_id, | |
2026 GetFilename("on_record.txt.crdownload").c_str(), | |
2027 GetFilename("on_record.txt").c_str()))); | |
2028 } | |
OLD | NEW |