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
3 // found in the LICENSE file.
5 // Disable everything on windows only. http://crbug.com/306144
10 #include "base/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/json/json_reader.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/stl_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/synchronization/waitable_event.h"
18 #include "chrome/browser/chrome_notification_types.h"
19 #include "chrome/browser/download/download_file_icon_extractor.h"
20 #include "chrome/browser/download/download_service.h"
21 #include "chrome/browser/download/download_service_factory.h"
22 #include "chrome/browser/download/download_test_file_activity_observer.h"
23 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
24 #include "chrome/browser/extensions/browser_action_test_util.h"
25 #include "chrome/browser/extensions/extension_apitest.h"
26 #include "chrome/browser/extensions/extension_function_test_utils.h"
27 #include "chrome/browser/extensions/extension_service.h"
28 #include "chrome/browser/history/download_row.h"
29 #include "chrome/browser/net/url_request_mock_util.h"
30 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/browser/ui/browser.h"
32 #include "chrome/browser/ui/browser_tabstrip.h"
33 #include "chrome/common/pref_names.h"
34 #include "chrome/test/base/in_process_browser_test.h"
35 #include "chrome/test/base/ui_test_utils.h"
36 #include "content/public/browser/browser_context.h"
37 #include "content/public/browser/browser_thread.h"
38 #include "content/public/browser/download_item.h"
39 #include "content/public/browser/download_manager.h"
40 #include "content/public/browser/notification_service.h"
41 #include "content/public/browser/storage_partition.h"
42 #include "content/public/browser/web_contents.h"
43 #include "content/public/common/content_switches.h"
44 #include "content/public/common/page_transition_types.h"
45 #include "content/public/test/download_test_observer.h"
46 #include "content/test/net/url_request_slow_download_job.h"
47 #include "net/base/data_url.h"
48 #include "net/base/net_util.h"
49 #include "net/url_request/url_request.h"
50 #include "net/url_request/url_request_context.h"
51 #include "net/url_request/url_request_job.h"
52 #include "net/url_request/url_request_job_factory.h"
53 #include "net/url_request/url_request_job_factory_impl.h"
54 #include "webkit/browser/fileapi/file_system_context.h"
55 #include "webkit/browser/fileapi/file_system_operation_runner.h"
56 #include "webkit/browser/fileapi/file_system_url.h"
58 using content::BrowserContext;
59 using content::BrowserThread;
60 using content::DownloadItem;
61 using content::DownloadManager;
62 using content::URLRequestSlowDownloadJob;
64 namespace errors = download_extension_errors;
66 namespace downloads = extensions::api::downloads;
68 namespace extensions {
72 // Comparator that orders download items by their ID. Can be used with
74 struct DownloadIdComparator {
75 bool operator() (DownloadItem* first, DownloadItem* second) {
76 return first->GetId() < second->GetId();
80 class DownloadsEventsListener : public content::NotificationObserver {
82 DownloadsEventsListener()
84 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
85 content::NotificationService::AllSources());
88 virtual ~DownloadsEventsListener() {
89 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
90 content::NotificationService::AllSources());
91 STLDeleteElements(&events_);
95 STLDeleteElements(&events_);
101 Event(Profile* profile,
102 const std::string& event_name,
103 const std::string& json_args,
106 event_name_(event_name),
107 json_args_(json_args),
108 args_(base::JSONReader::Read(json_args)),
112 const base::Time& caught() { return caught_; }
114 bool Satisfies(const Event& other) const {
115 return other.SatisfiedBy(*this);
118 bool SatisfiedBy(const Event& other) const {
119 if ((profile_ != other.profile_) ||
120 (event_name_ != other.event_name_))
122 if (((event_name_ == downloads::OnDeterminingFilename::kEventName) ||
123 (event_name_ == downloads::OnCreated::kEventName) ||
124 (event_name_ == downloads::OnChanged::kEventName)) &&
125 args_.get() && other.args_.get()) {
126 base::ListValue* left_list = NULL;
127 base::DictionaryValue* left_dict = NULL;
128 base::ListValue* right_list = NULL;
129 base::DictionaryValue* right_dict = NULL;
130 if (!args_->GetAsList(&left_list) ||
131 !other.args_->GetAsList(&right_list) ||
132 !left_list->GetDictionary(0, &left_dict) ||
133 !right_list->GetDictionary(0, &right_dict))
135 for (base::DictionaryValue::Iterator iter(*left_dict);
136 !iter.IsAtEnd(); iter.Advance()) {
137 base::Value* right_value = NULL;
138 if (!right_dict->HasKey(iter.key()) ||
139 (right_dict->Get(iter.key(), &right_value) &&
140 !iter.value().Equals(right_value))) {
145 } else if ((event_name_ == downloads::OnErased::kEventName) &&
146 args_.get() && other.args_.get()) {
147 int my_id = -1, other_id = -1;
148 return (args_->GetAsInteger(&my_id) &&
149 other.args_->GetAsInteger(&other_id) &&
152 return json_args_ == other.json_args_;
155 std::string Debug() {
156 return base::StringPrintf("Event(%p, %s, %s, %f)",
165 std::string event_name_;
166 std::string json_args_;
167 scoped_ptr<base::Value> args_;
170 DISALLOW_COPY_AND_ASSIGN(Event);
173 typedef ExtensionDownloadsEventRouter::DownloadsNotificationSource
174 DownloadsNotificationSource;
176 virtual void Observe(int type,
177 const content::NotificationSource& source,
178 const content::NotificationDetails& details) OVERRIDE {
180 case chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT:
182 DownloadsNotificationSource* dns =
183 content::Source<DownloadsNotificationSource>(source).ptr();
184 Event* new_event = new Event(
187 *content::Details<std::string>(details).ptr(), base::Time::Now());
188 events_.push_back(new_event);
190 waiting_for_.get() &&
191 new_event->Satisfies(*waiting_for_)) {
193 base::MessageLoopForUI::current()->Quit();
202 bool WaitFor(Profile* profile,
203 const std::string& event_name,
204 const std::string& json_args) {
205 waiting_for_.reset(new Event(profile, event_name, json_args, base::Time()));
206 for (std::deque<Event*>::const_iterator iter = events_.begin();
207 iter != events_.end(); ++iter) {
208 if ((*iter)->Satisfies(*waiting_for_.get())) {
213 content::RunMessageLoop();
214 bool success = !waiting_;
216 // Print the events that were caught since the last WaitFor() call to help
217 // find the erroneous event.
218 // TODO(benjhayden) Fuzzy-match and highlight the erroneous event.
219 for (std::deque<Event*>::const_iterator iter = events_.begin();
220 iter != events_.end(); ++iter) {
221 if ((*iter)->caught() > last_wait_) {
222 LOG(INFO) << "Caught " << (*iter)->Debug();
225 if (waiting_for_.get()) {
226 LOG(INFO) << "Timed out waiting for " << waiting_for_->Debug();
230 waiting_for_.reset();
231 last_wait_ = base::Time::Now();
237 base::Time last_wait_;
238 scoped_ptr<Event> waiting_for_;
239 content::NotificationRegistrar registrar_;
240 std::deque<Event*> events_;
242 DISALLOW_COPY_AND_ASSIGN(DownloadsEventsListener);
245 class DownloadExtensionTest : public ExtensionApiTest {
247 DownloadExtensionTest()
249 incognito_browser_(NULL),
250 current_browser_(NULL) {
254 // Used with CreateHistoryDownloads
255 struct HistoryDownloadInfo {
256 // Filename to use. CreateHistoryDownloads will append this filename to the
257 // temporary downloads directory specified by downloads_directory().
258 const base::FilePath::CharType* filename;
260 // State for the download. Note that IN_PROGRESS downloads will be created
262 DownloadItem::DownloadState state;
264 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
265 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT.
266 content::DownloadDangerType danger_type;
269 void LoadExtension(const char* name) {
270 // Store the created Extension object so that we can attach it to
271 // ExtensionFunctions. Also load the extension in incognito profiles for
272 // testing incognito.
273 extension_ = LoadExtensionIncognito(test_data_dir_.AppendASCII(name));
275 content::WebContents* tab = chrome::AddSelectedTabWithURL(
277 extension_->GetResourceURL("empty.html"),
278 content::PAGE_TRANSITION_LINK);
279 extensions::EventRouter::Get(current_browser()->profile())
280 ->AddEventListener(downloads::OnCreated::kEventName,
281 tab->GetRenderProcessHost(),
283 extensions::EventRouter::Get(current_browser()->profile())
284 ->AddEventListener(downloads::OnChanged::kEventName,
285 tab->GetRenderProcessHost(),
287 extensions::EventRouter::Get(current_browser()->profile())
288 ->AddEventListener(downloads::OnErased::kEventName,
289 tab->GetRenderProcessHost(),
293 content::RenderProcessHost* AddFilenameDeterminer() {
294 ExtensionDownloadsEventRouter::SetDetermineFilenameTimeoutSecondsForTesting(
296 content::WebContents* tab = chrome::AddSelectedTabWithURL(
298 extension_->GetResourceURL("empty.html"),
299 content::PAGE_TRANSITION_LINK);
300 extensions::ExtensionSystem::Get(current_browser()->profile())
302 ->AddEventListener(downloads::OnDeterminingFilename::kEventName,
303 tab->GetRenderProcessHost(),
305 return tab->GetRenderProcessHost();
308 void RemoveFilenameDeterminer(content::RenderProcessHost* host) {
309 extensions::ExtensionSystem::Get(current_browser()->profile())
311 ->RemoveEventListener(downloads::OnDeterminingFilename::kEventName,
316 Browser* current_browser() { return current_browser_; }
318 // InProcessBrowserTest
319 virtual void SetUpOnMainThread() OVERRIDE {
320 ExtensionApiTest::SetUpOnMainThread();
321 BrowserThread::PostTask(
322 BrowserThread::IO, FROM_HERE,
323 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
324 InProcessBrowserTest::SetUpOnMainThread();
326 CreateAndSetDownloadsDirectory();
327 current_browser()->profile()->GetPrefs()->SetBoolean(
328 prefs::kPromptForDownload, false);
329 GetOnRecordManager()->RemoveAllDownloads();
330 events_listener_.reset(new DownloadsEventsListener());
331 // Disable file chooser for current profile.
332 DownloadTestFileActivityObserver observer(current_browser()->profile());
333 observer.EnableFileChooser(false);
336 void GoOnTheRecord() { current_browser_ = browser(); }
338 void GoOffTheRecord() {
339 if (!incognito_browser_) {
340 incognito_browser_ = CreateIncognitoBrowser();
341 GetOffRecordManager()->RemoveAllDownloads();
342 // Disable file chooser for incognito profile.
343 DownloadTestFileActivityObserver observer(incognito_browser_->profile());
344 observer.EnableFileChooser(false);
346 current_browser_ = incognito_browser_;
349 bool WaitFor(const std::string& event_name, const std::string& json_args) {
350 return events_listener_->WaitFor(
351 current_browser()->profile(), event_name, json_args);
354 bool WaitForInterruption(
356 content::DownloadInterruptReason expected_error,
357 const std::string& on_created_event) {
358 if (!WaitFor(downloads::OnCreated::kEventName, on_created_event))
360 // Now, onCreated is always fired before interruption.
362 downloads::OnChanged::kEventName,
365 " \"error\": {\"current\": \"%s\"},"
367 " \"previous\": \"in_progress\","
368 " \"current\": \"interrupted\"}}]",
370 content::DownloadInterruptReasonToString(expected_error).c_str()));
374 events_listener_->ClearEvents();
377 std::string GetExtensionURL() {
378 return extension_->url().spec();
380 std::string GetExtensionId() {
381 return extension_->id();
384 std::string GetFilename(const char* path) {
386 downloads_directory_.path().AppendASCII(path).AsUTF8Unsafe();
388 for (std::string::size_type next = result.find("\\");
389 next != std::string::npos;
390 next = result.find("\\", next)) {
391 result.replace(next, 1, "\\\\");
398 DownloadManager* GetOnRecordManager() {
399 return BrowserContext::GetDownloadManager(browser()->profile());
401 DownloadManager* GetOffRecordManager() {
402 return BrowserContext::GetDownloadManager(
403 browser()->profile()->GetOffTheRecordProfile());
405 DownloadManager* GetCurrentManager() {
406 return (current_browser_ == incognito_browser_) ?
407 GetOffRecordManager() : GetOnRecordManager();
410 // Creates a set of history downloads based on the provided |history_info|
411 // array. |count| is the number of elements in |history_info|. On success,
412 // |items| will contain |count| DownloadItems in the order that they were
413 // specified in |history_info|. Returns true on success and false otherwise.
414 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info,
416 DownloadManager::DownloadVector* items) {
417 DownloadIdComparator download_id_comparator;
418 base::Time current = base::Time::Now();
420 GetOnRecordManager()->GetAllDownloads(items);
421 CHECK_EQ(0, static_cast<int>(items->size()));
422 std::vector<GURL> url_chain;
423 url_chain.push_back(GURL());
424 for (size_t i = 0; i < count; ++i) {
425 DownloadItem* item = GetOnRecordManager()->CreateDownloadItem(
426 content::DownloadItem::kInvalidId + 1 + i,
427 downloads_directory().Append(history_info[i].filename),
428 downloads_directory().Append(history_info[i].filename),
429 url_chain, GURL(), // URL Chain, referrer
430 current, current, // start_time, end_time
431 std::string(), std::string(), // etag, last_modified
432 1, 1, // received_bytes, total_bytes
433 history_info[i].state, // state
434 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
435 content::DOWNLOAD_INTERRUPT_REASON_NONE,
437 items->push_back(item);
440 // Order by ID so that they are in the order that we created them.
441 std::sort(items->begin(), items->end(), download_id_comparator);
442 // Set the danger type if necessary.
443 for (size_t i = 0; i < count; ++i) {
444 if (history_info[i].danger_type !=
445 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
446 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT,
447 history_info[i].danger_type);
448 items->at(i)->OnContentCheckCompleted(history_info[i].danger_type);
454 void CreateSlowTestDownloads(
455 size_t count, DownloadManager::DownloadVector* items) {
456 for (size_t i = 0; i < count; ++i) {
457 scoped_ptr<content::DownloadTestObserver> observer(
458 CreateInProgressDownloadObserver(1));
459 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
460 ui_test_utils::NavigateToURLWithDisposition(
461 current_browser(), slow_download_url, CURRENT_TAB,
462 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
463 observer->WaitForFinished();
465 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
467 GetCurrentManager()->GetAllDownloads(items);
468 ASSERT_EQ(count, items->size());
471 DownloadItem* CreateSlowTestDownload() {
472 scoped_ptr<content::DownloadTestObserver> observer(
473 CreateInProgressDownloadObserver(1));
474 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
475 DownloadManager* manager = GetCurrentManager();
477 EXPECT_EQ(0, manager->NonMaliciousInProgressCount());
478 EXPECT_EQ(0, manager->InProgressCount());
479 if (manager->InProgressCount() != 0)
482 ui_test_utils::NavigateToURLWithDisposition(
483 current_browser(), slow_download_url, CURRENT_TAB,
484 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
486 observer->WaitForFinished();
487 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
489 DownloadManager::DownloadVector items;
490 manager->GetAllDownloads(&items);
492 DownloadItem* new_item = NULL;
493 for (DownloadManager::DownloadVector::iterator iter = items.begin();
494 iter != items.end(); ++iter) {
495 if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) {
496 // There should be only one IN_PROGRESS item.
497 EXPECT_EQ(NULL, new_item);
504 void FinishPendingSlowDownloads() {
505 scoped_ptr<content::DownloadTestObserver> observer(
506 CreateDownloadObserver(1));
507 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl);
508 ui_test_utils::NavigateToURLWithDisposition(
509 current_browser(), finish_url, NEW_FOREGROUND_TAB,
510 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
511 observer->WaitForFinished();
512 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
515 content::DownloadTestObserver* CreateDownloadObserver(size_t download_count) {
516 return new content::DownloadTestObserverTerminal(
517 GetCurrentManager(), download_count,
518 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
521 content::DownloadTestObserver* CreateInProgressDownloadObserver(
522 size_t download_count) {
523 return new content::DownloadTestObserverInProgress(
524 GetCurrentManager(), download_count);
527 bool RunFunction(UIThreadExtensionFunction* function,
528 const std::string& args) {
529 scoped_refptr<UIThreadExtensionFunction> delete_function(function);
530 SetUpExtensionFunction(function);
531 bool result = extension_function_test_utils::RunFunction(
532 function, args, browser(), GetFlags());
534 LOG(ERROR) << function->GetError();
539 extension_function_test_utils::RunFunctionFlags GetFlags() {
540 return current_browser()->profile()->IsOffTheRecord() ?
541 extension_function_test_utils::INCLUDE_INCOGNITO :
542 extension_function_test_utils::NONE;
545 // extension_function_test_utils::RunFunction*() only uses browser for its
546 // profile(), so pass it the on-record browser so that it always uses the
547 // on-record profile to match real-life behavior.
549 base::Value* RunFunctionAndReturnResult(
550 scoped_refptr<UIThreadExtensionFunction> function,
551 const std::string& args) {
552 SetUpExtensionFunction(function.get());
553 return extension_function_test_utils::RunFunctionAndReturnSingleResult(
554 function.get(), args, browser(), GetFlags());
557 std::string RunFunctionAndReturnError(
558 scoped_refptr<UIThreadExtensionFunction> function,
559 const std::string& args) {
560 SetUpExtensionFunction(function.get());
561 return extension_function_test_utils::RunFunctionAndReturnError(
562 function.get(), args, browser(), GetFlags());
565 bool RunFunctionAndReturnString(
566 scoped_refptr<UIThreadExtensionFunction> function,
567 const std::string& args,
568 std::string* result_string) {
569 SetUpExtensionFunction(function.get());
570 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args));
571 EXPECT_TRUE(result.get());
572 return result.get() && result->GetAsString(result_string);
575 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) {
576 return base::StringPrintf("[%d]", download_item->GetId());
579 const base::FilePath& downloads_directory() {
580 return downloads_directory_.path();
583 DownloadsEventsListener* events_listener() { return events_listener_.get(); }
586 void SetUpExtensionFunction(UIThreadExtensionFunction* function) {
588 // Recreate the tab each time for insulation.
589 content::WebContents* tab = chrome::AddSelectedTabWithURL(
591 extension_->GetResourceURL("empty.html"),
592 content::PAGE_TRANSITION_LINK);
593 function->set_extension(extension_);
594 function->SetRenderViewHost(tab->GetRenderViewHost());
598 void CreateAndSetDownloadsDirectory() {
599 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
600 current_browser()->profile()->GetPrefs()->SetFilePath(
601 prefs::kDownloadDefaultDirectory,
602 downloads_directory_.path());
605 base::ScopedTempDir downloads_directory_;
606 const extensions::Extension* extension_;
607 Browser* incognito_browser_;
608 Browser* current_browser_;
609 scoped_ptr<DownloadsEventsListener> events_listener_;
611 DISALLOW_COPY_AND_ASSIGN(DownloadExtensionTest);
614 class MockIconExtractorImpl : public DownloadFileIconExtractor {
616 MockIconExtractorImpl(const base::FilePath& path,
617 IconLoader::IconSize icon_size,
618 const std::string& response)
619 : expected_path_(path),
620 expected_icon_size_(icon_size),
621 response_(response) {
623 virtual ~MockIconExtractorImpl() {}
625 virtual bool ExtractIconURLForPath(const base::FilePath& path,
627 IconLoader::IconSize icon_size,
628 IconURLCallback callback) OVERRIDE {
629 EXPECT_STREQ(expected_path_.value().c_str(), path.value().c_str());
630 EXPECT_EQ(expected_icon_size_, icon_size);
631 if (expected_path_ == path &&
632 expected_icon_size_ == icon_size) {
633 callback_ = callback;
634 BrowserThread::PostTask(
635 BrowserThread::UI, FROM_HERE,
636 base::Bind(&MockIconExtractorImpl::RunCallback,
637 base::Unretained(this)));
646 callback_.Run(response_);
647 // Drop the reference on extension function to avoid memory leaks.
648 callback_ = IconURLCallback();
651 base::FilePath expected_path_;
652 IconLoader::IconSize expected_icon_size_;
653 std::string response_;
654 IconURLCallback callback_;
657 bool ItemNotInProgress(DownloadItem* item) {
658 return item->GetState() != DownloadItem::IN_PROGRESS;
661 // Cancels the underlying DownloadItem when the ScopedCancellingItem goes out of
662 // scope. Like a scoped_ptr, but for DownloadItems.
663 class ScopedCancellingItem {
665 explicit ScopedCancellingItem(DownloadItem* item) : item_(item) {}
666 ~ScopedCancellingItem() {
668 content::DownloadUpdatedObserver observer(
669 item_, base::Bind(&ItemNotInProgress));
670 observer.WaitForEvent();
672 DownloadItem* get() { return item_; }
675 DISALLOW_COPY_AND_ASSIGN(ScopedCancellingItem);
678 // Cancels all the underlying DownloadItems when the ScopedItemVectorCanceller
679 // goes out of scope. Generalization of ScopedCancellingItem to many
681 class ScopedItemVectorCanceller {
683 explicit ScopedItemVectorCanceller(DownloadManager::DownloadVector* items)
686 ~ScopedItemVectorCanceller() {
687 for (DownloadManager::DownloadVector::const_iterator item = items_->begin();
688 item != items_->end(); ++item) {
689 if ((*item)->GetState() == DownloadItem::IN_PROGRESS)
690 (*item)->Cancel(true);
691 content::DownloadUpdatedObserver observer(
692 (*item), base::Bind(&ItemNotInProgress));
693 observer.WaitForEvent();
698 DownloadManager::DownloadVector* items_;
699 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller);
702 // Writes an HTML5 file so that it can be downloaded.
703 class HTML5FileWriter {
705 static bool CreateFileForTesting(fileapi::FileSystemContext* context,
706 const fileapi::FileSystemURL& path,
709 // Create a temp file.
710 base::FilePath temp_file;
711 if (!base::CreateTemporaryFile(&temp_file) ||
712 base::WriteFile(temp_file, data, length) != length) {
715 // Invoke the fileapi to copy it into the sandboxed filesystem.
717 base::WaitableEvent done_event(true, false);
718 BrowserThread::PostTask(
719 BrowserThread::IO, FROM_HERE,
720 base::Bind(&CreateFileForTestingOnIOThread,
721 base::Unretained(context),
723 base::Unretained(&result),
724 base::Unretained(&done_event)));
725 // Wait for that to finish.
727 base::DeleteFile(temp_file, false);
732 static void CopyInCompletion(bool* result,
733 base::WaitableEvent* done_event,
734 base::File::Error error) {
735 DCHECK_CURRENTLY_ON(BrowserThread::IO);
736 *result = error == base::File::FILE_OK;
737 done_event->Signal();
740 static void CreateFileForTestingOnIOThread(
741 fileapi::FileSystemContext* context,
742 const fileapi::FileSystemURL& path,
743 const base::FilePath& temp_file,
745 base::WaitableEvent* done_event) {
746 DCHECK_CURRENTLY_ON(BrowserThread::IO);
747 context->operation_runner()->CopyInForeignFile(
749 base::Bind(&CopyInCompletion,
750 base::Unretained(result),
751 base::Unretained(done_event)));
755 // TODO(benjhayden) Merge this with the other TestObservers.
756 class JustInProgressDownloadObserver
757 : public content::DownloadTestObserverInProgress {
759 JustInProgressDownloadObserver(
760 DownloadManager* download_manager, size_t wait_count)
761 : content::DownloadTestObserverInProgress(download_manager, wait_count) {
764 virtual ~JustInProgressDownloadObserver() {}
767 virtual bool IsDownloadInFinalState(DownloadItem* item) OVERRIDE {
768 return item->GetState() == DownloadItem::IN_PROGRESS;
771 DISALLOW_COPY_AND_ASSIGN(JustInProgressDownloadObserver);
774 bool ItemIsInterrupted(DownloadItem* item) {
775 return item->GetState() == DownloadItem::INTERRUPTED;
778 content::DownloadInterruptReason InterruptReasonExtensionToContent(
779 downloads::InterruptReason error) {
781 case downloads::INTERRUPT_REASON_NONE:
782 return content::DOWNLOAD_INTERRUPT_REASON_NONE;
783 #define INTERRUPT_REASON(name, value) \
784 case downloads::INTERRUPT_REASON_##name: \
785 return content::DOWNLOAD_INTERRUPT_REASON_##name;
786 #include "content/public/browser/download_interrupt_reason_values.h"
787 #undef INTERRUPT_REASON
790 return content::DOWNLOAD_INTERRUPT_REASON_NONE;
793 downloads::InterruptReason InterruptReasonContentToExtension(
794 content::DownloadInterruptReason error) {
796 case content::DOWNLOAD_INTERRUPT_REASON_NONE:
797 return downloads::INTERRUPT_REASON_NONE;
798 #define INTERRUPT_REASON(name, value) \
799 case content::DOWNLOAD_INTERRUPT_REASON_##name: \
800 return downloads::INTERRUPT_REASON_##name;
801 #include "content/public/browser/download_interrupt_reason_values.h"
802 #undef INTERRUPT_REASON
805 return downloads::INTERRUPT_REASON_NONE;
810 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
811 DownloadExtensionTest_Open) {
812 LoadExtension("downloads_split");
813 DownloadsOpenFunction* open_function = new DownloadsOpenFunction();
814 open_function->set_user_gesture(true);
815 EXPECT_STREQ(errors::kInvalidId,
816 RunFunctionAndReturnError(
820 DownloadItem* download_item = CreateSlowTestDownload();
821 ASSERT_TRUE(download_item);
822 EXPECT_FALSE(download_item->GetOpened());
823 EXPECT_FALSE(download_item->GetOpenWhenComplete());
824 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
826 "[{\"danger\": \"safe\","
827 " \"incognito\": false,"
828 " \"mime\": \"application/octet-stream\","
829 " \"paused\": false,"
830 " \"url\": \"%s\"}]",
831 download_item->GetURL().spec().c_str())));
832 open_function = new DownloadsOpenFunction();
833 open_function->set_user_gesture(true);
834 EXPECT_STREQ(errors::kNotComplete,
835 RunFunctionAndReturnError(
837 DownloadItemIdAsArgList(download_item)).c_str());
839 FinishPendingSlowDownloads();
840 EXPECT_FALSE(download_item->GetOpened());
842 open_function = new DownloadsOpenFunction();
843 EXPECT_STREQ(errors::kUserGesture,
844 RunFunctionAndReturnError(
846 DownloadItemIdAsArgList(download_item)).c_str());
847 EXPECT_FALSE(download_item->GetOpened());
849 open_function = new DownloadsOpenFunction();
850 open_function->set_user_gesture(true);
851 EXPECT_TRUE(RunFunction(open_function,
852 DownloadItemIdAsArgList(download_item)));
853 EXPECT_TRUE(download_item->GetOpened());
856 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
857 DownloadExtensionTest_PauseResumeCancelErase) {
858 DownloadItem* download_item = CreateSlowTestDownload();
859 ASSERT_TRUE(download_item);
862 // Call pause(). It should succeed and the download should be paused on
864 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
865 DownloadItemIdAsArgList(download_item)));
866 EXPECT_TRUE(download_item->IsPaused());
868 // Calling removeFile on a non-active download yields kNotComplete
869 // and should not crash. http://crbug.com/319984
870 error = RunFunctionAndReturnError(new DownloadsRemoveFileFunction(),
871 DownloadItemIdAsArgList(download_item));
872 EXPECT_STREQ(errors::kNotComplete, error.c_str());
874 // Calling pause() twice shouldn't be an error.
875 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
876 DownloadItemIdAsArgList(download_item)));
877 EXPECT_TRUE(download_item->IsPaused());
879 // Now try resuming this download. It should succeed.
880 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
881 DownloadItemIdAsArgList(download_item)));
882 EXPECT_FALSE(download_item->IsPaused());
884 // Resume again. Resuming a download that wasn't paused is not an error.
885 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
886 DownloadItemIdAsArgList(download_item)));
887 EXPECT_FALSE(download_item->IsPaused());
890 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
891 DownloadItemIdAsArgList(download_item)));
892 EXPECT_TRUE(download_item->IsPaused());
895 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
896 DownloadItemIdAsArgList(download_item)));
897 EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());
899 // Cancel again. Shouldn't have any effect.
900 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
901 DownloadItemIdAsArgList(download_item)));
902 EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());
904 // Calling paused on a non-active download yields kNotInProgress.
905 error = RunFunctionAndReturnError(
906 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item));
907 EXPECT_STREQ(errors::kNotInProgress, error.c_str());
909 // Calling resume on a non-active download yields kNotResumable
910 error = RunFunctionAndReturnError(
911 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item));
912 EXPECT_STREQ(errors::kNotResumable, error.c_str());
914 // Calling pause on a non-existent download yields kInvalidId.
915 error = RunFunctionAndReturnError(
916 new DownloadsPauseFunction(), "[-42]");
917 EXPECT_STREQ(errors::kInvalidId, error.c_str());
919 // Calling resume on a non-existent download yields kInvalidId
920 error = RunFunctionAndReturnError(
921 new DownloadsResumeFunction(), "[-42]");
922 EXPECT_STREQ(errors::kInvalidId, error.c_str());
924 // Calling removeFile on a non-existent download yields kInvalidId.
925 error = RunFunctionAndReturnError(
926 new DownloadsRemoveFileFunction(), "[-42]");
927 EXPECT_STREQ(errors::kInvalidId, error.c_str());
929 int id = download_item->GetId();
930 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
931 new DownloadsEraseFunction(),
932 base::StringPrintf("[{\"id\": %d}]", id)));
933 DownloadManager::DownloadVector items;
934 GetCurrentManager()->GetAllDownloads(&items);
935 EXPECT_EQ(0UL, items.size());
937 download_item = NULL;
938 base::ListValue* result_list = NULL;
939 ASSERT_TRUE(result->GetAsList(&result_list));
940 ASSERT_EQ(1UL, result_list->GetSize());
942 ASSERT_TRUE(result_list->GetInteger(0, &element));
943 EXPECT_EQ(id, element);
946 scoped_refptr<UIThreadExtensionFunction> MockedGetFileIconFunction(
947 const base::FilePath& expected_path,
948 IconLoader::IconSize icon_size,
949 const std::string& response) {
950 scoped_refptr<DownloadsGetFileIconFunction> function(
951 new DownloadsGetFileIconFunction());
952 function->SetIconExtractorForTesting(new MockIconExtractorImpl(
953 expected_path, icon_size, response));
957 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted
959 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
960 DownloadExtensionTest_FileIcon_Active) {
961 DownloadItem* download_item = CreateSlowTestDownload();
962 ASSERT_TRUE(download_item);
963 ASSERT_FALSE(download_item->GetTargetFilePath().empty());
964 std::string args32(base::StringPrintf("[%d, {\"size\": 32}]",
965 download_item->GetId()));
966 std::string result_string;
968 // Get the icon for the in-progress download. This call should succeed even
969 // if the file type isn't registered.
970 // Test whether the correct path is being pased into the icon extractor.
971 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
972 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
973 base::StringPrintf("[%d, {}]", download_item->GetId()), &result_string));
975 // Now try a 16x16 icon.
976 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
977 download_item->GetTargetFilePath(), IconLoader::SMALL, "foo"),
978 base::StringPrintf("[%d, {\"size\": 16}]", download_item->GetId()),
981 // Explicitly asking for 32x32 should give us a 32x32 icon.
982 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
983 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
984 args32, &result_string));
986 // Finish the download and try again.
987 FinishPendingSlowDownloads();
988 EXPECT_EQ(DownloadItem::COMPLETE, download_item->GetState());
989 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
990 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
991 args32, &result_string));
993 // Check the path passed to the icon extractor post-completion.
994 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
995 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
996 args32, &result_string));
998 // Now create another download.
999 download_item = CreateSlowTestDownload();
1000 ASSERT_TRUE(download_item);
1001 ASSERT_FALSE(download_item->GetTargetFilePath().empty());
1002 args32 = base::StringPrintf("[%d, {\"size\": 32}]", download_item->GetId());
1004 // Cancel the download. As long as the download has a target path, we should
1005 // be able to query the file icon.
1006 download_item->Cancel(true);
1007 ASSERT_FALSE(download_item->GetTargetFilePath().empty());
1008 // Let cleanup complete on the FILE thread.
1009 content::RunAllPendingInMessageLoop(BrowserThread::FILE);
1010 // Check the path passed to the icon extractor post-cancellation.
1011 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1012 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
1016 // Simulate an error during icon load by invoking the mock with an empty
1018 std::string error = RunFunctionAndReturnError(
1019 MockedGetFileIconFunction(download_item->GetTargetFilePath(),
1023 EXPECT_STREQ(errors::kIconNotFound, error.c_str());
1025 // Once the download item is deleted, we should return kInvalidId.
1026 int id = download_item->GetId();
1027 download_item->Remove();
1028 download_item = NULL;
1029 EXPECT_EQ(static_cast<DownloadItem*>(NULL),
1030 GetCurrentManager()->GetDownload(id));
1031 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args32);
1032 EXPECT_STREQ(errors::kInvalidId,
1036 // Test that we can acquire file icons for history downloads regardless of
1037 // whether they exist or not. If the file doesn't exist we should receive a
1038 // generic icon from the OS/toolkit that may or may not be specific to the file
1040 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1041 DownloadExtensionTest_FileIcon_History) {
1042 const HistoryDownloadInfo kHistoryInfo[] = {
1043 { FILE_PATH_LITERAL("real.txt"),
1044 DownloadItem::COMPLETE,
1045 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1046 { FILE_PATH_LITERAL("fake.txt"),
1047 DownloadItem::COMPLETE,
1048 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1050 DownloadManager::DownloadVector all_downloads;
1051 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1054 base::FilePath real_path = all_downloads[0]->GetTargetFilePath();
1055 base::FilePath fake_path = all_downloads[1]->GetTargetFilePath();
1057 EXPECT_EQ(0, base::WriteFile(real_path, "", 0));
1058 ASSERT_TRUE(base::PathExists(real_path));
1059 ASSERT_FALSE(base::PathExists(fake_path));
1061 for (DownloadManager::DownloadVector::iterator iter = all_downloads.begin();
1062 iter != all_downloads.end();
1064 std::string result_string;
1065 // Use a MockIconExtractorImpl to test if the correct path is being passed
1066 // into the DownloadFileIconExtractor.
1067 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1068 (*iter)->GetTargetFilePath(), IconLoader::NORMAL, "hello"),
1069 base::StringPrintf("[%d, {\"size\": 32}]", (*iter)->GetId()),
1071 EXPECT_STREQ("hello", result_string.c_str());
1075 // Test passing the empty query to search().
1076 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1077 DownloadExtensionTest_SearchEmptyQuery) {
1078 ScopedCancellingItem item(CreateSlowTestDownload());
1079 ASSERT_TRUE(item.get());
1081 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1082 new DownloadsSearchFunction(), "[{}]"));
1083 ASSERT_TRUE(result.get());
1084 base::ListValue* result_list = NULL;
1085 ASSERT_TRUE(result->GetAsList(&result_list));
1086 ASSERT_EQ(1UL, result_list->GetSize());
1089 // Test the |filenameRegex| parameter for search().
1090 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1091 DownloadExtensionTest_SearchFilenameRegex) {
1092 const HistoryDownloadInfo kHistoryInfo[] = {
1093 { FILE_PATH_LITERAL("foobar"),
1094 DownloadItem::COMPLETE,
1095 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1096 { FILE_PATH_LITERAL("baz"),
1097 DownloadItem::COMPLETE,
1098 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1100 DownloadManager::DownloadVector all_downloads;
1101 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1104 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1105 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]"));
1106 ASSERT_TRUE(result.get());
1107 base::ListValue* result_list = NULL;
1108 ASSERT_TRUE(result->GetAsList(&result_list));
1109 ASSERT_EQ(1UL, result_list->GetSize());
1110 base::DictionaryValue* item_value = NULL;
1111 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
1113 ASSERT_TRUE(item_value->GetInteger("id", &item_id));
1114 ASSERT_EQ(all_downloads[0]->GetId(), static_cast<uint32>(item_id));
1117 // Test the |id| parameter for search().
1118 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_SearchId) {
1119 DownloadManager::DownloadVector items;
1120 CreateSlowTestDownloads(2, &items);
1121 ScopedItemVectorCanceller delete_items(&items);
1123 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1124 new DownloadsSearchFunction(), base::StringPrintf(
1125 "[{\"id\": %u}]", items[0]->GetId())));
1126 ASSERT_TRUE(result.get());
1127 base::ListValue* result_list = NULL;
1128 ASSERT_TRUE(result->GetAsList(&result_list));
1129 ASSERT_EQ(1UL, result_list->GetSize());
1130 base::DictionaryValue* item_value = NULL;
1131 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
1133 ASSERT_TRUE(item_value->GetInteger("id", &item_id));
1134 ASSERT_EQ(items[0]->GetId(), static_cast<uint32>(item_id));
1137 // Test specifying both the |id| and |filename| parameters for search().
1138 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1139 DownloadExtensionTest_SearchIdAndFilename) {
1140 DownloadManager::DownloadVector items;
1141 CreateSlowTestDownloads(2, &items);
1142 ScopedItemVectorCanceller delete_items(&items);
1144 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1145 new DownloadsSearchFunction(),
1146 "[{\"id\": 0, \"filename\": \"foobar\"}]"));
1147 ASSERT_TRUE(result.get());
1148 base::ListValue* result_list = NULL;
1149 ASSERT_TRUE(result->GetAsList(&result_list));
1150 ASSERT_EQ(0UL, result_list->GetSize());
1153 // Test a single |orderBy| parameter for search().
1154 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1155 DownloadExtensionTest_SearchOrderBy) {
1156 const HistoryDownloadInfo kHistoryInfo[] = {
1157 { FILE_PATH_LITERAL("zzz"),
1158 DownloadItem::COMPLETE,
1159 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1160 { FILE_PATH_LITERAL("baz"),
1161 DownloadItem::COMPLETE,
1162 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1164 DownloadManager::DownloadVector items;
1165 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1168 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1169 new DownloadsSearchFunction(), "[{\"orderBy\": [\"filename\"]}]"));
1170 ASSERT_TRUE(result.get());
1171 base::ListValue* result_list = NULL;
1172 ASSERT_TRUE(result->GetAsList(&result_list));
1173 ASSERT_EQ(2UL, result_list->GetSize());
1174 base::DictionaryValue* item0_value = NULL;
1175 base::DictionaryValue* item1_value = NULL;
1176 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value));
1177 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value));
1178 std::string item0_name, item1_name;
1179 ASSERT_TRUE(item0_value->GetString("filename", &item0_name));
1180 ASSERT_TRUE(item1_value->GetString("filename", &item1_name));
1181 ASSERT_GT(items[0]->GetTargetFilePath().value(),
1182 items[1]->GetTargetFilePath().value());
1183 ASSERT_LT(item0_name, item1_name);
1186 // Test specifying an empty |orderBy| parameter for search().
1187 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1188 DownloadExtensionTest_SearchOrderByEmpty) {
1189 const HistoryDownloadInfo kHistoryInfo[] = {
1190 { FILE_PATH_LITERAL("zzz"),
1191 DownloadItem::COMPLETE,
1192 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1193 { FILE_PATH_LITERAL("baz"),
1194 DownloadItem::COMPLETE,
1195 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1197 DownloadManager::DownloadVector items;
1198 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1201 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1202 new DownloadsSearchFunction(), "[{\"orderBy\": []}]"));
1203 ASSERT_TRUE(result.get());
1204 base::ListValue* result_list = NULL;
1205 ASSERT_TRUE(result->GetAsList(&result_list));
1206 ASSERT_EQ(2UL, result_list->GetSize());
1207 base::DictionaryValue* item0_value = NULL;
1208 base::DictionaryValue* item1_value = NULL;
1209 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value));
1210 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value));
1211 std::string item0_name, item1_name;
1212 ASSERT_TRUE(item0_value->GetString("filename", &item0_name));
1213 ASSERT_TRUE(item1_value->GetString("filename", &item1_name));
1214 ASSERT_GT(items[0]->GetTargetFilePath().value(),
1215 items[1]->GetTargetFilePath().value());
1216 // The order of results when orderBy is empty is unspecified. When there are
1217 // no sorters, DownloadQuery does not call sort(), so the order of the results
1218 // depends on the order of the items in base::hash_map<uint32,...>
1219 // DownloadManagerImpl::downloads_, which is unspecified and differs between
1220 // libc++ and libstdc++. http://crbug.com/365334
1223 // Test the |danger| option for search().
1224 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1225 DownloadExtensionTest_SearchDanger) {
1226 const HistoryDownloadInfo kHistoryInfo[] = {
1227 { FILE_PATH_LITERAL("zzz"),
1228 DownloadItem::COMPLETE,
1229 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
1230 { FILE_PATH_LITERAL("baz"),
1231 DownloadItem::COMPLETE,
1232 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1234 DownloadManager::DownloadVector items;
1235 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1238 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1239 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]"));
1240 ASSERT_TRUE(result.get());
1241 base::ListValue* result_list = NULL;
1242 ASSERT_TRUE(result->GetAsList(&result_list));
1243 ASSERT_EQ(1UL, result_list->GetSize());
1246 // Test the |state| option for search().
1247 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1248 DownloadExtensionTest_SearchState) {
1249 DownloadManager::DownloadVector items;
1250 CreateSlowTestDownloads(2, &items);
1251 ScopedItemVectorCanceller delete_items(&items);
1253 items[0]->Cancel(true);
1255 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1256 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]"));
1257 ASSERT_TRUE(result.get());
1258 base::ListValue* result_list = NULL;
1259 ASSERT_TRUE(result->GetAsList(&result_list));
1260 ASSERT_EQ(1UL, result_list->GetSize());
1263 // Test the |limit| option for search().
1264 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1265 DownloadExtensionTest_SearchLimit) {
1266 DownloadManager::DownloadVector items;
1267 CreateSlowTestDownloads(2, &items);
1268 ScopedItemVectorCanceller delete_items(&items);
1270 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1271 new DownloadsSearchFunction(), "[{\"limit\": 1}]"));
1272 ASSERT_TRUE(result.get());
1273 base::ListValue* result_list = NULL;
1274 ASSERT_TRUE(result->GetAsList(&result_list));
1275 ASSERT_EQ(1UL, result_list->GetSize());
1278 // Test invalid search parameters.
1279 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1280 DownloadExtensionTest_SearchInvalid) {
1281 std::string error = RunFunctionAndReturnError(
1282 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]");
1283 EXPECT_STREQ(errors::kInvalidFilter,
1285 error = RunFunctionAndReturnError(
1286 new DownloadsSearchFunction(), "[{\"orderBy\": [\"goat\"]}]");
1287 EXPECT_STREQ(errors::kInvalidOrderBy,
1289 error = RunFunctionAndReturnError(
1290 new DownloadsSearchFunction(), "[{\"limit\": -1}]");
1291 EXPECT_STREQ(errors::kInvalidQueryLimit,
1295 // Test searching using multiple conditions through multiple downloads.
1296 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1297 DownloadExtensionTest_SearchPlural) {
1298 const HistoryDownloadInfo kHistoryInfo[] = {
1299 { FILE_PATH_LITERAL("aaa"),
1300 DownloadItem::CANCELLED,
1301 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1302 { FILE_PATH_LITERAL("zzz"),
1303 DownloadItem::COMPLETE,
1304 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
1305 { FILE_PATH_LITERAL("baz"),
1306 DownloadItem::COMPLETE,
1307 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
1309 DownloadManager::DownloadVector items;
1310 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1313 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1314 new DownloadsSearchFunction(), "[{"
1315 "\"state\": \"complete\", "
1316 "\"danger\": \"content\", "
1317 "\"orderBy\": [\"filename\"], "
1319 ASSERT_TRUE(result.get());
1320 base::ListValue* result_list = NULL;
1321 ASSERT_TRUE(result->GetAsList(&result_list));
1322 ASSERT_EQ(1UL, result_list->GetSize());
1323 base::DictionaryValue* item_value = NULL;
1324 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
1325 base::FilePath::StringType item_name;
1326 ASSERT_TRUE(item_value->GetString("filename", &item_name));
1327 ASSERT_EQ(items[2]->GetTargetFilePath().value(), item_name);
1330 // Test that incognito downloads are only visible in incognito contexts, and
1331 // test that on-record downloads are visible in both incognito and on-record
1332 // contexts, for DownloadsSearchFunction, DownloadsPauseFunction,
1333 // DownloadsResumeFunction, and DownloadsCancelFunction.
1334 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1335 DownloadExtensionTest_SearchPauseResumeCancelGetFileIconIncognito) {
1336 scoped_ptr<base::Value> result_value;
1337 base::ListValue* result_list = NULL;
1338 base::DictionaryValue* result_dict = NULL;
1339 base::FilePath::StringType filename;
1340 bool is_incognito = false;
1342 std::string on_item_arg;
1343 std::string off_item_arg;
1344 std::string result_string;
1346 // Set up one on-record item and one off-record item.
1347 // Set up the off-record item first because otherwise there are mysteriously 3
1348 // items total instead of 2.
1349 // TODO(benjhayden): Figure out where the third item comes from.
1351 DownloadItem* off_item = CreateSlowTestDownload();
1352 ASSERT_TRUE(off_item);
1353 off_item_arg = DownloadItemIdAsArgList(off_item);
1356 DownloadItem* on_item = CreateSlowTestDownload();
1357 ASSERT_TRUE(on_item);
1358 on_item_arg = DownloadItemIdAsArgList(on_item);
1359 ASSERT_TRUE(on_item->GetTargetFilePath() != off_item->GetTargetFilePath());
1361 // Extensions running in the incognito window should have access to both
1362 // items because the Test extension is in spanning mode.
1364 result_value.reset(RunFunctionAndReturnResult(
1365 new DownloadsSearchFunction(), "[{}]"));
1366 ASSERT_TRUE(result_value.get());
1367 ASSERT_TRUE(result_value->GetAsList(&result_list));
1368 ASSERT_EQ(2UL, result_list->GetSize());
1369 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict));
1370 ASSERT_TRUE(result_dict->GetString("filename", &filename));
1371 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
1372 EXPECT_TRUE(on_item->GetTargetFilePath() == base::FilePath(filename));
1373 EXPECT_FALSE(is_incognito);
1374 ASSERT_TRUE(result_list->GetDictionary(1, &result_dict));
1375 ASSERT_TRUE(result_dict->GetString("filename", &filename));
1376 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
1377 EXPECT_TRUE(off_item->GetTargetFilePath() == base::FilePath(filename));
1378 EXPECT_TRUE(is_incognito);
1380 // Extensions running in the on-record window should have access only to the
1383 result_value.reset(RunFunctionAndReturnResult(
1384 new DownloadsSearchFunction(), "[{}]"));
1385 ASSERT_TRUE(result_value.get());
1386 ASSERT_TRUE(result_value->GetAsList(&result_list));
1387 ASSERT_EQ(1UL, result_list->GetSize());
1388 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict));
1389 ASSERT_TRUE(result_dict->GetString("filename", &filename));
1390 EXPECT_TRUE(on_item->GetTargetFilePath() == base::FilePath(filename));
1391 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
1392 EXPECT_FALSE(is_incognito);
1394 // Pausing/Resuming the off-record item while on the record should return an
1395 // error. Cancelling "non-existent" downloads is not an error.
1396 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg);
1397 EXPECT_STREQ(errors::kInvalidId,
1399 error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
1401 EXPECT_STREQ(errors::kInvalidId,
1403 error = RunFunctionAndReturnError(
1404 new DownloadsGetFileIconFunction(),
1405 base::StringPrintf("[%d, {}]", off_item->GetId()));
1406 EXPECT_STREQ(errors::kInvalidId,
1411 // Do the FileIcon test for both the on- and off-items while off the record.
1412 // NOTE(benjhayden): This does not include the FileIcon test from history,
1413 // just active downloads. This shouldn't be a problem.
1414 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1415 on_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
1416 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string));
1417 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1418 off_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
1419 base::StringPrintf("[%d, {}]", off_item->GetId()), &result_string));
1421 // Do the pause/resume/cancel test for both the on- and off-items while off
1423 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
1424 EXPECT_TRUE(on_item->IsPaused());
1425 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
1426 EXPECT_TRUE(on_item->IsPaused());
1427 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg));
1428 EXPECT_FALSE(on_item->IsPaused());
1429 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg));
1430 EXPECT_FALSE(on_item->IsPaused());
1431 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
1432 EXPECT_TRUE(on_item->IsPaused());
1433 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg));
1434 EXPECT_EQ(DownloadItem::CANCELLED, on_item->GetState());
1435 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg));
1436 EXPECT_EQ(DownloadItem::CANCELLED, on_item->GetState());
1437 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), on_item_arg);
1438 EXPECT_STREQ(errors::kNotInProgress, error.c_str());
1439 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), on_item_arg);
1440 EXPECT_STREQ(errors::kNotResumable, error.c_str());
1441 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
1442 EXPECT_TRUE(off_item->IsPaused());
1443 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
1444 EXPECT_TRUE(off_item->IsPaused());
1445 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg));
1446 EXPECT_FALSE(off_item->IsPaused());
1447 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg));
1448 EXPECT_FALSE(off_item->IsPaused());
1449 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
1450 EXPECT_TRUE(off_item->IsPaused());
1451 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg));
1452 EXPECT_EQ(DownloadItem::CANCELLED, off_item->GetState());
1453 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg));
1454 EXPECT_EQ(DownloadItem::CANCELLED, off_item->GetState());
1455 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg);
1456 EXPECT_STREQ(errors::kNotInProgress, error.c_str());
1457 error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
1459 EXPECT_STREQ(errors::kNotResumable, error.c_str());
1462 // Test that we can start a download and that the correct sequence of events is
1464 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1465 DownloadExtensionTest_Download_Basic) {
1466 LoadExtension("downloads_split");
1467 ASSERT_TRUE(StartEmbeddedTestServer());
1468 ASSERT_TRUE(test_server()->Start());
1469 std::string download_url = test_server()->GetURL("slow?0").spec();
1472 // Start downloading a file.
1473 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1474 new DownloadsDownloadFunction(), base::StringPrintf(
1475 "[{\"url\": \"%s\"}]", download_url.c_str())));
1476 ASSERT_TRUE(result.get());
1478 ASSERT_TRUE(result->GetAsInteger(&result_id));
1479 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1481 ScopedCancellingItem canceller(item);
1482 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1484 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1486 "[{\"danger\": \"safe\","
1487 " \"incognito\": false,"
1488 " \"mime\": \"text/plain\","
1489 " \"paused\": false,"
1490 " \"url\": \"%s\"}]",
1491 download_url.c_str())));
1492 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1496 " \"previous\": \"\","
1497 " \"current\": \"%s\"}}]",
1499 GetFilename("slow.txt").c_str())));
1500 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1504 " \"previous\": \"in_progress\","
1505 " \"current\": \"complete\"}}]",
1509 // Test that we can start a download from an incognito context, and that the
1510 // download knows that it's incognito.
1511 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1512 DownloadExtensionTest_Download_Incognito) {
1513 LoadExtension("downloads_split");
1514 ASSERT_TRUE(StartEmbeddedTestServer());
1515 ASSERT_TRUE(test_server()->Start());
1517 std::string download_url = test_server()->GetURL("slow?0").spec();
1519 // Start downloading a file.
1520 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1521 new DownloadsDownloadFunction(), base::StringPrintf(
1522 "[{\"url\": \"%s\"}]", download_url.c_str())));
1523 ASSERT_TRUE(result.get());
1525 ASSERT_TRUE(result->GetAsInteger(&result_id));
1526 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1528 ScopedCancellingItem canceller(item);
1529 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1531 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1533 "[{\"danger\": \"safe\","
1534 " \"incognito\": true,"
1535 " \"mime\": \"text/plain\","
1536 " \"paused\": false,"
1537 " \"url\": \"%s\"}]",
1538 download_url.c_str())));
1539 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1543 " \"previous\": \"\","
1544 " \"current\": \"%s\"}}]",
1546 GetFilename("slow.txt").c_str())));
1547 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1551 " \"current\": \"complete\","
1552 " \"previous\": \"in_progress\"}}]",
1557 // This test is very flaky on Win. http://crbug.com/248438
1558 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1559 DISABLED_DownloadExtensionTest_Download_UnsafeHeaders
1561 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1562 DownloadExtensionTest_Download_UnsafeHeaders
1565 // Test that we disallow certain headers case-insensitively.
1566 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1567 MAYBE_DownloadExtensionTest_Download_UnsafeHeaders) {
1568 LoadExtension("downloads_split");
1569 ASSERT_TRUE(StartEmbeddedTestServer());
1570 ASSERT_TRUE(test_server()->Start());
1573 static const char* kUnsafeHeaders[] = {
1580 "coNteNt-traNsfer-eNcodiNg",
1588 "trANsfer-eNcodiNg",
1594 "pRoxY-probably-not-evil",
1595 "sEc-probably-not-evil",
1597 "Access-Control-Request-Headers",
1598 "Access-Control-Request-Method",
1601 for (size_t index = 0; index < arraysize(kUnsafeHeaders); ++index) {
1602 std::string download_url = test_server()->GetURL("slow?0").spec();
1603 EXPECT_STREQ(errors::kInvalidHeader,
1604 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1606 "[{\"url\": \"%s\","
1607 " \"filename\": \"unsafe-header-%d.txt\","
1609 " \"name\": \"%s\","
1610 " \"value\": \"unsafe\"}]}]",
1611 download_url.c_str(),
1612 static_cast<int>(index),
1613 kUnsafeHeaders[index])).c_str());
1618 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1619 DISABLED_DownloadExtensionTest_Download_Subdirectory
1621 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1622 DownloadExtensionTest_Download_Subdirectory
1624 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1625 MAYBE_DownloadExtensionTest_Download_Subdirectory) {
1626 LoadExtension("downloads_split");
1627 ASSERT_TRUE(StartEmbeddedTestServer());
1628 ASSERT_TRUE(test_server()->Start());
1629 std::string download_url = test_server()->GetURL("slow?0").spec();
1632 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1633 new DownloadsDownloadFunction(), base::StringPrintf(
1634 "[{\"url\": \"%s\","
1635 " \"filename\": \"sub/dir/ect/ory.txt\"}]",
1636 download_url.c_str())));
1637 ASSERT_TRUE(result.get());
1639 ASSERT_TRUE(result->GetAsInteger(&result_id));
1640 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1642 ScopedCancellingItem canceller(item);
1643 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1645 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1647 "[{\"danger\": \"safe\","
1648 " \"incognito\": false,"
1649 " \"mime\": \"text/plain\","
1650 " \"paused\": false,"
1651 " \"url\": \"%s\"}]",
1652 download_url.c_str())));
1653 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1657 " \"previous\": \"\","
1658 " \"current\": \"%s\"}}]",
1660 GetFilename("sub/dir/ect/ory.txt").c_str())));
1661 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1665 " \"previous\": \"in_progress\","
1666 " \"current\": \"complete\"}}]",
1670 // Test that invalid filenames are disallowed.
1671 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1672 DownloadExtensionTest_Download_InvalidFilename) {
1673 LoadExtension("downloads_split");
1674 ASSERT_TRUE(StartEmbeddedTestServer());
1675 ASSERT_TRUE(test_server()->Start());
1676 std::string download_url = test_server()->GetURL("slow?0").spec();
1679 EXPECT_STREQ(errors::kInvalidFilename,
1680 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1682 "[{\"url\": \"%s\","
1683 " \"filename\": \"../../../../../etc/passwd\"}]",
1684 download_url.c_str())).c_str());
1687 // Test that downloading invalid URLs immediately returns kInvalidURLError.
1688 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1689 DownloadExtensionTest_Download_InvalidURLs) {
1690 LoadExtension("downloads_split");
1693 static const char* kInvalidURLs[] = {
1699 "foo/bar.html#frag",
1703 for (size_t index = 0; index < arraysize(kInvalidURLs); ++index) {
1704 EXPECT_STREQ(errors::kInvalidURL,
1705 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1707 "[{\"url\": \"%s\"}]", kInvalidURLs[index])).c_str())
1708 << kInvalidURLs[index];
1711 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1712 new DownloadsDownloadFunction(),
1713 "[{\"url\": \"javascript:document.write(\\\"hello\\\");\"}]").c_str());
1714 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1715 new DownloadsDownloadFunction(),
1716 "[{\"url\": \"javascript:return false;\"}]").c_str());
1717 EXPECT_STREQ("NETWORK_FAILED", RunFunctionAndReturnError(
1718 new DownloadsDownloadFunction(),
1719 "[{\"url\": \"ftp://example.com/example.txt\"}]").c_str());
1722 // TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to
1723 // permissions, test downloading from ftp.
1725 // Valid URLs plus fragments are still valid URLs.
1726 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1727 DownloadExtensionTest_Download_URLFragment) {
1728 LoadExtension("downloads_split");
1729 ASSERT_TRUE(StartEmbeddedTestServer());
1730 ASSERT_TRUE(test_server()->Start());
1731 std::string download_url = test_server()->GetURL("slow?0#fragment").spec();
1734 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1735 new DownloadsDownloadFunction(), base::StringPrintf(
1736 "[{\"url\": \"%s\"}]", download_url.c_str())));
1737 ASSERT_TRUE(result.get());
1739 ASSERT_TRUE(result->GetAsInteger(&result_id));
1740 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1742 ScopedCancellingItem canceller(item);
1743 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1745 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1747 "[{\"danger\": \"safe\","
1748 " \"incognito\": false,"
1749 " \"mime\": \"text/plain\","
1750 " \"paused\": false,"
1751 " \"url\": \"%s\"}]",
1752 download_url.c_str())));
1753 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1757 " \"previous\": \"\","
1758 " \"current\": \"%s\"}}]",
1760 GetFilename("slow.txt").c_str())));
1761 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1765 " \"previous\": \"in_progress\","
1766 " \"current\": \"complete\"}}]",
1770 // conflictAction may be specified without filename.
1771 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1772 DownloadExtensionTest_Download_ConflictAction) {
1773 static char kFilename[] = "download.txt";
1774 LoadExtension("downloads_split");
1775 std::string download_url = "data:text/plain,hello";
1778 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1779 new DownloadsDownloadFunction(), base::StringPrintf(
1780 "[{\"url\": \"%s\"}]", download_url.c_str())));
1781 ASSERT_TRUE(result.get());
1783 ASSERT_TRUE(result->GetAsInteger(&result_id));
1784 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1786 ScopedCancellingItem canceller(item);
1787 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1789 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1791 "[{\"danger\": \"safe\","
1792 " \"incognito\": false,"
1793 " \"mime\": \"text/plain\","
1794 " \"paused\": false,"
1795 " \"url\": \"%s\"}]",
1796 download_url.c_str())));
1797 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1801 " \"previous\": \"\","
1802 " \"current\": \"%s\"}}]",
1804 GetFilename(kFilename).c_str())));
1805 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1809 " \"previous\": \"in_progress\","
1810 " \"current\": \"complete\"}}]",
1813 result.reset(RunFunctionAndReturnResult(
1814 new DownloadsDownloadFunction(), base::StringPrintf(
1815 "[{\"url\": \"%s\", \"conflictAction\": \"overwrite\"}]",
1816 download_url.c_str())));
1817 ASSERT_TRUE(result.get());
1819 ASSERT_TRUE(result->GetAsInteger(&result_id));
1820 item = GetCurrentManager()->GetDownload(result_id);
1822 ScopedCancellingItem canceller2(item);
1823 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1825 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1827 "[{\"danger\": \"safe\","
1828 " \"incognito\": false,"
1829 " \"mime\": \"text/plain\","
1830 " \"paused\": false,"
1831 " \"url\": \"%s\"}]",
1832 download_url.c_str())));
1833 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1837 " \"previous\": \"\","
1838 " \"current\": \"%s\"}}]",
1840 GetFilename(kFilename).c_str())));
1841 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1845 " \"previous\": \"in_progress\","
1846 " \"current\": \"complete\"}}]",
1850 // Valid data URLs are valid URLs.
1851 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1852 DownloadExtensionTest_Download_DataURL) {
1853 LoadExtension("downloads_split");
1854 std::string download_url = "data:text/plain,hello";
1857 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1858 new DownloadsDownloadFunction(), base::StringPrintf(
1859 "[{\"url\": \"%s\","
1860 " \"filename\": \"data.txt\"}]", download_url.c_str())));
1861 ASSERT_TRUE(result.get());
1863 ASSERT_TRUE(result->GetAsInteger(&result_id));
1864 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1866 ScopedCancellingItem canceller(item);
1867 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1869 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1871 "[{\"danger\": \"safe\","
1872 " \"incognito\": false,"
1873 " \"mime\": \"text/plain\","
1874 " \"paused\": false,"
1875 " \"url\": \"%s\"}]",
1876 download_url.c_str())));
1877 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1881 " \"previous\": \"\","
1882 " \"current\": \"%s\"}}]",
1884 GetFilename("data.txt").c_str())));
1885 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1889 " \"previous\": \"in_progress\","
1890 " \"current\": \"complete\"}}]",
1894 // Valid file URLs are valid URLs.
1896 // Disabled due to crbug.com/175711
1897 #define MAYBE_DownloadExtensionTest_Download_File \
1898 DISABLED_DownloadExtensionTest_Download_File
1900 #define MAYBE_DownloadExtensionTest_Download_File \
1901 DownloadExtensionTest_Download_File
1903 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1904 MAYBE_DownloadExtensionTest_Download_File) {
1906 LoadExtension("downloads_split");
1907 std::string download_url = "file:///";
1909 download_url += "C:/";
1912 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1913 new DownloadsDownloadFunction(), base::StringPrintf(
1914 "[{\"url\": \"%s\","
1915 " \"filename\": \"file.txt\"}]", download_url.c_str())));
1916 ASSERT_TRUE(result.get());
1918 ASSERT_TRUE(result->GetAsInteger(&result_id));
1919 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1921 ScopedCancellingItem canceller(item);
1922 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1924 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1926 "[{\"danger\": \"safe\","
1927 " \"incognito\": false,"
1928 " \"mime\": \"text/html\","
1929 " \"paused\": false,"
1930 " \"url\": \"%s\"}]",
1931 download_url.c_str())));
1932 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1936 " \"previous\": \"\","
1937 " \"current\": \"%s\"}}]",
1939 GetFilename("file.txt").c_str())));
1940 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1944 " \"previous\": \"in_progress\","
1945 " \"current\": \"complete\"}}]",
1949 // Test that auth-basic-succeed would fail if the resource requires the
1950 // Authorization header and chrome fails to propagate it back to the server.
1951 // This tests both that testserver.py does not succeed when it should fail as
1952 // well as how the downloads extension API exposes the failure to extensions.
1953 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1954 DownloadExtensionTest_Download_AuthBasic_Fail) {
1955 LoadExtension("downloads_split");
1956 ASSERT_TRUE(StartEmbeddedTestServer());
1957 ASSERT_TRUE(test_server()->Start());
1958 std::string download_url = test_server()->GetURL("auth-basic").spec();
1961 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1962 new DownloadsDownloadFunction(), base::StringPrintf(
1963 "[{\"url\": \"%s\","
1964 " \"filename\": \"auth-basic-fail.txt\"}]",
1965 download_url.c_str())));
1966 ASSERT_TRUE(result.get());
1968 ASSERT_TRUE(result->GetAsInteger(&result_id));
1969 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1971 ScopedCancellingItem canceller(item);
1972 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1974 ASSERT_TRUE(WaitForInterruption(
1976 content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED,
1977 base::StringPrintf("[{\"danger\": \"safe\","
1978 " \"incognito\": false,"
1979 " \"mime\": \"text/html\","
1980 " \"paused\": false,"
1981 " \"url\": \"%s\"}]",
1982 download_url.c_str())));
1985 // Test that DownloadsDownloadFunction propagates |headers| to the URLRequest.
1986 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1987 DownloadExtensionTest_Download_Headers) {
1988 LoadExtension("downloads_split");
1989 ASSERT_TRUE(StartEmbeddedTestServer());
1990 ASSERT_TRUE(test_server()->Start());
1991 std::string download_url = test_server()->GetURL("files/downloads/"
1992 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
1995 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1996 new DownloadsDownloadFunction(), base::StringPrintf(
1997 "[{\"url\": \"%s\","
1998 " \"filename\": \"headers-succeed.txt\","
2000 " {\"name\": \"Foo\", \"value\": \"bar\"},"
2001 " {\"name\": \"Qx\", \"value\":\"yo\"}]}]",
2002 download_url.c_str())));
2003 ASSERT_TRUE(result.get());
2005 ASSERT_TRUE(result->GetAsInteger(&result_id));
2006 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2008 ScopedCancellingItem canceller(item);
2009 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2011 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2013 "[{\"danger\": \"safe\","
2014 " \"incognito\": false,"
2015 " \"mime\": \"application/octet-stream\","
2016 " \"paused\": false,"
2017 " \"url\": \"%s\"}]",
2018 download_url.c_str())));
2019 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2023 " \"previous\": \"\","
2024 " \"current\": \"%s\"}}]",
2026 GetFilename("headers-succeed.txt").c_str())));
2027 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2031 " \"previous\": \"in_progress\","
2032 " \"current\": \"complete\"}}]",
2036 // Test that headers-succeed would fail if the resource requires the headers and
2037 // chrome fails to propagate them back to the server. This tests both that
2038 // testserver.py does not succeed when it should fail as well as how the
2039 // downloads extension api exposes the failure to extensions.
2040 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2041 DownloadExtensionTest_Download_Headers_Fail) {
2042 LoadExtension("downloads_split");
2043 ASSERT_TRUE(StartEmbeddedTestServer());
2044 ASSERT_TRUE(test_server()->Start());
2045 std::string download_url = test_server()->GetURL("files/downloads/"
2046 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
2049 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2050 new DownloadsDownloadFunction(), base::StringPrintf(
2051 "[{\"url\": \"%s\","
2052 " \"filename\": \"headers-fail.txt\"}]",
2053 download_url.c_str())));
2054 ASSERT_TRUE(result.get());
2056 ASSERT_TRUE(result->GetAsInteger(&result_id));
2057 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2059 ScopedCancellingItem canceller(item);
2060 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2062 ASSERT_TRUE(WaitForInterruption(
2064 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2065 base::StringPrintf("[{\"danger\": \"safe\","
2066 " \"incognito\": false,"
2067 " \"bytesReceived\": 0.0,"
2068 " \"fileSize\": 0.0,"
2070 " \"paused\": false,"
2071 " \"url\": \"%s\"}]",
2072 download_url.c_str())));
2075 // Test that DownloadsDownloadFunction propagates the Authorization header
2077 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2078 DownloadExtensionTest_Download_AuthBasic) {
2079 LoadExtension("downloads_split");
2080 ASSERT_TRUE(StartEmbeddedTestServer());
2081 ASSERT_TRUE(test_server()->Start());
2082 std::string download_url = test_server()->GetURL("auth-basic").spec();
2083 // This is just base64 of 'username:secret'.
2084 static const char* kAuthorization = "dXNlcm5hbWU6c2VjcmV0";
2087 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2088 new DownloadsDownloadFunction(), base::StringPrintf(
2089 "[{\"url\": \"%s\","
2090 " \"filename\": \"auth-basic-succeed.txt\","
2092 " \"name\": \"Authorization\","
2093 " \"value\": \"Basic %s\"}]}]",
2094 download_url.c_str(), kAuthorization)));
2095 ASSERT_TRUE(result.get());
2097 ASSERT_TRUE(result->GetAsInteger(&result_id));
2098 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2100 ScopedCancellingItem canceller(item);
2101 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2103 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2105 "[{\"danger\": \"safe\","
2106 " \"incognito\": false,"
2107 " \"bytesReceived\": 0.0,"
2108 " \"fileSize\": 0.0,"
2109 " \"mime\": \"text/html\","
2110 " \"paused\": false,"
2111 " \"url\": \"%s\"}]",
2112 download_url.c_str())));
2113 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2117 " \"previous\": \"in_progress\","
2118 " \"current\": \"complete\"}}]",
2122 // Test that DownloadsDownloadFunction propagates the |method| and |body|
2123 // parameters to the URLRequest.
2124 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2125 DownloadExtensionTest_Download_Post) {
2126 LoadExtension("downloads_split");
2127 ASSERT_TRUE(StartEmbeddedTestServer());
2128 ASSERT_TRUE(test_server()->Start());
2129 std::string download_url = test_server()->GetURL("files/post/downloads/"
2130 "a_zip_file.zip?expected_body=BODY").spec();
2133 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2134 new DownloadsDownloadFunction(), base::StringPrintf(
2135 "[{\"url\": \"%s\","
2136 " \"filename\": \"post-succeed.txt\","
2137 " \"method\": \"POST\","
2138 " \"body\": \"BODY\"}]",
2139 download_url.c_str())));
2140 ASSERT_TRUE(result.get());
2142 ASSERT_TRUE(result->GetAsInteger(&result_id));
2143 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2145 ScopedCancellingItem canceller(item);
2146 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2148 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2150 "[{\"danger\": \"safe\","
2151 " \"incognito\": false,"
2152 " \"mime\": \"application/octet-stream\","
2153 " \"paused\": false,"
2154 " \"url\": \"%s\"}]",
2155 download_url.c_str())));
2156 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2160 " \"previous\": \"\","
2161 " \"current\": \"%s\"}}]",
2163 GetFilename("post-succeed.txt").c_str())));
2164 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2168 " \"previous\": \"in_progress\","
2169 " \"current\": \"complete\"}}]",
2173 // Test that downloadPostSuccess would fail if the resource requires the POST
2174 // method, and chrome fails to propagate the |method| parameter back to the
2175 // server. This tests both that testserver.py does not succeed when it should
2176 // fail, and this tests how the downloads extension api exposes the failure to
2178 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2179 DownloadExtensionTest_Download_Post_Get) {
2180 LoadExtension("downloads_split");
2181 ASSERT_TRUE(StartEmbeddedTestServer());
2182 ASSERT_TRUE(test_server()->Start());
2183 std::string download_url = test_server()->GetURL("files/post/downloads/"
2184 "a_zip_file.zip?expected_body=BODY").spec();
2187 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2188 new DownloadsDownloadFunction(), base::StringPrintf(
2189 "[{\"url\": \"%s\","
2190 " \"body\": \"BODY\","
2191 " \"filename\": \"post-get.txt\"}]",
2192 download_url.c_str())));
2193 ASSERT_TRUE(result.get());
2195 ASSERT_TRUE(result->GetAsInteger(&result_id));
2196 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2198 ScopedCancellingItem canceller(item);
2199 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2201 ASSERT_TRUE(WaitForInterruption(
2203 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2204 base::StringPrintf("[{\"danger\": \"safe\","
2205 " \"incognito\": false,"
2207 " \"paused\": false,"
2209 " \"url\": \"%s\"}]",
2211 download_url.c_str())));
2214 // Test that downloadPostSuccess would fail if the resource requires the POST
2215 // method, and chrome fails to propagate the |body| parameter back to the
2216 // server. This tests both that testserver.py does not succeed when it should
2217 // fail, and this tests how the downloads extension api exposes the failure to
2219 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2220 DownloadExtensionTest_Download_Post_NoBody) {
2221 LoadExtension("downloads_split");
2222 ASSERT_TRUE(StartEmbeddedTestServer());
2223 ASSERT_TRUE(test_server()->Start());
2224 std::string download_url = test_server()->GetURL("files/post/downloads/"
2225 "a_zip_file.zip?expected_body=BODY").spec();
2228 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2229 new DownloadsDownloadFunction(), base::StringPrintf(
2230 "[{\"url\": \"%s\","
2231 " \"method\": \"POST\","
2232 " \"filename\": \"post-nobody.txt\"}]",
2233 download_url.c_str())));
2234 ASSERT_TRUE(result.get());
2236 ASSERT_TRUE(result->GetAsInteger(&result_id));
2237 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2239 ScopedCancellingItem canceller(item);
2240 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2242 ASSERT_TRUE(WaitForInterruption(
2244 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2245 base::StringPrintf("[{\"danger\": \"safe\","
2246 " \"incognito\": false,"
2248 " \"paused\": false,"
2250 " \"url\": \"%s\"}]",
2252 download_url.c_str())));
2255 // Test that cancel()ing an in-progress download causes its state to transition
2256 // to interrupted, and test that that state transition is detectable by an
2257 // onChanged event listener. TODO(benjhayden): Test other sources of
2258 // interruptions such as server death.
2259 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2260 DownloadExtensionTest_Download_Cancel) {
2261 LoadExtension("downloads_split");
2262 ASSERT_TRUE(StartEmbeddedTestServer());
2263 ASSERT_TRUE(test_server()->Start());
2264 std::string download_url = test_server()->GetURL(
2265 "download-known-size").spec();
2268 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2269 new DownloadsDownloadFunction(), base::StringPrintf(
2270 "[{\"url\": \"%s\"}]", download_url.c_str())));
2271 ASSERT_TRUE(result.get());
2273 ASSERT_TRUE(result->GetAsInteger(&result_id));
2274 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2276 ScopedCancellingItem canceller(item);
2277 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2279 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2281 "[{\"danger\": \"safe\","
2282 " \"incognito\": false,"
2283 " \"mime\": \"application/octet-stream\","
2284 " \"paused\": false,"
2286 " \"url\": \"%s\"}]",
2288 download_url.c_str())));
2290 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2293 " \"error\": {\"current\":\"USER_CANCELED\"},"
2295 " \"previous\": \"in_progress\","
2296 " \"current\": \"interrupted\"}}]",
2300 // Test downloading filesystem: URLs.
2301 // NOTE: chrome disallows creating HTML5 FileSystem Files in incognito.
2302 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2303 DownloadExtensionTest_Download_FileSystemURL) {
2304 static const char* kPayloadData = "on the record\ndata";
2306 LoadExtension("downloads_split");
2308 const std::string download_url = "filesystem:" + GetExtensionURL() +
2309 "temporary/on_record.txt";
2311 // Setup a file in the filesystem which we can download.
2312 ASSERT_TRUE(HTML5FileWriter::CreateFileForTesting(
2313 BrowserContext::GetDefaultStoragePartition(browser()->profile())->
2314 GetFileSystemContext(),
2315 fileapi::FileSystemURL::CreateForTest(GURL(download_url)),
2316 kPayloadData, strlen(kPayloadData)));
2319 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2320 new DownloadsDownloadFunction(), base::StringPrintf(
2321 "[{\"url\": \"%s\"}]", download_url.c_str())));
2322 ASSERT_TRUE(result.get());
2324 ASSERT_TRUE(result->GetAsInteger(&result_id));
2326 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2328 ScopedCancellingItem canceller(item);
2329 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2331 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2333 "[{\"danger\": \"safe\","
2334 " \"incognito\": false,"
2335 " \"mime\": \"text/plain\","
2336 " \"paused\": false,"
2337 " \"url\": \"%s\"}]",
2338 download_url.c_str())));
2339 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2343 " \"previous\": \"\","
2344 " \"current\": \"%s\"}}]",
2346 GetFilename("on_record.txt").c_str())));
2347 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2351 " \"previous\": \"in_progress\","
2352 " \"current\": \"complete\"}}]",
2354 std::string disk_data;
2355 EXPECT_TRUE(base::ReadFileToString(item->GetTargetFilePath(), &disk_data));
2356 EXPECT_STREQ(kPayloadData, disk_data.c_str());
2359 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2360 DownloadExtensionTest_OnDeterminingFilename_NoChange) {
2362 LoadExtension("downloads_split");
2363 AddFilenameDeterminer();
2364 ASSERT_TRUE(StartEmbeddedTestServer());
2365 ASSERT_TRUE(test_server()->Start());
2366 std::string download_url = test_server()->GetURL("slow?0").spec();
2368 // Start downloading a file.
2369 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2370 new DownloadsDownloadFunction(), base::StringPrintf(
2371 "[{\"url\": \"%s\"}]", download_url.c_str())));
2372 ASSERT_TRUE(result.get());
2374 ASSERT_TRUE(result->GetAsInteger(&result_id));
2375 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2377 ScopedCancellingItem canceller(item);
2378 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2380 // Wait for the onCreated and onDeterminingFilename events.
2381 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2383 "[{\"danger\": \"safe\","
2384 " \"incognito\": false,"
2386 " \"mime\": \"text/plain\","
2387 " \"paused\": false,"
2388 " \"url\": \"%s\"}]",
2390 download_url.c_str())));
2391 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2394 " \"filename\":\"slow.txt\"}]",
2396 ASSERT_TRUE(item->GetTargetFilePath().empty());
2397 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2399 // Respond to the onDeterminingFilename.
2401 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2402 browser()->profile(),
2407 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2409 EXPECT_EQ("", error);
2411 // The download should complete successfully.
2412 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2416 " \"previous\": \"\","
2417 " \"current\": \"%s\"}}]",
2419 GetFilename("slow.txt").c_str())));
2420 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2424 " \"previous\": \"in_progress\","
2425 " \"current\": \"complete\"}}]",
2429 // Disabled due to cross-platform flakes; http://crbug.com/370531.
2430 IN_PROC_BROWSER_TEST_F(
2431 DownloadExtensionTest,
2432 DISABLED_DownloadExtensionTest_OnDeterminingFilename_Timeout) {
2434 LoadExtension("downloads_split");
2435 AddFilenameDeterminer();
2436 ASSERT_TRUE(StartEmbeddedTestServer());
2437 ASSERT_TRUE(test_server()->Start());
2438 std::string download_url = test_server()->GetURL("slow?0").spec();
2440 ExtensionDownloadsEventRouter::SetDetermineFilenameTimeoutSecondsForTesting(
2443 // Start downloading a file.
2444 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2445 new DownloadsDownloadFunction(), base::StringPrintf(
2446 "[{\"url\": \"%s\"}]", download_url.c_str())));
2447 ASSERT_TRUE(result.get());
2449 ASSERT_TRUE(result->GetAsInteger(&result_id));
2450 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2452 ScopedCancellingItem canceller(item);
2453 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2455 // Wait for the onCreated and onDeterminingFilename events.
2456 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2457 base::StringPrintf("[{\"danger\": \"safe\","
2458 " \"incognito\": false,"
2460 " \"mime\": \"text/plain\","
2461 " \"paused\": false,"
2462 " \"url\": \"%s\"}]",
2464 download_url.c_str())));
2465 ASSERT_TRUE(WaitFor(
2466 downloads::OnDeterminingFilename::kEventName,
2467 base::StringPrintf("[{\"id\": %d,"
2468 " \"filename\":\"slow.txt\"}]",
2470 ASSERT_TRUE(item->GetTargetFilePath().empty());
2471 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2473 // Do not respond to the onDeterminingFilename.
2475 // The download should complete successfully.
2476 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2477 base::StringPrintf("[{\"id\": %d,"
2479 " \"previous\": \"\","
2480 " \"current\": \"%s\"}}]",
2482 GetFilename("slow.txt").c_str())));
2483 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2484 base::StringPrintf("[{\"id\": %d,"
2486 " \"previous\": \"in_progress\","
2487 " \"current\": \"complete\"}}]",
2491 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2492 DownloadExtensionTest_OnDeterminingFilename_Twice) {
2494 LoadExtension("downloads_split");
2495 AddFilenameDeterminer();
2496 ASSERT_TRUE(StartEmbeddedTestServer());
2497 ASSERT_TRUE(test_server()->Start());
2498 std::string download_url = test_server()->GetURL("slow?0").spec();
2500 // Start downloading a file.
2501 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2502 new DownloadsDownloadFunction(), base::StringPrintf(
2503 "[{\"url\": \"%s\"}]", download_url.c_str())));
2504 ASSERT_TRUE(result.get());
2506 ASSERT_TRUE(result->GetAsInteger(&result_id));
2507 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2509 ScopedCancellingItem canceller(item);
2510 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2512 // Wait for the onCreated and onDeterminingFilename events.
2513 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2514 base::StringPrintf("[{\"danger\": \"safe\","
2515 " \"incognito\": false,"
2517 " \"mime\": \"text/plain\","
2518 " \"paused\": false,"
2519 " \"url\": \"%s\"}]",
2521 download_url.c_str())));
2522 ASSERT_TRUE(WaitFor(
2523 downloads::OnDeterminingFilename::kEventName,
2524 base::StringPrintf("[{\"id\": %d,"
2525 " \"filename\":\"slow.txt\"}]",
2527 ASSERT_TRUE(item->GetTargetFilePath().empty());
2528 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2530 // Respond to the onDeterminingFilename.
2532 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2533 browser()->profile(),
2538 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2540 EXPECT_EQ("", error);
2542 // Calling DetermineFilename again should return an error instead of calling
2543 // DownloadTargetDeterminer.
2544 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2545 browser()->profile(),
2549 base::FilePath(FILE_PATH_LITERAL("different")),
2550 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE,
2552 EXPECT_EQ(errors::kTooManyListeners, error);
2554 // The download should complete successfully.
2555 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2556 base::StringPrintf("[{\"id\": %d,"
2558 " \"previous\": \"\","
2559 " \"current\": \"%s\"}}]",
2561 GetFilename("slow.txt").c_str())));
2562 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2563 base::StringPrintf("[{\"id\": %d,"
2565 " \"previous\": \"in_progress\","
2566 " \"current\": \"complete\"}}]",
2570 IN_PROC_BROWSER_TEST_F(
2571 DownloadExtensionTest,
2572 DownloadExtensionTest_OnDeterminingFilename_DangerousOverride) {
2574 LoadExtension("downloads_split");
2575 AddFilenameDeterminer();
2576 ASSERT_TRUE(StartEmbeddedTestServer());
2577 ASSERT_TRUE(test_server()->Start());
2578 std::string download_url = test_server()->GetURL("slow?0").spec();
2580 // Start downloading a file.
2581 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2582 new DownloadsDownloadFunction(), base::StringPrintf(
2583 "[{\"url\": \"%s\"}]", download_url.c_str())));
2584 ASSERT_TRUE(result.get());
2586 ASSERT_TRUE(result->GetAsInteger(&result_id));
2587 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2589 ScopedCancellingItem canceller(item);
2590 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2592 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2594 "[{\"danger\": \"safe\","
2595 " \"incognito\": false,"
2597 " \"mime\": \"text/plain\","
2598 " \"paused\": false,"
2599 " \"url\": \"%s\"}]",
2601 download_url.c_str())));
2602 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2605 " \"filename\":\"slow.txt\"}]",
2607 ASSERT_TRUE(item->GetTargetFilePath().empty());
2608 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2610 // Respond to the onDeterminingFilename.
2612 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2613 browser()->profile(),
2617 base::FilePath(FILE_PATH_LITERAL("overridden.swf")),
2618 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2620 EXPECT_EQ("", error);
2622 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2626 " \"previous\":\"safe\","
2627 " \"current\":\"file\"}}]",
2630 item->ValidateDangerousDownload();
2631 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2635 " \"previous\":\"file\","
2636 " \"current\":\"accepted\"}}]",
2638 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2642 " \"previous\": \"in_progress\","
2643 " \"current\": \"complete\"}}]",
2645 EXPECT_EQ(downloads_directory().AppendASCII("overridden.swf"),
2646 item->GetTargetFilePath());
2649 IN_PROC_BROWSER_TEST_F(
2650 DownloadExtensionTest,
2651 DownloadExtensionTest_OnDeterminingFilename_ReferencesParentInvalid) {
2653 LoadExtension("downloads_split");
2654 AddFilenameDeterminer();
2655 ASSERT_TRUE(StartEmbeddedTestServer());
2656 ASSERT_TRUE(test_server()->Start());
2657 std::string download_url = test_server()->GetURL("slow?0").spec();
2659 // Start downloading a file.
2660 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2661 new DownloadsDownloadFunction(), base::StringPrintf(
2662 "[{\"url\": \"%s\"}]", download_url.c_str())));
2663 ASSERT_TRUE(result.get());
2665 ASSERT_TRUE(result->GetAsInteger(&result_id));
2666 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2668 ScopedCancellingItem canceller(item);
2669 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2671 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2673 "[{\"danger\": \"safe\","
2674 " \"incognito\": false,"
2676 " \"mime\": \"text/plain\","
2677 " \"paused\": false,"
2678 " \"url\": \"%s\"}]",
2680 download_url.c_str())));
2681 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2684 " \"filename\":\"slow.txt\"}]",
2686 ASSERT_TRUE(item->GetTargetFilePath().empty());
2687 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2689 // Respond to the onDeterminingFilename.
2691 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2692 browser()->profile(),
2696 base::FilePath(FILE_PATH_LITERAL("sneaky/../../sneaky.txt")),
2697 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2699 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2700 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2704 " \"previous\": \"\","
2705 " \"current\": \"%s\"}}]",
2707 GetFilename("slow.txt").c_str())));
2708 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2712 " \"previous\": \"in_progress\","
2713 " \"current\": \"complete\"}}]",
2717 IN_PROC_BROWSER_TEST_F(
2718 DownloadExtensionTest,
2719 DownloadExtensionTest_OnDeterminingFilename_IllegalFilename) {
2721 LoadExtension("downloads_split");
2722 AddFilenameDeterminer();
2723 ASSERT_TRUE(StartEmbeddedTestServer());
2724 ASSERT_TRUE(test_server()->Start());
2725 std::string download_url = test_server()->GetURL("slow?0").spec();
2727 // Start downloading a file.
2728 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2729 new DownloadsDownloadFunction(), base::StringPrintf(
2730 "[{\"url\": \"%s\"}]", download_url.c_str())));
2731 ASSERT_TRUE(result.get());
2733 ASSERT_TRUE(result->GetAsInteger(&result_id));
2734 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2736 ScopedCancellingItem canceller(item);
2737 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2739 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2741 "[{\"danger\": \"safe\","
2742 " \"incognito\": false,"
2744 " \"mime\": \"text/plain\","
2745 " \"paused\": false,"
2746 " \"url\": \"%s\"}]",
2748 download_url.c_str())));
2749 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2752 " \"filename\":\"slow.txt\"}]",
2754 ASSERT_TRUE(item->GetTargetFilePath().empty());
2755 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2757 // Respond to the onDeterminingFilename.
2759 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2760 browser()->profile(),
2764 base::FilePath(FILE_PATH_LITERAL("<")),
2765 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2767 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2768 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2772 " \"previous\": \"\","
2773 " \"current\": \"%s\"}}]",
2775 GetFilename("slow.txt").c_str())));
2776 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2780 " \"previous\": \"in_progress\","
2781 " \"current\": \"complete\"}}]",
2785 IN_PROC_BROWSER_TEST_F(
2786 DownloadExtensionTest,
2787 DownloadExtensionTest_OnDeterminingFilename_IllegalFilenameExtension) {
2789 LoadExtension("downloads_split");
2790 AddFilenameDeterminer();
2791 ASSERT_TRUE(StartEmbeddedTestServer());
2792 ASSERT_TRUE(test_server()->Start());
2793 std::string download_url = test_server()->GetURL("slow?0").spec();
2795 // Start downloading a file.
2796 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2797 new DownloadsDownloadFunction(), base::StringPrintf(
2798 "[{\"url\": \"%s\"}]", download_url.c_str())));
2799 ASSERT_TRUE(result.get());
2801 ASSERT_TRUE(result->GetAsInteger(&result_id));
2802 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2804 ScopedCancellingItem canceller(item);
2805 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2807 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2809 "[{\"danger\": \"safe\","
2810 " \"incognito\": false,"
2812 " \"mime\": \"text/plain\","
2813 " \"paused\": false,"
2814 " \"url\": \"%s\"}]",
2816 download_url.c_str())));
2817 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2820 " \"filename\":\"slow.txt\"}]",
2822 ASSERT_TRUE(item->GetTargetFilePath().empty());
2823 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2825 // Respond to the onDeterminingFilename.
2827 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2828 browser()->profile(),
2832 base::FilePath(FILE_PATH_LITERAL(
2833 "My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}/foo")),
2834 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2836 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2837 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2841 " \"previous\": \"\","
2842 " \"current\": \"%s\"}}]",
2844 GetFilename("slow.txt").c_str())));
2845 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2849 " \"previous\": \"in_progress\","
2850 " \"current\": \"complete\"}}]",
2854 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2855 DISABLED_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2857 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2858 DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2860 IN_PROC_BROWSER_TEST_F(
2861 DownloadExtensionTest,
2862 MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename) {
2864 LoadExtension("downloads_split");
2865 AddFilenameDeterminer();
2866 ASSERT_TRUE(StartEmbeddedTestServer());
2867 ASSERT_TRUE(test_server()->Start());
2868 std::string download_url = test_server()->GetURL("slow?0").spec();
2870 // Start downloading a file.
2871 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2872 new DownloadsDownloadFunction(), base::StringPrintf(
2873 "[{\"url\": \"%s\"}]", download_url.c_str())));
2874 ASSERT_TRUE(result.get());
2876 ASSERT_TRUE(result->GetAsInteger(&result_id));
2877 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2879 ScopedCancellingItem canceller(item);
2880 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2882 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2884 "[{\"danger\": \"safe\","
2885 " \"incognito\": false,"
2887 " \"mime\": \"text/plain\","
2888 " \"paused\": false,"
2889 " \"url\": \"%s\"}]",
2891 download_url.c_str())));
2892 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2895 " \"filename\":\"slow.txt\"}]",
2897 ASSERT_TRUE(item->GetTargetFilePath().empty());
2898 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2900 // Respond to the onDeterminingFilename.
2902 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2903 browser()->profile(),
2907 base::FilePath(FILE_PATH_LITERAL("con.foo")),
2908 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2910 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2911 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2915 " \"previous\": \"\","
2916 " \"current\": \"%s\"}}]",
2918 GetFilename("slow.txt").c_str())));
2919 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2923 " \"previous\": \"in_progress\","
2924 " \"current\": \"complete\"}}]",
2928 IN_PROC_BROWSER_TEST_F(
2929 DownloadExtensionTest,
2930 DownloadExtensionTest_OnDeterminingFilename_CurDirInvalid) {
2932 LoadExtension("downloads_split");
2933 AddFilenameDeterminer();
2934 ASSERT_TRUE(StartEmbeddedTestServer());
2935 ASSERT_TRUE(test_server()->Start());
2936 std::string download_url = test_server()->GetURL("slow?0").spec();
2938 // Start downloading a file.
2939 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2940 new DownloadsDownloadFunction(), base::StringPrintf(
2941 "[{\"url\": \"%s\"}]", download_url.c_str())));
2942 ASSERT_TRUE(result.get());
2944 ASSERT_TRUE(result->GetAsInteger(&result_id));
2945 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2947 ScopedCancellingItem canceller(item);
2948 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2950 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2952 "[{\"danger\": \"safe\","
2953 " \"incognito\": false,"
2955 " \"mime\": \"text/plain\","
2956 " \"paused\": false,"
2957 " \"url\": \"%s\"}]",
2959 download_url.c_str())));
2960 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2963 " \"filename\":\"slow.txt\"}]",
2965 ASSERT_TRUE(item->GetTargetFilePath().empty());
2966 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2968 // Respond to the onDeterminingFilename.
2970 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2971 browser()->profile(),
2975 base::FilePath(FILE_PATH_LITERAL(".")),
2976 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2978 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2979 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2983 " \"previous\": \"\","
2984 " \"current\": \"%s\"}}]",
2986 GetFilename("slow.txt").c_str())));
2987 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2991 " \"previous\": \"in_progress\","
2992 " \"current\": \"complete\"}}]",
2996 IN_PROC_BROWSER_TEST_F(
2997 DownloadExtensionTest,
2998 DownloadExtensionTest_OnDeterminingFilename_ParentDirInvalid) {
2999 ASSERT_TRUE(StartEmbeddedTestServer());
3000 ASSERT_TRUE(test_server()->Start());
3002 LoadExtension("downloads_split");
3003 AddFilenameDeterminer();
3004 std::string download_url = test_server()->GetURL("slow?0").spec();
3006 // Start downloading a file.
3007 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3008 new DownloadsDownloadFunction(), base::StringPrintf(
3009 "[{\"url\": \"%s\"}]", download_url.c_str())));
3010 ASSERT_TRUE(result.get());
3012 ASSERT_TRUE(result->GetAsInteger(&result_id));
3013 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3015 ScopedCancellingItem canceller(item);
3016 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3018 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3020 "[{\"danger\": \"safe\","
3021 " \"incognito\": false,"
3023 " \"mime\": \"text/plain\","
3024 " \"paused\": false,"
3025 " \"url\": \"%s\"}]",
3027 download_url.c_str())));
3028 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3031 " \"filename\":\"slow.txt\"}]",
3033 ASSERT_TRUE(item->GetTargetFilePath().empty());
3034 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3036 // Respond to the onDeterminingFilename.
3038 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3039 browser()->profile(),
3043 base::FilePath(FILE_PATH_LITERAL("..")),
3044 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3046 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
3047 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3051 " \"previous\": \"\","
3052 " \"current\": \"%s\"}}]",
3054 GetFilename("slow.txt").c_str())));
3055 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3059 " \"previous\": \"in_progress\","
3060 " \"current\": \"complete\"}}]",
3064 IN_PROC_BROWSER_TEST_F(
3065 DownloadExtensionTest,
3066 DownloadExtensionTest_OnDeterminingFilename_AbsPathInvalid) {
3068 LoadExtension("downloads_split");
3069 AddFilenameDeterminer();
3070 ASSERT_TRUE(StartEmbeddedTestServer());
3071 ASSERT_TRUE(test_server()->Start());
3072 std::string download_url = test_server()->GetURL("slow?0").spec();
3074 // Start downloading a file.
3075 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3076 new DownloadsDownloadFunction(), base::StringPrintf(
3077 "[{\"url\": \"%s\"}]", download_url.c_str())));
3078 ASSERT_TRUE(result.get());
3080 ASSERT_TRUE(result->GetAsInteger(&result_id));
3081 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3083 ScopedCancellingItem canceller(item);
3084 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3086 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3088 "[{\"danger\": \"safe\","
3089 " \"incognito\": false,"
3091 " \"mime\": \"text/plain\","
3092 " \"paused\": false,"
3093 " \"url\": \"%s\"}]",
3095 download_url.c_str())));
3096 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3099 " \"filename\":\"slow.txt\"}]",
3101 ASSERT_TRUE(item->GetTargetFilePath().empty());
3102 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3104 // Respond to the onDeterminingFilename. Absolute paths should be rejected.
3106 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3107 browser()->profile(),
3111 downloads_directory().Append(FILE_PATH_LITERAL("sneaky.txt")),
3112 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3114 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
3116 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3120 " \"previous\": \"\","
3121 " \"current\": \"%s\"}}]",
3123 GetFilename("slow.txt").c_str())));
3124 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3128 " \"previous\": \"in_progress\","
3129 " \"current\": \"complete\"}}]",
3133 IN_PROC_BROWSER_TEST_F(
3134 DownloadExtensionTest,
3135 DownloadExtensionTest_OnDeterminingFilename_EmptyBasenameInvalid) {
3137 LoadExtension("downloads_split");
3138 AddFilenameDeterminer();
3139 ASSERT_TRUE(StartEmbeddedTestServer());
3140 ASSERT_TRUE(test_server()->Start());
3141 std::string download_url = test_server()->GetURL("slow?0").spec();
3143 // Start downloading a file.
3144 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3145 new DownloadsDownloadFunction(), base::StringPrintf(
3146 "[{\"url\": \"%s\"}]", download_url.c_str())));
3147 ASSERT_TRUE(result.get());
3149 ASSERT_TRUE(result->GetAsInteger(&result_id));
3150 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3152 ScopedCancellingItem canceller(item);
3153 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3155 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3157 "[{\"danger\": \"safe\","
3158 " \"incognito\": false,"
3160 " \"mime\": \"text/plain\","
3161 " \"paused\": false,"
3162 " \"url\": \"%s\"}]",
3164 download_url.c_str())));
3165 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3168 " \"filename\":\"slow.txt\"}]",
3170 ASSERT_TRUE(item->GetTargetFilePath().empty());
3171 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3173 // Respond to the onDeterminingFilename. Empty basenames should be rejected.
3175 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3176 browser()->profile(),
3180 base::FilePath(FILE_PATH_LITERAL("foo/")),
3181 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3183 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
3185 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3189 " \"previous\": \"\","
3190 " \"current\": \"%s\"}}]",
3192 GetFilename("slow.txt").c_str())));
3193 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3197 " \"previous\": \"in_progress\","
3198 " \"current\": \"complete\"}}]",
3202 // conflictAction may be specified without filename.
3203 IN_PROC_BROWSER_TEST_F(
3204 DownloadExtensionTest,
3205 DownloadExtensionTest_OnDeterminingFilename_Overwrite) {
3207 LoadExtension("downloads_split");
3208 AddFilenameDeterminer();
3209 ASSERT_TRUE(StartEmbeddedTestServer());
3210 ASSERT_TRUE(test_server()->Start());
3211 std::string download_url = test_server()->GetURL("slow?0").spec();
3213 // Start downloading a file.
3214 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3215 new DownloadsDownloadFunction(), base::StringPrintf(
3216 "[{\"url\": \"%s\"}]", download_url.c_str())));
3217 ASSERT_TRUE(result.get());
3219 ASSERT_TRUE(result->GetAsInteger(&result_id));
3220 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3222 ScopedCancellingItem canceller(item);
3223 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3224 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3226 "[{\"danger\": \"safe\","
3227 " \"incognito\": false,"
3229 " \"mime\": \"text/plain\","
3230 " \"paused\": false,"
3231 " \"url\": \"%s\"}]",
3233 download_url.c_str())));
3234 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3237 " \"filename\":\"slow.txt\"}]",
3239 ASSERT_TRUE(item->GetTargetFilePath().empty());
3240 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3242 // Respond to the onDeterminingFilename.
3244 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3245 browser()->profile(),
3250 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3252 EXPECT_EQ("", error);
3254 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3258 " \"previous\": \"\","
3259 " \"current\": \"%s\"}}]",
3261 GetFilename("slow.txt").c_str())));
3262 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3266 " \"previous\": \"in_progress\","
3267 " \"current\": \"complete\"}}]",
3270 // Start downloading a file.
3271 result.reset(RunFunctionAndReturnResult(
3272 new DownloadsDownloadFunction(), base::StringPrintf(
3273 "[{\"url\": \"%s\"}]", download_url.c_str())));
3274 ASSERT_TRUE(result.get());
3276 ASSERT_TRUE(result->GetAsInteger(&result_id));
3277 item = GetCurrentManager()->GetDownload(result_id);
3279 ScopedCancellingItem canceller2(item);
3280 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3282 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3284 "[{\"danger\": \"safe\","
3285 " \"incognito\": false,"
3287 " \"mime\": \"text/plain\","
3288 " \"paused\": false,"
3289 " \"url\": \"%s\"}]",
3291 download_url.c_str())));
3292 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3295 " \"filename\":\"slow.txt\"}]",
3297 ASSERT_TRUE(item->GetTargetFilePath().empty());
3298 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3300 // Respond to the onDeterminingFilename.
3301 // Also test that DetermineFilename allows (chrome) extensions to set
3302 // filenames without (filename) extensions. (Don't ask about v8 extensions or
3303 // python extensions or kernel extensions or firefox extensions...)
3305 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3306 browser()->profile(),
3311 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE,
3313 EXPECT_EQ("", error);
3315 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3319 " \"previous\": \"\","
3320 " \"current\": \"%s\"}}]",
3322 GetFilename("slow.txt").c_str())));
3323 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3327 " \"previous\": \"in_progress\","
3328 " \"current\": \"complete\"}}]",
3332 IN_PROC_BROWSER_TEST_F(
3333 DownloadExtensionTest,
3334 DownloadExtensionTest_OnDeterminingFilename_Override) {
3336 LoadExtension("downloads_split");
3337 AddFilenameDeterminer();
3338 ASSERT_TRUE(StartEmbeddedTestServer());
3339 ASSERT_TRUE(test_server()->Start());
3340 std::string download_url = test_server()->GetURL("slow?0").spec();
3342 // Start downloading a file.
3343 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3344 new DownloadsDownloadFunction(), base::StringPrintf(
3345 "[{\"url\": \"%s\"}]", download_url.c_str())));
3346 ASSERT_TRUE(result.get());
3348 ASSERT_TRUE(result->GetAsInteger(&result_id));
3349 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3351 ScopedCancellingItem canceller(item);
3352 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3353 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3355 "[{\"danger\": \"safe\","
3356 " \"incognito\": false,"
3358 " \"mime\": \"text/plain\","
3359 " \"paused\": false,"
3360 " \"url\": \"%s\"}]",
3362 download_url.c_str())));
3363 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3366 " \"filename\":\"slow.txt\"}]",
3368 ASSERT_TRUE(item->GetTargetFilePath().empty());
3369 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3371 // Respond to the onDeterminingFilename.
3373 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3374 browser()->profile(),
3379 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3381 EXPECT_EQ("", error);
3383 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3387 " \"previous\": \"\","
3388 " \"current\": \"%s\"}}]",
3390 GetFilename("slow.txt").c_str())));
3391 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3395 " \"previous\": \"in_progress\","
3396 " \"current\": \"complete\"}}]",
3399 // Start downloading a file.
3400 result.reset(RunFunctionAndReturnResult(
3401 new DownloadsDownloadFunction(), base::StringPrintf(
3402 "[{\"url\": \"%s\"}]", download_url.c_str())));
3403 ASSERT_TRUE(result.get());
3405 ASSERT_TRUE(result->GetAsInteger(&result_id));
3406 item = GetCurrentManager()->GetDownload(result_id);
3408 ScopedCancellingItem canceller2(item);
3409 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3411 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3413 "[{\"danger\": \"safe\","
3414 " \"incognito\": false,"
3416 " \"mime\": \"text/plain\","
3417 " \"paused\": false,"
3418 " \"url\": \"%s\"}]",
3420 download_url.c_str())));
3421 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3424 " \"filename\":\"slow.txt\"}]",
3426 ASSERT_TRUE(item->GetTargetFilePath().empty());
3427 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3429 // Respond to the onDeterminingFilename.
3430 // Also test that DetermineFilename allows (chrome) extensions to set
3431 // filenames without (filename) extensions. (Don't ask about v8 extensions or
3432 // python extensions or kernel extensions or firefox extensions...)
3434 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3435 browser()->profile(),
3439 base::FilePath(FILE_PATH_LITERAL("foo")),
3440 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE,
3442 EXPECT_EQ("", error);
3444 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3448 " \"previous\": \"\","
3449 " \"current\": \"%s\"}}]",
3451 GetFilename("foo").c_str())));
3452 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3456 " \"previous\": \"in_progress\","
3457 " \"current\": \"complete\"}}]",
3461 // TODO test precedence rules: install_time
3463 IN_PROC_BROWSER_TEST_F(
3464 DownloadExtensionTest,
3465 DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer) {
3466 ASSERT_TRUE(StartEmbeddedTestServer());
3467 ASSERT_TRUE(test_server()->Start());
3469 LoadExtension("downloads_split");
3470 content::RenderProcessHost* host = AddFilenameDeterminer();
3471 std::string download_url = test_server()->GetURL("slow?0").spec();
3473 // Start downloading a file.
3474 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3475 new DownloadsDownloadFunction(), base::StringPrintf(
3476 "[{\"url\": \"%s\"}]", download_url.c_str())));
3477 ASSERT_TRUE(result.get());
3479 ASSERT_TRUE(result->GetAsInteger(&result_id));
3480 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3482 ScopedCancellingItem canceller(item);
3483 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3485 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3487 "[{\"danger\": \"safe\","
3488 " \"incognito\": false,"
3490 " \"mime\": \"text/plain\","
3491 " \"paused\": false,"
3492 " \"url\": \"%s\"}]",
3494 download_url.c_str())));
3495 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3498 " \"filename\":\"slow.txt\"}]",
3500 ASSERT_TRUE(item->GetTargetFilePath().empty());
3501 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3503 // Remove a determiner while waiting for it.
3504 RemoveFilenameDeterminer(host);
3506 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3510 " \"previous\": \"in_progress\","
3511 " \"current\": \"complete\"}}]",
3515 IN_PROC_BROWSER_TEST_F(
3516 DownloadExtensionTest,
3517 DownloadExtensionTest_OnDeterminingFilename_IncognitoSplit) {
3518 LoadExtension("downloads_split");
3519 ASSERT_TRUE(StartEmbeddedTestServer());
3520 ASSERT_TRUE(test_server()->Start());
3521 std::string download_url = test_server()->GetURL("slow?0").spec();
3524 AddFilenameDeterminer();
3527 AddFilenameDeterminer();
3529 // Start an on-record download.
3531 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3532 new DownloadsDownloadFunction(), base::StringPrintf(
3533 "[{\"url\": \"%s\"}]", download_url.c_str())));
3534 ASSERT_TRUE(result.get());
3536 ASSERT_TRUE(result->GetAsInteger(&result_id));
3537 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3539 ScopedCancellingItem canceller(item);
3540 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3542 // Wait for the onCreated and onDeterminingFilename events.
3543 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3545 "[{\"danger\": \"safe\","
3546 " \"incognito\": false,"
3548 " \"mime\": \"text/plain\","
3549 " \"paused\": false,"
3550 " \"url\": \"%s\"}]",
3552 download_url.c_str())));
3553 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3556 " \"incognito\": false,"
3557 " \"filename\":\"slow.txt\"}]",
3559 ASSERT_TRUE(item->GetTargetFilePath().empty());
3560 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3562 // Respond to the onDeterminingFilename events.
3564 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3565 current_browser()->profile(),
3569 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3570 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3572 EXPECT_EQ("", error);
3574 // The download should complete successfully.
3575 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3579 " \"previous\": \"\","
3580 " \"current\": \"%s\"}}]",
3582 GetFilename("42.txt").c_str())));
3583 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3587 " \"previous\": \"in_progress\","
3588 " \"current\": \"complete\"}}]",
3591 // Start an incognito download for comparison.
3593 result.reset(RunFunctionAndReturnResult(
3594 new DownloadsDownloadFunction(), base::StringPrintf(
3595 "[{\"url\": \"%s\"}]", download_url.c_str())));
3596 ASSERT_TRUE(result.get());
3598 ASSERT_TRUE(result->GetAsInteger(&result_id));
3599 item = GetCurrentManager()->GetDownload(result_id);
3601 ScopedCancellingItem canceller2(item);
3602 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3604 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3606 "[{\"danger\": \"safe\","
3607 " \"incognito\": true,"
3609 " \"mime\": \"text/plain\","
3610 " \"paused\": false,"
3611 " \"url\": \"%s\"}]",
3613 download_url.c_str())));
3614 // On-Record renderers should not see events for off-record items.
3615 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3618 " \"incognito\": true,"
3619 " \"filename\":\"slow.txt\"}]",
3621 ASSERT_TRUE(item->GetTargetFilePath().empty());
3622 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3624 // Respond to the onDeterminingFilename.
3626 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3627 current_browser()->profile(),
3631 base::FilePath(FILE_PATH_LITERAL("5.txt")),
3632 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3634 EXPECT_EQ("", error);
3636 // The download should complete successfully.
3637 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3641 " \"previous\": \"\","
3642 " \"current\": \"%s\"}}]",
3644 GetFilename("5.txt").c_str())));
3645 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3649 " \"previous\": \"in_progress\","
3650 " \"current\": \"complete\"}}]",
3654 IN_PROC_BROWSER_TEST_F(
3655 DownloadExtensionTest,
3656 DownloadExtensionTest_OnDeterminingFilename_IncognitoSpanning) {
3657 LoadExtension("downloads_spanning");
3658 ASSERT_TRUE(StartEmbeddedTestServer());
3659 ASSERT_TRUE(test_server()->Start());
3660 std::string download_url = test_server()->GetURL("slow?0").spec();
3663 AddFilenameDeterminer();
3665 // There is a single extension renderer that sees both on-record and
3666 // off-record events. The extension functions see the on-record profile with
3667 // include_incognito=true.
3669 // Start an on-record download.
3671 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3672 new DownloadsDownloadFunction(), base::StringPrintf(
3673 "[{\"url\": \"%s\"}]", download_url.c_str())));
3674 ASSERT_TRUE(result.get());
3676 ASSERT_TRUE(result->GetAsInteger(&result_id));
3677 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3679 ScopedCancellingItem canceller(item);
3680 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3682 // Wait for the onCreated and onDeterminingFilename events.
3683 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3685 "[{\"danger\": \"safe\","
3686 " \"incognito\": false,"
3688 " \"mime\": \"text/plain\","
3689 " \"paused\": false,"
3690 " \"url\": \"%s\"}]",
3692 download_url.c_str())));
3693 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3696 " \"incognito\": false,"
3697 " \"filename\":\"slow.txt\"}]",
3699 ASSERT_TRUE(item->GetTargetFilePath().empty());
3700 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3702 // Respond to the onDeterminingFilename events.
3704 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3705 current_browser()->profile(),
3709 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3710 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3712 EXPECT_EQ("", error);
3714 // The download should complete successfully.
3715 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3719 " \"previous\": \"\","
3720 " \"current\": \"%s\"}}]",
3722 GetFilename("42.txt").c_str())));
3723 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3727 " \"previous\": \"in_progress\","
3728 " \"current\": \"complete\"}}]",
3731 // Start an incognito download for comparison.
3733 result.reset(RunFunctionAndReturnResult(
3734 new DownloadsDownloadFunction(), base::StringPrintf(
3735 "[{\"url\": \"%s\"}]", download_url.c_str())));
3736 ASSERT_TRUE(result.get());
3738 ASSERT_TRUE(result->GetAsInteger(&result_id));
3739 item = GetCurrentManager()->GetDownload(result_id);
3741 ScopedCancellingItem canceller2(item);
3742 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3744 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3746 "[{\"danger\": \"safe\","
3747 " \"incognito\": true,"
3749 " \"mime\": \"text/plain\","
3750 " \"paused\": false,"
3751 " \"url\": \"%s\"}]",
3753 download_url.c_str())));
3754 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3757 " \"incognito\": true,"
3758 " \"filename\":\"slow.txt\"}]",
3760 ASSERT_TRUE(item->GetTargetFilePath().empty());
3761 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3763 // Respond to the onDeterminingFilename.
3765 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3766 current_browser()->profile(),
3770 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3771 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3773 EXPECT_EQ("", error);
3775 // The download should complete successfully.
3776 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3780 " \"previous\": \"\","
3781 " \"current\": \"%s\"}}]",
3783 GetFilename("42 (1).txt").c_str())));
3784 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3788 " \"previous\": \"in_progress\","
3789 " \"current\": \"complete\"}}]",
3794 // This test is very flaky on Win XP and Aura. http://crbug.com/248438
3795 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3796 DISABLED_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3798 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3799 DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3802 // Test download interruption while extensions determining filename. Should not
3803 // re-dispatch onDeterminingFilename.
3804 IN_PROC_BROWSER_TEST_F(
3805 DownloadExtensionTest,
3806 MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume) {
3807 CommandLine::ForCurrentProcess()->AppendSwitch(
3808 switches::kEnableDownloadResumption);
3809 LoadExtension("downloads_split");
3810 ASSERT_TRUE(StartEmbeddedTestServer());
3811 ASSERT_TRUE(test_server()->Start());
3813 content::RenderProcessHost* host = AddFilenameDeterminer();
3815 // Start a download.
3816 DownloadItem* item = NULL;
3818 DownloadManager* manager = GetCurrentManager();
3819 scoped_ptr<content::DownloadTestObserver> observer(
3820 new JustInProgressDownloadObserver(manager, 1));
3821 ASSERT_EQ(0, manager->InProgressCount());
3822 ASSERT_EQ(0, manager->NonMaliciousInProgressCount());
3823 // Tabs created just for a download are automatically closed, invalidating
3824 // the download's WebContents. Downloads without WebContents cannot be
3825 // resumed. http://crbug.com/225901
3826 ui_test_utils::NavigateToURLWithDisposition(
3828 GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl),
3830 ui_test_utils::BROWSER_TEST_NONE);
3831 observer->WaitForFinished();
3832 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
3833 DownloadManager::DownloadVector items;
3834 manager->GetAllDownloads(&items);
3835 for (DownloadManager::DownloadVector::iterator iter = items.begin();
3836 iter != items.end(); ++iter) {
3837 if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) {
3838 // There should be only one IN_PROGRESS item.
3839 EXPECT_EQ(NULL, item);
3845 ScopedCancellingItem canceller(item);
3847 // Wait for the onCreated and onDeterminingFilename event.
3848 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3850 "[{\"danger\": \"safe\","
3851 " \"incognito\": false,"
3853 " \"mime\": \"application/octet-stream\","
3854 " \"paused\": false}]",
3856 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3859 " \"incognito\": false,"
3860 " \"filename\":\"download-unknown-size\"}]",
3862 ASSERT_TRUE(item->GetTargetFilePath().empty());
3863 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3866 ui_test_utils::NavigateToURLWithDisposition(
3868 GURL(URLRequestSlowDownloadJob::kErrorDownloadUrl),
3870 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3872 // Errors caught before filename determination are delayed until after
3873 // filename determination.
3875 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3876 current_browser()->profile(),
3880 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3881 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3884 EXPECT_EQ("", error);
3885 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3889 " \"previous\": \"\","
3890 " \"current\": \"%s\"}}]",
3892 GetFilename("42.txt").c_str())));
3894 content::DownloadUpdatedObserver interrupted(item, base::Bind(
3895 ItemIsInterrupted));
3896 ASSERT_TRUE(interrupted.WaitForEvent());
3897 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3900 " \"error\":{\"current\":\"NETWORK_FAILED\"},"
3902 " \"previous\":\"in_progress\","
3903 " \"current\":\"interrupted\"}}]",
3907 // Downloads that are restarted on resumption trigger another download target
3909 RemoveFilenameDeterminer(host);
3912 // Errors caught before filename determination is complete are delayed until
3913 // after filename determination so that, on resumption, filename determination
3914 // does not need to be re-done. So, there will not be a second
3915 // onDeterminingFilename event.
3917 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3920 " \"error\":{\"previous\":\"NETWORK_FAILED\"},"
3922 " \"previous\":\"interrupted\","
3923 " \"current\":\"in_progress\"}}]",
3927 FinishPendingSlowDownloads();
3929 // The download should complete successfully.
3930 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3934 " \"previous\": \"in_progress\","
3935 " \"current\": \"complete\"}}]",
3939 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
3940 DownloadExtensionTest_SetShelfEnabled) {
3941 LoadExtension("downloads_split");
3942 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[false]"));
3943 EXPECT_FALSE(DownloadServiceFactory::GetForBrowserContext(
3944 browser()->profile())->IsShelfEnabled());
3945 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[true]"));
3946 EXPECT_TRUE(DownloadServiceFactory::GetForBrowserContext(
3947 browser()->profile())->IsShelfEnabled());
3948 // TODO(benjhayden) Test that existing shelves are hidden.
3949 // TODO(benjhayden) Test multiple extensions.
3950 // TODO(benjhayden) Test disabling extensions.
3951 // TODO(benjhayden) Test that browsers associated with other profiles are not
3953 // TODO(benjhayden) Test incognito.
3956 // TODO(benjhayden) Figure out why DisableExtension() does not fire
3957 // OnListenerRemoved.
3959 // TODO(benjhayden) Test that the shelf is shown for download() both with and
3960 // without a WebContents.
3962 void OnDangerPromptCreated(DownloadDangerPrompt* prompt) {
3963 prompt->InvokeActionForTesting(DownloadDangerPrompt::ACCEPT);
3966 #if defined(OS_MACOSX)
3967 // Flakily triggers and assert on Mac.
3968 // http://crbug.com/180759
3969 #define MAYBE_DownloadExtensionTest_AcceptDanger DownloadExtensionTest_AcceptDanger
3971 #define MAYBE_DownloadExtensionTest_AcceptDanger DISABLED_DownloadExtensionTest_AcceptDanger
3973 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
3974 MAYBE_DownloadExtensionTest_AcceptDanger) {
3975 // Download a file that will be marked dangerous; click the browser action
3976 // button; the browser action poup will call acceptDanger(); when the
3977 // DownloadDangerPrompt is created, pretend that the user clicks the Accept
3978 // button; wait until the download completes.
3979 LoadExtension("downloads_split");
3980 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3981 new DownloadsDownloadFunction(),
3982 "[{\"url\": \"data:,\", \"filename\": \"dangerous.swf\"}]"));
3983 ASSERT_TRUE(result.get());
3985 ASSERT_TRUE(result->GetAsInteger(&result_id));
3986 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3988 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3992 " \"previous\": \"safe\","
3993 " \"current\": \"file\"}}]",
3995 ASSERT_TRUE(item->IsDangerous());
3996 ScopedCancellingItem canceller(item);
3997 scoped_ptr<content::DownloadTestObserver> observer(
3998 new content::DownloadTestObserverTerminal(
3999 GetCurrentManager(), 1,
4000 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_IGNORE));
4001 DownloadsAcceptDangerFunction::OnPromptCreatedCallback callback =
4002 base::Bind(&OnDangerPromptCreated);
4003 DownloadsAcceptDangerFunction::OnPromptCreatedForTesting(
4005 BrowserActionTestUtil(browser()).Press(0);
4006 observer->WaitForFinished();
4009 class DownloadsApiTest : public ExtensionApiTest {
4011 DownloadsApiTest() {}
4012 virtual ~DownloadsApiTest() {}
4014 DISALLOW_COPY_AND_ASSIGN(DownloadsApiTest);
4018 IN_PROC_BROWSER_TEST_F(DownloadsApiTest, DownloadsApiTest) {
4019 ASSERT_TRUE(RunExtensionTest("downloads")) << message_;
4022 TEST(DownloadInterruptReasonEnumsSynced,
4023 DownloadInterruptReasonEnumsSynced) {
4024 #define INTERRUPT_REASON(name, value) \
4025 EXPECT_EQ(InterruptReasonContentToExtension( \
4026 content::DOWNLOAD_INTERRUPT_REASON_##name), \
4027 downloads::INTERRUPT_REASON_##name); \
4029 InterruptReasonExtensionToContent(downloads::INTERRUPT_REASON_##name), \
4030 content::DOWNLOAD_INTERRUPT_REASON_##name);
4031 #include "content/public/browser/download_interrupt_reason_values.h"
4032 #undef INTERRUPT_REASON
4035 TEST(ExtensionDetermineDownloadFilenameInternal,
4036 ExtensionDetermineDownloadFilenameInternal) {
4037 std::string winner_id;
4038 base::FilePath filename;
4039 downloads::FilenameConflictAction conflict_action =
4040 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY;
4041 extensions::ExtensionWarningSet warnings;
4043 // Empty incumbent determiner
4045 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4046 base::FilePath(FILE_PATH_LITERAL("a")),
4047 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE,
4056 EXPECT_EQ("suggester", winner_id);
4057 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename.value());
4058 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_OVERWRITE, conflict_action);
4059 EXPECT_TRUE(warnings.empty());
4063 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4064 base::FilePath(FILE_PATH_LITERAL("b")),
4065 downloads::FILENAME_CONFLICT_ACTION_PROMPT,
4067 base::Time::Now() - base::TimeDelta::FromDays(1),
4074 EXPECT_EQ("incumbent", winner_id);
4075 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename.value());
4076 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_OVERWRITE, conflict_action);
4077 EXPECT_FALSE(warnings.empty());
4078 EXPECT_EQ(extensions::ExtensionWarning::kDownloadFilenameConflict,
4079 warnings.begin()->warning_type());
4080 EXPECT_EQ("suggester", warnings.begin()->extension_id());
4084 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4085 base::FilePath(FILE_PATH_LITERAL("b")),
4086 downloads::FILENAME_CONFLICT_ACTION_PROMPT,
4090 base::Time::Now() - base::TimeDelta::FromDays(1),
4095 EXPECT_EQ("suggester", winner_id);
4096 EXPECT_EQ(FILE_PATH_LITERAL("b"), filename.value());
4097 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_PROMPT, conflict_action);
4098 EXPECT_FALSE(warnings.empty());
4099 EXPECT_EQ(extensions::ExtensionWarning::kDownloadFilenameConflict,
4100 warnings.begin()->warning_type());
4101 EXPECT_EQ("incumbent", warnings.begin()->extension_id());
4104 } // namespace extensions
4106 #endif // http://crbug.com/3061144