1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Disable everything on windows only. http://crbug.com/306144
10 #include "base/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/json/json_reader.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/stl_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/synchronization/waitable_event.h"
18 #include "chrome/browser/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/common/page_transition_types.h"
43 #include "content/public/test/download_test_observer.h"
44 #include "content/test/net/url_request_slow_download_job.h"
45 #include "extensions/browser/event_router.h"
46 #include "extensions/browser/notification_types.h"
47 #include "net/base/data_url.h"
48 #include "net/base/net_util.h"
49 #include "net/url_request/url_request.h"
50 #include "net/url_request/url_request_context.h"
51 #include "net/url_request/url_request_job.h"
52 #include "net/url_request/url_request_job_factory.h"
53 #include "net/url_request/url_request_job_factory_impl.h"
54 #include "webkit/browser/fileapi/file_system_context.h"
55 #include "webkit/browser/fileapi/file_system_operation_runner.h"
56 #include "webkit/browser/fileapi/file_system_url.h"
58 using content::BrowserContext;
59 using content::BrowserThread;
60 using content::DownloadItem;
61 using content::DownloadManager;
62 using content::URLRequestSlowDownloadJob;
64 namespace errors = download_extension_errors;
66 namespace 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 virtual ~DownloadsEventsListener() {
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 virtual 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 content::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 content::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 virtual 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 content::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 virtual ~MockIconExtractorImpl() {}
622 virtual 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(fileapi::FileSystemContext* context,
703 const fileapi::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 fileapi::FileSystemContext* context,
739 const fileapi::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 virtual ~JustInProgressDownloadObserver() {}
764 virtual 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* 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::kInvalidHeader,
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());
1621 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1622 DISABLED_DownloadExtensionTest_Download_Subdirectory
1624 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1625 DownloadExtensionTest_Download_Subdirectory
1627 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1628 MAYBE_DownloadExtensionTest_Download_Subdirectory) {
1629 LoadExtension("downloads_split");
1630 ASSERT_TRUE(StartEmbeddedTestServer());
1631 ASSERT_TRUE(test_server()->Start());
1632 std::string download_url = test_server()->GetURL("slow?0").spec();
1635 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1636 new DownloadsDownloadFunction(), base::StringPrintf(
1637 "[{\"url\": \"%s\","
1638 " \"filename\": \"sub/dir/ect/ory.txt\"}]",
1639 download_url.c_str())));
1640 ASSERT_TRUE(result.get());
1642 ASSERT_TRUE(result->GetAsInteger(&result_id));
1643 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1645 ScopedCancellingItem canceller(item);
1646 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1648 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1650 "[{\"danger\": \"safe\","
1651 " \"incognito\": false,"
1652 " \"mime\": \"text/plain\","
1653 " \"paused\": false,"
1654 " \"url\": \"%s\"}]",
1655 download_url.c_str())));
1656 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1660 " \"previous\": \"\","
1661 " \"current\": \"%s\"}}]",
1663 GetFilename("sub/dir/ect/ory.txt").c_str())));
1664 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1668 " \"previous\": \"in_progress\","
1669 " \"current\": \"complete\"}}]",
1673 // Test that invalid filenames are disallowed.
1674 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1675 DownloadExtensionTest_Download_InvalidFilename) {
1676 LoadExtension("downloads_split");
1677 ASSERT_TRUE(StartEmbeddedTestServer());
1678 ASSERT_TRUE(test_server()->Start());
1679 std::string download_url = test_server()->GetURL("slow?0").spec();
1682 EXPECT_STREQ(errors::kInvalidFilename,
1683 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1685 "[{\"url\": \"%s\","
1686 " \"filename\": \"../../../../../etc/passwd\"}]",
1687 download_url.c_str())).c_str());
1690 // flaky on mac: crbug.com/392288
1691 #if defined(OS_MACOSX)
1692 #define MAYBE_DownloadExtensionTest_Download_InvalidURLs \
1693 DISABLED_DownloadExtensionTest_Download_InvalidURLs
1695 #define MAYBE_DownloadExtensionTest_Download_InvalidURLs \
1696 DownloadExtensionTest_Download_InvalidURLs
1699 // Test that downloading invalid URLs immediately returns kInvalidURLError.
1700 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1701 MAYBE_DownloadExtensionTest_Download_InvalidURLs) {
1702 LoadExtension("downloads_split");
1705 static const char* kInvalidURLs[] = {
1711 "foo/bar.html#frag",
1715 for (size_t index = 0; index < arraysize(kInvalidURLs); ++index) {
1716 EXPECT_STREQ(errors::kInvalidURL,
1717 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1719 "[{\"url\": \"%s\"}]", kInvalidURLs[index])).c_str())
1720 << kInvalidURLs[index];
1723 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1724 new DownloadsDownloadFunction(),
1725 "[{\"url\": \"javascript:document.write(\\\"hello\\\");\"}]").c_str());
1726 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1727 new DownloadsDownloadFunction(),
1728 "[{\"url\": \"javascript:return false;\"}]").c_str());
1729 EXPECT_STREQ("NETWORK_FAILED", RunFunctionAndReturnError(
1730 new DownloadsDownloadFunction(),
1731 "[{\"url\": \"ftp://example.com/example.txt\"}]").c_str());
1734 // TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to
1735 // permissions, test downloading from ftp.
1737 // Valid URLs plus fragments are still valid URLs.
1738 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1739 DownloadExtensionTest_Download_URLFragment) {
1740 LoadExtension("downloads_split");
1741 ASSERT_TRUE(StartEmbeddedTestServer());
1742 ASSERT_TRUE(test_server()->Start());
1743 std::string download_url = test_server()->GetURL("slow?0#fragment").spec();
1746 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1747 new DownloadsDownloadFunction(), base::StringPrintf(
1748 "[{\"url\": \"%s\"}]", download_url.c_str())));
1749 ASSERT_TRUE(result.get());
1751 ASSERT_TRUE(result->GetAsInteger(&result_id));
1752 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1754 ScopedCancellingItem canceller(item);
1755 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1757 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1759 "[{\"danger\": \"safe\","
1760 " \"incognito\": false,"
1761 " \"mime\": \"text/plain\","
1762 " \"paused\": false,"
1763 " \"url\": \"%s\"}]",
1764 download_url.c_str())));
1765 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1769 " \"previous\": \"\","
1770 " \"current\": \"%s\"}}]",
1772 GetFilename("slow.txt").c_str())));
1773 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1777 " \"previous\": \"in_progress\","
1778 " \"current\": \"complete\"}}]",
1782 // conflictAction may be specified without filename.
1783 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1784 DownloadExtensionTest_Download_ConflictAction) {
1785 static char kFilename[] = "download.txt";
1786 LoadExtension("downloads_split");
1787 std::string download_url = "data:text/plain,hello";
1790 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1791 new DownloadsDownloadFunction(), base::StringPrintf(
1792 "[{\"url\": \"%s\"}]", download_url.c_str())));
1793 ASSERT_TRUE(result.get());
1795 ASSERT_TRUE(result->GetAsInteger(&result_id));
1796 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1798 ScopedCancellingItem canceller(item);
1799 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1801 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1803 "[{\"danger\": \"safe\","
1804 " \"incognito\": false,"
1805 " \"mime\": \"text/plain\","
1806 " \"paused\": false,"
1807 " \"url\": \"%s\"}]",
1808 download_url.c_str())));
1809 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1813 " \"previous\": \"\","
1814 " \"current\": \"%s\"}}]",
1816 GetFilename(kFilename).c_str())));
1817 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1821 " \"previous\": \"in_progress\","
1822 " \"current\": \"complete\"}}]",
1825 result.reset(RunFunctionAndReturnResult(
1826 new DownloadsDownloadFunction(), base::StringPrintf(
1827 "[{\"url\": \"%s\", \"conflictAction\": \"overwrite\"}]",
1828 download_url.c_str())));
1829 ASSERT_TRUE(result.get());
1831 ASSERT_TRUE(result->GetAsInteger(&result_id));
1832 item = GetCurrentManager()->GetDownload(result_id);
1834 ScopedCancellingItem canceller2(item);
1835 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1837 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1839 "[{\"danger\": \"safe\","
1840 " \"incognito\": false,"
1841 " \"mime\": \"text/plain\","
1842 " \"paused\": false,"
1843 " \"url\": \"%s\"}]",
1844 download_url.c_str())));
1845 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1849 " \"previous\": \"\","
1850 " \"current\": \"%s\"}}]",
1852 GetFilename(kFilename).c_str())));
1853 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1857 " \"previous\": \"in_progress\","
1858 " \"current\": \"complete\"}}]",
1862 // Valid data URLs are valid URLs.
1863 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1864 DownloadExtensionTest_Download_DataURL) {
1865 LoadExtension("downloads_split");
1866 std::string download_url = "data:text/plain,hello";
1869 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1870 new DownloadsDownloadFunction(), base::StringPrintf(
1871 "[{\"url\": \"%s\","
1872 " \"filename\": \"data.txt\"}]", download_url.c_str())));
1873 ASSERT_TRUE(result.get());
1875 ASSERT_TRUE(result->GetAsInteger(&result_id));
1876 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1878 ScopedCancellingItem canceller(item);
1879 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1881 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1883 "[{\"danger\": \"safe\","
1884 " \"incognito\": false,"
1885 " \"mime\": \"text/plain\","
1886 " \"paused\": false,"
1887 " \"url\": \"%s\"}]",
1888 download_url.c_str())));
1889 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1893 " \"previous\": \"\","
1894 " \"current\": \"%s\"}}]",
1896 GetFilename("data.txt").c_str())));
1897 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1901 " \"previous\": \"in_progress\","
1902 " \"current\": \"complete\"}}]",
1906 // Valid file URLs are valid URLs.
1908 // Disabled due to crbug.com/175711
1909 #define MAYBE_DownloadExtensionTest_Download_File \
1910 DISABLED_DownloadExtensionTest_Download_File
1912 #define MAYBE_DownloadExtensionTest_Download_File \
1913 DownloadExtensionTest_Download_File
1915 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1916 MAYBE_DownloadExtensionTest_Download_File) {
1918 LoadExtension("downloads_split");
1919 std::string download_url = "file:///";
1921 download_url += "C:/";
1924 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1925 new DownloadsDownloadFunction(), base::StringPrintf(
1926 "[{\"url\": \"%s\","
1927 " \"filename\": \"file.txt\"}]", download_url.c_str())));
1928 ASSERT_TRUE(result.get());
1930 ASSERT_TRUE(result->GetAsInteger(&result_id));
1931 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1933 ScopedCancellingItem canceller(item);
1934 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1936 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
1938 "[{\"danger\": \"safe\","
1939 " \"incognito\": false,"
1940 " \"mime\": \"text/html\","
1941 " \"paused\": false,"
1942 " \"url\": \"%s\"}]",
1943 download_url.c_str())));
1944 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1948 " \"previous\": \"\","
1949 " \"current\": \"%s\"}}]",
1951 GetFilename("file.txt").c_str())));
1952 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
1956 " \"previous\": \"in_progress\","
1957 " \"current\": \"complete\"}}]",
1961 // Test that auth-basic-succeed would fail if the resource requires the
1962 // Authorization header and chrome fails to propagate it back to the server.
1963 // This tests both that testserver.py does not succeed when it should fail as
1964 // well as how the downloads extension API exposes the failure to extensions.
1965 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1966 DownloadExtensionTest_Download_AuthBasic_Fail) {
1967 LoadExtension("downloads_split");
1968 ASSERT_TRUE(StartEmbeddedTestServer());
1969 ASSERT_TRUE(test_server()->Start());
1970 std::string download_url = test_server()->GetURL("auth-basic").spec();
1973 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1974 new DownloadsDownloadFunction(), base::StringPrintf(
1975 "[{\"url\": \"%s\","
1976 " \"filename\": \"auth-basic-fail.txt\"}]",
1977 download_url.c_str())));
1978 ASSERT_TRUE(result.get());
1980 ASSERT_TRUE(result->GetAsInteger(&result_id));
1981 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
1983 ScopedCancellingItem canceller(item);
1984 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
1986 ASSERT_TRUE(WaitForInterruption(
1988 content::DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED,
1989 base::StringPrintf("[{\"danger\": \"safe\","
1990 " \"incognito\": false,"
1991 " \"mime\": \"text/html\","
1992 " \"paused\": false,"
1993 " \"url\": \"%s\"}]",
1994 download_url.c_str())));
1997 // Test that DownloadsDownloadFunction propagates |headers| to the URLRequest.
1998 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1999 DownloadExtensionTest_Download_Headers) {
2000 LoadExtension("downloads_split");
2001 ASSERT_TRUE(StartEmbeddedTestServer());
2002 ASSERT_TRUE(test_server()->Start());
2003 std::string download_url = test_server()->GetURL("files/downloads/"
2004 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
2007 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2008 new DownloadsDownloadFunction(), base::StringPrintf(
2009 "[{\"url\": \"%s\","
2010 " \"filename\": \"headers-succeed.txt\","
2012 " {\"name\": \"Foo\", \"value\": \"bar\"},"
2013 " {\"name\": \"Qx\", \"value\":\"yo\"}]}]",
2014 download_url.c_str())));
2015 ASSERT_TRUE(result.get());
2017 ASSERT_TRUE(result->GetAsInteger(&result_id));
2018 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2020 ScopedCancellingItem canceller(item);
2021 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2023 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2025 "[{\"danger\": \"safe\","
2026 " \"incognito\": false,"
2027 " \"mime\": \"application/octet-stream\","
2028 " \"paused\": false,"
2029 " \"url\": \"%s\"}]",
2030 download_url.c_str())));
2031 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2035 " \"previous\": \"\","
2036 " \"current\": \"%s\"}}]",
2038 GetFilename("headers-succeed.txt").c_str())));
2039 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2043 " \"previous\": \"in_progress\","
2044 " \"current\": \"complete\"}}]",
2048 // Test that headers-succeed would fail if the resource requires the headers and
2049 // chrome fails to propagate them back to the server. This tests both that
2050 // testserver.py does not succeed when it should fail as well as how the
2051 // downloads extension api exposes the failure to extensions.
2052 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2053 DownloadExtensionTest_Download_Headers_Fail) {
2054 LoadExtension("downloads_split");
2055 ASSERT_TRUE(StartEmbeddedTestServer());
2056 ASSERT_TRUE(test_server()->Start());
2057 std::string download_url = test_server()->GetURL("files/downloads/"
2058 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
2061 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2062 new DownloadsDownloadFunction(), base::StringPrintf(
2063 "[{\"url\": \"%s\","
2064 " \"filename\": \"headers-fail.txt\"}]",
2065 download_url.c_str())));
2066 ASSERT_TRUE(result.get());
2068 ASSERT_TRUE(result->GetAsInteger(&result_id));
2069 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2071 ScopedCancellingItem canceller(item);
2072 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2074 ASSERT_TRUE(WaitForInterruption(
2076 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2077 base::StringPrintf("[{\"danger\": \"safe\","
2078 " \"incognito\": false,"
2079 " \"bytesReceived\": 0.0,"
2080 " \"fileSize\": 0.0,"
2082 " \"paused\": false,"
2083 " \"url\": \"%s\"}]",
2084 download_url.c_str())));
2087 // Test that DownloadsDownloadFunction propagates the Authorization header
2089 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2090 DownloadExtensionTest_Download_AuthBasic) {
2091 LoadExtension("downloads_split");
2092 ASSERT_TRUE(StartEmbeddedTestServer());
2093 ASSERT_TRUE(test_server()->Start());
2094 std::string download_url = test_server()->GetURL("auth-basic").spec();
2095 // This is just base64 of 'username:secret'.
2096 static const char* kAuthorization = "dXNlcm5hbWU6c2VjcmV0";
2099 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2100 new DownloadsDownloadFunction(), base::StringPrintf(
2101 "[{\"url\": \"%s\","
2102 " \"filename\": \"auth-basic-succeed.txt\","
2104 " \"name\": \"Authorization\","
2105 " \"value\": \"Basic %s\"}]}]",
2106 download_url.c_str(), kAuthorization)));
2107 ASSERT_TRUE(result.get());
2109 ASSERT_TRUE(result->GetAsInteger(&result_id));
2110 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2112 ScopedCancellingItem canceller(item);
2113 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2115 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2117 "[{\"danger\": \"safe\","
2118 " \"incognito\": false,"
2119 " \"bytesReceived\": 0.0,"
2120 " \"fileSize\": 0.0,"
2121 " \"mime\": \"text/html\","
2122 " \"paused\": false,"
2123 " \"url\": \"%s\"}]",
2124 download_url.c_str())));
2125 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2129 " \"previous\": \"in_progress\","
2130 " \"current\": \"complete\"}}]",
2134 // Test that DownloadsDownloadFunction propagates the |method| and |body|
2135 // parameters to the URLRequest.
2136 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2137 DownloadExtensionTest_Download_Post) {
2138 LoadExtension("downloads_split");
2139 ASSERT_TRUE(StartEmbeddedTestServer());
2140 ASSERT_TRUE(test_server()->Start());
2141 std::string download_url = test_server()->GetURL("files/post/downloads/"
2142 "a_zip_file.zip?expected_body=BODY").spec();
2145 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2146 new DownloadsDownloadFunction(), base::StringPrintf(
2147 "[{\"url\": \"%s\","
2148 " \"filename\": \"post-succeed.txt\","
2149 " \"method\": \"POST\","
2150 " \"body\": \"BODY\"}]",
2151 download_url.c_str())));
2152 ASSERT_TRUE(result.get());
2154 ASSERT_TRUE(result->GetAsInteger(&result_id));
2155 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2157 ScopedCancellingItem canceller(item);
2158 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2160 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2162 "[{\"danger\": \"safe\","
2163 " \"incognito\": false,"
2164 " \"mime\": \"application/octet-stream\","
2165 " \"paused\": false,"
2166 " \"url\": \"%s\"}]",
2167 download_url.c_str())));
2168 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2172 " \"previous\": \"\","
2173 " \"current\": \"%s\"}}]",
2175 GetFilename("post-succeed.txt").c_str())));
2176 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2180 " \"previous\": \"in_progress\","
2181 " \"current\": \"complete\"}}]",
2185 // Test that downloadPostSuccess would fail if the resource requires the POST
2186 // method, and chrome fails to propagate the |method| parameter back to the
2187 // server. This tests both that testserver.py does not succeed when it should
2188 // fail, and this tests how the downloads extension api exposes the failure to
2190 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2191 DownloadExtensionTest_Download_Post_Get) {
2192 LoadExtension("downloads_split");
2193 ASSERT_TRUE(StartEmbeddedTestServer());
2194 ASSERT_TRUE(test_server()->Start());
2195 std::string download_url = test_server()->GetURL("files/post/downloads/"
2196 "a_zip_file.zip?expected_body=BODY").spec();
2199 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2200 new DownloadsDownloadFunction(), base::StringPrintf(
2201 "[{\"url\": \"%s\","
2202 " \"body\": \"BODY\","
2203 " \"filename\": \"post-get.txt\"}]",
2204 download_url.c_str())));
2205 ASSERT_TRUE(result.get());
2207 ASSERT_TRUE(result->GetAsInteger(&result_id));
2208 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2210 ScopedCancellingItem canceller(item);
2211 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2213 ASSERT_TRUE(WaitForInterruption(
2215 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2216 base::StringPrintf("[{\"danger\": \"safe\","
2217 " \"incognito\": false,"
2219 " \"paused\": false,"
2221 " \"url\": \"%s\"}]",
2223 download_url.c_str())));
2226 // Test that downloadPostSuccess would fail if the resource requires the POST
2227 // method, and chrome fails to propagate the |body| parameter back to the
2228 // server. This tests both that testserver.py does not succeed when it should
2229 // fail, and this tests how the downloads extension api exposes the failure to
2231 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2232 DownloadExtensionTest_Download_Post_NoBody) {
2233 LoadExtension("downloads_split");
2234 ASSERT_TRUE(StartEmbeddedTestServer());
2235 ASSERT_TRUE(test_server()->Start());
2236 std::string download_url = test_server()->GetURL("files/post/downloads/"
2237 "a_zip_file.zip?expected_body=BODY").spec();
2240 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2241 new DownloadsDownloadFunction(), base::StringPrintf(
2242 "[{\"url\": \"%s\","
2243 " \"method\": \"POST\","
2244 " \"filename\": \"post-nobody.txt\"}]",
2245 download_url.c_str())));
2246 ASSERT_TRUE(result.get());
2248 ASSERT_TRUE(result->GetAsInteger(&result_id));
2249 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2251 ScopedCancellingItem canceller(item);
2252 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2254 ASSERT_TRUE(WaitForInterruption(
2256 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2257 base::StringPrintf("[{\"danger\": \"safe\","
2258 " \"incognito\": false,"
2260 " \"paused\": false,"
2262 " \"url\": \"%s\"}]",
2264 download_url.c_str())));
2267 // Test that cancel()ing an in-progress download causes its state to transition
2268 // to interrupted, and test that that state transition is detectable by an
2269 // onChanged event listener. TODO(benjhayden): Test other sources of
2270 // interruptions such as server death.
2271 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2272 DownloadExtensionTest_Download_Cancel) {
2273 LoadExtension("downloads_split");
2274 ASSERT_TRUE(StartEmbeddedTestServer());
2275 ASSERT_TRUE(test_server()->Start());
2276 std::string download_url = test_server()->GetURL(
2277 "download-known-size").spec();
2280 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2281 new DownloadsDownloadFunction(), base::StringPrintf(
2282 "[{\"url\": \"%s\"}]", download_url.c_str())));
2283 ASSERT_TRUE(result.get());
2285 ASSERT_TRUE(result->GetAsInteger(&result_id));
2286 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2288 ScopedCancellingItem canceller(item);
2289 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2291 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2293 "[{\"danger\": \"safe\","
2294 " \"incognito\": false,"
2295 " \"mime\": \"application/octet-stream\","
2296 " \"paused\": false,"
2298 " \"url\": \"%s\"}]",
2300 download_url.c_str())));
2302 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2305 " \"error\": {\"current\":\"USER_CANCELED\"},"
2307 " \"previous\": \"in_progress\","
2308 " \"current\": \"interrupted\"}}]",
2312 // flaky on mac: crbug.com/392288
2313 #if defined(OS_MACOSX)
2314 #define MAYBE_DownloadExtensionTest_Download_FileSystemURL \
2315 DISABLED_DownloadExtensionTest_Download_FileSystemURL
2317 #define MAYBE_DownloadExtensionTest_Download_FileSystemURL \
2318 DownloadExtensionTest_Download_FileSystemURL
2321 // Test downloading filesystem: URLs.
2322 // NOTE: chrome disallows creating HTML5 FileSystem Files in incognito.
2323 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2324 MAYBE_DownloadExtensionTest_Download_FileSystemURL) {
2325 static const char* kPayloadData = "on the record\ndata";
2327 LoadExtension("downloads_split");
2329 const std::string download_url = "filesystem:" + GetExtensionURL() +
2330 "temporary/on_record.txt";
2332 // Setup a file in the filesystem which we can download.
2333 ASSERT_TRUE(HTML5FileWriter::CreateFileForTesting(
2334 BrowserContext::GetDefaultStoragePartition(browser()->profile())->
2335 GetFileSystemContext(),
2336 fileapi::FileSystemURL::CreateForTest(GURL(download_url)),
2337 kPayloadData, strlen(kPayloadData)));
2340 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2341 new DownloadsDownloadFunction(), base::StringPrintf(
2342 "[{\"url\": \"%s\"}]", download_url.c_str())));
2343 ASSERT_TRUE(result.get());
2345 ASSERT_TRUE(result->GetAsInteger(&result_id));
2347 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2349 ScopedCancellingItem canceller(item);
2350 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2352 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2354 "[{\"danger\": \"safe\","
2355 " \"incognito\": false,"
2356 " \"mime\": \"text/plain\","
2357 " \"paused\": false,"
2358 " \"url\": \"%s\"}]",
2359 download_url.c_str())));
2360 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2364 " \"previous\": \"\","
2365 " \"current\": \"%s\"}}]",
2367 GetFilename("on_record.txt").c_str())));
2368 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2372 " \"previous\": \"in_progress\","
2373 " \"current\": \"complete\"}}]",
2375 std::string disk_data;
2376 EXPECT_TRUE(base::ReadFileToString(item->GetTargetFilePath(), &disk_data));
2377 EXPECT_STREQ(kPayloadData, disk_data.c_str());
2380 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2381 DownloadExtensionTest_OnDeterminingFilename_NoChange) {
2383 LoadExtension("downloads_split");
2384 AddFilenameDeterminer();
2385 ASSERT_TRUE(StartEmbeddedTestServer());
2386 ASSERT_TRUE(test_server()->Start());
2387 std::string download_url = test_server()->GetURL("slow?0").spec();
2389 // Start downloading a file.
2390 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2391 new DownloadsDownloadFunction(), base::StringPrintf(
2392 "[{\"url\": \"%s\"}]", download_url.c_str())));
2393 ASSERT_TRUE(result.get());
2395 ASSERT_TRUE(result->GetAsInteger(&result_id));
2396 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2398 ScopedCancellingItem canceller(item);
2399 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2401 // Wait for the onCreated and onDeterminingFilename events.
2402 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2404 "[{\"danger\": \"safe\","
2405 " \"incognito\": false,"
2407 " \"mime\": \"text/plain\","
2408 " \"paused\": false,"
2409 " \"url\": \"%s\"}]",
2411 download_url.c_str())));
2412 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2415 " \"filename\":\"slow.txt\"}]",
2417 ASSERT_TRUE(item->GetTargetFilePath().empty());
2418 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2420 // Respond to the onDeterminingFilename.
2422 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2423 browser()->profile(),
2428 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2430 EXPECT_EQ("", error);
2432 // The download should complete successfully.
2433 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2437 " \"previous\": \"\","
2438 " \"current\": \"%s\"}}]",
2440 GetFilename("slow.txt").c_str())));
2441 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2445 " \"previous\": \"in_progress\","
2446 " \"current\": \"complete\"}}]",
2450 // Disabled due to cross-platform flakes; http://crbug.com/370531.
2451 IN_PROC_BROWSER_TEST_F(
2452 DownloadExtensionTest,
2453 DISABLED_DownloadExtensionTest_OnDeterminingFilename_Timeout) {
2455 LoadExtension("downloads_split");
2456 AddFilenameDeterminer();
2457 ASSERT_TRUE(StartEmbeddedTestServer());
2458 ASSERT_TRUE(test_server()->Start());
2459 std::string download_url = test_server()->GetURL("slow?0").spec();
2461 ExtensionDownloadsEventRouter::SetDetermineFilenameTimeoutSecondsForTesting(
2464 // Start downloading a file.
2465 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2466 new DownloadsDownloadFunction(), base::StringPrintf(
2467 "[{\"url\": \"%s\"}]", download_url.c_str())));
2468 ASSERT_TRUE(result.get());
2470 ASSERT_TRUE(result->GetAsInteger(&result_id));
2471 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2473 ScopedCancellingItem canceller(item);
2474 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2476 // Wait for the onCreated and onDeterminingFilename events.
2477 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2478 base::StringPrintf("[{\"danger\": \"safe\","
2479 " \"incognito\": false,"
2481 " \"mime\": \"text/plain\","
2482 " \"paused\": false,"
2483 " \"url\": \"%s\"}]",
2485 download_url.c_str())));
2486 ASSERT_TRUE(WaitFor(
2487 downloads::OnDeterminingFilename::kEventName,
2488 base::StringPrintf("[{\"id\": %d,"
2489 " \"filename\":\"slow.txt\"}]",
2491 ASSERT_TRUE(item->GetTargetFilePath().empty());
2492 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2494 // Do not respond to the onDeterminingFilename.
2496 // The download should complete successfully.
2497 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2498 base::StringPrintf("[{\"id\": %d,"
2500 " \"previous\": \"\","
2501 " \"current\": \"%s\"}}]",
2503 GetFilename("slow.txt").c_str())));
2504 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2505 base::StringPrintf("[{\"id\": %d,"
2507 " \"previous\": \"in_progress\","
2508 " \"current\": \"complete\"}}]",
2512 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
2513 DownloadExtensionTest_OnDeterminingFilename_Twice) {
2515 LoadExtension("downloads_split");
2516 AddFilenameDeterminer();
2517 ASSERT_TRUE(StartEmbeddedTestServer());
2518 ASSERT_TRUE(test_server()->Start());
2519 std::string download_url = test_server()->GetURL("slow?0").spec();
2521 // Start downloading a file.
2522 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2523 new DownloadsDownloadFunction(), base::StringPrintf(
2524 "[{\"url\": \"%s\"}]", download_url.c_str())));
2525 ASSERT_TRUE(result.get());
2527 ASSERT_TRUE(result->GetAsInteger(&result_id));
2528 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2530 ScopedCancellingItem canceller(item);
2531 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2533 // Wait for the onCreated and onDeterminingFilename events.
2534 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2535 base::StringPrintf("[{\"danger\": \"safe\","
2536 " \"incognito\": false,"
2538 " \"mime\": \"text/plain\","
2539 " \"paused\": false,"
2540 " \"url\": \"%s\"}]",
2542 download_url.c_str())));
2543 ASSERT_TRUE(WaitFor(
2544 downloads::OnDeterminingFilename::kEventName,
2545 base::StringPrintf("[{\"id\": %d,"
2546 " \"filename\":\"slow.txt\"}]",
2548 ASSERT_TRUE(item->GetTargetFilePath().empty());
2549 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2551 // Respond to the onDeterminingFilename.
2553 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2554 browser()->profile(),
2559 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2561 EXPECT_EQ("", error);
2563 // Calling DetermineFilename again should return an error instead of calling
2564 // DownloadTargetDeterminer.
2565 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2566 browser()->profile(),
2570 base::FilePath(FILE_PATH_LITERAL("different")),
2571 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE,
2573 EXPECT_EQ(errors::kTooManyListeners, error);
2575 // The download should complete successfully.
2576 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2577 base::StringPrintf("[{\"id\": %d,"
2579 " \"previous\": \"\","
2580 " \"current\": \"%s\"}}]",
2582 GetFilename("slow.txt").c_str())));
2583 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2584 base::StringPrintf("[{\"id\": %d,"
2586 " \"previous\": \"in_progress\","
2587 " \"current\": \"complete\"}}]",
2591 IN_PROC_BROWSER_TEST_F(
2592 DownloadExtensionTest,
2593 DownloadExtensionTest_OnDeterminingFilename_DangerousOverride) {
2595 LoadExtension("downloads_split");
2596 AddFilenameDeterminer();
2597 ASSERT_TRUE(StartEmbeddedTestServer());
2598 ASSERT_TRUE(test_server()->Start());
2599 std::string download_url = test_server()->GetURL("slow?0").spec();
2601 // Start downloading a file.
2602 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2603 new DownloadsDownloadFunction(), base::StringPrintf(
2604 "[{\"url\": \"%s\"}]", download_url.c_str())));
2605 ASSERT_TRUE(result.get());
2607 ASSERT_TRUE(result->GetAsInteger(&result_id));
2608 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2610 ScopedCancellingItem canceller(item);
2611 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2613 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2615 "[{\"danger\": \"safe\","
2616 " \"incognito\": false,"
2618 " \"mime\": \"text/plain\","
2619 " \"paused\": false,"
2620 " \"url\": \"%s\"}]",
2622 download_url.c_str())));
2623 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2626 " \"filename\":\"slow.txt\"}]",
2628 ASSERT_TRUE(item->GetTargetFilePath().empty());
2629 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2631 // Respond to the onDeterminingFilename.
2633 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2634 browser()->profile(),
2638 base::FilePath(FILE_PATH_LITERAL("overridden.swf")),
2639 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2641 EXPECT_EQ("", error);
2643 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2647 " \"previous\":\"safe\","
2648 " \"current\":\"file\"}}]",
2651 item->ValidateDangerousDownload();
2652 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2656 " \"previous\":\"file\","
2657 " \"current\":\"accepted\"}}]",
2659 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2663 " \"previous\": \"in_progress\","
2664 " \"current\": \"complete\"}}]",
2666 EXPECT_EQ(downloads_directory().AppendASCII("overridden.swf"),
2667 item->GetTargetFilePath());
2670 IN_PROC_BROWSER_TEST_F(
2671 DownloadExtensionTest,
2672 DownloadExtensionTest_OnDeterminingFilename_ReferencesParentInvalid) {
2674 LoadExtension("downloads_split");
2675 AddFilenameDeterminer();
2676 ASSERT_TRUE(StartEmbeddedTestServer());
2677 ASSERT_TRUE(test_server()->Start());
2678 std::string download_url = test_server()->GetURL("slow?0").spec();
2680 // Start downloading a file.
2681 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2682 new DownloadsDownloadFunction(), base::StringPrintf(
2683 "[{\"url\": \"%s\"}]", download_url.c_str())));
2684 ASSERT_TRUE(result.get());
2686 ASSERT_TRUE(result->GetAsInteger(&result_id));
2687 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2689 ScopedCancellingItem canceller(item);
2690 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2692 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2694 "[{\"danger\": \"safe\","
2695 " \"incognito\": false,"
2697 " \"mime\": \"text/plain\","
2698 " \"paused\": false,"
2699 " \"url\": \"%s\"}]",
2701 download_url.c_str())));
2702 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2705 " \"filename\":\"slow.txt\"}]",
2707 ASSERT_TRUE(item->GetTargetFilePath().empty());
2708 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2710 // Respond to the onDeterminingFilename.
2712 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2713 browser()->profile(),
2717 base::FilePath(FILE_PATH_LITERAL("sneaky/../../sneaky.txt")),
2718 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2720 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2721 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2725 " \"previous\": \"\","
2726 " \"current\": \"%s\"}}]",
2728 GetFilename("slow.txt").c_str())));
2729 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2733 " \"previous\": \"in_progress\","
2734 " \"current\": \"complete\"}}]",
2738 IN_PROC_BROWSER_TEST_F(
2739 DownloadExtensionTest,
2740 DownloadExtensionTest_OnDeterminingFilename_IllegalFilename) {
2742 LoadExtension("downloads_split");
2743 AddFilenameDeterminer();
2744 ASSERT_TRUE(StartEmbeddedTestServer());
2745 ASSERT_TRUE(test_server()->Start());
2746 std::string download_url = test_server()->GetURL("slow?0").spec();
2748 // Start downloading a file.
2749 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2750 new DownloadsDownloadFunction(), base::StringPrintf(
2751 "[{\"url\": \"%s\"}]", download_url.c_str())));
2752 ASSERT_TRUE(result.get());
2754 ASSERT_TRUE(result->GetAsInteger(&result_id));
2755 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2757 ScopedCancellingItem canceller(item);
2758 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2760 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2762 "[{\"danger\": \"safe\","
2763 " \"incognito\": false,"
2765 " \"mime\": \"text/plain\","
2766 " \"paused\": false,"
2767 " \"url\": \"%s\"}]",
2769 download_url.c_str())));
2770 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2773 " \"filename\":\"slow.txt\"}]",
2775 ASSERT_TRUE(item->GetTargetFilePath().empty());
2776 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2778 // Respond to the onDeterminingFilename.
2780 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2781 browser()->profile(),
2785 base::FilePath(FILE_PATH_LITERAL("<")),
2786 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2788 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2789 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2793 " \"previous\": \"\","
2794 " \"current\": \"%s\"}}]",
2796 GetFilename("slow.txt").c_str())));
2797 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2801 " \"previous\": \"in_progress\","
2802 " \"current\": \"complete\"}}]",
2806 IN_PROC_BROWSER_TEST_F(
2807 DownloadExtensionTest,
2808 DownloadExtensionTest_OnDeterminingFilename_IllegalFilenameExtension) {
2810 LoadExtension("downloads_split");
2811 AddFilenameDeterminer();
2812 ASSERT_TRUE(StartEmbeddedTestServer());
2813 ASSERT_TRUE(test_server()->Start());
2814 std::string download_url = test_server()->GetURL("slow?0").spec();
2816 // Start downloading a file.
2817 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2818 new DownloadsDownloadFunction(), base::StringPrintf(
2819 "[{\"url\": \"%s\"}]", download_url.c_str())));
2820 ASSERT_TRUE(result.get());
2822 ASSERT_TRUE(result->GetAsInteger(&result_id));
2823 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2825 ScopedCancellingItem canceller(item);
2826 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2828 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2830 "[{\"danger\": \"safe\","
2831 " \"incognito\": false,"
2833 " \"mime\": \"text/plain\","
2834 " \"paused\": false,"
2835 " \"url\": \"%s\"}]",
2837 download_url.c_str())));
2838 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2841 " \"filename\":\"slow.txt\"}]",
2843 ASSERT_TRUE(item->GetTargetFilePath().empty());
2844 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2846 // Respond to the onDeterminingFilename.
2848 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2849 browser()->profile(),
2853 base::FilePath(FILE_PATH_LITERAL(
2854 "My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}/foo")),
2855 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2857 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2858 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2862 " \"previous\": \"\","
2863 " \"current\": \"%s\"}}]",
2865 GetFilename("slow.txt").c_str())));
2866 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2870 " \"previous\": \"in_progress\","
2871 " \"current\": \"complete\"}}]",
2875 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2876 DISABLED_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2878 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2879 DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2881 IN_PROC_BROWSER_TEST_F(
2882 DownloadExtensionTest,
2883 MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename) {
2885 LoadExtension("downloads_split");
2886 AddFilenameDeterminer();
2887 ASSERT_TRUE(StartEmbeddedTestServer());
2888 ASSERT_TRUE(test_server()->Start());
2889 std::string download_url = test_server()->GetURL("slow?0").spec();
2891 // Start downloading a file.
2892 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2893 new DownloadsDownloadFunction(), base::StringPrintf(
2894 "[{\"url\": \"%s\"}]", download_url.c_str())));
2895 ASSERT_TRUE(result.get());
2897 ASSERT_TRUE(result->GetAsInteger(&result_id));
2898 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2900 ScopedCancellingItem canceller(item);
2901 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2903 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2905 "[{\"danger\": \"safe\","
2906 " \"incognito\": false,"
2908 " \"mime\": \"text/plain\","
2909 " \"paused\": false,"
2910 " \"url\": \"%s\"}]",
2912 download_url.c_str())));
2913 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2916 " \"filename\":\"slow.txt\"}]",
2918 ASSERT_TRUE(item->GetTargetFilePath().empty());
2919 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2921 // Respond to the onDeterminingFilename.
2923 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2924 browser()->profile(),
2928 base::FilePath(FILE_PATH_LITERAL("con.foo")),
2929 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2931 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
2932 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2936 " \"previous\": \"\","
2937 " \"current\": \"%s\"}}]",
2939 GetFilename("slow.txt").c_str())));
2940 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
2944 " \"previous\": \"in_progress\","
2945 " \"current\": \"complete\"}}]",
2949 IN_PROC_BROWSER_TEST_F(
2950 DownloadExtensionTest,
2951 DownloadExtensionTest_OnDeterminingFilename_CurDirInvalid) {
2953 LoadExtension("downloads_split");
2954 AddFilenameDeterminer();
2955 ASSERT_TRUE(StartEmbeddedTestServer());
2956 ASSERT_TRUE(test_server()->Start());
2957 std::string download_url = test_server()->GetURL("slow?0").spec();
2959 // Start downloading a file.
2960 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
2961 new DownloadsDownloadFunction(), base::StringPrintf(
2962 "[{\"url\": \"%s\"}]", download_url.c_str())));
2963 ASSERT_TRUE(result.get());
2965 ASSERT_TRUE(result->GetAsInteger(&result_id));
2966 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
2968 ScopedCancellingItem canceller(item);
2969 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
2971 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
2973 "[{\"danger\": \"safe\","
2974 " \"incognito\": false,"
2976 " \"mime\": \"text/plain\","
2977 " \"paused\": false,"
2978 " \"url\": \"%s\"}]",
2980 download_url.c_str())));
2981 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
2984 " \"filename\":\"slow.txt\"}]",
2986 ASSERT_TRUE(item->GetTargetFilePath().empty());
2987 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
2989 // Respond to the onDeterminingFilename.
2991 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2992 browser()->profile(),
2996 base::FilePath(FILE_PATH_LITERAL(".")),
2997 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
2999 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
3000 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3004 " \"previous\": \"\","
3005 " \"current\": \"%s\"}}]",
3007 GetFilename("slow.txt").c_str())));
3008 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3012 " \"previous\": \"in_progress\","
3013 " \"current\": \"complete\"}}]",
3017 IN_PROC_BROWSER_TEST_F(
3018 DownloadExtensionTest,
3019 DownloadExtensionTest_OnDeterminingFilename_ParentDirInvalid) {
3020 ASSERT_TRUE(StartEmbeddedTestServer());
3021 ASSERT_TRUE(test_server()->Start());
3023 LoadExtension("downloads_split");
3024 AddFilenameDeterminer();
3025 std::string download_url = test_server()->GetURL("slow?0").spec();
3027 // Start downloading a file.
3028 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3029 new DownloadsDownloadFunction(), base::StringPrintf(
3030 "[{\"url\": \"%s\"}]", download_url.c_str())));
3031 ASSERT_TRUE(result.get());
3033 ASSERT_TRUE(result->GetAsInteger(&result_id));
3034 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3036 ScopedCancellingItem canceller(item);
3037 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3039 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3041 "[{\"danger\": \"safe\","
3042 " \"incognito\": false,"
3044 " \"mime\": \"text/plain\","
3045 " \"paused\": false,"
3046 " \"url\": \"%s\"}]",
3048 download_url.c_str())));
3049 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3052 " \"filename\":\"slow.txt\"}]",
3054 ASSERT_TRUE(item->GetTargetFilePath().empty());
3055 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3057 // Respond to the onDeterminingFilename.
3059 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3060 browser()->profile(),
3064 base::FilePath(FILE_PATH_LITERAL("..")),
3065 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3067 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
3068 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3072 " \"previous\": \"\","
3073 " \"current\": \"%s\"}}]",
3075 GetFilename("slow.txt").c_str())));
3076 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3080 " \"previous\": \"in_progress\","
3081 " \"current\": \"complete\"}}]",
3085 IN_PROC_BROWSER_TEST_F(
3086 DownloadExtensionTest,
3087 DownloadExtensionTest_OnDeterminingFilename_AbsPathInvalid) {
3089 LoadExtension("downloads_split");
3090 AddFilenameDeterminer();
3091 ASSERT_TRUE(StartEmbeddedTestServer());
3092 ASSERT_TRUE(test_server()->Start());
3093 std::string download_url = test_server()->GetURL("slow?0").spec();
3095 // Start downloading a file.
3096 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3097 new DownloadsDownloadFunction(), base::StringPrintf(
3098 "[{\"url\": \"%s\"}]", download_url.c_str())));
3099 ASSERT_TRUE(result.get());
3101 ASSERT_TRUE(result->GetAsInteger(&result_id));
3102 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3104 ScopedCancellingItem canceller(item);
3105 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3107 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3109 "[{\"danger\": \"safe\","
3110 " \"incognito\": false,"
3112 " \"mime\": \"text/plain\","
3113 " \"paused\": false,"
3114 " \"url\": \"%s\"}]",
3116 download_url.c_str())));
3117 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3120 " \"filename\":\"slow.txt\"}]",
3122 ASSERT_TRUE(item->GetTargetFilePath().empty());
3123 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3125 // Respond to the onDeterminingFilename. Absolute paths should be rejected.
3127 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3128 browser()->profile(),
3132 downloads_directory().Append(FILE_PATH_LITERAL("sneaky.txt")),
3133 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3135 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
3137 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3141 " \"previous\": \"\","
3142 " \"current\": \"%s\"}}]",
3144 GetFilename("slow.txt").c_str())));
3145 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3149 " \"previous\": \"in_progress\","
3150 " \"current\": \"complete\"}}]",
3154 IN_PROC_BROWSER_TEST_F(
3155 DownloadExtensionTest,
3156 DownloadExtensionTest_OnDeterminingFilename_EmptyBasenameInvalid) {
3158 LoadExtension("downloads_split");
3159 AddFilenameDeterminer();
3160 ASSERT_TRUE(StartEmbeddedTestServer());
3161 ASSERT_TRUE(test_server()->Start());
3162 std::string download_url = test_server()->GetURL("slow?0").spec();
3164 // Start downloading a file.
3165 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3166 new DownloadsDownloadFunction(), base::StringPrintf(
3167 "[{\"url\": \"%s\"}]", download_url.c_str())));
3168 ASSERT_TRUE(result.get());
3170 ASSERT_TRUE(result->GetAsInteger(&result_id));
3171 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3173 ScopedCancellingItem canceller(item);
3174 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3176 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3178 "[{\"danger\": \"safe\","
3179 " \"incognito\": false,"
3181 " \"mime\": \"text/plain\","
3182 " \"paused\": false,"
3183 " \"url\": \"%s\"}]",
3185 download_url.c_str())));
3186 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3189 " \"filename\":\"slow.txt\"}]",
3191 ASSERT_TRUE(item->GetTargetFilePath().empty());
3192 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3194 // Respond to the onDeterminingFilename. Empty basenames should be rejected.
3196 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3197 browser()->profile(),
3201 base::FilePath(FILE_PATH_LITERAL("foo/")),
3202 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3204 EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
3206 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3210 " \"previous\": \"\","
3211 " \"current\": \"%s\"}}]",
3213 GetFilename("slow.txt").c_str())));
3214 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3218 " \"previous\": \"in_progress\","
3219 " \"current\": \"complete\"}}]",
3223 // conflictAction may be specified without filename.
3224 IN_PROC_BROWSER_TEST_F(
3225 DownloadExtensionTest,
3226 DownloadExtensionTest_OnDeterminingFilename_Overwrite) {
3228 LoadExtension("downloads_split");
3229 AddFilenameDeterminer();
3230 ASSERT_TRUE(StartEmbeddedTestServer());
3231 ASSERT_TRUE(test_server()->Start());
3232 std::string download_url = test_server()->GetURL("slow?0").spec();
3234 // Start downloading a file.
3235 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3236 new DownloadsDownloadFunction(), base::StringPrintf(
3237 "[{\"url\": \"%s\"}]", download_url.c_str())));
3238 ASSERT_TRUE(result.get());
3240 ASSERT_TRUE(result->GetAsInteger(&result_id));
3241 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3243 ScopedCancellingItem canceller(item);
3244 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3245 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3247 "[{\"danger\": \"safe\","
3248 " \"incognito\": false,"
3250 " \"mime\": \"text/plain\","
3251 " \"paused\": false,"
3252 " \"url\": \"%s\"}]",
3254 download_url.c_str())));
3255 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3258 " \"filename\":\"slow.txt\"}]",
3260 ASSERT_TRUE(item->GetTargetFilePath().empty());
3261 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3263 // Respond to the onDeterminingFilename.
3265 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3266 browser()->profile(),
3271 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3273 EXPECT_EQ("", error);
3275 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3279 " \"previous\": \"\","
3280 " \"current\": \"%s\"}}]",
3282 GetFilename("slow.txt").c_str())));
3283 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3287 " \"previous\": \"in_progress\","
3288 " \"current\": \"complete\"}}]",
3291 // Start downloading a file.
3292 result.reset(RunFunctionAndReturnResult(
3293 new DownloadsDownloadFunction(), base::StringPrintf(
3294 "[{\"url\": \"%s\"}]", download_url.c_str())));
3295 ASSERT_TRUE(result.get());
3297 ASSERT_TRUE(result->GetAsInteger(&result_id));
3298 item = GetCurrentManager()->GetDownload(result_id);
3300 ScopedCancellingItem canceller2(item);
3301 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3303 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3305 "[{\"danger\": \"safe\","
3306 " \"incognito\": false,"
3308 " \"mime\": \"text/plain\","
3309 " \"paused\": false,"
3310 " \"url\": \"%s\"}]",
3312 download_url.c_str())));
3313 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3316 " \"filename\":\"slow.txt\"}]",
3318 ASSERT_TRUE(item->GetTargetFilePath().empty());
3319 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3321 // Respond to the onDeterminingFilename.
3322 // Also test that DetermineFilename allows (chrome) extensions to set
3323 // filenames without (filename) extensions. (Don't ask about v8 extensions or
3324 // python extensions or kernel extensions or firefox extensions...)
3326 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3327 browser()->profile(),
3332 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE,
3334 EXPECT_EQ("", error);
3336 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3340 " \"previous\": \"\","
3341 " \"current\": \"%s\"}}]",
3343 GetFilename("slow.txt").c_str())));
3344 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3348 " \"previous\": \"in_progress\","
3349 " \"current\": \"complete\"}}]",
3353 IN_PROC_BROWSER_TEST_F(
3354 DownloadExtensionTest,
3355 DownloadExtensionTest_OnDeterminingFilename_Override) {
3357 LoadExtension("downloads_split");
3358 AddFilenameDeterminer();
3359 ASSERT_TRUE(StartEmbeddedTestServer());
3360 ASSERT_TRUE(test_server()->Start());
3361 std::string download_url = test_server()->GetURL("slow?0").spec();
3363 // Start downloading a file.
3364 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3365 new DownloadsDownloadFunction(), base::StringPrintf(
3366 "[{\"url\": \"%s\"}]", download_url.c_str())));
3367 ASSERT_TRUE(result.get());
3369 ASSERT_TRUE(result->GetAsInteger(&result_id));
3370 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3372 ScopedCancellingItem canceller(item);
3373 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3374 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3376 "[{\"danger\": \"safe\","
3377 " \"incognito\": false,"
3379 " \"mime\": \"text/plain\","
3380 " \"paused\": false,"
3381 " \"url\": \"%s\"}]",
3383 download_url.c_str())));
3384 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3387 " \"filename\":\"slow.txt\"}]",
3389 ASSERT_TRUE(item->GetTargetFilePath().empty());
3390 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3392 // Respond to the onDeterminingFilename.
3394 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3395 browser()->profile(),
3400 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3402 EXPECT_EQ("", error);
3404 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3408 " \"previous\": \"\","
3409 " \"current\": \"%s\"}}]",
3411 GetFilename("slow.txt").c_str())));
3412 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3416 " \"previous\": \"in_progress\","
3417 " \"current\": \"complete\"}}]",
3420 // Start downloading a file.
3421 result.reset(RunFunctionAndReturnResult(
3422 new DownloadsDownloadFunction(), base::StringPrintf(
3423 "[{\"url\": \"%s\"}]", download_url.c_str())));
3424 ASSERT_TRUE(result.get());
3426 ASSERT_TRUE(result->GetAsInteger(&result_id));
3427 item = GetCurrentManager()->GetDownload(result_id);
3429 ScopedCancellingItem canceller2(item);
3430 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3432 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3434 "[{\"danger\": \"safe\","
3435 " \"incognito\": false,"
3437 " \"mime\": \"text/plain\","
3438 " \"paused\": false,"
3439 " \"url\": \"%s\"}]",
3441 download_url.c_str())));
3442 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3445 " \"filename\":\"slow.txt\"}]",
3447 ASSERT_TRUE(item->GetTargetFilePath().empty());
3448 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3450 // Respond to the onDeterminingFilename.
3451 // Also test that DetermineFilename allows (chrome) extensions to set
3452 // filenames without (filename) extensions. (Don't ask about v8 extensions or
3453 // python extensions or kernel extensions or firefox extensions...)
3455 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3456 browser()->profile(),
3460 base::FilePath(FILE_PATH_LITERAL("foo")),
3461 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE,
3463 EXPECT_EQ("", error);
3465 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3469 " \"previous\": \"\","
3470 " \"current\": \"%s\"}}]",
3472 GetFilename("foo").c_str())));
3473 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3477 " \"previous\": \"in_progress\","
3478 " \"current\": \"complete\"}}]",
3482 // TODO test precedence rules: install_time
3484 #if defined(OS_MACOSX)
3485 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer \
3486 DISABLED_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer
3488 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer \
3489 DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer
3491 IN_PROC_BROWSER_TEST_F(
3492 DownloadExtensionTest,
3493 MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer) {
3494 ASSERT_TRUE(StartEmbeddedTestServer());
3495 ASSERT_TRUE(test_server()->Start());
3497 LoadExtension("downloads_split");
3498 content::RenderProcessHost* host = AddFilenameDeterminer();
3499 std::string download_url = test_server()->GetURL("slow?0").spec();
3501 // Start downloading a file.
3502 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3503 new DownloadsDownloadFunction(), base::StringPrintf(
3504 "[{\"url\": \"%s\"}]", download_url.c_str())));
3505 ASSERT_TRUE(result.get());
3507 ASSERT_TRUE(result->GetAsInteger(&result_id));
3508 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3510 ScopedCancellingItem canceller(item);
3511 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3513 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3515 "[{\"danger\": \"safe\","
3516 " \"incognito\": false,"
3518 " \"mime\": \"text/plain\","
3519 " \"paused\": false,"
3520 " \"url\": \"%s\"}]",
3522 download_url.c_str())));
3523 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3526 " \"filename\":\"slow.txt\"}]",
3528 ASSERT_TRUE(item->GetTargetFilePath().empty());
3529 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3531 // Remove a determiner while waiting for it.
3532 RemoveFilenameDeterminer(host);
3534 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3538 " \"previous\": \"in_progress\","
3539 " \"current\": \"complete\"}}]",
3543 IN_PROC_BROWSER_TEST_F(
3544 DownloadExtensionTest,
3545 DownloadExtensionTest_OnDeterminingFilename_IncognitoSplit) {
3546 LoadExtension("downloads_split");
3547 ASSERT_TRUE(StartEmbeddedTestServer());
3548 ASSERT_TRUE(test_server()->Start());
3549 std::string download_url = test_server()->GetURL("slow?0").spec();
3552 AddFilenameDeterminer();
3555 AddFilenameDeterminer();
3557 // Start an on-record download.
3559 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3560 new DownloadsDownloadFunction(), base::StringPrintf(
3561 "[{\"url\": \"%s\"}]", download_url.c_str())));
3562 ASSERT_TRUE(result.get());
3564 ASSERT_TRUE(result->GetAsInteger(&result_id));
3565 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3567 ScopedCancellingItem canceller(item);
3568 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3570 // Wait for the onCreated and onDeterminingFilename events.
3571 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3573 "[{\"danger\": \"safe\","
3574 " \"incognito\": false,"
3576 " \"mime\": \"text/plain\","
3577 " \"paused\": false,"
3578 " \"url\": \"%s\"}]",
3580 download_url.c_str())));
3581 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3584 " \"incognito\": false,"
3585 " \"filename\":\"slow.txt\"}]",
3587 ASSERT_TRUE(item->GetTargetFilePath().empty());
3588 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3590 // Respond to the onDeterminingFilename events.
3592 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3593 current_browser()->profile(),
3597 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3598 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3600 EXPECT_EQ("", error);
3602 // The download should complete successfully.
3603 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3607 " \"previous\": \"\","
3608 " \"current\": \"%s\"}}]",
3610 GetFilename("42.txt").c_str())));
3611 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3615 " \"previous\": \"in_progress\","
3616 " \"current\": \"complete\"}}]",
3619 // Start an incognito download for comparison.
3621 result.reset(RunFunctionAndReturnResult(
3622 new DownloadsDownloadFunction(), base::StringPrintf(
3623 "[{\"url\": \"%s\"}]", download_url.c_str())));
3624 ASSERT_TRUE(result.get());
3626 ASSERT_TRUE(result->GetAsInteger(&result_id));
3627 item = GetCurrentManager()->GetDownload(result_id);
3629 ScopedCancellingItem canceller2(item);
3630 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3632 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3634 "[{\"danger\": \"safe\","
3635 " \"incognito\": true,"
3637 " \"mime\": \"text/plain\","
3638 " \"paused\": false,"
3639 " \"url\": \"%s\"}]",
3641 download_url.c_str())));
3642 // On-Record renderers should not see events for off-record items.
3643 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3646 " \"incognito\": true,"
3647 " \"filename\":\"slow.txt\"}]",
3649 ASSERT_TRUE(item->GetTargetFilePath().empty());
3650 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3652 // Respond to the onDeterminingFilename.
3654 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3655 current_browser()->profile(),
3659 base::FilePath(FILE_PATH_LITERAL("5.txt")),
3660 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3662 EXPECT_EQ("", error);
3664 // The download should complete successfully.
3665 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3669 " \"previous\": \"\","
3670 " \"current\": \"%s\"}}]",
3672 GetFilename("5.txt").c_str())));
3673 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3677 " \"previous\": \"in_progress\","
3678 " \"current\": \"complete\"}}]",
3682 IN_PROC_BROWSER_TEST_F(
3683 DownloadExtensionTest,
3684 DownloadExtensionTest_OnDeterminingFilename_IncognitoSpanning) {
3685 LoadExtension("downloads_spanning");
3686 ASSERT_TRUE(StartEmbeddedTestServer());
3687 ASSERT_TRUE(test_server()->Start());
3688 std::string download_url = test_server()->GetURL("slow?0").spec();
3691 AddFilenameDeterminer();
3693 // There is a single extension renderer that sees both on-record and
3694 // off-record events. The extension functions see the on-record profile with
3695 // include_incognito=true.
3697 // Start an on-record download.
3699 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
3700 new DownloadsDownloadFunction(), base::StringPrintf(
3701 "[{\"url\": \"%s\"}]", download_url.c_str())));
3702 ASSERT_TRUE(result.get());
3704 ASSERT_TRUE(result->GetAsInteger(&result_id));
3705 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
3707 ScopedCancellingItem canceller(item);
3708 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3710 // Wait for the onCreated and onDeterminingFilename events.
3711 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3713 "[{\"danger\": \"safe\","
3714 " \"incognito\": false,"
3716 " \"mime\": \"text/plain\","
3717 " \"paused\": false,"
3718 " \"url\": \"%s\"}]",
3720 download_url.c_str())));
3721 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3724 " \"incognito\": false,"
3725 " \"filename\":\"slow.txt\"}]",
3727 ASSERT_TRUE(item->GetTargetFilePath().empty());
3728 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3730 // Respond to the onDeterminingFilename events.
3732 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3733 current_browser()->profile(),
3737 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3738 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3740 EXPECT_EQ("", error);
3742 // The download should complete successfully.
3743 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3747 " \"previous\": \"\","
3748 " \"current\": \"%s\"}}]",
3750 GetFilename("42.txt").c_str())));
3751 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3755 " \"previous\": \"in_progress\","
3756 " \"current\": \"complete\"}}]",
3759 // Start an incognito download for comparison.
3761 result.reset(RunFunctionAndReturnResult(
3762 new DownloadsDownloadFunction(), base::StringPrintf(
3763 "[{\"url\": \"%s\"}]", download_url.c_str())));
3764 ASSERT_TRUE(result.get());
3766 ASSERT_TRUE(result->GetAsInteger(&result_id));
3767 item = GetCurrentManager()->GetDownload(result_id);
3769 ScopedCancellingItem canceller2(item);
3770 ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
3772 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3774 "[{\"danger\": \"safe\","
3775 " \"incognito\": true,"
3777 " \"mime\": \"text/plain\","
3778 " \"paused\": false,"
3779 " \"url\": \"%s\"}]",
3781 download_url.c_str())));
3782 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3785 " \"incognito\": true,"
3786 " \"filename\":\"slow.txt\"}]",
3788 ASSERT_TRUE(item->GetTargetFilePath().empty());
3789 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3791 // Respond to the onDeterminingFilename.
3793 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3794 current_browser()->profile(),
3798 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3799 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3801 EXPECT_EQ("", error);
3803 // The download should complete successfully.
3804 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3808 " \"previous\": \"\","
3809 " \"current\": \"%s\"}}]",
3811 GetFilename("42 (1).txt").c_str())));
3812 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3816 " \"previous\": \"in_progress\","
3817 " \"current\": \"complete\"}}]",
3822 // This test is very flaky on Win XP and Aura. http://crbug.com/248438
3823 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3824 DISABLED_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3826 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3827 DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3830 // Test download interruption while extensions determining filename. Should not
3831 // re-dispatch onDeterminingFilename.
3832 IN_PROC_BROWSER_TEST_F(
3833 DownloadExtensionTest,
3834 MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume) {
3835 CommandLine::ForCurrentProcess()->AppendSwitch(
3836 switches::kEnableDownloadResumption);
3837 LoadExtension("downloads_split");
3838 ASSERT_TRUE(StartEmbeddedTestServer());
3839 ASSERT_TRUE(test_server()->Start());
3841 content::RenderProcessHost* host = AddFilenameDeterminer();
3843 // Start a download.
3844 DownloadItem* item = NULL;
3846 DownloadManager* manager = GetCurrentManager();
3847 scoped_ptr<content::DownloadTestObserver> observer(
3848 new JustInProgressDownloadObserver(manager, 1));
3849 ASSERT_EQ(0, manager->InProgressCount());
3850 ASSERT_EQ(0, manager->NonMaliciousInProgressCount());
3851 // Tabs created just for a download are automatically closed, invalidating
3852 // the download's WebContents. Downloads without WebContents cannot be
3853 // resumed. http://crbug.com/225901
3854 ui_test_utils::NavigateToURLWithDisposition(
3856 GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl),
3858 ui_test_utils::BROWSER_TEST_NONE);
3859 observer->WaitForFinished();
3860 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
3861 DownloadManager::DownloadVector items;
3862 manager->GetAllDownloads(&items);
3863 for (DownloadManager::DownloadVector::iterator iter = items.begin();
3864 iter != items.end(); ++iter) {
3865 if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) {
3866 // There should be only one IN_PROGRESS item.
3867 EXPECT_EQ(NULL, item);
3873 ScopedCancellingItem canceller(item);
3875 // Wait for the onCreated and onDeterminingFilename event.
3876 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName,
3878 "[{\"danger\": \"safe\","
3879 " \"incognito\": false,"
3881 " \"mime\": \"application/octet-stream\","
3882 " \"paused\": false}]",
3884 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName,
3887 " \"incognito\": false,"
3888 " \"filename\":\"download-unknown-size\"}]",
3890 ASSERT_TRUE(item->GetTargetFilePath().empty());
3891 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
3894 ui_test_utils::NavigateToURLWithDisposition(
3896 GURL(URLRequestSlowDownloadJob::kErrorDownloadUrl),
3898 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
3900 // Errors caught before filename determination are delayed until after
3901 // filename determination.
3903 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3904 current_browser()->profile(),
3908 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3909 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY,
3912 EXPECT_EQ("", error);
3913 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3917 " \"previous\": \"\","
3918 " \"current\": \"%s\"}}]",
3920 GetFilename("42.txt").c_str())));
3922 content::DownloadUpdatedObserver interrupted(item, base::Bind(
3923 ItemIsInterrupted));
3924 ASSERT_TRUE(interrupted.WaitForEvent());
3925 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3928 " \"error\":{\"current\":\"NETWORK_FAILED\"},"
3930 " \"previous\":\"in_progress\","
3931 " \"current\":\"interrupted\"}}]",
3935 // Downloads that are restarted on resumption trigger another download target
3937 RemoveFilenameDeterminer(host);
3940 // Errors caught before filename determination is complete are delayed until
3941 // after filename determination so that, on resumption, filename determination
3942 // does not need to be re-done. So, there will not be a second
3943 // onDeterminingFilename event.
3945 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3948 " \"error\":{\"previous\":\"NETWORK_FAILED\"},"
3950 " \"previous\":\"interrupted\","
3951 " \"current\":\"in_progress\"}}]",
3955 FinishPendingSlowDownloads();
3957 // The download should complete successfully.
3958 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
3962 " \"previous\": \"in_progress\","
3963 " \"current\": \"complete\"}}]",
3967 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
3968 DownloadExtensionTest_SetShelfEnabled) {
3969 LoadExtension("downloads_split");
3970 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[false]"));
3971 EXPECT_FALSE(DownloadServiceFactory::GetForBrowserContext(
3972 browser()->profile())->IsShelfEnabled());
3973 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[true]"));
3974 EXPECT_TRUE(DownloadServiceFactory::GetForBrowserContext(
3975 browser()->profile())->IsShelfEnabled());
3976 // TODO(benjhayden) Test that existing shelves are hidden.
3977 // TODO(benjhayden) Test multiple extensions.
3978 // TODO(benjhayden) Test disabling extensions.
3979 // TODO(benjhayden) Test that browsers associated with other profiles are not
3981 // TODO(benjhayden) Test incognito.
3984 // TODO(benjhayden) Figure out why DisableExtension() does not fire
3985 // OnListenerRemoved.
3987 // TODO(benjhayden) Test that the shelf is shown for download() both with and
3988 // without a WebContents.
3990 void OnDangerPromptCreated(DownloadDangerPrompt* prompt) {
3991 prompt->InvokeActionForTesting(DownloadDangerPrompt::ACCEPT);
3994 #if defined(OS_MACOSX)
3995 // Flakily triggers and assert on Mac.
3996 // http://crbug.com/180759
3997 #define MAYBE_DownloadExtensionTest_AcceptDanger DownloadExtensionTest_AcceptDanger
3999 #define MAYBE_DownloadExtensionTest_AcceptDanger DISABLED_DownloadExtensionTest_AcceptDanger
4001 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
4002 MAYBE_DownloadExtensionTest_AcceptDanger) {
4003 // Download a file that will be marked dangerous; click the browser action
4004 // button; the browser action poup will call acceptDanger(); when the
4005 // DownloadDangerPrompt is created, pretend that the user clicks the Accept
4006 // button; wait until the download completes.
4007 LoadExtension("downloads_split");
4008 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
4009 new DownloadsDownloadFunction(),
4010 "[{\"url\": \"data:,\", \"filename\": \"dangerous.swf\"}]"));
4011 ASSERT_TRUE(result.get());
4013 ASSERT_TRUE(result->GetAsInteger(&result_id));
4014 DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
4016 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName,
4020 " \"previous\": \"safe\","
4021 " \"current\": \"file\"}}]",
4023 ASSERT_TRUE(item->IsDangerous());
4024 ScopedCancellingItem canceller(item);
4025 scoped_ptr<content::DownloadTestObserver> observer(
4026 new content::DownloadTestObserverTerminal(
4027 GetCurrentManager(), 1,
4028 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_IGNORE));
4029 DownloadsAcceptDangerFunction::OnPromptCreatedCallback callback =
4030 base::Bind(&OnDangerPromptCreated);
4031 DownloadsAcceptDangerFunction::OnPromptCreatedForTesting(
4033 BrowserActionTestUtil(browser()).Press(0);
4034 observer->WaitForFinished();
4037 class DownloadsApiTest : public ExtensionApiTest {
4039 DownloadsApiTest() {}
4040 virtual ~DownloadsApiTest() {}
4042 DISALLOW_COPY_AND_ASSIGN(DownloadsApiTest);
4046 IN_PROC_BROWSER_TEST_F(DownloadsApiTest, DownloadsApiTest) {
4047 ASSERT_TRUE(RunExtensionTest("downloads")) << message_;
4050 TEST(DownloadInterruptReasonEnumsSynced,
4051 DownloadInterruptReasonEnumsSynced) {
4052 #define INTERRUPT_REASON(name, value) \
4053 EXPECT_EQ(InterruptReasonContentToExtension( \
4054 content::DOWNLOAD_INTERRUPT_REASON_##name), \
4055 downloads::INTERRUPT_REASON_##name); \
4057 InterruptReasonExtensionToContent(downloads::INTERRUPT_REASON_##name), \
4058 content::DOWNLOAD_INTERRUPT_REASON_##name);
4059 #include "content/public/browser/download_interrupt_reason_values.h"
4060 #undef INTERRUPT_REASON
4063 TEST(ExtensionDetermineDownloadFilenameInternal,
4064 ExtensionDetermineDownloadFilenameInternal) {
4065 std::string winner_id;
4066 base::FilePath filename;
4067 downloads::FilenameConflictAction conflict_action =
4068 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY;
4069 ExtensionWarningSet warnings;
4071 // Empty incumbent determiner
4073 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4074 base::FilePath(FILE_PATH_LITERAL("a")),
4075 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE,
4084 EXPECT_EQ("suggester", winner_id);
4085 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename.value());
4086 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_OVERWRITE, conflict_action);
4087 EXPECT_TRUE(warnings.empty());
4091 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4092 base::FilePath(FILE_PATH_LITERAL("b")),
4093 downloads::FILENAME_CONFLICT_ACTION_PROMPT,
4095 base::Time::Now() - base::TimeDelta::FromDays(1),
4102 EXPECT_EQ("incumbent", winner_id);
4103 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename.value());
4104 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_OVERWRITE, conflict_action);
4105 EXPECT_FALSE(warnings.empty());
4106 EXPECT_EQ(ExtensionWarning::kDownloadFilenameConflict,
4107 warnings.begin()->warning_type());
4108 EXPECT_EQ("suggester", warnings.begin()->extension_id());
4112 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4113 base::FilePath(FILE_PATH_LITERAL("b")),
4114 downloads::FILENAME_CONFLICT_ACTION_PROMPT,
4118 base::Time::Now() - base::TimeDelta::FromDays(1),
4123 EXPECT_EQ("suggester", winner_id);
4124 EXPECT_EQ(FILE_PATH_LITERAL("b"), filename.value());
4125 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_PROMPT, conflict_action);
4126 EXPECT_FALSE(warnings.empty());
4127 EXPECT_EQ(ExtensionWarning::kDownloadFilenameConflict,
4128 warnings.begin()->warning_type());
4129 EXPECT_EQ("incumbent", warnings.begin()->extension_id());
4132 } // namespace extensions
4134 #endif // http://crbug.com/3061144