Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: chrome/browser/download/download_extension_test.cc

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

Powered by Google App Engine
This is Rietveld 408576698