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" | |
11 #include "base/scoped_temp_dir.h" | 8 #include "base/scoped_temp_dir.h" |
12 #include "base/stl_util.h" | |
13 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
14 #include "chrome/browser/download/download_file_icon_extractor.h" | 10 #include "chrome/browser/download/download_file_icon_extractor.h" |
15 #include "chrome/browser/download/download_service.h" | 11 #include "chrome/browser/download/download_service.h" |
16 #include "chrome/browser/download/download_service_factory.h" | 12 #include "chrome/browser/download/download_service_factory.h" |
17 #include "chrome/browser/download/download_test_observer.h" | 13 #include "chrome/browser/download/download_test_observer.h" |
18 #include "chrome/browser/extensions/api/downloads/downloads_api.h" | 14 #include "chrome/browser/extensions/api/downloads/downloads_api.h" |
19 #include "chrome/browser/extensions/extension_apitest.h" | |
20 #include "chrome/browser/extensions/extension_event_names.h" | |
21 #include "chrome/browser/extensions/extension_function_test_utils.h" | 15 #include "chrome/browser/extensions/extension_function_test_utils.h" |
22 #include "chrome/browser/net/url_request_mock_util.h" | 16 #include "chrome/browser/net/url_request_mock_util.h" |
23 #include "chrome/browser/prefs/pref_service.h" | 17 #include "chrome/browser/prefs/pref_service.h" |
24 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
25 #include "chrome/browser/ui/browser.h" | 19 #include "chrome/browser/ui/browser.h" |
26 #include "chrome/browser/ui/tab_contents/tab_contents.h" | |
27 #include "chrome/common/chrome_notification_types.h" | |
28 #include "chrome/common/pref_names.h" | 20 #include "chrome/common/pref_names.h" |
29 #include "chrome/test/base/in_process_browser_test.h" | 21 #include "chrome/test/base/in_process_browser_test.h" |
30 #include "chrome/test/base/ui_test_utils.h" | 22 #include "chrome/test/base/ui_test_utils.h" |
31 #include "content/public/browser/browser_context.h" | |
32 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
33 #include "content/public/browser/download_item.h" | |
34 #include "content/public/browser/download_manager.h" | 24 #include "content/public/browser/download_manager.h" |
35 #include "content/public/browser/download_persistent_store_info.h" | 25 #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" | |
39 #include "content/test/net/url_request_slow_download_job.h" | 26 #include "content/test/net/url_request_slow_download_job.h" |
40 #include "net/base/data_url.h" | 27 #include "net/base/data_url.h" |
41 #include "net/base/net_util.h" | 28 #include "net/base/net_util.h" |
42 #include "net/url_request/url_request.h" | |
43 #include "net/url_request/url_request_context.h" | |
44 #include "net/url_request/url_request_job.h" | |
45 #include "net/url_request/url_request_job_factory.h" | |
46 #include "ui/gfx/codec/png_codec.h" | 29 #include "ui/gfx/codec/png_codec.h" |
47 #include "webkit/blob/blob_data.h" | |
48 #include "webkit/blob/blob_storage_controller.h" | |
49 #include "webkit/blob/blob_url_request_job.h" | |
50 #include "webkit/fileapi/file_system_context.h" | |
51 #include "webkit/fileapi/file_system_operation_interface.h" | |
52 #include "webkit/fileapi/file_system_url.h" | |
53 | 30 |
54 using content::BrowserContext; | 31 using content::BrowserContext; |
55 using content::BrowserThread; | 32 using content::BrowserThread; |
56 using content::DownloadItem; | 33 using content::DownloadItem; |
57 using content::DownloadManager; | 34 using content::DownloadManager; |
58 using content::DownloadPersistentStoreInfo; | 35 using content::DownloadPersistentStoreInfo; |
59 | 36 |
60 namespace { | 37 namespace { |
61 | 38 |
62 // Comparator that orders download items by their ID. Can be used with | 39 // Comparator that orders download items by their ID. Can be used with |
63 // std::sort. | 40 // std::sort. |
64 struct DownloadIdComparator { | 41 struct DownloadIdComparator { |
65 bool operator() (DownloadItem* first, DownloadItem* second) { | 42 bool operator() (DownloadItem* first, DownloadItem* second) { |
66 return first->GetId() < second->GetId(); | 43 return first->GetId() < second->GetId(); |
67 } | 44 } |
68 }; | 45 }; |
69 | 46 |
70 class DownloadsEventsListener : public content::NotificationObserver { | 47 class DownloadExtensionTest : public InProcessBrowserTest { |
71 public: | |
72 DownloadsEventsListener() | |
73 : waiting_(false) { | |
74 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | |
75 content::NotificationService::AllSources()); | |
76 } | |
77 | |
78 virtual ~DownloadsEventsListener() { | |
79 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | |
80 content::NotificationService::AllSources()); | |
81 STLDeleteElements(&events_); | |
82 } | |
83 | |
84 class Event { | |
85 public: | |
86 Event(Profile* profile, | |
87 const std::string& event_name, | |
88 const std::string& json_args, | |
89 base::Time caught) | |
90 : profile_(profile), | |
91 event_name_(event_name), | |
92 json_args_(json_args), | |
93 args_(base::JSONReader::Read(json_args)), | |
94 caught_(caught) { | |
95 } | |
96 | |
97 const base::Time& caught() { return caught_; } | |
98 | |
99 bool Equals(const Event& other) { | |
100 if ((profile_ != other.profile_) || | |
101 (event_name_ != other.event_name_)) | |
102 return false; | |
103 if ((event_name_ == extension_event_names::kOnDownloadCreated || | |
104 event_name_ == extension_event_names::kOnDownloadChanged) && | |
105 args_.get() && | |
106 other.args_.get()) { | |
107 base::ListValue* left_list = NULL; | |
108 base::DictionaryValue* left_dict = NULL; | |
109 base::ListValue* right_list = NULL; | |
110 base::DictionaryValue* right_dict = NULL; | |
111 if (!args_->GetAsList(&left_list) || | |
112 !other.args_->GetAsList(&right_list) || | |
113 !left_list->GetDictionary(0, &left_dict) || | |
114 !right_list->GetDictionary(0, &right_dict)) | |
115 return false; | |
116 for (base::DictionaryValue::Iterator iter(*left_dict); | |
117 iter.HasNext(); iter.Advance()) { | |
118 base::Value* right_value = NULL; | |
119 if (right_dict->HasKey(iter.key()) && | |
120 right_dict->Get(iter.key(), &right_value) && | |
121 !iter.value().Equals(right_value)) { | |
122 return false; | |
123 } | |
124 } | |
125 return true; | |
126 } else if ((event_name_ == extension_event_names::kOnDownloadErased) && | |
127 args_.get() && | |
128 other.args_.get()) { | |
129 int my_id = -1, other_id = -1; | |
130 return (args_->GetAsInteger(&my_id) && | |
131 other.args_->GetAsInteger(&other_id) && | |
132 my_id == other_id); | |
133 } | |
134 return json_args_ == other.json_args_; | |
135 } | |
136 | |
137 std::string Debug() { | |
138 return base::StringPrintf("Event(%p, %s, %s, %f)", | |
139 profile_, | |
140 event_name_.c_str(), | |
141 json_args_.c_str(), | |
142 caught_.ToJsTime()); | |
143 } | |
144 | |
145 private: | |
146 Profile* profile_; | |
147 std::string event_name_; | |
148 std::string json_args_; | |
149 scoped_ptr<base::Value> args_; | |
150 base::Time caught_; | |
151 | |
152 DISALLOW_COPY_AND_ASSIGN(Event); | |
153 }; | |
154 | |
155 typedef ExtensionDownloadsEventRouter::DownloadsNotificationSource | |
156 DownloadsNotificationSource; | |
157 | |
158 void Observe(int type, const content::NotificationSource& source, | |
159 const content::NotificationDetails& details) { | |
160 switch (type) { | |
161 case chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT: | |
162 { | |
163 DownloadsNotificationSource* dns = | |
164 content::Source<DownloadsNotificationSource>(source).ptr(); | |
165 Event* new_event = new Event( | |
166 dns->profile, | |
167 dns->event_name, | |
168 *content::Details<std::string>(details).ptr(), base::Time::Now()); | |
169 events_.push_back(new_event); | |
170 if (waiting_ && | |
171 waiting_for_.get() && | |
172 waiting_for_->Equals(*new_event)) { | |
173 waiting_ = false; | |
174 MessageLoopForUI::current()->Quit(); | |
175 } | |
176 break; | |
177 } | |
178 default: | |
179 NOTREACHED(); | |
180 } | |
181 } | |
182 | |
183 bool WaitFor(Profile* profile, | |
184 const std::string& event_name, | |
185 const std::string& json_args) { | |
186 waiting_for_.reset(new Event(profile, event_name, json_args, base::Time())); | |
187 for (std::deque<Event*>::const_iterator iter = events_.begin(); | |
188 iter != events_.end(); ++iter) { | |
189 if ((*iter)->Equals(*waiting_for_.get())) | |
190 return true; | |
191 } | |
192 waiting_ = true; | |
193 ui_test_utils::RunMessageLoop(); | |
194 bool success = !waiting_; | |
195 if (waiting_) { | |
196 // Print the events that were caught since the last WaitFor() call to help | |
197 // find the erroneous event. | |
198 // TODO(benjhayden) Fuzzy-match and highlight the erroneous event. | |
199 for (std::deque<Event*>::const_iterator iter = events_.begin(); | |
200 iter != events_.end(); ++iter) { | |
201 if ((*iter)->caught() > last_wait_) { | |
202 LOG(INFO) << "Caught " << (*iter)->Debug(); | |
203 } | |
204 } | |
205 if (waiting_for_.get()) { | |
206 LOG(INFO) << "Timed out waiting for " << waiting_for_->Debug(); | |
207 } | |
208 waiting_ = false; | |
209 } | |
210 waiting_for_.reset(); | |
211 last_wait_ = base::Time::Now(); | |
212 return success; | |
213 } | |
214 | |
215 private: | |
216 void TimedOut() { | |
217 if (!waiting_for_.get()) | |
218 return; | |
219 MessageLoopForUI::current()->Quit(); | |
220 } | |
221 | |
222 bool waiting_; | |
223 base::Time last_wait_; | |
224 scoped_ptr<Event> waiting_for_; | |
225 content::NotificationRegistrar registrar_; | |
226 std::deque<Event*> events_; | |
227 | |
228 DISALLOW_COPY_AND_ASSIGN(DownloadsEventsListener); | |
229 }; | |
230 | |
231 class DownloadExtensionTest : public ExtensionApiTest { | |
232 public: | |
233 DownloadExtensionTest() | |
234 : extension_(NULL), | |
235 incognito_browser_(NULL), | |
236 current_browser_(NULL) { | |
237 } | |
238 | |
239 protected: | 48 protected: |
240 // Used with CreateHistoryDownloads | 49 // Used with CreateHistoryDownloads |
241 struct HistoryDownloadInfo { | 50 struct HistoryDownloadInfo { |
242 // Filename to use. CreateHistoryDownloads will append this filename to the | 51 // Filename to use. CreateHistoryDownloads will append this filename to the |
243 // temporary downloads directory specified by downloads_directory(). | 52 // temporary downloads directory specified by downloads_directory(). |
244 const FilePath::CharType* filename; | 53 const FilePath::CharType* filename; |
245 | 54 |
246 // State for the download. Note that IN_PROGRESS downloads will be created | 55 // State for the download. Note that IN_PROGRESS downloads will be created |
247 // as CANCELLED. | 56 // as CANCELLED. |
248 DownloadItem::DownloadState state; | 57 DownloadItem::DownloadState state; |
249 | 58 |
250 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS | 59 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS |
251 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT. | 60 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT. |
252 content::DownloadDangerType danger_type; | 61 content::DownloadDangerType danger_type; |
253 }; | 62 }; |
254 | 63 |
255 void LoadExtension(const char* name) { | 64 virtual Browser* current_browser() { return browser(); } |
256 // Store the created Extension object so that we can attach it to | |
257 // ExtensionFunctions. Also load the extension in incognito profiles for | |
258 // testing incognito. | |
259 extension_ = LoadExtensionIncognito(test_data_dir_.AppendASCII(name)); | |
260 CHECK(extension_); | |
261 } | |
262 | |
263 Browser* current_browser() { return current_browser_; } | |
264 | 65 |
265 // InProcessBrowserTest | 66 // InProcessBrowserTest |
266 virtual void SetUpOnMainThread() OVERRIDE { | 67 virtual void SetUpOnMainThread() OVERRIDE { |
267 BrowserThread::PostTask( | 68 BrowserThread::PostTask( |
268 BrowserThread::IO, FROM_HERE, | 69 BrowserThread::IO, FROM_HERE, |
269 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); | 70 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); |
270 InProcessBrowserTest::SetUpOnMainThread(); | 71 InProcessBrowserTest::SetUpOnMainThread(); |
271 GoOnTheRecord(); | |
272 CreateAndSetDownloadsDirectory(); | 72 CreateAndSetDownloadsDirectory(); |
273 current_browser()->profile()->GetPrefs()->SetBoolean( | 73 current_browser()->profile()->GetPrefs()->SetBoolean( |
274 prefs::kPromptForDownload, false); | 74 prefs::kPromptForDownload, false); |
275 GetOnRecordManager()->RemoveAllDownloads(); | 75 GetDownloadManager()->RemoveAllDownloads(); |
276 events_listener_.reset(new DownloadsEventsListener()); | |
277 } | 76 } |
278 | 77 |
279 void GoOnTheRecord() { current_browser_ = browser(); } | 78 virtual DownloadManager* GetDownloadManager() { |
280 | 79 return BrowserContext::GetDownloadManager(current_browser()->profile()); |
281 void GoOffTheRecord() { | |
282 if (!incognito_browser_) { | |
283 incognito_browser_ = CreateIncognitoBrowser(); | |
284 GetOffRecordManager()->RemoveAllDownloads(); | |
285 } | |
286 current_browser_ = incognito_browser_; | |
287 } | |
288 | |
289 bool WaitFor(const std::string& event_name, const std::string& json_args) { | |
290 return events_listener_->WaitFor( | |
291 current_browser()->profile(), event_name, json_args); | |
292 } | |
293 | |
294 bool WaitForInterruption(DownloadItem* item, int expected_error, | |
295 const std::string& on_created_event) { | |
296 if (!WaitFor(extension_event_names::kOnDownloadCreated, on_created_event)) | |
297 return false; | |
298 // The item may or may not be interrupted before the onCreated event fires. | |
299 if (item->IsInterrupted()) { | |
300 scoped_ptr<base::Value> args(base::JSONReader::Read(on_created_event)); | |
301 base::ListValue* args_list = NULL; | |
302 base::DictionaryValue* args_dict = NULL; | |
303 if (!args->GetAsList(&args_list) || | |
304 !args_list->GetDictionary(0, &args_dict)) | |
305 return false; | |
306 args_dict->SetString("state", "interrupted"); | |
307 args_dict->SetInteger("error", expected_error); | |
308 std::string created_error; | |
309 base::JSONWriter::Write(args_list, &created_error); | |
310 // This is not waiting for a different event, it's refining the | |
311 // expectations on the onCreated event that was just caught. Specifically, | |
312 // if a DownloadItem is already interrupted by the time the onCreated | |
313 // event fires, then the onCreated event should already describe the | |
314 // error. | |
315 return WaitFor(extension_event_names::kOnDownloadCreated, created_error); | |
316 } else { | |
317 return WaitFor(extension_event_names::kOnDownloadChanged, | |
318 base::StringPrintf("[{\"id\": %d," | |
319 " \"error\": {\"current\": %d}," | |
320 " \"state\": {" | |
321 " \"previous\": \"in_progress\"," | |
322 " \"current\": \"interrupted\"}}]", | |
323 item->GetId(), | |
324 expected_error)); | |
325 } | |
326 } | |
327 | |
328 std::string GetExtensionURL() { | |
329 return extension_->url().spec(); | |
330 } | |
331 | |
332 std::string GetFilename(const char* path) { | |
333 std::string result = | |
334 downloads_directory_.path().AppendASCII(path).AsUTF8Unsafe(); | |
335 #if defined(OS_WIN) | |
336 for (std::string::size_type next = result.find("\\"); | |
337 next != std::string::npos; | |
338 next = result.find("\\", next)) { | |
339 result.replace(next, 1, "\\\\"); | |
340 next += 2; | |
341 } | |
342 #endif | |
343 return result; | |
344 } | |
345 | |
346 DownloadManager* GetOnRecordManager() { | |
347 return BrowserContext::GetDownloadManager(browser()->profile()); | |
348 } | |
349 DownloadManager* GetOffRecordManager() { | |
350 return BrowserContext::GetDownloadManager( | |
351 browser()->profile()->GetOffTheRecordProfile()); | |
352 } | |
353 DownloadManager* GetCurrentManager() { | |
354 return (current_browser_ == incognito_browser_) ? | |
355 GetOffRecordManager() : GetOnRecordManager(); | |
356 } | 80 } |
357 | 81 |
358 // Creates a set of history downloads based on the provided |history_info| | 82 // Creates a set of history downloads based on the provided |history_info| |
359 // array. |count| is the number of elements in |history_info|. On success, | 83 // array. |count| is the number of elements in |history_info|. On success, |
360 // |items| will contain |count| DownloadItems in the order that they were | 84 // |items| will contain |count| DownloadItems in the order that they were |
361 // specified in |history_info|. Returns true on success and false otherwise. | 85 // specified in |history_info|. Returns true on success and false otherwise. |
362 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info, | 86 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info, |
363 size_t count, | 87 size_t count, |
364 DownloadManager::DownloadVector* items) { | 88 DownloadManager::DownloadVector* items) { |
365 DownloadIdComparator download_id_comparator; | 89 DownloadIdComparator download_id_comparator; |
366 base::Time current = base::Time::Now(); | 90 base::Time current = base::Time::Now(); |
367 std::vector<DownloadPersistentStoreInfo> entries; | 91 std::vector<DownloadPersistentStoreInfo> entries; |
368 entries.reserve(count); | 92 entries.reserve(count); |
369 for (size_t i = 0; i < count; ++i) { | 93 for (size_t i = 0; i < count; ++i) { |
370 DownloadPersistentStoreInfo entry( | 94 DownloadPersistentStoreInfo entry( |
371 downloads_directory().Append(history_info[i].filename), | 95 downloads_directory().Append(history_info[i].filename), |
372 GURL(), GURL(), // URL, referrer | 96 GURL(), GURL(), // URL, referrer |
373 current, current, // start_time, end_time | 97 current, current, // start_time, end_time |
374 1, 1, // received_bytes, total_bytes | 98 1, 1, // received_bytes, total_bytes |
375 history_info[i].state, // state | 99 history_info[i].state, // state |
376 i + 1, // db_handle | 100 i + 1, // db_handle |
377 false); // opened | 101 false); // opened |
378 entries.push_back(entry); | 102 entries.push_back(entry); |
379 } | 103 } |
380 GetOnRecordManager()->OnPersistentStoreQueryComplete(&entries); | 104 GetDownloadManager()->OnPersistentStoreQueryComplete(&entries); |
381 GetOnRecordManager()->GetAllDownloads(FilePath(), items); | 105 GetDownloadManager()->GetAllDownloads(FilePath(), items); |
382 EXPECT_EQ(count, items->size()); | 106 EXPECT_EQ(count, items->size()); |
383 if (count != items->size()) | 107 if (count != items->size()) |
384 return false; | 108 return false; |
385 | 109 |
386 // Order by ID so that they are in the order that we created them. | 110 // Order by ID so that they are in the order that we created them. |
387 std::sort(items->begin(), items->end(), download_id_comparator); | 111 std::sort(items->begin(), items->end(), download_id_comparator); |
388 // Set the danger type if necessary. | 112 // Set the danger type if necessary. |
389 for (size_t i = 0; i < count; ++i) { | 113 for (size_t i = 0; i < count; ++i) { |
390 if (history_info[i].danger_type != | 114 if (history_info[i].danger_type != |
391 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) { | 115 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) { |
(...skipping 13 matching lines...) Expand all Loading... |
405 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); | 129 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); |
406 ui_test_utils::NavigateToURLWithDisposition( | 130 ui_test_utils::NavigateToURLWithDisposition( |
407 current_browser(), slow_download_url, CURRENT_TAB, | 131 current_browser(), slow_download_url, CURRENT_TAB, |
408 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 132 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
409 observer->WaitForFinished(); | 133 observer->WaitForFinished(); |
410 EXPECT_EQ( | 134 EXPECT_EQ( |
411 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS)); | 135 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS)); |
412 // We don't expect a select file dialog. | 136 // We don't expect a select file dialog. |
413 ASSERT_FALSE(observer->select_file_dialog_seen()); | 137 ASSERT_FALSE(observer->select_file_dialog_seen()); |
414 } | 138 } |
415 GetCurrentManager()->GetAllDownloads(FilePath(), items); | 139 GetDownloadManager()->GetAllDownloads(FilePath(), items); |
416 ASSERT_EQ(count, items->size()); | 140 ASSERT_EQ(count, items->size()); |
417 } | 141 } |
418 | 142 |
419 DownloadItem* CreateSlowTestDownload() { | 143 DownloadItem* CreateSlowTestDownload() { |
420 scoped_ptr<DownloadTestObserver> observer( | 144 scoped_ptr<DownloadTestObserver> observer( |
421 CreateInProgressDownloadObserver(1)); | 145 CreateInProgressDownloadObserver(1)); |
422 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); | 146 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); |
423 DownloadManager* manager = GetCurrentManager(); | 147 DownloadManager* manager = GetDownloadManager(); |
424 | 148 |
425 EXPECT_EQ(0, manager->InProgressCount()); | 149 EXPECT_EQ(0, manager->InProgressCount()); |
426 if (manager->InProgressCount() != 0) | 150 if (manager->InProgressCount() != 0) |
427 return NULL; | 151 return NULL; |
428 | 152 |
429 ui_test_utils::NavigateToURLWithDisposition( | 153 ui_test_utils::NavigateToURLWithDisposition( |
430 current_browser(), slow_download_url, CURRENT_TAB, | 154 current_browser(), slow_download_url, CURRENT_TAB, |
431 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 155 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
432 | 156 |
433 observer->WaitForFinished(); | 157 observer->WaitForFinished(); |
(...skipping 23 matching lines...) Expand all Loading... |
457 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl); | 181 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl); |
458 ui_test_utils::NavigateToURLWithDisposition( | 182 ui_test_utils::NavigateToURLWithDisposition( |
459 current_browser(), finish_url, NEW_FOREGROUND_TAB, | 183 current_browser(), finish_url, NEW_FOREGROUND_TAB, |
460 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 184 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
461 observer->WaitForFinished(); | 185 observer->WaitForFinished(); |
462 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); | 186 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); |
463 } | 187 } |
464 | 188 |
465 DownloadTestObserver* CreateDownloadObserver(size_t download_count) { | 189 DownloadTestObserver* CreateDownloadObserver(size_t download_count) { |
466 return new DownloadTestObserverTerminal( | 190 return new DownloadTestObserverTerminal( |
467 GetCurrentManager(), download_count, true, | 191 GetDownloadManager(), download_count, true, |
468 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); | 192 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); |
469 } | 193 } |
470 | 194 |
471 DownloadTestObserver* CreateInProgressDownloadObserver( | 195 DownloadTestObserver* CreateInProgressDownloadObserver( |
472 size_t download_count) { | 196 size_t download_count) { |
473 return new DownloadTestObserverInProgress( | 197 return new DownloadTestObserverInProgress(GetDownloadManager(), |
474 GetCurrentManager(), download_count, true); | 198 download_count, |
475 } | 199 true); |
476 | |
477 bool RunFunction(UIThreadExtensionFunction* function, | |
478 const std::string& args) { | |
479 scoped_refptr<UIThreadExtensionFunction> delete_function(function); | |
480 SetUpExtensionFunction(function); | |
481 return extension_function_test_utils::RunFunction( | |
482 function, args, browser(), GetFlags()); | |
483 } | 200 } |
484 | 201 |
485 extension_function_test_utils::RunFunctionFlags GetFlags() { | 202 extension_function_test_utils::RunFunctionFlags GetFlags() { |
486 return current_browser()->profile()->IsOffTheRecord() ? | 203 return current_browser()->profile()->IsOffTheRecord() ? |
487 extension_function_test_utils::INCLUDE_INCOGNITO : | 204 extension_function_test_utils::INCLUDE_INCOGNITO : |
488 extension_function_test_utils::NONE; | 205 extension_function_test_utils::NONE; |
489 } | 206 } |
490 | 207 |
491 // extension_function_test_utils::RunFunction*() only uses browser for its | 208 // extension_function_test_utils::RunFunction*() only uses browser for its |
492 // profile(), so pass it the on-record browser so that it always uses the | 209 // profile(), so pass it the on-record browser so that it always uses the |
493 // on-record profile to match real-life behavior. | 210 // on-record profile. |
| 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 } |
494 | 220 |
495 base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function, | 221 base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function, |
496 const std::string& args) { | 222 const std::string& args) { |
497 SetUpExtensionFunction(function); | |
498 return extension_function_test_utils::RunFunctionAndReturnResult( | 223 return extension_function_test_utils::RunFunctionAndReturnResult( |
499 function, args, browser(), GetFlags()); | 224 function, args, browser(), GetFlags()); |
500 } | 225 } |
501 | 226 |
502 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, | 227 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, |
503 const std::string& args) { | 228 const std::string& args) { |
504 SetUpExtensionFunction(function); | |
505 return extension_function_test_utils::RunFunctionAndReturnError( | 229 return extension_function_test_utils::RunFunctionAndReturnError( |
506 function, args, browser(), GetFlags()); | 230 function, args, browser(), GetFlags()); |
507 } | 231 } |
508 | 232 |
509 bool RunFunctionAndReturnString(UIThreadExtensionFunction* function, | 233 bool RunFunctionAndReturnString(UIThreadExtensionFunction* function, |
510 const std::string& args, | 234 const std::string& args, |
511 std::string* result_string) { | 235 std::string* result_string) { |
512 SetUpExtensionFunction(function); | |
513 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args)); | 236 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args)); |
514 EXPECT_TRUE(result.get()); | 237 EXPECT_TRUE(result.get()); |
515 return result.get() && result->GetAsString(result_string); | 238 return result.get() && result->GetAsString(result_string); |
516 } | 239 } |
517 | 240 |
518 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) { | 241 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) { |
519 return base::StringPrintf("[%d]", download_item->GetId()); | 242 return base::StringPrintf("[%d]", download_item->GetId()); |
520 } | 243 } |
521 | 244 |
522 // Checks if a data URL encoded image is a PNG of a given size. | 245 // Checks if a data URL encoded image is a PNG of a given size. |
(...skipping 16 matching lines...) Expand all Loading... |
539 gfx::PNGCodec::FORMAT_RGBA, &decoded_data, | 262 gfx::PNGCodec::FORMAT_RGBA, &decoded_data, |
540 &width, &height)); | 263 &width, &height)); |
541 EXPECT_EQ(expected_size, width); | 264 EXPECT_EQ(expected_size, width); |
542 EXPECT_EQ(expected_size, height); | 265 EXPECT_EQ(expected_size, height); |
543 } | 266 } |
544 | 267 |
545 const FilePath& downloads_directory() { | 268 const FilePath& downloads_directory() { |
546 return downloads_directory_.path(); | 269 return downloads_directory_.path(); |
547 } | 270 } |
548 | 271 |
549 DownloadsEventsListener* events_listener() { return events_listener_.get(); } | |
550 | |
551 private: | 272 private: |
552 void SetUpExtensionFunction(UIThreadExtensionFunction* function) { | |
553 if (extension_) { | |
554 // Recreate the tab each time for insulation. | |
555 TabContents* tab = current_browser()->AddSelectedTabWithURL( | |
556 extension_->GetResourceURL("empty.html"), | |
557 content::PAGE_TRANSITION_LINK); | |
558 function->set_extension(extension_); | |
559 function->SetRenderViewHost(tab->web_contents()->GetRenderViewHost()); | |
560 } | |
561 } | |
562 | |
563 void CreateAndSetDownloadsDirectory() { | 273 void CreateAndSetDownloadsDirectory() { |
564 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); | 274 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); |
565 current_browser()->profile()->GetPrefs()->SetFilePath( | 275 current_browser()->profile()->GetPrefs()->SetFilePath( |
566 prefs::kDownloadDefaultDirectory, | 276 prefs::kDownloadDefaultDirectory, |
567 downloads_directory_.path()); | 277 downloads_directory_.path()); |
568 } | 278 } |
569 | 279 |
570 ScopedTempDir downloads_directory_; | 280 ScopedTempDir downloads_directory_; |
571 const extensions::Extension* extension_; | 281 }; |
| 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: |
572 Browser* incognito_browser_; | 299 Browser* incognito_browser_; |
573 Browser* current_browser_; | 300 Browser* current_browser_; |
574 scoped_ptr<DownloadsEventsListener> events_listener_; | |
575 | |
576 DISALLOW_COPY_AND_ASSIGN(DownloadExtensionTest); | |
577 }; | 301 }; |
578 | 302 |
579 class MockIconExtractorImpl : public DownloadFileIconExtractor { | 303 class MockIconExtractorImpl : public DownloadFileIconExtractor { |
580 public: | 304 public: |
581 MockIconExtractorImpl(const FilePath& path, IconLoader::IconSize icon_size, | 305 MockIconExtractorImpl(const FilePath& path, IconLoader::IconSize icon_size, |
582 const std::string& response) | 306 const std::string& response) |
583 : expected_path_(path), | 307 : expected_path_(path), |
584 expected_icon_size_(icon_size), | 308 expected_icon_size_(icon_size), |
585 response_(response) { | 309 response_(response) { |
586 } | 310 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 if ((*item)->IsInProgress()) | 369 if ((*item)->IsInProgress()) |
646 (*item)->Cancel(true); | 370 (*item)->Cancel(true); |
647 } | 371 } |
648 } | 372 } |
649 | 373 |
650 private: | 374 private: |
651 DownloadManager::DownloadVector* items_; | 375 DownloadManager::DownloadVector* items_; |
652 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller); | 376 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller); |
653 }; | 377 }; |
654 | 378 |
655 class TestProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler { | 379 } // namespace |
656 public: | |
657 explicit TestProtocolHandler( | |
658 webkit_blob::BlobStorageController* blob_storage_controller) | |
659 : blob_storage_controller_(blob_storage_controller) {} | |
660 | |
661 virtual ~TestProtocolHandler() {} | |
662 | |
663 virtual net::URLRequestJob* MaybeCreateJob( | |
664 net::URLRequest* request) const OVERRIDE { | |
665 return new webkit_blob::BlobURLRequestJob( | |
666 request, | |
667 blob_storage_controller_->GetBlobDataFromUrl(request->url()), | |
668 base::MessageLoopProxy::current()); | |
669 } | |
670 | |
671 private: | |
672 webkit_blob::BlobStorageController* const blob_storage_controller_; | |
673 | |
674 DISALLOW_COPY_AND_ASSIGN(TestProtocolHandler); | |
675 }; | |
676 | |
677 class TestURLRequestContext : public net::URLRequestContext { | |
678 public: | |
679 TestURLRequestContext() | |
680 : blob_storage_controller_(new webkit_blob::BlobStorageController) { | |
681 // Job factory owns the protocol handler. | |
682 job_factory_.SetProtocolHandler( | |
683 "blob", new TestProtocolHandler(blob_storage_controller_.get())); | |
684 set_job_factory(&job_factory_); | |
685 } | |
686 | |
687 virtual ~TestURLRequestContext() {} | |
688 | |
689 webkit_blob::BlobStorageController* blob_storage_controller() const { | |
690 return blob_storage_controller_.get(); | |
691 } | |
692 | |
693 private: | |
694 net::URLRequestJobFactory job_factory_; | |
695 scoped_ptr<webkit_blob::BlobStorageController> blob_storage_controller_; | |
696 | |
697 DISALLOW_COPY_AND_ASSIGN(TestURLRequestContext); | |
698 }; | |
699 | |
700 // TODO(benjhayden): Comment. | |
701 class HTML5FileWriter { | |
702 public: | |
703 HTML5FileWriter( | |
704 Profile* profile, | |
705 const std::string& filename, | |
706 const std::string& origin, | |
707 DownloadsEventsListener* events_listener, | |
708 const std::string& payload) | |
709 : profile_(profile), | |
710 filename_(filename), | |
711 origin_(origin), | |
712 events_listener_(events_listener), | |
713 blob_data_(new webkit_blob::BlobData()), | |
714 payload_(payload), | |
715 fs_(BrowserContext::GetFileSystemContext(profile_)) { | |
716 CHECK(profile_); | |
717 CHECK(events_listener_); | |
718 CHECK(fs_); | |
719 } | |
720 | |
721 ~HTML5FileWriter() { | |
722 CHECK(BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | |
723 &HTML5FileWriter::TearDownURLRequestContext, base::Unretained(this)))); | |
724 events_listener_->WaitFor(profile_, kURLRequestContextToreDown, ""); | |
725 } | |
726 | |
727 bool WriteFile() { | |
728 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
729 fs_->OpenFileSystem( | |
730 GURL(origin_), | |
731 fileapi::kFileSystemTypeTemporary, | |
732 kCreateFileSystem, | |
733 base::Bind(&HTML5FileWriter::OpenFileSystemCallback, | |
734 base::Unretained(this))); | |
735 return events_listener_->WaitFor(profile_, kHTML5FileWritten, filename_); | |
736 } | |
737 | |
738 private: | |
739 static const char kHTML5FileWritten[]; | |
740 static const char kURLRequestContextToreDown[]; | |
741 static const bool kExclusive = true; | |
742 static const bool kCreateFileSystem = true; | |
743 | |
744 GURL blob_url() const { return GURL("blob:" + filename_); } | |
745 | |
746 void OpenFileSystemCallback( | |
747 base::PlatformFileError result, | |
748 const std::string& fs_name, | |
749 const GURL& root) { | |
750 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
751 root_ = root.spec(); | |
752 CHECK(BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | |
753 &HTML5FileWriter::CreateFile, base::Unretained(this)))); | |
754 } | |
755 | |
756 fileapi::FileSystemOperationInterface* operation() { | |
757 return fs_->CreateFileSystemOperation(fileapi::FileSystemURL(GURL(root_))); | |
758 } | |
759 | |
760 void CreateFile() { | |
761 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
762 operation()->CreateFile(fileapi::FileSystemURL(GURL(root_ + filename_)), | |
763 kExclusive, base::Bind( | |
764 &HTML5FileWriter::CreateFileCallback, base::Unretained(this))); | |
765 } | |
766 | |
767 void CreateFileCallback(base::PlatformFileError result) { | |
768 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
769 CHECK_EQ(base::PLATFORM_FILE_OK, result); | |
770 blob_data_->AppendData(payload_); | |
771 url_request_context_.reset(new TestURLRequestContext()); | |
772 url_request_context_->blob_storage_controller()->AddFinishedBlob( | |
773 blob_url(), blob_data_); | |
774 operation()->Write( | |
775 url_request_context_.get(), | |
776 fileapi::FileSystemURL(GURL(root_ + filename_)), | |
777 blob_url(), | |
778 0, // offset | |
779 base::Bind(&HTML5FileWriter::WriteCallback, base::Unretained(this))); | |
780 } | |
781 | |
782 void WriteCallback( | |
783 base::PlatformFileError result, | |
784 int64 bytes, | |
785 bool complete) { | |
786 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
787 CHECK_EQ(base::PLATFORM_FILE_OK, result); | |
788 CHECK(BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( | |
789 &HTML5FileWriter::NotifyWritten, base::Unretained(this)))); | |
790 } | |
791 | |
792 void NotifyWritten() { | |
793 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
794 DownloadsEventsListener::DownloadsNotificationSource notification_source; | |
795 notification_source.event_name = kHTML5FileWritten; | |
796 notification_source.profile = profile_; | |
797 content::NotificationService::current()->Notify( | |
798 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | |
799 content::Source<DownloadsEventsListener::DownloadsNotificationSource>( | |
800 ¬ification_source), | |
801 content::Details<std::string>(&filename_)); | |
802 } | |
803 | |
804 void TearDownURLRequestContext() { | |
805 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
806 url_request_context_->blob_storage_controller()->RemoveBlob(blob_url()); | |
807 url_request_context_.reset(); | |
808 CHECK(BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( | |
809 &HTML5FileWriter::NotifyURLRequestContextToreDown, | |
810 base::Unretained(this)))); | |
811 } | |
812 | |
813 void NotifyURLRequestContextToreDown() { | |
814 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
815 DownloadsEventsListener::DownloadsNotificationSource notification_source; | |
816 notification_source.event_name = kURLRequestContextToreDown; | |
817 notification_source.profile = profile_; | |
818 std::string empty_args; | |
819 content::NotificationService::current()->Notify( | |
820 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | |
821 content::Source<DownloadsEventsListener::DownloadsNotificationSource>( | |
822 ¬ification_source), | |
823 content::Details<std::string>(&empty_args)); | |
824 } | |
825 | |
826 Profile* profile_; | |
827 std::string filename_; | |
828 std::string origin_; | |
829 std::string root_; | |
830 DownloadsEventsListener* events_listener_; | |
831 scoped_refptr<webkit_blob::BlobData> blob_data_; | |
832 std::string payload_; | |
833 scoped_ptr<TestURLRequestContext> url_request_context_; | |
834 fileapi::FileSystemContext* fs_; | |
835 | |
836 DISALLOW_COPY_AND_ASSIGN(HTML5FileWriter); | |
837 }; | |
838 | |
839 const char HTML5FileWriter::kHTML5FileWritten[] = "html5_file_written"; | |
840 const char HTML5FileWriter::kURLRequestContextToreDown[] = | |
841 "url_request_context_tore_down"; | |
842 | |
843 } // namespace | |
844 | 380 |
845 IN_PROC_BROWSER_TEST_F( | 381 IN_PROC_BROWSER_TEST_F( |
846 DownloadExtensionTest, DownloadExtensionTest_PauseResumeCancel) { | 382 DownloadExtensionTest, DownloadExtensionTest_PauseResumeCancel) { |
847 DownloadItem* download_item = CreateSlowTestDownload(); | 383 DownloadItem* download_item = CreateSlowTestDownload(); |
848 ASSERT_TRUE(download_item); | 384 ASSERT_TRUE(download_item); |
849 | 385 |
850 // Call pause(). It should succeed and the download should be paused on | 386 // Call pause(). It should succeed and the download should be paused on |
851 // return. | 387 // return. |
852 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), | 388 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), |
853 DownloadItemIdAsArgList(download_item))); | 389 DownloadItemIdAsArgList(download_item))); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
888 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item)); | 424 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item)); |
889 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 425 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
890 error.c_str()); | 426 error.c_str()); |
891 | 427 |
892 // Calling resume on a non-active download yields kInvalidOperationError | 428 // Calling resume on a non-active download yields kInvalidOperationError |
893 error = RunFunctionAndReturnError( | 429 error = RunFunctionAndReturnError( |
894 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item)); | 430 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item)); |
895 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 431 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
896 error.c_str()); | 432 error.c_str()); |
897 | 433 |
898 // Calling paused on a non-existent download yields kInvalidOperationError. | 434 // Calling pause()/resume()/cancel() with invalid download Ids is |
899 error = RunFunctionAndReturnError( | 435 // tested in the API test (DownloadsApiTest). |
900 new DownloadsPauseFunction(), "[-42]"); | |
901 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
902 error.c_str()); | |
903 | |
904 // Calling resume on a non-existent download yields kInvalidOperationError | |
905 error = RunFunctionAndReturnError( | |
906 new DownloadsResumeFunction(), "[-42]"); | |
907 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
908 error.c_str()); | |
909 } | 436 } |
910 | 437 |
911 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted | 438 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted |
912 // download items. | 439 // download items. |
913 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 440 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
914 DownloadExtensionTest_FileIcon_Active) { | 441 DownloadExtensionTest_FileIcon_Active) { |
915 DownloadItem* download_item = CreateSlowTestDownload(); | 442 DownloadItem* download_item = CreateSlowTestDownload(); |
916 ASSERT_TRUE(download_item); | 443 ASSERT_TRUE(download_item); |
917 | 444 |
918 // Get the icon for the in-progress download. This call should succeed even | 445 // Get the icon for the in-progress download. This call should succeed even |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
994 expected_path, IconLoader::NORMAL, "")); | 521 expected_path, IconLoader::NORMAL, "")); |
995 std::string error = RunFunctionAndReturnError(function.release(), args); | 522 std::string error = RunFunctionAndReturnError(function.release(), args); |
996 EXPECT_STREQ(download_extension_errors::kIconNotFoundError, | 523 EXPECT_STREQ(download_extension_errors::kIconNotFoundError, |
997 error.c_str()); | 524 error.c_str()); |
998 | 525 |
999 // Once the download item is deleted, we should return kInvalidOperationError. | 526 // Once the download item is deleted, we should return kInvalidOperationError. |
1000 download_item->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); | 527 download_item->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); |
1001 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args); | 528 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args); |
1002 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 529 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
1003 error.c_str()); | 530 error.c_str()); |
| 531 |
| 532 // Asking for icons of other (invalid) sizes is tested in the API test |
| 533 // (DownloadsApiTest). |
1004 } | 534 } |
1005 | 535 |
1006 // Test that we can acquire file icons for history downloads regardless of | 536 // Test that we can acquire file icons for history downloads regardless of |
1007 // whether they exist or not. If the file doesn't exist we should receive a | 537 // whether they exist or not. If the file doesn't exist we should receive a |
1008 // generic icon from the OS/toolkit that may or may not be specific to the file | 538 // generic icon from the OS/toolkit that may or may not be specific to the file |
1009 // type. | 539 // type. |
1010 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 540 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
1011 DownloadExtensionTest_FileIcon_History) { | 541 DownloadExtensionTest_FileIcon_History) { |
1012 const HistoryDownloadInfo kHistoryInfo[] = { | 542 const HistoryDownloadInfo kHistoryInfo[] = { |
1013 { FILE_PATH_LITERAL("real.txt"), | 543 { FILE_PATH_LITERAL("real.txt"), |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1049 function->SetIconExtractorForTesting(new MockIconExtractorImpl( | 579 function->SetIconExtractorForTesting(new MockIconExtractorImpl( |
1050 (*iter)->GetFullPath(), IconLoader::NORMAL, "hello")); | 580 (*iter)->GetFullPath(), IconLoader::NORMAL, "hello")); |
1051 EXPECT_TRUE(RunFunctionAndReturnString(function.release(), args, | 581 EXPECT_TRUE(RunFunctionAndReturnString(function.release(), args, |
1052 &result_string)); | 582 &result_string)); |
1053 EXPECT_STREQ("hello", result_string.c_str()); | 583 EXPECT_STREQ("hello", result_string.c_str()); |
1054 } | 584 } |
1055 | 585 |
1056 // The temporary files should be cleaned up when the ScopedTempDir is removed. | 586 // The temporary files should be cleaned up when the ScopedTempDir is removed. |
1057 } | 587 } |
1058 | 588 |
1059 // Test passing the empty query to search(). | |
1060 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 589 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
1061 DownloadExtensionTest_SearchEmptyQuery) { | 590 DownloadExtensionTest_SearchEmptyQuery) { |
1062 ScopedCancellingItem item(CreateSlowTestDownload()); | 591 ScopedCancellingItem item(CreateSlowTestDownload()); |
1063 ASSERT_TRUE(item.get()); | 592 ASSERT_TRUE(item.get()); |
1064 | 593 |
1065 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 594 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
1066 new DownloadsSearchFunction(), "[{}]")); | 595 new DownloadsSearchFunction(), "[{}]")); |
1067 ASSERT_TRUE(result.get()); | 596 ASSERT_TRUE(result.get()); |
1068 base::ListValue* result_list = NULL; | 597 base::ListValue* result_list = NULL; |
1069 ASSERT_TRUE(result->GetAsList(&result_list)); | 598 ASSERT_TRUE(result->GetAsList(&result_list)); |
1070 ASSERT_EQ(1UL, result_list->GetSize()); | 599 ASSERT_EQ(1UL, result_list->GetSize()); |
1071 } | 600 } |
1072 | 601 |
1073 // Test the |filenameRegex| parameter for search(). | |
1074 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 602 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
1075 DownloadExtensionTest_SearchFilenameRegex) { | 603 DownloadExtensionTest_SearchFilenameRegex) { |
1076 const HistoryDownloadInfo kHistoryInfo[] = { | 604 const HistoryDownloadInfo kHistoryInfo[] = { |
1077 { FILE_PATH_LITERAL("foobar"), | 605 { FILE_PATH_LITERAL("foobar"), |
1078 DownloadItem::COMPLETE, | 606 DownloadItem::COMPLETE, |
1079 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | 607 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, |
1080 { FILE_PATH_LITERAL("baz"), | 608 { FILE_PATH_LITERAL("baz"), |
1081 DownloadItem::COMPLETE, | 609 DownloadItem::COMPLETE, |
1082 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | 610 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } |
1083 }; | 611 }; |
1084 DownloadManager::DownloadVector all_downloads; | 612 DownloadManager::DownloadVector all_downloads; |
1085 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), | 613 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), |
1086 &all_downloads)); | 614 &all_downloads)); |
1087 | 615 |
1088 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 616 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
1089 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]")); | 617 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]")); |
1090 ASSERT_TRUE(result.get()); | 618 ASSERT_TRUE(result.get()); |
1091 base::ListValue* result_list = NULL; | 619 base::ListValue* result_list = NULL; |
1092 ASSERT_TRUE(result->GetAsList(&result_list)); | 620 ASSERT_TRUE(result->GetAsList(&result_list)); |
1093 ASSERT_EQ(1UL, result_list->GetSize()); | 621 ASSERT_EQ(1UL, result_list->GetSize()); |
1094 base::DictionaryValue* item_value = NULL; | 622 base::DictionaryValue* item_value = NULL; |
1095 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); | 623 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); |
1096 int item_id = -1; | 624 int item_id = -1; |
1097 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); | 625 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); |
1098 ASSERT_EQ(0, item_id); | 626 ASSERT_EQ(0, item_id); |
1099 } | 627 } |
1100 | 628 |
1101 // Test the |id| parameter for search(). | |
1102 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_SearchId) { | 629 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_SearchId) { |
1103 DownloadManager::DownloadVector items; | 630 DownloadManager::DownloadVector items; |
1104 CreateSlowTestDownloads(2, &items); | 631 CreateSlowTestDownloads(2, &items); |
1105 ScopedItemVectorCanceller delete_items(&items); | 632 ScopedItemVectorCanceller delete_items(&items); |
1106 | 633 |
1107 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 634 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
1108 new DownloadsSearchFunction(), "[{\"id\": 0}]")); | 635 new DownloadsSearchFunction(), "[{\"id\": 0}]")); |
1109 ASSERT_TRUE(result.get()); | 636 ASSERT_TRUE(result.get()); |
1110 base::ListValue* result_list = NULL; | 637 base::ListValue* result_list = NULL; |
1111 ASSERT_TRUE(result->GetAsList(&result_list)); | 638 ASSERT_TRUE(result->GetAsList(&result_list)); |
1112 ASSERT_EQ(1UL, result_list->GetSize()); | 639 ASSERT_EQ(1UL, result_list->GetSize()); |
1113 base::DictionaryValue* item_value = NULL; | 640 base::DictionaryValue* item_value = NULL; |
1114 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); | 641 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); |
1115 int item_id = -1; | 642 int item_id = -1; |
1116 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); | 643 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); |
1117 ASSERT_EQ(0, item_id); | 644 ASSERT_EQ(0, item_id); |
1118 } | 645 } |
1119 | 646 |
1120 // Test specifying both the |id| and |filename| parameters for search(). | |
1121 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 647 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
1122 DownloadExtensionTest_SearchIdAndFilename) { | 648 DownloadExtensionTest_SearchIdAndFilename) { |
1123 DownloadManager::DownloadVector items; | 649 DownloadManager::DownloadVector items; |
1124 CreateSlowTestDownloads(2, &items); | 650 CreateSlowTestDownloads(2, &items); |
1125 ScopedItemVectorCanceller delete_items(&items); | 651 ScopedItemVectorCanceller delete_items(&items); |
1126 | 652 |
1127 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 653 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
1128 new DownloadsSearchFunction(), | 654 new DownloadsSearchFunction(), "[{\"id\": 0,\"filename\": \"foobar\"}]")); |
1129 "[{\"id\": 0, \"filename\": \"foobar\"}]")); | |
1130 ASSERT_TRUE(result.get()); | 655 ASSERT_TRUE(result.get()); |
1131 base::ListValue* result_list = NULL; | 656 base::ListValue* result_list = NULL; |
1132 ASSERT_TRUE(result->GetAsList(&result_list)); | 657 ASSERT_TRUE(result->GetAsList(&result_list)); |
1133 ASSERT_EQ(0UL, result_list->GetSize()); | 658 ASSERT_EQ(0UL, result_list->GetSize()); |
1134 } | 659 } |
1135 | 660 |
1136 // Test a single |orderBy| parameter for search(). | |
1137 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 661 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
1138 DownloadExtensionTest_SearchOrderBy) { | 662 DownloadExtensionTest_SearchOrderBy) { |
1139 const HistoryDownloadInfo kHistoryInfo[] = { | 663 const HistoryDownloadInfo kHistoryInfo[] = { |
1140 { FILE_PATH_LITERAL("zzz"), | 664 { FILE_PATH_LITERAL("zzz"), |
1141 DownloadItem::COMPLETE, | 665 DownloadItem::COMPLETE, |
1142 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | 666 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, |
1143 { FILE_PATH_LITERAL("baz"), | 667 { FILE_PATH_LITERAL("baz"), |
1144 DownloadItem::COMPLETE, | 668 DownloadItem::COMPLETE, |
1145 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | 669 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } |
1146 }; | 670 }; |
(...skipping 11 matching lines...) Expand all Loading... |
1158 base::DictionaryValue* item1_value = NULL; | 682 base::DictionaryValue* item1_value = NULL; |
1159 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); | 683 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); |
1160 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); | 684 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); |
1161 std::string item0_name, item1_name; | 685 std::string item0_name, item1_name; |
1162 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); | 686 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); |
1163 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); | 687 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); |
1164 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); | 688 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); |
1165 ASSERT_LT(item0_name, item1_name); | 689 ASSERT_LT(item0_name, item1_name); |
1166 } | 690 } |
1167 | 691 |
1168 // Test specifying an empty |orderBy| parameter for search(). | |
1169 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 692 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
1170 DownloadExtensionTest_SearchOrderByEmpty) { | 693 DownloadExtensionTest_SearchOrderByEmpty) { |
1171 const HistoryDownloadInfo kHistoryInfo[] = { | 694 const HistoryDownloadInfo kHistoryInfo[] = { |
1172 { FILE_PATH_LITERAL("zzz"), | 695 { FILE_PATH_LITERAL("zzz"), |
1173 DownloadItem::COMPLETE, | 696 DownloadItem::COMPLETE, |
1174 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | 697 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, |
1175 { FILE_PATH_LITERAL("baz"), | 698 { FILE_PATH_LITERAL("baz"), |
1176 DownloadItem::COMPLETE, | 699 DownloadItem::COMPLETE, |
1177 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | 700 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } |
1178 }; | 701 }; |
(...skipping 11 matching lines...) Expand all Loading... |
1190 base::DictionaryValue* item1_value = NULL; | 713 base::DictionaryValue* item1_value = NULL; |
1191 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); | 714 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); |
1192 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); | 715 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); |
1193 std::string item0_name, item1_name; | 716 std::string item0_name, item1_name; |
1194 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); | 717 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); |
1195 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); | 718 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); |
1196 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); | 719 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); |
1197 ASSERT_GT(item0_name, item1_name); | 720 ASSERT_GT(item0_name, item1_name); |
1198 } | 721 } |
1199 | 722 |
1200 // Test the |danger| option for search(). | |
1201 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 723 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
1202 DownloadExtensionTest_SearchDanger) { | 724 DownloadExtensionTest_SearchDanger) { |
1203 const HistoryDownloadInfo kHistoryInfo[] = { | 725 const HistoryDownloadInfo kHistoryInfo[] = { |
1204 { FILE_PATH_LITERAL("zzz"), | 726 { FILE_PATH_LITERAL("zzz"), |
1205 DownloadItem::COMPLETE, | 727 DownloadItem::COMPLETE, |
1206 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, | 728 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, |
1207 { FILE_PATH_LITERAL("baz"), | 729 { FILE_PATH_LITERAL("baz"), |
1208 DownloadItem::COMPLETE, | 730 DownloadItem::COMPLETE, |
1209 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | 731 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } |
1210 }; | 732 }; |
1211 DownloadManager::DownloadVector items; | 733 DownloadManager::DownloadVector items; |
1212 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), | 734 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), |
1213 &items)); | 735 &items)); |
1214 | 736 |
1215 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 737 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
1216 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]")); | 738 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]")); |
1217 ASSERT_TRUE(result.get()); | 739 ASSERT_TRUE(result.get()); |
1218 base::ListValue* result_list = NULL; | 740 base::ListValue* result_list = NULL; |
1219 ASSERT_TRUE(result->GetAsList(&result_list)); | 741 ASSERT_TRUE(result->GetAsList(&result_list)); |
1220 ASSERT_EQ(1UL, result_list->GetSize()); | 742 ASSERT_EQ(1UL, result_list->GetSize()); |
1221 } | 743 } |
1222 | 744 |
1223 // Test the |state| option for search(). | |
1224 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 745 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
1225 DownloadExtensionTest_SearchState) { | 746 DownloadExtensionTest_SearchState) { |
1226 DownloadManager::DownloadVector items; | 747 DownloadManager::DownloadVector items; |
1227 CreateSlowTestDownloads(2, &items); | 748 CreateSlowTestDownloads(2, &items); |
1228 ScopedItemVectorCanceller delete_items(&items); | 749 ScopedItemVectorCanceller delete_items(&items); |
1229 | 750 |
1230 items[0]->Cancel(true); | 751 items[0]->Cancel(true); |
1231 | 752 |
1232 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 753 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
1233 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]")); | 754 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]")); |
1234 ASSERT_TRUE(result.get()); | 755 ASSERT_TRUE(result.get()); |
1235 base::ListValue* result_list = NULL; | 756 base::ListValue* result_list = NULL; |
1236 ASSERT_TRUE(result->GetAsList(&result_list)); | 757 ASSERT_TRUE(result->GetAsList(&result_list)); |
1237 ASSERT_EQ(1UL, result_list->GetSize()); | 758 ASSERT_EQ(1UL, result_list->GetSize()); |
1238 } | 759 } |
1239 | 760 |
1240 // Test the |limit| option for search(). | |
1241 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 761 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
1242 DownloadExtensionTest_SearchLimit) { | 762 DownloadExtensionTest_SearchLimit) { |
1243 DownloadManager::DownloadVector items; | 763 DownloadManager::DownloadVector items; |
1244 CreateSlowTestDownloads(2, &items); | 764 CreateSlowTestDownloads(2, &items); |
1245 ScopedItemVectorCanceller delete_items(&items); | 765 ScopedItemVectorCanceller delete_items(&items); |
1246 | 766 |
1247 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 767 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
1248 new DownloadsSearchFunction(), "[{\"limit\": 1}]")); | 768 new DownloadsSearchFunction(), "[{\"limit\": 1}]")); |
1249 ASSERT_TRUE(result.get()); | 769 ASSERT_TRUE(result.get()); |
1250 base::ListValue* result_list = NULL; | 770 base::ListValue* result_list = NULL; |
1251 ASSERT_TRUE(result->GetAsList(&result_list)); | 771 ASSERT_TRUE(result->GetAsList(&result_list)); |
1252 ASSERT_EQ(1UL, result_list->GetSize()); | 772 ASSERT_EQ(1UL, result_list->GetSize()); |
1253 } | 773 } |
1254 | 774 |
1255 // Test invalid search parameters. | |
1256 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 775 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
1257 DownloadExtensionTest_SearchInvalid) { | 776 DownloadExtensionTest_SearchInvalid) { |
1258 std::string error = RunFunctionAndReturnError( | 777 std::string error = RunFunctionAndReturnError( |
1259 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]"); | 778 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]"); |
1260 EXPECT_STREQ(download_extension_errors::kInvalidFilterError, | 779 EXPECT_STREQ(download_extension_errors::kInvalidFilterError, |
1261 error.c_str()); | 780 error.c_str()); |
1262 error = RunFunctionAndReturnError( | 781 error = RunFunctionAndReturnError( |
1263 new DownloadsSearchFunction(), "[{\"danger\": \"goat\"}]"); | 782 new DownloadsSearchFunction(), "[{\"danger\": \"goat\"}]"); |
1264 EXPECT_STREQ(download_extension_errors::kInvalidDangerTypeError, | 783 EXPECT_STREQ(download_extension_errors::kInvalidDangerTypeError, |
1265 error.c_str()); | 784 error.c_str()); |
1266 error = RunFunctionAndReturnError( | 785 error = RunFunctionAndReturnError( |
1267 new DownloadsSearchFunction(), "[{\"state\": \"goat\"}]"); | 786 new DownloadsSearchFunction(), "[{\"state\": \"goat\"}]"); |
1268 EXPECT_STREQ(download_extension_errors::kInvalidStateError, | 787 EXPECT_STREQ(download_extension_errors::kInvalidStateError, |
1269 error.c_str()); | 788 error.c_str()); |
1270 error = RunFunctionAndReturnError( | 789 error = RunFunctionAndReturnError( |
1271 new DownloadsSearchFunction(), "[{\"orderBy\": \"goat\"}]"); | 790 new DownloadsSearchFunction(), "[{\"orderBy\": \"goat\"}]"); |
1272 EXPECT_STREQ(download_extension_errors::kInvalidOrderByError, | 791 EXPECT_STREQ(download_extension_errors::kInvalidOrderByError, |
1273 error.c_str()); | 792 error.c_str()); |
1274 error = RunFunctionAndReturnError( | 793 error = RunFunctionAndReturnError( |
1275 new DownloadsSearchFunction(), "[{\"limit\": -1}]"); | 794 new DownloadsSearchFunction(), "[{\"limit\": -1}]"); |
1276 EXPECT_STREQ(download_extension_errors::kInvalidQueryLimit, | 795 EXPECT_STREQ(download_extension_errors::kInvalidQueryLimit, |
1277 error.c_str()); | 796 error.c_str()); |
1278 } | 797 } |
1279 | 798 |
1280 // Test searching using multiple conditions through multiple downloads. | |
1281 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 799 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
1282 DownloadExtensionTest_SearchPlural) { | 800 DownloadExtensionTest_SearchPlural) { |
1283 const HistoryDownloadInfo kHistoryInfo[] = { | 801 const HistoryDownloadInfo kHistoryInfo[] = { |
1284 { FILE_PATH_LITERAL("aaa"), | 802 { FILE_PATH_LITERAL("aaa"), |
1285 DownloadItem::CANCELLED, | 803 DownloadItem::CANCELLED, |
1286 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | 804 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, |
1287 { FILE_PATH_LITERAL("zzz"), | 805 { FILE_PATH_LITERAL("zzz"), |
1288 DownloadItem::COMPLETE, | 806 DownloadItem::COMPLETE, |
1289 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, | 807 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, |
1290 { FILE_PATH_LITERAL("baz"), | 808 { FILE_PATH_LITERAL("baz"), |
(...skipping 14 matching lines...) Expand all Loading... |
1305 base::ListValue* result_list = NULL; | 823 base::ListValue* result_list = NULL; |
1306 ASSERT_TRUE(result->GetAsList(&result_list)); | 824 ASSERT_TRUE(result->GetAsList(&result_list)); |
1307 ASSERT_EQ(1UL, result_list->GetSize()); | 825 ASSERT_EQ(1UL, result_list->GetSize()); |
1308 base::DictionaryValue* item_value = NULL; | 826 base::DictionaryValue* item_value = NULL; |
1309 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); | 827 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); |
1310 FilePath::StringType item_name; | 828 FilePath::StringType item_name; |
1311 ASSERT_TRUE(item_value->GetString("filename", &item_name)); | 829 ASSERT_TRUE(item_value->GetString("filename", &item_name)); |
1312 ASSERT_EQ(items[2]->GetFullPath().value(), item_name); | 830 ASSERT_EQ(items[2]->GetFullPath().value(), item_name); |
1313 } | 831 } |
1314 | 832 |
1315 // Test that incognito downloads are only visible in incognito contexts, and | 833 IN_PROC_BROWSER_TEST_F(DownloadExtensionTestIncognito, |
1316 // test that on-record downloads are visible in both incognito and on-record | |
1317 // contexts, for DownloadsSearchFunction, DownloadsPauseFunction, | |
1318 // DownloadsResumeFunction, and DownloadsCancelFunction. | |
1319 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1320 DownloadExtensionTest_SearchPauseResumeCancelGetFileIconIncognito) { | 834 DownloadExtensionTest_SearchPauseResumeCancelGetFileIconIncognito) { |
1321 scoped_ptr<base::Value> result_value; | 835 scoped_ptr<base::Value> result_value; |
1322 base::ListValue* result_list = NULL; | 836 base::ListValue* result_list = NULL; |
1323 base::DictionaryValue* result_dict = NULL; | 837 base::DictionaryValue* result_dict = NULL; |
1324 FilePath::StringType filename; | 838 FilePath::StringType filename; |
1325 bool is_incognito = false; | 839 bool is_incognito = false; |
1326 std::string error; | 840 std::string error; |
1327 std::string on_item_arg; | 841 std::string on_item_arg; |
1328 std::string off_item_arg; | 842 std::string off_item_arg; |
1329 std::string result_string; | 843 std::string result_string; |
1330 | 844 |
1331 // Set up one on-record item and one off-record item. | 845 // Set up one on-record item and one off-record item. |
1332 // Set up the off-record item first because otherwise there are mysteriously 3 | |
1333 // items total instead of 2. | |
1334 // TODO(benjhayden): Figure out where the third item comes from. | |
1335 GoOffTheRecord(); | |
1336 DownloadItem* off_item = CreateSlowTestDownload(); | |
1337 ASSERT_TRUE(off_item); | |
1338 ASSERT_TRUE(off_item->IsOtr()); | |
1339 off_item_arg = DownloadItemIdAsArgList(off_item); | |
1340 | 846 |
1341 GoOnTheRecord(); | 847 GoOnTheRecord(); |
1342 DownloadItem* on_item = CreateSlowTestDownload(); | 848 DownloadItem* on_item = CreateSlowTestDownload(); |
1343 ASSERT_TRUE(on_item); | 849 ASSERT_TRUE(on_item); |
1344 ASSERT_FALSE(on_item->IsOtr()); | 850 ASSERT_FALSE(on_item->IsOtr()); |
1345 on_item_arg = DownloadItemIdAsArgList(on_item); | 851 on_item_arg = DownloadItemIdAsArgList(on_item); |
| 852 |
| 853 GoOffTheRecord(); |
| 854 DownloadItem* off_item = CreateSlowTestDownload(); |
| 855 ASSERT_TRUE(off_item); |
| 856 ASSERT_TRUE(off_item->IsOtr()); |
1346 ASSERT_TRUE(on_item->GetFullPath() != off_item->GetFullPath()); | 857 ASSERT_TRUE(on_item->GetFullPath() != off_item->GetFullPath()); |
| 858 off_item_arg = DownloadItemIdAsArgList(off_item); |
1347 | 859 |
1348 // Extensions running in the incognito window should have access to both | 860 // Extensions running in the incognito window should have access to both |
1349 // items because the Test extension is in spanning mode. | 861 // items because the Test extension is in spanning mode. |
1350 GoOffTheRecord(); | |
1351 result_value.reset(RunFunctionAndReturnResult( | 862 result_value.reset(RunFunctionAndReturnResult( |
1352 new DownloadsSearchFunction(), "[{}]")); | 863 new DownloadsSearchFunction(), "[{}]")); |
1353 ASSERT_TRUE(result_value.get()); | 864 ASSERT_TRUE(result_value.get()); |
1354 ASSERT_TRUE(result_value->GetAsList(&result_list)); | 865 ASSERT_TRUE(result_value->GetAsList(&result_list)); |
1355 ASSERT_EQ(2UL, result_list->GetSize()); | 866 ASSERT_EQ(2UL, result_list->GetSize()); |
1356 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict)); | 867 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict)); |
1357 ASSERT_TRUE(result_dict->GetString("filename", &filename)); | 868 ASSERT_TRUE(result_dict->GetString("filename", &filename)); |
1358 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito)); | 869 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito)); |
1359 EXPECT_TRUE(on_item->GetFullPath() == FilePath(filename)); | 870 EXPECT_TRUE(on_item->GetFullPath() == FilePath(filename)); |
1360 EXPECT_FALSE(is_incognito); | 871 EXPECT_FALSE(is_incognito); |
(...skipping 25 matching lines...) Expand all Loading... |
1386 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), | 897 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), |
1387 off_item_arg); | 898 off_item_arg); |
1388 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 899 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
1389 error.c_str()); | 900 error.c_str()); |
1390 error = RunFunctionAndReturnError( | 901 error = RunFunctionAndReturnError( |
1391 new DownloadsGetFileIconFunction(), | 902 new DownloadsGetFileIconFunction(), |
1392 base::StringPrintf("[%d, {}]", off_item->GetId())); | 903 base::StringPrintf("[%d, {}]", off_item->GetId())); |
1393 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 904 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
1394 error.c_str()); | 905 error.c_str()); |
1395 | 906 |
| 907 // TODO(benjhayden): Test incognito_split_mode() extension. |
| 908 // TODO(benjhayden): Test download(), onCreated, onChanged, onErased. |
| 909 |
1396 GoOffTheRecord(); | 910 GoOffTheRecord(); |
1397 | 911 |
1398 // Do the FileIcon test for both the on- and off-items while off the record. | 912 // Do the FileIcon test for both the on- and off-items while off the record. |
1399 // NOTE(benjhayden): This does not include the FileIcon test from history, | 913 // NOTE(benjhayden): This does not include the FileIcon test from history, |
1400 // just active downloads. This shouldn't be a problem. | 914 // just active downloads. This shouldn't be a problem. |
1401 EXPECT_TRUE(RunFunctionAndReturnString( | 915 EXPECT_TRUE(RunFunctionAndReturnString( |
1402 new DownloadsGetFileIconFunction(), | 916 new DownloadsGetFileIconFunction(), |
1403 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string)); | 917 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string)); |
1404 EXPECT_TRUE(RunFunctionAndReturnString( | 918 EXPECT_TRUE(RunFunctionAndReturnString( |
1405 new DownloadsGetFileIconFunction(), | 919 new DownloadsGetFileIconFunction(), |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1443 EXPECT_TRUE(off_item->IsCancelled()); | 957 EXPECT_TRUE(off_item->IsCancelled()); |
1444 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), | 958 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), |
1445 off_item_arg); | 959 off_item_arg); |
1446 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 960 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
1447 error.c_str()); | 961 error.c_str()); |
1448 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), | 962 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), |
1449 off_item_arg); | 963 off_item_arg); |
1450 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 964 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
1451 error.c_str()); | 965 error.c_str()); |
1452 } | 966 } |
1453 | |
1454 // Test that we can start a download and that the correct sequence of events is | |
1455 // fired for it. | |
1456 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1457 DownloadExtensionTest_Download_Basic) { | |
1458 LoadExtension("downloads_split"); | |
1459 CHECK(StartTestServer()); | |
1460 std::string download_url = test_server()->GetURL("slow?0").spec(); | |
1461 GoOnTheRecord(); | |
1462 | |
1463 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1464 new DownloadsDownloadFunction(), base::StringPrintf( | |
1465 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
1466 ASSERT_TRUE(result.get()); | |
1467 int result_id = -1; | |
1468 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1469 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1470 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1471 ASSERT_TRUE(item); | |
1472 ScopedCancellingItem canceller(item); | |
1473 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); | |
1474 | |
1475 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1476 base::StringPrintf("[{\"danger\": \"safe\"," | |
1477 " \"filename\": \"%s\"," | |
1478 " \"incognito\": false," | |
1479 " \"mime\": \"text/plain\"," | |
1480 " \"paused\": false," | |
1481 " \"url\": \"%s\"}]", | |
1482 GetFilename("slow.txt.crdownload").c_str(), | |
1483 download_url.c_str()))); | |
1484 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1485 base::StringPrintf("[{\"id\": %d," | |
1486 " \"filename\": {" | |
1487 " \"previous\": \"%s\"," | |
1488 " \"current\": \"%s\"}," | |
1489 " \"state\": {" | |
1490 " \"previous\": \"in_progress\"," | |
1491 " \"current\": \"complete\"}}]", | |
1492 result_id, | |
1493 GetFilename("slow.txt.crdownload").c_str(), | |
1494 GetFilename("slow.txt").c_str()))); | |
1495 } | |
1496 | |
1497 // Test that we can start a download from an incognito context, and that the | |
1498 // download knows that it's incognito. | |
1499 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1500 DownloadExtensionTest_Download_Incognito) { | |
1501 LoadExtension("downloads_split"); | |
1502 CHECK(StartTestServer()); | |
1503 GoOffTheRecord(); | |
1504 std::string download_url = test_server()->GetURL("slow?0").spec(); | |
1505 | |
1506 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1507 new DownloadsDownloadFunction(), base::StringPrintf( | |
1508 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
1509 ASSERT_TRUE(result.get()); | |
1510 int result_id = -1; | |
1511 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1512 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1513 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1514 ASSERT_TRUE(item); | |
1515 ScopedCancellingItem canceller(item); | |
1516 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); | |
1517 | |
1518 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1519 base::StringPrintf("[{\"danger\": \"safe\"," | |
1520 " \"filename\": \"%s\"," | |
1521 " \"incognito\": true," | |
1522 " \"mime\": \"text/plain\"," | |
1523 " \"paused\": false," | |
1524 " \"url\": \"%s\"}]", | |
1525 GetFilename("slow.txt.crdownload").c_str(), | |
1526 download_url.c_str()))); | |
1527 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1528 base::StringPrintf("[{\"id\":%d," | |
1529 " \"filename\": {" | |
1530 " \"previous\": \"%s\"," | |
1531 " \"current\": \"%s\"}," | |
1532 " \"state\": {" | |
1533 " \"current\": \"complete\"," | |
1534 " \"previous\": \"in_progress\"}}]", | |
1535 result_id, | |
1536 GetFilename("slow.txt.crdownload").c_str(), | |
1537 GetFilename("slow.txt").c_str()))); | |
1538 } | |
1539 | |
1540 // Test that we disallow certain headers case-insensitively. | |
1541 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1542 DownloadExtensionTest_Download_UnsafeHeaders) { | |
1543 LoadExtension("downloads_split"); | |
1544 CHECK(StartTestServer()); | |
1545 GoOnTheRecord(); | |
1546 | |
1547 static const char* kUnsafeHeaders[] = { | |
1548 "Accept-chArsEt", | |
1549 "accept-eNcoding", | |
1550 "coNNection", | |
1551 "coNteNt-leNgth", | |
1552 "cooKIE", | |
1553 "cOOkie2", | |
1554 "coNteNt-traNsfer-eNcodiNg", | |
1555 "dAtE", | |
1556 "ExpEcT", | |
1557 "hOsT", | |
1558 "kEEp-aLivE", | |
1559 "rEfErEr", | |
1560 "tE", | |
1561 "trAilER", | |
1562 "trANsfer-eNcodiNg", | |
1563 "upGRAde", | |
1564 "usER-agENt", | |
1565 "viA", | |
1566 "pRoxY-", | |
1567 "sEc-", | |
1568 "pRoxY-probably-not-evil", | |
1569 "sEc-probably-not-evil", | |
1570 "oRiGiN", | |
1571 "Access-Control-Request-Headers", | |
1572 "Access-Control-Request-Method", | |
1573 }; | |
1574 | |
1575 for (size_t index = 0; index < arraysize(kUnsafeHeaders); ++index) { | |
1576 std::string download_url = test_server()->GetURL("slow?0").spec(); | |
1577 EXPECT_STREQ(download_extension_errors::kGenericError, | |
1578 RunFunctionAndReturnError(new DownloadsDownloadFunction(), | |
1579 base::StringPrintf( | |
1580 "[{\"url\": \"%s\"," | |
1581 " \"filename\": \"unsafe-header-%lu.txt\"," | |
1582 " \"headers\": [{" | |
1583 " \"name\": \"%s\"," | |
1584 " \"value\": \"unsafe\"}]}]", | |
1585 download_url.c_str(), index, kUnsafeHeaders[index])).c_str()); | |
1586 } | |
1587 } | |
1588 | |
1589 // Test that subdirectories (slashes) are disallowed in filenames. | |
1590 // TODO(benjhayden) Update this when subdirectories are supported. | |
1591 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1592 DownloadExtensionTest_Download_Subdirectory) { | |
1593 LoadExtension("downloads_split"); | |
1594 CHECK(StartTestServer()); | |
1595 std::string download_url = test_server()->GetURL("slow?0").spec(); | |
1596 GoOnTheRecord(); | |
1597 | |
1598 EXPECT_STREQ(download_extension_errors::kGenericError, | |
1599 RunFunctionAndReturnError(new DownloadsDownloadFunction(), | |
1600 base::StringPrintf( | |
1601 "[{\"url\": \"%s\"," | |
1602 " \"filename\": \"sub/dir/ect/ory.txt\"}]", | |
1603 download_url.c_str())).c_str()); | |
1604 } | |
1605 | |
1606 // Test that invalid filenames are disallowed. | |
1607 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1608 DownloadExtensionTest_Download_InvalidFilename) { | |
1609 LoadExtension("downloads_split"); | |
1610 CHECK(StartTestServer()); | |
1611 std::string download_url = test_server()->GetURL("slow?0").spec(); | |
1612 GoOnTheRecord(); | |
1613 | |
1614 EXPECT_STREQ(download_extension_errors::kGenericError, | |
1615 RunFunctionAndReturnError(new DownloadsDownloadFunction(), | |
1616 base::StringPrintf( | |
1617 "[{\"url\": \"%s\"," | |
1618 " \"filename\": \"../../../../../etc/passwd\"}]", | |
1619 download_url.c_str())).c_str()); | |
1620 } | |
1621 | |
1622 // Test that downloading invalid URLs immediately returns kInvalidURLError. | |
1623 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1624 DownloadExtensionTest_Download_InvalidURLs) { | |
1625 LoadExtension("downloads_split"); | |
1626 GoOnTheRecord(); | |
1627 | |
1628 static const char* kInvalidURLs[] = { | |
1629 "foo bar", | |
1630 "../hello", | |
1631 "/hello", | |
1632 "google.com/", | |
1633 "http://", | |
1634 "#frag", | |
1635 "foo/bar.html#frag", | |
1636 "javascript:document.write(\\\"hello\\\");", | |
1637 "javascript:return false;", | |
1638 "ftp://example.com/example.txt", | |
1639 }; | |
1640 | |
1641 for (size_t index = 0; index < arraysize(kInvalidURLs); ++index) { | |
1642 EXPECT_STREQ(download_extension_errors::kInvalidURLError, | |
1643 RunFunctionAndReturnError(new DownloadsDownloadFunction(), | |
1644 base::StringPrintf( | |
1645 "[{\"url\": \"%s\"}]", kInvalidURLs[index])).c_str()); | |
1646 } | |
1647 } | |
1648 | |
1649 // TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to | |
1650 // permissions, test downloading from ftp. | |
1651 | |
1652 // Valid URLs plus fragments are still valid URLs. | |
1653 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1654 DownloadExtensionTest_Download_URLFragment) { | |
1655 LoadExtension("downloads_split"); | |
1656 CHECK(StartTestServer()); | |
1657 std::string download_url = test_server()->GetURL("slow?0#fragment").spec(); | |
1658 GoOnTheRecord(); | |
1659 | |
1660 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1661 new DownloadsDownloadFunction(), base::StringPrintf( | |
1662 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
1663 ASSERT_TRUE(result.get()); | |
1664 int result_id = -1; | |
1665 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1666 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1667 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1668 ASSERT_TRUE(item); | |
1669 ScopedCancellingItem canceller(item); | |
1670 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); | |
1671 | |
1672 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1673 base::StringPrintf("[{\"danger\": \"safe\"," | |
1674 " \"filename\": \"%s\"," | |
1675 " \"incognito\": false," | |
1676 " \"mime\": \"text/plain\"," | |
1677 " \"paused\": false," | |
1678 " \"url\": \"%s\"}]", | |
1679 GetFilename("slow.txt.crdownload").c_str(), | |
1680 download_url.c_str()))); | |
1681 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1682 base::StringPrintf("[{\"id\": %d," | |
1683 " \"filename\": {" | |
1684 " \"previous\": \"%s\"," | |
1685 " \"current\": \"%s\"}," | |
1686 " \"state\": {" | |
1687 " \"previous\": \"in_progress\"," | |
1688 " \"current\": \"complete\"}}]", | |
1689 result_id, | |
1690 GetFilename("slow.txt.crdownload").c_str(), | |
1691 GetFilename("slow.txt").c_str()))); | |
1692 } | |
1693 | |
1694 // Valid data URLs are valid URLs. | |
1695 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1696 DownloadExtensionTest_Download_DataURL) { | |
1697 LoadExtension("downloads_split"); | |
1698 CHECK(StartTestServer()); | |
1699 std::string download_url = "data:text/plain,hello"; | |
1700 GoOnTheRecord(); | |
1701 | |
1702 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1703 new DownloadsDownloadFunction(), base::StringPrintf( | |
1704 "[{\"url\": \"%s\"," | |
1705 " \"filename\": \"data.txt\"}]", 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->GetOriginalUrl().spec()); | |
1714 | |
1715 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1716 base::StringPrintf("[{\"danger\": \"safe\"," | |
1717 " \"filename\": \"%s\"," | |
1718 " \"incognito\": false," | |
1719 " \"mime\": \"text/plain\"," | |
1720 " \"paused\": false," | |
1721 " \"url\": \"%s\"}]", | |
1722 GetFilename("data.txt.crdownload").c_str(), | |
1723 download_url.c_str()))); | |
1724 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1725 base::StringPrintf("[{\"id\": %d," | |
1726 " \"filename\": {" | |
1727 " \"previous\": \"%s\"," | |
1728 " \"current\": \"%s\"}," | |
1729 " \"state\": {" | |
1730 " \"previous\": \"in_progress\"," | |
1731 " \"current\": \"complete\"}}]", | |
1732 result_id, | |
1733 GetFilename("data.txt.crdownload").c_str(), | |
1734 GetFilename("data.txt").c_str()))); | |
1735 } | |
1736 | |
1737 // Valid file URLs are valid URLs. | |
1738 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1739 DownloadExtensionTest_Download_File) { | |
1740 GoOnTheRecord(); | |
1741 CHECK(StartTestServer()); | |
1742 LoadExtension("downloads_split"); | |
1743 std::string download_url = "file:///"; | |
1744 #if defined(OS_WIN) | |
1745 download_url += "C:/"; | |
1746 #endif | |
1747 | |
1748 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1749 new DownloadsDownloadFunction(), base::StringPrintf( | |
1750 "[{\"url\": \"%s\"," | |
1751 " \"filename\": \"file.txt\"}]", download_url.c_str()))); | |
1752 ASSERT_TRUE(result.get()); | |
1753 int result_id = -1; | |
1754 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1755 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1756 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1757 ASSERT_TRUE(item); | |
1758 ScopedCancellingItem canceller(item); | |
1759 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); | |
1760 | |
1761 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1762 base::StringPrintf("[{\"danger\": \"safe\"," | |
1763 " \"filename\": \"%s\"," | |
1764 " \"incognito\": false," | |
1765 " \"mime\": \"text/html\"," | |
1766 " \"paused\": false," | |
1767 " \"url\": \"%s\"}]", | |
1768 GetFilename("file.txt.crdownload").c_str(), | |
1769 download_url.c_str()))); | |
1770 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1771 base::StringPrintf("[{\"id\": %d," | |
1772 " \"filename\": {" | |
1773 " \"previous\": \"%s\"," | |
1774 " \"current\": \"%s\"}," | |
1775 " \"state\": {" | |
1776 " \"previous\": \"in_progress\"," | |
1777 " \"current\": \"complete\"}}]", | |
1778 result_id, | |
1779 GetFilename("file.txt.crdownload").c_str(), | |
1780 GetFilename("file.txt").c_str()))); | |
1781 } | |
1782 | |
1783 // Test that auth-basic-succeed would fail if the resource requires the | |
1784 // Authorization header and chrome fails to propagate it back to the server. | |
1785 // This tests both that testserver.py does not succeed when it should fail as | |
1786 // well as how the downloads extension API exposes the failure to extensions. | |
1787 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1788 DownloadExtensionTest_Download_AuthBasic_Fail) { | |
1789 LoadExtension("downloads_split"); | |
1790 CHECK(StartTestServer()); | |
1791 std::string download_url = test_server()->GetURL("auth-basic").spec(); | |
1792 GoOnTheRecord(); | |
1793 | |
1794 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1795 new DownloadsDownloadFunction(), base::StringPrintf( | |
1796 "[{\"url\": \"%s\"," | |
1797 " \"filename\": \"auth-basic-fail.txt\"}]", | |
1798 download_url.c_str()))); | |
1799 ASSERT_TRUE(result.get()); | |
1800 int result_id = -1; | |
1801 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1802 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1803 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1804 ASSERT_TRUE(item); | |
1805 ScopedCancellingItem canceller(item); | |
1806 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); | |
1807 | |
1808 ASSERT_TRUE(WaitForInterruption(item, 30, base::StringPrintf( | |
1809 "[{\"danger\": \"safe\"," | |
1810 " \"incognito\": false," | |
1811 " \"mime\": \"text/html\"," | |
1812 " \"paused\": false," | |
1813 " \"url\": \"%s\"}]", | |
1814 download_url.c_str()))); | |
1815 } | |
1816 | |
1817 // Test that DownloadsDownloadFunction propagates |headers| to the URLRequest. | |
1818 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1819 DownloadExtensionTest_Download_Headers) { | |
1820 LoadExtension("downloads_split"); | |
1821 CHECK(StartTestServer()); | |
1822 std::string download_url = test_server()->GetURL("files/downloads/" | |
1823 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec(); | |
1824 GoOnTheRecord(); | |
1825 | |
1826 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1827 new DownloadsDownloadFunction(), base::StringPrintf( | |
1828 "[{\"url\": \"%s\"," | |
1829 " \"filename\": \"headers-succeed.txt\"," | |
1830 " \"headers\": [" | |
1831 " {\"name\": \"Foo\", \"value\": \"bar\"}," | |
1832 " {\"name\": \"Qx\", \"value\":\"yo\"}]}]", | |
1833 download_url.c_str()))); | |
1834 ASSERT_TRUE(result.get()); | |
1835 int result_id = -1; | |
1836 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1837 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1838 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1839 ASSERT_TRUE(item); | |
1840 ScopedCancellingItem canceller(item); | |
1841 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); | |
1842 | |
1843 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1844 base::StringPrintf("[{\"danger\": \"safe\"," | |
1845 " \"incognito\": false," | |
1846 " \"mime\": \"application/octet-stream\"," | |
1847 " \"paused\": false," | |
1848 " \"url\": \"%s\"}]", | |
1849 download_url.c_str()))); | |
1850 std::string incomplete_filename = GetFilename( | |
1851 "headers-succeed.txt.crdownload"); | |
1852 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1853 base::StringPrintf("[{\"id\": %d," | |
1854 " \"filename\": {" | |
1855 " \"previous\": \"%s\"," | |
1856 " \"current\": \"%s\"}," | |
1857 " \"state\": {" | |
1858 " \"previous\": \"in_progress\"," | |
1859 " \"current\": \"complete\"}}]", | |
1860 result_id, | |
1861 incomplete_filename.c_str(), | |
1862 GetFilename("headers-succeed.txt").c_str()))); | |
1863 } | |
1864 | |
1865 // Test that headers-succeed would fail if the resource requires the headers and | |
1866 // chrome fails to propagate them back to the server. This tests both that | |
1867 // testserver.py does not succeed when it should fail as well as how the | |
1868 // downloads extension api exposes the failure to extensions. | |
1869 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1870 DownloadExtensionTest_Download_Headers_Fail) { | |
1871 LoadExtension("downloads_split"); | |
1872 CHECK(StartTestServer()); | |
1873 std::string download_url = test_server()->GetURL("files/downloads/" | |
1874 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec(); | |
1875 GoOnTheRecord(); | |
1876 | |
1877 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1878 new DownloadsDownloadFunction(), base::StringPrintf( | |
1879 "[{\"url\": \"%s\"," | |
1880 " \"filename\": \"headers-fail.txt\"}]", | |
1881 download_url.c_str()))); | |
1882 ASSERT_TRUE(result.get()); | |
1883 int result_id = -1; | |
1884 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1885 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1886 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1887 ASSERT_TRUE(item); | |
1888 ScopedCancellingItem canceller(item); | |
1889 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); | |
1890 | |
1891 ASSERT_TRUE(WaitForInterruption(item, 33, base::StringPrintf( | |
1892 "[{\"danger\": \"safe\"," | |
1893 " \"incognito\": false," | |
1894 " \"bytesReceived\": 0," | |
1895 " \"mime\": \"\"," | |
1896 " \"paused\": false," | |
1897 " \"url\": \"%s\"}]", | |
1898 download_url.c_str()))); | |
1899 } | |
1900 | |
1901 // Test that DownloadsDownloadFunction propagates the Authorization header | |
1902 // correctly. | |
1903 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1904 DownloadExtensionTest_Download_AuthBasic) { | |
1905 LoadExtension("downloads_split"); | |
1906 CHECK(StartTestServer()); | |
1907 std::string download_url = test_server()->GetURL("auth-basic").spec(); | |
1908 // This is just base64 of 'username:secret'. | |
1909 static const char* kAuthorization = "dXNlcm5hbWU6c2VjcmV0"; | |
1910 GoOnTheRecord(); | |
1911 | |
1912 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1913 new DownloadsDownloadFunction(), base::StringPrintf( | |
1914 "[{\"url\": \"%s\"," | |
1915 " \"filename\": \"auth-basic-succeed.txt\"," | |
1916 " \"headers\": [{" | |
1917 " \"name\": \"Authorization\"," | |
1918 " \"value\": \"Basic %s\"}]}]", | |
1919 download_url.c_str(), kAuthorization))); | |
1920 ASSERT_TRUE(result.get()); | |
1921 int result_id = -1; | |
1922 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1923 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1924 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1925 ASSERT_TRUE(item); | |
1926 ScopedCancellingItem canceller(item); | |
1927 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); | |
1928 | |
1929 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1930 base::StringPrintf("[{\"danger\": \"safe\"," | |
1931 " \"incognito\": false," | |
1932 " \"mime\": \"text/html\"," | |
1933 " \"paused\": false," | |
1934 " \"url\": \"%s\"}]", download_url.c_str()))); | |
1935 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1936 base::StringPrintf("[{\"id\": %d," | |
1937 " \"state\": {" | |
1938 " \"previous\": \"in_progress\"," | |
1939 " \"current\": \"complete\"}}]", result_id))); | |
1940 } | |
1941 | |
1942 // Test that DownloadsDownloadFunction propagates the |method| and |body| | |
1943 // parameters to the URLRequest. | |
1944 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1945 DownloadExtensionTest_Download_Post) { | |
1946 LoadExtension("downloads_split"); | |
1947 CHECK(StartTestServer()); | |
1948 std::string download_url = test_server()->GetURL("files/post/downloads/" | |
1949 "a_zip_file.zip?expected_body=BODY").spec(); | |
1950 GoOnTheRecord(); | |
1951 | |
1952 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1953 new DownloadsDownloadFunction(), base::StringPrintf( | |
1954 "[{\"url\": \"%s\"," | |
1955 " \"filename\": \"post-succeed.txt\"," | |
1956 " \"method\": \"POST\"," | |
1957 " \"body\": \"BODY\"}]", | |
1958 download_url.c_str()))); | |
1959 ASSERT_TRUE(result.get()); | |
1960 int result_id = -1; | |
1961 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
1962 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
1963 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
1964 ASSERT_TRUE(item); | |
1965 ScopedCancellingItem canceller(item); | |
1966 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); | |
1967 | |
1968 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
1969 base::StringPrintf("[{\"danger\": \"safe\"," | |
1970 " \"incognito\": false," | |
1971 " \"mime\": \"application/octet-stream\"," | |
1972 " \"paused\": false," | |
1973 " \"bytesReceived\": 164," | |
1974 " \"url\": \"%s\"}]", download_url.c_str()))); | |
1975 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
1976 base::StringPrintf("[{\"id\": %d," | |
1977 " \"state\": {" | |
1978 " \"previous\": \"in_progress\"," | |
1979 " \"current\": \"complete\"}}]", result_id))); | |
1980 } | |
1981 | |
1982 // Test that downloadPostSuccess would fail if the resource requires the POST | |
1983 // method, and chrome fails to propagate the |method| parameter back to the | |
1984 // server. This tests both that testserver.py does not succeed when it should | |
1985 // fail, and this tests how the downloads extension api exposes the failure to | |
1986 // extensions. | |
1987 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
1988 DownloadExtensionTest_Download_Post_Get) { | |
1989 LoadExtension("downloads_split"); | |
1990 CHECK(StartTestServer()); | |
1991 std::string download_url = test_server()->GetURL("files/post/downloads/" | |
1992 "a_zip_file.zip?expected_body=BODY").spec(); | |
1993 GoOnTheRecord(); | |
1994 | |
1995 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
1996 new DownloadsDownloadFunction(), base::StringPrintf( | |
1997 "[{\"url\": \"%s\"," | |
1998 " \"body\": \"BODY\"," | |
1999 " \"filename\": \"post-get.txt\"}]", | |
2000 download_url.c_str()))); | |
2001 ASSERT_TRUE(result.get()); | |
2002 int result_id = -1; | |
2003 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
2004 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
2005 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
2006 ASSERT_TRUE(item); | |
2007 ScopedCancellingItem canceller(item); | |
2008 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); | |
2009 | |
2010 ASSERT_TRUE(WaitForInterruption(item, 33, base::StringPrintf( | |
2011 "[{\"danger\": \"safe\"," | |
2012 " \"incognito\": false," | |
2013 " \"mime\": \"\"," | |
2014 " \"paused\": false," | |
2015 " \"id\": %d," | |
2016 " \"url\": \"%s\"}]", | |
2017 result_id, | |
2018 download_url.c_str()))); | |
2019 } | |
2020 | |
2021 // Test that downloadPostSuccess would fail if the resource requires the POST | |
2022 // method, and chrome fails to propagate the |body| parameter back to the | |
2023 // server. This tests both that testserver.py does not succeed when it should | |
2024 // fail, and this tests how the downloads extension api exposes the failure to | |
2025 // extensions. | |
2026 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
2027 DownloadExtensionTest_Download_Post_NoBody) { | |
2028 LoadExtension("downloads_split"); | |
2029 CHECK(StartTestServer()); | |
2030 std::string download_url = test_server()->GetURL("files/post/downloads/" | |
2031 "a_zip_file.zip?expected_body=BODY").spec(); | |
2032 GoOnTheRecord(); | |
2033 | |
2034 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
2035 new DownloadsDownloadFunction(), base::StringPrintf( | |
2036 "[{\"url\": \"%s\"," | |
2037 " \"method\": \"POST\"," | |
2038 " \"filename\": \"post-nobody.txt\"}]", | |
2039 download_url.c_str()))); | |
2040 ASSERT_TRUE(result.get()); | |
2041 int result_id = -1; | |
2042 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
2043 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
2044 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
2045 ASSERT_TRUE(item); | |
2046 ScopedCancellingItem canceller(item); | |
2047 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); | |
2048 | |
2049 ASSERT_TRUE(WaitForInterruption(item, 33, base::StringPrintf( | |
2050 "[{\"danger\": \"safe\"," | |
2051 " \"incognito\": false," | |
2052 " \"mime\": \"\"," | |
2053 " \"paused\": false," | |
2054 " \"id\": %d," | |
2055 " \"url\": \"%s\"}]", | |
2056 result_id, | |
2057 download_url.c_str()))); | |
2058 } | |
2059 | |
2060 // Test that cancel()ing an in-progress download causes its state to transition | |
2061 // to interrupted, and test that that state transition is detectable by an | |
2062 // onChanged event listener. TODO(benjhayden): Test other sources of | |
2063 // interruptions such as server death. | |
2064 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
2065 DownloadExtensionTest_Download_Cancel) { | |
2066 LoadExtension("downloads_split"); | |
2067 CHECK(StartTestServer()); | |
2068 std::string download_url = test_server()->GetURL( | |
2069 "download-known-size").spec(); | |
2070 GoOnTheRecord(); | |
2071 | |
2072 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
2073 new DownloadsDownloadFunction(), base::StringPrintf( | |
2074 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
2075 ASSERT_TRUE(result.get()); | |
2076 int result_id = -1; | |
2077 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
2078 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
2079 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
2080 ASSERT_TRUE(item); | |
2081 ScopedCancellingItem canceller(item); | |
2082 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); | |
2083 | |
2084 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
2085 base::StringPrintf("[{\"danger\": \"safe\"," | |
2086 " \"incognito\": false," | |
2087 " \"mime\": \"application/octet-stream\"," | |
2088 " \"paused\": false," | |
2089 " \"id\": %d," | |
2090 " \"url\": \"%s\"}]", | |
2091 result_id, | |
2092 download_url.c_str()))); | |
2093 item->Cancel(true); | |
2094 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
2095 base::StringPrintf("[{\"id\": %d," | |
2096 " \"error\": {\"current\": 40}," | |
2097 " \"state\": {" | |
2098 " \"previous\": \"in_progress\"," | |
2099 " \"current\": \"interrupted\"}}]", | |
2100 result_id))); | |
2101 } | |
2102 | |
2103 // Test downloading filesystem: URLs. | |
2104 // NOTE: chrome disallows creating HTML5 FileSystem Files in incognito. | |
2105 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
2106 DownloadExtensionTest_Download_FileSystemURL) { | |
2107 static const char* kPayloadData = "on the record\ndata"; | |
2108 GoOnTheRecord(); | |
2109 LoadExtension("downloads_split"); | |
2110 HTML5FileWriter html5_file_writer( | |
2111 browser()->profile(), | |
2112 "on_record.txt", | |
2113 GetExtensionURL(), | |
2114 events_listener(), | |
2115 kPayloadData); | |
2116 ASSERT_TRUE(html5_file_writer.WriteFile()); | |
2117 | |
2118 std::string download_url = "filesystem:" + GetExtensionURL() + | |
2119 "temporary/on_record.txt"; | |
2120 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
2121 new DownloadsDownloadFunction(), base::StringPrintf( | |
2122 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
2123 ASSERT_TRUE(result.get()); | |
2124 int result_id = -1; | |
2125 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
2126 | |
2127 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
2128 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
2129 ASSERT_TRUE(item); | |
2130 ScopedCancellingItem canceller(item); | |
2131 ASSERT_EQ(download_url, item->GetOriginalUrl().spec()); | |
2132 | |
2133 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
2134 base::StringPrintf("[{\"danger\": \"safe\"," | |
2135 " \"filename\": \"%s\"," | |
2136 " \"incognito\": false," | |
2137 " \"mime\": \"text/plain\"," | |
2138 " \"paused\": false," | |
2139 " \"url\": \"%s\"}]", | |
2140 GetFilename("on_record.txt.crdownload").c_str(), | |
2141 download_url.c_str()))); | |
2142 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
2143 base::StringPrintf("[{\"id\": %d," | |
2144 " \"filename\": {" | |
2145 " \"previous\": \"%s\"," | |
2146 " \"current\": \"%s\"}," | |
2147 " \"state\": {" | |
2148 " \"previous\": \"in_progress\"," | |
2149 " \"current\": \"complete\"}}]", | |
2150 result_id, | |
2151 GetFilename("on_record.txt.crdownload").c_str(), | |
2152 GetFilename("on_record.txt").c_str()))); | |
2153 std::string disk_data; | |
2154 EXPECT_TRUE(file_util::ReadFileToString(item->GetFullPath(), &disk_data)); | |
2155 EXPECT_STREQ(kPayloadData, disk_data.c_str()); | |
2156 } | |
OLD | NEW |