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

Side by Side Diff: chrome/browser/extensions/api/downloads/downloads_api_unittest.cc

Issue 10542038: Rewrite DownloadsApiTest in C++. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 5 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_file_icon_extractor.h" 14 #include "chrome/browser/download/download_file_icon_extractor.h"
11 #include "chrome/browser/download/download_service.h" 15 #include "chrome/browser/download/download_service.h"
12 #include "chrome/browser/download/download_service_factory.h" 16 #include "chrome/browser/download/download_service_factory.h"
13 #include "chrome/browser/download/download_test_observer.h" 17 #include "chrome/browser/download/download_test_observer.h"
14 #include "chrome/browser/extensions/api/downloads/downloads_api.h" 18 #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"
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"
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"
29 #include "ui/gfx/codec/png_codec.h" 46 #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"
30 53
31 using content::BrowserContext; 54 using content::BrowserContext;
32 using content::BrowserThread; 55 using content::BrowserThread;
33 using content::DownloadItem; 56 using content::DownloadItem;
34 using content::DownloadManager; 57 using content::DownloadManager;
35 using content::DownloadPersistentStoreInfo; 58 using content::DownloadPersistentStoreInfo;
36 59
37 namespace { 60 namespace {
38 61
39 // Comparator that orders download items by their ID. Can be used with 62 // Comparator that orders download items by their ID. Can be used with
40 // std::sort. 63 // std::sort.
41 struct DownloadIdComparator { 64 struct DownloadIdComparator {
42 bool operator() (DownloadItem* first, DownloadItem* second) { 65 bool operator() (DownloadItem* first, DownloadItem* second) {
43 return first->GetId() < second->GetId(); 66 return first->GetId() < second->GetId();
44 } 67 }
45 }; 68 };
46 69
47 class DownloadExtensionTest : public InProcessBrowserTest { 70 class DownloadsEventsListener : public content::NotificationObserver {
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
48 protected: 239 protected:
49 // Used with CreateHistoryDownloads 240 // Used with CreateHistoryDownloads
50 struct HistoryDownloadInfo { 241 struct HistoryDownloadInfo {
51 // Filename to use. CreateHistoryDownloads will append this filename to the 242 // Filename to use. CreateHistoryDownloads will append this filename to the
52 // temporary downloads directory specified by downloads_directory(). 243 // temporary downloads directory specified by downloads_directory().
53 const FilePath::CharType* filename; 244 const FilePath::CharType* filename;
54 245
55 // State for the download. Note that IN_PROGRESS downloads will be created 246 // State for the download. Note that IN_PROGRESS downloads will be created
56 // as CANCELLED. 247 // as CANCELLED.
57 DownloadItem::DownloadState state; 248 DownloadItem::DownloadState state;
58 249
59 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS 250 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
60 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT. 251 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT.
61 content::DownloadDangerType danger_type; 252 content::DownloadDangerType danger_type;
62 }; 253 };
63 254
64 virtual Browser* current_browser() { return browser(); } 255 void LoadExtension(const char* name) {
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_; }
65 264
66 // InProcessBrowserTest 265 // InProcessBrowserTest
67 virtual void SetUpOnMainThread() OVERRIDE { 266 virtual void SetUpOnMainThread() OVERRIDE {
68 BrowserThread::PostTask( 267 BrowserThread::PostTask(
69 BrowserThread::IO, FROM_HERE, 268 BrowserThread::IO, FROM_HERE,
70 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); 269 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
71 InProcessBrowserTest::SetUpOnMainThread(); 270 InProcessBrowserTest::SetUpOnMainThread();
271 GoOnTheRecord();
72 CreateAndSetDownloadsDirectory(); 272 CreateAndSetDownloadsDirectory();
73 current_browser()->profile()->GetPrefs()->SetBoolean( 273 current_browser()->profile()->GetPrefs()->SetBoolean(
74 prefs::kPromptForDownload, false); 274 prefs::kPromptForDownload, false);
75 GetDownloadManager()->RemoveAllDownloads(); 275 GetOnRecordManager()->RemoveAllDownloads();
276 events_listener_.reset(new DownloadsEventsListener());
76 } 277 }
77 278
78 virtual DownloadManager* GetDownloadManager() { 279 void GoOnTheRecord() { current_browser_ = browser(); }
79 return BrowserContext::GetDownloadManager(current_browser()->profile()); 280
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();
80 } 356 }
81 357
82 // Creates a set of history downloads based on the provided |history_info| 358 // 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, 359 // array. |count| is the number of elements in |history_info|. On success,
84 // |items| will contain |count| DownloadItems in the order that they were 360 // |items| will contain |count| DownloadItems in the order that they were
85 // specified in |history_info|. Returns true on success and false otherwise. 361 // specified in |history_info|. Returns true on success and false otherwise.
86 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info, 362 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info,
87 size_t count, 363 size_t count,
88 DownloadManager::DownloadVector* items) { 364 DownloadManager::DownloadVector* items) {
89 DownloadIdComparator download_id_comparator; 365 DownloadIdComparator download_id_comparator;
90 base::Time current = base::Time::Now(); 366 base::Time current = base::Time::Now();
91 std::vector<DownloadPersistentStoreInfo> entries; 367 std::vector<DownloadPersistentStoreInfo> entries;
92 entries.reserve(count); 368 entries.reserve(count);
93 for (size_t i = 0; i < count; ++i) { 369 for (size_t i = 0; i < count; ++i) {
94 DownloadPersistentStoreInfo entry( 370 DownloadPersistentStoreInfo entry(
95 downloads_directory().Append(history_info[i].filename), 371 downloads_directory().Append(history_info[i].filename),
96 GURL(), GURL(), // URL, referrer 372 GURL(), GURL(), // URL, referrer
97 current, current, // start_time, end_time 373 current, current, // start_time, end_time
98 1, 1, // received_bytes, total_bytes 374 1, 1, // received_bytes, total_bytes
99 history_info[i].state, // state 375 history_info[i].state, // state
100 i + 1, // db_handle 376 i + 1, // db_handle
101 false); // opened 377 false); // opened
102 entries.push_back(entry); 378 entries.push_back(entry);
103 } 379 }
104 GetDownloadManager()->OnPersistentStoreQueryComplete(&entries); 380 GetOnRecordManager()->OnPersistentStoreQueryComplete(&entries);
105 GetDownloadManager()->GetAllDownloads(FilePath(), items); 381 GetOnRecordManager()->GetAllDownloads(FilePath(), items);
106 EXPECT_EQ(count, items->size()); 382 EXPECT_EQ(count, items->size());
107 if (count != items->size()) 383 if (count != items->size())
108 return false; 384 return false;
109 385
110 // Order by ID so that they are in the order that we created them. 386 // Order by ID so that they are in the order that we created them.
111 std::sort(items->begin(), items->end(), download_id_comparator); 387 std::sort(items->begin(), items->end(), download_id_comparator);
112 // Set the danger type if necessary. 388 // Set the danger type if necessary.
113 for (size_t i = 0; i < count; ++i) { 389 for (size_t i = 0; i < count; ++i) {
114 if (history_info[i].danger_type != 390 if (history_info[i].danger_type !=
115 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) { 391 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
(...skipping 13 matching lines...) Expand all
129 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); 405 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
130 ui_test_utils::NavigateToURLWithDisposition( 406 ui_test_utils::NavigateToURLWithDisposition(
131 current_browser(), slow_download_url, CURRENT_TAB, 407 current_browser(), slow_download_url, CURRENT_TAB,
132 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 408 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
133 observer->WaitForFinished(); 409 observer->WaitForFinished();
134 EXPECT_EQ( 410 EXPECT_EQ(
135 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS)); 411 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
136 // We don't expect a select file dialog. 412 // We don't expect a select file dialog.
137 ASSERT_FALSE(observer->select_file_dialog_seen()); 413 ASSERT_FALSE(observer->select_file_dialog_seen());
138 } 414 }
139 GetDownloadManager()->GetAllDownloads(FilePath(), items); 415 GetCurrentManager()->GetAllDownloads(FilePath(), items);
140 ASSERT_EQ(count, items->size()); 416 ASSERT_EQ(count, items->size());
141 } 417 }
142 418
143 DownloadItem* CreateSlowTestDownload() { 419 DownloadItem* CreateSlowTestDownload() {
144 scoped_ptr<DownloadTestObserver> observer( 420 scoped_ptr<DownloadTestObserver> observer(
145 CreateInProgressDownloadObserver(1)); 421 CreateInProgressDownloadObserver(1));
146 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); 422 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
147 DownloadManager* manager = GetDownloadManager(); 423 DownloadManager* manager = GetCurrentManager();
148 424
149 EXPECT_EQ(0, manager->InProgressCount()); 425 EXPECT_EQ(0, manager->InProgressCount());
150 if (manager->InProgressCount() != 0) 426 if (manager->InProgressCount() != 0)
151 return NULL; 427 return NULL;
152 428
153 ui_test_utils::NavigateToURLWithDisposition( 429 ui_test_utils::NavigateToURLWithDisposition(
154 current_browser(), slow_download_url, CURRENT_TAB, 430 current_browser(), slow_download_url, CURRENT_TAB,
155 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 431 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
156 432
157 observer->WaitForFinished(); 433 observer->WaitForFinished();
(...skipping 23 matching lines...) Expand all
181 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl); 457 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl);
182 ui_test_utils::NavigateToURLWithDisposition( 458 ui_test_utils::NavigateToURLWithDisposition(
183 current_browser(), finish_url, NEW_FOREGROUND_TAB, 459 current_browser(), finish_url, NEW_FOREGROUND_TAB,
184 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 460 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
185 observer->WaitForFinished(); 461 observer->WaitForFinished();
186 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); 462 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
187 } 463 }
188 464
189 DownloadTestObserver* CreateDownloadObserver(size_t download_count) { 465 DownloadTestObserver* CreateDownloadObserver(size_t download_count) {
190 return new DownloadTestObserverTerminal( 466 return new DownloadTestObserverTerminal(
191 GetDownloadManager(), download_count, true, 467 GetCurrentManager(), download_count, true,
192 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); 468 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
193 } 469 }
194 470
195 DownloadTestObserver* CreateInProgressDownloadObserver( 471 DownloadTestObserver* CreateInProgressDownloadObserver(
196 size_t download_count) { 472 size_t download_count) {
197 return new DownloadTestObserverInProgress(GetDownloadManager(), 473 return new DownloadTestObserverInProgress(
198 download_count, 474 GetCurrentManager(), download_count, true);
199 true); 475 }
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());
200 } 483 }
201 484
202 extension_function_test_utils::RunFunctionFlags GetFlags() { 485 extension_function_test_utils::RunFunctionFlags GetFlags() {
203 return current_browser()->profile()->IsOffTheRecord() ? 486 return current_browser()->profile()->IsOffTheRecord() ?
204 extension_function_test_utils::INCLUDE_INCOGNITO : 487 extension_function_test_utils::INCLUDE_INCOGNITO :
205 extension_function_test_utils::NONE; 488 extension_function_test_utils::NONE;
206 } 489 }
207 490
208 // extension_function_test_utils::RunFunction*() only uses browser for its 491 // 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 492 // profile(), so pass it the on-record browser so that it always uses the
210 // on-record profile. 493 // 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 494
221 base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function, 495 base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function,
222 const std::string& args) { 496 const std::string& args) {
497 SetUpExtensionFunction(function);
223 return extension_function_test_utils::RunFunctionAndReturnResult( 498 return extension_function_test_utils::RunFunctionAndReturnResult(
224 function, args, browser(), GetFlags()); 499 function, args, browser(), GetFlags());
225 } 500 }
226 501
227 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, 502 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function,
228 const std::string& args) { 503 const std::string& args) {
504 SetUpExtensionFunction(function);
229 return extension_function_test_utils::RunFunctionAndReturnError( 505 return extension_function_test_utils::RunFunctionAndReturnError(
230 function, args, browser(), GetFlags()); 506 function, args, browser(), GetFlags());
231 } 507 }
232 508
233 bool RunFunctionAndReturnString(UIThreadExtensionFunction* function, 509 bool RunFunctionAndReturnString(UIThreadExtensionFunction* function,
234 const std::string& args, 510 const std::string& args,
235 std::string* result_string) { 511 std::string* result_string) {
512 SetUpExtensionFunction(function);
236 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args)); 513 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args));
237 EXPECT_TRUE(result.get()); 514 EXPECT_TRUE(result.get());
238 return result.get() && result->GetAsString(result_string); 515 return result.get() && result->GetAsString(result_string);
239 } 516 }
240 517
241 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) { 518 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) {
242 return base::StringPrintf("[%d]", download_item->GetId()); 519 return base::StringPrintf("[%d]", download_item->GetId());
243 } 520 }
244 521
245 // Checks if a data URL encoded image is a PNG of a given size. 522 // Checks if a data URL encoded image is a PNG of a given size.
(...skipping 16 matching lines...) Expand all
262 gfx::PNGCodec::FORMAT_RGBA, &decoded_data, 539 gfx::PNGCodec::FORMAT_RGBA, &decoded_data,
263 &width, &height)); 540 &width, &height));
264 EXPECT_EQ(expected_size, width); 541 EXPECT_EQ(expected_size, width);
265 EXPECT_EQ(expected_size, height); 542 EXPECT_EQ(expected_size, height);
266 } 543 }
267 544
268 const FilePath& downloads_directory() { 545 const FilePath& downloads_directory() {
269 return downloads_directory_.path(); 546 return downloads_directory_.path();
270 } 547 }
271 548
549 DownloadsEventsListener* events_listener() { return events_listener_.get(); }
550
272 private: 551 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
273 void CreateAndSetDownloadsDirectory() { 563 void CreateAndSetDownloadsDirectory() {
274 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); 564 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
275 current_browser()->profile()->GetPrefs()->SetFilePath( 565 current_browser()->profile()->GetPrefs()->SetFilePath(
276 prefs::kDownloadDefaultDirectory, 566 prefs::kDownloadDefaultDirectory,
277 downloads_directory_.path()); 567 downloads_directory_.path());
278 } 568 }
279 569
280 ScopedTempDir downloads_directory_; 570 ScopedTempDir downloads_directory_;
281 }; 571 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_; 572 Browser* incognito_browser_;
300 Browser* current_browser_; 573 Browser* current_browser_;
574 scoped_ptr<DownloadsEventsListener> events_listener_;
575
576 DISALLOW_COPY_AND_ASSIGN(DownloadExtensionTest);
301 }; 577 };
302 578
303 class MockIconExtractorImpl : public DownloadFileIconExtractor { 579 class MockIconExtractorImpl : public DownloadFileIconExtractor {
304 public: 580 public:
305 MockIconExtractorImpl(const FilePath& path, IconLoader::IconSize icon_size, 581 MockIconExtractorImpl(const FilePath& path, IconLoader::IconSize icon_size,
306 const std::string& response) 582 const std::string& response)
307 : expected_path_(path), 583 : expected_path_(path),
308 expected_icon_size_(icon_size), 584 expected_icon_size_(icon_size),
309 response_(response) { 585 response_(response) {
310 } 586 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 if ((*item)->IsInProgress()) 645 if ((*item)->IsInProgress())
370 (*item)->Cancel(true); 646 (*item)->Cancel(true);
371 } 647 }
372 } 648 }
373 649
374 private: 650 private:
375 DownloadManager::DownloadVector* items_; 651 DownloadManager::DownloadVector* items_;
376 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller); 652 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller);
377 }; 653 };
378 654
379 } // namespace 655 class TestProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
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 &notification_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 &notification_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
380 844
381 IN_PROC_BROWSER_TEST_F( 845 IN_PROC_BROWSER_TEST_F(
382 DownloadExtensionTest, DownloadExtensionTest_PauseResumeCancel) { 846 DownloadExtensionTest, DownloadExtensionTest_PauseResumeCancel) {
383 DownloadItem* download_item = CreateSlowTestDownload(); 847 DownloadItem* download_item = CreateSlowTestDownload();
384 ASSERT_TRUE(download_item); 848 ASSERT_TRUE(download_item);
385 849
386 // Call pause(). It should succeed and the download should be paused on 850 // Call pause(). It should succeed and the download should be paused on
387 // return. 851 // return.
388 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), 852 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
389 DownloadItemIdAsArgList(download_item))); 853 DownloadItemIdAsArgList(download_item)));
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item)); 888 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item));
425 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 889 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
426 error.c_str()); 890 error.c_str());
427 891
428 // Calling resume on a non-active download yields kInvalidOperationError 892 // Calling resume on a non-active download yields kInvalidOperationError
429 error = RunFunctionAndReturnError( 893 error = RunFunctionAndReturnError(
430 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item)); 894 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item));
431 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 895 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
432 error.c_str()); 896 error.c_str());
433 897
434 // Calling pause()/resume()/cancel() with invalid download Ids is 898 // Calling paused on a non-existent download yields kInvalidOperationError.
435 // tested in the API test (DownloadsApiTest). 899 error = RunFunctionAndReturnError(
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());
436 } 909 }
437 910
438 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted 911 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted
439 // download items. 912 // download items.
440 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, 913 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
441 DownloadExtensionTest_FileIcon_Active) { 914 DownloadExtensionTest_FileIcon_Active) {
442 DownloadItem* download_item = CreateSlowTestDownload(); 915 DownloadItem* download_item = CreateSlowTestDownload();
443 ASSERT_TRUE(download_item); 916 ASSERT_TRUE(download_item);
444 917
445 // Get the icon for the in-progress download. This call should succeed even 918 // 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
521 expected_path, IconLoader::NORMAL, "")); 994 expected_path, IconLoader::NORMAL, ""));
522 std::string error = RunFunctionAndReturnError(function.release(), args); 995 std::string error = RunFunctionAndReturnError(function.release(), args);
523 EXPECT_STREQ(download_extension_errors::kIconNotFoundError, 996 EXPECT_STREQ(download_extension_errors::kIconNotFoundError,
524 error.c_str()); 997 error.c_str());
525 998
526 // Once the download item is deleted, we should return kInvalidOperationError. 999 // Once the download item is deleted, we should return kInvalidOperationError.
527 download_item->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); 1000 download_item->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD);
528 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args); 1001 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args);
529 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 1002 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
530 error.c_str()); 1003 error.c_str());
531
532 // Asking for icons of other (invalid) sizes is tested in the API test
533 // (DownloadsApiTest).
534 } 1004 }
535 1005
536 // Test that we can acquire file icons for history downloads regardless of 1006 // Test that we can acquire file icons for history downloads regardless of
537 // whether they exist or not. If the file doesn't exist we should receive a 1007 // whether they exist or not. If the file doesn't exist we should receive a
538 // generic icon from the OS/toolkit that may or may not be specific to the file 1008 // generic icon from the OS/toolkit that may or may not be specific to the file
539 // type. 1009 // type.
540 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, 1010 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
541 DownloadExtensionTest_FileIcon_History) { 1011 DownloadExtensionTest_FileIcon_History) {
542 const HistoryDownloadInfo kHistoryInfo[] = { 1012 const HistoryDownloadInfo kHistoryInfo[] = {
543 { FILE_PATH_LITERAL("real.txt"), 1013 { FILE_PATH_LITERAL("real.txt"),
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 function->SetIconExtractorForTesting(new MockIconExtractorImpl( 1049 function->SetIconExtractorForTesting(new MockIconExtractorImpl(
580 (*iter)->GetFullPath(), IconLoader::NORMAL, "hello")); 1050 (*iter)->GetFullPath(), IconLoader::NORMAL, "hello"));
581 EXPECT_TRUE(RunFunctionAndReturnString(function.release(), args, 1051 EXPECT_TRUE(RunFunctionAndReturnString(function.release(), args,
582 &result_string)); 1052 &result_string));
583 EXPECT_STREQ("hello", result_string.c_str()); 1053 EXPECT_STREQ("hello", result_string.c_str());
584 } 1054 }
585 1055
586 // The temporary files should be cleaned up when the ScopedTempDir is removed. 1056 // The temporary files should be cleaned up when the ScopedTempDir is removed.
587 } 1057 }
588 1058
1059 // Test passing the empty query to search().
589 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, 1060 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
590 DownloadExtensionTest_SearchEmptyQuery) { 1061 DownloadExtensionTest_SearchEmptyQuery) {
591 ScopedCancellingItem item(CreateSlowTestDownload()); 1062 ScopedCancellingItem item(CreateSlowTestDownload());
592 ASSERT_TRUE(item.get()); 1063 ASSERT_TRUE(item.get());
593 1064
594 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( 1065 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
595 new DownloadsSearchFunction(), "[{}]")); 1066 new DownloadsSearchFunction(), "[{}]"));
596 ASSERT_TRUE(result.get()); 1067 ASSERT_TRUE(result.get());
597 base::ListValue* result_list = NULL; 1068 base::ListValue* result_list = NULL;
598 ASSERT_TRUE(result->GetAsList(&result_list)); 1069 ASSERT_TRUE(result->GetAsList(&result_list));
599 ASSERT_EQ(1UL, result_list->GetSize()); 1070 ASSERT_EQ(1UL, result_list->GetSize());
600 } 1071 }
601 1072
1073 // Test the |filenameRegex| parameter for search().
602 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, 1074 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
603 DownloadExtensionTest_SearchFilenameRegex) { 1075 DownloadExtensionTest_SearchFilenameRegex) {
604 const HistoryDownloadInfo kHistoryInfo[] = { 1076 const HistoryDownloadInfo kHistoryInfo[] = {
605 { FILE_PATH_LITERAL("foobar"), 1077 { FILE_PATH_LITERAL("foobar"),
606 DownloadItem::COMPLETE, 1078 DownloadItem::COMPLETE,
607 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, 1079 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
608 { FILE_PATH_LITERAL("baz"), 1080 { FILE_PATH_LITERAL("baz"),
609 DownloadItem::COMPLETE, 1081 DownloadItem::COMPLETE,
610 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } 1082 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
611 }; 1083 };
612 DownloadManager::DownloadVector all_downloads; 1084 DownloadManager::DownloadVector all_downloads;
613 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), 1085 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
614 &all_downloads)); 1086 &all_downloads));
615 1087
616 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( 1088 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
617 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]")); 1089 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]"));
618 ASSERT_TRUE(result.get()); 1090 ASSERT_TRUE(result.get());
619 base::ListValue* result_list = NULL; 1091 base::ListValue* result_list = NULL;
620 ASSERT_TRUE(result->GetAsList(&result_list)); 1092 ASSERT_TRUE(result->GetAsList(&result_list));
621 ASSERT_EQ(1UL, result_list->GetSize()); 1093 ASSERT_EQ(1UL, result_list->GetSize());
622 base::DictionaryValue* item_value = NULL; 1094 base::DictionaryValue* item_value = NULL;
623 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); 1095 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
624 int item_id = -1; 1096 int item_id = -1;
625 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); 1097 ASSERT_TRUE(item_value->GetInteger("id", &item_id));
626 ASSERT_EQ(0, item_id); 1098 ASSERT_EQ(0, item_id);
627 } 1099 }
628 1100
1101 // Test the |id| parameter for search().
629 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_SearchId) { 1102 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_SearchId) {
630 DownloadManager::DownloadVector items; 1103 DownloadManager::DownloadVector items;
631 CreateSlowTestDownloads(2, &items); 1104 CreateSlowTestDownloads(2, &items);
632 ScopedItemVectorCanceller delete_items(&items); 1105 ScopedItemVectorCanceller delete_items(&items);
633 1106
634 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( 1107 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
635 new DownloadsSearchFunction(), "[{\"id\": 0}]")); 1108 new DownloadsSearchFunction(), "[{\"id\": 0}]"));
636 ASSERT_TRUE(result.get()); 1109 ASSERT_TRUE(result.get());
637 base::ListValue* result_list = NULL; 1110 base::ListValue* result_list = NULL;
638 ASSERT_TRUE(result->GetAsList(&result_list)); 1111 ASSERT_TRUE(result->GetAsList(&result_list));
639 ASSERT_EQ(1UL, result_list->GetSize()); 1112 ASSERT_EQ(1UL, result_list->GetSize());
640 base::DictionaryValue* item_value = NULL; 1113 base::DictionaryValue* item_value = NULL;
641 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); 1114 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
642 int item_id = -1; 1115 int item_id = -1;
643 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); 1116 ASSERT_TRUE(item_value->GetInteger("id", &item_id));
644 ASSERT_EQ(0, item_id); 1117 ASSERT_EQ(0, item_id);
645 } 1118 }
646 1119
1120 // Test specifying both the |id| and |filename| parameters for search().
647 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, 1121 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
648 DownloadExtensionTest_SearchIdAndFilename) { 1122 DownloadExtensionTest_SearchIdAndFilename) {
649 DownloadManager::DownloadVector items; 1123 DownloadManager::DownloadVector items;
650 CreateSlowTestDownloads(2, &items); 1124 CreateSlowTestDownloads(2, &items);
651 ScopedItemVectorCanceller delete_items(&items); 1125 ScopedItemVectorCanceller delete_items(&items);
652 1126
653 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( 1127 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
654 new DownloadsSearchFunction(), "[{\"id\": 0,\"filename\": \"foobar\"}]")); 1128 new DownloadsSearchFunction(),
1129 "[{\"id\": 0, \"filename\": \"foobar\"}]"));
655 ASSERT_TRUE(result.get()); 1130 ASSERT_TRUE(result.get());
656 base::ListValue* result_list = NULL; 1131 base::ListValue* result_list = NULL;
657 ASSERT_TRUE(result->GetAsList(&result_list)); 1132 ASSERT_TRUE(result->GetAsList(&result_list));
658 ASSERT_EQ(0UL, result_list->GetSize()); 1133 ASSERT_EQ(0UL, result_list->GetSize());
659 } 1134 }
660 1135
1136 // Test a single |orderBy| parameter for search().
661 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, 1137 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
662 DownloadExtensionTest_SearchOrderBy) { 1138 DownloadExtensionTest_SearchOrderBy) {
663 const HistoryDownloadInfo kHistoryInfo[] = { 1139 const HistoryDownloadInfo kHistoryInfo[] = {
664 { FILE_PATH_LITERAL("zzz"), 1140 { FILE_PATH_LITERAL("zzz"),
665 DownloadItem::COMPLETE, 1141 DownloadItem::COMPLETE,
666 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, 1142 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
667 { FILE_PATH_LITERAL("baz"), 1143 { FILE_PATH_LITERAL("baz"),
668 DownloadItem::COMPLETE, 1144 DownloadItem::COMPLETE,
669 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } 1145 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
670 }; 1146 };
(...skipping 11 matching lines...) Expand all
682 base::DictionaryValue* item1_value = NULL; 1158 base::DictionaryValue* item1_value = NULL;
683 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); 1159 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value));
684 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); 1160 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value));
685 std::string item0_name, item1_name; 1161 std::string item0_name, item1_name;
686 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); 1162 ASSERT_TRUE(item0_value->GetString("filename", &item0_name));
687 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); 1163 ASSERT_TRUE(item1_value->GetString("filename", &item1_name));
688 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); 1164 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value());
689 ASSERT_LT(item0_name, item1_name); 1165 ASSERT_LT(item0_name, item1_name);
690 } 1166 }
691 1167
1168 // Test specifying an empty |orderBy| parameter for search().
692 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, 1169 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
693 DownloadExtensionTest_SearchOrderByEmpty) { 1170 DownloadExtensionTest_SearchOrderByEmpty) {
694 const HistoryDownloadInfo kHistoryInfo[] = { 1171 const HistoryDownloadInfo kHistoryInfo[] = {
695 { FILE_PATH_LITERAL("zzz"), 1172 { FILE_PATH_LITERAL("zzz"),
696 DownloadItem::COMPLETE, 1173 DownloadItem::COMPLETE,
697 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, 1174 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
698 { FILE_PATH_LITERAL("baz"), 1175 { FILE_PATH_LITERAL("baz"),
699 DownloadItem::COMPLETE, 1176 DownloadItem::COMPLETE,
700 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } 1177 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
701 }; 1178 };
(...skipping 11 matching lines...) Expand all
713 base::DictionaryValue* item1_value = NULL; 1190 base::DictionaryValue* item1_value = NULL;
714 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); 1191 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value));
715 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); 1192 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value));
716 std::string item0_name, item1_name; 1193 std::string item0_name, item1_name;
717 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); 1194 ASSERT_TRUE(item0_value->GetString("filename", &item0_name));
718 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); 1195 ASSERT_TRUE(item1_value->GetString("filename", &item1_name));
719 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); 1196 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value());
720 ASSERT_GT(item0_name, item1_name); 1197 ASSERT_GT(item0_name, item1_name);
721 } 1198 }
722 1199
1200 // Test the |danger| option for search().
723 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, 1201 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
724 DownloadExtensionTest_SearchDanger) { 1202 DownloadExtensionTest_SearchDanger) {
725 const HistoryDownloadInfo kHistoryInfo[] = { 1203 const HistoryDownloadInfo kHistoryInfo[] = {
726 { FILE_PATH_LITERAL("zzz"), 1204 { FILE_PATH_LITERAL("zzz"),
727 DownloadItem::COMPLETE, 1205 DownloadItem::COMPLETE,
728 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, 1206 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
729 { FILE_PATH_LITERAL("baz"), 1207 { FILE_PATH_LITERAL("baz"),
730 DownloadItem::COMPLETE, 1208 DownloadItem::COMPLETE,
731 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } 1209 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
732 }; 1210 };
733 DownloadManager::DownloadVector items; 1211 DownloadManager::DownloadVector items;
734 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), 1212 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
735 &items)); 1213 &items));
736 1214
737 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( 1215 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
738 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]")); 1216 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]"));
739 ASSERT_TRUE(result.get()); 1217 ASSERT_TRUE(result.get());
740 base::ListValue* result_list = NULL; 1218 base::ListValue* result_list = NULL;
741 ASSERT_TRUE(result->GetAsList(&result_list)); 1219 ASSERT_TRUE(result->GetAsList(&result_list));
742 ASSERT_EQ(1UL, result_list->GetSize()); 1220 ASSERT_EQ(1UL, result_list->GetSize());
743 } 1221 }
744 1222
1223 // Test the |state| option for search().
745 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, 1224 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
746 DownloadExtensionTest_SearchState) { 1225 DownloadExtensionTest_SearchState) {
747 DownloadManager::DownloadVector items; 1226 DownloadManager::DownloadVector items;
748 CreateSlowTestDownloads(2, &items); 1227 CreateSlowTestDownloads(2, &items);
749 ScopedItemVectorCanceller delete_items(&items); 1228 ScopedItemVectorCanceller delete_items(&items);
750 1229
751 items[0]->Cancel(true); 1230 items[0]->Cancel(true);
752 1231
753 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( 1232 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
754 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]")); 1233 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]"));
755 ASSERT_TRUE(result.get()); 1234 ASSERT_TRUE(result.get());
756 base::ListValue* result_list = NULL; 1235 base::ListValue* result_list = NULL;
757 ASSERT_TRUE(result->GetAsList(&result_list)); 1236 ASSERT_TRUE(result->GetAsList(&result_list));
758 ASSERT_EQ(1UL, result_list->GetSize()); 1237 ASSERT_EQ(1UL, result_list->GetSize());
759 } 1238 }
760 1239
1240 // Test the |limit| option for search().
761 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, 1241 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
762 DownloadExtensionTest_SearchLimit) { 1242 DownloadExtensionTest_SearchLimit) {
763 DownloadManager::DownloadVector items; 1243 DownloadManager::DownloadVector items;
764 CreateSlowTestDownloads(2, &items); 1244 CreateSlowTestDownloads(2, &items);
765 ScopedItemVectorCanceller delete_items(&items); 1245 ScopedItemVectorCanceller delete_items(&items);
766 1246
767 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( 1247 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
768 new DownloadsSearchFunction(), "[{\"limit\": 1}]")); 1248 new DownloadsSearchFunction(), "[{\"limit\": 1}]"));
769 ASSERT_TRUE(result.get()); 1249 ASSERT_TRUE(result.get());
770 base::ListValue* result_list = NULL; 1250 base::ListValue* result_list = NULL;
771 ASSERT_TRUE(result->GetAsList(&result_list)); 1251 ASSERT_TRUE(result->GetAsList(&result_list));
772 ASSERT_EQ(1UL, result_list->GetSize()); 1252 ASSERT_EQ(1UL, result_list->GetSize());
773 } 1253 }
774 1254
1255 // Test invalid search parameters.
775 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, 1256 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
776 DownloadExtensionTest_SearchInvalid) { 1257 DownloadExtensionTest_SearchInvalid) {
777 std::string error = RunFunctionAndReturnError( 1258 std::string error = RunFunctionAndReturnError(
778 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]"); 1259 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]");
779 EXPECT_STREQ(download_extension_errors::kInvalidFilterError, 1260 EXPECT_STREQ(download_extension_errors::kInvalidFilterError,
780 error.c_str()); 1261 error.c_str());
781 error = RunFunctionAndReturnError( 1262 error = RunFunctionAndReturnError(
782 new DownloadsSearchFunction(), "[{\"danger\": \"goat\"}]"); 1263 new DownloadsSearchFunction(), "[{\"danger\": \"goat\"}]");
783 EXPECT_STREQ(download_extension_errors::kInvalidDangerTypeError, 1264 EXPECT_STREQ(download_extension_errors::kInvalidDangerTypeError,
784 error.c_str()); 1265 error.c_str());
785 error = RunFunctionAndReturnError( 1266 error = RunFunctionAndReturnError(
786 new DownloadsSearchFunction(), "[{\"state\": \"goat\"}]"); 1267 new DownloadsSearchFunction(), "[{\"state\": \"goat\"}]");
787 EXPECT_STREQ(download_extension_errors::kInvalidStateError, 1268 EXPECT_STREQ(download_extension_errors::kInvalidStateError,
788 error.c_str()); 1269 error.c_str());
789 error = RunFunctionAndReturnError( 1270 error = RunFunctionAndReturnError(
790 new DownloadsSearchFunction(), "[{\"orderBy\": \"goat\"}]"); 1271 new DownloadsSearchFunction(), "[{\"orderBy\": \"goat\"}]");
791 EXPECT_STREQ(download_extension_errors::kInvalidOrderByError, 1272 EXPECT_STREQ(download_extension_errors::kInvalidOrderByError,
792 error.c_str()); 1273 error.c_str());
793 error = RunFunctionAndReturnError( 1274 error = RunFunctionAndReturnError(
794 new DownloadsSearchFunction(), "[{\"limit\": -1}]"); 1275 new DownloadsSearchFunction(), "[{\"limit\": -1}]");
795 EXPECT_STREQ(download_extension_errors::kInvalidQueryLimit, 1276 EXPECT_STREQ(download_extension_errors::kInvalidQueryLimit,
796 error.c_str()); 1277 error.c_str());
797 } 1278 }
798 1279
1280 // Test searching using multiple conditions through multiple downloads.
799 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, 1281 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
800 DownloadExtensionTest_SearchPlural) { 1282 DownloadExtensionTest_SearchPlural) {
801 const HistoryDownloadInfo kHistoryInfo[] = { 1283 const HistoryDownloadInfo kHistoryInfo[] = {
802 { FILE_PATH_LITERAL("aaa"), 1284 { FILE_PATH_LITERAL("aaa"),
803 DownloadItem::CANCELLED, 1285 DownloadItem::CANCELLED,
804 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, 1286 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
805 { FILE_PATH_LITERAL("zzz"), 1287 { FILE_PATH_LITERAL("zzz"),
806 DownloadItem::COMPLETE, 1288 DownloadItem::COMPLETE,
807 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, 1289 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
808 { FILE_PATH_LITERAL("baz"), 1290 { FILE_PATH_LITERAL("baz"),
(...skipping 14 matching lines...) Expand all
823 base::ListValue* result_list = NULL; 1305 base::ListValue* result_list = NULL;
824 ASSERT_TRUE(result->GetAsList(&result_list)); 1306 ASSERT_TRUE(result->GetAsList(&result_list));
825 ASSERT_EQ(1UL, result_list->GetSize()); 1307 ASSERT_EQ(1UL, result_list->GetSize());
826 base::DictionaryValue* item_value = NULL; 1308 base::DictionaryValue* item_value = NULL;
827 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); 1309 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
828 FilePath::StringType item_name; 1310 FilePath::StringType item_name;
829 ASSERT_TRUE(item_value->GetString("filename", &item_name)); 1311 ASSERT_TRUE(item_value->GetString("filename", &item_name));
830 ASSERT_EQ(items[2]->GetFullPath().value(), item_name); 1312 ASSERT_EQ(items[2]->GetFullPath().value(), item_name);
831 } 1313 }
832 1314
833 IN_PROC_BROWSER_TEST_F(DownloadExtensionTestIncognito, 1315 // Test that incognito downloads are only visible in incognito contexts, and
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,
834 DownloadExtensionTest_SearchPauseResumeCancelGetFileIconIncognito) { 1320 DownloadExtensionTest_SearchPauseResumeCancelGetFileIconIncognito) {
835 scoped_ptr<base::Value> result_value; 1321 scoped_ptr<base::Value> result_value;
836 base::ListValue* result_list = NULL; 1322 base::ListValue* result_list = NULL;
837 base::DictionaryValue* result_dict = NULL; 1323 base::DictionaryValue* result_dict = NULL;
838 FilePath::StringType filename; 1324 FilePath::StringType filename;
839 bool is_incognito = false; 1325 bool is_incognito = false;
840 std::string error; 1326 std::string error;
841 std::string on_item_arg; 1327 std::string on_item_arg;
842 std::string off_item_arg; 1328 std::string off_item_arg;
843 std::string result_string; 1329 std::string result_string;
844 1330
845 // Set up one on-record item and one off-record item. 1331 // 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);
846 1340
847 GoOnTheRecord(); 1341 GoOnTheRecord();
848 DownloadItem* on_item = CreateSlowTestDownload(); 1342 DownloadItem* on_item = CreateSlowTestDownload();
849 ASSERT_TRUE(on_item); 1343 ASSERT_TRUE(on_item);
850 ASSERT_FALSE(on_item->IsOtr()); 1344 ASSERT_FALSE(on_item->IsOtr());
851 on_item_arg = DownloadItemIdAsArgList(on_item); 1345 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());
857 ASSERT_TRUE(on_item->GetFullPath() != off_item->GetFullPath()); 1346 ASSERT_TRUE(on_item->GetFullPath() != off_item->GetFullPath());
858 off_item_arg = DownloadItemIdAsArgList(off_item);
859 1347
860 // Extensions running in the incognito window should have access to both 1348 // Extensions running in the incognito window should have access to both
861 // items because the Test extension is in spanning mode. 1349 // items because the Test extension is in spanning mode.
1350 GoOffTheRecord();
862 result_value.reset(RunFunctionAndReturnResult( 1351 result_value.reset(RunFunctionAndReturnResult(
863 new DownloadsSearchFunction(), "[{}]")); 1352 new DownloadsSearchFunction(), "[{}]"));
864 ASSERT_TRUE(result_value.get()); 1353 ASSERT_TRUE(result_value.get());
865 ASSERT_TRUE(result_value->GetAsList(&result_list)); 1354 ASSERT_TRUE(result_value->GetAsList(&result_list));
866 ASSERT_EQ(2UL, result_list->GetSize()); 1355 ASSERT_EQ(2UL, result_list->GetSize());
867 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict)); 1356 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict));
868 ASSERT_TRUE(result_dict->GetString("filename", &filename)); 1357 ASSERT_TRUE(result_dict->GetString("filename", &filename));
869 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito)); 1358 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
870 EXPECT_TRUE(on_item->GetFullPath() == FilePath(filename)); 1359 EXPECT_TRUE(on_item->GetFullPath() == FilePath(filename));
871 EXPECT_FALSE(is_incognito); 1360 EXPECT_FALSE(is_incognito);
(...skipping 25 matching lines...) Expand all
897 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), 1386 error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
898 off_item_arg); 1387 off_item_arg);
899 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 1388 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
900 error.c_str()); 1389 error.c_str());
901 error = RunFunctionAndReturnError( 1390 error = RunFunctionAndReturnError(
902 new DownloadsGetFileIconFunction(), 1391 new DownloadsGetFileIconFunction(),
903 base::StringPrintf("[%d, {}]", off_item->GetId())); 1392 base::StringPrintf("[%d, {}]", off_item->GetId()));
904 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 1393 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
905 error.c_str()); 1394 error.c_str());
906 1395
907 // TODO(benjhayden): Test incognito_split_mode() extension.
908 // TODO(benjhayden): Test download(), onCreated, onChanged, onErased.
909
910 GoOffTheRecord(); 1396 GoOffTheRecord();
911 1397
912 // Do the FileIcon test for both the on- and off-items while off the record. 1398 // Do the FileIcon test for both the on- and off-items while off the record.
913 // NOTE(benjhayden): This does not include the FileIcon test from history, 1399 // NOTE(benjhayden): This does not include the FileIcon test from history,
914 // just active downloads. This shouldn't be a problem. 1400 // just active downloads. This shouldn't be a problem.
915 EXPECT_TRUE(RunFunctionAndReturnString( 1401 EXPECT_TRUE(RunFunctionAndReturnString(
916 new DownloadsGetFileIconFunction(), 1402 new DownloadsGetFileIconFunction(),
917 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string)); 1403 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string));
918 EXPECT_TRUE(RunFunctionAndReturnString( 1404 EXPECT_TRUE(RunFunctionAndReturnString(
919 new DownloadsGetFileIconFunction(), 1405 new DownloadsGetFileIconFunction(),
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 EXPECT_TRUE(off_item->IsCancelled()); 1443 EXPECT_TRUE(off_item->IsCancelled());
958 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), 1444 error = RunFunctionAndReturnError(new DownloadsPauseFunction(),
959 off_item_arg); 1445 off_item_arg);
960 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 1446 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
961 error.c_str()); 1447 error.c_str());
962 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), 1448 error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
963 off_item_arg); 1449 off_item_arg);
964 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 1450 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
965 error.c_str()); 1451 error.c_str());
966 } 1452 }
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-%d.txt\","
1582 " \"headers\": [{"
1583 " \"name\": \"%s\","
1584 " \"value\": \"unsafe\"}]}]",
1585 download_url.c_str(),
1586 static_cast<int>(index),
1587 kUnsafeHeaders[index])).c_str());
1588 }
1589 }
1590
1591 // Test that subdirectories (slashes) are disallowed in filenames.
1592 // TODO(benjhayden) Update this when subdirectories are supported.
1593 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1594 DownloadExtensionTest_Download_Subdirectory) {
1595 LoadExtension("downloads_split");
1596 CHECK(StartTestServer());
1597 std::string download_url = test_server()->GetURL("slow?0").spec();
1598 GoOnTheRecord();
1599
1600 EXPECT_STREQ(download_extension_errors::kGenericError,
1601 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1602 base::StringPrintf(
1603 "[{\"url\": \"%s\","
1604 " \"filename\": \"sub/dir/ect/ory.txt\"}]",
1605 download_url.c_str())).c_str());
1606 }
1607
1608 // Test that invalid filenames are disallowed.
1609 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1610 DownloadExtensionTest_Download_InvalidFilename) {
1611 LoadExtension("downloads_split");
1612 CHECK(StartTestServer());
1613 std::string download_url = test_server()->GetURL("slow?0").spec();
1614 GoOnTheRecord();
1615
1616 EXPECT_STREQ(download_extension_errors::kGenericError,
1617 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1618 base::StringPrintf(
1619 "[{\"url\": \"%s\","
1620 " \"filename\": \"../../../../../etc/passwd\"}]",
1621 download_url.c_str())).c_str());
1622 }
1623
1624 // Test that downloading invalid URLs immediately returns kInvalidURLError.
1625 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1626 DownloadExtensionTest_Download_InvalidURLs) {
1627 LoadExtension("downloads_split");
1628 GoOnTheRecord();
1629
1630 static const char* kInvalidURLs[] = {
1631 "foo bar",
1632 "../hello",
1633 "/hello",
1634 "google.com/",
1635 "http://",
1636 "#frag",
1637 "foo/bar.html#frag",
1638 "javascript:document.write(\\\"hello\\\");",
1639 "javascript:return false;",
1640 "ftp://example.com/example.txt",
1641 };
1642
1643 for (size_t index = 0; index < arraysize(kInvalidURLs); ++index) {
1644 EXPECT_STREQ(download_extension_errors::kInvalidURLError,
1645 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1646 base::StringPrintf(
1647 "[{\"url\": \"%s\"}]", kInvalidURLs[index])).c_str());
1648 }
1649 }
1650
1651 // TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to
1652 // permissions, test downloading from ftp.
1653
1654 // Valid URLs plus fragments are still valid URLs.
1655 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1656 DownloadExtensionTest_Download_URLFragment) {
1657 LoadExtension("downloads_split");
1658 CHECK(StartTestServer());
1659 std::string download_url = test_server()->GetURL("slow?0#fragment").spec();
1660 GoOnTheRecord();
1661
1662 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1663 new DownloadsDownloadFunction(), base::StringPrintf(
1664 "[{\"url\": \"%s\"}]", download_url.c_str())));
1665 ASSERT_TRUE(result.get());
1666 int result_id = -1;
1667 ASSERT_TRUE(result->GetAsInteger(&result_id));
1668 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1669 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1670 ASSERT_TRUE(item);
1671 ScopedCancellingItem canceller(item);
1672 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1673
1674 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1675 base::StringPrintf("[{\"danger\": \"safe\","
1676 " \"filename\": \"%s\","
1677 " \"incognito\": false,"
1678 " \"mime\": \"text/plain\","
1679 " \"paused\": false,"
1680 " \"url\": \"%s\"}]",
1681 GetFilename("slow.txt.crdownload").c_str(),
1682 download_url.c_str())));
1683 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1684 base::StringPrintf("[{\"id\": %d,"
1685 " \"filename\": {"
1686 " \"previous\": \"%s\","
1687 " \"current\": \"%s\"},"
1688 " \"state\": {"
1689 " \"previous\": \"in_progress\","
1690 " \"current\": \"complete\"}}]",
1691 result_id,
1692 GetFilename("slow.txt.crdownload").c_str(),
1693 GetFilename("slow.txt").c_str())));
1694 }
1695
1696 // Valid data URLs are valid URLs.
1697 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1698 DownloadExtensionTest_Download_DataURL) {
1699 LoadExtension("downloads_split");
1700 CHECK(StartTestServer());
1701 std::string download_url = "data:text/plain,hello";
1702 GoOnTheRecord();
1703
1704 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1705 new DownloadsDownloadFunction(), base::StringPrintf(
1706 "[{\"url\": \"%s\","
1707 " \"filename\": \"data.txt\"}]", download_url.c_str())));
1708 ASSERT_TRUE(result.get());
1709 int result_id = -1;
1710 ASSERT_TRUE(result->GetAsInteger(&result_id));
1711 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1712 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1713 ASSERT_TRUE(item);
1714 ScopedCancellingItem canceller(item);
1715 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1716
1717 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1718 base::StringPrintf("[{\"danger\": \"safe\","
1719 " \"filename\": \"%s\","
1720 " \"incognito\": false,"
1721 " \"mime\": \"text/plain\","
1722 " \"paused\": false,"
1723 " \"url\": \"%s\"}]",
1724 GetFilename("data.txt.crdownload").c_str(),
1725 download_url.c_str())));
1726 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1727 base::StringPrintf("[{\"id\": %d,"
1728 " \"filename\": {"
1729 " \"previous\": \"%s\","
1730 " \"current\": \"%s\"},"
1731 " \"state\": {"
1732 " \"previous\": \"in_progress\","
1733 " \"current\": \"complete\"}}]",
1734 result_id,
1735 GetFilename("data.txt.crdownload").c_str(),
1736 GetFilename("data.txt").c_str())));
1737 }
1738
1739 // Valid file URLs are valid URLs.
1740 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1741 DownloadExtensionTest_Download_File) {
1742 GoOnTheRecord();
1743 CHECK(StartTestServer());
1744 LoadExtension("downloads_split");
1745 std::string download_url = "file:///";
1746 #if defined(OS_WIN)
1747 download_url += "C:/";
1748 #endif
1749
1750 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1751 new DownloadsDownloadFunction(), base::StringPrintf(
1752 "[{\"url\": \"%s\","
1753 " \"filename\": \"file.txt\"}]", 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->GetOriginalUrl().spec());
1762
1763 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1764 base::StringPrintf("[{\"danger\": \"safe\","
1765 " \"filename\": \"%s\","
1766 " \"incognito\": false,"
1767 " \"mime\": \"text/html\","
1768 " \"paused\": false,"
1769 " \"url\": \"%s\"}]",
1770 GetFilename("file.txt.crdownload").c_str(),
1771 download_url.c_str())));
1772 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1773 base::StringPrintf("[{\"id\": %d,"
1774 " \"filename\": {"
1775 " \"previous\": \"%s\","
1776 " \"current\": \"%s\"},"
1777 " \"state\": {"
1778 " \"previous\": \"in_progress\","
1779 " \"current\": \"complete\"}}]",
1780 result_id,
1781 GetFilename("file.txt.crdownload").c_str(),
1782 GetFilename("file.txt").c_str())));
1783 }
1784
1785 // Test that auth-basic-succeed would fail if the resource requires the
1786 // Authorization header and chrome fails to propagate it back to the server.
1787 // This tests both that testserver.py does not succeed when it should fail as
1788 // well as how the downloads extension API exposes the failure to extensions.
1789 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1790 DownloadExtensionTest_Download_AuthBasic_Fail) {
1791 LoadExtension("downloads_split");
1792 CHECK(StartTestServer());
1793 std::string download_url = test_server()->GetURL("auth-basic").spec();
1794 GoOnTheRecord();
1795
1796 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1797 new DownloadsDownloadFunction(), base::StringPrintf(
1798 "[{\"url\": \"%s\","
1799 " \"filename\": \"auth-basic-fail.txt\"}]",
1800 download_url.c_str())));
1801 ASSERT_TRUE(result.get());
1802 int result_id = -1;
1803 ASSERT_TRUE(result->GetAsInteger(&result_id));
1804 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1805 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1806 ASSERT_TRUE(item);
1807 ScopedCancellingItem canceller(item);
1808 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1809
1810 ASSERT_TRUE(WaitForInterruption(item, 30, base::StringPrintf(
1811 "[{\"danger\": \"safe\","
1812 " \"incognito\": false,"
1813 " \"mime\": \"text/html\","
1814 " \"paused\": false,"
1815 " \"url\": \"%s\"}]",
1816 download_url.c_str())));
1817 }
1818
1819 // Test that DownloadsDownloadFunction propagates |headers| to the URLRequest.
1820 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1821 DownloadExtensionTest_Download_Headers) {
1822 LoadExtension("downloads_split");
1823 CHECK(StartTestServer());
1824 std::string download_url = test_server()->GetURL("files/downloads/"
1825 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
1826 GoOnTheRecord();
1827
1828 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1829 new DownloadsDownloadFunction(), base::StringPrintf(
1830 "[{\"url\": \"%s\","
1831 " \"filename\": \"headers-succeed.txt\","
1832 " \"headers\": ["
1833 " {\"name\": \"Foo\", \"value\": \"bar\"},"
1834 " {\"name\": \"Qx\", \"value\":\"yo\"}]}]",
1835 download_url.c_str())));
1836 ASSERT_TRUE(result.get());
1837 int result_id = -1;
1838 ASSERT_TRUE(result->GetAsInteger(&result_id));
1839 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1840 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1841 ASSERT_TRUE(item);
1842 ScopedCancellingItem canceller(item);
1843 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1844
1845 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1846 base::StringPrintf("[{\"danger\": \"safe\","
1847 " \"incognito\": false,"
1848 " \"mime\": \"application/octet-stream\","
1849 " \"paused\": false,"
1850 " \"url\": \"%s\"}]",
1851 download_url.c_str())));
1852 std::string incomplete_filename = GetFilename(
1853 "headers-succeed.txt.crdownload");
1854 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1855 base::StringPrintf("[{\"id\": %d,"
1856 " \"filename\": {"
1857 " \"previous\": \"%s\","
1858 " \"current\": \"%s\"},"
1859 " \"state\": {"
1860 " \"previous\": \"in_progress\","
1861 " \"current\": \"complete\"}}]",
1862 result_id,
1863 incomplete_filename.c_str(),
1864 GetFilename("headers-succeed.txt").c_str())));
1865 }
1866
1867 // Test that headers-succeed would fail if the resource requires the headers and
1868 // chrome fails to propagate them back to the server. This tests both that
1869 // testserver.py does not succeed when it should fail as well as how the
1870 // downloads extension api exposes the failure to extensions.
1871 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1872 DownloadExtensionTest_Download_Headers_Fail) {
1873 LoadExtension("downloads_split");
1874 CHECK(StartTestServer());
1875 std::string download_url = test_server()->GetURL("files/downloads/"
1876 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
1877 GoOnTheRecord();
1878
1879 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1880 new DownloadsDownloadFunction(), base::StringPrintf(
1881 "[{\"url\": \"%s\","
1882 " \"filename\": \"headers-fail.txt\"}]",
1883 download_url.c_str())));
1884 ASSERT_TRUE(result.get());
1885 int result_id = -1;
1886 ASSERT_TRUE(result->GetAsInteger(&result_id));
1887 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1888 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1889 ASSERT_TRUE(item);
1890 ScopedCancellingItem canceller(item);
1891 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1892
1893 ASSERT_TRUE(WaitForInterruption(item, 33, base::StringPrintf(
1894 "[{\"danger\": \"safe\","
1895 " \"incognito\": false,"
1896 " \"bytesReceived\": 0,"
1897 " \"mime\": \"\","
1898 " \"paused\": false,"
1899 " \"url\": \"%s\"}]",
1900 download_url.c_str())));
1901 }
1902
1903 // Test that DownloadsDownloadFunction propagates the Authorization header
1904 // correctly.
1905 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1906 DownloadExtensionTest_Download_AuthBasic) {
1907 LoadExtension("downloads_split");
1908 CHECK(StartTestServer());
1909 std::string download_url = test_server()->GetURL("auth-basic").spec();
1910 // This is just base64 of 'username:secret'.
1911 static const char* kAuthorization = "dXNlcm5hbWU6c2VjcmV0";
1912 GoOnTheRecord();
1913
1914 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1915 new DownloadsDownloadFunction(), base::StringPrintf(
1916 "[{\"url\": \"%s\","
1917 " \"filename\": \"auth-basic-succeed.txt\","
1918 " \"headers\": [{"
1919 " \"name\": \"Authorization\","
1920 " \"value\": \"Basic %s\"}]}]",
1921 download_url.c_str(), kAuthorization)));
1922 ASSERT_TRUE(result.get());
1923 int result_id = -1;
1924 ASSERT_TRUE(result->GetAsInteger(&result_id));
1925 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1926 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1927 ASSERT_TRUE(item);
1928 ScopedCancellingItem canceller(item);
1929 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1930
1931 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1932 base::StringPrintf("[{\"danger\": \"safe\","
1933 " \"incognito\": false,"
1934 " \"mime\": \"text/html\","
1935 " \"paused\": false,"
1936 " \"url\": \"%s\"}]", download_url.c_str())));
1937 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1938 base::StringPrintf("[{\"id\": %d,"
1939 " \"state\": {"
1940 " \"previous\": \"in_progress\","
1941 " \"current\": \"complete\"}}]", result_id)));
1942 }
1943
1944 // Test that DownloadsDownloadFunction propagates the |method| and |body|
1945 // parameters to the URLRequest.
1946 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1947 DownloadExtensionTest_Download_Post) {
1948 LoadExtension("downloads_split");
1949 CHECK(StartTestServer());
1950 std::string download_url = test_server()->GetURL("files/post/downloads/"
1951 "a_zip_file.zip?expected_body=BODY").spec();
1952 GoOnTheRecord();
1953
1954 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1955 new DownloadsDownloadFunction(), base::StringPrintf(
1956 "[{\"url\": \"%s\","
1957 " \"filename\": \"post-succeed.txt\","
1958 " \"method\": \"POST\","
1959 " \"body\": \"BODY\"}]",
1960 download_url.c_str())));
1961 ASSERT_TRUE(result.get());
1962 int result_id = -1;
1963 ASSERT_TRUE(result->GetAsInteger(&result_id));
1964 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1965 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1966 ASSERT_TRUE(item);
1967 ScopedCancellingItem canceller(item);
1968 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1969
1970 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1971 base::StringPrintf("[{\"danger\": \"safe\","
1972 " \"incognito\": false,"
1973 " \"mime\": \"application/octet-stream\","
1974 " \"paused\": false,"
1975 " \"bytesReceived\": 164,"
1976 " \"url\": \"%s\"}]", download_url.c_str())));
1977 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1978 base::StringPrintf("[{\"id\": %d,"
1979 " \"state\": {"
1980 " \"previous\": \"in_progress\","
1981 " \"current\": \"complete\"}}]", result_id)));
1982 }
1983
1984 // Test that downloadPostSuccess would fail if the resource requires the POST
1985 // method, and chrome fails to propagate the |method| parameter back to the
1986 // server. This tests both that testserver.py does not succeed when it should
1987 // fail, and this tests how the downloads extension api exposes the failure to
1988 // extensions.
1989 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1990 DownloadExtensionTest_Download_Post_Get) {
1991 LoadExtension("downloads_split");
1992 CHECK(StartTestServer());
1993 std::string download_url = test_server()->GetURL("files/post/downloads/"
1994 "a_zip_file.zip?expected_body=BODY").spec();
1995 GoOnTheRecord();
1996
1997 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1998 new DownloadsDownloadFunction(), base::StringPrintf(
1999 "[{\"url\": \"%s\","
2000 " \"body\": \"BODY\","
2001 " \"filename\": \"post-get.txt\"}]",
2002 download_url.c_str())));
2003 ASSERT_TRUE(result.get());
2004 int result_id = -1;
2005 ASSERT_TRUE(result->GetAsInteger(&result_id));
2006 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
2007 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
2008 ASSERT_TRUE(item);
2009 ScopedCancellingItem canceller(item);
2010 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2011
2012 ASSERT_TRUE(WaitForInterruption(item, 33, base::StringPrintf(
2013 "[{\"danger\": \"safe\","
2014 " \"incognito\": false,"
2015 " \"mime\": \"\","
2016 " \"paused\": false,"
2017 " \"id\": %d,"
2018 " \"url\": \"%s\"}]",
2019 result_id,
2020 download_url.c_str())));
2021 }
2022
2023 // Test that downloadPostSuccess would fail if the resource requires the POST
2024 // method, and chrome fails to propagate the |body| parameter back to the
2025 // server. This tests both that testserver.py does not succeed when it should
2026 // fail, and this tests how the downloads extension api exposes the failure to
2027 // extensions.
2028 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2029 DownloadExtensionTest_Download_Post_NoBody) {
2030 LoadExtension("downloads_split");
2031 CHECK(StartTestServer());
2032 std::string download_url = test_server()->GetURL("files/post/downloads/"
2033 "a_zip_file.zip?expected_body=BODY").spec();
2034 GoOnTheRecord();
2035
2036 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2037 new DownloadsDownloadFunction(), base::StringPrintf(
2038 "[{\"url\": \"%s\","
2039 " \"method\": \"POST\","
2040 " \"filename\": \"post-nobody.txt\"}]",
2041 download_url.c_str())));
2042 ASSERT_TRUE(result.get());
2043 int result_id = -1;
2044 ASSERT_TRUE(result->GetAsInteger(&result_id));
2045 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
2046 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
2047 ASSERT_TRUE(item);
2048 ScopedCancellingItem canceller(item);
2049 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2050
2051 ASSERT_TRUE(WaitForInterruption(item, 33, base::StringPrintf(
2052 "[{\"danger\": \"safe\","
2053 " \"incognito\": false,"
2054 " \"mime\": \"\","
2055 " \"paused\": false,"
2056 " \"id\": %d,"
2057 " \"url\": \"%s\"}]",
2058 result_id,
2059 download_url.c_str())));
2060 }
2061
2062 // Test that cancel()ing an in-progress download causes its state to transition
2063 // to interrupted, and test that that state transition is detectable by an
2064 // onChanged event listener. TODO(benjhayden): Test other sources of
2065 // interruptions such as server death.
2066 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2067 DownloadExtensionTest_Download_Cancel) {
2068 LoadExtension("downloads_split");
2069 CHECK(StartTestServer());
2070 std::string download_url = test_server()->GetURL(
2071 "download-known-size").spec();
2072 GoOnTheRecord();
2073
2074 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2075 new DownloadsDownloadFunction(), base::StringPrintf(
2076 "[{\"url\": \"%s\"}]", download_url.c_str())));
2077 ASSERT_TRUE(result.get());
2078 int result_id = -1;
2079 ASSERT_TRUE(result->GetAsInteger(&result_id));
2080 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
2081 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
2082 ASSERT_TRUE(item);
2083 ScopedCancellingItem canceller(item);
2084 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2085
2086 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
2087 base::StringPrintf("[{\"danger\": \"safe\","
2088 " \"incognito\": false,"
2089 " \"mime\": \"application/octet-stream\","
2090 " \"paused\": false,"
2091 " \"id\": %d,"
2092 " \"url\": \"%s\"}]",
2093 result_id,
2094 download_url.c_str())));
2095 item->Cancel(true);
2096 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
2097 base::StringPrintf("[{\"id\": %d,"
2098 " \"error\": {\"current\": 40},"
2099 " \"state\": {"
2100 " \"previous\": \"in_progress\","
2101 " \"current\": \"interrupted\"}}]",
2102 result_id)));
2103 }
2104
2105 // Test downloading filesystem: URLs.
2106 // NOTE: chrome disallows creating HTML5 FileSystem Files in incognito.
2107 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2108 DownloadExtensionTest_Download_FileSystemURL) {
2109 static const char* kPayloadData = "on the record\ndata";
2110 GoOnTheRecord();
2111 LoadExtension("downloads_split");
2112 HTML5FileWriter html5_file_writer(
2113 browser()->profile(),
2114 "on_record.txt",
2115 GetExtensionURL(),
2116 events_listener(),
2117 kPayloadData);
2118 ASSERT_TRUE(html5_file_writer.WriteFile());
2119
2120 std::string download_url = "filesystem:" + GetExtensionURL() +
2121 "temporary/on_record.txt";
2122 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2123 new DownloadsDownloadFunction(), base::StringPrintf(
2124 "[{\"url\": \"%s\"}]", download_url.c_str())));
2125 ASSERT_TRUE(result.get());
2126 int result_id = -1;
2127 ASSERT_TRUE(result->GetAsInteger(&result_id));
2128
2129 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
2130 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
2131 ASSERT_TRUE(item);
2132 ScopedCancellingItem canceller(item);
2133 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2134
2135 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
2136 base::StringPrintf("[{\"danger\": \"safe\","
2137 " \"filename\": \"%s\","
2138 " \"incognito\": false,"
2139 " \"mime\": \"text/plain\","
2140 " \"paused\": false,"
2141 " \"url\": \"%s\"}]",
2142 GetFilename("on_record.txt.crdownload").c_str(),
2143 download_url.c_str())));
2144 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
2145 base::StringPrintf("[{\"id\": %d,"
2146 " \"filename\": {"
2147 " \"previous\": \"%s\","
2148 " \"current\": \"%s\"},"
2149 " \"state\": {"
2150 " \"previous\": \"in_progress\","
2151 " \"current\": \"complete\"}}]",
2152 result_id,
2153 GetFilename("on_record.txt.crdownload").c_str(),
2154 GetFilename("on_record.txt").c_str())));
2155 std::string disk_data;
2156 EXPECT_TRUE(file_util::ReadFileToString(item->GetFullPath(), &disk_data));
2157 EXPECT_STREQ(kPayloadData, disk_data.c_str());
2158 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/downloads/downloads_api.cc ('k') | chrome/browser/extensions/api/downloads/downloads_apitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698