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.
7 #include "base/file_util.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/json/json_reader.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/stl_util.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/download/download_file_icon_extractor.h"
17 #include "chrome/browser/download/download_service.h"
18 #include "chrome/browser/download/download_service_factory.h"
19 #include "chrome/browser/download/download_test_file_activity_observer.h"
20 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
21 #include "chrome/browser/extensions/browser_action_test_util.h"
22 #include "chrome/browser/extensions/extension_apitest.h"
23 #include "chrome/browser/extensions/extension_function_test_utils.h"
24 #include "chrome/browser/extensions/extension_service.h"
25 #include "chrome/browser/history/download_row.h"
26 #include "chrome/browser/net/url_request_mock_util.h"
27 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/browser/ui/browser.h"
29 #include "chrome/browser/ui/browser_tabstrip.h"
30 #include "chrome/common/pref_names.h"
31 #include "chrome/test/base/in_process_browser_test.h"
32 #include "chrome/test/base/ui_test_utils.h"
33 #include "content/public/browser/browser_context.h"
34 #include "content/public/browser/browser_thread.h"
35 #include "content/public/browser/download_item.h"
36 #include "content/public/browser/download_manager.h"
37 #include "content/public/browser/notification_service.h"
38 #include "content/public/browser/storage_partition.h"
39 #include "content/public/browser/web_contents.h"
40 #include "content/public/common/content_switches.h"
41 #include "content/public/common/page_transition_types.h"
42 #include "content/public/test/download_test_observer.h"
43 #include "content/test/net/url_request_slow_download_job.h"
44 #include "net/base/data_url.h"
45 #include "net/base/net_util.h"
46 #include "net/url_request/url_request.h"
47 #include "net/url_request/url_request_context.h"
48 #include "net/url_request/url_request_job.h"
49 #include "net/url_request/url_request_job_factory.h"
50 #include "net/url_request/url_request_job_factory_impl.h"
51 #include "webkit/browser/fileapi/file_system_context.h"
52 #include "webkit/browser/fileapi/file_system_operation_runner.h"
53 #include "webkit/browser/fileapi/file_system_url.h"
55 // Disable everything due to issue 306144
57 using content::BrowserContext;
58 using content::BrowserThread;
59 using content::DownloadItem;
60 using content::DownloadManager;
61 using content::URLRequestSlowDownloadJob;
63 namespace errors = download_extension_errors;
65 namespace api = extensions::api::downloads;
69 // Comparator that orders download items by their ID. Can be used with
71 struct DownloadIdComparator {
72 bool operator() (DownloadItem* first, DownloadItem* second) {
73 return first->GetId() < second->GetId();
77 class DownloadsEventsListener : public content::NotificationObserver {
79 DownloadsEventsListener()
81 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
82 content::NotificationService::AllSources());
85 virtual ~DownloadsEventsListener() {
86 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
87 content::NotificationService::AllSources());
88 STLDeleteElements(&events_);
92 STLDeleteElements(&events_);
98 Event(Profile* profile,
99 const std::string& event_name,
100 const std::string& json_args,
103 event_name_(event_name),
104 json_args_(json_args),
105 args_(base::JSONReader::Read(json_args)),
109 const base::Time& caught() { return caught_; }
111 bool Satisfies(const Event& other) const {
112 return other.SatisfiedBy(*this);
115 bool SatisfiedBy(const Event& other) const {
116 if ((profile_ != other.profile_) ||
117 (event_name_ != other.event_name_))
119 if (((event_name_ == api::OnDeterminingFilename::kEventName) ||
120 (event_name_ == api::OnCreated::kEventName) ||
121 (event_name_ == api::OnChanged::kEventName)) &&
124 base::ListValue* left_list = NULL;
125 base::DictionaryValue* left_dict = NULL;
126 base::ListValue* right_list = NULL;
127 base::DictionaryValue* right_dict = NULL;
128 if (!args_->GetAsList(&left_list) ||
129 !other.args_->GetAsList(&right_list) ||
130 !left_list->GetDictionary(0, &left_dict) ||
131 !right_list->GetDictionary(0, &right_dict))
133 for (base::DictionaryValue::Iterator iter(*left_dict);
134 !iter.IsAtEnd(); iter.Advance()) {
135 base::Value* right_value = NULL;
136 if (!right_dict->HasKey(iter.key()) ||
137 (right_dict->Get(iter.key(), &right_value) &&
138 !iter.value().Equals(right_value))) {
143 } else if ((event_name_ == api::OnErased::kEventName) &&
146 int my_id = -1, other_id = -1;
147 return (args_->GetAsInteger(&my_id) &&
148 other.args_->GetAsInteger(&other_id) &&
151 return json_args_ == other.json_args_;
154 std::string Debug() {
155 return base::StringPrintf("Event(%p, %s, %s, %f)",
164 std::string event_name_;
165 std::string json_args_;
166 scoped_ptr<base::Value> args_;
169 DISALLOW_COPY_AND_ASSIGN(Event);
172 typedef ExtensionDownloadsEventRouter::DownloadsNotificationSource
173 DownloadsNotificationSource;
175 virtual void Observe(int type,
176 const content::NotificationSource& source,
177 const content::NotificationDetails& details) OVERRIDE {
179 case chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT:
181 DownloadsNotificationSource* dns =
182 content::Source<DownloadsNotificationSource>(source).ptr();
183 Event* new_event = new Event(
186 *content::Details<std::string>(details).ptr(), base::Time::Now());
187 events_.push_back(new_event);
189 waiting_for_.get() &&
190 new_event->Satisfies(*waiting_for_)) {
192 base::MessageLoopForUI::current()->Quit();
201 bool WaitFor(Profile* profile,
202 const std::string& event_name,
203 const std::string& json_args) {
204 waiting_for_.reset(new Event(profile, event_name, json_args, base::Time()));
205 for (std::deque<Event*>::const_iterator iter = events_.begin();
206 iter != events_.end(); ++iter) {
207 if ((*iter)->Satisfies(*waiting_for_.get())) {
212 content::RunMessageLoop();
213 bool success = !waiting_;
215 // Print the events that were caught since the last WaitFor() call to help
216 // find the erroneous event.
217 // TODO(benjhayden) Fuzzy-match and highlight the erroneous event.
218 for (std::deque<Event*>::const_iterator iter = events_.begin();
219 iter != events_.end(); ++iter) {
220 if ((*iter)->caught() > last_wait_) {
221 LOG(INFO) << "Caught " << (*iter)->Debug();
224 if (waiting_for_.get()) {
225 LOG(INFO) << "Timed out waiting for " << waiting_for_->Debug();
229 waiting_for_.reset();
230 last_wait_ = base::Time::Now();
236 base::Time last_wait_;
237 scoped_ptr<Event> waiting_for_;
238 content::NotificationRegistrar registrar_;
239 std::deque<Event*> events_;
241 DISALLOW_COPY_AND_ASSIGN(DownloadsEventsListener);
244 class DownloadExtensionTest : public ExtensionApiTest {
246 DownloadExtensionTest()
248 incognito_browser_(NULL),
249 current_browser_(NULL) {
253 // Used with CreateHistoryDownloads
254 struct HistoryDownloadInfo {
255 // Filename to use. CreateHistoryDownloads will append this filename to the
256 // temporary downloads directory specified by downloads_directory().
257 const base::FilePath::CharType* filename;
259 // State for the download. Note that IN_PROGRESS downloads will be created
261 DownloadItem::DownloadState state;
263 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
264 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT.
265 content::DownloadDangerType danger_type;
268 void LoadExtension(const char* name) {
269 // Store the created Extension object so that we can attach it to
270 // ExtensionFunctions. Also load the extension in incognito profiles for
271 // testing incognito.
272 extension_ = LoadExtensionIncognito(test_data_dir_.AppendASCII(name));
274 content::WebContents* tab = chrome::AddSelectedTabWithURL(
276 extension_->GetResourceURL("empty.html"),
277 content::PAGE_TRANSITION_LINK);
278 extensions::ExtensionSystem::Get(current_browser()->profile())->
279 event_router()->AddEventListener(
280 api::OnCreated::kEventName,
281 tab->GetRenderProcessHost(),
283 extensions::ExtensionSystem::Get(current_browser()->profile())->
284 event_router()->AddEventListener(
285 api::OnChanged::kEventName,
286 tab->GetRenderProcessHost(),
288 extensions::ExtensionSystem::Get(current_browser()->profile())->
289 event_router()->AddEventListener(
290 api::OnErased::kEventName,
291 tab->GetRenderProcessHost(),
295 content::RenderProcessHost* AddFilenameDeterminer() {
296 content::WebContents* tab = chrome::AddSelectedTabWithURL(
298 extension_->GetResourceURL("empty.html"),
299 content::PAGE_TRANSITION_LINK);
300 extensions::ExtensionSystem::Get(current_browser()->profile())->
301 event_router()->AddEventListener(
302 api::OnDeterminingFilename::kEventName,
303 tab->GetRenderProcessHost(),
305 return tab->GetRenderProcessHost();
308 void RemoveFilenameDeterminer(content::RenderProcessHost* host) {
309 extensions::ExtensionSystem::Get(current_browser()->profile())->
310 event_router()->RemoveEventListener(
311 api::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(api::OnCreated::kEventName, on_created_event))
360 // Now, onCreated is always fired before interruption.
361 return WaitFor(api::OnChanged::kEventName,
362 base::StringPrintf("[{\"id\": %d,"
363 " \"error\": {\"current\": \"%s\"},"
365 " \"previous\": \"in_progress\","
366 " \"current\": \"interrupted\"}}]",
368 content::InterruptReasonDebugString(
369 expected_error).c_str()));
373 events_listener_->ClearEvents();
376 std::string GetExtensionURL() {
377 return extension_->url().spec();
379 std::string GetExtensionId() {
380 return extension_->id();
383 std::string GetFilename(const char* path) {
385 downloads_directory_.path().AppendASCII(path).AsUTF8Unsafe();
387 for (std::string::size_type next = result.find("\\");
388 next != std::string::npos;
389 next = result.find("\\", next)) {
390 result.replace(next, 1, "\\\\");
397 DownloadManager* GetOnRecordManager() {
398 return BrowserContext::GetDownloadManager(browser()->profile());
400 DownloadManager* GetOffRecordManager() {
401 return BrowserContext::GetDownloadManager(
402 browser()->profile()->GetOffTheRecordProfile());
404 DownloadManager* GetCurrentManager() {
405 return (current_browser_ == incognito_browser_) ?
406 GetOffRecordManager() : GetOnRecordManager();
409 // Creates a set of history downloads based on the provided |history_info|
410 // array. |count| is the number of elements in |history_info|. On success,
411 // |items| will contain |count| DownloadItems in the order that they were
412 // specified in |history_info|. Returns true on success and false otherwise.
413 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info,
415 DownloadManager::DownloadVector* items) {
416 DownloadIdComparator download_id_comparator;
417 base::Time current = base::Time::Now();
419 GetOnRecordManager()->GetAllDownloads(items);
420 CHECK_EQ(0, static_cast<int>(items->size()));
421 std::vector<GURL> url_chain;
422 url_chain.push_back(GURL());
423 for (size_t i = 0; i < count; ++i) {
424 DownloadItem* item = GetOnRecordManager()->CreateDownloadItem(
425 content::DownloadItem::kInvalidId + 1 + i,
426 downloads_directory().Append(history_info[i].filename),
427 downloads_directory().Append(history_info[i].filename),
428 url_chain, GURL(), // URL Chain, referrer
429 current, current, // start_time, end_time
430 std::string(), std::string(), // etag, last_modified
431 1, 1, // received_bytes, total_bytes
432 history_info[i].state, // state
433 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
434 content::DOWNLOAD_INTERRUPT_REASON_NONE,
436 items->push_back(item);
439 // Order by ID so that they are in the order that we created them.
440 std::sort(items->begin(), items->end(), download_id_comparator);
441 // Set the danger type if necessary.
442 for (size_t i = 0; i < count; ++i) {
443 if (history_info[i].danger_type !=
444 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
445 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT,
446 history_info[i].danger_type);
447 items->at(i)->OnContentCheckCompleted(history_info[i].danger_type);
453 void CreateSlowTestDownloads(
454 size_t count, DownloadManager::DownloadVector* items) {
455 for (size_t i = 0; i < count; ++i) {
456 scoped_ptr<content::DownloadTestObserver> observer(
457 CreateInProgressDownloadObserver(1));
458 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
459 ui_test_utils::NavigateToURLWithDisposition(
460 current_browser(), slow_download_url, CURRENT_TAB,
461 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
462 observer->WaitForFinished();
464 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
466 GetCurrentManager()->GetAllDownloads(items);
467 ASSERT_EQ(count, items->size());
470 DownloadItem* CreateSlowTestDownload() {
471 scoped_ptr<content::DownloadTestObserver> observer(
472 CreateInProgressDownloadObserver(1));
473 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
474 DownloadManager* manager = GetCurrentManager();
476 EXPECT_EQ(0, manager->NonMaliciousInProgressCount());
477 EXPECT_EQ(0, manager->InProgressCount());
478 if (manager->InProgressCount() != 0)
481 ui_test_utils::NavigateToURLWithDisposition(
482 current_browser(), slow_download_url, CURRENT_TAB,
483 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
485 observer->WaitForFinished();
486 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
488 DownloadManager::DownloadVector items;
489 manager->GetAllDownloads(&items);
491 DownloadItem* new_item = NULL;
492 for (DownloadManager::DownloadVector::iterator iter = items.begin();
493 iter != items.end(); ++iter) {
494 if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) {
495 // There should be only one IN_PROGRESS item.
496 EXPECT_EQ(NULL, new_item);
503 void FinishPendingSlowDownloads() {
504 scoped_ptr<content::DownloadTestObserver> observer(
505 CreateDownloadObserver(1));
506 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl);
507 ui_test_utils::NavigateToURLWithDisposition(
508 current_browser(), finish_url, NEW_FOREGROUND_TAB,
509 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
510 observer->WaitForFinished();
511 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
514 content::DownloadTestObserver* CreateDownloadObserver(size_t download_count) {
515 return new content::DownloadTestObserverTerminal(
516 GetCurrentManager(), download_count,
517 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
520 content::DownloadTestObserver* CreateInProgressDownloadObserver(
521 size_t download_count) {
522 return new content::DownloadTestObserverInProgress(
523 GetCurrentManager(), download_count);
526 bool RunFunction(UIThreadExtensionFunction* function,
527 const std::string& args) {
528 scoped_refptr<UIThreadExtensionFunction> delete_function(function);
529 SetUpExtensionFunction(function);
530 bool result = extension_function_test_utils::RunFunction(
531 function, args, browser(), GetFlags());
533 LOG(ERROR) << function->GetError();
538 extension_function_test_utils::RunFunctionFlags GetFlags() {
539 return current_browser()->profile()->IsOffTheRecord() ?
540 extension_function_test_utils::INCLUDE_INCOGNITO :
541 extension_function_test_utils::NONE;
544 // extension_function_test_utils::RunFunction*() only uses browser for its
545 // profile(), so pass it the on-record browser so that it always uses the
546 // on-record profile to match real-life behavior.
548 base::Value* RunFunctionAndReturnResult(
549 scoped_refptr<UIThreadExtensionFunction> function,
550 const std::string& args) {
551 SetUpExtensionFunction(function.get());
552 return extension_function_test_utils::RunFunctionAndReturnSingleResult(
553 function.get(), args, browser(), GetFlags());
556 std::string RunFunctionAndReturnError(
557 scoped_refptr<UIThreadExtensionFunction> function,
558 const std::string& args) {
559 SetUpExtensionFunction(function.get());
560 return extension_function_test_utils::RunFunctionAndReturnError(
561 function.get(), args, browser(), GetFlags());
564 bool RunFunctionAndReturnString(
565 scoped_refptr<UIThreadExtensionFunction> function,
566 const std::string& args,
567 std::string* result_string) {
568 SetUpExtensionFunction(function.get());
569 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args));
570 EXPECT_TRUE(result.get());
571 return result.get() && result->GetAsString(result_string);
574 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) {
575 return base::StringPrintf("[%d]", download_item->GetId());
578 const base::FilePath& downloads_directory() {
579 return downloads_directory_.path();
582 DownloadsEventsListener* events_listener() { return events_listener_.get(); }
585 void SetUpExtensionFunction(UIThreadExtensionFunction* function) {
587 // Recreate the tab each time for insulation.
588 content::WebContents* tab = chrome::AddSelectedTabWithURL(
590 extension_->GetResourceURL("empty.html"),
591 content::PAGE_TRANSITION_LINK);
592 function->set_extension(extension_);
593 function->SetRenderViewHost(tab->GetRenderViewHost());
597 void CreateAndSetDownloadsDirectory() {
598 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
599 current_browser()->profile()->GetPrefs()->SetFilePath(
600 prefs::kDownloadDefaultDirectory,
601 downloads_directory_.path());
604 base::ScopedTempDir downloads_directory_;
605 const extensions::Extension* extension_;
606 Browser* incognito_browser_;
607 Browser* current_browser_;
608 scoped_ptr<DownloadsEventsListener> events_listener_;
610 DISALLOW_COPY_AND_ASSIGN(DownloadExtensionTest);
613 class MockIconExtractorImpl : public DownloadFileIconExtractor {
615 MockIconExtractorImpl(const base::FilePath& path,
616 IconLoader::IconSize icon_size,
617 const std::string& response)
618 : expected_path_(path),
619 expected_icon_size_(icon_size),
620 response_(response) {
622 virtual ~MockIconExtractorImpl() {}
624 virtual bool ExtractIconURLForPath(const base::FilePath& path,
625 IconLoader::IconSize icon_size,
626 IconURLCallback callback) OVERRIDE {
627 EXPECT_STREQ(expected_path_.value().c_str(), path.value().c_str());
628 EXPECT_EQ(expected_icon_size_, icon_size);
629 if (expected_path_ == path &&
630 expected_icon_size_ == icon_size) {
631 callback_ = callback;
632 BrowserThread::PostTask(
633 BrowserThread::UI, FROM_HERE,
634 base::Bind(&MockIconExtractorImpl::RunCallback,
635 base::Unretained(this)));
644 callback_.Run(response_);
647 base::FilePath expected_path_;
648 IconLoader::IconSize expected_icon_size_;
649 std::string response_;
650 IconURLCallback callback_;
653 bool ItemNotInProgress(DownloadItem* item) {
654 return item->GetState() != DownloadItem::IN_PROGRESS;
657 // Cancels the underlying DownloadItem when the ScopedCancellingItem goes out of
658 // scope. Like a scoped_ptr, but for DownloadItems.
659 class ScopedCancellingItem {
661 explicit ScopedCancellingItem(DownloadItem* item) : item_(item) {}
662 ~ScopedCancellingItem() {
664 content::DownloadUpdatedObserver observer(
665 item_, base::Bind(&ItemNotInProgress));
666 observer.WaitForEvent();
668 DownloadItem* get() { return item_; }
671 DISALLOW_COPY_AND_ASSIGN(ScopedCancellingItem);
674 // Cancels all the underlying DownloadItems when the ScopedItemVectorCanceller
675 // goes out of scope. Generalization of ScopedCancellingItem to many
677 class ScopedItemVectorCanceller {
679 explicit ScopedItemVectorCanceller(DownloadManager::DownloadVector* items)
682 ~ScopedItemVectorCanceller() {
683 for (DownloadManager::DownloadVector::const_iterator item = items_->begin();
684 item != items_->end(); ++item) {
685 if ((*item)->GetState() == DownloadItem::IN_PROGRESS)
686 (*item)->Cancel(true);
687 content::DownloadUpdatedObserver observer(
688 (*item), base::Bind(&ItemNotInProgress));
689 observer.WaitForEvent();
694 DownloadManager::DownloadVector* items_;
695 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller);
698 // Writes an HTML5 file so that it can be downloaded.
699 class HTML5FileWriter {
701 static bool CreateFileForTesting(fileapi::FileSystemContext* context,
702 const fileapi::FileSystemURL& path,
705 // Create a temp file.
706 base::FilePath temp_file;
707 if (!file_util::CreateTemporaryFile(&temp_file) ||
708 file_util::WriteFile(temp_file, data, length) != length) {
711 // Invoke the fileapi to copy it into the sandboxed filesystem.
713 base::WaitableEvent done_event(true, false);
714 BrowserThread::PostTask(
715 BrowserThread::IO, FROM_HERE,
716 base::Bind(&CreateFileForTestingOnIOThread,
717 base::Unretained(context),
719 base::Unretained(&result),
720 base::Unretained(&done_event)));
721 // Wait for that to finish.
723 base::DeleteFile(temp_file, false);
728 static void CopyInCompletion(bool* result,
729 base::WaitableEvent* done_event,
730 base::PlatformFileError error) {
731 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
732 *result = error == base::PLATFORM_FILE_OK;
733 done_event->Signal();
736 static void CreateFileForTestingOnIOThread(
737 fileapi::FileSystemContext* context,
738 const fileapi::FileSystemURL& path,
739 const base::FilePath& temp_file,
741 base::WaitableEvent* done_event) {
742 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
743 context->operation_runner()->CopyInForeignFile(
745 base::Bind(&CopyInCompletion,
746 base::Unretained(result),
747 base::Unretained(done_event)));
751 // TODO(benjhayden) Merge this with the other TestObservers.
752 class JustInProgressDownloadObserver
753 : public content::DownloadTestObserverInProgress {
755 JustInProgressDownloadObserver(
756 DownloadManager* download_manager, size_t wait_count)
757 : content::DownloadTestObserverInProgress(download_manager, wait_count) {
760 virtual ~JustInProgressDownloadObserver() {}
763 virtual bool IsDownloadInFinalState(DownloadItem* item) OVERRIDE {
764 return item->GetState() == DownloadItem::IN_PROGRESS;
767 DISALLOW_COPY_AND_ASSIGN(JustInProgressDownloadObserver);
770 bool ItemIsInterrupted(DownloadItem* item) {
771 return item->GetState() == DownloadItem::INTERRUPTED;
774 content::DownloadInterruptReason InterruptReasonExtensionToContent(
775 api::InterruptReason error) {
777 case api::INTERRUPT_REASON_NONE:
778 return content::DOWNLOAD_INTERRUPT_REASON_NONE;
779 #define INTERRUPT_REASON(name, value) \
780 case api::INTERRUPT_REASON_##name: \
781 return content::DOWNLOAD_INTERRUPT_REASON_##name;
782 #include "content/public/browser/download_interrupt_reason_values.h"
783 #undef INTERRUPT_REASON
786 return content::DOWNLOAD_INTERRUPT_REASON_NONE;
789 api::InterruptReason InterruptReasonContentToExtension(
790 content::DownloadInterruptReason error) {
792 case content::DOWNLOAD_INTERRUPT_REASON_NONE:
793 return api::INTERRUPT_REASON_NONE;
794 #define INTERRUPT_REASON(name, value) \
795 case content::DOWNLOAD_INTERRUPT_REASON_##name: \
796 return api::INTERRUPT_REASON_##name;
797 #include "content/public/browser/download_interrupt_reason_values.h"
798 #undef INTERRUPT_REASON
801 return api::INTERRUPT_REASON_NONE;
806 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
807 DownloadExtensionTest_Open) {
808 LoadExtension("downloads_split");
809 EXPECT_STREQ(errors::kInvalidId,
810 RunFunctionAndReturnError(
811 new DownloadsOpenFunction(),
814 DownloadItem* download_item = CreateSlowTestDownload();
815 ASSERT_TRUE(download_item);
816 EXPECT_FALSE(download_item->GetOpened());
817 EXPECT_FALSE(download_item->GetOpenWhenComplete());
818 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
819 base::StringPrintf("[{\"danger\": \"safe\","
820 " \"incognito\": false,"
821 " \"mime\": \"application/octet-stream\","
822 " \"paused\": false,"
823 " \"url\": \"%s\"}]",
824 download_item->GetURL().spec().c_str())));
825 EXPECT_STREQ(errors::kNotComplete,
826 RunFunctionAndReturnError(
827 new DownloadsOpenFunction(),
828 DownloadItemIdAsArgList(download_item)).c_str());
830 FinishPendingSlowDownloads();
831 EXPECT_FALSE(download_item->GetOpened());
832 EXPECT_TRUE(RunFunction(new DownloadsOpenFunction(),
833 DownloadItemIdAsArgList(download_item)));
834 EXPECT_TRUE(download_item->GetOpened());
837 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
838 DownloadExtensionTest_PauseResumeCancelErase) {
839 DownloadItem* download_item = CreateSlowTestDownload();
840 ASSERT_TRUE(download_item);
842 // Call pause(). It should succeed and the download should be paused on
844 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
845 DownloadItemIdAsArgList(download_item)));
846 EXPECT_TRUE(download_item->IsPaused());
848 // Calling pause() twice shouldn't be an error.
849 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
850 DownloadItemIdAsArgList(download_item)));
851 EXPECT_TRUE(download_item->IsPaused());
853 // Now try resuming this download. It should succeed.
854 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
855 DownloadItemIdAsArgList(download_item)));
856 EXPECT_FALSE(download_item->IsPaused());
858 // Resume again. Resuming a download that wasn't paused is not an error.
859 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
860 DownloadItemIdAsArgList(download_item)));
861 EXPECT_FALSE(download_item->IsPaused());
864 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
865 DownloadItemIdAsArgList(download_item)));
866 EXPECT_TRUE(download_item->IsPaused());
869 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
870 DownloadItemIdAsArgList(download_item)));
871 EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());
873 // Cancel again. Shouldn't have any effect.
874 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
875 DownloadItemIdAsArgList(download_item)));
876 EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());
878 // Calling paused on a non-active download yields kInvalidId.
879 std::string error = RunFunctionAndReturnError(
880 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item));
881 EXPECT_STREQ(errors::kNotInProgress, error.c_str());
883 // Calling resume on a non-active download yields kInvalidId
884 error = RunFunctionAndReturnError(
885 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item));
886 EXPECT_STREQ(errors::kNotResumable, error.c_str());
888 // Calling paused on a non-existent download yields kInvalidId.
889 error = RunFunctionAndReturnError(
890 new DownloadsPauseFunction(), "[-42]");
891 EXPECT_STREQ(errors::kInvalidId, error.c_str());
893 // Calling resume on a non-existent download yields kInvalidId
894 error = RunFunctionAndReturnError(
895 new DownloadsResumeFunction(), "[-42]");
896 EXPECT_STREQ(errors::kInvalidId, error.c_str());
898 int id = download_item->GetId();
899 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
900 new DownloadsEraseFunction(),
901 base::StringPrintf("[{\"id\": %d}]", id)));
902 DownloadManager::DownloadVector items;
903 GetCurrentManager()->GetAllDownloads(&items);
904 EXPECT_EQ(0UL, items.size());
906 download_item = NULL;
907 base::ListValue* result_list = NULL;
908 ASSERT_TRUE(result->GetAsList(&result_list));
909 ASSERT_EQ(1UL, result_list->GetSize());
911 ASSERT_TRUE(result_list->GetInteger(0, &element));
912 EXPECT_EQ(id, element);
915 scoped_refptr<UIThreadExtensionFunction> MockedGetFileIconFunction(
916 const base::FilePath& expected_path,
917 IconLoader::IconSize icon_size,
918 const std::string& response) {
919 scoped_refptr<DownloadsGetFileIconFunction> function(
920 new DownloadsGetFileIconFunction());
921 function->SetIconExtractorForTesting(new MockIconExtractorImpl(
922 expected_path, icon_size, response));
926 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted
928 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
929 DownloadExtensionTest_FileIcon_Active) {
930 DownloadItem* download_item = CreateSlowTestDownload();
931 ASSERT_TRUE(download_item);
932 ASSERT_FALSE(download_item->GetTargetFilePath().empty());
933 std::string args32(base::StringPrintf("[%d, {\"size\": 32}]",
934 download_item->GetId()));
935 std::string result_string;
937 // Get the icon for the in-progress download. This call should succeed even
938 // if the file type isn't registered.
939 // Test whether the correct path is being pased into the icon extractor.
940 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
941 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
942 base::StringPrintf("[%d, {}]", download_item->GetId()), &result_string));
944 // Now try a 16x16 icon.
945 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
946 download_item->GetTargetFilePath(), IconLoader::SMALL, "foo"),
947 base::StringPrintf("[%d, {\"size\": 16}]", download_item->GetId()),
950 // Explicitly asking for 32x32 should give us a 32x32 icon.
951 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
952 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
953 args32, &result_string));
955 // Finish the download and try again.
956 FinishPendingSlowDownloads();
957 EXPECT_EQ(DownloadItem::COMPLETE, download_item->GetState());
958 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
959 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
960 args32, &result_string));
962 // Check the path passed to the icon extractor post-completion.
963 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
964 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
965 args32, &result_string));
967 // Now create another download.
968 download_item = CreateSlowTestDownload();
969 ASSERT_TRUE(download_item);
970 ASSERT_FALSE(download_item->GetTargetFilePath().empty());
971 args32 = base::StringPrintf("[%d, {\"size\": 32}]", download_item->GetId());
973 // Cancel the download. As long as the download has a target path, we should
974 // be able to query the file icon.
975 download_item->Cancel(true);
976 ASSERT_FALSE(download_item->GetTargetFilePath().empty());
977 // Let cleanup complete on the FILE thread.
978 content::RunAllPendingInMessageLoop(BrowserThread::FILE);
979 // Check the path passed to the icon extractor post-cancellation.
980 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
981 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
985 // Simulate an error during icon load by invoking the mock with an empty
987 std::string error = RunFunctionAndReturnError(
988 MockedGetFileIconFunction(download_item->GetTargetFilePath(),
992 EXPECT_STREQ(errors::kIconNotFound, error.c_str());
994 // Once the download item is deleted, we should return kInvalidId.
995 int id = download_item->GetId();
996 download_item->Remove();
997 download_item = NULL;
998 EXPECT_EQ(static_cast<DownloadItem*>(NULL),
999 GetCurrentManager()->GetDownload(id));
1000 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args32);
1001 EXPECT_STREQ(errors::kInvalidId,
1005 // Test that we can acquire file icons for history downloads regardless of
1006 // whether they exist or not. If the file doesn't exist we should receive a
1007 // generic icon from the OS/toolkit that may or may not be specific to the file
1009 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1010 DownloadExtensionTest_FileIcon_History) {
1011 const HistoryDownloadInfo kHistoryInfo[] = {
1012 { FILE_PATH_LITERAL("real.txt"),
1013 DownloadItem::COMPLETE,
1014 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1015 { FILE_PATH_LITERAL("fake.txt"),
1016 DownloadItem::COMPLETE,
1017 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1019 DownloadManager::DownloadVector all_downloads;
1020 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1023 base::FilePath real_path = all_downloads[0]->GetTargetFilePath();
1024 base::FilePath fake_path = all_downloads[1]->GetTargetFilePath();
1026 EXPECT_EQ(0, file_util::WriteFile(real_path, "", 0));
1027 ASSERT_TRUE(base::PathExists(real_path));
1028 ASSERT_FALSE(base::PathExists(fake_path));
1030 for (DownloadManager::DownloadVector::iterator iter = all_downloads.begin();
1031 iter != all_downloads.end();
1033 std::string result_string;
1034 // Use a MockIconExtractorImpl to test if the correct path is being passed
1035 // into the DownloadFileIconExtractor.
1036 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1037 (*iter)->GetTargetFilePath(), IconLoader::NORMAL, "hello"),
1038 base::StringPrintf("[%d, {\"size\": 32}]", (*iter)->GetId()),
1040 EXPECT_STREQ("hello", result_string.c_str());
1044 // Test passing the empty query to search().
1045 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1046 DownloadExtensionTest_SearchEmptyQuery) {
1047 ScopedCancellingItem item(CreateSlowTestDownload());
1048 ASSERT_TRUE(item.get());
1050 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1051 new DownloadsSearchFunction(), "[{}]"));
1052 ASSERT_TRUE(result.get());
1053 base::ListValue* result_list = NULL;
1054 ASSERT_TRUE(result->GetAsList(&result_list));
1055 ASSERT_EQ(1UL, result_list->GetSize());
1058 // Test the |filenameRegex| parameter for search().
1059 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1060 DownloadExtensionTest_SearchFilenameRegex) {
1061 const HistoryDownloadInfo kHistoryInfo[] = {
1062 { FILE_PATH_LITERAL("foobar"),
1063 DownloadItem::COMPLETE,
1064 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1065 { FILE_PATH_LITERAL("baz"),
1066 DownloadItem::COMPLETE,
1067 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1069 DownloadManager::DownloadVector all_downloads;
1070 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1073 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1074 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]"));
1075 ASSERT_TRUE(result.get());
1076 base::ListValue* result_list = NULL;
1077 ASSERT_TRUE(result->GetAsList(&result_list));
1078 ASSERT_EQ(1UL, result_list->GetSize());
1079 base::DictionaryValue* item_value = NULL;
1080 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
1082 ASSERT_TRUE(item_value->GetInteger("id", &item_id));
1083 ASSERT_EQ(all_downloads[0]->GetId(), static_cast<uint32>(item_id));
1086 // Test the |id| parameter for search().
1087 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_SearchId) {
1088 DownloadManager::DownloadVector items;
1089 CreateSlowTestDownloads(2, &items);
1090 ScopedItemVectorCanceller delete_items(&items);
1092 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1093 new DownloadsSearchFunction(), base::StringPrintf(
1094 "[{\"id\": %u}]", items[0]->GetId())));
1095 ASSERT_TRUE(result.get());
1096 base::ListValue* result_list = NULL;
1097 ASSERT_TRUE(result->GetAsList(&result_list));
1098 ASSERT_EQ(1UL, result_list->GetSize());
1099 base::DictionaryValue* item_value = NULL;
1100 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
1102 ASSERT_TRUE(item_value->GetInteger("id", &item_id));
1103 ASSERT_EQ(items[0]->GetId(), static_cast<uint32>(item_id));
1106 // Test specifying both the |id| and |filename| parameters for search().
1107 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1108 DownloadExtensionTest_SearchIdAndFilename) {
1109 DownloadManager::DownloadVector items;
1110 CreateSlowTestDownloads(2, &items);
1111 ScopedItemVectorCanceller delete_items(&items);
1113 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1114 new DownloadsSearchFunction(),
1115 "[{\"id\": 0, \"filename\": \"foobar\"}]"));
1116 ASSERT_TRUE(result.get());
1117 base::ListValue* result_list = NULL;
1118 ASSERT_TRUE(result->GetAsList(&result_list));
1119 ASSERT_EQ(0UL, result_list->GetSize());
1122 // Test a single |orderBy| parameter for search().
1123 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1124 DownloadExtensionTest_SearchOrderBy) {
1125 const HistoryDownloadInfo kHistoryInfo[] = {
1126 { FILE_PATH_LITERAL("zzz"),
1127 DownloadItem::COMPLETE,
1128 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1129 { FILE_PATH_LITERAL("baz"),
1130 DownloadItem::COMPLETE,
1131 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1133 DownloadManager::DownloadVector items;
1134 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1137 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1138 new DownloadsSearchFunction(), "[{\"orderBy\": [\"filename\"]}]"));
1139 ASSERT_TRUE(result.get());
1140 base::ListValue* result_list = NULL;
1141 ASSERT_TRUE(result->GetAsList(&result_list));
1142 ASSERT_EQ(2UL, result_list->GetSize());
1143 base::DictionaryValue* item0_value = NULL;
1144 base::DictionaryValue* item1_value = NULL;
1145 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value));
1146 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value));
1147 std::string item0_name, item1_name;
1148 ASSERT_TRUE(item0_value->GetString("filename", &item0_name));
1149 ASSERT_TRUE(item1_value->GetString("filename", &item1_name));
1150 ASSERT_GT(items[0]->GetTargetFilePath().value(),
1151 items[1]->GetTargetFilePath().value());
1152 ASSERT_LT(item0_name, item1_name);
1155 // Test specifying an empty |orderBy| parameter for search().
1156 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1157 DownloadExtensionTest_SearchOrderByEmpty) {
1158 const HistoryDownloadInfo kHistoryInfo[] = {
1159 { FILE_PATH_LITERAL("zzz"),
1160 DownloadItem::COMPLETE,
1161 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1162 { FILE_PATH_LITERAL("baz"),
1163 DownloadItem::COMPLETE,
1164 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1166 DownloadManager::DownloadVector items;
1167 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1170 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1171 new DownloadsSearchFunction(), "[{\"orderBy\": []}]"));
1172 ASSERT_TRUE(result.get());
1173 base::ListValue* result_list = NULL;
1174 ASSERT_TRUE(result->GetAsList(&result_list));
1175 ASSERT_EQ(2UL, result_list->GetSize());
1176 base::DictionaryValue* item0_value = NULL;
1177 base::DictionaryValue* item1_value = NULL;
1178 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value));
1179 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value));
1180 std::string item0_name, item1_name;
1181 ASSERT_TRUE(item0_value->GetString("filename", &item0_name));
1182 ASSERT_TRUE(item1_value->GetString("filename", &item1_name));
1183 ASSERT_GT(items[0]->GetTargetFilePath().value(),
1184 items[1]->GetTargetFilePath().value());
1185 ASSERT_GT(item0_name, item1_name);
1188 // Test the |danger| option for search().
1189 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1190 DownloadExtensionTest_SearchDanger) {
1191 const HistoryDownloadInfo kHistoryInfo[] = {
1192 { FILE_PATH_LITERAL("zzz"),
1193 DownloadItem::COMPLETE,
1194 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
1195 { FILE_PATH_LITERAL("baz"),
1196 DownloadItem::COMPLETE,
1197 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1199 DownloadManager::DownloadVector items;
1200 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1203 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1204 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]"));
1205 ASSERT_TRUE(result.get());
1206 base::ListValue* result_list = NULL;
1207 ASSERT_TRUE(result->GetAsList(&result_list));
1208 ASSERT_EQ(1UL, result_list->GetSize());
1211 // Test the |state| option for search().
1212 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1213 DownloadExtensionTest_SearchState) {
1214 DownloadManager::DownloadVector items;
1215 CreateSlowTestDownloads(2, &items);
1216 ScopedItemVectorCanceller delete_items(&items);
1218 items[0]->Cancel(true);
1220 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1221 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]"));
1222 ASSERT_TRUE(result.get());
1223 base::ListValue* result_list = NULL;
1224 ASSERT_TRUE(result->GetAsList(&result_list));
1225 ASSERT_EQ(1UL, result_list->GetSize());
1228 // Test the |limit| option for search().
1229 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1230 DownloadExtensionTest_SearchLimit) {
1231 DownloadManager::DownloadVector items;
1232 CreateSlowTestDownloads(2, &items);
1233 ScopedItemVectorCanceller delete_items(&items);
1235 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1236 new DownloadsSearchFunction(), "[{\"limit\": 1}]"));
1237 ASSERT_TRUE(result.get());
1238 base::ListValue* result_list = NULL;
1239 ASSERT_TRUE(result->GetAsList(&result_list));
1240 ASSERT_EQ(1UL, result_list->GetSize());
1243 // Test invalid search parameters.
1244 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1245 DownloadExtensionTest_SearchInvalid) {
1246 std::string error = RunFunctionAndReturnError(
1247 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]");
1248 EXPECT_STREQ(errors::kInvalidFilter,
1250 error = RunFunctionAndReturnError(
1251 new DownloadsSearchFunction(), "[{\"orderBy\": [\"goat\"]}]");
1252 EXPECT_STREQ(errors::kInvalidOrderBy,
1254 error = RunFunctionAndReturnError(
1255 new DownloadsSearchFunction(), "[{\"limit\": -1}]");
1256 EXPECT_STREQ(errors::kInvalidQueryLimit,
1260 // Test searching using multiple conditions through multiple downloads.
1261 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1262 DownloadExtensionTest_SearchPlural) {
1263 const HistoryDownloadInfo kHistoryInfo[] = {
1264 { FILE_PATH_LITERAL("aaa"),
1265 DownloadItem::CANCELLED,
1266 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1267 { FILE_PATH_LITERAL("zzz"),
1268 DownloadItem::COMPLETE,
1269 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
1270 { FILE_PATH_LITERAL("baz"),
1271 DownloadItem::COMPLETE,
1272 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
1274 DownloadManager::DownloadVector items;
1275 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1278 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1279 new DownloadsSearchFunction(), "[{"
1280 "\"state\": \"complete\", "
1281 "\"danger\": \"content\", "
1282 "\"orderBy\": [\"filename\"], "
1284 ASSERT_TRUE(result.get());
1285 base::ListValue* result_list = NULL;
1286 ASSERT_TRUE(result->GetAsList(&result_list));
1287 ASSERT_EQ(1UL, result_list->GetSize());
1288 base::DictionaryValue* item_value = NULL;
1289 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
1290 base::FilePath::StringType item_name;
1291 ASSERT_TRUE(item_value->GetString("filename", &item_name));
1292 ASSERT_EQ(items[2]->GetTargetFilePath().value(), item_name);
1295 // Test that incognito downloads are only visible in incognito contexts, and
1296 // test that on-record downloads are visible in both incognito and on-record
1297 // contexts, for DownloadsSearchFunction, DownloadsPauseFunction,
1298 // DownloadsResumeFunction, and DownloadsCancelFunction.
1299 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1300 DownloadExtensionTest_SearchPauseResumeCancelGetFileIconIncognito) {
1301 scoped_ptr<base::Value> result_value;
1302 base::ListValue* result_list = NULL;
1303 base::DictionaryValue* result_dict = NULL;
1304 base::FilePath::StringType filename;
1305 bool is_incognito = false;
1307 std::string on_item_arg;
1308 std::string off_item_arg;
1309 std::string result_string;
1311 // Set up one on-record item and one off-record item.
1312 // Set up the off-record item first because otherwise there are mysteriously 3
1313 // items total instead of 2.
1314 // TODO(benjhayden): Figure out where the third item comes from.
1316 DownloadItem* off_item = CreateSlowTestDownload();
1317 ASSERT_TRUE(off_item);
1318 off_item_arg = DownloadItemIdAsArgList(off_item);
1321 DownloadItem* on_item = CreateSlowTestDownload();
1322 ASSERT_TRUE(on_item);
1323 on_item_arg = DownloadItemIdAsArgList(on_item);
1324 ASSERT_TRUE(on_item->GetTargetFilePath() != off_item->GetTargetFilePath());
1326 // Extensions running in the incognito window should have access to both
1327 // items because the Test extension is in spanning mode.
1329 result_value.reset(RunFunctionAndReturnResult(
1330 new DownloadsSearchFunction(), "[{}]"));
1331 ASSERT_TRUE(result_value.get());
1332 ASSERT_TRUE(result_value->GetAsList(&result_list));
1333 ASSERT_EQ(2UL, result_list->GetSize());
1334 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict));
1335 ASSERT_TRUE(result_dict->GetString("filename", &filename));
1336 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
1337 EXPECT_TRUE(on_item->GetTargetFilePath() == base::FilePath(filename));
1338 EXPECT_FALSE(is_incognito);
1339 ASSERT_TRUE(result_list->GetDictionary(1, &result_dict));
1340 ASSERT_TRUE(result_dict->GetString("filename", &filename));
1341 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
1342 EXPECT_TRUE(off_item->GetTargetFilePath() == base::FilePath(filename));
1343 EXPECT_TRUE(is_incognito);
1345 // Extensions running in the on-record window should have access only to the
1348 result_value.reset(RunFunctionAndReturnResult(
1349 new DownloadsSearchFunction(), "[{}]"));
1350 ASSERT_TRUE(result_value.get());
1351 ASSERT_TRUE(result_value->GetAsList(&result_list));
1352 ASSERT_EQ(1UL, result_list->GetSize());
1353 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict));
1354 ASSERT_TRUE(result_dict->GetString("filename", &filename));
1355 EXPECT_TRUE(on_item->GetTargetFilePath() == base::FilePath(filename));
1356 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
1357 EXPECT_FALSE(is_incognito);
1359 // Pausing/Resuming the off-record item while on the record should return an
1360 // error. Cancelling "non-existent" downloads is not an error.
1361 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg);
1362 EXPECT_STREQ(errors::kInvalidId,
1364 error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
1366 EXPECT_STREQ(errors::kInvalidId,
1368 error = RunFunctionAndReturnError(
1369 new DownloadsGetFileIconFunction(),
1370 base::StringPrintf("[%d, {}]", off_item->GetId()));
1371 EXPECT_STREQ(errors::kInvalidId,
1376 // Do the FileIcon test for both the on- and off-items while off the record.
1377 // NOTE(benjhayden): This does not include the FileIcon test from history,
1378 // just active downloads. This shouldn't be a problem.
1379 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1380 on_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
1381 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string));
1382 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1383 off_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
1384 base::StringPrintf("[%d, {}]", off_item->GetId()), &result_string));
1386 // Do the pause/resume/cancel test for both the on- and off-items while off
1388 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
1389 EXPECT_TRUE(on_item->IsPaused());
1390 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
1391 EXPECT_TRUE(on_item->IsPaused());
1392 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg));
1393 EXPECT_FALSE(on_item->IsPaused());
1394 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg));
1395 EXPECT_FALSE(on_item->IsPaused());
1396 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
1397 EXPECT_TRUE(on_item->IsPaused());
1398 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg));
1399 EXPECT_EQ(DownloadItem::CANCELLED, on_item->GetState());
1400 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg));
1401 EXPECT_EQ(DownloadItem::CANCELLED, on_item->GetState());
1402 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), on_item_arg);
1403 EXPECT_STREQ(errors::kNotInProgress, error.c_str());
1404 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), on_item_arg);
1405 EXPECT_STREQ(errors::kNotResumable, error.c_str());
1406 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
1407 EXPECT_TRUE(off_item->IsPaused());
1408 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
1409 EXPECT_TRUE(off_item->IsPaused());
1410 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg));
1411 EXPECT_FALSE(off_item->IsPaused());
1412 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg));
1413 EXPECT_FALSE(off_item->IsPaused());
1414 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
1415 EXPECT_TRUE(off_item->IsPaused());
1416 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg));
1417 EXPECT_EQ(DownloadItem::CANCELLED, off_item->GetState());
1418 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg));
1419 EXPECT_EQ(DownloadItem::CANCELLED, off_item->GetState());
1420 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg);
1421 EXPECT_STREQ(errors::kNotInProgress, error.c_str());
1422 error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
1424 EXPECT_STREQ(errors::kNotResumable, error.c_str());
1427 // Test that we can start a download and that the correct sequence of events is
1429 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1430 DownloadExtensionTest_Download_Basic) {
1431 LoadExtension("downloads_split");
1432 ASSERT_TRUE(StartEmbeddedTestServer());
1433 ASSERT_TRUE(test_server()->Start());
1434 std::string download_url = test_server()->GetURL("slow?0").spec();
1437 // Start downloading a file.
1438 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1439 new DownloadsDownloadFunction(), base::StringPrintf(
1440 "[{\"url\": \"%s\"}]", download_url.c_str())));
1441 ASSERT_TRUE(result.get());
1443 ASSERT_TRUE(result->GetAsInteger(&result_id));
1444 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1446 ScopedCancellingItem canceller(item);
1447 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1449 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1450 base::StringPrintf("[{\"danger\": \"safe\","
1451 " \"incognito\": false,"
1452 " \"mime\": \"text/plain\","
1453 " \"paused\": false,"
1454 " \"url\": \"%s\"}]",
1455 download_url.c_str())));
1456 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1457 base::StringPrintf("[{\"id\": %d,"
1459 " \"previous\": \"\","
1460 " \"current\": \"%s\"}}]",
1462 GetFilename("slow.txt").c_str())));
1463 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1464 base::StringPrintf("[{\"id\": %d,"
1466 " \"previous\": \"in_progress\","
1467 " \"current\": \"complete\"}}]",
1471 // Test that we can start a download from an incognito context, and that the
1472 // download knows that it's incognito.
1473 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1474 DownloadExtensionTest_Download_Incognito) {
1475 LoadExtension("downloads_split");
1476 ASSERT_TRUE(StartEmbeddedTestServer());
1477 ASSERT_TRUE(test_server()->Start());
1479 std::string download_url = test_server()->GetURL("slow?0").spec();
1481 // Start downloading a file.
1482 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1483 new DownloadsDownloadFunction(), base::StringPrintf(
1484 "[{\"url\": \"%s\"}]", download_url.c_str())));
1485 ASSERT_TRUE(result.get());
1487 ASSERT_TRUE(result->GetAsInteger(&result_id));
1488 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1490 ScopedCancellingItem canceller(item);
1491 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1493 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1494 base::StringPrintf("[{\"danger\": \"safe\","
1495 " \"incognito\": true,"
1496 " \"mime\": \"text/plain\","
1497 " \"paused\": false,"
1498 " \"url\": \"%s\"}]",
1499 download_url.c_str())));
1500 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1501 base::StringPrintf("[{\"id\":%d,"
1503 " \"previous\": \"\","
1504 " \"current\": \"%s\"}}]",
1506 GetFilename("slow.txt").c_str())));
1507 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1508 base::StringPrintf("[{\"id\":%d,"
1510 " \"current\": \"complete\","
1511 " \"previous\": \"in_progress\"}}]",
1515 #if defined(OS_WIN) && defined(USE_AURA)
1516 // This test is very flaky on Win Aura. http://crbug.com/248438
1517 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1518 DISABLED_DownloadExtensionTest_Download_UnsafeHeaders
1520 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1521 DownloadExtensionTest_Download_UnsafeHeaders
1524 // Test that we disallow certain headers case-insensitively.
1525 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1526 MAYBE_DownloadExtensionTest_Download_UnsafeHeaders) {
1527 LoadExtension("downloads_split");
1528 ASSERT_TRUE(StartEmbeddedTestServer());
1529 ASSERT_TRUE(test_server()->Start());
1532 static const char* kUnsafeHeaders[] = {
1539 "coNteNt-traNsfer-eNcodiNg",
1547 "trANsfer-eNcodiNg",
1553 "pRoxY-probably-not-evil",
1554 "sEc-probably-not-evil",
1556 "Access-Control-Request-Headers",
1557 "Access-Control-Request-Method",
1560 for (size_t index = 0; index < arraysize(kUnsafeHeaders); ++index) {
1561 std::string download_url = test_server()->GetURL("slow?0").spec();
1562 EXPECT_STREQ(errors::kInvalidHeader,
1563 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1565 "[{\"url\": \"%s\","
1566 " \"filename\": \"unsafe-header-%d.txt\","
1568 " \"name\": \"%s\","
1569 " \"value\": \"unsafe\"}]}]",
1570 download_url.c_str(),
1571 static_cast<int>(index),
1572 kUnsafeHeaders[index])).c_str());
1577 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1578 DISABLED_DownloadExtensionTest_Download_Subdirectory
1580 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1581 DownloadExtensionTest_Download_Subdirectory
1583 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1584 MAYBE_DownloadExtensionTest_Download_Subdirectory) {
1585 LoadExtension("downloads_split");
1586 ASSERT_TRUE(StartEmbeddedTestServer());
1587 ASSERT_TRUE(test_server()->Start());
1588 std::string download_url = test_server()->GetURL("slow?0").spec();
1591 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1592 new DownloadsDownloadFunction(), base::StringPrintf(
1593 "[{\"url\": \"%s\","
1594 " \"filename\": \"sub/dir/ect/ory.txt\"}]",
1595 download_url.c_str())));
1596 ASSERT_TRUE(result.get());
1598 ASSERT_TRUE(result->GetAsInteger(&result_id));
1599 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1601 ScopedCancellingItem canceller(item);
1602 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1604 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1605 base::StringPrintf("[{\"danger\": \"safe\","
1606 " \"incognito\": false,"
1607 " \"mime\": \"text/plain\","
1608 " \"paused\": false,"
1609 " \"url\": \"%s\"}]",
1610 download_url.c_str())));
1611 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1612 base::StringPrintf("[{\"id\": %d,"
1614 " \"previous\": \"\","
1615 " \"current\": \"%s\"}}]",
1617 GetFilename("sub/dir/ect/ory.txt").c_str())));
1618 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1619 base::StringPrintf("[{\"id\": %d,"
1621 " \"previous\": \"in_progress\","
1622 " \"current\": \"complete\"}}]",
1626 // Test that invalid filenames are disallowed.
1627 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1628 DownloadExtensionTest_Download_InvalidFilename) {
1629 LoadExtension("downloads_split");
1630 ASSERT_TRUE(StartEmbeddedTestServer());
1631 ASSERT_TRUE(test_server()->Start());
1632 std::string download_url = test_server()->GetURL("slow?0").spec();
1635 EXPECT_STREQ(errors::kInvalidFilename,
1636 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1638 "[{\"url\": \"%s\","
1639 " \"filename\": \"../../../../../etc/passwd\"}]",
1640 download_url.c_str())).c_str());
1643 // Test that downloading invalid URLs immediately returns kInvalidURLError.
1644 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1645 DownloadExtensionTest_Download_InvalidURLs) {
1646 LoadExtension("downloads_split");
1649 static const char* kInvalidURLs[] = {
1655 "foo/bar.html#frag",
1659 for (size_t index = 0; index < arraysize(kInvalidURLs); ++index) {
1660 EXPECT_STREQ(errors::kInvalidURL,
1661 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1663 "[{\"url\": \"%s\"}]", kInvalidURLs[index])).c_str())
1664 << kInvalidURLs[index];
1667 EXPECT_STREQ("net::ERR_ACCESS_DENIED", RunFunctionAndReturnError(
1668 new DownloadsDownloadFunction(),
1669 "[{\"url\": \"javascript:document.write(\\\"hello\\\");\"}]").c_str());
1670 EXPECT_STREQ("net::ERR_ACCESS_DENIED", RunFunctionAndReturnError(
1671 new DownloadsDownloadFunction(),
1672 "[{\"url\": \"javascript:return false;\"}]").c_str());
1673 EXPECT_STREQ("net::ERR_NOT_IMPLEMENTED", RunFunctionAndReturnError(
1674 new DownloadsDownloadFunction(),
1675 "[{\"url\": \"ftp://example.com/example.txt\"}]").c_str());
1678 // TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to
1679 // permissions, test downloading from ftp.
1681 // Valid URLs plus fragments are still valid URLs.
1682 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1683 DownloadExtensionTest_Download_URLFragment) {
1684 LoadExtension("downloads_split");
1685 ASSERT_TRUE(StartEmbeddedTestServer());
1686 ASSERT_TRUE(test_server()->Start());
1687 std::string download_url = test_server()->GetURL("slow?0#fragment").spec();
1690 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1691 new DownloadsDownloadFunction(), base::StringPrintf(
1692 "[{\"url\": \"%s\"}]", download_url.c_str())));
1693 ASSERT_TRUE(result.get());
1695 ASSERT_TRUE(result->GetAsInteger(&result_id));
1696 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1698 ScopedCancellingItem canceller(item);
1699 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1701 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1702 base::StringPrintf("[{\"danger\": \"safe\","
1703 " \"incognito\": false,"
1704 " \"mime\": \"text/plain\","
1705 " \"paused\": false,"
1706 " \"url\": \"%s\"}]",
1707 download_url.c_str())));
1708 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1709 base::StringPrintf("[{\"id\": %d,"
1711 " \"previous\": \"\","
1712 " \"current\": \"%s\"}}]",
1714 GetFilename("slow.txt").c_str())));
1715 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1716 base::StringPrintf("[{\"id\": %d,"
1718 " \"previous\": \"in_progress\","
1719 " \"current\": \"complete\"}}]",
1723 // Valid data URLs are valid URLs.
1724 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1725 DownloadExtensionTest_Download_DataURL) {
1726 LoadExtension("downloads_split");
1727 std::string download_url = "data:text/plain,hello";
1730 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1731 new DownloadsDownloadFunction(), base::StringPrintf(
1732 "[{\"url\": \"%s\","
1733 " \"filename\": \"data.txt\"}]", download_url.c_str())));
1734 ASSERT_TRUE(result.get());
1736 ASSERT_TRUE(result->GetAsInteger(&result_id));
1737 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1739 ScopedCancellingItem canceller(item);
1740 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1742 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1743 base::StringPrintf("[{\"danger\": \"safe\","
1744 " \"incognito\": false,"
1745 " \"mime\": \"text/plain\","
1746 " \"paused\": false,"
1747 " \"url\": \"%s\"}]",
1748 download_url.c_str())));
1749 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1750 base::StringPrintf("[{\"id\": %d,"
1752 " \"previous\": \"\","
1753 " \"current\": \"%s\"}}]",
1755 GetFilename("data.txt").c_str())));
1756 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1757 base::StringPrintf("[{\"id\": %d,"
1759 " \"previous\": \"in_progress\","
1760 " \"current\": \"complete\"}}]",
1764 // Valid file URLs are valid URLs.
1765 #if defined(OS_WIN) && defined(USE_AURA)
1766 // Disabled due to crbug.com/175711
1767 #define MAYBE_DownloadExtensionTest_Download_File \
1768 DISABLED_DownloadExtensionTest_Download_File
1770 #define MAYBE_DownloadExtensionTest_Download_File \
1771 DownloadExtensionTest_Download_File
1773 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1774 MAYBE_DownloadExtensionTest_Download_File) {
1776 LoadExtension("downloads_split");
1777 std::string download_url = "file:///";
1779 download_url += "C:/";
1782 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1783 new DownloadsDownloadFunction(), base::StringPrintf(
1784 "[{\"url\": \"%s\","
1785 " \"filename\": \"file.txt\"}]", download_url.c_str())));
1786 ASSERT_TRUE(result.get());
1788 ASSERT_TRUE(result->GetAsInteger(&result_id));
1789 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1791 ScopedCancellingItem canceller(item);
1792 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1794 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1795 base::StringPrintf("[{\"danger\": \"safe\","
1796 " \"incognito\": false,"
1797 " \"mime\": \"text/html\","
1798 " \"paused\": false,"
1799 " \"url\": \"%s\"}]",
1800 download_url.c_str())));
1801 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1802 base::StringPrintf("[{\"id\": %d,"
1804 " \"previous\": \"\","
1805 " \"current\": \"%s\"}}]",
1807 GetFilename("file.txt").c_str())));
1808 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1809 base::StringPrintf("[{\"id\": %d,"
1811 " \"previous\": \"in_progress\","
1812 " \"current\": \"complete\"}}]",
1816 // Test that auth-basic-succeed would fail if the resource requires the
1817 // Authorization header and chrome fails to propagate it back to the server.
1818 // This tests both that testserver.py does not succeed when it should fail as
1819 // well as how the downloads extension API exposes the failure to extensions.
1820 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1821 DownloadExtensionTest_Download_AuthBasic_Fail) {
1822 LoadExtension("downloads_split");
1823 ASSERT_TRUE(StartEmbeddedTestServer());
1824 ASSERT_TRUE(test_server()->Start());
1825 std::string download_url = test_server()->GetURL("auth-basic").spec();
1828 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1829 new DownloadsDownloadFunction(), base::StringPrintf(
1830 "[{\"url\": \"%s\","
1831 " \"filename\": \"auth-basic-fail.txt\"}]",
1832 download_url.c_str())));
1833 ASSERT_TRUE(result.get());
1835 ASSERT_TRUE(result->GetAsInteger(&result_id));
1836 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1838 ScopedCancellingItem canceller(item);
1839 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1841 ASSERT_TRUE(WaitForInterruption(
1843 content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED,
1844 base::StringPrintf("[{\"danger\": \"safe\","
1845 " \"incognito\": false,"
1846 " \"mime\": \"text/html\","
1847 " \"paused\": false,"
1848 " \"url\": \"%s\"}]",
1849 download_url.c_str())));
1852 // Test that DownloadsDownloadFunction propagates |headers| to the URLRequest.
1853 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1854 DownloadExtensionTest_Download_Headers) {
1855 LoadExtension("downloads_split");
1856 ASSERT_TRUE(StartEmbeddedTestServer());
1857 ASSERT_TRUE(test_server()->Start());
1858 std::string download_url = test_server()->GetURL("files/downloads/"
1859 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
1862 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1863 new DownloadsDownloadFunction(), base::StringPrintf(
1864 "[{\"url\": \"%s\","
1865 " \"filename\": \"headers-succeed.txt\","
1867 " {\"name\": \"Foo\", \"value\": \"bar\"},"
1868 " {\"name\": \"Qx\", \"value\":\"yo\"}]}]",
1869 download_url.c_str())));
1870 ASSERT_TRUE(result.get());
1872 ASSERT_TRUE(result->GetAsInteger(&result_id));
1873 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1875 ScopedCancellingItem canceller(item);
1876 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1878 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1879 base::StringPrintf("[{\"danger\": \"safe\","
1880 " \"incognito\": false,"
1881 " \"mime\": \"application/octet-stream\","
1882 " \"paused\": false,"
1883 " \"url\": \"%s\"}]",
1884 download_url.c_str())));
1885 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1886 base::StringPrintf("[{\"id\": %d,"
1888 " \"previous\": \"\","
1889 " \"current\": \"%s\"}}]",
1891 GetFilename("headers-succeed.txt").c_str())));
1892 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1893 base::StringPrintf("[{\"id\": %d,"
1895 " \"previous\": \"in_progress\","
1896 " \"current\": \"complete\"}}]",
1900 // Test that headers-succeed would fail if the resource requires the headers and
1901 // chrome fails to propagate them back to the server. This tests both that
1902 // testserver.py does not succeed when it should fail as well as how the
1903 // downloads extension api exposes the failure to extensions.
1904 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1905 DownloadExtensionTest_Download_Headers_Fail) {
1906 LoadExtension("downloads_split");
1907 ASSERT_TRUE(StartEmbeddedTestServer());
1908 ASSERT_TRUE(test_server()->Start());
1909 std::string download_url = test_server()->GetURL("files/downloads/"
1910 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
1913 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1914 new DownloadsDownloadFunction(), base::StringPrintf(
1915 "[{\"url\": \"%s\","
1916 " \"filename\": \"headers-fail.txt\"}]",
1917 download_url.c_str())));
1918 ASSERT_TRUE(result.get());
1920 ASSERT_TRUE(result->GetAsInteger(&result_id));
1921 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1923 ScopedCancellingItem canceller(item);
1924 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1926 ASSERT_TRUE(WaitForInterruption(
1928 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
1929 base::StringPrintf("[{\"danger\": \"safe\","
1930 " \"incognito\": false,"
1931 " \"bytesReceived\": 0,"
1933 " \"paused\": false,"
1934 " \"url\": \"%s\"}]",
1935 download_url.c_str())));
1938 // Test that DownloadsDownloadFunction propagates the Authorization header
1940 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1941 DownloadExtensionTest_Download_AuthBasic) {
1942 LoadExtension("downloads_split");
1943 ASSERT_TRUE(StartEmbeddedTestServer());
1944 ASSERT_TRUE(test_server()->Start());
1945 std::string download_url = test_server()->GetURL("auth-basic").spec();
1946 // This is just base64 of 'username:secret'.
1947 static const char* kAuthorization = "dXNlcm5hbWU6c2VjcmV0";
1950 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1951 new DownloadsDownloadFunction(), base::StringPrintf(
1952 "[{\"url\": \"%s\","
1953 " \"filename\": \"auth-basic-succeed.txt\","
1955 " \"name\": \"Authorization\","
1956 " \"value\": \"Basic %s\"}]}]",
1957 download_url.c_str(), kAuthorization)));
1958 ASSERT_TRUE(result.get());
1960 ASSERT_TRUE(result->GetAsInteger(&result_id));
1961 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1963 ScopedCancellingItem canceller(item);
1964 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1966 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1967 base::StringPrintf("[{\"danger\": \"safe\","
1968 " \"incognito\": false,"
1969 " \"mime\": \"text/html\","
1970 " \"paused\": false,"
1971 " \"url\": \"%s\"}]", download_url.c_str())));
1972 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1973 base::StringPrintf("[{\"id\": %d,"
1975 " \"previous\": \"in_progress\","
1976 " \"current\": \"complete\"}}]", result_id)));
1979 // Test that DownloadsDownloadFunction propagates the |method| and |body|
1980 // parameters to the URLRequest.
1981 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1982 DownloadExtensionTest_Download_Post) {
1983 LoadExtension("downloads_split");
1984 ASSERT_TRUE(StartEmbeddedTestServer());
1985 ASSERT_TRUE(test_server()->Start());
1986 std::string download_url = test_server()->GetURL("files/post/downloads/"
1987 "a_zip_file.zip?expected_body=BODY").spec();
1990 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1991 new DownloadsDownloadFunction(), base::StringPrintf(
1992 "[{\"url\": \"%s\","
1993 " \"filename\": \"post-succeed.txt\","
1994 " \"method\": \"POST\","
1995 " \"body\": \"BODY\"}]",
1996 download_url.c_str())));
1997 ASSERT_TRUE(result.get());
1999 ASSERT_TRUE(result->GetAsInteger(&result_id));
2000 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2002 ScopedCancellingItem canceller(item);
2003 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2005 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2006 base::StringPrintf("[{\"danger\": \"safe\","
2007 " \"incognito\": false,"
2008 " \"mime\": \"application/octet-stream\","
2009 " \"paused\": false,"
2010 " \"url\": \"%s\"}]", download_url.c_str())));
2011 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2012 base::StringPrintf("[{\"id\": %d,"
2014 " \"previous\": \"\","
2015 " \"current\": \"%s\"}}]",
2017 GetFilename("post-succeed.txt").c_str())));
2018 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2019 base::StringPrintf("[{\"id\": %d,"
2021 " \"previous\": \"in_progress\","
2022 " \"current\": \"complete\"}}]",
2026 // Test that downloadPostSuccess would fail if the resource requires the POST
2027 // method, and chrome fails to propagate the |method| parameter back to the
2028 // server. This tests both that testserver.py does not succeed when it should
2029 // fail, and this tests how the downloads extension api exposes the failure to
2031 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2032 DownloadExtensionTest_Download_Post_Get) {
2033 LoadExtension("downloads_split");
2034 ASSERT_TRUE(StartEmbeddedTestServer());
2035 ASSERT_TRUE(test_server()->Start());
2036 std::string download_url = test_server()->GetURL("files/post/downloads/"
2037 "a_zip_file.zip?expected_body=BODY").spec();
2040 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2041 new DownloadsDownloadFunction(), base::StringPrintf(
2042 "[{\"url\": \"%s\","
2043 " \"body\": \"BODY\","
2044 " \"filename\": \"post-get.txt\"}]",
2045 download_url.c_str())));
2046 ASSERT_TRUE(result.get());
2048 ASSERT_TRUE(result->GetAsInteger(&result_id));
2049 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2051 ScopedCancellingItem canceller(item);
2052 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2054 ASSERT_TRUE(WaitForInterruption(
2056 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2057 base::StringPrintf("[{\"danger\": \"safe\","
2058 " \"incognito\": false,"
2060 " \"paused\": false,"
2062 " \"url\": \"%s\"}]",
2064 download_url.c_str())));
2067 // Test that downloadPostSuccess would fail if the resource requires the POST
2068 // method, and chrome fails to propagate the |body| parameter back to the
2069 // server. This tests both that testserver.py does not succeed when it should
2070 // fail, and this tests how the downloads extension api exposes the failure to
2072 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2073 DownloadExtensionTest_Download_Post_NoBody) {
2074 LoadExtension("downloads_split");
2075 ASSERT_TRUE(StartEmbeddedTestServer());
2076 ASSERT_TRUE(test_server()->Start());
2077 std::string download_url = test_server()->GetURL("files/post/downloads/"
2078 "a_zip_file.zip?expected_body=BODY").spec();
2081 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2082 new DownloadsDownloadFunction(), base::StringPrintf(
2083 "[{\"url\": \"%s\","
2084 " \"method\": \"POST\","
2085 " \"filename\": \"post-nobody.txt\"}]",
2086 download_url.c_str())));
2087 ASSERT_TRUE(result.get());
2089 ASSERT_TRUE(result->GetAsInteger(&result_id));
2090 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2092 ScopedCancellingItem canceller(item);
2093 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2095 ASSERT_TRUE(WaitForInterruption(
2097 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2098 base::StringPrintf("[{\"danger\": \"safe\","
2099 " \"incognito\": false,"
2101 " \"paused\": false,"
2103 " \"url\": \"%s\"}]",
2105 download_url.c_str())));
2108 // Test that cancel()ing an in-progress download causes its state to transition
2109 // to interrupted, and test that that state transition is detectable by an
2110 // onChanged event listener. TODO(benjhayden): Test other sources of
2111 // interruptions such as server death.
2112 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2113 DownloadExtensionTest_Download_Cancel) {
2114 LoadExtension("downloads_split");
2115 ASSERT_TRUE(StartEmbeddedTestServer());
2116 ASSERT_TRUE(test_server()->Start());
2117 std::string download_url = test_server()->GetURL(
2118 "download-known-size").spec();
2121 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2122 new DownloadsDownloadFunction(), base::StringPrintf(
2123 "[{\"url\": \"%s\"}]", download_url.c_str())));
2124 ASSERT_TRUE(result.get());
2126 ASSERT_TRUE(result->GetAsInteger(&result_id));
2127 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2129 ScopedCancellingItem canceller(item);
2130 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2132 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2133 base::StringPrintf("[{\"danger\": \"safe\","
2134 " \"incognito\": false,"
2135 " \"mime\": \"application/octet-stream\","
2136 " \"paused\": false,"
2138 " \"url\": \"%s\"}]",
2140 download_url.c_str())));
2142 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2143 base::StringPrintf("[{\"id\": %d,"
2144 " \"error\": {\"current\":\"USER_CANCELED\"},"
2146 " \"previous\": \"in_progress\","
2147 " \"current\": \"interrupted\"}}]",
2151 // Test downloading filesystem: URLs.
2152 // NOTE: chrome disallows creating HTML5 FileSystem Files in incognito.
2153 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2154 DownloadExtensionTest_Download_FileSystemURL) {
2155 static const char* kPayloadData = "on the record\ndata";
2157 LoadExtension("downloads_split");
2159 const std::string download_url = "filesystem:" + GetExtensionURL() +
2160 "temporary/on_record.txt";
2162 // Setup a file in the filesystem which we can download.
2163 ASSERT_TRUE(HTML5FileWriter::CreateFileForTesting(
2164 BrowserContext::GetDefaultStoragePartition(browser()->profile())->
2165 GetFileSystemContext(),
2166 fileapi::FileSystemURL::CreateForTest(GURL(download_url)),
2167 kPayloadData, strlen(kPayloadData)));
2170 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2171 new DownloadsDownloadFunction(), base::StringPrintf(
2172 "[{\"url\": \"%s\"}]", download_url.c_str())));
2173 ASSERT_TRUE(result.get());
2175 ASSERT_TRUE(result->GetAsInteger(&result_id));
2177 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2179 ScopedCancellingItem canceller(item);
2180 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2182 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2183 base::StringPrintf("[{\"danger\": \"safe\","
2184 " \"incognito\": false,"
2185 " \"mime\": \"text/plain\","
2186 " \"paused\": false,"
2187 " \"url\": \"%s\"}]",
2188 download_url.c_str())));
2189 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2190 base::StringPrintf("[{\"id\": %d,"
2192 " \"previous\": \"\","
2193 " \"current\": \"%s\"}}]",
2195 GetFilename("on_record.txt").c_str())));
2196 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2197 base::StringPrintf("[{\"id\": %d,"
2199 " \"previous\": \"in_progress\","
2200 " \"current\": \"complete\"}}]",
2202 std::string disk_data;
2203 EXPECT_TRUE(base::ReadFileToString(item->GetTargetFilePath(), &disk_data));
2204 EXPECT_STREQ(kPayloadData, disk_data.c_str());
2207 // Test is flaky: http://crbug.com/302071
2208 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2209 DISABLED_DownloadExtensionTest_OnDeterminingFilename_NoChange) {
2211 LoadExtension("downloads_split");
2212 AddFilenameDeterminer();
2213 ASSERT_TRUE(StartEmbeddedTestServer());
2214 ASSERT_TRUE(test_server()->Start());
2215 std::string download_url = test_server()->GetURL("slow?0").spec();
2217 // Start downloading a file.
2218 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2219 new DownloadsDownloadFunction(), base::StringPrintf(
2220 "[{\"url\": \"%s\"}]", download_url.c_str())));
2221 ASSERT_TRUE(result.get());
2223 ASSERT_TRUE(result->GetAsInteger(&result_id));
2224 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2226 ScopedCancellingItem canceller(item);
2227 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2229 // Wait for the onCreated and onDeterminingFilename events.
2230 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2231 base::StringPrintf("[{\"danger\": \"safe\","
2232 " \"incognito\": false,"
2234 " \"mime\": \"text/plain\","
2235 " \"paused\": false,"
2236 " \"url\": \"%s\"}]",
2238 download_url.c_str())));
2239 ASSERT_TRUE(WaitFor(
2240 api::OnDeterminingFilename::kEventName,
2241 base::StringPrintf("[{\"id\": %d,"
2242 " \"filename\":\"slow.txt\"}]",
2244 ASSERT_TRUE(item->GetTargetFilePath().empty());
2245 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2247 // Respond to the onDeterminingFilename.
2249 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2250 browser()->profile(),
2255 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2257 EXPECT_EQ("", error);
2259 // The download should complete successfully.
2260 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2261 base::StringPrintf("[{\"id\": %d,"
2263 " \"previous\": \"\","
2264 " \"current\": \"%s\"}}]",
2266 GetFilename("slow.txt").c_str())));
2267 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2268 base::StringPrintf("[{\"id\": %d,"
2270 " \"previous\": \"in_progress\","
2271 " \"current\": \"complete\"}}]",
2275 IN_PROC_BROWSER_TEST_F(
2276 DownloadExtensionTest,
2277 DownloadExtensionTest_OnDeterminingFilename_DangerousOverride) {
2279 LoadExtension("downloads_split");
2280 AddFilenameDeterminer();
2281 ASSERT_TRUE(StartEmbeddedTestServer());
2282 ASSERT_TRUE(test_server()->Start());
2283 std::string download_url = test_server()->GetURL("slow?0").spec();
2285 // Start downloading a file.
2286 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2287 new DownloadsDownloadFunction(), base::StringPrintf(
2288 "[{\"url\": \"%s\"}]", download_url.c_str())));
2289 ASSERT_TRUE(result.get());
2291 ASSERT_TRUE(result->GetAsInteger(&result_id));
2292 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2294 ScopedCancellingItem canceller(item);
2295 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2297 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2298 base::StringPrintf("[{\"danger\": \"safe\","
2299 " \"incognito\": false,"
2301 " \"mime\": \"text/plain\","
2302 " \"paused\": false,"
2303 " \"url\": \"%s\"}]",
2305 download_url.c_str())));
2306 ASSERT_TRUE(WaitFor(
2307 api::OnDeterminingFilename::kEventName,
2308 base::StringPrintf("[{\"id\": %d,"
2309 " \"filename\":\"slow.txt\"}]",
2311 ASSERT_TRUE(item->GetTargetFilePath().empty());
2312 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2314 // Respond to the onDeterminingFilename.
2316 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2317 browser()->profile(),
2321 base::FilePath(FILE_PATH_LITERAL("overridden.swf")),
2322 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2324 EXPECT_EQ("", error);
2326 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2327 base::StringPrintf("[{\"id\": %d,"
2329 " \"previous\":\"safe\","
2330 " \"current\":\"file\"}}]",
2333 item->ValidateDangerousDownload();
2334 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2335 base::StringPrintf("[{\"id\": %d,"
2337 " \"previous\":\"file\","
2338 " \"current\":\"accepted\"}}]",
2340 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2341 base::StringPrintf("[{\"id\": %d,"
2343 " \"previous\": \"in_progress\","
2344 " \"current\": \"complete\"}}]",
2346 EXPECT_EQ(downloads_directory().AppendASCII("overridden.swf"),
2347 item->GetTargetFilePath());
2350 IN_PROC_BROWSER_TEST_F(
2351 DownloadExtensionTest,
2352 DownloadExtensionTest_OnDeterminingFilename_ReferencesParentInvalid) {
2354 LoadExtension("downloads_split");
2355 AddFilenameDeterminer();
2356 ASSERT_TRUE(StartEmbeddedTestServer());
2357 ASSERT_TRUE(test_server()->Start());
2358 std::string download_url = test_server()->GetURL("slow?0").spec();
2360 // Start downloading a file.
2361 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2362 new DownloadsDownloadFunction(), base::StringPrintf(
2363 "[{\"url\": \"%s\"}]", download_url.c_str())));
2364 ASSERT_TRUE(result.get());
2366 ASSERT_TRUE(result->GetAsInteger(&result_id));
2367 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2369 ScopedCancellingItem canceller(item);
2370 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2372 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2373 base::StringPrintf("[{\"danger\": \"safe\","
2374 " \"incognito\": false,"
2376 " \"mime\": \"text/plain\","
2377 " \"paused\": false,"
2378 " \"url\": \"%s\"}]",
2380 download_url.c_str())));
2381 ASSERT_TRUE(WaitFor(
2382 api::OnDeterminingFilename::kEventName,
2383 base::StringPrintf("[{\"id\": %d,"
2384 " \"filename\":\"slow.txt\"}]",
2386 ASSERT_TRUE(item->GetTargetFilePath().empty());
2387 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2389 // Respond to the onDeterminingFilename.
2391 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2392 browser()->profile(),
2396 base::FilePath(FILE_PATH_LITERAL("sneaky/../../sneaky.txt")),
2397 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2399 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2400 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2401 base::StringPrintf("[{\"id\": %d,"
2403 " \"previous\": \"\","
2404 " \"current\": \"%s\"}}]",
2406 GetFilename("slow.txt").c_str())));
2407 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2408 base::StringPrintf("[{\"id\": %d,"
2410 " \"previous\": \"in_progress\","
2411 " \"current\": \"complete\"}}]",
2415 IN_PROC_BROWSER_TEST_F(
2416 DownloadExtensionTest,
2417 DownloadExtensionTest_OnDeterminingFilename_IllegalFilename) {
2419 LoadExtension("downloads_split");
2420 AddFilenameDeterminer();
2421 ASSERT_TRUE(StartEmbeddedTestServer());
2422 ASSERT_TRUE(test_server()->Start());
2423 std::string download_url = test_server()->GetURL("slow?0").spec();
2425 // Start downloading a file.
2426 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2427 new DownloadsDownloadFunction(), base::StringPrintf(
2428 "[{\"url\": \"%s\"}]", download_url.c_str())));
2429 ASSERT_TRUE(result.get());
2431 ASSERT_TRUE(result->GetAsInteger(&result_id));
2432 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2434 ScopedCancellingItem canceller(item);
2435 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2437 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2438 base::StringPrintf("[{\"danger\": \"safe\","
2439 " \"incognito\": false,"
2441 " \"mime\": \"text/plain\","
2442 " \"paused\": false,"
2443 " \"url\": \"%s\"}]",
2445 download_url.c_str())));
2446 ASSERT_TRUE(WaitFor(
2447 api::OnDeterminingFilename::kEventName,
2448 base::StringPrintf("[{\"id\": %d,"
2449 " \"filename\":\"slow.txt\"}]",
2451 ASSERT_TRUE(item->GetTargetFilePath().empty());
2452 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2454 // Respond to the onDeterminingFilename.
2456 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2457 browser()->profile(),
2461 base::FilePath(FILE_PATH_LITERAL("<")),
2462 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2464 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2465 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
2468 " \"previous\": \"\","
2469 " \"current\": \"%s\"}}]",
2471 GetFilename("slow.txt").c_str())));
2472 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
2475 " \"previous\": \"in_progress\","
2476 " \"current\": \"complete\"}}]",
2480 IN_PROC_BROWSER_TEST_F(
2481 DownloadExtensionTest,
2482 DownloadExtensionTest_OnDeterminingFilename_IllegalFilenameExtension) {
2484 LoadExtension("downloads_split");
2485 AddFilenameDeterminer();
2486 ASSERT_TRUE(StartEmbeddedTestServer());
2487 ASSERT_TRUE(test_server()->Start());
2488 std::string download_url = test_server()->GetURL("slow?0").spec();
2490 // Start downloading a file.
2491 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2492 new DownloadsDownloadFunction(), base::StringPrintf(
2493 "[{\"url\": \"%s\"}]", download_url.c_str())));
2494 ASSERT_TRUE(result.get());
2496 ASSERT_TRUE(result->GetAsInteger(&result_id));
2497 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2499 ScopedCancellingItem canceller(item);
2500 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2502 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2503 base::StringPrintf("[{\"danger\": \"safe\","
2504 " \"incognito\": false,"
2506 " \"mime\": \"text/plain\","
2507 " \"paused\": false,"
2508 " \"url\": \"%s\"}]",
2510 download_url.c_str())));
2511 ASSERT_TRUE(WaitFor(
2512 api::OnDeterminingFilename::kEventName,
2513 base::StringPrintf("[{\"id\": %d,"
2514 " \"filename\":\"slow.txt\"}]",
2516 ASSERT_TRUE(item->GetTargetFilePath().empty());
2517 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2519 // Respond to the onDeterminingFilename.
2521 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2522 browser()->profile(),
2526 base::FilePath(FILE_PATH_LITERAL(
2527 "My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}/foo")),
2528 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2530 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2531 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
2534 " \"previous\": \"\","
2535 " \"current\": \"%s\"}}]",
2537 GetFilename("slow.txt").c_str())));
2538 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
2541 " \"previous\": \"in_progress\","
2542 " \"current\": \"complete\"}}]",
2546 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2547 DISABLED_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2549 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2550 DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2552 IN_PROC_BROWSER_TEST_F(
2553 DownloadExtensionTest,
2554 MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename) {
2556 LoadExtension("downloads_split");
2557 AddFilenameDeterminer();
2558 ASSERT_TRUE(StartEmbeddedTestServer());
2559 ASSERT_TRUE(test_server()->Start());
2560 std::string download_url = test_server()->GetURL("slow?0").spec();
2562 // Start downloading a file.
2563 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2564 new DownloadsDownloadFunction(), base::StringPrintf(
2565 "[{\"url\": \"%s\"}]", download_url.c_str())));
2566 ASSERT_TRUE(result.get());
2568 ASSERT_TRUE(result->GetAsInteger(&result_id));
2569 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2571 ScopedCancellingItem canceller(item);
2572 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2574 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2575 base::StringPrintf("[{\"danger\": \"safe\","
2576 " \"incognito\": false,"
2578 " \"mime\": \"text/plain\","
2579 " \"paused\": false,"
2580 " \"url\": \"%s\"}]",
2582 download_url.c_str())));
2583 ASSERT_TRUE(WaitFor(
2584 api::OnDeterminingFilename::kEventName,
2585 base::StringPrintf("[{\"id\": %d,"
2586 " \"filename\":\"slow.txt\"}]",
2588 ASSERT_TRUE(item->GetTargetFilePath().empty());
2589 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2591 // Respond to the onDeterminingFilename.
2593 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2594 browser()->profile(),
2598 base::FilePath(FILE_PATH_LITERAL("con.foo")),
2599 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2601 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2602 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
2605 " \"previous\": \"\","
2606 " \"current\": \"%s\"}}]",
2608 GetFilename("slow.txt").c_str())));
2609 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
2612 " \"previous\": \"in_progress\","
2613 " \"current\": \"complete\"}}]",
2617 IN_PROC_BROWSER_TEST_F(
2618 DownloadExtensionTest,
2619 DownloadExtensionTest_OnDeterminingFilename_CurDirInvalid) {
2621 LoadExtension("downloads_split");
2622 AddFilenameDeterminer();
2623 ASSERT_TRUE(StartEmbeddedTestServer());
2624 ASSERT_TRUE(test_server()->Start());
2625 std::string download_url = test_server()->GetURL("slow?0").spec();
2627 // Start downloading a file.
2628 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2629 new DownloadsDownloadFunction(), base::StringPrintf(
2630 "[{\"url\": \"%s\"}]", download_url.c_str())));
2631 ASSERT_TRUE(result.get());
2633 ASSERT_TRUE(result->GetAsInteger(&result_id));
2634 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2636 ScopedCancellingItem canceller(item);
2637 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2639 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2640 base::StringPrintf("[{\"danger\": \"safe\","
2641 " \"incognito\": false,"
2643 " \"mime\": \"text/plain\","
2644 " \"paused\": false,"
2645 " \"url\": \"%s\"}]",
2647 download_url.c_str())));
2648 ASSERT_TRUE(WaitFor(
2649 api::OnDeterminingFilename::kEventName,
2650 base::StringPrintf("[{\"id\": %d,"
2651 " \"filename\":\"slow.txt\"}]",
2653 ASSERT_TRUE(item->GetTargetFilePath().empty());
2654 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2656 // Respond to the onDeterminingFilename.
2658 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2659 browser()->profile(),
2663 base::FilePath(FILE_PATH_LITERAL(".")),
2664 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2666 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2667 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2668 base::StringPrintf("[{\"id\": %d,"
2670 " \"previous\": \"\","
2671 " \"current\": \"%s\"}}]",
2673 GetFilename("slow.txt").c_str())));
2674 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2675 base::StringPrintf("[{\"id\": %d,"
2677 " \"previous\": \"in_progress\","
2678 " \"current\": \"complete\"}}]",
2682 IN_PROC_BROWSER_TEST_F(
2683 DownloadExtensionTest,
2684 DownloadExtensionTest_OnDeterminingFilename_ParentDirInvalid) {
2685 ASSERT_TRUE(StartEmbeddedTestServer());
2686 ASSERT_TRUE(test_server()->Start());
2688 LoadExtension("downloads_split");
2689 AddFilenameDeterminer();
2690 std::string download_url = test_server()->GetURL("slow?0").spec();
2692 // Start downloading a file.
2693 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2694 new DownloadsDownloadFunction(), base::StringPrintf(
2695 "[{\"url\": \"%s\"}]", download_url.c_str())));
2696 ASSERT_TRUE(result.get());
2698 ASSERT_TRUE(result->GetAsInteger(&result_id));
2699 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2701 ScopedCancellingItem canceller(item);
2702 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2704 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2705 base::StringPrintf("[{\"danger\": \"safe\","
2706 " \"incognito\": false,"
2708 " \"mime\": \"text/plain\","
2709 " \"paused\": false,"
2710 " \"url\": \"%s\"}]",
2712 download_url.c_str())));
2713 ASSERT_TRUE(WaitFor(
2714 api::OnDeterminingFilename::kEventName,
2715 base::StringPrintf("[{\"id\": %d,"
2716 " \"filename\":\"slow.txt\"}]",
2718 ASSERT_TRUE(item->GetTargetFilePath().empty());
2719 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2721 // Respond to the onDeterminingFilename.
2723 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2724 browser()->profile(),
2728 base::FilePath(FILE_PATH_LITERAL("..")),
2729 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2731 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2732 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2733 base::StringPrintf("[{\"id\": %d,"
2735 " \"previous\": \"\","
2736 " \"current\": \"%s\"}}]",
2738 GetFilename("slow.txt").c_str())));
2739 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2740 base::StringPrintf("[{\"id\": %d,"
2742 " \"previous\": \"in_progress\","
2743 " \"current\": \"complete\"}}]",
2747 IN_PROC_BROWSER_TEST_F(
2748 DownloadExtensionTest,
2749 DownloadExtensionTest_OnDeterminingFilename_AbsPathInvalid) {
2751 LoadExtension("downloads_split");
2752 AddFilenameDeterminer();
2753 ASSERT_TRUE(StartEmbeddedTestServer());
2754 ASSERT_TRUE(test_server()->Start());
2755 std::string download_url = test_server()->GetURL("slow?0").spec();
2757 // Start downloading a file.
2758 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2759 new DownloadsDownloadFunction(), base::StringPrintf(
2760 "[{\"url\": \"%s\"}]", download_url.c_str())));
2761 ASSERT_TRUE(result.get());
2763 ASSERT_TRUE(result->GetAsInteger(&result_id));
2764 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2766 ScopedCancellingItem canceller(item);
2767 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2769 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2770 base::StringPrintf("[{\"danger\": \"safe\","
2771 " \"incognito\": false,"
2773 " \"mime\": \"text/plain\","
2774 " \"paused\": false,"
2775 " \"url\": \"%s\"}]",
2777 download_url.c_str())));
2778 ASSERT_TRUE(WaitFor(
2779 api::OnDeterminingFilename::kEventName,
2780 base::StringPrintf("[{\"id\": %d,"
2781 " \"filename\":\"slow.txt\"}]",
2783 ASSERT_TRUE(item->GetTargetFilePath().empty());
2784 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2786 // Respond to the onDeterminingFilename. Absolute paths should be rejected.
2788 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2789 browser()->profile(),
2793 downloads_directory().Append(FILE_PATH_LITERAL("sneaky.txt")),
2794 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2796 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2798 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2799 base::StringPrintf("[{\"id\": %d,"
2801 " \"previous\": \"\","
2802 " \"current\": \"%s\"}}]",
2804 GetFilename("slow.txt").c_str())));
2805 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2806 base::StringPrintf("[{\"id\": %d,"
2808 " \"previous\": \"in_progress\","
2809 " \"current\": \"complete\"}}]",
2813 IN_PROC_BROWSER_TEST_F(
2814 DownloadExtensionTest,
2815 DownloadExtensionTest_OnDeterminingFilename_EmptyBasenameInvalid) {
2817 LoadExtension("downloads_split");
2818 AddFilenameDeterminer();
2819 ASSERT_TRUE(StartEmbeddedTestServer());
2820 ASSERT_TRUE(test_server()->Start());
2821 std::string download_url = test_server()->GetURL("slow?0").spec();
2823 // Start downloading a file.
2824 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2825 new DownloadsDownloadFunction(), base::StringPrintf(
2826 "[{\"url\": \"%s\"}]", download_url.c_str())));
2827 ASSERT_TRUE(result.get());
2829 ASSERT_TRUE(result->GetAsInteger(&result_id));
2830 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2832 ScopedCancellingItem canceller(item);
2833 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2835 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2836 base::StringPrintf("[{\"danger\": \"safe\","
2837 " \"incognito\": false,"
2839 " \"mime\": \"text/plain\","
2840 " \"paused\": false,"
2841 " \"url\": \"%s\"}]",
2843 download_url.c_str())));
2844 ASSERT_TRUE(WaitFor(
2845 api::OnDeterminingFilename::kEventName,
2846 base::StringPrintf("[{\"id\": %d,"
2847 " \"filename\":\"slow.txt\"}]",
2849 ASSERT_TRUE(item->GetTargetFilePath().empty());
2850 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2852 // Respond to the onDeterminingFilename. Empty basenames should be rejected.
2854 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2855 browser()->profile(),
2859 base::FilePath(FILE_PATH_LITERAL("foo/")),
2860 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2862 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2864 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2865 base::StringPrintf("[{\"id\": %d,"
2867 " \"previous\": \"\","
2868 " \"current\": \"%s\"}}]",
2870 GetFilename("slow.txt").c_str())));
2871 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2872 base::StringPrintf("[{\"id\": %d,"
2874 " \"previous\": \"in_progress\","
2875 " \"current\": \"complete\"}}]",
2879 IN_PROC_BROWSER_TEST_F(
2880 DownloadExtensionTest,
2881 DownloadExtensionTest_OnDeterminingFilename_Override) {
2883 LoadExtension("downloads_split");
2884 AddFilenameDeterminer();
2885 ASSERT_TRUE(StartEmbeddedTestServer());
2886 ASSERT_TRUE(test_server()->Start());
2887 std::string download_url = test_server()->GetURL("slow?0").spec();
2889 // Start downloading a file.
2890 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2891 new DownloadsDownloadFunction(), base::StringPrintf(
2892 "[{\"url\": \"%s\"}]", download_url.c_str())));
2893 ASSERT_TRUE(result.get());
2895 ASSERT_TRUE(result->GetAsInteger(&result_id));
2896 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2898 ScopedCancellingItem canceller(item);
2899 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2900 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2901 base::StringPrintf("[{\"danger\": \"safe\","
2902 " \"incognito\": false,"
2904 " \"mime\": \"text/plain\","
2905 " \"paused\": false,"
2906 " \"url\": \"%s\"}]",
2908 download_url.c_str())));
2909 ASSERT_TRUE(WaitFor(
2910 api::OnDeterminingFilename::kEventName,
2911 base::StringPrintf("[{\"id\": %d,"
2912 " \"filename\":\"slow.txt\"}]",
2914 ASSERT_TRUE(item->GetTargetFilePath().empty());
2915 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2917 // Respond to the onDeterminingFilename.
2919 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2920 browser()->profile(),
2925 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2927 EXPECT_EQ("", error);
2929 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2930 base::StringPrintf("[{\"id\": %d,"
2932 " \"previous\": \"\","
2933 " \"current\": \"%s\"}}]",
2935 GetFilename("slow.txt").c_str())));
2936 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2937 base::StringPrintf("[{\"id\": %d,"
2939 " \"previous\": \"in_progress\","
2940 " \"current\": \"complete\"}}]",
2943 // Start downloading a file.
2944 result.reset(RunFunctionAndReturnResult(
2945 new DownloadsDownloadFunction(), base::StringPrintf(
2946 "[{\"url\": \"%s\"}]", download_url.c_str())));
2947 ASSERT_TRUE(result.get());
2949 ASSERT_TRUE(result->GetAsInteger(&result_id));
2950 item = GetCurrentManager()->GetDownload(result_id);
2952 ScopedCancellingItem canceller2(item);
2953 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2955 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2956 base::StringPrintf("[{\"danger\": \"safe\","
2957 " \"incognito\": false,"
2959 " \"mime\": \"text/plain\","
2960 " \"paused\": false,"
2961 " \"url\": \"%s\"}]",
2963 download_url.c_str())));
2964 ASSERT_TRUE(WaitFor(
2965 api::OnDeterminingFilename::kEventName,
2966 base::StringPrintf("[{\"id\": %d,"
2967 " \"filename\":\"slow.txt\"}]",
2969 ASSERT_TRUE(item->GetTargetFilePath().empty());
2970 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2972 // Respond to the onDeterminingFilename.
2973 // Also test that DetermineFilename allows (chrome) extensions to set
2974 // filenames without (filename) extensions. (Don't ask about v8 extensions or
2975 // python extensions or kernel extensions or firefox extensions...)
2977 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2978 browser()->profile(),
2982 base::FilePath(FILE_PATH_LITERAL("foo")),
2983 api::FILENAME_CONFLICT_ACTION_OVERWRITE,
2985 EXPECT_EQ("", error);
2987 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2988 base::StringPrintf("[{\"id\": %d,"
2990 " \"previous\": \"\","
2991 " \"current\": \"%s\"}}]",
2993 GetFilename("foo").c_str())));
2994 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2995 base::StringPrintf("[{\"id\": %d,"
2997 " \"previous\": \"in_progress\","
2998 " \"current\": \"complete\"}}]",
3002 // TODO test precedence rules: install_time
3004 IN_PROC_BROWSER_TEST_F(
3005 DownloadExtensionTest,
3006 DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer) {
3007 ASSERT_TRUE(StartEmbeddedTestServer());
3008 ASSERT_TRUE(test_server()->Start());
3010 LoadExtension("downloads_split");
3011 content::RenderProcessHost* host = AddFilenameDeterminer();
3012 std::string download_url = test_server()->GetURL("slow?0").spec();
3014 // Start downloading a file.
3015 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3016 new DownloadsDownloadFunction(), base::StringPrintf(
3017 "[{\"url\": \"%s\"}]", download_url.c_str())));
3018 ASSERT_TRUE(result.get());
3020 ASSERT_TRUE(result->GetAsInteger(&result_id));
3021 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3023 ScopedCancellingItem canceller(item);
3024 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3026 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
3027 base::StringPrintf("[{\"danger\": \"safe\","
3028 " \"incognito\": false,"
3030 " \"mime\": \"text/plain\","
3031 " \"paused\": false,"
3032 " \"url\": \"%s\"}]",
3034 download_url.c_str())));
3035 ASSERT_TRUE(WaitFor(
3036 api::OnDeterminingFilename::kEventName,
3037 base::StringPrintf("[{\"id\": %d,"
3038 " \"filename\":\"slow.txt\"}]",
3040 ASSERT_TRUE(item->GetTargetFilePath().empty());
3041 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3043 // Remove a determiner while waiting for it.
3044 RemoveFilenameDeterminer(host);
3046 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3047 base::StringPrintf("[{\"id\": %d,"
3049 " \"previous\": \"in_progress\","
3050 " \"current\": \"complete\"}}]",
3054 IN_PROC_BROWSER_TEST_F(
3055 DownloadExtensionTest,
3056 DownloadExtensionTest_OnDeterminingFilename_IncognitoSplit) {
3057 LoadExtension("downloads_split");
3058 ASSERT_TRUE(StartEmbeddedTestServer());
3059 ASSERT_TRUE(test_server()->Start());
3060 std::string download_url = test_server()->GetURL("slow?0").spec();
3063 AddFilenameDeterminer();
3066 AddFilenameDeterminer();
3068 // Start an on-record download.
3070 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3071 new DownloadsDownloadFunction(), base::StringPrintf(
3072 "[{\"url\": \"%s\"}]", download_url.c_str())));
3073 ASSERT_TRUE(result.get());
3075 ASSERT_TRUE(result->GetAsInteger(&result_id));
3076 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3078 ScopedCancellingItem canceller(item);
3079 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3081 // Wait for the onCreated and onDeterminingFilename events.
3082 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
3083 base::StringPrintf("[{\"danger\": \"safe\","
3084 " \"incognito\": false,"
3086 " \"mime\": \"text/plain\","
3087 " \"paused\": false,"
3088 " \"url\": \"%s\"}]",
3090 download_url.c_str())));
3091 ASSERT_TRUE(WaitFor(
3092 api::OnDeterminingFilename::kEventName,
3093 base::StringPrintf("[{\"id\": %d,"
3094 " \"incognito\": false,"
3095 " \"filename\":\"slow.txt\"}]",
3097 ASSERT_TRUE(item->GetTargetFilePath().empty());
3098 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3100 // Respond to the onDeterminingFilename events.
3102 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3103 current_browser()->profile(),
3107 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3108 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3110 EXPECT_EQ("", error);
3112 // The download should complete successfully.
3113 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3114 base::StringPrintf("[{\"id\": %d,"
3116 " \"previous\": \"\","
3117 " \"current\": \"%s\"}}]",
3119 GetFilename("42.txt").c_str())));
3120 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3121 base::StringPrintf("[{\"id\": %d,"
3123 " \"previous\": \"in_progress\","
3124 " \"current\": \"complete\"}}]",
3127 // Start an incognito download for comparison.
3129 result.reset(RunFunctionAndReturnResult(
3130 new DownloadsDownloadFunction(), base::StringPrintf(
3131 "[{\"url\": \"%s\"}]", download_url.c_str())));
3132 ASSERT_TRUE(result.get());
3134 ASSERT_TRUE(result->GetAsInteger(&result_id));
3135 item = GetCurrentManager()->GetDownload(result_id);
3137 ScopedCancellingItem canceller2(item);
3138 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3140 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
3141 base::StringPrintf("[{\"danger\": \"safe\","
3142 " \"incognito\": true,"
3144 " \"mime\": \"text/plain\","
3145 " \"paused\": false,"
3146 " \"url\": \"%s\"}]",
3148 download_url.c_str())));
3149 // On-Record renderers should not see events for off-record items.
3150 ASSERT_TRUE(WaitFor(
3151 api::OnDeterminingFilename::kEventName,
3152 base::StringPrintf("[{\"id\": %d,"
3153 " \"incognito\": true,"
3154 " \"filename\":\"slow.txt\"}]",
3156 ASSERT_TRUE(item->GetTargetFilePath().empty());
3157 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3159 // Respond to the onDeterminingFilename.
3161 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3162 current_browser()->profile(),
3166 base::FilePath(FILE_PATH_LITERAL("5.txt")),
3167 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3169 EXPECT_EQ("", error);
3171 // The download should complete successfully.
3172 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3173 base::StringPrintf("[{\"id\": %d,"
3175 " \"previous\": \"\","
3176 " \"current\": \"%s\"}}]",
3178 GetFilename("5.txt").c_str())));
3179 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3180 base::StringPrintf("[{\"id\": %d,"
3182 " \"previous\": \"in_progress\","
3183 " \"current\": \"complete\"}}]",
3187 IN_PROC_BROWSER_TEST_F(
3188 DownloadExtensionTest,
3189 DownloadExtensionTest_OnDeterminingFilename_IncognitoSpanning) {
3190 LoadExtension("downloads_spanning");
3191 ASSERT_TRUE(StartEmbeddedTestServer());
3192 ASSERT_TRUE(test_server()->Start());
3193 std::string download_url = test_server()->GetURL("slow?0").spec();
3196 AddFilenameDeterminer();
3198 // There is a single extension renderer that sees both on-record and
3199 // off-record events. The extension functions see the on-record profile with
3200 // include_incognito=true.
3202 // Start an on-record download.
3204 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3205 new DownloadsDownloadFunction(), base::StringPrintf(
3206 "[{\"url\": \"%s\"}]", download_url.c_str())));
3207 ASSERT_TRUE(result.get());
3209 ASSERT_TRUE(result->GetAsInteger(&result_id));
3210 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3212 ScopedCancellingItem canceller(item);
3213 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3215 // Wait for the onCreated and onDeterminingFilename events.
3216 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
3217 base::StringPrintf("[{\"danger\": \"safe\","
3218 " \"incognito\": false,"
3220 " \"mime\": \"text/plain\","
3221 " \"paused\": false,"
3222 " \"url\": \"%s\"}]",
3224 download_url.c_str())));
3225 ASSERT_TRUE(WaitFor(
3226 api::OnDeterminingFilename::kEventName,
3227 base::StringPrintf("[{\"id\": %d,"
3228 " \"incognito\": false,"
3229 " \"filename\":\"slow.txt\"}]",
3231 ASSERT_TRUE(item->GetTargetFilePath().empty());
3232 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3234 // Respond to the onDeterminingFilename events.
3236 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3237 current_browser()->profile(),
3241 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3242 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3244 EXPECT_EQ("", error);
3246 // The download should complete successfully.
3247 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3248 base::StringPrintf("[{\"id\": %d,"
3250 " \"previous\": \"\","
3251 " \"current\": \"%s\"}}]",
3253 GetFilename("42.txt").c_str())));
3254 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3255 base::StringPrintf("[{\"id\": %d,"
3257 " \"previous\": \"in_progress\","
3258 " \"current\": \"complete\"}}]",
3261 // Start an incognito download for comparison.
3263 result.reset(RunFunctionAndReturnResult(
3264 new DownloadsDownloadFunction(), base::StringPrintf(
3265 "[{\"url\": \"%s\"}]", download_url.c_str())));
3266 ASSERT_TRUE(result.get());
3268 ASSERT_TRUE(result->GetAsInteger(&result_id));
3269 item = GetCurrentManager()->GetDownload(result_id);
3271 ScopedCancellingItem canceller2(item);
3272 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3274 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
3275 base::StringPrintf("[{\"danger\": \"safe\","
3276 " \"incognito\": true,"
3278 " \"mime\": \"text/plain\","
3279 " \"paused\": false,"
3280 " \"url\": \"%s\"}]",
3282 download_url.c_str())));
3283 ASSERT_TRUE(WaitFor(
3284 api::OnDeterminingFilename::kEventName,
3285 base::StringPrintf("[{\"id\": %d,"
3286 " \"incognito\": true,"
3287 " \"filename\":\"slow.txt\"}]",
3289 ASSERT_TRUE(item->GetTargetFilePath().empty());
3290 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3292 // Respond to the onDeterminingFilename.
3294 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3295 current_browser()->profile(),
3299 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3300 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3302 EXPECT_EQ("", error);
3304 // The download should complete successfully.
3305 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3306 base::StringPrintf("[{\"id\": %d,"
3308 " \"previous\": \"\","
3309 " \"current\": \"%s\"}}]",
3311 GetFilename("42 (1).txt").c_str())));
3312 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3313 base::StringPrintf("[{\"id\": %d,"
3315 " \"previous\": \"in_progress\","
3316 " \"current\": \"complete\"}}]",
3321 // This test is very flaky on Win XP and Aura. http://crbug.com/248438
3322 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3323 DISABLED_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3325 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3326 DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3329 // Test download interruption while extensions determining filename. Should not
3330 // re-dispatch onDeterminingFilename.
3331 IN_PROC_BROWSER_TEST_F(
3332 DownloadExtensionTest,
3333 MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume) {
3334 CommandLine::ForCurrentProcess()->AppendSwitch(
3335 switches::kEnableDownloadResumption);
3336 LoadExtension("downloads_split");
3337 ASSERT_TRUE(StartEmbeddedTestServer());
3338 ASSERT_TRUE(test_server()->Start());
3340 content::RenderProcessHost* host = AddFilenameDeterminer();
3342 // Start a download.
3343 DownloadItem* item = NULL;
3345 DownloadManager* manager = GetCurrentManager();
3346 scoped_ptr<content::DownloadTestObserver> observer(
3347 new JustInProgressDownloadObserver(manager, 1));
3348 ASSERT_EQ(0, manager->InProgressCount());
3349 ASSERT_EQ(0, manager->NonMaliciousInProgressCount());
3350 // Tabs created just for a download are automatically closed, invalidating
3351 // the download's WebContents. Downloads without WebContents cannot be
3352 // resumed. http://crbug.com/225901
3353 ui_test_utils::NavigateToURLWithDisposition(
3355 GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl),
3357 ui_test_utils::BROWSER_TEST_NONE);
3358 observer->WaitForFinished();
3359 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
3360 DownloadManager::DownloadVector items;
3361 manager->GetAllDownloads(&items);
3362 for (DownloadManager::DownloadVector::iterator iter = items.begin();
3363 iter != items.end(); ++iter) {
3364 if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) {
3365 // There should be only one IN_PROGRESS item.
3366 EXPECT_EQ(NULL, item);
3372 ScopedCancellingItem canceller(item);
3374 // Wait for the onCreated and onDeterminingFilename event.
3375 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
3376 base::StringPrintf("[{\"danger\": \"safe\","
3377 " \"incognito\": false,"
3379 " \"mime\": \"application/octet-stream\","
3380 " \"paused\": false}]",
3382 ASSERT_TRUE(WaitFor(
3383 api::OnDeterminingFilename::kEventName,
3384 base::StringPrintf("[{\"id\": %d,"
3385 " \"incognito\": false,"
3386 " \"filename\":\"download-unknown-size\"}]",
3388 ASSERT_TRUE(item->GetTargetFilePath().empty());
3389 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3392 ui_test_utils::NavigateToURLWithDisposition(
3394 GURL(URLRequestSlowDownloadJob::kErrorDownloadUrl),
3396 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3398 // Errors caught before filename determination are delayed until after
3399 // filename determination.
3401 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3402 current_browser()->profile(),
3406 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3407 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3409 EXPECT_EQ("", error);
3410 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3411 base::StringPrintf("[{\"id\": %d,"
3413 " \"previous\": \"\","
3414 " \"current\": \"%s\"}}]",
3416 GetFilename("42.txt").c_str())));
3418 content::DownloadUpdatedObserver interrupted(item, base::Bind(
3419 ItemIsInterrupted));
3420 ASSERT_TRUE(interrupted.WaitForEvent());
3421 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3422 base::StringPrintf("[{\"id\": %d,"
3423 " \"error\":{\"current\":\"NETWORK_FAILED\"},"
3425 " \"previous\":\"in_progress\","
3426 " \"current\":\"interrupted\"}}]",
3430 // Downloads that are restarted on resumption trigger another download target
3432 RemoveFilenameDeterminer(host);
3435 // Errors caught before filename determination is complete are delayed until
3436 // after filename determination so that, on resumption, filename determination
3437 // does not need to be re-done. So, there will not be a second
3438 // onDeterminingFilename event.
3440 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3441 base::StringPrintf("[{\"id\": %d,"
3442 " \"error\":{\"previous\":\"NETWORK_FAILED\"},"
3444 " \"previous\":\"interrupted\","
3445 " \"current\":\"in_progress\"}}]",
3449 FinishPendingSlowDownloads();
3451 // The download should complete successfully.
3452 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3453 base::StringPrintf("[{\"id\": %d,"
3455 " \"previous\": \"in_progress\","
3456 " \"current\": \"complete\"}}]",
3460 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
3461 DownloadExtensionTest_SetShelfEnabled) {
3462 LoadExtension("downloads_split");
3463 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[false]"));
3464 EXPECT_FALSE(DownloadServiceFactory::GetForBrowserContext(
3465 browser()->profile())->IsShelfEnabled());
3466 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[true]"));
3467 EXPECT_TRUE(DownloadServiceFactory::GetForBrowserContext(
3468 browser()->profile())->IsShelfEnabled());
3469 // TODO(benjhayden) Test that existing shelves are hidden.
3470 // TODO(benjhayden) Test multiple extensions.
3471 // TODO(benjhayden) Test disabling extensions.
3472 // TODO(benjhayden) Test that browsers associated with other profiles are not
3474 // TODO(benjhayden) Test incognito.
3477 // TODO(benjhayden) Figure out why DisableExtension() does not fire
3478 // OnListenerRemoved.
3480 // TODO(benjhayden) Test that the shelf is shown for download() both with and
3481 // without a WebContents.
3483 void OnDangerPromptCreated(DownloadDangerPrompt* prompt) {
3484 prompt->InvokeActionForTesting(DownloadDangerPrompt::ACCEPT);
3487 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
3488 DownloadExtensionTest_AcceptDanger) {
3489 // Download a file that will be marked dangerous; click the browser action
3490 // button; the browser action poup will call acceptDanger(); when the
3491 // DownloadDangerPrompt is created, pretend that the user clicks the Accept
3492 // button; wait until the download completes.
3493 LoadExtension("downloads_split");
3494 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3495 new DownloadsDownloadFunction(),
3496 "[{\"url\": \"data:,\", \"filename\": \"dangerous.swf\"}]"));
3497 ASSERT_TRUE(result.get());
3499 ASSERT_TRUE(result->GetAsInteger(&result_id));
3500 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3502 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
3505 " \"previous\": \"safe\","
3506 " \"current\": \"file\"}}]",
3508 ASSERT_TRUE(item->IsDangerous());
3509 ScopedCancellingItem canceller(item);
3510 scoped_ptr<content::DownloadTestObserver> observer(
3511 new content::DownloadTestObserverTerminal(
3512 GetCurrentManager(), 1,
3513 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_IGNORE));
3514 DownloadsAcceptDangerFunction::OnPromptCreatedCallback callback =
3515 base::Bind(&OnDangerPromptCreated);
3516 DownloadsAcceptDangerFunction::OnPromptCreatedForTesting(
3518 BrowserActionTestUtil(browser()).Press(0);
3519 observer->WaitForFinished();
3522 class DownloadsApiTest : public ExtensionApiTest {
3524 DownloadsApiTest() {}
3525 virtual ~DownloadsApiTest() {}
3527 DISALLOW_COPY_AND_ASSIGN(DownloadsApiTest);
3531 IN_PROC_BROWSER_TEST_F(DownloadsApiTest, DownloadsApiTest) {
3532 ASSERT_TRUE(RunExtensionTest("downloads")) << message_;
3535 TEST(DownloadInterruptReasonEnumsSynced,
3536 DownloadInterruptReasonEnumsSynced) {
3537 #define INTERRUPT_REASON(name, value) \
3538 EXPECT_EQ(InterruptReasonContentToExtension( \
3539 content::DOWNLOAD_INTERRUPT_REASON_##name), \
3540 api::INTERRUPT_REASON_##name); \
3541 EXPECT_EQ(InterruptReasonExtensionToContent( \
3542 api::INTERRUPT_REASON_##name), \
3543 content::DOWNLOAD_INTERRUPT_REASON_##name);
3544 #include "content/public/browser/download_interrupt_reason_values.h"
3545 #undef INTERRUPT_REASON
3548 TEST(ExtensionDetermineDownloadFilenameInternal,
3549 ExtensionDetermineDownloadFilenameInternal) {
3551 std::string winner_id;
3552 base::FilePath filename;
3553 extensions::api::downloads::FilenameConflictAction conflict_action =
3554 api::FILENAME_CONFLICT_ACTION_UNIQUIFY;
3555 extensions::ExtensionWarningSet warnings;
3557 // Empty incumbent determiner
3559 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
3560 base::FilePath(FILE_PATH_LITERAL("a")),
3561 api::FILENAME_CONFLICT_ACTION_OVERWRITE,
3570 EXPECT_EQ("suggester", winner_id);
3571 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename.value());
3572 EXPECT_EQ(api::FILENAME_CONFLICT_ACTION_OVERWRITE, conflict_action);
3573 EXPECT_TRUE(warnings.empty());
3577 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
3578 base::FilePath(FILE_PATH_LITERAL("b")),
3579 api::FILENAME_CONFLICT_ACTION_PROMPT,
3581 base::Time::Now() - base::TimeDelta::FromDays(1),
3588 EXPECT_EQ("incumbent", winner_id);
3589 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename.value());
3590 EXPECT_EQ(api::FILENAME_CONFLICT_ACTION_OVERWRITE, conflict_action);
3591 EXPECT_FALSE(warnings.empty());
3592 EXPECT_EQ(extensions::ExtensionWarning::kDownloadFilenameConflict,
3593 warnings.begin()->warning_type());
3594 EXPECT_EQ("suggester", warnings.begin()->extension_id());
3598 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
3599 base::FilePath(FILE_PATH_LITERAL("b")),
3600 api::FILENAME_CONFLICT_ACTION_PROMPT,
3604 base::Time::Now() - base::TimeDelta::FromDays(1),
3609 EXPECT_EQ("suggester", winner_id);
3610 EXPECT_EQ(FILE_PATH_LITERAL("b"), filename.value());
3611 EXPECT_EQ(api::FILENAME_CONFLICT_ACTION_PROMPT, conflict_action);
3612 EXPECT_FALSE(warnings.empty());
3613 EXPECT_EQ(extensions::ExtensionWarning::kDownloadFilenameConflict,
3614 warnings.begin()->warning_type());
3615 EXPECT_EQ("incumbent", warnings.begin()->extension_id());
3617 #endif // Issue 306144