1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Disable everything on windows only. http://crbug.com/306144
10 #include "base/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/json/json_reader.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/stl_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/synchronization/waitable_event.h"
18 #include "chrome/browser/chrome_notification_types.h"
19 #include "chrome/browser/download/download_file_icon_extractor.h"
20 #include "chrome/browser/download/download_service.h"
21 #include "chrome/browser/download/download_service_factory.h"
22 #include "chrome/browser/download/download_test_file_activity_observer.h"
23 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
24 #include "chrome/browser/extensions/browser_action_test_util.h"
25 #include "chrome/browser/extensions/extension_apitest.h"
26 #include "chrome/browser/extensions/extension_function_test_utils.h"
27 #include "chrome/browser/extensions/extension_service.h"
28 #include "chrome/browser/history/download_row.h"
29 #include "chrome/browser/net/url_request_mock_util.h"
30 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/browser/ui/browser.h"
32 #include "chrome/browser/ui/browser_tabstrip.h"
33 #include "chrome/common/pref_names.h"
34 #include "chrome/test/base/in_process_browser_test.h"
35 #include "chrome/test/base/ui_test_utils.h"
36 #include "content/public/browser/browser_context.h"
37 #include "content/public/browser/browser_thread.h"
38 #include "content/public/browser/download_item.h"
39 #include "content/public/browser/download_manager.h"
40 #include "content/public/browser/notification_service.h"
41 #include "content/public/browser/storage_partition.h"
42 #include "content/public/browser/web_contents.h"
43 #include "content/public/common/content_switches.h"
44 #include "content/public/common/page_transition_types.h"
45 #include "content/public/test/download_test_observer.h"
46 #include "content/test/net/url_request_slow_download_job.h"
47 #include "net/base/data_url.h"
48 #include "net/base/net_util.h"
49 #include "net/url_request/url_request.h"
50 #include "net/url_request/url_request_context.h"
51 #include "net/url_request/url_request_job.h"
52 #include "net/url_request/url_request_job_factory.h"
53 #include "net/url_request/url_request_job_factory_impl.h"
54 #include "webkit/browser/fileapi/file_system_context.h"
55 #include "webkit/browser/fileapi/file_system_operation_runner.h"
56 #include "webkit/browser/fileapi/file_system_url.h"
58 using content::BrowserContext;
59 using content::BrowserThread;
60 using content::DownloadItem;
61 using content::DownloadManager;
62 using content::URLRequestSlowDownloadJob;
64 namespace errors = download_extension_errors;
66 namespace api = extensions::api::downloads;
70 // Comparator that orders download items by their ID. Can be used with
72 struct DownloadIdComparator {
73 bool operator() (DownloadItem* first, DownloadItem* second) {
74 return first->GetId() < second->GetId();
78 class DownloadsEventsListener : public content::NotificationObserver {
80 DownloadsEventsListener()
82 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
83 content::NotificationService::AllSources());
86 virtual ~DownloadsEventsListener() {
87 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
88 content::NotificationService::AllSources());
89 STLDeleteElements(&events_);
93 STLDeleteElements(&events_);
99 Event(Profile* profile,
100 const std::string& event_name,
101 const std::string& json_args,
104 event_name_(event_name),
105 json_args_(json_args),
106 args_(base::JSONReader::Read(json_args)),
110 const base::Time& caught() { return caught_; }
112 bool Satisfies(const Event& other) const {
113 return other.SatisfiedBy(*this);
116 bool SatisfiedBy(const Event& other) const {
117 if ((profile_ != other.profile_) ||
118 (event_name_ != other.event_name_))
120 if (((event_name_ == api::OnDeterminingFilename::kEventName) ||
121 (event_name_ == api::OnCreated::kEventName) ||
122 (event_name_ == api::OnChanged::kEventName)) &&
125 base::ListValue* left_list = NULL;
126 base::DictionaryValue* left_dict = NULL;
127 base::ListValue* right_list = NULL;
128 base::DictionaryValue* right_dict = NULL;
129 if (!args_->GetAsList(&left_list) ||
130 !other.args_->GetAsList(&right_list) ||
131 !left_list->GetDictionary(0, &left_dict) ||
132 !right_list->GetDictionary(0, &right_dict))
134 for (base::DictionaryValue::Iterator iter(*left_dict);
135 !iter.IsAtEnd(); iter.Advance()) {
136 base::Value* right_value = NULL;
137 if (!right_dict->HasKey(iter.key()) ||
138 (right_dict->Get(iter.key(), &right_value) &&
139 !iter.value().Equals(right_value))) {
144 } else if ((event_name_ == api::OnErased::kEventName) &&
147 int my_id = -1, other_id = -1;
148 return (args_->GetAsInteger(&my_id) &&
149 other.args_->GetAsInteger(&other_id) &&
152 return json_args_ == other.json_args_;
155 std::string Debug() {
156 return base::StringPrintf("Event(%p, %s, %s, %f)",
165 std::string event_name_;
166 std::string json_args_;
167 scoped_ptr<base::Value> args_;
170 DISALLOW_COPY_AND_ASSIGN(Event);
173 typedef ExtensionDownloadsEventRouter::DownloadsNotificationSource
174 DownloadsNotificationSource;
176 virtual void Observe(int type,
177 const content::NotificationSource& source,
178 const content::NotificationDetails& details) OVERRIDE {
180 case chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT:
182 DownloadsNotificationSource* dns =
183 content::Source<DownloadsNotificationSource>(source).ptr();
184 Event* new_event = new Event(
187 *content::Details<std::string>(details).ptr(), base::Time::Now());
188 events_.push_back(new_event);
190 waiting_for_.get() &&
191 new_event->Satisfies(*waiting_for_)) {
193 base::MessageLoopForUI::current()->Quit();
202 bool WaitFor(Profile* profile,
203 const std::string& event_name,
204 const std::string& json_args) {
205 waiting_for_.reset(new Event(profile, event_name, json_args, base::Time()));
206 for (std::deque<Event*>::const_iterator iter = events_.begin();
207 iter != events_.end(); ++iter) {
208 if ((*iter)->Satisfies(*waiting_for_.get())) {
213 content::RunMessageLoop();
214 bool success = !waiting_;
216 // Print the events that were caught since the last WaitFor() call to help
217 // find the erroneous event.
218 // TODO(benjhayden) Fuzzy-match and highlight the erroneous event.
219 for (std::deque<Event*>::const_iterator iter = events_.begin();
220 iter != events_.end(); ++iter) {
221 if ((*iter)->caught() > last_wait_) {
222 LOG(INFO) << "Caught " << (*iter)->Debug();
225 if (waiting_for_.get()) {
226 LOG(INFO) << "Timed out waiting for " << waiting_for_->Debug();
230 waiting_for_.reset();
231 last_wait_ = base::Time::Now();
237 base::Time last_wait_;
238 scoped_ptr<Event> waiting_for_;
239 content::NotificationRegistrar registrar_;
240 std::deque<Event*> events_;
242 DISALLOW_COPY_AND_ASSIGN(DownloadsEventsListener);
245 class DownloadExtensionTest : public ExtensionApiTest {
247 DownloadExtensionTest()
249 incognito_browser_(NULL),
250 current_browser_(NULL) {
254 // Used with CreateHistoryDownloads
255 struct HistoryDownloadInfo {
256 // Filename to use. CreateHistoryDownloads will append this filename to the
257 // temporary downloads directory specified by downloads_directory().
258 const base::FilePath::CharType* filename;
260 // State for the download. Note that IN_PROGRESS downloads will be created
262 DownloadItem::DownloadState state;
264 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
265 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT.
266 content::DownloadDangerType danger_type;
269 void LoadExtension(const char* name) {
270 // Store the created Extension object so that we can attach it to
271 // ExtensionFunctions. Also load the extension in incognito profiles for
272 // testing incognito.
273 extension_ = LoadExtensionIncognito(test_data_dir_.AppendASCII(name));
275 content::WebContents* tab = chrome::AddSelectedTabWithURL(
277 extension_->GetResourceURL("empty.html"),
278 content::PAGE_TRANSITION_LINK);
279 extensions::ExtensionSystem::Get(current_browser()->profile())->
280 event_router()->AddEventListener(
281 api::OnCreated::kEventName,
282 tab->GetRenderProcessHost(),
284 extensions::ExtensionSystem::Get(current_browser()->profile())->
285 event_router()->AddEventListener(
286 api::OnChanged::kEventName,
287 tab->GetRenderProcessHost(),
289 extensions::ExtensionSystem::Get(current_browser()->profile())->
290 event_router()->AddEventListener(
291 api::OnErased::kEventName,
292 tab->GetRenderProcessHost(),
296 content::RenderProcessHost* AddFilenameDeterminer() {
297 content::WebContents* tab = chrome::AddSelectedTabWithURL(
299 extension_->GetResourceURL("empty.html"),
300 content::PAGE_TRANSITION_LINK);
301 extensions::ExtensionSystem::Get(current_browser()->profile())->
302 event_router()->AddEventListener(
303 api::OnDeterminingFilename::kEventName,
304 tab->GetRenderProcessHost(),
306 return tab->GetRenderProcessHost();
309 void RemoveFilenameDeterminer(content::RenderProcessHost* host) {
310 extensions::ExtensionSystem::Get(current_browser()->profile())->
311 event_router()->RemoveEventListener(
312 api::OnDeterminingFilename::kEventName,
317 Browser* current_browser() { return current_browser_; }
319 // InProcessBrowserTest
320 virtual void SetUpOnMainThread() OVERRIDE {
321 ExtensionApiTest::SetUpOnMainThread();
322 BrowserThread::PostTask(
323 BrowserThread::IO, FROM_HERE,
324 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
325 InProcessBrowserTest::SetUpOnMainThread();
327 CreateAndSetDownloadsDirectory();
328 current_browser()->profile()->GetPrefs()->SetBoolean(
329 prefs::kPromptForDownload, false);
330 GetOnRecordManager()->RemoveAllDownloads();
331 events_listener_.reset(new DownloadsEventsListener());
332 // Disable file chooser for current profile.
333 DownloadTestFileActivityObserver observer(current_browser()->profile());
334 observer.EnableFileChooser(false);
337 void GoOnTheRecord() { current_browser_ = browser(); }
339 void GoOffTheRecord() {
340 if (!incognito_browser_) {
341 incognito_browser_ = CreateIncognitoBrowser();
342 GetOffRecordManager()->RemoveAllDownloads();
343 // Disable file chooser for incognito profile.
344 DownloadTestFileActivityObserver observer(incognito_browser_->profile());
345 observer.EnableFileChooser(false);
347 current_browser_ = incognito_browser_;
350 bool WaitFor(const std::string& event_name, const std::string& json_args) {
351 return events_listener_->WaitFor(
352 current_browser()->profile(), event_name, json_args);
355 bool WaitForInterruption(
357 content::DownloadInterruptReason expected_error,
358 const std::string& on_created_event) {
359 if (!WaitFor(api::OnCreated::kEventName, on_created_event))
361 // Now, onCreated is always fired before interruption.
362 return WaitFor(api::OnChanged::kEventName,
363 base::StringPrintf("[{\"id\": %d,"
364 " \"error\": {\"current\": \"%s\"},"
366 " \"previous\": \"in_progress\","
367 " \"current\": \"interrupted\"}}]",
369 content::DownloadInterruptReasonToString(
370 expected_error).c_str()));
374 events_listener_->ClearEvents();
377 std::string GetExtensionURL() {
378 return extension_->url().spec();
380 std::string GetExtensionId() {
381 return extension_->id();
384 std::string GetFilename(const char* path) {
386 downloads_directory_.path().AppendASCII(path).AsUTF8Unsafe();
388 for (std::string::size_type next = result.find("\\");
389 next != std::string::npos;
390 next = result.find("\\", next)) {
391 result.replace(next, 1, "\\\\");
398 DownloadManager* GetOnRecordManager() {
399 return BrowserContext::GetDownloadManager(browser()->profile());
401 DownloadManager* GetOffRecordManager() {
402 return BrowserContext::GetDownloadManager(
403 browser()->profile()->GetOffTheRecordProfile());
405 DownloadManager* GetCurrentManager() {
406 return (current_browser_ == incognito_browser_) ?
407 GetOffRecordManager() : GetOnRecordManager();
410 // Creates a set of history downloads based on the provided |history_info|
411 // array. |count| is the number of elements in |history_info|. On success,
412 // |items| will contain |count| DownloadItems in the order that they were
413 // specified in |history_info|. Returns true on success and false otherwise.
414 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info,
416 DownloadManager::DownloadVector* items) {
417 DownloadIdComparator download_id_comparator;
418 base::Time current = base::Time::Now();
420 GetOnRecordManager()->GetAllDownloads(items);
421 CHECK_EQ(0, static_cast<int>(items->size()));
422 std::vector<GURL> url_chain;
423 url_chain.push_back(GURL());
424 for (size_t i = 0; i < count; ++i) {
425 DownloadItem* item = GetOnRecordManager()->CreateDownloadItem(
426 content::DownloadItem::kInvalidId + 1 + i,
427 downloads_directory().Append(history_info[i].filename),
428 downloads_directory().Append(history_info[i].filename),
429 url_chain, GURL(), // URL Chain, referrer
430 current, current, // start_time, end_time
431 std::string(), std::string(), // etag, last_modified
432 1, 1, // received_bytes, total_bytes
433 history_info[i].state, // state
434 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
435 content::DOWNLOAD_INTERRUPT_REASON_NONE,
437 items->push_back(item);
440 // Order by ID so that they are in the order that we created them.
441 std::sort(items->begin(), items->end(), download_id_comparator);
442 // Set the danger type if necessary.
443 for (size_t i = 0; i < count; ++i) {
444 if (history_info[i].danger_type !=
445 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
446 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT,
447 history_info[i].danger_type);
448 items->at(i)->OnContentCheckCompleted(history_info[i].danger_type);
454 void CreateSlowTestDownloads(
455 size_t count, DownloadManager::DownloadVector* items) {
456 for (size_t i = 0; i < count; ++i) {
457 scoped_ptr<content::DownloadTestObserver> observer(
458 CreateInProgressDownloadObserver(1));
459 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
460 ui_test_utils::NavigateToURLWithDisposition(
461 current_browser(), slow_download_url, CURRENT_TAB,
462 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
463 observer->WaitForFinished();
465 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
467 GetCurrentManager()->GetAllDownloads(items);
468 ASSERT_EQ(count, items->size());
471 DownloadItem* CreateSlowTestDownload() {
472 scoped_ptr<content::DownloadTestObserver> observer(
473 CreateInProgressDownloadObserver(1));
474 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
475 DownloadManager* manager = GetCurrentManager();
477 EXPECT_EQ(0, manager->NonMaliciousInProgressCount());
478 EXPECT_EQ(0, manager->InProgressCount());
479 if (manager->InProgressCount() != 0)
482 ui_test_utils::NavigateToURLWithDisposition(
483 current_browser(), slow_download_url, CURRENT_TAB,
484 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
486 observer->WaitForFinished();
487 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
489 DownloadManager::DownloadVector items;
490 manager->GetAllDownloads(&items);
492 DownloadItem* new_item = NULL;
493 for (DownloadManager::DownloadVector::iterator iter = items.begin();
494 iter != items.end(); ++iter) {
495 if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) {
496 // There should be only one IN_PROGRESS item.
497 EXPECT_EQ(NULL, new_item);
504 void FinishPendingSlowDownloads() {
505 scoped_ptr<content::DownloadTestObserver> observer(
506 CreateDownloadObserver(1));
507 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl);
508 ui_test_utils::NavigateToURLWithDisposition(
509 current_browser(), finish_url, NEW_FOREGROUND_TAB,
510 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
511 observer->WaitForFinished();
512 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
515 content::DownloadTestObserver* CreateDownloadObserver(size_t download_count) {
516 return new content::DownloadTestObserverTerminal(
517 GetCurrentManager(), download_count,
518 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
521 content::DownloadTestObserver* CreateInProgressDownloadObserver(
522 size_t download_count) {
523 return new content::DownloadTestObserverInProgress(
524 GetCurrentManager(), download_count);
527 bool RunFunction(UIThreadExtensionFunction* function,
528 const std::string& args) {
529 scoped_refptr<UIThreadExtensionFunction> delete_function(function);
530 SetUpExtensionFunction(function);
531 bool result = extension_function_test_utils::RunFunction(
532 function, args, browser(), GetFlags());
534 LOG(ERROR) << function->GetError();
539 extension_function_test_utils::RunFunctionFlags GetFlags() {
540 return current_browser()->profile()->IsOffTheRecord() ?
541 extension_function_test_utils::INCLUDE_INCOGNITO :
542 extension_function_test_utils::NONE;
545 // extension_function_test_utils::RunFunction*() only uses browser for its
546 // profile(), so pass it the on-record browser so that it always uses the
547 // on-record profile to match real-life behavior.
549 base::Value* RunFunctionAndReturnResult(
550 scoped_refptr<UIThreadExtensionFunction> function,
551 const std::string& args) {
552 SetUpExtensionFunction(function.get());
553 return extension_function_test_utils::RunFunctionAndReturnSingleResult(
554 function.get(), args, browser(), GetFlags());
557 std::string RunFunctionAndReturnError(
558 scoped_refptr<UIThreadExtensionFunction> function,
559 const std::string& args) {
560 SetUpExtensionFunction(function.get());
561 return extension_function_test_utils::RunFunctionAndReturnError(
562 function.get(), args, browser(), GetFlags());
565 bool RunFunctionAndReturnString(
566 scoped_refptr<UIThreadExtensionFunction> function,
567 const std::string& args,
568 std::string* result_string) {
569 SetUpExtensionFunction(function.get());
570 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args));
571 EXPECT_TRUE(result.get());
572 return result.get() && result->GetAsString(result_string);
575 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) {
576 return base::StringPrintf("[%d]", download_item->GetId());
579 const base::FilePath& downloads_directory() {
580 return downloads_directory_.path();
583 DownloadsEventsListener* events_listener() { return events_listener_.get(); }
586 void SetUpExtensionFunction(UIThreadExtensionFunction* function) {
588 // Recreate the tab each time for insulation.
589 content::WebContents* tab = chrome::AddSelectedTabWithURL(
591 extension_->GetResourceURL("empty.html"),
592 content::PAGE_TRANSITION_LINK);
593 function->set_extension(extension_);
594 function->SetRenderViewHost(tab->GetRenderViewHost());
598 void CreateAndSetDownloadsDirectory() {
599 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
600 current_browser()->profile()->GetPrefs()->SetFilePath(
601 prefs::kDownloadDefaultDirectory,
602 downloads_directory_.path());
605 base::ScopedTempDir downloads_directory_;
606 const extensions::Extension* extension_;
607 Browser* incognito_browser_;
608 Browser* current_browser_;
609 scoped_ptr<DownloadsEventsListener> events_listener_;
611 DISALLOW_COPY_AND_ASSIGN(DownloadExtensionTest);
614 class MockIconExtractorImpl : public DownloadFileIconExtractor {
616 MockIconExtractorImpl(const base::FilePath& path,
617 IconLoader::IconSize icon_size,
618 const std::string& response)
619 : expected_path_(path),
620 expected_icon_size_(icon_size),
621 response_(response) {
623 virtual ~MockIconExtractorImpl() {}
625 virtual bool ExtractIconURLForPath(const base::FilePath& path,
627 IconLoader::IconSize icon_size,
628 IconURLCallback callback) OVERRIDE {
629 EXPECT_STREQ(expected_path_.value().c_str(), path.value().c_str());
630 EXPECT_EQ(expected_icon_size_, icon_size);
631 if (expected_path_ == path &&
632 expected_icon_size_ == icon_size) {
633 callback_ = callback;
634 BrowserThread::PostTask(
635 BrowserThread::UI, FROM_HERE,
636 base::Bind(&MockIconExtractorImpl::RunCallback,
637 base::Unretained(this)));
646 callback_.Run(response_);
647 // Drop the reference on extension function to avoid memory leaks.
648 callback_ = IconURLCallback();
651 base::FilePath expected_path_;
652 IconLoader::IconSize expected_icon_size_;
653 std::string response_;
654 IconURLCallback callback_;
657 bool ItemNotInProgress(DownloadItem* item) {
658 return item->GetState() != DownloadItem::IN_PROGRESS;
661 // Cancels the underlying DownloadItem when the ScopedCancellingItem goes out of
662 // scope. Like a scoped_ptr, but for DownloadItems.
663 class ScopedCancellingItem {
665 explicit ScopedCancellingItem(DownloadItem* item) : item_(item) {}
666 ~ScopedCancellingItem() {
668 content::DownloadUpdatedObserver observer(
669 item_, base::Bind(&ItemNotInProgress));
670 observer.WaitForEvent();
672 DownloadItem* get() { return item_; }
675 DISALLOW_COPY_AND_ASSIGN(ScopedCancellingItem);
678 // Cancels all the underlying DownloadItems when the ScopedItemVectorCanceller
679 // goes out of scope. Generalization of ScopedCancellingItem to many
681 class ScopedItemVectorCanceller {
683 explicit ScopedItemVectorCanceller(DownloadManager::DownloadVector* items)
686 ~ScopedItemVectorCanceller() {
687 for (DownloadManager::DownloadVector::const_iterator item = items_->begin();
688 item != items_->end(); ++item) {
689 if ((*item)->GetState() == DownloadItem::IN_PROGRESS)
690 (*item)->Cancel(true);
691 content::DownloadUpdatedObserver observer(
692 (*item), base::Bind(&ItemNotInProgress));
693 observer.WaitForEvent();
698 DownloadManager::DownloadVector* items_;
699 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller);
702 // Writes an HTML5 file so that it can be downloaded.
703 class HTML5FileWriter {
705 static bool CreateFileForTesting(fileapi::FileSystemContext* context,
706 const fileapi::FileSystemURL& path,
709 // Create a temp file.
710 base::FilePath temp_file;
711 if (!base::CreateTemporaryFile(&temp_file) ||
712 file_util::WriteFile(temp_file, data, length) != length) {
715 // Invoke the fileapi to copy it into the sandboxed filesystem.
717 base::WaitableEvent done_event(true, false);
718 BrowserThread::PostTask(
719 BrowserThread::IO, FROM_HERE,
720 base::Bind(&CreateFileForTestingOnIOThread,
721 base::Unretained(context),
723 base::Unretained(&result),
724 base::Unretained(&done_event)));
725 // Wait for that to finish.
727 base::DeleteFile(temp_file, false);
732 static void CopyInCompletion(bool* result,
733 base::WaitableEvent* done_event,
734 base::File::Error error) {
735 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
736 *result = error == base::File::FILE_OK;
737 done_event->Signal();
740 static void CreateFileForTestingOnIOThread(
741 fileapi::FileSystemContext* context,
742 const fileapi::FileSystemURL& path,
743 const base::FilePath& temp_file,
745 base::WaitableEvent* done_event) {
746 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
747 context->operation_runner()->CopyInForeignFile(
749 base::Bind(&CopyInCompletion,
750 base::Unretained(result),
751 base::Unretained(done_event)));
755 // TODO(benjhayden) Merge this with the other TestObservers.
756 class JustInProgressDownloadObserver
757 : public content::DownloadTestObserverInProgress {
759 JustInProgressDownloadObserver(
760 DownloadManager* download_manager, size_t wait_count)
761 : content::DownloadTestObserverInProgress(download_manager, wait_count) {
764 virtual ~JustInProgressDownloadObserver() {}
767 virtual bool IsDownloadInFinalState(DownloadItem* item) OVERRIDE {
768 return item->GetState() == DownloadItem::IN_PROGRESS;
771 DISALLOW_COPY_AND_ASSIGN(JustInProgressDownloadObserver);
774 bool ItemIsInterrupted(DownloadItem* item) {
775 return item->GetState() == DownloadItem::INTERRUPTED;
778 content::DownloadInterruptReason InterruptReasonExtensionToContent(
779 api::InterruptReason error) {
781 case api::INTERRUPT_REASON_NONE:
782 return content::DOWNLOAD_INTERRUPT_REASON_NONE;
783 #define INTERRUPT_REASON(name, value) \
784 case api::INTERRUPT_REASON_##name: \
785 return content::DOWNLOAD_INTERRUPT_REASON_##name;
786 #include "content/public/browser/download_interrupt_reason_values.h"
787 #undef INTERRUPT_REASON
790 return content::DOWNLOAD_INTERRUPT_REASON_NONE;
793 api::InterruptReason InterruptReasonContentToExtension(
794 content::DownloadInterruptReason error) {
796 case content::DOWNLOAD_INTERRUPT_REASON_NONE:
797 return api::INTERRUPT_REASON_NONE;
798 #define INTERRUPT_REASON(name, value) \
799 case content::DOWNLOAD_INTERRUPT_REASON_##name: \
800 return api::INTERRUPT_REASON_##name;
801 #include "content/public/browser/download_interrupt_reason_values.h"
802 #undef INTERRUPT_REASON
805 return api::INTERRUPT_REASON_NONE;
810 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
811 DownloadExtensionTest_Open) {
812 LoadExtension("downloads_split");
813 EXPECT_STREQ(errors::kInvalidId,
814 RunFunctionAndReturnError(
815 new DownloadsOpenFunction(),
818 DownloadItem* download_item = CreateSlowTestDownload();
819 ASSERT_TRUE(download_item);
820 EXPECT_FALSE(download_item->GetOpened());
821 EXPECT_FALSE(download_item->GetOpenWhenComplete());
822 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
823 base::StringPrintf("[{\"danger\": \"safe\","
824 " \"incognito\": false,"
825 " \"mime\": \"application/octet-stream\","
826 " \"paused\": false,"
827 " \"url\": \"%s\"}]",
828 download_item->GetURL().spec().c_str())));
829 EXPECT_STREQ(errors::kNotComplete,
830 RunFunctionAndReturnError(
831 new DownloadsOpenFunction(),
832 DownloadItemIdAsArgList(download_item)).c_str());
834 FinishPendingSlowDownloads();
835 EXPECT_FALSE(download_item->GetOpened());
836 EXPECT_TRUE(RunFunction(new DownloadsOpenFunction(),
837 DownloadItemIdAsArgList(download_item)));
838 EXPECT_TRUE(download_item->GetOpened());
841 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
842 DownloadExtensionTest_PauseResumeCancelErase) {
843 DownloadItem* download_item = CreateSlowTestDownload();
844 ASSERT_TRUE(download_item);
847 // Call pause(). It should succeed and the download should be paused on
849 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
850 DownloadItemIdAsArgList(download_item)));
851 EXPECT_TRUE(download_item->IsPaused());
853 // Calling removeFile on a non-active download yields kNotComplete
854 // and should not crash. http://crbug.com/319984
855 error = RunFunctionAndReturnError(new DownloadsRemoveFileFunction(),
856 DownloadItemIdAsArgList(download_item));
857 EXPECT_STREQ(errors::kNotComplete, error.c_str());
859 // Calling pause() twice shouldn't be an error.
860 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
861 DownloadItemIdAsArgList(download_item)));
862 EXPECT_TRUE(download_item->IsPaused());
864 // Now try resuming this download. It should succeed.
865 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
866 DownloadItemIdAsArgList(download_item)));
867 EXPECT_FALSE(download_item->IsPaused());
869 // Resume again. Resuming a download that wasn't paused is not an error.
870 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
871 DownloadItemIdAsArgList(download_item)));
872 EXPECT_FALSE(download_item->IsPaused());
875 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
876 DownloadItemIdAsArgList(download_item)));
877 EXPECT_TRUE(download_item->IsPaused());
880 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
881 DownloadItemIdAsArgList(download_item)));
882 EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());
884 // Cancel again. Shouldn't have any effect.
885 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
886 DownloadItemIdAsArgList(download_item)));
887 EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());
889 // Calling paused on a non-active download yields kNotInProgress.
890 error = RunFunctionAndReturnError(
891 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item));
892 EXPECT_STREQ(errors::kNotInProgress, error.c_str());
894 // Calling resume on a non-active download yields kNotResumable
895 error = RunFunctionAndReturnError(
896 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item));
897 EXPECT_STREQ(errors::kNotResumable, error.c_str());
899 // Calling pause on a non-existent download yields kInvalidId.
900 error = RunFunctionAndReturnError(
901 new DownloadsPauseFunction(), "[-42]");
902 EXPECT_STREQ(errors::kInvalidId, error.c_str());
904 // Calling resume on a non-existent download yields kInvalidId
905 error = RunFunctionAndReturnError(
906 new DownloadsResumeFunction(), "[-42]");
907 EXPECT_STREQ(errors::kInvalidId, error.c_str());
909 // Calling removeFile on a non-existent download yields kInvalidId.
910 error = RunFunctionAndReturnError(
911 new DownloadsRemoveFileFunction(), "[-42]");
912 EXPECT_STREQ(errors::kInvalidId, error.c_str());
914 int id = download_item->GetId();
915 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
916 new DownloadsEraseFunction(),
917 base::StringPrintf("[{\"id\": %d}]", id)));
918 DownloadManager::DownloadVector items;
919 GetCurrentManager()->GetAllDownloads(&items);
920 EXPECT_EQ(0UL, items.size());
922 download_item = NULL;
923 base::ListValue* result_list = NULL;
924 ASSERT_TRUE(result->GetAsList(&result_list));
925 ASSERT_EQ(1UL, result_list->GetSize());
927 ASSERT_TRUE(result_list->GetInteger(0, &element));
928 EXPECT_EQ(id, element);
931 scoped_refptr<UIThreadExtensionFunction> MockedGetFileIconFunction(
932 const base::FilePath& expected_path,
933 IconLoader::IconSize icon_size,
934 const std::string& response) {
935 scoped_refptr<DownloadsGetFileIconFunction> function(
936 new DownloadsGetFileIconFunction());
937 function->SetIconExtractorForTesting(new MockIconExtractorImpl(
938 expected_path, icon_size, response));
942 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted
944 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
945 DownloadExtensionTest_FileIcon_Active) {
946 DownloadItem* download_item = CreateSlowTestDownload();
947 ASSERT_TRUE(download_item);
948 ASSERT_FALSE(download_item->GetTargetFilePath().empty());
949 std::string args32(base::StringPrintf("[%d, {\"size\": 32}]",
950 download_item->GetId()));
951 std::string result_string;
953 // Get the icon for the in-progress download. This call should succeed even
954 // if the file type isn't registered.
955 // Test whether the correct path is being pased into the icon extractor.
956 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
957 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
958 base::StringPrintf("[%d, {}]", download_item->GetId()), &result_string));
960 // Now try a 16x16 icon.
961 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
962 download_item->GetTargetFilePath(), IconLoader::SMALL, "foo"),
963 base::StringPrintf("[%d, {\"size\": 16}]", download_item->GetId()),
966 // Explicitly asking for 32x32 should give us a 32x32 icon.
967 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
968 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
969 args32, &result_string));
971 // Finish the download and try again.
972 FinishPendingSlowDownloads();
973 EXPECT_EQ(DownloadItem::COMPLETE, download_item->GetState());
974 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
975 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
976 args32, &result_string));
978 // Check the path passed to the icon extractor post-completion.
979 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
980 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
981 args32, &result_string));
983 // Now create another download.
984 download_item = CreateSlowTestDownload();
985 ASSERT_TRUE(download_item);
986 ASSERT_FALSE(download_item->GetTargetFilePath().empty());
987 args32 = base::StringPrintf("[%d, {\"size\": 32}]", download_item->GetId());
989 // Cancel the download. As long as the download has a target path, we should
990 // be able to query the file icon.
991 download_item->Cancel(true);
992 ASSERT_FALSE(download_item->GetTargetFilePath().empty());
993 // Let cleanup complete on the FILE thread.
994 content::RunAllPendingInMessageLoop(BrowserThread::FILE);
995 // Check the path passed to the icon extractor post-cancellation.
996 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
997 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
1001 // Simulate an error during icon load by invoking the mock with an empty
1003 std::string error = RunFunctionAndReturnError(
1004 MockedGetFileIconFunction(download_item->GetTargetFilePath(),
1008 EXPECT_STREQ(errors::kIconNotFound, error.c_str());
1010 // Once the download item is deleted, we should return kInvalidId.
1011 int id = download_item->GetId();
1012 download_item->Remove();
1013 download_item = NULL;
1014 EXPECT_EQ(static_cast<DownloadItem*>(NULL),
1015 GetCurrentManager()->GetDownload(id));
1016 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args32);
1017 EXPECT_STREQ(errors::kInvalidId,
1021 // Test that we can acquire file icons for history downloads regardless of
1022 // whether they exist or not. If the file doesn't exist we should receive a
1023 // generic icon from the OS/toolkit that may or may not be specific to the file
1025 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1026 DownloadExtensionTest_FileIcon_History) {
1027 const HistoryDownloadInfo kHistoryInfo[] = {
1028 { FILE_PATH_LITERAL("real.txt"),
1029 DownloadItem::COMPLETE,
1030 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1031 { FILE_PATH_LITERAL("fake.txt"),
1032 DownloadItem::COMPLETE,
1033 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1035 DownloadManager::DownloadVector all_downloads;
1036 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1039 base::FilePath real_path = all_downloads[0]->GetTargetFilePath();
1040 base::FilePath fake_path = all_downloads[1]->GetTargetFilePath();
1042 EXPECT_EQ(0, file_util::WriteFile(real_path, "", 0));
1043 ASSERT_TRUE(base::PathExists(real_path));
1044 ASSERT_FALSE(base::PathExists(fake_path));
1046 for (DownloadManager::DownloadVector::iterator iter = all_downloads.begin();
1047 iter != all_downloads.end();
1049 std::string result_string;
1050 // Use a MockIconExtractorImpl to test if the correct path is being passed
1051 // into the DownloadFileIconExtractor.
1052 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1053 (*iter)->GetTargetFilePath(), IconLoader::NORMAL, "hello"),
1054 base::StringPrintf("[%d, {\"size\": 32}]", (*iter)->GetId()),
1056 EXPECT_STREQ("hello", result_string.c_str());
1060 // Test passing the empty query to search().
1061 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1062 DownloadExtensionTest_SearchEmptyQuery) {
1063 ScopedCancellingItem item(CreateSlowTestDownload());
1064 ASSERT_TRUE(item.get());
1066 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1067 new DownloadsSearchFunction(), "[{}]"));
1068 ASSERT_TRUE(result.get());
1069 base::ListValue* result_list = NULL;
1070 ASSERT_TRUE(result->GetAsList(&result_list));
1071 ASSERT_EQ(1UL, result_list->GetSize());
1074 // Test the |filenameRegex| parameter for search().
1075 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1076 DownloadExtensionTest_SearchFilenameRegex) {
1077 const HistoryDownloadInfo kHistoryInfo[] = {
1078 { FILE_PATH_LITERAL("foobar"),
1079 DownloadItem::COMPLETE,
1080 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1081 { FILE_PATH_LITERAL("baz"),
1082 DownloadItem::COMPLETE,
1083 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1085 DownloadManager::DownloadVector all_downloads;
1086 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1089 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1090 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]"));
1091 ASSERT_TRUE(result.get());
1092 base::ListValue* result_list = NULL;
1093 ASSERT_TRUE(result->GetAsList(&result_list));
1094 ASSERT_EQ(1UL, result_list->GetSize());
1095 base::DictionaryValue* item_value = NULL;
1096 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
1098 ASSERT_TRUE(item_value->GetInteger("id", &item_id));
1099 ASSERT_EQ(all_downloads[0]->GetId(), static_cast<uint32>(item_id));
1102 // Test the |id| parameter for search().
1103 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_SearchId) {
1104 DownloadManager::DownloadVector items;
1105 CreateSlowTestDownloads(2, &items);
1106 ScopedItemVectorCanceller delete_items(&items);
1108 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1109 new DownloadsSearchFunction(), base::StringPrintf(
1110 "[{\"id\": %u}]", items[0]->GetId())));
1111 ASSERT_TRUE(result.get());
1112 base::ListValue* result_list = NULL;
1113 ASSERT_TRUE(result->GetAsList(&result_list));
1114 ASSERT_EQ(1UL, result_list->GetSize());
1115 base::DictionaryValue* item_value = NULL;
1116 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
1118 ASSERT_TRUE(item_value->GetInteger("id", &item_id));
1119 ASSERT_EQ(items[0]->GetId(), static_cast<uint32>(item_id));
1122 // Test specifying both the |id| and |filename| parameters for search().
1123 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1124 DownloadExtensionTest_SearchIdAndFilename) {
1125 DownloadManager::DownloadVector items;
1126 CreateSlowTestDownloads(2, &items);
1127 ScopedItemVectorCanceller delete_items(&items);
1129 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1130 new DownloadsSearchFunction(),
1131 "[{\"id\": 0, \"filename\": \"foobar\"}]"));
1132 ASSERT_TRUE(result.get());
1133 base::ListValue* result_list = NULL;
1134 ASSERT_TRUE(result->GetAsList(&result_list));
1135 ASSERT_EQ(0UL, result_list->GetSize());
1138 // Test a single |orderBy| parameter for search().
1139 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1140 DownloadExtensionTest_SearchOrderBy) {
1141 const HistoryDownloadInfo kHistoryInfo[] = {
1142 { FILE_PATH_LITERAL("zzz"),
1143 DownloadItem::COMPLETE,
1144 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1145 { FILE_PATH_LITERAL("baz"),
1146 DownloadItem::COMPLETE,
1147 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1149 DownloadManager::DownloadVector items;
1150 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1153 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1154 new DownloadsSearchFunction(), "[{\"orderBy\": [\"filename\"]}]"));
1155 ASSERT_TRUE(result.get());
1156 base::ListValue* result_list = NULL;
1157 ASSERT_TRUE(result->GetAsList(&result_list));
1158 ASSERT_EQ(2UL, result_list->GetSize());
1159 base::DictionaryValue* item0_value = NULL;
1160 base::DictionaryValue* item1_value = NULL;
1161 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value));
1162 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value));
1163 std::string item0_name, item1_name;
1164 ASSERT_TRUE(item0_value->GetString("filename", &item0_name));
1165 ASSERT_TRUE(item1_value->GetString("filename", &item1_name));
1166 ASSERT_GT(items[0]->GetTargetFilePath().value(),
1167 items[1]->GetTargetFilePath().value());
1168 ASSERT_LT(item0_name, item1_name);
1171 // Test specifying an empty |orderBy| parameter for search().
1172 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1173 DownloadExtensionTest_SearchOrderByEmpty) {
1174 const HistoryDownloadInfo kHistoryInfo[] = {
1175 { FILE_PATH_LITERAL("zzz"),
1176 DownloadItem::COMPLETE,
1177 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1178 { FILE_PATH_LITERAL("baz"),
1179 DownloadItem::COMPLETE,
1180 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1182 DownloadManager::DownloadVector items;
1183 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1186 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1187 new DownloadsSearchFunction(), "[{\"orderBy\": []}]"));
1188 ASSERT_TRUE(result.get());
1189 base::ListValue* result_list = NULL;
1190 ASSERT_TRUE(result->GetAsList(&result_list));
1191 ASSERT_EQ(2UL, result_list->GetSize());
1192 base::DictionaryValue* item0_value = NULL;
1193 base::DictionaryValue* item1_value = NULL;
1194 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value));
1195 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value));
1196 std::string item0_name, item1_name;
1197 ASSERT_TRUE(item0_value->GetString("filename", &item0_name));
1198 ASSERT_TRUE(item1_value->GetString("filename", &item1_name));
1199 ASSERT_GT(items[0]->GetTargetFilePath().value(),
1200 items[1]->GetTargetFilePath().value());
1201 ASSERT_GT(item0_name, item1_name);
1204 // Test the |danger| option for search().
1205 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1206 DownloadExtensionTest_SearchDanger) {
1207 const HistoryDownloadInfo kHistoryInfo[] = {
1208 { FILE_PATH_LITERAL("zzz"),
1209 DownloadItem::COMPLETE,
1210 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
1211 { FILE_PATH_LITERAL("baz"),
1212 DownloadItem::COMPLETE,
1213 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1215 DownloadManager::DownloadVector items;
1216 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1219 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1220 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]"));
1221 ASSERT_TRUE(result.get());
1222 base::ListValue* result_list = NULL;
1223 ASSERT_TRUE(result->GetAsList(&result_list));
1224 ASSERT_EQ(1UL, result_list->GetSize());
1227 // Test the |state| option for search().
1228 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1229 DownloadExtensionTest_SearchState) {
1230 DownloadManager::DownloadVector items;
1231 CreateSlowTestDownloads(2, &items);
1232 ScopedItemVectorCanceller delete_items(&items);
1234 items[0]->Cancel(true);
1236 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1237 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]"));
1238 ASSERT_TRUE(result.get());
1239 base::ListValue* result_list = NULL;
1240 ASSERT_TRUE(result->GetAsList(&result_list));
1241 ASSERT_EQ(1UL, result_list->GetSize());
1244 // Test the |limit| option for search().
1245 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1246 DownloadExtensionTest_SearchLimit) {
1247 DownloadManager::DownloadVector items;
1248 CreateSlowTestDownloads(2, &items);
1249 ScopedItemVectorCanceller delete_items(&items);
1251 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1252 new DownloadsSearchFunction(), "[{\"limit\": 1}]"));
1253 ASSERT_TRUE(result.get());
1254 base::ListValue* result_list = NULL;
1255 ASSERT_TRUE(result->GetAsList(&result_list));
1256 ASSERT_EQ(1UL, result_list->GetSize());
1259 // Test invalid search parameters.
1260 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1261 DownloadExtensionTest_SearchInvalid) {
1262 std::string error = RunFunctionAndReturnError(
1263 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]");
1264 EXPECT_STREQ(errors::kInvalidFilter,
1266 error = RunFunctionAndReturnError(
1267 new DownloadsSearchFunction(), "[{\"orderBy\": [\"goat\"]}]");
1268 EXPECT_STREQ(errors::kInvalidOrderBy,
1270 error = RunFunctionAndReturnError(
1271 new DownloadsSearchFunction(), "[{\"limit\": -1}]");
1272 EXPECT_STREQ(errors::kInvalidQueryLimit,
1276 // Test searching using multiple conditions through multiple downloads.
1277 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1278 DownloadExtensionTest_SearchPlural) {
1279 const HistoryDownloadInfo kHistoryInfo[] = {
1280 { FILE_PATH_LITERAL("aaa"),
1281 DownloadItem::CANCELLED,
1282 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1283 { FILE_PATH_LITERAL("zzz"),
1284 DownloadItem::COMPLETE,
1285 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
1286 { FILE_PATH_LITERAL("baz"),
1287 DownloadItem::COMPLETE,
1288 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
1290 DownloadManager::DownloadVector items;
1291 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1294 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1295 new DownloadsSearchFunction(), "[{"
1296 "\"state\": \"complete\", "
1297 "\"danger\": \"content\", "
1298 "\"orderBy\": [\"filename\"], "
1300 ASSERT_TRUE(result.get());
1301 base::ListValue* result_list = NULL;
1302 ASSERT_TRUE(result->GetAsList(&result_list));
1303 ASSERT_EQ(1UL, result_list->GetSize());
1304 base::DictionaryValue* item_value = NULL;
1305 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
1306 base::FilePath::StringType item_name;
1307 ASSERT_TRUE(item_value->GetString("filename", &item_name));
1308 ASSERT_EQ(items[2]->GetTargetFilePath().value(), item_name);
1311 // Test that incognito downloads are only visible in incognito contexts, and
1312 // test that on-record downloads are visible in both incognito and on-record
1313 // contexts, for DownloadsSearchFunction, DownloadsPauseFunction,
1314 // DownloadsResumeFunction, and DownloadsCancelFunction.
1315 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1316 DownloadExtensionTest_SearchPauseResumeCancelGetFileIconIncognito) {
1317 scoped_ptr<base::Value> result_value;
1318 base::ListValue* result_list = NULL;
1319 base::DictionaryValue* result_dict = NULL;
1320 base::FilePath::StringType filename;
1321 bool is_incognito = false;
1323 std::string on_item_arg;
1324 std::string off_item_arg;
1325 std::string result_string;
1327 // Set up one on-record item and one off-record item.
1328 // Set up the off-record item first because otherwise there are mysteriously 3
1329 // items total instead of 2.
1330 // TODO(benjhayden): Figure out where the third item comes from.
1332 DownloadItem* off_item = CreateSlowTestDownload();
1333 ASSERT_TRUE(off_item);
1334 off_item_arg = DownloadItemIdAsArgList(off_item);
1337 DownloadItem* on_item = CreateSlowTestDownload();
1338 ASSERT_TRUE(on_item);
1339 on_item_arg = DownloadItemIdAsArgList(on_item);
1340 ASSERT_TRUE(on_item->GetTargetFilePath() != off_item->GetTargetFilePath());
1342 // Extensions running in the incognito window should have access to both
1343 // items because the Test extension is in spanning mode.
1345 result_value.reset(RunFunctionAndReturnResult(
1346 new DownloadsSearchFunction(), "[{}]"));
1347 ASSERT_TRUE(result_value.get());
1348 ASSERT_TRUE(result_value->GetAsList(&result_list));
1349 ASSERT_EQ(2UL, result_list->GetSize());
1350 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict));
1351 ASSERT_TRUE(result_dict->GetString("filename", &filename));
1352 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
1353 EXPECT_TRUE(on_item->GetTargetFilePath() == base::FilePath(filename));
1354 EXPECT_FALSE(is_incognito);
1355 ASSERT_TRUE(result_list->GetDictionary(1, &result_dict));
1356 ASSERT_TRUE(result_dict->GetString("filename", &filename));
1357 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
1358 EXPECT_TRUE(off_item->GetTargetFilePath() == base::FilePath(filename));
1359 EXPECT_TRUE(is_incognito);
1361 // Extensions running in the on-record window should have access only to the
1364 result_value.reset(RunFunctionAndReturnResult(
1365 new DownloadsSearchFunction(), "[{}]"));
1366 ASSERT_TRUE(result_value.get());
1367 ASSERT_TRUE(result_value->GetAsList(&result_list));
1368 ASSERT_EQ(1UL, result_list->GetSize());
1369 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict));
1370 ASSERT_TRUE(result_dict->GetString("filename", &filename));
1371 EXPECT_TRUE(on_item->GetTargetFilePath() == base::FilePath(filename));
1372 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
1373 EXPECT_FALSE(is_incognito);
1375 // Pausing/Resuming the off-record item while on the record should return an
1376 // error. Cancelling "non-existent" downloads is not an error.
1377 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg);
1378 EXPECT_STREQ(errors::kInvalidId,
1380 error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
1382 EXPECT_STREQ(errors::kInvalidId,
1384 error = RunFunctionAndReturnError(
1385 new DownloadsGetFileIconFunction(),
1386 base::StringPrintf("[%d, {}]", off_item->GetId()));
1387 EXPECT_STREQ(errors::kInvalidId,
1392 // Do the FileIcon test for both the on- and off-items while off the record.
1393 // NOTE(benjhayden): This does not include the FileIcon test from history,
1394 // just active downloads. This shouldn't be a problem.
1395 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1396 on_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
1397 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string));
1398 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1399 off_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
1400 base::StringPrintf("[%d, {}]", off_item->GetId()), &result_string));
1402 // Do the pause/resume/cancel test for both the on- and off-items while off
1404 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
1405 EXPECT_TRUE(on_item->IsPaused());
1406 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
1407 EXPECT_TRUE(on_item->IsPaused());
1408 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg));
1409 EXPECT_FALSE(on_item->IsPaused());
1410 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg));
1411 EXPECT_FALSE(on_item->IsPaused());
1412 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
1413 EXPECT_TRUE(on_item->IsPaused());
1414 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg));
1415 EXPECT_EQ(DownloadItem::CANCELLED, on_item->GetState());
1416 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg));
1417 EXPECT_EQ(DownloadItem::CANCELLED, on_item->GetState());
1418 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), on_item_arg);
1419 EXPECT_STREQ(errors::kNotInProgress, error.c_str());
1420 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), on_item_arg);
1421 EXPECT_STREQ(errors::kNotResumable, error.c_str());
1422 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
1423 EXPECT_TRUE(off_item->IsPaused());
1424 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
1425 EXPECT_TRUE(off_item->IsPaused());
1426 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg));
1427 EXPECT_FALSE(off_item->IsPaused());
1428 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg));
1429 EXPECT_FALSE(off_item->IsPaused());
1430 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
1431 EXPECT_TRUE(off_item->IsPaused());
1432 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg));
1433 EXPECT_EQ(DownloadItem::CANCELLED, off_item->GetState());
1434 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg));
1435 EXPECT_EQ(DownloadItem::CANCELLED, off_item->GetState());
1436 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg);
1437 EXPECT_STREQ(errors::kNotInProgress, error.c_str());
1438 error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
1440 EXPECT_STREQ(errors::kNotResumable, error.c_str());
1443 // Test that we can start a download and that the correct sequence of events is
1445 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1446 DownloadExtensionTest_Download_Basic) {
1447 LoadExtension("downloads_split");
1448 ASSERT_TRUE(StartEmbeddedTestServer());
1449 ASSERT_TRUE(test_server()->Start());
1450 std::string download_url = test_server()->GetURL("slow?0").spec();
1453 // Start downloading a file.
1454 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1455 new DownloadsDownloadFunction(), base::StringPrintf(
1456 "[{\"url\": \"%s\"}]", download_url.c_str())));
1457 ASSERT_TRUE(result.get());
1459 ASSERT_TRUE(result->GetAsInteger(&result_id));
1460 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1462 ScopedCancellingItem canceller(item);
1463 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1465 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1466 base::StringPrintf("[{\"danger\": \"safe\","
1467 " \"incognito\": false,"
1468 " \"mime\": \"text/plain\","
1469 " \"paused\": false,"
1470 " \"url\": \"%s\"}]",
1471 download_url.c_str())));
1472 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1473 base::StringPrintf("[{\"id\": %d,"
1475 " \"previous\": \"\","
1476 " \"current\": \"%s\"}}]",
1478 GetFilename("slow.txt").c_str())));
1479 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1480 base::StringPrintf("[{\"id\": %d,"
1482 " \"previous\": \"in_progress\","
1483 " \"current\": \"complete\"}}]",
1487 // Test that we can start a download from an incognito context, and that the
1488 // download knows that it's incognito.
1489 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1490 DownloadExtensionTest_Download_Incognito) {
1491 LoadExtension("downloads_split");
1492 ASSERT_TRUE(StartEmbeddedTestServer());
1493 ASSERT_TRUE(test_server()->Start());
1495 std::string download_url = test_server()->GetURL("slow?0").spec();
1497 // Start downloading a file.
1498 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1499 new DownloadsDownloadFunction(), base::StringPrintf(
1500 "[{\"url\": \"%s\"}]", download_url.c_str())));
1501 ASSERT_TRUE(result.get());
1503 ASSERT_TRUE(result->GetAsInteger(&result_id));
1504 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1506 ScopedCancellingItem canceller(item);
1507 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1509 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1510 base::StringPrintf("[{\"danger\": \"safe\","
1511 " \"incognito\": true,"
1512 " \"mime\": \"text/plain\","
1513 " \"paused\": false,"
1514 " \"url\": \"%s\"}]",
1515 download_url.c_str())));
1516 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1517 base::StringPrintf("[{\"id\":%d,"
1519 " \"previous\": \"\","
1520 " \"current\": \"%s\"}}]",
1522 GetFilename("slow.txt").c_str())));
1523 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1524 base::StringPrintf("[{\"id\":%d,"
1526 " \"current\": \"complete\","
1527 " \"previous\": \"in_progress\"}}]",
1532 // This test is very flaky on Win. http://crbug.com/248438
1533 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1534 DISABLED_DownloadExtensionTest_Download_UnsafeHeaders
1536 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1537 DownloadExtensionTest_Download_UnsafeHeaders
1540 // Test that we disallow certain headers case-insensitively.
1541 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1542 MAYBE_DownloadExtensionTest_Download_UnsafeHeaders) {
1543 LoadExtension("downloads_split");
1544 ASSERT_TRUE(StartEmbeddedTestServer());
1545 ASSERT_TRUE(test_server()->Start());
1548 static const char* kUnsafeHeaders[] = {
1555 "coNteNt-traNsfer-eNcodiNg",
1563 "trANsfer-eNcodiNg",
1569 "pRoxY-probably-not-evil",
1570 "sEc-probably-not-evil",
1572 "Access-Control-Request-Headers",
1573 "Access-Control-Request-Method",
1576 for (size_t index = 0; index < arraysize(kUnsafeHeaders); ++index) {
1577 std::string download_url = test_server()->GetURL("slow?0").spec();
1578 EXPECT_STREQ(errors::kInvalidHeader,
1579 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1581 "[{\"url\": \"%s\","
1582 " \"filename\": \"unsafe-header-%d.txt\","
1584 " \"name\": \"%s\","
1585 " \"value\": \"unsafe\"}]}]",
1586 download_url.c_str(),
1587 static_cast<int>(index),
1588 kUnsafeHeaders[index])).c_str());
1593 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1594 DISABLED_DownloadExtensionTest_Download_Subdirectory
1596 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1597 DownloadExtensionTest_Download_Subdirectory
1599 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1600 MAYBE_DownloadExtensionTest_Download_Subdirectory) {
1601 LoadExtension("downloads_split");
1602 ASSERT_TRUE(StartEmbeddedTestServer());
1603 ASSERT_TRUE(test_server()->Start());
1604 std::string download_url = test_server()->GetURL("slow?0").spec();
1607 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1608 new DownloadsDownloadFunction(), base::StringPrintf(
1609 "[{\"url\": \"%s\","
1610 " \"filename\": \"sub/dir/ect/ory.txt\"}]",
1611 download_url.c_str())));
1612 ASSERT_TRUE(result.get());
1614 ASSERT_TRUE(result->GetAsInteger(&result_id));
1615 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1617 ScopedCancellingItem canceller(item);
1618 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1620 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1621 base::StringPrintf("[{\"danger\": \"safe\","
1622 " \"incognito\": false,"
1623 " \"mime\": \"text/plain\","
1624 " \"paused\": false,"
1625 " \"url\": \"%s\"}]",
1626 download_url.c_str())));
1627 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1628 base::StringPrintf("[{\"id\": %d,"
1630 " \"previous\": \"\","
1631 " \"current\": \"%s\"}}]",
1633 GetFilename("sub/dir/ect/ory.txt").c_str())));
1634 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1635 base::StringPrintf("[{\"id\": %d,"
1637 " \"previous\": \"in_progress\","
1638 " \"current\": \"complete\"}}]",
1642 // Test that invalid filenames are disallowed.
1643 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1644 DownloadExtensionTest_Download_InvalidFilename) {
1645 LoadExtension("downloads_split");
1646 ASSERT_TRUE(StartEmbeddedTestServer());
1647 ASSERT_TRUE(test_server()->Start());
1648 std::string download_url = test_server()->GetURL("slow?0").spec();
1651 EXPECT_STREQ(errors::kInvalidFilename,
1652 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1654 "[{\"url\": \"%s\","
1655 " \"filename\": \"../../../../../etc/passwd\"}]",
1656 download_url.c_str())).c_str());
1659 // Test that downloading invalid URLs immediately returns kInvalidURLError.
1660 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1661 DownloadExtensionTest_Download_InvalidURLs) {
1662 LoadExtension("downloads_split");
1665 static const char* kInvalidURLs[] = {
1671 "foo/bar.html#frag",
1675 for (size_t index = 0; index < arraysize(kInvalidURLs); ++index) {
1676 EXPECT_STREQ(errors::kInvalidURL,
1677 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1679 "[{\"url\": \"%s\"}]", kInvalidURLs[index])).c_str())
1680 << kInvalidURLs[index];
1683 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1684 new DownloadsDownloadFunction(),
1685 "[{\"url\": \"javascript:document.write(\\\"hello\\\");\"}]").c_str());
1686 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1687 new DownloadsDownloadFunction(),
1688 "[{\"url\": \"javascript:return false;\"}]").c_str());
1689 EXPECT_STREQ("NETWORK_FAILED", RunFunctionAndReturnError(
1690 new DownloadsDownloadFunction(),
1691 "[{\"url\": \"ftp://example.com/example.txt\"}]").c_str());
1694 // TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to
1695 // permissions, test downloading from ftp.
1697 // Valid URLs plus fragments are still valid URLs.
1698 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1699 DownloadExtensionTest_Download_URLFragment) {
1700 LoadExtension("downloads_split");
1701 ASSERT_TRUE(StartEmbeddedTestServer());
1702 ASSERT_TRUE(test_server()->Start());
1703 std::string download_url = test_server()->GetURL("slow?0#fragment").spec();
1706 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1707 new DownloadsDownloadFunction(), base::StringPrintf(
1708 "[{\"url\": \"%s\"}]", download_url.c_str())));
1709 ASSERT_TRUE(result.get());
1711 ASSERT_TRUE(result->GetAsInteger(&result_id));
1712 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1714 ScopedCancellingItem canceller(item);
1715 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1717 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1718 base::StringPrintf("[{\"danger\": \"safe\","
1719 " \"incognito\": false,"
1720 " \"mime\": \"text/plain\","
1721 " \"paused\": false,"
1722 " \"url\": \"%s\"}]",
1723 download_url.c_str())));
1724 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1725 base::StringPrintf("[{\"id\": %d,"
1727 " \"previous\": \"\","
1728 " \"current\": \"%s\"}}]",
1730 GetFilename("slow.txt").c_str())));
1731 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1732 base::StringPrintf("[{\"id\": %d,"
1734 " \"previous\": \"in_progress\","
1735 " \"current\": \"complete\"}}]",
1739 // Valid data URLs are valid URLs.
1740 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1741 DownloadExtensionTest_Download_DataURL) {
1742 LoadExtension("downloads_split");
1743 std::string download_url = "data:text/plain,hello";
1746 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1747 new DownloadsDownloadFunction(), base::StringPrintf(
1748 "[{\"url\": \"%s\","
1749 " \"filename\": \"data.txt\"}]", download_url.c_str())));
1750 ASSERT_TRUE(result.get());
1752 ASSERT_TRUE(result->GetAsInteger(&result_id));
1753 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1755 ScopedCancellingItem canceller(item);
1756 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1758 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1759 base::StringPrintf("[{\"danger\": \"safe\","
1760 " \"incognito\": false,"
1761 " \"mime\": \"text/plain\","
1762 " \"paused\": false,"
1763 " \"url\": \"%s\"}]",
1764 download_url.c_str())));
1765 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1766 base::StringPrintf("[{\"id\": %d,"
1768 " \"previous\": \"\","
1769 " \"current\": \"%s\"}}]",
1771 GetFilename("data.txt").c_str())));
1772 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1773 base::StringPrintf("[{\"id\": %d,"
1775 " \"previous\": \"in_progress\","
1776 " \"current\": \"complete\"}}]",
1780 // Valid file URLs are valid URLs.
1782 // Disabled due to crbug.com/175711
1783 #define MAYBE_DownloadExtensionTest_Download_File \
1784 DISABLED_DownloadExtensionTest_Download_File
1786 #define MAYBE_DownloadExtensionTest_Download_File \
1787 DownloadExtensionTest_Download_File
1789 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1790 MAYBE_DownloadExtensionTest_Download_File) {
1792 LoadExtension("downloads_split");
1793 std::string download_url = "file:///";
1795 download_url += "C:/";
1798 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1799 new DownloadsDownloadFunction(), base::StringPrintf(
1800 "[{\"url\": \"%s\","
1801 " \"filename\": \"file.txt\"}]", download_url.c_str())));
1802 ASSERT_TRUE(result.get());
1804 ASSERT_TRUE(result->GetAsInteger(&result_id));
1805 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1807 ScopedCancellingItem canceller(item);
1808 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1810 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1811 base::StringPrintf("[{\"danger\": \"safe\","
1812 " \"incognito\": false,"
1813 " \"mime\": \"text/html\","
1814 " \"paused\": false,"
1815 " \"url\": \"%s\"}]",
1816 download_url.c_str())));
1817 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1818 base::StringPrintf("[{\"id\": %d,"
1820 " \"previous\": \"\","
1821 " \"current\": \"%s\"}}]",
1823 GetFilename("file.txt").c_str())));
1824 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1825 base::StringPrintf("[{\"id\": %d,"
1827 " \"previous\": \"in_progress\","
1828 " \"current\": \"complete\"}}]",
1832 // Test that auth-basic-succeed would fail if the resource requires the
1833 // Authorization header and chrome fails to propagate it back to the server.
1834 // This tests both that testserver.py does not succeed when it should fail as
1835 // well as how the downloads extension API exposes the failure to extensions.
1836 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1837 DownloadExtensionTest_Download_AuthBasic_Fail) {
1838 LoadExtension("downloads_split");
1839 ASSERT_TRUE(StartEmbeddedTestServer());
1840 ASSERT_TRUE(test_server()->Start());
1841 std::string download_url = test_server()->GetURL("auth-basic").spec();
1844 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1845 new DownloadsDownloadFunction(), base::StringPrintf(
1846 "[{\"url\": \"%s\","
1847 " \"filename\": \"auth-basic-fail.txt\"}]",
1848 download_url.c_str())));
1849 ASSERT_TRUE(result.get());
1851 ASSERT_TRUE(result->GetAsInteger(&result_id));
1852 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1854 ScopedCancellingItem canceller(item);
1855 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1857 ASSERT_TRUE(WaitForInterruption(
1859 content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED,
1860 base::StringPrintf("[{\"danger\": \"safe\","
1861 " \"incognito\": false,"
1862 " \"mime\": \"text/html\","
1863 " \"paused\": false,"
1864 " \"url\": \"%s\"}]",
1865 download_url.c_str())));
1868 // Test that DownloadsDownloadFunction propagates |headers| to the URLRequest.
1869 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1870 DownloadExtensionTest_Download_Headers) {
1871 LoadExtension("downloads_split");
1872 ASSERT_TRUE(StartEmbeddedTestServer());
1873 ASSERT_TRUE(test_server()->Start());
1874 std::string download_url = test_server()->GetURL("files/downloads/"
1875 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
1878 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1879 new DownloadsDownloadFunction(), base::StringPrintf(
1880 "[{\"url\": \"%s\","
1881 " \"filename\": \"headers-succeed.txt\","
1883 " {\"name\": \"Foo\", \"value\": \"bar\"},"
1884 " {\"name\": \"Qx\", \"value\":\"yo\"}]}]",
1885 download_url.c_str())));
1886 ASSERT_TRUE(result.get());
1888 ASSERT_TRUE(result->GetAsInteger(&result_id));
1889 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1891 ScopedCancellingItem canceller(item);
1892 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1894 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1895 base::StringPrintf("[{\"danger\": \"safe\","
1896 " \"incognito\": false,"
1897 " \"mime\": \"application/octet-stream\","
1898 " \"paused\": false,"
1899 " \"url\": \"%s\"}]",
1900 download_url.c_str())));
1901 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1902 base::StringPrintf("[{\"id\": %d,"
1904 " \"previous\": \"\","
1905 " \"current\": \"%s\"}}]",
1907 GetFilename("headers-succeed.txt").c_str())));
1908 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1909 base::StringPrintf("[{\"id\": %d,"
1911 " \"previous\": \"in_progress\","
1912 " \"current\": \"complete\"}}]",
1916 // Test that headers-succeed would fail if the resource requires the headers and
1917 // chrome fails to propagate them back to the server. This tests both that
1918 // testserver.py does not succeed when it should fail as well as how the
1919 // downloads extension api exposes the failure to extensions.
1920 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1921 DownloadExtensionTest_Download_Headers_Fail) {
1922 LoadExtension("downloads_split");
1923 ASSERT_TRUE(StartEmbeddedTestServer());
1924 ASSERT_TRUE(test_server()->Start());
1925 std::string download_url = test_server()->GetURL("files/downloads/"
1926 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
1929 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1930 new DownloadsDownloadFunction(), base::StringPrintf(
1931 "[{\"url\": \"%s\","
1932 " \"filename\": \"headers-fail.txt\"}]",
1933 download_url.c_str())));
1934 ASSERT_TRUE(result.get());
1936 ASSERT_TRUE(result->GetAsInteger(&result_id));
1937 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1939 ScopedCancellingItem canceller(item);
1940 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1942 ASSERT_TRUE(WaitForInterruption(
1944 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
1945 base::StringPrintf("[{\"danger\": \"safe\","
1946 " \"incognito\": false,"
1947 " \"bytesReceived\": 0.0,"
1948 " \"fileSize\": 0.0,"
1950 " \"paused\": false,"
1951 " \"url\": \"%s\"}]",
1952 download_url.c_str())));
1955 // Test that DownloadsDownloadFunction propagates the Authorization header
1957 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1958 DownloadExtensionTest_Download_AuthBasic) {
1959 LoadExtension("downloads_split");
1960 ASSERT_TRUE(StartEmbeddedTestServer());
1961 ASSERT_TRUE(test_server()->Start());
1962 std::string download_url = test_server()->GetURL("auth-basic").spec();
1963 // This is just base64 of 'username:secret'.
1964 static const char* kAuthorization = "dXNlcm5hbWU6c2VjcmV0";
1967 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1968 new DownloadsDownloadFunction(), base::StringPrintf(
1969 "[{\"url\": \"%s\","
1970 " \"filename\": \"auth-basic-succeed.txt\","
1972 " \"name\": \"Authorization\","
1973 " \"value\": \"Basic %s\"}]}]",
1974 download_url.c_str(), kAuthorization)));
1975 ASSERT_TRUE(result.get());
1977 ASSERT_TRUE(result->GetAsInteger(&result_id));
1978 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1980 ScopedCancellingItem canceller(item);
1981 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1983 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
1984 base::StringPrintf("[{\"danger\": \"safe\","
1985 " \"incognito\": false,"
1986 " \"bytesReceived\": 0.0,"
1987 " \"fileSize\": 0.0,"
1988 " \"mime\": \"text/html\","
1989 " \"paused\": false,"
1990 " \"url\": \"%s\"}]", download_url.c_str())));
1991 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
1992 base::StringPrintf("[{\"id\": %d,"
1994 " \"previous\": \"in_progress\","
1995 " \"current\": \"complete\"}}]", result_id)));
1998 // Test that DownloadsDownloadFunction propagates the |method| and |body|
1999 // parameters to the URLRequest.
2000 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2001 DownloadExtensionTest_Download_Post) {
2002 LoadExtension("downloads_split");
2003 ASSERT_TRUE(StartEmbeddedTestServer());
2004 ASSERT_TRUE(test_server()->Start());
2005 std::string download_url = test_server()->GetURL("files/post/downloads/"
2006 "a_zip_file.zip?expected_body=BODY").spec();
2009 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2010 new DownloadsDownloadFunction(), base::StringPrintf(
2011 "[{\"url\": \"%s\","
2012 " \"filename\": \"post-succeed.txt\","
2013 " \"method\": \"POST\","
2014 " \"body\": \"BODY\"}]",
2015 download_url.c_str())));
2016 ASSERT_TRUE(result.get());
2018 ASSERT_TRUE(result->GetAsInteger(&result_id));
2019 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2021 ScopedCancellingItem canceller(item);
2022 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2024 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2025 base::StringPrintf("[{\"danger\": \"safe\","
2026 " \"incognito\": false,"
2027 " \"mime\": \"application/octet-stream\","
2028 " \"paused\": false,"
2029 " \"url\": \"%s\"}]", download_url.c_str())));
2030 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2031 base::StringPrintf("[{\"id\": %d,"
2033 " \"previous\": \"\","
2034 " \"current\": \"%s\"}}]",
2036 GetFilename("post-succeed.txt").c_str())));
2037 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2038 base::StringPrintf("[{\"id\": %d,"
2040 " \"previous\": \"in_progress\","
2041 " \"current\": \"complete\"}}]",
2045 // Test that downloadPostSuccess would fail if the resource requires the POST
2046 // method, and chrome fails to propagate the |method| parameter back to the
2047 // server. This tests both that testserver.py does not succeed when it should
2048 // fail, and this tests how the downloads extension api exposes the failure to
2050 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2051 DownloadExtensionTest_Download_Post_Get) {
2052 LoadExtension("downloads_split");
2053 ASSERT_TRUE(StartEmbeddedTestServer());
2054 ASSERT_TRUE(test_server()->Start());
2055 std::string download_url = test_server()->GetURL("files/post/downloads/"
2056 "a_zip_file.zip?expected_body=BODY").spec();
2059 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2060 new DownloadsDownloadFunction(), base::StringPrintf(
2061 "[{\"url\": \"%s\","
2062 " \"body\": \"BODY\","
2063 " \"filename\": \"post-get.txt\"}]",
2064 download_url.c_str())));
2065 ASSERT_TRUE(result.get());
2067 ASSERT_TRUE(result->GetAsInteger(&result_id));
2068 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2070 ScopedCancellingItem canceller(item);
2071 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2073 ASSERT_TRUE(WaitForInterruption(
2075 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2076 base::StringPrintf("[{\"danger\": \"safe\","
2077 " \"incognito\": false,"
2079 " \"paused\": false,"
2081 " \"url\": \"%s\"}]",
2083 download_url.c_str())));
2086 // Test that downloadPostSuccess would fail if the resource requires the POST
2087 // method, and chrome fails to propagate the |body| parameter back to the
2088 // server. This tests both that testserver.py does not succeed when it should
2089 // fail, and this tests how the downloads extension api exposes the failure to
2091 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2092 DownloadExtensionTest_Download_Post_NoBody) {
2093 LoadExtension("downloads_split");
2094 ASSERT_TRUE(StartEmbeddedTestServer());
2095 ASSERT_TRUE(test_server()->Start());
2096 std::string download_url = test_server()->GetURL("files/post/downloads/"
2097 "a_zip_file.zip?expected_body=BODY").spec();
2100 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2101 new DownloadsDownloadFunction(), base::StringPrintf(
2102 "[{\"url\": \"%s\","
2103 " \"method\": \"POST\","
2104 " \"filename\": \"post-nobody.txt\"}]",
2105 download_url.c_str())));
2106 ASSERT_TRUE(result.get());
2108 ASSERT_TRUE(result->GetAsInteger(&result_id));
2109 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2111 ScopedCancellingItem canceller(item);
2112 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2114 ASSERT_TRUE(WaitForInterruption(
2116 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2117 base::StringPrintf("[{\"danger\": \"safe\","
2118 " \"incognito\": false,"
2120 " \"paused\": false,"
2122 " \"url\": \"%s\"}]",
2124 download_url.c_str())));
2127 // Test that cancel()ing an in-progress download causes its state to transition
2128 // to interrupted, and test that that state transition is detectable by an
2129 // onChanged event listener. TODO(benjhayden): Test other sources of
2130 // interruptions such as server death.
2131 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2132 DownloadExtensionTest_Download_Cancel) {
2133 LoadExtension("downloads_split");
2134 ASSERT_TRUE(StartEmbeddedTestServer());
2135 ASSERT_TRUE(test_server()->Start());
2136 std::string download_url = test_server()->GetURL(
2137 "download-known-size").spec();
2140 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2141 new DownloadsDownloadFunction(), base::StringPrintf(
2142 "[{\"url\": \"%s\"}]", download_url.c_str())));
2143 ASSERT_TRUE(result.get());
2145 ASSERT_TRUE(result->GetAsInteger(&result_id));
2146 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2148 ScopedCancellingItem canceller(item);
2149 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2151 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2152 base::StringPrintf("[{\"danger\": \"safe\","
2153 " \"incognito\": false,"
2154 " \"mime\": \"application/octet-stream\","
2155 " \"paused\": false,"
2157 " \"url\": \"%s\"}]",
2159 download_url.c_str())));
2161 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2162 base::StringPrintf("[{\"id\": %d,"
2163 " \"error\": {\"current\":\"USER_CANCELED\"},"
2165 " \"previous\": \"in_progress\","
2166 " \"current\": \"interrupted\"}}]",
2170 // Test downloading filesystem: URLs.
2171 // NOTE: chrome disallows creating HTML5 FileSystem Files in incognito.
2172 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2173 DownloadExtensionTest_Download_FileSystemURL) {
2174 static const char* kPayloadData = "on the record\ndata";
2176 LoadExtension("downloads_split");
2178 const std::string download_url = "filesystem:" + GetExtensionURL() +
2179 "temporary/on_record.txt";
2181 // Setup a file in the filesystem which we can download.
2182 ASSERT_TRUE(HTML5FileWriter::CreateFileForTesting(
2183 BrowserContext::GetDefaultStoragePartition(browser()->profile())->
2184 GetFileSystemContext(),
2185 fileapi::FileSystemURL::CreateForTest(GURL(download_url)),
2186 kPayloadData, strlen(kPayloadData)));
2189 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2190 new DownloadsDownloadFunction(), base::StringPrintf(
2191 "[{\"url\": \"%s\"}]", download_url.c_str())));
2192 ASSERT_TRUE(result.get());
2194 ASSERT_TRUE(result->GetAsInteger(&result_id));
2196 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2198 ScopedCancellingItem canceller(item);
2199 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2201 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2202 base::StringPrintf("[{\"danger\": \"safe\","
2203 " \"incognito\": false,"
2204 " \"mime\": \"text/plain\","
2205 " \"paused\": false,"
2206 " \"url\": \"%s\"}]",
2207 download_url.c_str())));
2208 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2209 base::StringPrintf("[{\"id\": %d,"
2211 " \"previous\": \"\","
2212 " \"current\": \"%s\"}}]",
2214 GetFilename("on_record.txt").c_str())));
2215 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2216 base::StringPrintf("[{\"id\": %d,"
2218 " \"previous\": \"in_progress\","
2219 " \"current\": \"complete\"}}]",
2221 std::string disk_data;
2222 EXPECT_TRUE(base::ReadFileToString(item->GetTargetFilePath(), &disk_data));
2223 EXPECT_STREQ(kPayloadData, disk_data.c_str());
2226 // Test is flaky: http://crbug.com/302071
2227 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2228 DISABLED_DownloadExtensionTest_OnDeterminingFilename_NoChange) {
2230 LoadExtension("downloads_split");
2231 AddFilenameDeterminer();
2232 ASSERT_TRUE(StartEmbeddedTestServer());
2233 ASSERT_TRUE(test_server()->Start());
2234 std::string download_url = test_server()->GetURL("slow?0").spec();
2236 // Start downloading a file.
2237 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2238 new DownloadsDownloadFunction(), base::StringPrintf(
2239 "[{\"url\": \"%s\"}]", download_url.c_str())));
2240 ASSERT_TRUE(result.get());
2242 ASSERT_TRUE(result->GetAsInteger(&result_id));
2243 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2245 ScopedCancellingItem canceller(item);
2246 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2248 // Wait for the onCreated and onDeterminingFilename events.
2249 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2250 base::StringPrintf("[{\"danger\": \"safe\","
2251 " \"incognito\": false,"
2253 " \"mime\": \"text/plain\","
2254 " \"paused\": false,"
2255 " \"url\": \"%s\"}]",
2257 download_url.c_str())));
2258 ASSERT_TRUE(WaitFor(
2259 api::OnDeterminingFilename::kEventName,
2260 base::StringPrintf("[{\"id\": %d,"
2261 " \"filename\":\"slow.txt\"}]",
2263 ASSERT_TRUE(item->GetTargetFilePath().empty());
2264 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2266 // Respond to the onDeterminingFilename.
2268 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2269 browser()->profile(),
2274 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2276 EXPECT_EQ("", error);
2278 // The download should complete successfully.
2279 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2280 base::StringPrintf("[{\"id\": %d,"
2282 " \"previous\": \"\","
2283 " \"current\": \"%s\"}}]",
2285 GetFilename("slow.txt").c_str())));
2286 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2287 base::StringPrintf("[{\"id\": %d,"
2289 " \"previous\": \"in_progress\","
2290 " \"current\": \"complete\"}}]",
2294 IN_PROC_BROWSER_TEST_F(
2295 DownloadExtensionTest,
2296 DownloadExtensionTest_OnDeterminingFilename_DangerousOverride) {
2298 LoadExtension("downloads_split");
2299 AddFilenameDeterminer();
2300 ASSERT_TRUE(StartEmbeddedTestServer());
2301 ASSERT_TRUE(test_server()->Start());
2302 std::string download_url = test_server()->GetURL("slow?0").spec();
2304 // Start downloading a file.
2305 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2306 new DownloadsDownloadFunction(), base::StringPrintf(
2307 "[{\"url\": \"%s\"}]", download_url.c_str())));
2308 ASSERT_TRUE(result.get());
2310 ASSERT_TRUE(result->GetAsInteger(&result_id));
2311 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2313 ScopedCancellingItem canceller(item);
2314 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2316 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2317 base::StringPrintf("[{\"danger\": \"safe\","
2318 " \"incognito\": false,"
2320 " \"mime\": \"text/plain\","
2321 " \"paused\": false,"
2322 " \"url\": \"%s\"}]",
2324 download_url.c_str())));
2325 ASSERT_TRUE(WaitFor(
2326 api::OnDeterminingFilename::kEventName,
2327 base::StringPrintf("[{\"id\": %d,"
2328 " \"filename\":\"slow.txt\"}]",
2330 ASSERT_TRUE(item->GetTargetFilePath().empty());
2331 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2333 // Respond to the onDeterminingFilename.
2335 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2336 browser()->profile(),
2340 base::FilePath(FILE_PATH_LITERAL("overridden.swf")),
2341 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2343 EXPECT_EQ("", error);
2345 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2346 base::StringPrintf("[{\"id\": %d,"
2348 " \"previous\":\"safe\","
2349 " \"current\":\"file\"}}]",
2352 item->ValidateDangerousDownload();
2353 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2354 base::StringPrintf("[{\"id\": %d,"
2356 " \"previous\":\"file\","
2357 " \"current\":\"accepted\"}}]",
2359 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2360 base::StringPrintf("[{\"id\": %d,"
2362 " \"previous\": \"in_progress\","
2363 " \"current\": \"complete\"}}]",
2365 EXPECT_EQ(downloads_directory().AppendASCII("overridden.swf"),
2366 item->GetTargetFilePath());
2369 IN_PROC_BROWSER_TEST_F(
2370 DownloadExtensionTest,
2371 DownloadExtensionTest_OnDeterminingFilename_ReferencesParentInvalid) {
2373 LoadExtension("downloads_split");
2374 AddFilenameDeterminer();
2375 ASSERT_TRUE(StartEmbeddedTestServer());
2376 ASSERT_TRUE(test_server()->Start());
2377 std::string download_url = test_server()->GetURL("slow?0").spec();
2379 // Start downloading a file.
2380 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2381 new DownloadsDownloadFunction(), base::StringPrintf(
2382 "[{\"url\": \"%s\"}]", download_url.c_str())));
2383 ASSERT_TRUE(result.get());
2385 ASSERT_TRUE(result->GetAsInteger(&result_id));
2386 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2388 ScopedCancellingItem canceller(item);
2389 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2391 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2392 base::StringPrintf("[{\"danger\": \"safe\","
2393 " \"incognito\": false,"
2395 " \"mime\": \"text/plain\","
2396 " \"paused\": false,"
2397 " \"url\": \"%s\"}]",
2399 download_url.c_str())));
2400 ASSERT_TRUE(WaitFor(
2401 api::OnDeterminingFilename::kEventName,
2402 base::StringPrintf("[{\"id\": %d,"
2403 " \"filename\":\"slow.txt\"}]",
2405 ASSERT_TRUE(item->GetTargetFilePath().empty());
2406 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2408 // Respond to the onDeterminingFilename.
2410 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2411 browser()->profile(),
2415 base::FilePath(FILE_PATH_LITERAL("sneaky/../../sneaky.txt")),
2416 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2418 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2419 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2420 base::StringPrintf("[{\"id\": %d,"
2422 " \"previous\": \"\","
2423 " \"current\": \"%s\"}}]",
2425 GetFilename("slow.txt").c_str())));
2426 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2427 base::StringPrintf("[{\"id\": %d,"
2429 " \"previous\": \"in_progress\","
2430 " \"current\": \"complete\"}}]",
2434 IN_PROC_BROWSER_TEST_F(
2435 DownloadExtensionTest,
2436 DownloadExtensionTest_OnDeterminingFilename_IllegalFilename) {
2438 LoadExtension("downloads_split");
2439 AddFilenameDeterminer();
2440 ASSERT_TRUE(StartEmbeddedTestServer());
2441 ASSERT_TRUE(test_server()->Start());
2442 std::string download_url = test_server()->GetURL("slow?0").spec();
2444 // Start downloading a file.
2445 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2446 new DownloadsDownloadFunction(), base::StringPrintf(
2447 "[{\"url\": \"%s\"}]", download_url.c_str())));
2448 ASSERT_TRUE(result.get());
2450 ASSERT_TRUE(result->GetAsInteger(&result_id));
2451 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2453 ScopedCancellingItem canceller(item);
2454 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2456 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2457 base::StringPrintf("[{\"danger\": \"safe\","
2458 " \"incognito\": false,"
2460 " \"mime\": \"text/plain\","
2461 " \"paused\": false,"
2462 " \"url\": \"%s\"}]",
2464 download_url.c_str())));
2465 ASSERT_TRUE(WaitFor(
2466 api::OnDeterminingFilename::kEventName,
2467 base::StringPrintf("[{\"id\": %d,"
2468 " \"filename\":\"slow.txt\"}]",
2470 ASSERT_TRUE(item->GetTargetFilePath().empty());
2471 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2473 // Respond to the onDeterminingFilename.
2475 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2476 browser()->profile(),
2480 base::FilePath(FILE_PATH_LITERAL("<")),
2481 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2483 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2484 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
2487 " \"previous\": \"\","
2488 " \"current\": \"%s\"}}]",
2490 GetFilename("slow.txt").c_str())));
2491 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
2494 " \"previous\": \"in_progress\","
2495 " \"current\": \"complete\"}}]",
2499 IN_PROC_BROWSER_TEST_F(
2500 DownloadExtensionTest,
2501 DownloadExtensionTest_OnDeterminingFilename_IllegalFilenameExtension) {
2503 LoadExtension("downloads_split");
2504 AddFilenameDeterminer();
2505 ASSERT_TRUE(StartEmbeddedTestServer());
2506 ASSERT_TRUE(test_server()->Start());
2507 std::string download_url = test_server()->GetURL("slow?0").spec();
2509 // Start downloading a file.
2510 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2511 new DownloadsDownloadFunction(), base::StringPrintf(
2512 "[{\"url\": \"%s\"}]", download_url.c_str())));
2513 ASSERT_TRUE(result.get());
2515 ASSERT_TRUE(result->GetAsInteger(&result_id));
2516 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2518 ScopedCancellingItem canceller(item);
2519 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2521 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2522 base::StringPrintf("[{\"danger\": \"safe\","
2523 " \"incognito\": false,"
2525 " \"mime\": \"text/plain\","
2526 " \"paused\": false,"
2527 " \"url\": \"%s\"}]",
2529 download_url.c_str())));
2530 ASSERT_TRUE(WaitFor(
2531 api::OnDeterminingFilename::kEventName,
2532 base::StringPrintf("[{\"id\": %d,"
2533 " \"filename\":\"slow.txt\"}]",
2535 ASSERT_TRUE(item->GetTargetFilePath().empty());
2536 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2538 // Respond to the onDeterminingFilename.
2540 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2541 browser()->profile(),
2545 base::FilePath(FILE_PATH_LITERAL(
2546 "My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}/foo")),
2547 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2549 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2550 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
2553 " \"previous\": \"\","
2554 " \"current\": \"%s\"}}]",
2556 GetFilename("slow.txt").c_str())));
2557 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
2560 " \"previous\": \"in_progress\","
2561 " \"current\": \"complete\"}}]",
2565 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2566 DISABLED_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2568 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2569 DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2571 IN_PROC_BROWSER_TEST_F(
2572 DownloadExtensionTest,
2573 MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename) {
2575 LoadExtension("downloads_split");
2576 AddFilenameDeterminer();
2577 ASSERT_TRUE(StartEmbeddedTestServer());
2578 ASSERT_TRUE(test_server()->Start());
2579 std::string download_url = test_server()->GetURL("slow?0").spec();
2581 // Start downloading a file.
2582 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2583 new DownloadsDownloadFunction(), base::StringPrintf(
2584 "[{\"url\": \"%s\"}]", download_url.c_str())));
2585 ASSERT_TRUE(result.get());
2587 ASSERT_TRUE(result->GetAsInteger(&result_id));
2588 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2590 ScopedCancellingItem canceller(item);
2591 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2593 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2594 base::StringPrintf("[{\"danger\": \"safe\","
2595 " \"incognito\": false,"
2597 " \"mime\": \"text/plain\","
2598 " \"paused\": false,"
2599 " \"url\": \"%s\"}]",
2601 download_url.c_str())));
2602 ASSERT_TRUE(WaitFor(
2603 api::OnDeterminingFilename::kEventName,
2604 base::StringPrintf("[{\"id\": %d,"
2605 " \"filename\":\"slow.txt\"}]",
2607 ASSERT_TRUE(item->GetTargetFilePath().empty());
2608 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2610 // Respond to the onDeterminingFilename.
2612 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2613 browser()->profile(),
2617 base::FilePath(FILE_PATH_LITERAL("con.foo")),
2618 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2620 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2621 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
2624 " \"previous\": \"\","
2625 " \"current\": \"%s\"}}]",
2627 GetFilename("slow.txt").c_str())));
2628 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
2631 " \"previous\": \"in_progress\","
2632 " \"current\": \"complete\"}}]",
2636 IN_PROC_BROWSER_TEST_F(
2637 DownloadExtensionTest,
2638 DownloadExtensionTest_OnDeterminingFilename_CurDirInvalid) {
2640 LoadExtension("downloads_split");
2641 AddFilenameDeterminer();
2642 ASSERT_TRUE(StartEmbeddedTestServer());
2643 ASSERT_TRUE(test_server()->Start());
2644 std::string download_url = test_server()->GetURL("slow?0").spec();
2646 // Start downloading a file.
2647 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2648 new DownloadsDownloadFunction(), base::StringPrintf(
2649 "[{\"url\": \"%s\"}]", download_url.c_str())));
2650 ASSERT_TRUE(result.get());
2652 ASSERT_TRUE(result->GetAsInteger(&result_id));
2653 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2655 ScopedCancellingItem canceller(item);
2656 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2658 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2659 base::StringPrintf("[{\"danger\": \"safe\","
2660 " \"incognito\": false,"
2662 " \"mime\": \"text/plain\","
2663 " \"paused\": false,"
2664 " \"url\": \"%s\"}]",
2666 download_url.c_str())));
2667 ASSERT_TRUE(WaitFor(
2668 api::OnDeterminingFilename::kEventName,
2669 base::StringPrintf("[{\"id\": %d,"
2670 " \"filename\":\"slow.txt\"}]",
2672 ASSERT_TRUE(item->GetTargetFilePath().empty());
2673 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2675 // Respond to the onDeterminingFilename.
2677 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2678 browser()->profile(),
2682 base::FilePath(FILE_PATH_LITERAL(".")),
2683 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2685 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2686 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2687 base::StringPrintf("[{\"id\": %d,"
2689 " \"previous\": \"\","
2690 " \"current\": \"%s\"}}]",
2692 GetFilename("slow.txt").c_str())));
2693 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2694 base::StringPrintf("[{\"id\": %d,"
2696 " \"previous\": \"in_progress\","
2697 " \"current\": \"complete\"}}]",
2701 IN_PROC_BROWSER_TEST_F(
2702 DownloadExtensionTest,
2703 DownloadExtensionTest_OnDeterminingFilename_ParentDirInvalid) {
2704 ASSERT_TRUE(StartEmbeddedTestServer());
2705 ASSERT_TRUE(test_server()->Start());
2707 LoadExtension("downloads_split");
2708 AddFilenameDeterminer();
2709 std::string download_url = test_server()->GetURL("slow?0").spec();
2711 // Start downloading a file.
2712 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2713 new DownloadsDownloadFunction(), base::StringPrintf(
2714 "[{\"url\": \"%s\"}]", download_url.c_str())));
2715 ASSERT_TRUE(result.get());
2717 ASSERT_TRUE(result->GetAsInteger(&result_id));
2718 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2720 ScopedCancellingItem canceller(item);
2721 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2723 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2724 base::StringPrintf("[{\"danger\": \"safe\","
2725 " \"incognito\": false,"
2727 " \"mime\": \"text/plain\","
2728 " \"paused\": false,"
2729 " \"url\": \"%s\"}]",
2731 download_url.c_str())));
2732 ASSERT_TRUE(WaitFor(
2733 api::OnDeterminingFilename::kEventName,
2734 base::StringPrintf("[{\"id\": %d,"
2735 " \"filename\":\"slow.txt\"}]",
2737 ASSERT_TRUE(item->GetTargetFilePath().empty());
2738 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2740 // Respond to the onDeterminingFilename.
2742 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2743 browser()->profile(),
2747 base::FilePath(FILE_PATH_LITERAL("..")),
2748 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2750 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2751 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2752 base::StringPrintf("[{\"id\": %d,"
2754 " \"previous\": \"\","
2755 " \"current\": \"%s\"}}]",
2757 GetFilename("slow.txt").c_str())));
2758 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2759 base::StringPrintf("[{\"id\": %d,"
2761 " \"previous\": \"in_progress\","
2762 " \"current\": \"complete\"}}]",
2766 IN_PROC_BROWSER_TEST_F(
2767 DownloadExtensionTest,
2768 DownloadExtensionTest_OnDeterminingFilename_AbsPathInvalid) {
2770 LoadExtension("downloads_split");
2771 AddFilenameDeterminer();
2772 ASSERT_TRUE(StartEmbeddedTestServer());
2773 ASSERT_TRUE(test_server()->Start());
2774 std::string download_url = test_server()->GetURL("slow?0").spec();
2776 // Start downloading a file.
2777 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2778 new DownloadsDownloadFunction(), base::StringPrintf(
2779 "[{\"url\": \"%s\"}]", download_url.c_str())));
2780 ASSERT_TRUE(result.get());
2782 ASSERT_TRUE(result->GetAsInteger(&result_id));
2783 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2785 ScopedCancellingItem canceller(item);
2786 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2788 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2789 base::StringPrintf("[{\"danger\": \"safe\","
2790 " \"incognito\": false,"
2792 " \"mime\": \"text/plain\","
2793 " \"paused\": false,"
2794 " \"url\": \"%s\"}]",
2796 download_url.c_str())));
2797 ASSERT_TRUE(WaitFor(
2798 api::OnDeterminingFilename::kEventName,
2799 base::StringPrintf("[{\"id\": %d,"
2800 " \"filename\":\"slow.txt\"}]",
2802 ASSERT_TRUE(item->GetTargetFilePath().empty());
2803 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2805 // Respond to the onDeterminingFilename. Absolute paths should be rejected.
2807 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2808 browser()->profile(),
2812 downloads_directory().Append(FILE_PATH_LITERAL("sneaky.txt")),
2813 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2815 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2817 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2818 base::StringPrintf("[{\"id\": %d,"
2820 " \"previous\": \"\","
2821 " \"current\": \"%s\"}}]",
2823 GetFilename("slow.txt").c_str())));
2824 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2825 base::StringPrintf("[{\"id\": %d,"
2827 " \"previous\": \"in_progress\","
2828 " \"current\": \"complete\"}}]",
2832 IN_PROC_BROWSER_TEST_F(
2833 DownloadExtensionTest,
2834 DownloadExtensionTest_OnDeterminingFilename_EmptyBasenameInvalid) {
2836 LoadExtension("downloads_split");
2837 AddFilenameDeterminer();
2838 ASSERT_TRUE(StartEmbeddedTestServer());
2839 ASSERT_TRUE(test_server()->Start());
2840 std::string download_url = test_server()->GetURL("slow?0").spec();
2842 // Start downloading a file.
2843 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2844 new DownloadsDownloadFunction(), base::StringPrintf(
2845 "[{\"url\": \"%s\"}]", download_url.c_str())));
2846 ASSERT_TRUE(result.get());
2848 ASSERT_TRUE(result->GetAsInteger(&result_id));
2849 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2851 ScopedCancellingItem canceller(item);
2852 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2854 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2855 base::StringPrintf("[{\"danger\": \"safe\","
2856 " \"incognito\": false,"
2858 " \"mime\": \"text/plain\","
2859 " \"paused\": false,"
2860 " \"url\": \"%s\"}]",
2862 download_url.c_str())));
2863 ASSERT_TRUE(WaitFor(
2864 api::OnDeterminingFilename::kEventName,
2865 base::StringPrintf("[{\"id\": %d,"
2866 " \"filename\":\"slow.txt\"}]",
2868 ASSERT_TRUE(item->GetTargetFilePath().empty());
2869 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2871 // Respond to the onDeterminingFilename. Empty basenames should be rejected.
2873 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2874 browser()->profile(),
2878 base::FilePath(FILE_PATH_LITERAL("foo/")),
2879 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2881 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2883 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2884 base::StringPrintf("[{\"id\": %d,"
2886 " \"previous\": \"\","
2887 " \"current\": \"%s\"}}]",
2889 GetFilename("slow.txt").c_str())));
2890 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2891 base::StringPrintf("[{\"id\": %d,"
2893 " \"previous\": \"in_progress\","
2894 " \"current\": \"complete\"}}]",
2898 IN_PROC_BROWSER_TEST_F(
2899 DownloadExtensionTest,
2900 DownloadExtensionTest_OnDeterminingFilename_Override) {
2902 LoadExtension("downloads_split");
2903 AddFilenameDeterminer();
2904 ASSERT_TRUE(StartEmbeddedTestServer());
2905 ASSERT_TRUE(test_server()->Start());
2906 std::string download_url = test_server()->GetURL("slow?0").spec();
2908 // Start downloading a file.
2909 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2910 new DownloadsDownloadFunction(), base::StringPrintf(
2911 "[{\"url\": \"%s\"}]", download_url.c_str())));
2912 ASSERT_TRUE(result.get());
2914 ASSERT_TRUE(result->GetAsInteger(&result_id));
2915 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2917 ScopedCancellingItem canceller(item);
2918 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2919 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2920 base::StringPrintf("[{\"danger\": \"safe\","
2921 " \"incognito\": false,"
2923 " \"mime\": \"text/plain\","
2924 " \"paused\": false,"
2925 " \"url\": \"%s\"}]",
2927 download_url.c_str())));
2928 ASSERT_TRUE(WaitFor(
2929 api::OnDeterminingFilename::kEventName,
2930 base::StringPrintf("[{\"id\": %d,"
2931 " \"filename\":\"slow.txt\"}]",
2933 ASSERT_TRUE(item->GetTargetFilePath().empty());
2934 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2936 // Respond to the onDeterminingFilename.
2938 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2939 browser()->profile(),
2944 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2946 EXPECT_EQ("", error);
2948 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2949 base::StringPrintf("[{\"id\": %d,"
2951 " \"previous\": \"\","
2952 " \"current\": \"%s\"}}]",
2954 GetFilename("slow.txt").c_str())));
2955 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
2956 base::StringPrintf("[{\"id\": %d,"
2958 " \"previous\": \"in_progress\","
2959 " \"current\": \"complete\"}}]",
2962 // Start downloading a file.
2963 result.reset(RunFunctionAndReturnResult(
2964 new DownloadsDownloadFunction(), base::StringPrintf(
2965 "[{\"url\": \"%s\"}]", download_url.c_str())));
2966 ASSERT_TRUE(result.get());
2968 ASSERT_TRUE(result->GetAsInteger(&result_id));
2969 item = GetCurrentManager()->GetDownload(result_id);
2971 ScopedCancellingItem canceller2(item);
2972 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2974 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
2975 base::StringPrintf("[{\"danger\": \"safe\","
2976 " \"incognito\": false,"
2978 " \"mime\": \"text/plain\","
2979 " \"paused\": false,"
2980 " \"url\": \"%s\"}]",
2982 download_url.c_str())));
2983 ASSERT_TRUE(WaitFor(
2984 api::OnDeterminingFilename::kEventName,
2985 base::StringPrintf("[{\"id\": %d,"
2986 " \"filename\":\"slow.txt\"}]",
2988 ASSERT_TRUE(item->GetTargetFilePath().empty());
2989 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2991 // Respond to the onDeterminingFilename.
2992 // Also test that DetermineFilename allows (chrome) extensions to set
2993 // filenames without (filename) extensions. (Don't ask about v8 extensions or
2994 // python extensions or kernel extensions or firefox extensions...)
2996 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2997 browser()->profile(),
3001 base::FilePath(FILE_PATH_LITERAL("foo")),
3002 api::FILENAME_CONFLICT_ACTION_OVERWRITE,
3004 EXPECT_EQ("", error);
3006 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3007 base::StringPrintf("[{\"id\": %d,"
3009 " \"previous\": \"\","
3010 " \"current\": \"%s\"}}]",
3012 GetFilename("foo").c_str())));
3013 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3014 base::StringPrintf("[{\"id\": %d,"
3016 " \"previous\": \"in_progress\","
3017 " \"current\": \"complete\"}}]",
3021 // TODO test precedence rules: install_time
3023 IN_PROC_BROWSER_TEST_F(
3024 DownloadExtensionTest,
3025 DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer) {
3026 ASSERT_TRUE(StartEmbeddedTestServer());
3027 ASSERT_TRUE(test_server()->Start());
3029 LoadExtension("downloads_split");
3030 content::RenderProcessHost* host = AddFilenameDeterminer();
3031 std::string download_url = test_server()->GetURL("slow?0").spec();
3033 // Start downloading a file.
3034 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3035 new DownloadsDownloadFunction(), base::StringPrintf(
3036 "[{\"url\": \"%s\"}]", download_url.c_str())));
3037 ASSERT_TRUE(result.get());
3039 ASSERT_TRUE(result->GetAsInteger(&result_id));
3040 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3042 ScopedCancellingItem canceller(item);
3043 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3045 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
3046 base::StringPrintf("[{\"danger\": \"safe\","
3047 " \"incognito\": false,"
3049 " \"mime\": \"text/plain\","
3050 " \"paused\": false,"
3051 " \"url\": \"%s\"}]",
3053 download_url.c_str())));
3054 ASSERT_TRUE(WaitFor(
3055 api::OnDeterminingFilename::kEventName,
3056 base::StringPrintf("[{\"id\": %d,"
3057 " \"filename\":\"slow.txt\"}]",
3059 ASSERT_TRUE(item->GetTargetFilePath().empty());
3060 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3062 // Remove a determiner while waiting for it.
3063 RemoveFilenameDeterminer(host);
3065 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3066 base::StringPrintf("[{\"id\": %d,"
3068 " \"previous\": \"in_progress\","
3069 " \"current\": \"complete\"}}]",
3073 IN_PROC_BROWSER_TEST_F(
3074 DownloadExtensionTest,
3075 DownloadExtensionTest_OnDeterminingFilename_IncognitoSplit) {
3076 LoadExtension("downloads_split");
3077 ASSERT_TRUE(StartEmbeddedTestServer());
3078 ASSERT_TRUE(test_server()->Start());
3079 std::string download_url = test_server()->GetURL("slow?0").spec();
3082 AddFilenameDeterminer();
3085 AddFilenameDeterminer();
3087 // Start an on-record download.
3089 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3090 new DownloadsDownloadFunction(), base::StringPrintf(
3091 "[{\"url\": \"%s\"}]", download_url.c_str())));
3092 ASSERT_TRUE(result.get());
3094 ASSERT_TRUE(result->GetAsInteger(&result_id));
3095 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3097 ScopedCancellingItem canceller(item);
3098 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3100 // Wait for the onCreated and onDeterminingFilename events.
3101 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
3102 base::StringPrintf("[{\"danger\": \"safe\","
3103 " \"incognito\": false,"
3105 " \"mime\": \"text/plain\","
3106 " \"paused\": false,"
3107 " \"url\": \"%s\"}]",
3109 download_url.c_str())));
3110 ASSERT_TRUE(WaitFor(
3111 api::OnDeterminingFilename::kEventName,
3112 base::StringPrintf("[{\"id\": %d,"
3113 " \"incognito\": false,"
3114 " \"filename\":\"slow.txt\"}]",
3116 ASSERT_TRUE(item->GetTargetFilePath().empty());
3117 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3119 // Respond to the onDeterminingFilename events.
3121 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3122 current_browser()->profile(),
3126 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3127 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3129 EXPECT_EQ("", error);
3131 // The download should complete successfully.
3132 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3133 base::StringPrintf("[{\"id\": %d,"
3135 " \"previous\": \"\","
3136 " \"current\": \"%s\"}}]",
3138 GetFilename("42.txt").c_str())));
3139 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3140 base::StringPrintf("[{\"id\": %d,"
3142 " \"previous\": \"in_progress\","
3143 " \"current\": \"complete\"}}]",
3146 // Start an incognito download for comparison.
3148 result.reset(RunFunctionAndReturnResult(
3149 new DownloadsDownloadFunction(), base::StringPrintf(
3150 "[{\"url\": \"%s\"}]", download_url.c_str())));
3151 ASSERT_TRUE(result.get());
3153 ASSERT_TRUE(result->GetAsInteger(&result_id));
3154 item = GetCurrentManager()->GetDownload(result_id);
3156 ScopedCancellingItem canceller2(item);
3157 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3159 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
3160 base::StringPrintf("[{\"danger\": \"safe\","
3161 " \"incognito\": true,"
3163 " \"mime\": \"text/plain\","
3164 " \"paused\": false,"
3165 " \"url\": \"%s\"}]",
3167 download_url.c_str())));
3168 // On-Record renderers should not see events for off-record items.
3169 ASSERT_TRUE(WaitFor(
3170 api::OnDeterminingFilename::kEventName,
3171 base::StringPrintf("[{\"id\": %d,"
3172 " \"incognito\": true,"
3173 " \"filename\":\"slow.txt\"}]",
3175 ASSERT_TRUE(item->GetTargetFilePath().empty());
3176 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3178 // Respond to the onDeterminingFilename.
3180 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3181 current_browser()->profile(),
3185 base::FilePath(FILE_PATH_LITERAL("5.txt")),
3186 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3188 EXPECT_EQ("", error);
3190 // The download should complete successfully.
3191 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3192 base::StringPrintf("[{\"id\": %d,"
3194 " \"previous\": \"\","
3195 " \"current\": \"%s\"}}]",
3197 GetFilename("5.txt").c_str())));
3198 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3199 base::StringPrintf("[{\"id\": %d,"
3201 " \"previous\": \"in_progress\","
3202 " \"current\": \"complete\"}}]",
3206 IN_PROC_BROWSER_TEST_F(
3207 DownloadExtensionTest,
3208 DownloadExtensionTest_OnDeterminingFilename_IncognitoSpanning) {
3209 LoadExtension("downloads_spanning");
3210 ASSERT_TRUE(StartEmbeddedTestServer());
3211 ASSERT_TRUE(test_server()->Start());
3212 std::string download_url = test_server()->GetURL("slow?0").spec();
3215 AddFilenameDeterminer();
3217 // There is a single extension renderer that sees both on-record and
3218 // off-record events. The extension functions see the on-record profile with
3219 // include_incognito=true.
3221 // Start an on-record download.
3223 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3224 new DownloadsDownloadFunction(), base::StringPrintf(
3225 "[{\"url\": \"%s\"}]", download_url.c_str())));
3226 ASSERT_TRUE(result.get());
3228 ASSERT_TRUE(result->GetAsInteger(&result_id));
3229 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3231 ScopedCancellingItem canceller(item);
3232 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3234 // Wait for the onCreated and onDeterminingFilename events.
3235 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
3236 base::StringPrintf("[{\"danger\": \"safe\","
3237 " \"incognito\": false,"
3239 " \"mime\": \"text/plain\","
3240 " \"paused\": false,"
3241 " \"url\": \"%s\"}]",
3243 download_url.c_str())));
3244 ASSERT_TRUE(WaitFor(
3245 api::OnDeterminingFilename::kEventName,
3246 base::StringPrintf("[{\"id\": %d,"
3247 " \"incognito\": false,"
3248 " \"filename\":\"slow.txt\"}]",
3250 ASSERT_TRUE(item->GetTargetFilePath().empty());
3251 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3253 // Respond to the onDeterminingFilename events.
3255 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3256 current_browser()->profile(),
3260 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3261 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3263 EXPECT_EQ("", error);
3265 // The download should complete successfully.
3266 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3267 base::StringPrintf("[{\"id\": %d,"
3269 " \"previous\": \"\","
3270 " \"current\": \"%s\"}}]",
3272 GetFilename("42.txt").c_str())));
3273 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3274 base::StringPrintf("[{\"id\": %d,"
3276 " \"previous\": \"in_progress\","
3277 " \"current\": \"complete\"}}]",
3280 // Start an incognito download for comparison.
3282 result.reset(RunFunctionAndReturnResult(
3283 new DownloadsDownloadFunction(), base::StringPrintf(
3284 "[{\"url\": \"%s\"}]", download_url.c_str())));
3285 ASSERT_TRUE(result.get());
3287 ASSERT_TRUE(result->GetAsInteger(&result_id));
3288 item = GetCurrentManager()->GetDownload(result_id);
3290 ScopedCancellingItem canceller2(item);
3291 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3293 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
3294 base::StringPrintf("[{\"danger\": \"safe\","
3295 " \"incognito\": true,"
3297 " \"mime\": \"text/plain\","
3298 " \"paused\": false,"
3299 " \"url\": \"%s\"}]",
3301 download_url.c_str())));
3302 ASSERT_TRUE(WaitFor(
3303 api::OnDeterminingFilename::kEventName,
3304 base::StringPrintf("[{\"id\": %d,"
3305 " \"incognito\": true,"
3306 " \"filename\":\"slow.txt\"}]",
3308 ASSERT_TRUE(item->GetTargetFilePath().empty());
3309 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3311 // Respond to the onDeterminingFilename.
3313 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3314 current_browser()->profile(),
3318 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3319 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3321 EXPECT_EQ("", error);
3323 // The download should complete successfully.
3324 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3325 base::StringPrintf("[{\"id\": %d,"
3327 " \"previous\": \"\","
3328 " \"current\": \"%s\"}}]",
3330 GetFilename("42 (1).txt").c_str())));
3331 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3332 base::StringPrintf("[{\"id\": %d,"
3334 " \"previous\": \"in_progress\","
3335 " \"current\": \"complete\"}}]",
3340 // This test is very flaky on Win XP and Aura. http://crbug.com/248438
3341 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3342 DISABLED_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3344 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3345 DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3348 // Test download interruption while extensions determining filename. Should not
3349 // re-dispatch onDeterminingFilename.
3350 IN_PROC_BROWSER_TEST_F(
3351 DownloadExtensionTest,
3352 MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume) {
3353 CommandLine::ForCurrentProcess()->AppendSwitch(
3354 switches::kEnableDownloadResumption);
3355 LoadExtension("downloads_split");
3356 ASSERT_TRUE(StartEmbeddedTestServer());
3357 ASSERT_TRUE(test_server()->Start());
3359 content::RenderProcessHost* host = AddFilenameDeterminer();
3361 // Start a download.
3362 DownloadItem* item = NULL;
3364 DownloadManager* manager = GetCurrentManager();
3365 scoped_ptr<content::DownloadTestObserver> observer(
3366 new JustInProgressDownloadObserver(manager, 1));
3367 ASSERT_EQ(0, manager->InProgressCount());
3368 ASSERT_EQ(0, manager->NonMaliciousInProgressCount());
3369 // Tabs created just for a download are automatically closed, invalidating
3370 // the download's WebContents. Downloads without WebContents cannot be
3371 // resumed. http://crbug.com/225901
3372 ui_test_utils::NavigateToURLWithDisposition(
3374 GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl),
3376 ui_test_utils::BROWSER_TEST_NONE);
3377 observer->WaitForFinished();
3378 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
3379 DownloadManager::DownloadVector items;
3380 manager->GetAllDownloads(&items);
3381 for (DownloadManager::DownloadVector::iterator iter = items.begin();
3382 iter != items.end(); ++iter) {
3383 if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) {
3384 // There should be only one IN_PROGRESS item.
3385 EXPECT_EQ(NULL, item);
3391 ScopedCancellingItem canceller(item);
3393 // Wait for the onCreated and onDeterminingFilename event.
3394 ASSERT_TRUE(WaitFor(api::OnCreated::kEventName,
3395 base::StringPrintf("[{\"danger\": \"safe\","
3396 " \"incognito\": false,"
3398 " \"mime\": \"application/octet-stream\","
3399 " \"paused\": false}]",
3401 ASSERT_TRUE(WaitFor(
3402 api::OnDeterminingFilename::kEventName,
3403 base::StringPrintf("[{\"id\": %d,"
3404 " \"incognito\": false,"
3405 " \"filename\":\"download-unknown-size\"}]",
3407 ASSERT_TRUE(item->GetTargetFilePath().empty());
3408 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3411 ui_test_utils::NavigateToURLWithDisposition(
3413 GURL(URLRequestSlowDownloadJob::kErrorDownloadUrl),
3415 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3417 // Errors caught before filename determination are delayed until after
3418 // filename determination.
3420 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3421 current_browser()->profile(),
3425 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3426 api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3428 EXPECT_EQ("", error);
3429 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3430 base::StringPrintf("[{\"id\": %d,"
3432 " \"previous\": \"\","
3433 " \"current\": \"%s\"}}]",
3435 GetFilename("42.txt").c_str())));
3437 content::DownloadUpdatedObserver interrupted(item, base::Bind(
3438 ItemIsInterrupted));
3439 ASSERT_TRUE(interrupted.WaitForEvent());
3440 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3441 base::StringPrintf("[{\"id\": %d,"
3442 " \"error\":{\"current\":\"NETWORK_FAILED\"},"
3444 " \"previous\":\"in_progress\","
3445 " \"current\":\"interrupted\"}}]",
3449 // Downloads that are restarted on resumption trigger another download target
3451 RemoveFilenameDeterminer(host);
3454 // Errors caught before filename determination is complete are delayed until
3455 // after filename determination so that, on resumption, filename determination
3456 // does not need to be re-done. So, there will not be a second
3457 // onDeterminingFilename event.
3459 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3460 base::StringPrintf("[{\"id\": %d,"
3461 " \"error\":{\"previous\":\"NETWORK_FAILED\"},"
3463 " \"previous\":\"interrupted\","
3464 " \"current\":\"in_progress\"}}]",
3468 FinishPendingSlowDownloads();
3470 // The download should complete successfully.
3471 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName,
3472 base::StringPrintf("[{\"id\": %d,"
3474 " \"previous\": \"in_progress\","
3475 " \"current\": \"complete\"}}]",
3479 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
3480 DownloadExtensionTest_SetShelfEnabled) {
3481 LoadExtension("downloads_split");
3482 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[false]"));
3483 EXPECT_FALSE(DownloadServiceFactory::GetForBrowserContext(
3484 browser()->profile())->IsShelfEnabled());
3485 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[true]"));
3486 EXPECT_TRUE(DownloadServiceFactory::GetForBrowserContext(
3487 browser()->profile())->IsShelfEnabled());
3488 // TODO(benjhayden) Test that existing shelves are hidden.
3489 // TODO(benjhayden) Test multiple extensions.
3490 // TODO(benjhayden) Test disabling extensions.
3491 // TODO(benjhayden) Test that browsers associated with other profiles are not
3493 // TODO(benjhayden) Test incognito.
3496 // TODO(benjhayden) Figure out why DisableExtension() does not fire
3497 // OnListenerRemoved.
3499 // TODO(benjhayden) Test that the shelf is shown for download() both with and
3500 // without a WebContents.
3502 void OnDangerPromptCreated(DownloadDangerPrompt* prompt) {
3503 prompt->InvokeActionForTesting(DownloadDangerPrompt::ACCEPT);
3506 #if defined(OS_MACOSX)
3507 // Flakily triggers and assert on Mac.
3508 // http://crbug.com/180759
3509 #define MAYBE_DownloadExtensionTest_AcceptDanger DownloadExtensionTest_AcceptDanger
3511 #define MAYBE_DownloadExtensionTest_AcceptDanger DISABLED_DownloadExtensionTest_AcceptDanger
3513 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
3514 MAYBE_DownloadExtensionTest_AcceptDanger) {
3515 // Download a file that will be marked dangerous; click the browser action
3516 // button; the browser action poup will call acceptDanger(); when the
3517 // DownloadDangerPrompt is created, pretend that the user clicks the Accept
3518 // button; wait until the download completes.
3519 LoadExtension("downloads_split");
3520 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3521 new DownloadsDownloadFunction(),
3522 "[{\"url\": \"data:,\", \"filename\": \"dangerous.swf\"}]"));
3523 ASSERT_TRUE(result.get());
3525 ASSERT_TRUE(result->GetAsInteger(&result_id));
3526 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3528 ASSERT_TRUE(WaitFor(api::OnChanged::kEventName, base::StringPrintf(
3531 " \"previous\": \"safe\","
3532 " \"current\": \"file\"}}]",
3534 ASSERT_TRUE(item->IsDangerous());
3535 ScopedCancellingItem canceller(item);
3536 scoped_ptr<content::DownloadTestObserver> observer(
3537 new content::DownloadTestObserverTerminal(
3538 GetCurrentManager(), 1,
3539 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_IGNORE));
3540 DownloadsAcceptDangerFunction::OnPromptCreatedCallback callback =
3541 base::Bind(&OnDangerPromptCreated);
3542 DownloadsAcceptDangerFunction::OnPromptCreatedForTesting(
3544 BrowserActionTestUtil(browser()).Press(0);
3545 observer->WaitForFinished();
3548 class DownloadsApiTest : public ExtensionApiTest {
3550 DownloadsApiTest() {}
3551 virtual ~DownloadsApiTest() {}
3553 DISALLOW_COPY_AND_ASSIGN(DownloadsApiTest);
3557 IN_PROC_BROWSER_TEST_F(DownloadsApiTest, DownloadsApiTest) {
3558 ASSERT_TRUE(RunExtensionTest("downloads")) << message_;
3561 TEST(DownloadInterruptReasonEnumsSynced,
3562 DownloadInterruptReasonEnumsSynced) {
3563 #define INTERRUPT_REASON(name, value) \
3564 EXPECT_EQ(InterruptReasonContentToExtension( \
3565 content::DOWNLOAD_INTERRUPT_REASON_##name), \
3566 api::INTERRUPT_REASON_##name); \
3567 EXPECT_EQ(InterruptReasonExtensionToContent( \
3568 api::INTERRUPT_REASON_##name), \
3569 content::DOWNLOAD_INTERRUPT_REASON_##name);
3570 #include "content/public/browser/download_interrupt_reason_values.h"
3571 #undef INTERRUPT_REASON
3574 TEST(ExtensionDetermineDownloadFilenameInternal,
3575 ExtensionDetermineDownloadFilenameInternal) {
3577 std::string winner_id;
3578 base::FilePath filename;
3579 extensions::api::downloads::FilenameConflictAction conflict_action =
3580 api::FILENAME_CONFLICT_ACTION_UNIQUIFY;
3581 extensions::ExtensionWarningSet warnings;
3583 // Empty incumbent determiner
3585 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
3586 base::FilePath(FILE_PATH_LITERAL("a")),
3587 api::FILENAME_CONFLICT_ACTION_OVERWRITE,
3596 EXPECT_EQ("suggester", winner_id);
3597 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename.value());
3598 EXPECT_EQ(api::FILENAME_CONFLICT_ACTION_OVERWRITE, conflict_action);
3599 EXPECT_TRUE(warnings.empty());
3603 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
3604 base::FilePath(FILE_PATH_LITERAL("b")),
3605 api::FILENAME_CONFLICT_ACTION_PROMPT,
3607 base::Time::Now() - base::TimeDelta::FromDays(1),
3614 EXPECT_EQ("incumbent", winner_id);
3615 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename.value());
3616 EXPECT_EQ(api::FILENAME_CONFLICT_ACTION_OVERWRITE, conflict_action);
3617 EXPECT_FALSE(warnings.empty());
3618 EXPECT_EQ(extensions::ExtensionWarning::kDownloadFilenameConflict,
3619 warnings.begin()->warning_type());
3620 EXPECT_EQ("suggester", warnings.begin()->extension_id());
3624 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
3625 base::FilePath(FILE_PATH_LITERAL("b")),
3626 api::FILENAME_CONFLICT_ACTION_PROMPT,
3630 base::Time::Now() - base::TimeDelta::FromDays(1),
3635 EXPECT_EQ("suggester", winner_id);
3636 EXPECT_EQ(FILE_PATH_LITERAL("b"), filename.value());
3637 EXPECT_EQ(api::FILENAME_CONFLICT_ACTION_PROMPT, conflict_action);
3638 EXPECT_FALSE(warnings.empty());
3639 EXPECT_EQ(extensions::ExtensionWarning::kDownloadFilenameConflict,
3640 warnings.begin()->warning_type());
3641 EXPECT_EQ("incumbent", warnings.begin()->extension_id());
3644 #endif // http://crbug.com/3061144