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/files/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/download/download_file_icon_extractor.h"
19 #include "chrome/browser/download/download_service.h"
20 #include "chrome/browser/download/download_service_factory.h"
21 #include "chrome/browser/download/download_test_file_activity_observer.h"
22 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
23 #include "chrome/browser/extensions/browser_action_test_util.h"
24 #include "chrome/browser/extensions/extension_apitest.h"
25 #include "chrome/browser/extensions/extension_function_test_utils.h"
26 #include "chrome/browser/history/download_row.h"
27 #include "chrome/browser/net/url_request_mock_util.h"
28 #include "chrome/browser/profiles/profile.h"
29 #include "chrome/browser/ui/browser.h"
30 #include "chrome/browser/ui/browser_tabstrip.h"
31 #include "chrome/common/pref_names.h"
32 #include "chrome/test/base/in_process_browser_test.h"
33 #include "chrome/test/base/ui_test_utils.h"
34 #include "content/public/browser/browser_context.h"
35 #include "content/public/browser/browser_thread.h"
36 #include "content/public/browser/download_item.h"
37 #include "content/public/browser/download_manager.h"
38 #include "content/public/browser/notification_service.h"
39 #include "content/public/browser/storage_partition.h"
40 #include "content/public/browser/web_contents.h"
41 #include "content/public/common/content_switches.h"
42 #include "content/public/test/download_test_observer.h"
43 #include "content/test/net/url_request_slow_download_job.h"
44 #include "extensions/browser/event_router.h"
45 #include "extensions/browser/notification_types.h"
46 #include "net/base/data_url.h"
47 #include "net/base/net_util.h"
48 #include "net/url_request/url_request.h"
49 #include "net/url_request/url_request_context.h"
50 #include "net/url_request/url_request_job.h"
51 #include "net/url_request/url_request_job_factory.h"
52 #include "net/url_request/url_request_job_factory_impl.h"
53 #include "storage/browser/fileapi/file_system_context.h"
54 #include "storage/browser/fileapi/file_system_operation_runner.h"
55 #include "storage/browser/fileapi/file_system_url.h"
56 #include "ui/base/page_transition_types.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 extensions {
67 namespace downloads = api::downloads;
71 // Comparator that orders download items by their ID. Can be used with
73 struct DownloadIdComparator {
74 bool operator() (DownloadItem* first, DownloadItem* second) {
75 return first->GetId() < second->GetId();
79 class DownloadsEventsListener : public content::NotificationObserver {
81 DownloadsEventsListener()
84 extensions::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
85 content::NotificationService::AllSources());
88 ~DownloadsEventsListener() override {
89 registrar_.Remove(this,
90 extensions::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
91 content::NotificationService::AllSources());
92 STLDeleteElements(&events_);
96 STLDeleteElements(&events_);
102 Event(Profile* profile,
103 const std::string& event_name,
104 const std::string& json_args,
107 event_name_(event_name),
108 json_args_(json_args),
109 args_(base::JSONReader::Read(json_args)),
113 const base::Time& caught() { return caught_; }
115 bool Satisfies(const Event& other) const {
116 return other.SatisfiedBy(*this);
119 bool SatisfiedBy(const Event& other) const {
120 if ((profile_ != other.profile_) ||
121 (event_name_ != other.event_name_))
123 if (((event_name_ == downloads::OnDeterminingFilename::kEventName) ||
124 (event_name_ == downloads::OnCreated::kEventName) ||
125 (event_name_ == downloads::OnChanged::kEventName)) &&
126 args_.get() && other.args_.get()) {
127 base::ListValue* left_list = NULL;
128 base::DictionaryValue* left_dict = NULL;
129 base::ListValue* right_list = NULL;
130 base::DictionaryValue* right_dict = NULL;
131 if (!args_->GetAsList(&left_list) ||
132 !other.args_->GetAsList(&right_list) ||
133 !left_list->GetDictionary(0, &left_dict) ||
134 !right_list->GetDictionary(0, &right_dict))
136 for (base::DictionaryValue::Iterator iter(*left_dict);
137 !iter.IsAtEnd(); iter.Advance()) {
138 base::Value* right_value = NULL;
139 if (!right_dict->HasKey(iter.key()) ||
140 (right_dict->Get(iter.key(), &right_value) &&
141 !iter.value().Equals(right_value))) {
146 } else if ((event_name_ == downloads::OnErased::kEventName) &&
147 args_.get() && other.args_.get()) {
148 int my_id = -1, other_id = -1;
149 return (args_->GetAsInteger(&my_id) &&
150 other.args_->GetAsInteger(&other_id) &&
153 return json_args_ == other.json_args_;
156 std::string Debug() {
157 return base::StringPrintf("Event(%p, %s, %s, %f)",
166 std::string event_name_;
167 std::string json_args_;
168 scoped_ptr<base::Value> args_;
171 DISALLOW_COPY_AND_ASSIGN(Event);
174 typedef ExtensionDownloadsEventRouter::DownloadsNotificationSource
175 DownloadsNotificationSource;
177 void Observe(int type,
178 const content::NotificationSource& source,
179 const content::NotificationDetails& details) override {
181 case extensions::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 ui::PAGE_TRANSITION_LINK);
279 EventRouter::Get(current_browser()->profile())
280 ->AddEventListener(downloads::OnCreated::kEventName,
281 tab->GetRenderProcessHost(),
283 EventRouter::Get(current_browser()->profile())
284 ->AddEventListener(downloads::OnChanged::kEventName,
285 tab->GetRenderProcessHost(),
287 EventRouter::Get(current_browser()->profile())
288 ->AddEventListener(downloads::OnErased::kEventName,
289 tab->GetRenderProcessHost(),
293 content::RenderProcessHost* AddFilenameDeterminer() {
294 ExtensionDownloadsEventRouter::SetDetermineFilenameTimeoutSecondsForTesting(
296 content::WebContents* tab = chrome::AddSelectedTabWithURL(
298 extension_->GetResourceURL("empty.html"),
299 ui::PAGE_TRANSITION_LINK);
300 EventRouter::Get(current_browser()->profile())
301 ->AddEventListener(downloads::OnDeterminingFilename::kEventName,
302 tab->GetRenderProcessHost(),
304 return tab->GetRenderProcessHost();
307 void RemoveFilenameDeterminer(content::RenderProcessHost* host) {
308 EventRouter::Get(current_browser()->profile())->RemoveEventListener(
309 downloads::OnDeterminingFilename::kEventName, host, GetExtensionId());
312 Browser* current_browser() { return current_browser_; }
314 // InProcessBrowserTest
315 void SetUpOnMainThread() override {
316 ExtensionApiTest::SetUpOnMainThread();
317 BrowserThread::PostTask(
318 BrowserThread::IO, FROM_HERE,
319 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
320 InProcessBrowserTest::SetUpOnMainThread();
322 CreateAndSetDownloadsDirectory();
323 current_browser()->profile()->GetPrefs()->SetBoolean(
324 prefs::kPromptForDownload, false);
325 GetOnRecordManager()->RemoveAllDownloads();
326 events_listener_.reset(new DownloadsEventsListener());
327 // Disable file chooser for current profile.
328 DownloadTestFileActivityObserver observer(current_browser()->profile());
329 observer.EnableFileChooser(false);
332 void GoOnTheRecord() { current_browser_ = browser(); }
334 void GoOffTheRecord() {
335 if (!incognito_browser_) {
336 incognito_browser_ = CreateIncognitoBrowser();
337 GetOffRecordManager()->RemoveAllDownloads();
338 // Disable file chooser for incognito profile.
339 DownloadTestFileActivityObserver observer(incognito_browser_->profile());
340 observer.EnableFileChooser(false);
342 current_browser_ = incognito_browser_;
345 bool WaitFor(const std::string& event_name, const std::string& json_args) {
346 return events_listener_->WaitFor(
347 current_browser()->profile(), event_name, json_args);
350 bool WaitForInterruption(
352 content::DownloadInterruptReason expected_error,
353 const std::string& on_created_event) {
354 if (!WaitFor(downloads::OnCreated::kEventName, on_created_event))
356 // Now, onCreated is always fired before interruption.
358 downloads::OnChanged::kEventName,
361 " \"error\": {\"current\": \"%s\"},"
363 " \"previous\": \"in_progress\","
364 " \"current\": \"interrupted\"}}]",
366 content::DownloadInterruptReasonToString(expected_error).c_str()));
370 events_listener_->ClearEvents();
373 std::string GetExtensionURL() {
374 return extension_->url().spec();
376 std::string GetExtensionId() {
377 return extension_->id();
380 std::string GetFilename(const char* path) {
382 downloads_directory_.path().AppendASCII(path).AsUTF8Unsafe();
384 for (std::string::size_type next = result.find("\\");
385 next != std::string::npos;
386 next = result.find("\\", next)) {
387 result.replace(next, 1, "\\\\");
394 DownloadManager* GetOnRecordManager() {
395 return BrowserContext::GetDownloadManager(browser()->profile());
397 DownloadManager* GetOffRecordManager() {
398 return BrowserContext::GetDownloadManager(
399 browser()->profile()->GetOffTheRecordProfile());
401 DownloadManager* GetCurrentManager() {
402 return (current_browser_ == incognito_browser_) ?
403 GetOffRecordManager() : GetOnRecordManager();
406 // Creates a set of history downloads based on the provided |history_info|
407 // array. |count| is the number of elements in |history_info|. On success,
408 // |items| will contain |count| DownloadItems in the order that they were
409 // specified in |history_info|. Returns true on success and false otherwise.
410 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info,
412 DownloadManager::DownloadVector* items) {
413 DownloadIdComparator download_id_comparator;
414 base::Time current = base::Time::Now();
416 GetOnRecordManager()->GetAllDownloads(items);
417 CHECK_EQ(0, static_cast<int>(items->size()));
418 std::vector<GURL> url_chain;
419 url_chain.push_back(GURL());
420 for (size_t i = 0; i < count; ++i) {
421 DownloadItem* item = GetOnRecordManager()->CreateDownloadItem(
422 content::DownloadItem::kInvalidId + 1 + i,
423 downloads_directory().Append(history_info[i].filename),
424 downloads_directory().Append(history_info[i].filename),
425 url_chain, GURL(), // URL Chain, referrer
426 std::string(), std::string(), // mime_type, original_mime_type
427 current, current, // start_time, end_time
428 std::string(), std::string(), // etag, last_modified
429 1, 1, // received_bytes, total_bytes
430 history_info[i].state, // state
431 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
432 content::DOWNLOAD_INTERRUPT_REASON_NONE,
434 items->push_back(item);
437 // Order by ID so that they are in the order that we created them.
438 std::sort(items->begin(), items->end(), download_id_comparator);
439 // Set the danger type if necessary.
440 for (size_t i = 0; i < count; ++i) {
441 if (history_info[i].danger_type !=
442 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
443 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT,
444 history_info[i].danger_type);
445 items->at(i)->OnContentCheckCompleted(history_info[i].danger_type);
451 void CreateSlowTestDownloads(
452 size_t count, DownloadManager::DownloadVector* items) {
453 for (size_t i = 0; i < count; ++i) {
454 scoped_ptr<content::DownloadTestObserver> observer(
455 CreateInProgressDownloadObserver(1));
456 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
457 ui_test_utils::NavigateToURLWithDisposition(
458 current_browser(), slow_download_url, CURRENT_TAB,
459 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
460 observer->WaitForFinished();
462 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
464 GetCurrentManager()->GetAllDownloads(items);
465 ASSERT_EQ(count, items->size());
468 DownloadItem* CreateSlowTestDownload() {
469 scoped_ptr<content::DownloadTestObserver> observer(
470 CreateInProgressDownloadObserver(1));
471 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
472 DownloadManager* manager = GetCurrentManager();
474 EXPECT_EQ(0, manager->NonMaliciousInProgressCount());
475 EXPECT_EQ(0, manager->InProgressCount());
476 if (manager->InProgressCount() != 0)
479 ui_test_utils::NavigateToURLWithDisposition(
480 current_browser(), slow_download_url, CURRENT_TAB,
481 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
483 observer->WaitForFinished();
484 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
486 DownloadManager::DownloadVector items;
487 manager->GetAllDownloads(&items);
489 DownloadItem* new_item = NULL;
490 for (DownloadManager::DownloadVector::iterator iter = items.begin();
491 iter != items.end(); ++iter) {
492 if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) {
493 // There should be only one IN_PROGRESS item.
494 EXPECT_EQ(NULL, new_item);
501 void FinishPendingSlowDownloads() {
502 scoped_ptr<content::DownloadTestObserver> observer(
503 CreateDownloadObserver(1));
504 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl);
505 ui_test_utils::NavigateToURLWithDisposition(
506 current_browser(), finish_url, NEW_FOREGROUND_TAB,
507 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
508 observer->WaitForFinished();
509 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
512 content::DownloadTestObserver* CreateDownloadObserver(size_t download_count) {
513 return new content::DownloadTestObserverTerminal(
514 GetCurrentManager(), download_count,
515 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
518 content::DownloadTestObserver* CreateInProgressDownloadObserver(
519 size_t download_count) {
520 return new content::DownloadTestObserverInProgress(
521 GetCurrentManager(), download_count);
524 bool RunFunction(UIThreadExtensionFunction* function,
525 const std::string& args) {
526 scoped_refptr<UIThreadExtensionFunction> delete_function(function);
527 SetUpExtensionFunction(function);
528 bool result = extension_function_test_utils::RunFunction(
529 function, args, browser(), GetFlags());
531 LOG(ERROR) << function->GetError();
536 extension_function_test_utils::RunFunctionFlags GetFlags() {
537 return current_browser()->profile()->IsOffTheRecord() ?
538 extension_function_test_utils::INCLUDE_INCOGNITO :
539 extension_function_test_utils::NONE;
542 // extension_function_test_utils::RunFunction*() only uses browser for its
543 // profile(), so pass it the on-record browser so that it always uses the
544 // on-record profile to match real-life behavior.
546 base::Value* RunFunctionAndReturnResult(
547 scoped_refptr<UIThreadExtensionFunction> function,
548 const std::string& args) {
549 SetUpExtensionFunction(function.get());
550 return extension_function_test_utils::RunFunctionAndReturnSingleResult(
551 function.get(), args, browser(), GetFlags());
554 std::string RunFunctionAndReturnError(
555 scoped_refptr<UIThreadExtensionFunction> function,
556 const std::string& args) {
557 SetUpExtensionFunction(function.get());
558 return extension_function_test_utils::RunFunctionAndReturnError(
559 function.get(), args, browser(), GetFlags());
562 bool RunFunctionAndReturnString(
563 scoped_refptr<UIThreadExtensionFunction> function,
564 const std::string& args,
565 std::string* result_string) {
566 SetUpExtensionFunction(function.get());
567 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args));
568 EXPECT_TRUE(result.get());
569 return result.get() && result->GetAsString(result_string);
572 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) {
573 return base::StringPrintf("[%d]", download_item->GetId());
576 const base::FilePath& downloads_directory() {
577 return downloads_directory_.path();
580 DownloadsEventsListener* events_listener() { return events_listener_.get(); }
583 void SetUpExtensionFunction(UIThreadExtensionFunction* function) {
585 // Recreate the tab each time for insulation.
586 content::WebContents* tab = chrome::AddSelectedTabWithURL(
588 extension_->GetResourceURL("empty.html"),
589 ui::PAGE_TRANSITION_LINK);
590 function->set_extension(extension_);
591 function->SetRenderViewHost(tab->GetRenderViewHost());
595 void CreateAndSetDownloadsDirectory() {
596 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
597 current_browser()->profile()->GetPrefs()->SetFilePath(
598 prefs::kDownloadDefaultDirectory,
599 downloads_directory_.path());
602 base::ScopedTempDir downloads_directory_;
603 const Extension* extension_;
604 Browser* incognito_browser_;
605 Browser* current_browser_;
606 scoped_ptr<DownloadsEventsListener> events_listener_;
608 DISALLOW_COPY_AND_ASSIGN(DownloadExtensionTest);
611 class MockIconExtractorImpl : public DownloadFileIconExtractor {
613 MockIconExtractorImpl(const base::FilePath& path,
614 IconLoader::IconSize icon_size,
615 const std::string& response)
616 : expected_path_(path),
617 expected_icon_size_(icon_size),
618 response_(response) {
620 ~MockIconExtractorImpl() override {}
622 bool ExtractIconURLForPath(const base::FilePath& path,
624 IconLoader::IconSize icon_size,
625 IconURLCallback callback) override {
626 EXPECT_STREQ(expected_path_.value().c_str(), path.value().c_str());
627 EXPECT_EQ(expected_icon_size_, icon_size);
628 if (expected_path_ == path &&
629 expected_icon_size_ == icon_size) {
630 callback_ = callback;
631 BrowserThread::PostTask(
632 BrowserThread::UI, FROM_HERE,
633 base::Bind(&MockIconExtractorImpl::RunCallback,
634 base::Unretained(this)));
643 callback_.Run(response_);
644 // Drop the reference on extension function to avoid memory leaks.
645 callback_ = IconURLCallback();
648 base::FilePath expected_path_;
649 IconLoader::IconSize expected_icon_size_;
650 std::string response_;
651 IconURLCallback callback_;
654 bool ItemNotInProgress(DownloadItem* item) {
655 return item->GetState() != DownloadItem::IN_PROGRESS;
658 // Cancels the underlying DownloadItem when the ScopedCancellingItem goes out of
659 // scope. Like a scoped_ptr, but for DownloadItems.
660 class ScopedCancellingItem {
662 explicit ScopedCancellingItem(DownloadItem* item) : item_(item) {}
663 ~ScopedCancellingItem() {
665 content::DownloadUpdatedObserver observer(
666 item_, base::Bind(&ItemNotInProgress));
667 observer.WaitForEvent();
669 DownloadItem* get() { return item_; }
672 DISALLOW_COPY_AND_ASSIGN(ScopedCancellingItem);
675 // Cancels all the underlying DownloadItems when the ScopedItemVectorCanceller
676 // goes out of scope. Generalization of ScopedCancellingItem to many
678 class ScopedItemVectorCanceller {
680 explicit ScopedItemVectorCanceller(DownloadManager::DownloadVector* items)
683 ~ScopedItemVectorCanceller() {
684 for (DownloadManager::DownloadVector::const_iterator item = items_->begin();
685 item != items_->end(); ++item) {
686 if ((*item)->GetState() == DownloadItem::IN_PROGRESS)
687 (*item)->Cancel(true);
688 content::DownloadUpdatedObserver observer(
689 (*item), base::Bind(&ItemNotInProgress));
690 observer.WaitForEvent();
695 DownloadManager::DownloadVector* items_;
696 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller);
699 // Writes an HTML5 file so that it can be downloaded.
700 class HTML5FileWriter {
702 static bool CreateFileForTesting(storage::FileSystemContext* context,
703 const storage::FileSystemURL& path,
706 // Create a temp file.
707 base::FilePath temp_file;
708 if (!base::CreateTemporaryFile(&temp_file) ||
709 base::WriteFile(temp_file, data, length) != length) {
712 // Invoke the fileapi to copy it into the sandboxed filesystem.
714 base::WaitableEvent done_event(true, false);
715 BrowserThread::PostTask(
716 BrowserThread::IO, FROM_HERE,
717 base::Bind(&CreateFileForTestingOnIOThread,
718 base::Unretained(context),
720 base::Unretained(&result),
721 base::Unretained(&done_event)));
722 // Wait for that to finish.
724 base::DeleteFile(temp_file, false);
729 static void CopyInCompletion(bool* result,
730 base::WaitableEvent* done_event,
731 base::File::Error error) {
732 DCHECK_CURRENTLY_ON(BrowserThread::IO);
733 *result = error == base::File::FILE_OK;
734 done_event->Signal();
737 static void CreateFileForTestingOnIOThread(
738 storage::FileSystemContext* context,
739 const storage::FileSystemURL& path,
740 const base::FilePath& temp_file,
742 base::WaitableEvent* done_event) {
743 DCHECK_CURRENTLY_ON(BrowserThread::IO);
744 context->operation_runner()->CopyInForeignFile(
746 base::Bind(&CopyInCompletion,
747 base::Unretained(result),
748 base::Unretained(done_event)));
752 // TODO(benjhayden) Merge this with the other TestObservers.
753 class JustInProgressDownloadObserver
754 : public content::DownloadTestObserverInProgress {
756 JustInProgressDownloadObserver(
757 DownloadManager* download_manager, size_t wait_count)
758 : content::DownloadTestObserverInProgress(download_manager, wait_count) {
761 ~JustInProgressDownloadObserver() override {}
764 bool IsDownloadInFinalState(DownloadItem* item) override {
765 return item->GetState() == DownloadItem::IN_PROGRESS;
768 DISALLOW_COPY_AND_ASSIGN(JustInProgressDownloadObserver);
771 bool ItemIsInterrupted(DownloadItem* item) {
772 return item->GetState() == DownloadItem::INTERRUPTED;
775 content::DownloadInterruptReason InterruptReasonExtensionToContent(
776 downloads::InterruptReason error) {
778 case downloads::INTERRUPT_REASON_NONE:
779 return content::DOWNLOAD_INTERRUPT_REASON_NONE;
780 #define INTERRUPT_REASON(name, value) \
781 case downloads::INTERRUPT_REASON_##name: \
782 return content::DOWNLOAD_INTERRUPT_REASON_##name;
783 #include "content/public/browser/download_interrupt_reason_values.h"
784 #undef INTERRUPT_REASON
787 return content::DOWNLOAD_INTERRUPT_REASON_NONE;
790 downloads::InterruptReason InterruptReasonContentToExtension(
791 content::DownloadInterruptReason error) {
793 case content::DOWNLOAD_INTERRUPT_REASON_NONE:
794 return downloads::INTERRUPT_REASON_NONE;
795 #define INTERRUPT_REASON(name, value) \
796 case content::DOWNLOAD_INTERRUPT_REASON_##name: \
797 return downloads::INTERRUPT_REASON_##name;
798 #include "content/public/browser/download_interrupt_reason_values.h"
799 #undef INTERRUPT_REASON
802 return downloads::INTERRUPT_REASON_NONE;
807 #if defined(OS_CHROMEOS)
808 // http://crbug.com/396510
809 #define MAYBE_DownloadExtensionTest_Open DISABLED_DownloadExtensionTest_Open
811 #define MAYBE_DownloadExtensionTest_Open DownloadExtensionTest_Open
813 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
814 MAYBE_DownloadExtensionTest_Open) {
815 LoadExtension("downloads_split");
816 DownloadsOpenFunction* open_function = new DownloadsOpenFunction();
817 open_function->set_user_gesture(true);
818 EXPECT_STREQ(errors::kInvalidId,
819 RunFunctionAndReturnError(
823 DownloadItem* download_item = CreateSlowTestDownload();
824 ASSERT_TRUE(download_item);
825 EXPECT_FALSE(download_item->GetOpened());
826 EXPECT_FALSE(download_item->GetOpenWhenComplete());
827 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
829 "[{\"danger\": \"safe\","
830 " \"incognito\": false,"
831 " \"mime\": \"application/octet-stream\","
832 " \"paused\": false,"
833 " \"url\": \"%s\"}]",
834 download_item->GetURL().spec().c_str())));
835 open_function = new DownloadsOpenFunction();
836 open_function->set_user_gesture(true);
837 EXPECT_STREQ(errors::kNotComplete,
838 RunFunctionAndReturnError(
840 DownloadItemIdAsArgList(download_item)).c_str());
842 FinishPendingSlowDownloads();
843 EXPECT_FALSE(download_item->GetOpened());
845 open_function = new DownloadsOpenFunction();
846 EXPECT_STREQ(errors::kUserGesture,
847 RunFunctionAndReturnError(
849 DownloadItemIdAsArgList(download_item)).c_str());
850 EXPECT_FALSE(download_item->GetOpened());
852 open_function = new DownloadsOpenFunction();
853 open_function->set_user_gesture(true);
854 EXPECT_TRUE(RunFunction(open_function,
855 DownloadItemIdAsArgList(download_item)));
856 EXPECT_TRUE(download_item->GetOpened());
859 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
860 DownloadExtensionTest_PauseResumeCancelErase) {
861 DownloadItem* download_item = CreateSlowTestDownload();
862 ASSERT_TRUE(download_item);
865 // Call pause(). It should succeed and the download should be paused on
867 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
868 DownloadItemIdAsArgList(download_item)));
869 EXPECT_TRUE(download_item->IsPaused());
871 // Calling removeFile on a non-active download yields kNotComplete
872 // and should not crash. http://crbug.com/319984
873 error = RunFunctionAndReturnError(new DownloadsRemoveFileFunction(),
874 DownloadItemIdAsArgList(download_item));
875 EXPECT_STREQ(errors::kNotComplete, error.c_str());
877 // Calling pause() twice shouldn't be an error.
878 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
879 DownloadItemIdAsArgList(download_item)));
880 EXPECT_TRUE(download_item->IsPaused());
882 // Now try resuming this download. It should succeed.
883 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
884 DownloadItemIdAsArgList(download_item)));
885 EXPECT_FALSE(download_item->IsPaused());
887 // Resume again. Resuming a download that wasn't paused is not an error.
888 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
889 DownloadItemIdAsArgList(download_item)));
890 EXPECT_FALSE(download_item->IsPaused());
893 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
894 DownloadItemIdAsArgList(download_item)));
895 EXPECT_TRUE(download_item->IsPaused());
898 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
899 DownloadItemIdAsArgList(download_item)));
900 EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());
902 // Cancel again. Shouldn't have any effect.
903 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
904 DownloadItemIdAsArgList(download_item)));
905 EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());
907 // Calling paused on a non-active download yields kNotInProgress.
908 error = RunFunctionAndReturnError(
909 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item));
910 EXPECT_STREQ(errors::kNotInProgress, error.c_str());
912 // Calling resume on a non-active download yields kNotResumable
913 error = RunFunctionAndReturnError(
914 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item));
915 EXPECT_STREQ(errors::kNotResumable, error.c_str());
917 // Calling pause on a non-existent download yields kInvalidId.
918 error = RunFunctionAndReturnError(
919 new DownloadsPauseFunction(), "[-42]");
920 EXPECT_STREQ(errors::kInvalidId, error.c_str());
922 // Calling resume on a non-existent download yields kInvalidId
923 error = RunFunctionAndReturnError(
924 new DownloadsResumeFunction(), "[-42]");
925 EXPECT_STREQ(errors::kInvalidId, error.c_str());
927 // Calling removeFile on a non-existent download yields kInvalidId.
928 error = RunFunctionAndReturnError(
929 new DownloadsRemoveFileFunction(), "[-42]");
930 EXPECT_STREQ(errors::kInvalidId, error.c_str());
932 int id = download_item->GetId();
933 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
934 new DownloadsEraseFunction(),
935 base::StringPrintf("[{\"id\": %d}]", id)));
936 DownloadManager::DownloadVector items;
937 GetCurrentManager()->GetAllDownloads(&items);
938 EXPECT_EQ(0UL, items.size());
940 download_item = NULL;
941 base::ListValue* result_list = NULL;
942 ASSERT_TRUE(result->GetAsList(&result_list));
943 ASSERT_EQ(1UL, result_list->GetSize());
945 ASSERT_TRUE(result_list->GetInteger(0, &element));
946 EXPECT_EQ(id, element);
949 scoped_refptr<UIThreadExtensionFunction> MockedGetFileIconFunction(
950 const base::FilePath& expected_path,
951 IconLoader::IconSize icon_size,
952 const std::string& response) {
953 scoped_refptr<DownloadsGetFileIconFunction> function(
954 new DownloadsGetFileIconFunction());
955 function->SetIconExtractorForTesting(new MockIconExtractorImpl(
956 expected_path, icon_size, response));
960 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted
962 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
963 DownloadExtensionTest_FileIcon_Active) {
964 DownloadItem* download_item = CreateSlowTestDownload();
965 ASSERT_TRUE(download_item);
966 ASSERT_FALSE(download_item->GetTargetFilePath().empty());
967 std::string args32(base::StringPrintf("[%d, {\"size\": 32}]",
968 download_item->GetId()));
969 std::string result_string;
971 // Get the icon for the in-progress download. This call should succeed even
972 // if the file type isn't registered.
973 // Test whether the correct path is being pased into the icon extractor.
974 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
975 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
976 base::StringPrintf("[%d, {}]", download_item->GetId()), &result_string));
978 // Now try a 16x16 icon.
979 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
980 download_item->GetTargetFilePath(), IconLoader::SMALL, "foo"),
981 base::StringPrintf("[%d, {\"size\": 16}]", download_item->GetId()),
984 // Explicitly asking for 32x32 should give us a 32x32 icon.
985 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
986 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
987 args32, &result_string));
989 // Finish the download and try again.
990 FinishPendingSlowDownloads();
991 EXPECT_EQ(DownloadItem::COMPLETE, download_item->GetState());
992 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
993 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
994 args32, &result_string));
996 // Check the path passed to the icon extractor post-completion.
997 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
998 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
999 args32, &result_string));
1001 // Now create another download.
1002 download_item = CreateSlowTestDownload();
1003 ASSERT_TRUE(download_item);
1004 ASSERT_FALSE(download_item->GetTargetFilePath().empty());
1005 args32 = base::StringPrintf("[%d, {\"size\": 32}]", download_item->GetId());
1007 // Cancel the download. As long as the download has a target path, we should
1008 // be able to query the file icon.
1009 download_item->Cancel(true);
1010 ASSERT_FALSE(download_item->GetTargetFilePath().empty());
1011 // Let cleanup complete on the FILE thread.
1012 content::RunAllPendingInMessageLoop(BrowserThread::FILE);
1013 // Check the path passed to the icon extractor post-cancellation.
1014 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1015 download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
1019 // Simulate an error during icon load by invoking the mock with an empty
1021 std::string error = RunFunctionAndReturnError(
1022 MockedGetFileIconFunction(download_item->GetTargetFilePath(),
1026 EXPECT_STREQ(errors::kIconNotFound, error.c_str());
1028 // Once the download item is deleted, we should return kInvalidId.
1029 int id = download_item->GetId();
1030 download_item->Remove();
1031 download_item = NULL;
1032 EXPECT_EQ(static_cast<DownloadItem*>(NULL),
1033 GetCurrentManager()->GetDownload(id));
1034 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args32);
1035 EXPECT_STREQ(errors::kInvalidId,
1039 // Test that we can acquire file icons for history downloads regardless of
1040 // whether they exist or not. If the file doesn't exist we should receive a
1041 // generic icon from the OS/toolkit that may or may not be specific to the file
1043 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1044 DownloadExtensionTest_FileIcon_History) {
1045 const HistoryDownloadInfo kHistoryInfo[] = {
1046 { FILE_PATH_LITERAL("real.txt"),
1047 DownloadItem::COMPLETE,
1048 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1049 { FILE_PATH_LITERAL("fake.txt"),
1050 DownloadItem::COMPLETE,
1051 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1053 DownloadManager::DownloadVector all_downloads;
1054 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1057 base::FilePath real_path = all_downloads[0]->GetTargetFilePath();
1058 base::FilePath fake_path = all_downloads[1]->GetTargetFilePath();
1060 EXPECT_EQ(0, base::WriteFile(real_path, "", 0));
1061 ASSERT_TRUE(base::PathExists(real_path));
1062 ASSERT_FALSE(base::PathExists(fake_path));
1064 for (DownloadManager::DownloadVector::iterator iter = all_downloads.begin();
1065 iter != all_downloads.end();
1067 std::string result_string;
1068 // Use a MockIconExtractorImpl to test if the correct path is being passed
1069 // into the DownloadFileIconExtractor.
1070 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1071 (*iter)->GetTargetFilePath(), IconLoader::NORMAL, "hello"),
1072 base::StringPrintf("[%d, {\"size\": 32}]", (*iter)->GetId()),
1074 EXPECT_STREQ("hello", result_string.c_str());
1078 // Test passing the empty query to search().
1079 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1080 DownloadExtensionTest_SearchEmptyQuery) {
1081 ScopedCancellingItem item(CreateSlowTestDownload());
1082 ASSERT_TRUE(item.get());
1084 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1085 new DownloadsSearchFunction(), "[{}]"));
1086 ASSERT_TRUE(result.get());
1087 base::ListValue* result_list = NULL;
1088 ASSERT_TRUE(result->GetAsList(&result_list));
1089 ASSERT_EQ(1UL, result_list->GetSize());
1092 // Test the |filenameRegex| parameter for search().
1093 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1094 DownloadExtensionTest_SearchFilenameRegex) {
1095 const HistoryDownloadInfo kHistoryInfo[] = {
1096 { FILE_PATH_LITERAL("foobar"),
1097 DownloadItem::COMPLETE,
1098 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1099 { FILE_PATH_LITERAL("baz"),
1100 DownloadItem::COMPLETE,
1101 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1103 DownloadManager::DownloadVector all_downloads;
1104 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1107 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1108 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]"));
1109 ASSERT_TRUE(result.get());
1110 base::ListValue* result_list = NULL;
1111 ASSERT_TRUE(result->GetAsList(&result_list));
1112 ASSERT_EQ(1UL, result_list->GetSize());
1113 base::DictionaryValue* item_value = NULL;
1114 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
1116 ASSERT_TRUE(item_value->GetInteger("id", &item_id));
1117 ASSERT_EQ(all_downloads[0]->GetId(), static_cast<uint32>(item_id));
1120 // Test the |id| parameter for search().
1121 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_SearchId) {
1122 DownloadManager::DownloadVector items;
1123 CreateSlowTestDownloads(2, &items);
1124 ScopedItemVectorCanceller delete_items(&items);
1126 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1127 new DownloadsSearchFunction(), base::StringPrintf(
1128 "[{\"id\": %u}]", items[0]->GetId())));
1129 ASSERT_TRUE(result.get());
1130 base::ListValue* result_list = NULL;
1131 ASSERT_TRUE(result->GetAsList(&result_list));
1132 ASSERT_EQ(1UL, result_list->GetSize());
1133 base::DictionaryValue* item_value = NULL;
1134 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
1136 ASSERT_TRUE(item_value->GetInteger("id", &item_id));
1137 ASSERT_EQ(items[0]->GetId(), static_cast<uint32>(item_id));
1140 // Test specifying both the |id| and |filename| parameters for search().
1141 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1142 DownloadExtensionTest_SearchIdAndFilename) {
1143 DownloadManager::DownloadVector items;
1144 CreateSlowTestDownloads(2, &items);
1145 ScopedItemVectorCanceller delete_items(&items);
1147 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1148 new DownloadsSearchFunction(),
1149 "[{\"id\": 0, \"filename\": \"foobar\"}]"));
1150 ASSERT_TRUE(result.get());
1151 base::ListValue* result_list = NULL;
1152 ASSERT_TRUE(result->GetAsList(&result_list));
1153 ASSERT_EQ(0UL, result_list->GetSize());
1156 // Test a single |orderBy| parameter for search().
1157 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1158 DownloadExtensionTest_SearchOrderBy) {
1159 const HistoryDownloadInfo kHistoryInfo[] = {
1160 { FILE_PATH_LITERAL("zzz"),
1161 DownloadItem::COMPLETE,
1162 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1163 { FILE_PATH_LITERAL("baz"),
1164 DownloadItem::COMPLETE,
1165 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1167 DownloadManager::DownloadVector items;
1168 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1171 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1172 new DownloadsSearchFunction(), "[{\"orderBy\": [\"filename\"]}]"));
1173 ASSERT_TRUE(result.get());
1174 base::ListValue* result_list = NULL;
1175 ASSERT_TRUE(result->GetAsList(&result_list));
1176 ASSERT_EQ(2UL, result_list->GetSize());
1177 base::DictionaryValue* item0_value = NULL;
1178 base::DictionaryValue* item1_value = NULL;
1179 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value));
1180 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value));
1181 std::string item0_name, item1_name;
1182 ASSERT_TRUE(item0_value->GetString("filename", &item0_name));
1183 ASSERT_TRUE(item1_value->GetString("filename", &item1_name));
1184 ASSERT_GT(items[0]->GetTargetFilePath().value(),
1185 items[1]->GetTargetFilePath().value());
1186 ASSERT_LT(item0_name, item1_name);
1189 // Test specifying an empty |orderBy| parameter for search().
1190 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1191 DownloadExtensionTest_SearchOrderByEmpty) {
1192 const HistoryDownloadInfo kHistoryInfo[] = {
1193 { FILE_PATH_LITERAL("zzz"),
1194 DownloadItem::COMPLETE,
1195 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1196 { FILE_PATH_LITERAL("baz"),
1197 DownloadItem::COMPLETE,
1198 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1200 DownloadManager::DownloadVector items;
1201 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1204 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1205 new DownloadsSearchFunction(), "[{\"orderBy\": []}]"));
1206 ASSERT_TRUE(result.get());
1207 base::ListValue* result_list = NULL;
1208 ASSERT_TRUE(result->GetAsList(&result_list));
1209 ASSERT_EQ(2UL, result_list->GetSize());
1210 base::DictionaryValue* item0_value = NULL;
1211 base::DictionaryValue* item1_value = NULL;
1212 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value));
1213 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value));
1214 std::string item0_name, item1_name;
1215 ASSERT_TRUE(item0_value->GetString("filename", &item0_name));
1216 ASSERT_TRUE(item1_value->GetString("filename", &item1_name));
1217 ASSERT_GT(items[0]->GetTargetFilePath().value(),
1218 items[1]->GetTargetFilePath().value());
1219 // The order of results when orderBy is empty is unspecified. When there are
1220 // no sorters, DownloadQuery does not call sort(), so the order of the results
1221 // depends on the order of the items in base::hash_map<uint32,...>
1222 // DownloadManagerImpl::downloads_, which is unspecified and differs between
1223 // libc++ and libstdc++. http://crbug.com/365334
1226 // Test the |danger| option for search().
1227 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1228 DownloadExtensionTest_SearchDanger) {
1229 const HistoryDownloadInfo kHistoryInfo[] = {
1230 { FILE_PATH_LITERAL("zzz"),
1231 DownloadItem::COMPLETE,
1232 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
1233 { FILE_PATH_LITERAL("baz"),
1234 DownloadItem::COMPLETE,
1235 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
1237 DownloadManager::DownloadVector items;
1238 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1241 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1242 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]"));
1243 ASSERT_TRUE(result.get());
1244 base::ListValue* result_list = NULL;
1245 ASSERT_TRUE(result->GetAsList(&result_list));
1246 ASSERT_EQ(1UL, result_list->GetSize());
1249 // Test the |state| option for search().
1250 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1251 DownloadExtensionTest_SearchState) {
1252 DownloadManager::DownloadVector items;
1253 CreateSlowTestDownloads(2, &items);
1254 ScopedItemVectorCanceller delete_items(&items);
1256 items[0]->Cancel(true);
1258 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1259 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]"));
1260 ASSERT_TRUE(result.get());
1261 base::ListValue* result_list = NULL;
1262 ASSERT_TRUE(result->GetAsList(&result_list));
1263 ASSERT_EQ(1UL, result_list->GetSize());
1266 // Test the |limit| option for search().
1267 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1268 DownloadExtensionTest_SearchLimit) {
1269 DownloadManager::DownloadVector items;
1270 CreateSlowTestDownloads(2, &items);
1271 ScopedItemVectorCanceller delete_items(&items);
1273 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1274 new DownloadsSearchFunction(), "[{\"limit\": 1}]"));
1275 ASSERT_TRUE(result.get());
1276 base::ListValue* result_list = NULL;
1277 ASSERT_TRUE(result->GetAsList(&result_list));
1278 ASSERT_EQ(1UL, result_list->GetSize());
1281 // Test invalid search parameters.
1282 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1283 DownloadExtensionTest_SearchInvalid) {
1284 std::string error = RunFunctionAndReturnError(
1285 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]");
1286 EXPECT_STREQ(errors::kInvalidFilter,
1288 error = RunFunctionAndReturnError(
1289 new DownloadsSearchFunction(), "[{\"orderBy\": [\"goat\"]}]");
1290 EXPECT_STREQ(errors::kInvalidOrderBy,
1292 error = RunFunctionAndReturnError(
1293 new DownloadsSearchFunction(), "[{\"limit\": -1}]");
1294 EXPECT_STREQ(errors::kInvalidQueryLimit,
1298 // Test searching using multiple conditions through multiple downloads.
1299 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1300 DownloadExtensionTest_SearchPlural) {
1301 const HistoryDownloadInfo kHistoryInfo[] = {
1302 { FILE_PATH_LITERAL("aaa"),
1303 DownloadItem::CANCELLED,
1304 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
1305 { FILE_PATH_LITERAL("zzz"),
1306 DownloadItem::COMPLETE,
1307 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
1308 { FILE_PATH_LITERAL("baz"),
1309 DownloadItem::COMPLETE,
1310 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
1312 DownloadManager::DownloadVector items;
1313 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
1316 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1317 new DownloadsSearchFunction(), "[{"
1318 "\"state\": \"complete\", "
1319 "\"danger\": \"content\", "
1320 "\"orderBy\": [\"filename\"], "
1322 ASSERT_TRUE(result.get());
1323 base::ListValue* result_list = NULL;
1324 ASSERT_TRUE(result->GetAsList(&result_list));
1325 ASSERT_EQ(1UL, result_list->GetSize());
1326 base::DictionaryValue* item_value = NULL;
1327 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
1328 base::FilePath::StringType item_name;
1329 ASSERT_TRUE(item_value->GetString("filename", &item_name));
1330 ASSERT_EQ(items[2]->GetTargetFilePath().value(), item_name);
1333 // Test that incognito downloads are only visible in incognito contexts, and
1334 // test that on-record downloads are visible in both incognito and on-record
1335 // contexts, for DownloadsSearchFunction, DownloadsPauseFunction,
1336 // DownloadsResumeFunction, and DownloadsCancelFunction.
1337 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1338 DownloadExtensionTest_SearchPauseResumeCancelGetFileIconIncognito) {
1339 scoped_ptr<base::Value> result_value;
1340 base::ListValue* result_list = NULL;
1341 base::DictionaryValue* result_dict = NULL;
1342 base::FilePath::StringType filename;
1343 bool is_incognito = false;
1345 std::string on_item_arg;
1346 std::string off_item_arg;
1347 std::string result_string;
1349 // Set up one on-record item and one off-record item.
1350 // Set up the off-record item first because otherwise there are mysteriously 3
1351 // items total instead of 2.
1352 // TODO(benjhayden): Figure out where the third item comes from.
1354 DownloadItem* off_item = CreateSlowTestDownload();
1355 ASSERT_TRUE(off_item);
1356 off_item_arg = DownloadItemIdAsArgList(off_item);
1359 DownloadItem* on_item = CreateSlowTestDownload();
1360 ASSERT_TRUE(on_item);
1361 on_item_arg = DownloadItemIdAsArgList(on_item);
1362 ASSERT_TRUE(on_item->GetTargetFilePath() != off_item->GetTargetFilePath());
1364 // Extensions running in the incognito window should have access to both
1365 // items because the Test extension is in spanning mode.
1367 result_value.reset(RunFunctionAndReturnResult(
1368 new DownloadsSearchFunction(), "[{}]"));
1369 ASSERT_TRUE(result_value.get());
1370 ASSERT_TRUE(result_value->GetAsList(&result_list));
1371 ASSERT_EQ(2UL, result_list->GetSize());
1372 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict));
1373 ASSERT_TRUE(result_dict->GetString("filename", &filename));
1374 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
1375 EXPECT_TRUE(on_item->GetTargetFilePath() == base::FilePath(filename));
1376 EXPECT_FALSE(is_incognito);
1377 ASSERT_TRUE(result_list->GetDictionary(1, &result_dict));
1378 ASSERT_TRUE(result_dict->GetString("filename", &filename));
1379 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
1380 EXPECT_TRUE(off_item->GetTargetFilePath() == base::FilePath(filename));
1381 EXPECT_TRUE(is_incognito);
1383 // Extensions running in the on-record window should have access only to the
1386 result_value.reset(RunFunctionAndReturnResult(
1387 new DownloadsSearchFunction(), "[{}]"));
1388 ASSERT_TRUE(result_value.get());
1389 ASSERT_TRUE(result_value->GetAsList(&result_list));
1390 ASSERT_EQ(1UL, result_list->GetSize());
1391 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict));
1392 ASSERT_TRUE(result_dict->GetString("filename", &filename));
1393 EXPECT_TRUE(on_item->GetTargetFilePath() == base::FilePath(filename));
1394 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
1395 EXPECT_FALSE(is_incognito);
1397 // Pausing/Resuming the off-record item while on the record should return an
1398 // error. Cancelling "non-existent" downloads is not an error.
1399 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg);
1400 EXPECT_STREQ(errors::kInvalidId,
1402 error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
1404 EXPECT_STREQ(errors::kInvalidId,
1406 error = RunFunctionAndReturnError(
1407 new DownloadsGetFileIconFunction(),
1408 base::StringPrintf("[%d, {}]", off_item->GetId()));
1409 EXPECT_STREQ(errors::kInvalidId,
1414 // Do the FileIcon test for both the on- and off-items while off the record.
1415 // NOTE(benjhayden): This does not include the FileIcon test from history,
1416 // just active downloads. This shouldn't be a problem.
1417 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1418 on_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
1419 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string));
1420 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1421 off_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
1422 base::StringPrintf("[%d, {}]", off_item->GetId()), &result_string));
1424 // Do the pause/resume/cancel test for both the on- and off-items while off
1426 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
1427 EXPECT_TRUE(on_item->IsPaused());
1428 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
1429 EXPECT_TRUE(on_item->IsPaused());
1430 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg));
1431 EXPECT_FALSE(on_item->IsPaused());
1432 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg));
1433 EXPECT_FALSE(on_item->IsPaused());
1434 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
1435 EXPECT_TRUE(on_item->IsPaused());
1436 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg));
1437 EXPECT_EQ(DownloadItem::CANCELLED, on_item->GetState());
1438 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg));
1439 EXPECT_EQ(DownloadItem::CANCELLED, on_item->GetState());
1440 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), on_item_arg);
1441 EXPECT_STREQ(errors::kNotInProgress, error.c_str());
1442 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), on_item_arg);
1443 EXPECT_STREQ(errors::kNotResumable, error.c_str());
1444 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
1445 EXPECT_TRUE(off_item->IsPaused());
1446 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
1447 EXPECT_TRUE(off_item->IsPaused());
1448 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg));
1449 EXPECT_FALSE(off_item->IsPaused());
1450 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg));
1451 EXPECT_FALSE(off_item->IsPaused());
1452 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
1453 EXPECT_TRUE(off_item->IsPaused());
1454 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg));
1455 EXPECT_EQ(DownloadItem::CANCELLED, off_item->GetState());
1456 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg));
1457 EXPECT_EQ(DownloadItem::CANCELLED, off_item->GetState());
1458 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg);
1459 EXPECT_STREQ(errors::kNotInProgress, error.c_str());
1460 error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
1462 EXPECT_STREQ(errors::kNotResumable, error.c_str());
1465 // Test that we can start a download and that the correct sequence of events is
1467 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1468 DownloadExtensionTest_Download_Basic) {
1469 LoadExtension("downloads_split");
1470 ASSERT_TRUE(StartEmbeddedTestServer());
1471 ASSERT_TRUE(test_server()->Start());
1472 std::string download_url = test_server()->GetURL("slow?0").spec();
1475 // Start downloading a file.
1476 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1477 new DownloadsDownloadFunction(), base::StringPrintf(
1478 "[{\"url\": \"%s\"}]", download_url.c_str())));
1479 ASSERT_TRUE(result.get());
1481 ASSERT_TRUE(result->GetAsInteger(&result_id));
1482 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1484 ScopedCancellingItem canceller(item);
1485 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1487 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1489 "[{\"danger\": \"safe\","
1490 " \"incognito\": false,"
1491 " \"mime\": \"text/plain\","
1492 " \"paused\": false,"
1493 " \"url\": \"%s\"}]",
1494 download_url.c_str())));
1495 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1499 " \"previous\": \"\","
1500 " \"current\": \"%s\"}}]",
1502 GetFilename("slow.txt").c_str())));
1503 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1507 " \"previous\": \"in_progress\","
1508 " \"current\": \"complete\"}}]",
1512 // Test that we can start a download from an incognito context, and that the
1513 // download knows that it's incognito.
1514 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1515 DownloadExtensionTest_Download_Incognito) {
1516 LoadExtension("downloads_split");
1517 ASSERT_TRUE(StartEmbeddedTestServer());
1518 ASSERT_TRUE(test_server()->Start());
1520 std::string download_url = test_server()->GetURL("slow?0").spec();
1522 // Start downloading a file.
1523 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1524 new DownloadsDownloadFunction(), base::StringPrintf(
1525 "[{\"url\": \"%s\"}]", download_url.c_str())));
1526 ASSERT_TRUE(result.get());
1528 ASSERT_TRUE(result->GetAsInteger(&result_id));
1529 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1531 ScopedCancellingItem canceller(item);
1532 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1534 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1536 "[{\"danger\": \"safe\","
1537 " \"incognito\": true,"
1538 " \"mime\": \"text/plain\","
1539 " \"paused\": false,"
1540 " \"url\": \"%s\"}]",
1541 download_url.c_str())));
1542 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1546 " \"previous\": \"\","
1547 " \"current\": \"%s\"}}]",
1549 GetFilename("slow.txt").c_str())));
1550 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1554 " \"current\": \"complete\","
1555 " \"previous\": \"in_progress\"}}]",
1560 // This test is very flaky on Win. http://crbug.com/248438
1561 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1562 DISABLED_DownloadExtensionTest_Download_UnsafeHeaders
1564 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1565 DownloadExtensionTest_Download_UnsafeHeaders
1568 // Test that we disallow certain headers case-insensitively.
1569 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1570 MAYBE_DownloadExtensionTest_Download_UnsafeHeaders) {
1571 LoadExtension("downloads_split");
1572 ASSERT_TRUE(StartEmbeddedTestServer());
1573 ASSERT_TRUE(test_server()->Start());
1576 static const char* const kUnsafeHeaders[] = {
1583 "coNteNt-traNsfer-eNcodiNg",
1591 "trANsfer-eNcodiNg",
1597 "pRoxY-probably-not-evil",
1598 "sEc-probably-not-evil",
1600 "Access-Control-Request-Headers",
1601 "Access-Control-Request-Method",
1604 for (size_t index = 0; index < arraysize(kUnsafeHeaders); ++index) {
1605 std::string download_url = test_server()->GetURL("slow?0").spec();
1606 EXPECT_STREQ(errors::kInvalidHeaderUnsafe,
1607 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1609 "[{\"url\": \"%s\","
1610 " \"filename\": \"unsafe-header-%d.txt\","
1612 " \"name\": \"%s\","
1613 " \"value\": \"unsafe\"}]}]",
1614 download_url.c_str(),
1615 static_cast<int>(index),
1616 kUnsafeHeaders[index])).c_str());
1620 // Tests that invalid header names and values are rejected.
1621 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1622 DownloadExtensionTest_Download_InvalidHeaders) {
1623 LoadExtension("downloads_split");
1624 ASSERT_TRUE(StartEmbeddedTestServer());
1625 ASSERT_TRUE(test_server()->Start());
1627 std::string download_url = test_server()->GetURL("slow?0").spec();
1628 EXPECT_STREQ(errors::kInvalidHeaderName,
1629 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1631 "[{\"url\": \"%s\","
1632 " \"filename\": \"unsafe-header-crlf.txt\","
1634 " \"name\": \"Header\\r\\nSec-Spoof: Hey\\r\\nX-Split:X\","
1635 " \"value\": \"unsafe\"}]}]",
1636 download_url.c_str())).c_str());
1638 EXPECT_STREQ(errors::kInvalidHeaderValue,
1639 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1641 "[{\"url\": \"%s\","
1642 " \"filename\": \"unsafe-header-crlf.txt\","
1644 " \"name\": \"Invalid-value\","
1645 " \"value\": \"hey\\r\\nSec-Spoof: Hey\"}]}]",
1646 download_url.c_str())).c_str());
1650 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1651 DISABLED_DownloadExtensionTest_Download_Subdirectory
1653 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1654 DownloadExtensionTest_Download_Subdirectory
1656 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1657 MAYBE_DownloadExtensionTest_Download_Subdirectory) {
1658 LoadExtension("downloads_split");
1659 ASSERT_TRUE(StartEmbeddedTestServer());
1660 ASSERT_TRUE(test_server()->Start());
1661 std::string download_url = test_server()->GetURL("slow?0").spec();
1664 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1665 new DownloadsDownloadFunction(), base::StringPrintf(
1666 "[{\"url\": \"%s\","
1667 " \"filename\": \"sub/dir/ect/ory.txt\"}]",
1668 download_url.c_str())));
1669 ASSERT_TRUE(result.get());
1671 ASSERT_TRUE(result->GetAsInteger(&result_id));
1672 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1674 ScopedCancellingItem canceller(item);
1675 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1677 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1679 "[{\"danger\": \"safe\","
1680 " \"incognito\": false,"
1681 " \"mime\": \"text/plain\","
1682 " \"paused\": false,"
1683 " \"url\": \"%s\"}]",
1684 download_url.c_str())));
1685 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1689 " \"previous\": \"\","
1690 " \"current\": \"%s\"}}]",
1692 GetFilename("sub/dir/ect/ory.txt").c_str())));
1693 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1697 " \"previous\": \"in_progress\","
1698 " \"current\": \"complete\"}}]",
1702 // Test that invalid filenames are disallowed.
1703 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1704 DownloadExtensionTest_Download_InvalidFilename) {
1705 LoadExtension("downloads_split");
1706 ASSERT_TRUE(StartEmbeddedTestServer());
1707 ASSERT_TRUE(test_server()->Start());
1708 std::string download_url = test_server()->GetURL("slow?0").spec();
1711 EXPECT_STREQ(errors::kInvalidFilename,
1712 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1714 "[{\"url\": \"%s\","
1715 " \"filename\": \"../../../../../etc/passwd\"}]",
1716 download_url.c_str())).c_str());
1719 // flaky on mac: crbug.com/392288
1720 #if defined(OS_MACOSX)
1721 #define MAYBE_DownloadExtensionTest_Download_InvalidURLs \
1722 DISABLED_DownloadExtensionTest_Download_InvalidURLs
1724 #define MAYBE_DownloadExtensionTest_Download_InvalidURLs \
1725 DownloadExtensionTest_Download_InvalidURLs
1728 // Test that downloading invalid URLs immediately returns kInvalidURLError.
1729 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1730 MAYBE_DownloadExtensionTest_Download_InvalidURLs) {
1731 LoadExtension("downloads_split");
1734 static const char* const kInvalidURLs[] = {
1740 "foo/bar.html#frag",
1744 for (size_t index = 0; index < arraysize(kInvalidURLs); ++index) {
1745 EXPECT_STREQ(errors::kInvalidURL,
1746 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1748 "[{\"url\": \"%s\"}]", kInvalidURLs[index])).c_str())
1749 << kInvalidURLs[index];
1752 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1753 new DownloadsDownloadFunction(),
1754 "[{\"url\": \"javascript:document.write(\\\"hello\\\");\"}]").c_str());
1755 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1756 new DownloadsDownloadFunction(),
1757 "[{\"url\": \"javascript:return false;\"}]").c_str());
1758 EXPECT_STREQ("NETWORK_FAILED", RunFunctionAndReturnError(
1759 new DownloadsDownloadFunction(),
1760 "[{\"url\": \"ftp://example.com/example.txt\"}]").c_str());
1763 // TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to
1764 // permissions, test downloading from ftp.
1766 // Valid URLs plus fragments are still valid URLs.
1767 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1768 DownloadExtensionTest_Download_URLFragment) {
1769 LoadExtension("downloads_split");
1770 ASSERT_TRUE(StartEmbeddedTestServer());
1771 ASSERT_TRUE(test_server()->Start());
1772 std::string download_url = test_server()->GetURL("slow?0#fragment").spec();
1775 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1776 new DownloadsDownloadFunction(), base::StringPrintf(
1777 "[{\"url\": \"%s\"}]", download_url.c_str())));
1778 ASSERT_TRUE(result.get());
1780 ASSERT_TRUE(result->GetAsInteger(&result_id));
1781 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1783 ScopedCancellingItem canceller(item);
1784 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1786 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1788 "[{\"danger\": \"safe\","
1789 " \"incognito\": false,"
1790 " \"mime\": \"text/plain\","
1791 " \"paused\": false,"
1792 " \"url\": \"%s\"}]",
1793 download_url.c_str())));
1794 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1798 " \"previous\": \"\","
1799 " \"current\": \"%s\"}}]",
1801 GetFilename("slow.txt").c_str())));
1802 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1806 " \"previous\": \"in_progress\","
1807 " \"current\": \"complete\"}}]",
1811 // conflictAction may be specified without filename.
1812 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1813 DownloadExtensionTest_Download_ConflictAction) {
1814 static char kFilename[] = "download.txt";
1815 LoadExtension("downloads_split");
1816 std::string download_url = "data:text/plain,hello";
1819 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1820 new DownloadsDownloadFunction(), base::StringPrintf(
1821 "[{\"url\": \"%s\"}]", download_url.c_str())));
1822 ASSERT_TRUE(result.get());
1824 ASSERT_TRUE(result->GetAsInteger(&result_id));
1825 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1827 ScopedCancellingItem canceller(item);
1828 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1830 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1832 "[{\"danger\": \"safe\","
1833 " \"incognito\": false,"
1834 " \"mime\": \"text/plain\","
1835 " \"paused\": false,"
1836 " \"url\": \"%s\"}]",
1837 download_url.c_str())));
1838 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1842 " \"previous\": \"\","
1843 " \"current\": \"%s\"}}]",
1845 GetFilename(kFilename).c_str())));
1846 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1850 " \"previous\": \"in_progress\","
1851 " \"current\": \"complete\"}}]",
1854 result.reset(RunFunctionAndReturnResult(
1855 new DownloadsDownloadFunction(), base::StringPrintf(
1856 "[{\"url\": \"%s\", \"conflictAction\": \"overwrite\"}]",
1857 download_url.c_str())));
1858 ASSERT_TRUE(result.get());
1860 ASSERT_TRUE(result->GetAsInteger(&result_id));
1861 item = GetCurrentManager()->GetDownload(result_id);
1863 ScopedCancellingItem canceller2(item);
1864 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1866 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1868 "[{\"danger\": \"safe\","
1869 " \"incognito\": false,"
1870 " \"mime\": \"text/plain\","
1871 " \"paused\": false,"
1872 " \"url\": \"%s\"}]",
1873 download_url.c_str())));
1874 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1878 " \"previous\": \"\","
1879 " \"current\": \"%s\"}}]",
1881 GetFilename(kFilename).c_str())));
1882 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1886 " \"previous\": \"in_progress\","
1887 " \"current\": \"complete\"}}]",
1891 // Valid data URLs are valid URLs.
1892 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1893 DownloadExtensionTest_Download_DataURL) {
1894 LoadExtension("downloads_split");
1895 std::string download_url = "data:text/plain,hello";
1898 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1899 new DownloadsDownloadFunction(), base::StringPrintf(
1900 "[{\"url\": \"%s\","
1901 " \"filename\": \"data.txt\"}]", download_url.c_str())));
1902 ASSERT_TRUE(result.get());
1904 ASSERT_TRUE(result->GetAsInteger(&result_id));
1905 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1907 ScopedCancellingItem canceller(item);
1908 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1910 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1912 "[{\"danger\": \"safe\","
1913 " \"incognito\": false,"
1914 " \"mime\": \"text/plain\","
1915 " \"paused\": false,"
1916 " \"url\": \"%s\"}]",
1917 download_url.c_str())));
1918 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1922 " \"previous\": \"\","
1923 " \"current\": \"%s\"}}]",
1925 GetFilename("data.txt").c_str())));
1926 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1930 " \"previous\": \"in_progress\","
1931 " \"current\": \"complete\"}}]",
1935 // Valid file URLs are valid URLs.
1937 // Disabled due to crbug.com/175711
1938 #define MAYBE_DownloadExtensionTest_Download_File \
1939 DISABLED_DownloadExtensionTest_Download_File
1941 #define MAYBE_DownloadExtensionTest_Download_File \
1942 DownloadExtensionTest_Download_File
1944 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1945 MAYBE_DownloadExtensionTest_Download_File) {
1947 LoadExtension("downloads_split");
1948 std::string download_url = "file:///";
1950 download_url += "C:/";
1953 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1954 new DownloadsDownloadFunction(), base::StringPrintf(
1955 "[{\"url\": \"%s\","
1956 " \"filename\": \"file.txt\"}]", download_url.c_str())));
1957 ASSERT_TRUE(result.get());
1959 ASSERT_TRUE(result->GetAsInteger(&result_id));
1960 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1962 ScopedCancellingItem canceller(item);
1963 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1965 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1967 "[{\"danger\": \"safe\","
1968 " \"incognito\": false,"
1969 " \"mime\": \"text/html\","
1970 " \"paused\": false,"
1971 " \"url\": \"%s\"}]",
1972 download_url.c_str())));
1973 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1977 " \"previous\": \"\","
1978 " \"current\": \"%s\"}}]",
1980 GetFilename("file.txt").c_str())));
1981 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1985 " \"previous\": \"in_progress\","
1986 " \"current\": \"complete\"}}]",
1990 // Test that auth-basic-succeed would fail if the resource requires the
1991 // Authorization header and chrome fails to propagate it back to the server.
1992 // This tests both that testserver.py does not succeed when it should fail as
1993 // well as how the downloads extension API exposes the failure to extensions.
1994 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1995 DownloadExtensionTest_Download_AuthBasic_Fail) {
1996 LoadExtension("downloads_split");
1997 ASSERT_TRUE(StartEmbeddedTestServer());
1998 ASSERT_TRUE(test_server()->Start());
1999 std::string download_url = test_server()->GetURL("auth-basic").spec();
2002 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2003 new DownloadsDownloadFunction(), base::StringPrintf(
2004 "[{\"url\": \"%s\","
2005 " \"filename\": \"auth-basic-fail.txt\"}]",
2006 download_url.c_str())));
2007 ASSERT_TRUE(result.get());
2009 ASSERT_TRUE(result->GetAsInteger(&result_id));
2010 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2012 ScopedCancellingItem canceller(item);
2013 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2015 ASSERT_TRUE(WaitForInterruption(
2017 content::DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED,
2018 base::StringPrintf("[{\"danger\": \"safe\","
2019 " \"incognito\": false,"
2020 " \"mime\": \"text/html\","
2021 " \"paused\": false,"
2022 " \"url\": \"%s\"}]",
2023 download_url.c_str())));
2026 // Test that DownloadsDownloadFunction propagates |headers| to the URLRequest.
2027 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2028 DownloadExtensionTest_Download_Headers) {
2029 LoadExtension("downloads_split");
2030 ASSERT_TRUE(StartEmbeddedTestServer());
2031 ASSERT_TRUE(test_server()->Start());
2032 std::string download_url = test_server()->GetURL("files/downloads/"
2033 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
2036 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2037 new DownloadsDownloadFunction(), base::StringPrintf(
2038 "[{\"url\": \"%s\","
2039 " \"filename\": \"headers-succeed.txt\","
2041 " {\"name\": \"Foo\", \"value\": \"bar\"},"
2042 " {\"name\": \"Qx\", \"value\":\"yo\"}]}]",
2043 download_url.c_str())));
2044 ASSERT_TRUE(result.get());
2046 ASSERT_TRUE(result->GetAsInteger(&result_id));
2047 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2049 ScopedCancellingItem canceller(item);
2050 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2052 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2054 "[{\"danger\": \"safe\","
2055 " \"incognito\": false,"
2056 " \"mime\": \"application/octet-stream\","
2057 " \"paused\": false,"
2058 " \"url\": \"%s\"}]",
2059 download_url.c_str())));
2060 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2064 " \"previous\": \"\","
2065 " \"current\": \"%s\"}}]",
2067 GetFilename("headers-succeed.txt").c_str())));
2068 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2072 " \"previous\": \"in_progress\","
2073 " \"current\": \"complete\"}}]",
2077 // Test that headers-succeed would fail if the resource requires the headers and
2078 // chrome fails to propagate them back to the server. This tests both that
2079 // testserver.py does not succeed when it should fail as well as how the
2080 // downloads extension api exposes the failure to extensions.
2081 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2082 DownloadExtensionTest_Download_Headers_Fail) {
2083 LoadExtension("downloads_split");
2084 ASSERT_TRUE(StartEmbeddedTestServer());
2085 ASSERT_TRUE(test_server()->Start());
2086 std::string download_url = test_server()->GetURL("files/downloads/"
2087 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
2090 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2091 new DownloadsDownloadFunction(), base::StringPrintf(
2092 "[{\"url\": \"%s\","
2093 " \"filename\": \"headers-fail.txt\"}]",
2094 download_url.c_str())));
2095 ASSERT_TRUE(result.get());
2097 ASSERT_TRUE(result->GetAsInteger(&result_id));
2098 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2100 ScopedCancellingItem canceller(item);
2101 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2103 ASSERT_TRUE(WaitForInterruption(
2105 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2106 base::StringPrintf("[{\"danger\": \"safe\","
2107 " \"incognito\": false,"
2108 " \"bytesReceived\": 0.0,"
2109 " \"fileSize\": 0.0,"
2111 " \"paused\": false,"
2112 " \"url\": \"%s\"}]",
2113 download_url.c_str())));
2116 // Test that DownloadsDownloadFunction propagates the Authorization header
2118 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2119 DownloadExtensionTest_Download_AuthBasic) {
2120 LoadExtension("downloads_split");
2121 ASSERT_TRUE(StartEmbeddedTestServer());
2122 ASSERT_TRUE(test_server()->Start());
2123 std::string download_url = test_server()->GetURL("auth-basic").spec();
2124 // This is just base64 of 'username:secret'.
2125 static const char kAuthorization[] = "dXNlcm5hbWU6c2VjcmV0";
2128 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2129 new DownloadsDownloadFunction(), base::StringPrintf(
2130 "[{\"url\": \"%s\","
2131 " \"filename\": \"auth-basic-succeed.txt\","
2133 " \"name\": \"Authorization\","
2134 " \"value\": \"Basic %s\"}]}]",
2135 download_url.c_str(), kAuthorization)));
2136 ASSERT_TRUE(result.get());
2138 ASSERT_TRUE(result->GetAsInteger(&result_id));
2139 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2141 ScopedCancellingItem canceller(item);
2142 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2144 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2146 "[{\"danger\": \"safe\","
2147 " \"incognito\": false,"
2148 " \"bytesReceived\": 0.0,"
2149 " \"fileSize\": 0.0,"
2150 " \"mime\": \"text/html\","
2151 " \"paused\": false,"
2152 " \"url\": \"%s\"}]",
2153 download_url.c_str())));
2154 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2158 " \"previous\": \"in_progress\","
2159 " \"current\": \"complete\"}}]",
2163 // Test that DownloadsDownloadFunction propagates the |method| and |body|
2164 // parameters to the URLRequest.
2165 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2166 DownloadExtensionTest_Download_Post) {
2167 LoadExtension("downloads_split");
2168 ASSERT_TRUE(StartEmbeddedTestServer());
2169 ASSERT_TRUE(test_server()->Start());
2170 std::string download_url = test_server()->GetURL("files/post/downloads/"
2171 "a_zip_file.zip?expected_body=BODY").spec();
2174 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2175 new DownloadsDownloadFunction(), base::StringPrintf(
2176 "[{\"url\": \"%s\","
2177 " \"filename\": \"post-succeed.txt\","
2178 " \"method\": \"POST\","
2179 " \"body\": \"BODY\"}]",
2180 download_url.c_str())));
2181 ASSERT_TRUE(result.get());
2183 ASSERT_TRUE(result->GetAsInteger(&result_id));
2184 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2186 ScopedCancellingItem canceller(item);
2187 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2189 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2191 "[{\"danger\": \"safe\","
2192 " \"incognito\": false,"
2193 " \"mime\": \"application/octet-stream\","
2194 " \"paused\": false,"
2195 " \"url\": \"%s\"}]",
2196 download_url.c_str())));
2197 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2201 " \"previous\": \"\","
2202 " \"current\": \"%s\"}}]",
2204 GetFilename("post-succeed.txt").c_str())));
2205 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2209 " \"previous\": \"in_progress\","
2210 " \"current\": \"complete\"}}]",
2214 // Test that downloadPostSuccess would fail if the resource requires the POST
2215 // method, and chrome fails to propagate the |method| parameter back to the
2216 // server. This tests both that testserver.py does not succeed when it should
2217 // fail, and this tests how the downloads extension api exposes the failure to
2219 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2220 DownloadExtensionTest_Download_Post_Get) {
2221 LoadExtension("downloads_split");
2222 ASSERT_TRUE(StartEmbeddedTestServer());
2223 ASSERT_TRUE(test_server()->Start());
2224 std::string download_url = test_server()->GetURL("files/post/downloads/"
2225 "a_zip_file.zip?expected_body=BODY").spec();
2228 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2229 new DownloadsDownloadFunction(), base::StringPrintf(
2230 "[{\"url\": \"%s\","
2231 " \"body\": \"BODY\","
2232 " \"filename\": \"post-get.txt\"}]",
2233 download_url.c_str())));
2234 ASSERT_TRUE(result.get());
2236 ASSERT_TRUE(result->GetAsInteger(&result_id));
2237 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2239 ScopedCancellingItem canceller(item);
2240 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2242 ASSERT_TRUE(WaitForInterruption(
2244 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2245 base::StringPrintf("[{\"danger\": \"safe\","
2246 " \"incognito\": false,"
2248 " \"paused\": false,"
2250 " \"url\": \"%s\"}]",
2252 download_url.c_str())));
2255 // Test that downloadPostSuccess would fail if the resource requires the POST
2256 // method, and chrome fails to propagate the |body| parameter back to the
2257 // server. This tests both that testserver.py does not succeed when it should
2258 // fail, and this tests how the downloads extension api exposes the failure to
2260 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2261 DownloadExtensionTest_Download_Post_NoBody) {
2262 LoadExtension("downloads_split");
2263 ASSERT_TRUE(StartEmbeddedTestServer());
2264 ASSERT_TRUE(test_server()->Start());
2265 std::string download_url = test_server()->GetURL("files/post/downloads/"
2266 "a_zip_file.zip?expected_body=BODY").spec();
2269 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2270 new DownloadsDownloadFunction(), base::StringPrintf(
2271 "[{\"url\": \"%s\","
2272 " \"method\": \"POST\","
2273 " \"filename\": \"post-nobody.txt\"}]",
2274 download_url.c_str())));
2275 ASSERT_TRUE(result.get());
2277 ASSERT_TRUE(result->GetAsInteger(&result_id));
2278 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2280 ScopedCancellingItem canceller(item);
2281 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2283 ASSERT_TRUE(WaitForInterruption(
2285 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2286 base::StringPrintf("[{\"danger\": \"safe\","
2287 " \"incognito\": false,"
2289 " \"paused\": false,"
2291 " \"url\": \"%s\"}]",
2293 download_url.c_str())));
2296 // Test that cancel()ing an in-progress download causes its state to transition
2297 // to interrupted, and test that that state transition is detectable by an
2298 // onChanged event listener. TODO(benjhayden): Test other sources of
2299 // interruptions such as server death.
2300 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2301 DownloadExtensionTest_Download_Cancel) {
2302 LoadExtension("downloads_split");
2303 ASSERT_TRUE(StartEmbeddedTestServer());
2304 ASSERT_TRUE(test_server()->Start());
2305 std::string download_url = test_server()->GetURL(
2306 "download-known-size").spec();
2309 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2310 new DownloadsDownloadFunction(), base::StringPrintf(
2311 "[{\"url\": \"%s\"}]", download_url.c_str())));
2312 ASSERT_TRUE(result.get());
2314 ASSERT_TRUE(result->GetAsInteger(&result_id));
2315 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2317 ScopedCancellingItem canceller(item);
2318 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2320 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2322 "[{\"danger\": \"safe\","
2323 " \"incognito\": false,"
2324 " \"mime\": \"application/octet-stream\","
2325 " \"paused\": false,"
2327 " \"url\": \"%s\"}]",
2329 download_url.c_str())));
2331 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2334 " \"error\": {\"current\":\"USER_CANCELED\"},"
2336 " \"previous\": \"in_progress\","
2337 " \"current\": \"interrupted\"}}]",
2341 // flaky on mac: crbug.com/392288
2342 #if defined(OS_MACOSX)
2343 #define MAYBE_DownloadExtensionTest_Download_FileSystemURL \
2344 DISABLED_DownloadExtensionTest_Download_FileSystemURL
2346 #define MAYBE_DownloadExtensionTest_Download_FileSystemURL \
2347 DownloadExtensionTest_Download_FileSystemURL
2350 // Test downloading filesystem: URLs.
2351 // NOTE: chrome disallows creating HTML5 FileSystem Files in incognito.
2352 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2353 MAYBE_DownloadExtensionTest_Download_FileSystemURL) {
2354 static const char kPayloadData[] = "on the record\ndata";
2356 LoadExtension("downloads_split");
2358 const std::string download_url = "filesystem:" + GetExtensionURL() +
2359 "temporary/on_record.txt";
2361 // Setup a file in the filesystem which we can download.
2362 ASSERT_TRUE(HTML5FileWriter::CreateFileForTesting(
2363 BrowserContext::GetDefaultStoragePartition(browser()->profile())
2364 ->GetFileSystemContext(),
2365 storage::FileSystemURL::CreateForTest(GURL(download_url)),
2367 strlen(kPayloadData)));
2370 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2371 new DownloadsDownloadFunction(), base::StringPrintf(
2372 "[{\"url\": \"%s\"}]", download_url.c_str())));
2373 ASSERT_TRUE(result.get());
2375 ASSERT_TRUE(result->GetAsInteger(&result_id));
2377 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2379 ScopedCancellingItem canceller(item);
2380 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2382 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2384 "[{\"danger\": \"safe\","
2385 " \"incognito\": false,"
2386 " \"mime\": \"text/plain\","
2387 " \"paused\": false,"
2388 " \"url\": \"%s\"}]",
2389 download_url.c_str())));
2390 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2394 " \"previous\": \"\","
2395 " \"current\": \"%s\"}}]",
2397 GetFilename("on_record.txt").c_str())));
2398 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2402 " \"previous\": \"in_progress\","
2403 " \"current\": \"complete\"}}]",
2405 std::string disk_data;
2406 EXPECT_TRUE(base::ReadFileToString(item->GetTargetFilePath(), &disk_data));
2407 EXPECT_STREQ(kPayloadData, disk_data.c_str());
2410 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2411 DownloadExtensionTest_OnDeterminingFilename_NoChange) {
2413 LoadExtension("downloads_split");
2414 AddFilenameDeterminer();
2415 ASSERT_TRUE(StartEmbeddedTestServer());
2416 ASSERT_TRUE(test_server()->Start());
2417 std::string download_url = test_server()->GetURL("slow?0").spec();
2419 // Start downloading a file.
2420 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2421 new DownloadsDownloadFunction(), base::StringPrintf(
2422 "[{\"url\": \"%s\"}]", download_url.c_str())));
2423 ASSERT_TRUE(result.get());
2425 ASSERT_TRUE(result->GetAsInteger(&result_id));
2426 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2428 ScopedCancellingItem canceller(item);
2429 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2431 // Wait for the onCreated and onDeterminingFilename events.
2432 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2434 "[{\"danger\": \"safe\","
2435 " \"incognito\": false,"
2437 " \"mime\": \"text/plain\","
2438 " \"paused\": false,"
2439 " \"url\": \"%s\"}]",
2441 download_url.c_str())));
2442 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2445 " \"filename\":\"slow.txt\"}]",
2447 ASSERT_TRUE(item->GetTargetFilePath().empty());
2448 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2450 // Respond to the onDeterminingFilename.
2452 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2453 browser()->profile(),
2458 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2460 EXPECT_EQ("", error);
2462 // The download should complete successfully.
2463 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2467 " \"previous\": \"\","
2468 " \"current\": \"%s\"}}]",
2470 GetFilename("slow.txt").c_str())));
2471 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2475 " \"previous\": \"in_progress\","
2476 " \"current\": \"complete\"}}]",
2480 // Disabled due to cross-platform flakes; http://crbug.com/370531.
2481 IN_PROC_BROWSER_TEST_F(
2482 DownloadExtensionTest,
2483 DISABLED_DownloadExtensionTest_OnDeterminingFilename_Timeout) {
2485 LoadExtension("downloads_split");
2486 AddFilenameDeterminer();
2487 ASSERT_TRUE(StartEmbeddedTestServer());
2488 ASSERT_TRUE(test_server()->Start());
2489 std::string download_url = test_server()->GetURL("slow?0").spec();
2491 ExtensionDownloadsEventRouter::SetDetermineFilenameTimeoutSecondsForTesting(
2494 // Start downloading a file.
2495 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2496 new DownloadsDownloadFunction(), base::StringPrintf(
2497 "[{\"url\": \"%s\"}]", download_url.c_str())));
2498 ASSERT_TRUE(result.get());
2500 ASSERT_TRUE(result->GetAsInteger(&result_id));
2501 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2503 ScopedCancellingItem canceller(item);
2504 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2506 // Wait for the onCreated and onDeterminingFilename events.
2507 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2508 base::StringPrintf("[{\"danger\": \"safe\","
2509 " \"incognito\": false,"
2511 " \"mime\": \"text/plain\","
2512 " \"paused\": false,"
2513 " \"url\": \"%s\"}]",
2515 download_url.c_str())));
2516 ASSERT_TRUE(WaitFor(
2517 downloads::OnDeterminingFilename::kEventName,
2518 base::StringPrintf("[{\"id\": %d,"
2519 " \"filename\":\"slow.txt\"}]",
2521 ASSERT_TRUE(item->GetTargetFilePath().empty());
2522 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2524 // Do not respond to the onDeterminingFilename.
2526 // The download should complete successfully.
2527 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2528 base::StringPrintf("[{\"id\": %d,"
2530 " \"previous\": \"\","
2531 " \"current\": \"%s\"}}]",
2533 GetFilename("slow.txt").c_str())));
2534 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2535 base::StringPrintf("[{\"id\": %d,"
2537 " \"previous\": \"in_progress\","
2538 " \"current\": \"complete\"}}]",
2542 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2543 DownloadExtensionTest_OnDeterminingFilename_Twice) {
2545 LoadExtension("downloads_split");
2546 AddFilenameDeterminer();
2547 ASSERT_TRUE(StartEmbeddedTestServer());
2548 ASSERT_TRUE(test_server()->Start());
2549 std::string download_url = test_server()->GetURL("slow?0").spec();
2551 // Start downloading a file.
2552 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2553 new DownloadsDownloadFunction(), base::StringPrintf(
2554 "[{\"url\": \"%s\"}]", download_url.c_str())));
2555 ASSERT_TRUE(result.get());
2557 ASSERT_TRUE(result->GetAsInteger(&result_id));
2558 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2560 ScopedCancellingItem canceller(item);
2561 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2563 // Wait for the onCreated and onDeterminingFilename events.
2564 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2565 base::StringPrintf("[{\"danger\": \"safe\","
2566 " \"incognito\": false,"
2568 " \"mime\": \"text/plain\","
2569 " \"paused\": false,"
2570 " \"url\": \"%s\"}]",
2572 download_url.c_str())));
2573 ASSERT_TRUE(WaitFor(
2574 downloads::OnDeterminingFilename::kEventName,
2575 base::StringPrintf("[{\"id\": %d,"
2576 " \"filename\":\"slow.txt\"}]",
2578 ASSERT_TRUE(item->GetTargetFilePath().empty());
2579 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2581 // Respond to the onDeterminingFilename.
2583 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2584 browser()->profile(),
2589 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2591 EXPECT_EQ("", error);
2593 // Calling DetermineFilename again should return an error instead of calling
2594 // DownloadTargetDeterminer.
2595 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2596 browser()->profile(),
2600 base::FilePath(FILE_PATH_LITERAL("different")),
2601 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE,
2603 EXPECT_EQ(errors::kTooManyListeners, error);
2605 // The download should complete successfully.
2606 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2607 base::StringPrintf("[{\"id\": %d,"
2609 " \"previous\": \"\","
2610 " \"current\": \"%s\"}}]",
2612 GetFilename("slow.txt").c_str())));
2613 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2614 base::StringPrintf("[{\"id\": %d,"
2616 " \"previous\": \"in_progress\","
2617 " \"current\": \"complete\"}}]",
2621 IN_PROC_BROWSER_TEST_F(
2622 DownloadExtensionTest,
2623 DownloadExtensionTest_OnDeterminingFilename_DangerousOverride) {
2625 LoadExtension("downloads_split");
2626 AddFilenameDeterminer();
2627 ASSERT_TRUE(StartEmbeddedTestServer());
2628 ASSERT_TRUE(test_server()->Start());
2629 std::string download_url = test_server()->GetURL("slow?0").spec();
2631 // Start downloading a file.
2632 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2633 new DownloadsDownloadFunction(), base::StringPrintf(
2634 "[{\"url\": \"%s\"}]", download_url.c_str())));
2635 ASSERT_TRUE(result.get());
2637 ASSERT_TRUE(result->GetAsInteger(&result_id));
2638 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2640 ScopedCancellingItem canceller(item);
2641 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2643 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2645 "[{\"danger\": \"safe\","
2646 " \"incognito\": false,"
2648 " \"mime\": \"text/plain\","
2649 " \"paused\": false,"
2650 " \"url\": \"%s\"}]",
2652 download_url.c_str())));
2653 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2656 " \"filename\":\"slow.txt\"}]",
2658 ASSERT_TRUE(item->GetTargetFilePath().empty());
2659 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2661 // Respond to the onDeterminingFilename.
2663 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2664 browser()->profile(),
2668 base::FilePath(FILE_PATH_LITERAL("overridden.swf")),
2669 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2671 EXPECT_EQ("", error);
2673 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2677 " \"previous\":\"safe\","
2678 " \"current\":\"file\"}}]",
2681 item->ValidateDangerousDownload();
2682 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2686 " \"previous\":\"file\","
2687 " \"current\":\"accepted\"}}]",
2689 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2693 " \"previous\": \"in_progress\","
2694 " \"current\": \"complete\"}}]",
2696 EXPECT_EQ(downloads_directory().AppendASCII("overridden.swf"),
2697 item->GetTargetFilePath());
2700 IN_PROC_BROWSER_TEST_F(
2701 DownloadExtensionTest,
2702 DownloadExtensionTest_OnDeterminingFilename_ReferencesParentInvalid) {
2704 LoadExtension("downloads_split");
2705 AddFilenameDeterminer();
2706 ASSERT_TRUE(StartEmbeddedTestServer());
2707 ASSERT_TRUE(test_server()->Start());
2708 std::string download_url = test_server()->GetURL("slow?0").spec();
2710 // Start downloading a file.
2711 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2712 new DownloadsDownloadFunction(), base::StringPrintf(
2713 "[{\"url\": \"%s\"}]", download_url.c_str())));
2714 ASSERT_TRUE(result.get());
2716 ASSERT_TRUE(result->GetAsInteger(&result_id));
2717 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2719 ScopedCancellingItem canceller(item);
2720 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2722 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2724 "[{\"danger\": \"safe\","
2725 " \"incognito\": false,"
2727 " \"mime\": \"text/plain\","
2728 " \"paused\": false,"
2729 " \"url\": \"%s\"}]",
2731 download_url.c_str())));
2732 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
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("sneaky/../../sneaky.txt")),
2748 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2750 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2751 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2755 " \"previous\": \"\","
2756 " \"current\": \"%s\"}}]",
2758 GetFilename("slow.txt").c_str())));
2759 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2763 " \"previous\": \"in_progress\","
2764 " \"current\": \"complete\"}}]",
2768 IN_PROC_BROWSER_TEST_F(
2769 DownloadExtensionTest,
2770 DownloadExtensionTest_OnDeterminingFilename_IllegalFilename) {
2772 LoadExtension("downloads_split");
2773 AddFilenameDeterminer();
2774 ASSERT_TRUE(StartEmbeddedTestServer());
2775 ASSERT_TRUE(test_server()->Start());
2776 std::string download_url = test_server()->GetURL("slow?0").spec();
2778 // Start downloading a file.
2779 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2780 new DownloadsDownloadFunction(), base::StringPrintf(
2781 "[{\"url\": \"%s\"}]", download_url.c_str())));
2782 ASSERT_TRUE(result.get());
2784 ASSERT_TRUE(result->GetAsInteger(&result_id));
2785 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2787 ScopedCancellingItem canceller(item);
2788 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2790 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2792 "[{\"danger\": \"safe\","
2793 " \"incognito\": false,"
2795 " \"mime\": \"text/plain\","
2796 " \"paused\": false,"
2797 " \"url\": \"%s\"}]",
2799 download_url.c_str())));
2800 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2803 " \"filename\":\"slow.txt\"}]",
2805 ASSERT_TRUE(item->GetTargetFilePath().empty());
2806 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2808 // Respond to the onDeterminingFilename.
2810 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2811 browser()->profile(),
2815 base::FilePath(FILE_PATH_LITERAL("<")),
2816 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2818 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2819 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2823 " \"previous\": \"\","
2824 " \"current\": \"%s\"}}]",
2826 GetFilename("slow.txt").c_str())));
2827 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2831 " \"previous\": \"in_progress\","
2832 " \"current\": \"complete\"}}]",
2836 IN_PROC_BROWSER_TEST_F(
2837 DownloadExtensionTest,
2838 DownloadExtensionTest_OnDeterminingFilename_IllegalFilenameExtension) {
2840 LoadExtension("downloads_split");
2841 AddFilenameDeterminer();
2842 ASSERT_TRUE(StartEmbeddedTestServer());
2843 ASSERT_TRUE(test_server()->Start());
2844 std::string download_url = test_server()->GetURL("slow?0").spec();
2846 // Start downloading a file.
2847 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2848 new DownloadsDownloadFunction(), base::StringPrintf(
2849 "[{\"url\": \"%s\"}]", download_url.c_str())));
2850 ASSERT_TRUE(result.get());
2852 ASSERT_TRUE(result->GetAsInteger(&result_id));
2853 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2855 ScopedCancellingItem canceller(item);
2856 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2858 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2860 "[{\"danger\": \"safe\","
2861 " \"incognito\": false,"
2863 " \"mime\": \"text/plain\","
2864 " \"paused\": false,"
2865 " \"url\": \"%s\"}]",
2867 download_url.c_str())));
2868 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2871 " \"filename\":\"slow.txt\"}]",
2873 ASSERT_TRUE(item->GetTargetFilePath().empty());
2874 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2876 // Respond to the onDeterminingFilename.
2878 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2879 browser()->profile(),
2883 base::FilePath(FILE_PATH_LITERAL(
2884 "My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}/foo")),
2885 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2887 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2888 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2892 " \"previous\": \"\","
2893 " \"current\": \"%s\"}}]",
2895 GetFilename("slow.txt").c_str())));
2896 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2900 " \"previous\": \"in_progress\","
2901 " \"current\": \"complete\"}}]",
2905 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2906 DISABLED_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2908 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2909 DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2911 IN_PROC_BROWSER_TEST_F(
2912 DownloadExtensionTest,
2913 MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename) {
2915 LoadExtension("downloads_split");
2916 AddFilenameDeterminer();
2917 ASSERT_TRUE(StartEmbeddedTestServer());
2918 ASSERT_TRUE(test_server()->Start());
2919 std::string download_url = test_server()->GetURL("slow?0").spec();
2921 // Start downloading a file.
2922 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2923 new DownloadsDownloadFunction(), base::StringPrintf(
2924 "[{\"url\": \"%s\"}]", download_url.c_str())));
2925 ASSERT_TRUE(result.get());
2927 ASSERT_TRUE(result->GetAsInteger(&result_id));
2928 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2930 ScopedCancellingItem canceller(item);
2931 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2933 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2935 "[{\"danger\": \"safe\","
2936 " \"incognito\": false,"
2938 " \"mime\": \"text/plain\","
2939 " \"paused\": false,"
2940 " \"url\": \"%s\"}]",
2942 download_url.c_str())));
2943 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2946 " \"filename\":\"slow.txt\"}]",
2948 ASSERT_TRUE(item->GetTargetFilePath().empty());
2949 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2951 // Respond to the onDeterminingFilename.
2953 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2954 browser()->profile(),
2958 base::FilePath(FILE_PATH_LITERAL("con.foo")),
2959 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2961 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2962 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2966 " \"previous\": \"\","
2967 " \"current\": \"%s\"}}]",
2969 GetFilename("slow.txt").c_str())));
2970 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2974 " \"previous\": \"in_progress\","
2975 " \"current\": \"complete\"}}]",
2979 IN_PROC_BROWSER_TEST_F(
2980 DownloadExtensionTest,
2981 DownloadExtensionTest_OnDeterminingFilename_CurDirInvalid) {
2983 LoadExtension("downloads_split");
2984 AddFilenameDeterminer();
2985 ASSERT_TRUE(StartEmbeddedTestServer());
2986 ASSERT_TRUE(test_server()->Start());
2987 std::string download_url = test_server()->GetURL("slow?0").spec();
2989 // Start downloading a file.
2990 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2991 new DownloadsDownloadFunction(), base::StringPrintf(
2992 "[{\"url\": \"%s\"}]", download_url.c_str())));
2993 ASSERT_TRUE(result.get());
2995 ASSERT_TRUE(result->GetAsInteger(&result_id));
2996 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2998 ScopedCancellingItem canceller(item);
2999 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3001 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3003 "[{\"danger\": \"safe\","
3004 " \"incognito\": false,"
3006 " \"mime\": \"text/plain\","
3007 " \"paused\": false,"
3008 " \"url\": \"%s\"}]",
3010 download_url.c_str())));
3011 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3014 " \"filename\":\"slow.txt\"}]",
3016 ASSERT_TRUE(item->GetTargetFilePath().empty());
3017 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3019 // Respond to the onDeterminingFilename.
3021 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3022 browser()->profile(),
3026 base::FilePath(FILE_PATH_LITERAL(".")),
3027 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3029 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
3030 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3034 " \"previous\": \"\","
3035 " \"current\": \"%s\"}}]",
3037 GetFilename("slow.txt").c_str())));
3038 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3042 " \"previous\": \"in_progress\","
3043 " \"current\": \"complete\"}}]",
3047 IN_PROC_BROWSER_TEST_F(
3048 DownloadExtensionTest,
3049 DownloadExtensionTest_OnDeterminingFilename_ParentDirInvalid) {
3050 ASSERT_TRUE(StartEmbeddedTestServer());
3051 ASSERT_TRUE(test_server()->Start());
3053 LoadExtension("downloads_split");
3054 AddFilenameDeterminer();
3055 std::string download_url = test_server()->GetURL("slow?0").spec();
3057 // Start downloading a file.
3058 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3059 new DownloadsDownloadFunction(), base::StringPrintf(
3060 "[{\"url\": \"%s\"}]", download_url.c_str())));
3061 ASSERT_TRUE(result.get());
3063 ASSERT_TRUE(result->GetAsInteger(&result_id));
3064 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3066 ScopedCancellingItem canceller(item);
3067 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3069 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3071 "[{\"danger\": \"safe\","
3072 " \"incognito\": false,"
3074 " \"mime\": \"text/plain\","
3075 " \"paused\": false,"
3076 " \"url\": \"%s\"}]",
3078 download_url.c_str())));
3079 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3082 " \"filename\":\"slow.txt\"}]",
3084 ASSERT_TRUE(item->GetTargetFilePath().empty());
3085 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3087 // Respond to the onDeterminingFilename.
3089 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3090 browser()->profile(),
3094 base::FilePath(FILE_PATH_LITERAL("..")),
3095 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3097 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
3098 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3102 " \"previous\": \"\","
3103 " \"current\": \"%s\"}}]",
3105 GetFilename("slow.txt").c_str())));
3106 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3110 " \"previous\": \"in_progress\","
3111 " \"current\": \"complete\"}}]",
3115 IN_PROC_BROWSER_TEST_F(
3116 DownloadExtensionTest,
3117 DownloadExtensionTest_OnDeterminingFilename_AbsPathInvalid) {
3119 LoadExtension("downloads_split");
3120 AddFilenameDeterminer();
3121 ASSERT_TRUE(StartEmbeddedTestServer());
3122 ASSERT_TRUE(test_server()->Start());
3123 std::string download_url = test_server()->GetURL("slow?0").spec();
3125 // Start downloading a file.
3126 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3127 new DownloadsDownloadFunction(), base::StringPrintf(
3128 "[{\"url\": \"%s\"}]", download_url.c_str())));
3129 ASSERT_TRUE(result.get());
3131 ASSERT_TRUE(result->GetAsInteger(&result_id));
3132 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3134 ScopedCancellingItem canceller(item);
3135 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3137 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3139 "[{\"danger\": \"safe\","
3140 " \"incognito\": false,"
3142 " \"mime\": \"text/plain\","
3143 " \"paused\": false,"
3144 " \"url\": \"%s\"}]",
3146 download_url.c_str())));
3147 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3150 " \"filename\":\"slow.txt\"}]",
3152 ASSERT_TRUE(item->GetTargetFilePath().empty());
3153 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3155 // Respond to the onDeterminingFilename. Absolute paths should be rejected.
3157 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3158 browser()->profile(),
3162 downloads_directory().Append(FILE_PATH_LITERAL("sneaky.txt")),
3163 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3165 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
3167 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3171 " \"previous\": \"\","
3172 " \"current\": \"%s\"}}]",
3174 GetFilename("slow.txt").c_str())));
3175 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3179 " \"previous\": \"in_progress\","
3180 " \"current\": \"complete\"}}]",
3184 IN_PROC_BROWSER_TEST_F(
3185 DownloadExtensionTest,
3186 DownloadExtensionTest_OnDeterminingFilename_EmptyBasenameInvalid) {
3188 LoadExtension("downloads_split");
3189 AddFilenameDeterminer();
3190 ASSERT_TRUE(StartEmbeddedTestServer());
3191 ASSERT_TRUE(test_server()->Start());
3192 std::string download_url = test_server()->GetURL("slow?0").spec();
3194 // Start downloading a file.
3195 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3196 new DownloadsDownloadFunction(), base::StringPrintf(
3197 "[{\"url\": \"%s\"}]", download_url.c_str())));
3198 ASSERT_TRUE(result.get());
3200 ASSERT_TRUE(result->GetAsInteger(&result_id));
3201 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3203 ScopedCancellingItem canceller(item);
3204 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3206 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3208 "[{\"danger\": \"safe\","
3209 " \"incognito\": false,"
3211 " \"mime\": \"text/plain\","
3212 " \"paused\": false,"
3213 " \"url\": \"%s\"}]",
3215 download_url.c_str())));
3216 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3219 " \"filename\":\"slow.txt\"}]",
3221 ASSERT_TRUE(item->GetTargetFilePath().empty());
3222 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3224 // Respond to the onDeterminingFilename. Empty basenames should be rejected.
3226 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3227 browser()->profile(),
3231 base::FilePath(FILE_PATH_LITERAL("foo/")),
3232 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3234 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
3236 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3240 " \"previous\": \"\","
3241 " \"current\": \"%s\"}}]",
3243 GetFilename("slow.txt").c_str())));
3244 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3248 " \"previous\": \"in_progress\","
3249 " \"current\": \"complete\"}}]",
3253 // conflictAction may be specified without filename.
3254 IN_PROC_BROWSER_TEST_F(
3255 DownloadExtensionTest,
3256 DownloadExtensionTest_OnDeterminingFilename_Overwrite) {
3258 LoadExtension("downloads_split");
3259 AddFilenameDeterminer();
3260 ASSERT_TRUE(StartEmbeddedTestServer());
3261 ASSERT_TRUE(test_server()->Start());
3262 std::string download_url = test_server()->GetURL("slow?0").spec();
3264 // Start downloading a file.
3265 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3266 new DownloadsDownloadFunction(), base::StringPrintf(
3267 "[{\"url\": \"%s\"}]", download_url.c_str())));
3268 ASSERT_TRUE(result.get());
3270 ASSERT_TRUE(result->GetAsInteger(&result_id));
3271 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3273 ScopedCancellingItem canceller(item);
3274 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3275 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3277 "[{\"danger\": \"safe\","
3278 " \"incognito\": false,"
3280 " \"mime\": \"text/plain\","
3281 " \"paused\": false,"
3282 " \"url\": \"%s\"}]",
3284 download_url.c_str())));
3285 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3288 " \"filename\":\"slow.txt\"}]",
3290 ASSERT_TRUE(item->GetTargetFilePath().empty());
3291 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3293 // Respond to the onDeterminingFilename.
3295 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3296 browser()->profile(),
3301 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3303 EXPECT_EQ("", error);
3305 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3309 " \"previous\": \"\","
3310 " \"current\": \"%s\"}}]",
3312 GetFilename("slow.txt").c_str())));
3313 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3317 " \"previous\": \"in_progress\","
3318 " \"current\": \"complete\"}}]",
3321 // Start downloading a file.
3322 result.reset(RunFunctionAndReturnResult(
3323 new DownloadsDownloadFunction(), base::StringPrintf(
3324 "[{\"url\": \"%s\"}]", download_url.c_str())));
3325 ASSERT_TRUE(result.get());
3327 ASSERT_TRUE(result->GetAsInteger(&result_id));
3328 item = GetCurrentManager()->GetDownload(result_id);
3330 ScopedCancellingItem canceller2(item);
3331 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3333 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3335 "[{\"danger\": \"safe\","
3336 " \"incognito\": false,"
3338 " \"mime\": \"text/plain\","
3339 " \"paused\": false,"
3340 " \"url\": \"%s\"}]",
3342 download_url.c_str())));
3343 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3346 " \"filename\":\"slow.txt\"}]",
3348 ASSERT_TRUE(item->GetTargetFilePath().empty());
3349 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3351 // Respond to the onDeterminingFilename.
3352 // Also test that DetermineFilename allows (chrome) extensions to set
3353 // filenames without (filename) extensions. (Don't ask about v8 extensions or
3354 // python extensions or kernel extensions or firefox extensions...)
3356 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3357 browser()->profile(),
3362 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE,
3364 EXPECT_EQ("", error);
3366 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3370 " \"previous\": \"\","
3371 " \"current\": \"%s\"}}]",
3373 GetFilename("slow.txt").c_str())));
3374 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3378 " \"previous\": \"in_progress\","
3379 " \"current\": \"complete\"}}]",
3383 IN_PROC_BROWSER_TEST_F(
3384 DownloadExtensionTest,
3385 DownloadExtensionTest_OnDeterminingFilename_Override) {
3387 LoadExtension("downloads_split");
3388 AddFilenameDeterminer();
3389 ASSERT_TRUE(StartEmbeddedTestServer());
3390 ASSERT_TRUE(test_server()->Start());
3391 std::string download_url = test_server()->GetURL("slow?0").spec();
3393 // Start downloading a file.
3394 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3395 new DownloadsDownloadFunction(), base::StringPrintf(
3396 "[{\"url\": \"%s\"}]", download_url.c_str())));
3397 ASSERT_TRUE(result.get());
3399 ASSERT_TRUE(result->GetAsInteger(&result_id));
3400 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3402 ScopedCancellingItem canceller(item);
3403 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3404 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3406 "[{\"danger\": \"safe\","
3407 " \"incognito\": false,"
3409 " \"mime\": \"text/plain\","
3410 " \"paused\": false,"
3411 " \"url\": \"%s\"}]",
3413 download_url.c_str())));
3414 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3417 " \"filename\":\"slow.txt\"}]",
3419 ASSERT_TRUE(item->GetTargetFilePath().empty());
3420 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3422 // Respond to the onDeterminingFilename.
3424 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3425 browser()->profile(),
3430 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3432 EXPECT_EQ("", error);
3434 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3438 " \"previous\": \"\","
3439 " \"current\": \"%s\"}}]",
3441 GetFilename("slow.txt").c_str())));
3442 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3446 " \"previous\": \"in_progress\","
3447 " \"current\": \"complete\"}}]",
3450 // Start downloading a file.
3451 result.reset(RunFunctionAndReturnResult(
3452 new DownloadsDownloadFunction(), base::StringPrintf(
3453 "[{\"url\": \"%s\"}]", download_url.c_str())));
3454 ASSERT_TRUE(result.get());
3456 ASSERT_TRUE(result->GetAsInteger(&result_id));
3457 item = GetCurrentManager()->GetDownload(result_id);
3459 ScopedCancellingItem canceller2(item);
3460 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3462 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3464 "[{\"danger\": \"safe\","
3465 " \"incognito\": false,"
3467 " \"mime\": \"text/plain\","
3468 " \"paused\": false,"
3469 " \"url\": \"%s\"}]",
3471 download_url.c_str())));
3472 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3475 " \"filename\":\"slow.txt\"}]",
3477 ASSERT_TRUE(item->GetTargetFilePath().empty());
3478 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3480 // Respond to the onDeterminingFilename.
3481 // Also test that DetermineFilename allows (chrome) extensions to set
3482 // filenames without (filename) extensions. (Don't ask about v8 extensions or
3483 // python extensions or kernel extensions or firefox extensions...)
3485 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3486 browser()->profile(),
3490 base::FilePath(FILE_PATH_LITERAL("foo")),
3491 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE,
3493 EXPECT_EQ("", error);
3495 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3499 " \"previous\": \"\","
3500 " \"current\": \"%s\"}}]",
3502 GetFilename("foo").c_str())));
3503 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3507 " \"previous\": \"in_progress\","
3508 " \"current\": \"complete\"}}]",
3512 // TODO test precedence rules: install_time
3514 #if defined(OS_MACOSX)
3515 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer \
3516 DISABLED_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer
3518 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer \
3519 DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer
3521 IN_PROC_BROWSER_TEST_F(
3522 DownloadExtensionTest,
3523 MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer) {
3524 ASSERT_TRUE(StartEmbeddedTestServer());
3525 ASSERT_TRUE(test_server()->Start());
3527 LoadExtension("downloads_split");
3528 content::RenderProcessHost* host = AddFilenameDeterminer();
3529 std::string download_url = test_server()->GetURL("slow?0").spec();
3531 // Start downloading a file.
3532 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3533 new DownloadsDownloadFunction(), base::StringPrintf(
3534 "[{\"url\": \"%s\"}]", download_url.c_str())));
3535 ASSERT_TRUE(result.get());
3537 ASSERT_TRUE(result->GetAsInteger(&result_id));
3538 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3540 ScopedCancellingItem canceller(item);
3541 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3543 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3545 "[{\"danger\": \"safe\","
3546 " \"incognito\": false,"
3548 " \"mime\": \"text/plain\","
3549 " \"paused\": false,"
3550 " \"url\": \"%s\"}]",
3552 download_url.c_str())));
3553 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3556 " \"filename\":\"slow.txt\"}]",
3558 ASSERT_TRUE(item->GetTargetFilePath().empty());
3559 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3561 // Remove a determiner while waiting for it.
3562 RemoveFilenameDeterminer(host);
3564 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3568 " \"previous\": \"in_progress\","
3569 " \"current\": \"complete\"}}]",
3573 IN_PROC_BROWSER_TEST_F(
3574 DownloadExtensionTest,
3575 DownloadExtensionTest_OnDeterminingFilename_IncognitoSplit) {
3576 LoadExtension("downloads_split");
3577 ASSERT_TRUE(StartEmbeddedTestServer());
3578 ASSERT_TRUE(test_server()->Start());
3579 std::string download_url = test_server()->GetURL("slow?0").spec();
3582 AddFilenameDeterminer();
3585 AddFilenameDeterminer();
3587 // Start an on-record download.
3589 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3590 new DownloadsDownloadFunction(), base::StringPrintf(
3591 "[{\"url\": \"%s\"}]", download_url.c_str())));
3592 ASSERT_TRUE(result.get());
3594 ASSERT_TRUE(result->GetAsInteger(&result_id));
3595 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3597 ScopedCancellingItem canceller(item);
3598 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3600 // Wait for the onCreated and onDeterminingFilename events.
3601 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3603 "[{\"danger\": \"safe\","
3604 " \"incognito\": false,"
3606 " \"mime\": \"text/plain\","
3607 " \"paused\": false,"
3608 " \"url\": \"%s\"}]",
3610 download_url.c_str())));
3611 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3614 " \"incognito\": false,"
3615 " \"filename\":\"slow.txt\"}]",
3617 ASSERT_TRUE(item->GetTargetFilePath().empty());
3618 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3620 // Respond to the onDeterminingFilename events.
3622 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3623 current_browser()->profile(),
3627 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3628 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3630 EXPECT_EQ("", error);
3632 // The download should complete successfully.
3633 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3637 " \"previous\": \"\","
3638 " \"current\": \"%s\"}}]",
3640 GetFilename("42.txt").c_str())));
3641 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3645 " \"previous\": \"in_progress\","
3646 " \"current\": \"complete\"}}]",
3649 // Start an incognito download for comparison.
3651 result.reset(RunFunctionAndReturnResult(
3652 new DownloadsDownloadFunction(), base::StringPrintf(
3653 "[{\"url\": \"%s\"}]", download_url.c_str())));
3654 ASSERT_TRUE(result.get());
3656 ASSERT_TRUE(result->GetAsInteger(&result_id));
3657 item = GetCurrentManager()->GetDownload(result_id);
3659 ScopedCancellingItem canceller2(item);
3660 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3662 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3664 "[{\"danger\": \"safe\","
3665 " \"incognito\": true,"
3667 " \"mime\": \"text/plain\","
3668 " \"paused\": false,"
3669 " \"url\": \"%s\"}]",
3671 download_url.c_str())));
3672 // On-Record renderers should not see events for off-record items.
3673 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3676 " \"incognito\": true,"
3677 " \"filename\":\"slow.txt\"}]",
3679 ASSERT_TRUE(item->GetTargetFilePath().empty());
3680 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3682 // Respond to the onDeterminingFilename.
3684 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3685 current_browser()->profile(),
3689 base::FilePath(FILE_PATH_LITERAL("5.txt")),
3690 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3692 EXPECT_EQ("", error);
3694 // The download should complete successfully.
3695 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3699 " \"previous\": \"\","
3700 " \"current\": \"%s\"}}]",
3702 GetFilename("5.txt").c_str())));
3703 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3707 " \"previous\": \"in_progress\","
3708 " \"current\": \"complete\"}}]",
3712 IN_PROC_BROWSER_TEST_F(
3713 DownloadExtensionTest,
3714 DownloadExtensionTest_OnDeterminingFilename_IncognitoSpanning) {
3715 LoadExtension("downloads_spanning");
3716 ASSERT_TRUE(StartEmbeddedTestServer());
3717 ASSERT_TRUE(test_server()->Start());
3718 std::string download_url = test_server()->GetURL("slow?0").spec();
3721 AddFilenameDeterminer();
3723 // There is a single extension renderer that sees both on-record and
3724 // off-record events. The extension functions see the on-record profile with
3725 // include_incognito=true.
3727 // Start an on-record download.
3729 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3730 new DownloadsDownloadFunction(), base::StringPrintf(
3731 "[{\"url\": \"%s\"}]", download_url.c_str())));
3732 ASSERT_TRUE(result.get());
3734 ASSERT_TRUE(result->GetAsInteger(&result_id));
3735 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3737 ScopedCancellingItem canceller(item);
3738 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3740 // Wait for the onCreated and onDeterminingFilename events.
3741 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3743 "[{\"danger\": \"safe\","
3744 " \"incognito\": false,"
3746 " \"mime\": \"text/plain\","
3747 " \"paused\": false,"
3748 " \"url\": \"%s\"}]",
3750 download_url.c_str())));
3751 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3754 " \"incognito\": false,"
3755 " \"filename\":\"slow.txt\"}]",
3757 ASSERT_TRUE(item->GetTargetFilePath().empty());
3758 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3760 // Respond to the onDeterminingFilename events.
3762 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3763 current_browser()->profile(),
3767 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3768 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3770 EXPECT_EQ("", error);
3772 // The download should complete successfully.
3773 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3777 " \"previous\": \"\","
3778 " \"current\": \"%s\"}}]",
3780 GetFilename("42.txt").c_str())));
3781 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3785 " \"previous\": \"in_progress\","
3786 " \"current\": \"complete\"}}]",
3789 // Start an incognito download for comparison.
3791 result.reset(RunFunctionAndReturnResult(
3792 new DownloadsDownloadFunction(), base::StringPrintf(
3793 "[{\"url\": \"%s\"}]", download_url.c_str())));
3794 ASSERT_TRUE(result.get());
3796 ASSERT_TRUE(result->GetAsInteger(&result_id));
3797 item = GetCurrentManager()->GetDownload(result_id);
3799 ScopedCancellingItem canceller2(item);
3800 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3802 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3804 "[{\"danger\": \"safe\","
3805 " \"incognito\": true,"
3807 " \"mime\": \"text/plain\","
3808 " \"paused\": false,"
3809 " \"url\": \"%s\"}]",
3811 download_url.c_str())));
3812 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3815 " \"incognito\": true,"
3816 " \"filename\":\"slow.txt\"}]",
3818 ASSERT_TRUE(item->GetTargetFilePath().empty());
3819 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3821 // Respond to the onDeterminingFilename.
3823 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3824 current_browser()->profile(),
3828 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3829 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3831 EXPECT_EQ("", error);
3833 // The download should complete successfully.
3834 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3838 " \"previous\": \"\","
3839 " \"current\": \"%s\"}}]",
3841 GetFilename("42 (1).txt").c_str())));
3842 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3846 " \"previous\": \"in_progress\","
3847 " \"current\": \"complete\"}}]",
3852 // This test is very flaky on Win XP and Aura. http://crbug.com/248438
3853 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3854 DISABLED_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3856 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3857 DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3860 // Test download interruption while extensions determining filename. Should not
3861 // re-dispatch onDeterminingFilename.
3862 IN_PROC_BROWSER_TEST_F(
3863 DownloadExtensionTest,
3864 MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume) {
3865 CommandLine::ForCurrentProcess()->AppendSwitch(
3866 switches::kEnableDownloadResumption);
3867 LoadExtension("downloads_split");
3868 ASSERT_TRUE(StartEmbeddedTestServer());
3869 ASSERT_TRUE(test_server()->Start());
3871 content::RenderProcessHost* host = AddFilenameDeterminer();
3873 // Start a download.
3874 DownloadItem* item = NULL;
3876 DownloadManager* manager = GetCurrentManager();
3877 scoped_ptr<content::DownloadTestObserver> observer(
3878 new JustInProgressDownloadObserver(manager, 1));
3879 ASSERT_EQ(0, manager->InProgressCount());
3880 ASSERT_EQ(0, manager->NonMaliciousInProgressCount());
3881 // Tabs created just for a download are automatically closed, invalidating
3882 // the download's WebContents. Downloads without WebContents cannot be
3883 // resumed. http://crbug.com/225901
3884 ui_test_utils::NavigateToURLWithDisposition(
3886 GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl),
3888 ui_test_utils::BROWSER_TEST_NONE);
3889 observer->WaitForFinished();
3890 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
3891 DownloadManager::DownloadVector items;
3892 manager->GetAllDownloads(&items);
3893 for (DownloadManager::DownloadVector::iterator iter = items.begin();
3894 iter != items.end(); ++iter) {
3895 if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) {
3896 // There should be only one IN_PROGRESS item.
3897 EXPECT_EQ(NULL, item);
3903 ScopedCancellingItem canceller(item);
3905 // Wait for the onCreated and onDeterminingFilename event.
3906 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3908 "[{\"danger\": \"safe\","
3909 " \"incognito\": false,"
3911 " \"mime\": \"application/octet-stream\","
3912 " \"paused\": false}]",
3914 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3917 " \"incognito\": false,"
3918 " \"filename\":\"download-unknown-size\"}]",
3920 ASSERT_TRUE(item->GetTargetFilePath().empty());
3921 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3924 ui_test_utils::NavigateToURLWithDisposition(
3926 GURL(URLRequestSlowDownloadJob::kErrorDownloadUrl),
3928 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3930 // Errors caught before filename determination are delayed until after
3931 // filename determination.
3933 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3934 current_browser()->profile(),
3938 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3939 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3942 EXPECT_EQ("", error);
3943 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3947 " \"previous\": \"\","
3948 " \"current\": \"%s\"}}]",
3950 GetFilename("42.txt").c_str())));
3952 content::DownloadUpdatedObserver interrupted(item, base::Bind(
3953 ItemIsInterrupted));
3954 ASSERT_TRUE(interrupted.WaitForEvent());
3955 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3958 " \"error\":{\"current\":\"NETWORK_FAILED\"},"
3960 " \"previous\":\"in_progress\","
3961 " \"current\":\"interrupted\"}}]",
3965 // Downloads that are restarted on resumption trigger another download target
3967 RemoveFilenameDeterminer(host);
3970 // Errors caught before filename determination is complete are delayed until
3971 // after filename determination so that, on resumption, filename determination
3972 // does not need to be re-done. So, there will not be a second
3973 // onDeterminingFilename event.
3975 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3978 " \"error\":{\"previous\":\"NETWORK_FAILED\"},"
3980 " \"previous\":\"interrupted\","
3981 " \"current\":\"in_progress\"}}]",
3985 FinishPendingSlowDownloads();
3987 // The download should complete successfully.
3988 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3992 " \"previous\": \"in_progress\","
3993 " \"current\": \"complete\"}}]",
3997 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
3998 DownloadExtensionTest_SetShelfEnabled) {
3999 LoadExtension("downloads_split");
4000 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[false]"));
4001 EXPECT_FALSE(DownloadServiceFactory::GetForBrowserContext(
4002 browser()->profile())->IsShelfEnabled());
4003 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[true]"));
4004 EXPECT_TRUE(DownloadServiceFactory::GetForBrowserContext(
4005 browser()->profile())->IsShelfEnabled());
4006 // TODO(benjhayden) Test that existing shelves are hidden.
4007 // TODO(benjhayden) Test multiple extensions.
4008 // TODO(benjhayden) Test disabling extensions.
4009 // TODO(benjhayden) Test that browsers associated with other profiles are not
4011 // TODO(benjhayden) Test incognito.
4014 // TODO(benjhayden) Figure out why DisableExtension() does not fire
4015 // OnListenerRemoved.
4017 // TODO(benjhayden) Test that the shelf is shown for download() both with and
4018 // without a WebContents.
4020 void OnDangerPromptCreated(DownloadDangerPrompt* prompt) {
4021 prompt->InvokeActionForTesting(DownloadDangerPrompt::ACCEPT);
4024 #if defined(OS_MACOSX)
4025 // Flakily triggers and assert on Mac.
4026 // http://crbug.com/180759
4027 #define MAYBE_DownloadExtensionTest_AcceptDanger DISABLED_DownloadExtensionTest_AcceptDanger
4029 #define MAYBE_DownloadExtensionTest_AcceptDanger DownloadExtensionTest_AcceptDanger
4031 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
4032 MAYBE_DownloadExtensionTest_AcceptDanger) {
4033 // Download a file that will be marked dangerous; click the browser action
4034 // button; the browser action poup will call acceptDanger(); when the
4035 // DownloadDangerPrompt is created, pretend that the user clicks the Accept
4036 // button; wait until the download completes.
4037 LoadExtension("downloads_split");
4038 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
4039 new DownloadsDownloadFunction(),
4040 "[{\"url\": \"data:,\", \"filename\": \"dangerous.swf\"}]"));
4041 ASSERT_TRUE(result.get());
4043 ASSERT_TRUE(result->GetAsInteger(&result_id));
4044 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
4046 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
4050 " \"previous\": \"safe\","
4051 " \"current\": \"file\"}}]",
4053 ASSERT_TRUE(item->IsDangerous());
4054 ScopedCancellingItem canceller(item);
4055 scoped_ptr<content::DownloadTestObserver> observer(
4056 new content::DownloadTestObserverTerminal(
4057 GetCurrentManager(), 1,
4058 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_IGNORE));
4059 DownloadsAcceptDangerFunction::OnPromptCreatedCallback callback =
4060 base::Bind(&OnDangerPromptCreated);
4061 DownloadsAcceptDangerFunction::OnPromptCreatedForTesting(
4063 BrowserActionTestUtil(browser()).Press(0);
4064 observer->WaitForFinished();
4067 class DownloadsApiTest : public ExtensionApiTest {
4069 DownloadsApiTest() {}
4070 ~DownloadsApiTest() override {}
4073 DISALLOW_COPY_AND_ASSIGN(DownloadsApiTest);
4077 IN_PROC_BROWSER_TEST_F(DownloadsApiTest, DownloadsApiTest) {
4078 ASSERT_TRUE(RunExtensionTest("downloads")) << message_;
4081 TEST(DownloadInterruptReasonEnumsSynced,
4082 DownloadInterruptReasonEnumsSynced) {
4083 #define INTERRUPT_REASON(name, value) \
4084 EXPECT_EQ(InterruptReasonContentToExtension( \
4085 content::DOWNLOAD_INTERRUPT_REASON_##name), \
4086 downloads::INTERRUPT_REASON_##name); \
4088 InterruptReasonExtensionToContent(downloads::INTERRUPT_REASON_##name), \
4089 content::DOWNLOAD_INTERRUPT_REASON_##name);
4090 #include "content/public/browser/download_interrupt_reason_values.h" // NOLINT
4091 #undef INTERRUPT_REASON
4094 TEST(ExtensionDetermineDownloadFilenameInternal,
4095 ExtensionDetermineDownloadFilenameInternal) {
4096 std::string winner_id;
4097 base::FilePath filename;
4098 downloads::FilenameConflictAction conflict_action =
4099 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY;
4100 WarningSet warnings;
4102 // Empty incumbent determiner
4104 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4105 base::FilePath(FILE_PATH_LITERAL("a")),
4106 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE,
4115 EXPECT_EQ("suggester", winner_id);
4116 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename.value());
4117 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_OVERWRITE, conflict_action);
4118 EXPECT_TRUE(warnings.empty());
4122 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4123 base::FilePath(FILE_PATH_LITERAL("b")),
4124 downloads::FILENAME_CONFLICT_ACTION_PROMPT,
4126 base::Time::Now() - base::TimeDelta::FromDays(1),
4133 EXPECT_EQ("incumbent", winner_id);
4134 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename.value());
4135 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_OVERWRITE, conflict_action);
4136 EXPECT_FALSE(warnings.empty());
4137 EXPECT_EQ(Warning::kDownloadFilenameConflict,
4138 warnings.begin()->warning_type());
4139 EXPECT_EQ("suggester", warnings.begin()->extension_id());
4143 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4144 base::FilePath(FILE_PATH_LITERAL("b")),
4145 downloads::FILENAME_CONFLICT_ACTION_PROMPT,
4149 base::Time::Now() - base::TimeDelta::FromDays(1),
4154 EXPECT_EQ("suggester", winner_id);
4155 EXPECT_EQ(FILE_PATH_LITERAL("b"), filename.value());
4156 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_PROMPT, conflict_action);
4157 EXPECT_FALSE(warnings.empty());
4158 EXPECT_EQ(Warning::kDownloadFilenameConflict,
4159 warnings.begin()->warning_type());
4160 EXPECT_EQ("incumbent", warnings.begin()->extension_id());
4163 } // namespace extensions
4165 #endif // http://crbug.com/3061144