1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Disable everything on windows only. http://crbug.com/306144
10 #include "base/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/json/json_reader.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/stl_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/synchronization/waitable_event.h"
18 #include "chrome/browser/chrome_notification_types.h"
19 #include "chrome/browser/download/download_file_icon_extractor.h"
20 #include "chrome/browser/download/download_service.h"
21 #include "chrome/browser/download/download_service_factory.h"
22 #include "chrome/browser/download/download_test_file_activity_observer.h"
23 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
24 #include "chrome/browser/extensions/browser_action_test_util.h"
25 #include "chrome/browser/extensions/extension_apitest.h"
26 #include "chrome/browser/extensions/extension_function_test_utils.h"
27 #include "chrome/browser/history/download_row.h"
28 #include "chrome/browser/net/url_request_mock_util.h"
29 #include "chrome/browser/profiles/profile.h"
30 #include "chrome/browser/ui/browser.h"
31 #include "chrome/browser/ui/browser_tabstrip.h"
32 #include "chrome/common/pref_names.h"
33 #include "chrome/test/base/in_process_browser_test.h"
34 #include "chrome/test/base/ui_test_utils.h"
35 #include "content/public/browser/browser_context.h"
36 #include "content/public/browser/browser_thread.h"
37 #include "content/public/browser/download_item.h"
38 #include "content/public/browser/download_manager.h"
39 #include "content/public/browser/notification_service.h"
40 #include "content/public/browser/storage_partition.h"
41 #include "content/public/browser/web_contents.h"
42 #include "content/public/common/content_switches.h"
43 #include "content/public/common/page_transition_types.h"
44 #include "content/public/test/download_test_observer.h"
45 #include "content/test/net/url_request_slow_download_job.h"
46 #include "extensions/browser/event_router.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()
83 registrar_
.Add(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT
,
84 content::NotificationService::AllSources());
87 virtual ~DownloadsEventsListener() {
88 registrar_
.Remove(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT
,
89 content::NotificationService::AllSources());
90 STLDeleteElements(&events_
);
94 STLDeleteElements(&events_
);
100 Event(Profile
* profile
,
101 const std::string
& event_name
,
102 const std::string
& json_args
,
105 event_name_(event_name
),
106 json_args_(json_args
),
107 args_(base::JSONReader::Read(json_args
)),
111 const base::Time
& caught() { return caught_
; }
113 bool Satisfies(const Event
& other
) const {
114 return other
.SatisfiedBy(*this);
117 bool SatisfiedBy(const Event
& other
) const {
118 if ((profile_
!= other
.profile_
) ||
119 (event_name_
!= other
.event_name_
))
121 if (((event_name_
== downloads::OnDeterminingFilename::kEventName
) ||
122 (event_name_
== downloads::OnCreated::kEventName
) ||
123 (event_name_
== downloads::OnChanged::kEventName
)) &&
124 args_
.get() && other
.args_
.get()) {
125 base::ListValue
* left_list
= NULL
;
126 base::DictionaryValue
* left_dict
= NULL
;
127 base::ListValue
* right_list
= NULL
;
128 base::DictionaryValue
* right_dict
= NULL
;
129 if (!args_
->GetAsList(&left_list
) ||
130 !other
.args_
->GetAsList(&right_list
) ||
131 !left_list
->GetDictionary(0, &left_dict
) ||
132 !right_list
->GetDictionary(0, &right_dict
))
134 for (base::DictionaryValue::Iterator
iter(*left_dict
);
135 !iter
.IsAtEnd(); iter
.Advance()) {
136 base::Value
* right_value
= NULL
;
137 if (!right_dict
->HasKey(iter
.key()) ||
138 (right_dict
->Get(iter
.key(), &right_value
) &&
139 !iter
.value().Equals(right_value
))) {
144 } else if ((event_name_
== downloads::OnErased::kEventName
) &&
145 args_
.get() && other
.args_
.get()) {
146 int my_id
= -1, other_id
= -1;
147 return (args_
->GetAsInteger(&my_id
) &&
148 other
.args_
->GetAsInteger(&other_id
) &&
151 return json_args_
== other
.json_args_
;
154 std::string
Debug() {
155 return base::StringPrintf("Event(%p, %s, %s, %f)",
164 std::string event_name_
;
165 std::string json_args_
;
166 scoped_ptr
<base::Value
> args_
;
169 DISALLOW_COPY_AND_ASSIGN(Event
);
172 typedef ExtensionDownloadsEventRouter::DownloadsNotificationSource
173 DownloadsNotificationSource
;
175 virtual void Observe(int type
,
176 const content::NotificationSource
& source
,
177 const content::NotificationDetails
& details
) OVERRIDE
{
179 case chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT
:
181 DownloadsNotificationSource
* dns
=
182 content::Source
<DownloadsNotificationSource
>(source
).ptr();
183 Event
* new_event
= new Event(
186 *content::Details
<std::string
>(details
).ptr(), base::Time::Now());
187 events_
.push_back(new_event
);
189 waiting_for_
.get() &&
190 new_event
->Satisfies(*waiting_for_
)) {
192 base::MessageLoopForUI::current()->Quit();
201 bool WaitFor(Profile
* profile
,
202 const std::string
& event_name
,
203 const std::string
& json_args
) {
204 waiting_for_
.reset(new Event(profile
, event_name
, json_args
, base::Time()));
205 for (std::deque
<Event
*>::const_iterator iter
= events_
.begin();
206 iter
!= events_
.end(); ++iter
) {
207 if ((*iter
)->Satisfies(*waiting_for_
.get())) {
212 content::RunMessageLoop();
213 bool success
= !waiting_
;
215 // Print the events that were caught since the last WaitFor() call to help
216 // find the erroneous event.
217 // TODO(benjhayden) Fuzzy-match and highlight the erroneous event.
218 for (std::deque
<Event
*>::const_iterator iter
= events_
.begin();
219 iter
!= events_
.end(); ++iter
) {
220 if ((*iter
)->caught() > last_wait_
) {
221 LOG(INFO
) << "Caught " << (*iter
)->Debug();
224 if (waiting_for_
.get()) {
225 LOG(INFO
) << "Timed out waiting for " << waiting_for_
->Debug();
229 waiting_for_
.reset();
230 last_wait_
= base::Time::Now();
236 base::Time last_wait_
;
237 scoped_ptr
<Event
> waiting_for_
;
238 content::NotificationRegistrar registrar_
;
239 std::deque
<Event
*> events_
;
241 DISALLOW_COPY_AND_ASSIGN(DownloadsEventsListener
);
244 class DownloadExtensionTest
: public ExtensionApiTest
{
246 DownloadExtensionTest()
248 incognito_browser_(NULL
),
249 current_browser_(NULL
) {
253 // Used with CreateHistoryDownloads
254 struct HistoryDownloadInfo
{
255 // Filename to use. CreateHistoryDownloads will append this filename to the
256 // temporary downloads directory specified by downloads_directory().
257 const base::FilePath::CharType
* filename
;
259 // State for the download. Note that IN_PROGRESS downloads will be created
261 DownloadItem::DownloadState state
;
263 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
264 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT.
265 content::DownloadDangerType danger_type
;
268 void LoadExtension(const char* name
) {
269 // Store the created Extension object so that we can attach it to
270 // ExtensionFunctions. Also load the extension in incognito profiles for
271 // testing incognito.
272 extension_
= LoadExtensionIncognito(test_data_dir_
.AppendASCII(name
));
274 content::WebContents
* tab
= chrome::AddSelectedTabWithURL(
276 extension_
->GetResourceURL("empty.html"),
277 content::PAGE_TRANSITION_LINK
);
278 EventRouter::Get(current_browser()->profile())
279 ->AddEventListener(downloads::OnCreated::kEventName
,
280 tab
->GetRenderProcessHost(),
282 EventRouter::Get(current_browser()->profile())
283 ->AddEventListener(downloads::OnChanged::kEventName
,
284 tab
->GetRenderProcessHost(),
286 EventRouter::Get(current_browser()->profile())
287 ->AddEventListener(downloads::OnErased::kEventName
,
288 tab
->GetRenderProcessHost(),
292 content::RenderProcessHost
* AddFilenameDeterminer() {
293 ExtensionDownloadsEventRouter::SetDetermineFilenameTimeoutSecondsForTesting(
295 content::WebContents
* tab
= chrome::AddSelectedTabWithURL(
297 extension_
->GetResourceURL("empty.html"),
298 content::PAGE_TRANSITION_LINK
);
299 EventRouter::Get(current_browser()->profile())
300 ->AddEventListener(downloads::OnDeterminingFilename::kEventName
,
301 tab
->GetRenderProcessHost(),
303 return tab
->GetRenderProcessHost();
306 void RemoveFilenameDeterminer(content::RenderProcessHost
* host
) {
307 EventRouter::Get(current_browser()->profile())->RemoveEventListener(
308 downloads::OnDeterminingFilename::kEventName
, host
, GetExtensionId());
311 Browser
* current_browser() { return current_browser_
; }
313 // InProcessBrowserTest
314 virtual void SetUpOnMainThread() OVERRIDE
{
315 ExtensionApiTest::SetUpOnMainThread();
316 BrowserThread::PostTask(
317 BrowserThread::IO
, FROM_HERE
,
318 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled
, true));
319 InProcessBrowserTest::SetUpOnMainThread();
321 CreateAndSetDownloadsDirectory();
322 current_browser()->profile()->GetPrefs()->SetBoolean(
323 prefs::kPromptForDownload
, false);
324 GetOnRecordManager()->RemoveAllDownloads();
325 events_listener_
.reset(new DownloadsEventsListener());
326 // Disable file chooser for current profile.
327 DownloadTestFileActivityObserver
observer(current_browser()->profile());
328 observer
.EnableFileChooser(false);
331 void GoOnTheRecord() { current_browser_
= browser(); }
333 void GoOffTheRecord() {
334 if (!incognito_browser_
) {
335 incognito_browser_
= CreateIncognitoBrowser();
336 GetOffRecordManager()->RemoveAllDownloads();
337 // Disable file chooser for incognito profile.
338 DownloadTestFileActivityObserver
observer(incognito_browser_
->profile());
339 observer
.EnableFileChooser(false);
341 current_browser_
= incognito_browser_
;
344 bool WaitFor(const std::string
& event_name
, const std::string
& json_args
) {
345 return events_listener_
->WaitFor(
346 current_browser()->profile(), event_name
, json_args
);
349 bool WaitForInterruption(
351 content::DownloadInterruptReason expected_error
,
352 const std::string
& on_created_event
) {
353 if (!WaitFor(downloads::OnCreated::kEventName
, on_created_event
))
355 // Now, onCreated is always fired before interruption.
357 downloads::OnChanged::kEventName
,
360 " \"error\": {\"current\": \"%s\"},"
362 " \"previous\": \"in_progress\","
363 " \"current\": \"interrupted\"}}]",
365 content::DownloadInterruptReasonToString(expected_error
).c_str()));
369 events_listener_
->ClearEvents();
372 std::string
GetExtensionURL() {
373 return extension_
->url().spec();
375 std::string
GetExtensionId() {
376 return extension_
->id();
379 std::string
GetFilename(const char* path
) {
381 downloads_directory_
.path().AppendASCII(path
).AsUTF8Unsafe();
383 for (std::string::size_type next
= result
.find("\\");
384 next
!= std::string::npos
;
385 next
= result
.find("\\", next
)) {
386 result
.replace(next
, 1, "\\\\");
393 DownloadManager
* GetOnRecordManager() {
394 return BrowserContext::GetDownloadManager(browser()->profile());
396 DownloadManager
* GetOffRecordManager() {
397 return BrowserContext::GetDownloadManager(
398 browser()->profile()->GetOffTheRecordProfile());
400 DownloadManager
* GetCurrentManager() {
401 return (current_browser_
== incognito_browser_
) ?
402 GetOffRecordManager() : GetOnRecordManager();
405 // Creates a set of history downloads based on the provided |history_info|
406 // array. |count| is the number of elements in |history_info|. On success,
407 // |items| will contain |count| DownloadItems in the order that they were
408 // specified in |history_info|. Returns true on success and false otherwise.
409 bool CreateHistoryDownloads(const HistoryDownloadInfo
* history_info
,
411 DownloadManager::DownloadVector
* items
) {
412 DownloadIdComparator download_id_comparator
;
413 base::Time current
= base::Time::Now();
415 GetOnRecordManager()->GetAllDownloads(items
);
416 CHECK_EQ(0, static_cast<int>(items
->size()));
417 std::vector
<GURL
> url_chain
;
418 url_chain
.push_back(GURL());
419 for (size_t i
= 0; i
< count
; ++i
) {
420 DownloadItem
* item
= GetOnRecordManager()->CreateDownloadItem(
421 content::DownloadItem::kInvalidId
+ 1 + i
,
422 downloads_directory().Append(history_info
[i
].filename
),
423 downloads_directory().Append(history_info
[i
].filename
),
424 url_chain
, GURL(), // URL Chain, referrer
425 std::string(), std::string(), // mime_type, original_mime_type
426 current
, current
, // start_time, end_time
427 std::string(), std::string(), // etag, last_modified
428 1, 1, // received_bytes, total_bytes
429 history_info
[i
].state
, // state
430 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
,
431 content::DOWNLOAD_INTERRUPT_REASON_NONE
,
433 items
->push_back(item
);
436 // Order by ID so that they are in the order that we created them.
437 std::sort(items
->begin(), items
->end(), download_id_comparator
);
438 // Set the danger type if necessary.
439 for (size_t i
= 0; i
< count
; ++i
) {
440 if (history_info
[i
].danger_type
!=
441 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
) {
442 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT
,
443 history_info
[i
].danger_type
);
444 items
->at(i
)->OnContentCheckCompleted(history_info
[i
].danger_type
);
450 void CreateSlowTestDownloads(
451 size_t count
, DownloadManager::DownloadVector
* items
) {
452 for (size_t i
= 0; i
< count
; ++i
) {
453 scoped_ptr
<content::DownloadTestObserver
> observer(
454 CreateInProgressDownloadObserver(1));
455 GURL
slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl
);
456 ui_test_utils::NavigateToURLWithDisposition(
457 current_browser(), slow_download_url
, CURRENT_TAB
,
458 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
459 observer
->WaitForFinished();
461 1u, observer
->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS
));
463 GetCurrentManager()->GetAllDownloads(items
);
464 ASSERT_EQ(count
, items
->size());
467 DownloadItem
* CreateSlowTestDownload() {
468 scoped_ptr
<content::DownloadTestObserver
> observer(
469 CreateInProgressDownloadObserver(1));
470 GURL
slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl
);
471 DownloadManager
* manager
= GetCurrentManager();
473 EXPECT_EQ(0, manager
->NonMaliciousInProgressCount());
474 EXPECT_EQ(0, manager
->InProgressCount());
475 if (manager
->InProgressCount() != 0)
478 ui_test_utils::NavigateToURLWithDisposition(
479 current_browser(), slow_download_url
, CURRENT_TAB
,
480 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
482 observer
->WaitForFinished();
483 EXPECT_EQ(1u, observer
->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS
));
485 DownloadManager::DownloadVector items
;
486 manager
->GetAllDownloads(&items
);
488 DownloadItem
* new_item
= NULL
;
489 for (DownloadManager::DownloadVector::iterator iter
= items
.begin();
490 iter
!= items
.end(); ++iter
) {
491 if ((*iter
)->GetState() == DownloadItem::IN_PROGRESS
) {
492 // There should be only one IN_PROGRESS item.
493 EXPECT_EQ(NULL
, new_item
);
500 void FinishPendingSlowDownloads() {
501 scoped_ptr
<content::DownloadTestObserver
> observer(
502 CreateDownloadObserver(1));
503 GURL
finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl
);
504 ui_test_utils::NavigateToURLWithDisposition(
505 current_browser(), finish_url
, NEW_FOREGROUND_TAB
,
506 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
507 observer
->WaitForFinished();
508 EXPECT_EQ(1u, observer
->NumDownloadsSeenInState(DownloadItem::COMPLETE
));
511 content::DownloadTestObserver
* CreateDownloadObserver(size_t download_count
) {
512 return new content::DownloadTestObserverTerminal(
513 GetCurrentManager(), download_count
,
514 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL
);
517 content::DownloadTestObserver
* CreateInProgressDownloadObserver(
518 size_t download_count
) {
519 return new content::DownloadTestObserverInProgress(
520 GetCurrentManager(), download_count
);
523 bool RunFunction(UIThreadExtensionFunction
* function
,
524 const std::string
& args
) {
525 scoped_refptr
<UIThreadExtensionFunction
> delete_function(function
);
526 SetUpExtensionFunction(function
);
527 bool result
= extension_function_test_utils::RunFunction(
528 function
, args
, browser(), GetFlags());
530 LOG(ERROR
) << function
->GetError();
535 extension_function_test_utils::RunFunctionFlags
GetFlags() {
536 return current_browser()->profile()->IsOffTheRecord() ?
537 extension_function_test_utils::INCLUDE_INCOGNITO
:
538 extension_function_test_utils::NONE
;
541 // extension_function_test_utils::RunFunction*() only uses browser for its
542 // profile(), so pass it the on-record browser so that it always uses the
543 // on-record profile to match real-life behavior.
545 base::Value
* RunFunctionAndReturnResult(
546 scoped_refptr
<UIThreadExtensionFunction
> function
,
547 const std::string
& args
) {
548 SetUpExtensionFunction(function
.get());
549 return extension_function_test_utils::RunFunctionAndReturnSingleResult(
550 function
.get(), args
, browser(), GetFlags());
553 std::string
RunFunctionAndReturnError(
554 scoped_refptr
<UIThreadExtensionFunction
> function
,
555 const std::string
& args
) {
556 SetUpExtensionFunction(function
.get());
557 return extension_function_test_utils::RunFunctionAndReturnError(
558 function
.get(), args
, browser(), GetFlags());
561 bool RunFunctionAndReturnString(
562 scoped_refptr
<UIThreadExtensionFunction
> function
,
563 const std::string
& args
,
564 std::string
* result_string
) {
565 SetUpExtensionFunction(function
.get());
566 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(function
, args
));
567 EXPECT_TRUE(result
.get());
568 return result
.get() && result
->GetAsString(result_string
);
571 std::string
DownloadItemIdAsArgList(const DownloadItem
* download_item
) {
572 return base::StringPrintf("[%d]", download_item
->GetId());
575 const base::FilePath
& downloads_directory() {
576 return downloads_directory_
.path();
579 DownloadsEventsListener
* events_listener() { return events_listener_
.get(); }
582 void SetUpExtensionFunction(UIThreadExtensionFunction
* function
) {
584 // Recreate the tab each time for insulation.
585 content::WebContents
* tab
= chrome::AddSelectedTabWithURL(
587 extension_
->GetResourceURL("empty.html"),
588 content::PAGE_TRANSITION_LINK
);
589 function
->set_extension(extension_
);
590 function
->SetRenderViewHost(tab
->GetRenderViewHost());
594 void CreateAndSetDownloadsDirectory() {
595 ASSERT_TRUE(downloads_directory_
.CreateUniqueTempDir());
596 current_browser()->profile()->GetPrefs()->SetFilePath(
597 prefs::kDownloadDefaultDirectory
,
598 downloads_directory_
.path());
601 base::ScopedTempDir downloads_directory_
;
602 const Extension
* extension_
;
603 Browser
* incognito_browser_
;
604 Browser
* current_browser_
;
605 scoped_ptr
<DownloadsEventsListener
> events_listener_
;
607 DISALLOW_COPY_AND_ASSIGN(DownloadExtensionTest
);
610 class MockIconExtractorImpl
: public DownloadFileIconExtractor
{
612 MockIconExtractorImpl(const base::FilePath
& path
,
613 IconLoader::IconSize icon_size
,
614 const std::string
& response
)
615 : expected_path_(path
),
616 expected_icon_size_(icon_size
),
617 response_(response
) {
619 virtual ~MockIconExtractorImpl() {}
621 virtual bool ExtractIconURLForPath(const base::FilePath
& path
,
623 IconLoader::IconSize icon_size
,
624 IconURLCallback callback
) OVERRIDE
{
625 EXPECT_STREQ(expected_path_
.value().c_str(), path
.value().c_str());
626 EXPECT_EQ(expected_icon_size_
, icon_size
);
627 if (expected_path_
== path
&&
628 expected_icon_size_
== icon_size
) {
629 callback_
= callback
;
630 BrowserThread::PostTask(
631 BrowserThread::UI
, FROM_HERE
,
632 base::Bind(&MockIconExtractorImpl::RunCallback
,
633 base::Unretained(this)));
642 callback_
.Run(response_
);
643 // Drop the reference on extension function to avoid memory leaks.
644 callback_
= IconURLCallback();
647 base::FilePath expected_path_
;
648 IconLoader::IconSize expected_icon_size_
;
649 std::string response_
;
650 IconURLCallback callback_
;
653 bool ItemNotInProgress(DownloadItem
* item
) {
654 return item
->GetState() != DownloadItem::IN_PROGRESS
;
657 // Cancels the underlying DownloadItem when the ScopedCancellingItem goes out of
658 // scope. Like a scoped_ptr, but for DownloadItems.
659 class ScopedCancellingItem
{
661 explicit ScopedCancellingItem(DownloadItem
* item
) : item_(item
) {}
662 ~ScopedCancellingItem() {
664 content::DownloadUpdatedObserver
observer(
665 item_
, base::Bind(&ItemNotInProgress
));
666 observer
.WaitForEvent();
668 DownloadItem
* get() { return item_
; }
671 DISALLOW_COPY_AND_ASSIGN(ScopedCancellingItem
);
674 // Cancels all the underlying DownloadItems when the ScopedItemVectorCanceller
675 // goes out of scope. Generalization of ScopedCancellingItem to many
677 class ScopedItemVectorCanceller
{
679 explicit ScopedItemVectorCanceller(DownloadManager::DownloadVector
* items
)
682 ~ScopedItemVectorCanceller() {
683 for (DownloadManager::DownloadVector::const_iterator item
= items_
->begin();
684 item
!= items_
->end(); ++item
) {
685 if ((*item
)->GetState() == DownloadItem::IN_PROGRESS
)
686 (*item
)->Cancel(true);
687 content::DownloadUpdatedObserver
observer(
688 (*item
), base::Bind(&ItemNotInProgress
));
689 observer
.WaitForEvent();
694 DownloadManager::DownloadVector
* items_
;
695 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller
);
698 // Writes an HTML5 file so that it can be downloaded.
699 class HTML5FileWriter
{
701 static bool CreateFileForTesting(fileapi::FileSystemContext
* context
,
702 const fileapi::FileSystemURL
& path
,
705 // Create a temp file.
706 base::FilePath temp_file
;
707 if (!base::CreateTemporaryFile(&temp_file
) ||
708 base::WriteFile(temp_file
, data
, length
) != length
) {
711 // Invoke the fileapi to copy it into the sandboxed filesystem.
713 base::WaitableEvent
done_event(true, false);
714 BrowserThread::PostTask(
715 BrowserThread::IO
, FROM_HERE
,
716 base::Bind(&CreateFileForTestingOnIOThread
,
717 base::Unretained(context
),
719 base::Unretained(&result
),
720 base::Unretained(&done_event
)));
721 // Wait for that to finish.
723 base::DeleteFile(temp_file
, false);
728 static void CopyInCompletion(bool* result
,
729 base::WaitableEvent
* done_event
,
730 base::File::Error error
) {
731 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
732 *result
= error
== base::File::FILE_OK
;
733 done_event
->Signal();
736 static void CreateFileForTestingOnIOThread(
737 fileapi::FileSystemContext
* context
,
738 const fileapi::FileSystemURL
& path
,
739 const base::FilePath
& temp_file
,
741 base::WaitableEvent
* done_event
) {
742 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
743 context
->operation_runner()->CopyInForeignFile(
745 base::Bind(&CopyInCompletion
,
746 base::Unretained(result
),
747 base::Unretained(done_event
)));
751 // TODO(benjhayden) Merge this with the other TestObservers.
752 class JustInProgressDownloadObserver
753 : public content::DownloadTestObserverInProgress
{
755 JustInProgressDownloadObserver(
756 DownloadManager
* download_manager
, size_t wait_count
)
757 : content::DownloadTestObserverInProgress(download_manager
, wait_count
) {
760 virtual ~JustInProgressDownloadObserver() {}
763 virtual bool IsDownloadInFinalState(DownloadItem
* item
) OVERRIDE
{
764 return item
->GetState() == DownloadItem::IN_PROGRESS
;
767 DISALLOW_COPY_AND_ASSIGN(JustInProgressDownloadObserver
);
770 bool ItemIsInterrupted(DownloadItem
* item
) {
771 return item
->GetState() == DownloadItem::INTERRUPTED
;
774 content::DownloadInterruptReason
InterruptReasonExtensionToContent(
775 downloads::InterruptReason error
) {
777 case downloads::INTERRUPT_REASON_NONE
:
778 return content::DOWNLOAD_INTERRUPT_REASON_NONE
;
779 #define INTERRUPT_REASON(name, value) \
780 case downloads::INTERRUPT_REASON_##name: \
781 return content::DOWNLOAD_INTERRUPT_REASON_##name;
782 #include "content/public/browser/download_interrupt_reason_values.h"
783 #undef INTERRUPT_REASON
786 return content::DOWNLOAD_INTERRUPT_REASON_NONE
;
789 downloads::InterruptReason
InterruptReasonContentToExtension(
790 content::DownloadInterruptReason error
) {
792 case content::DOWNLOAD_INTERRUPT_REASON_NONE
:
793 return downloads::INTERRUPT_REASON_NONE
;
794 #define INTERRUPT_REASON(name, value) \
795 case content::DOWNLOAD_INTERRUPT_REASON_##name: \
796 return downloads::INTERRUPT_REASON_##name;
797 #include "content/public/browser/download_interrupt_reason_values.h"
798 #undef INTERRUPT_REASON
801 return downloads::INTERRUPT_REASON_NONE
;
806 #if defined(OS_CHROMEOS)
807 // http://crbug.com/396510
808 #define MAYBE_DownloadExtensionTest_Open DISABLED_DownloadExtensionTest_Open
810 #define MAYBE_DownloadExtensionTest_Open DownloadExtensionTest_Open
812 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
813 MAYBE_DownloadExtensionTest_Open
) {
814 LoadExtension("downloads_split");
815 DownloadsOpenFunction
* open_function
= new DownloadsOpenFunction();
816 open_function
->set_user_gesture(true);
817 EXPECT_STREQ(errors::kInvalidId
,
818 RunFunctionAndReturnError(
822 DownloadItem
* download_item
= CreateSlowTestDownload();
823 ASSERT_TRUE(download_item
);
824 EXPECT_FALSE(download_item
->GetOpened());
825 EXPECT_FALSE(download_item
->GetOpenWhenComplete());
826 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
828 "[{\"danger\": \"safe\","
829 " \"incognito\": false,"
830 " \"mime\": \"application/octet-stream\","
831 " \"paused\": false,"
832 " \"url\": \"%s\"}]",
833 download_item
->GetURL().spec().c_str())));
834 open_function
= new DownloadsOpenFunction();
835 open_function
->set_user_gesture(true);
836 EXPECT_STREQ(errors::kNotComplete
,
837 RunFunctionAndReturnError(
839 DownloadItemIdAsArgList(download_item
)).c_str());
841 FinishPendingSlowDownloads();
842 EXPECT_FALSE(download_item
->GetOpened());
844 open_function
= new DownloadsOpenFunction();
845 EXPECT_STREQ(errors::kUserGesture
,
846 RunFunctionAndReturnError(
848 DownloadItemIdAsArgList(download_item
)).c_str());
849 EXPECT_FALSE(download_item
->GetOpened());
851 open_function
= new DownloadsOpenFunction();
852 open_function
->set_user_gesture(true);
853 EXPECT_TRUE(RunFunction(open_function
,
854 DownloadItemIdAsArgList(download_item
)));
855 EXPECT_TRUE(download_item
->GetOpened());
858 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
859 DownloadExtensionTest_PauseResumeCancelErase
) {
860 DownloadItem
* download_item
= CreateSlowTestDownload();
861 ASSERT_TRUE(download_item
);
864 // Call pause(). It should succeed and the download should be paused on
866 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
867 DownloadItemIdAsArgList(download_item
)));
868 EXPECT_TRUE(download_item
->IsPaused());
870 // Calling removeFile on a non-active download yields kNotComplete
871 // and should not crash. http://crbug.com/319984
872 error
= RunFunctionAndReturnError(new DownloadsRemoveFileFunction(),
873 DownloadItemIdAsArgList(download_item
));
874 EXPECT_STREQ(errors::kNotComplete
, error
.c_str());
876 // Calling pause() twice shouldn't be an error.
877 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
878 DownloadItemIdAsArgList(download_item
)));
879 EXPECT_TRUE(download_item
->IsPaused());
881 // Now try resuming this download. It should succeed.
882 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
883 DownloadItemIdAsArgList(download_item
)));
884 EXPECT_FALSE(download_item
->IsPaused());
886 // Resume again. Resuming a download that wasn't paused is not an error.
887 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
888 DownloadItemIdAsArgList(download_item
)));
889 EXPECT_FALSE(download_item
->IsPaused());
892 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
893 DownloadItemIdAsArgList(download_item
)));
894 EXPECT_TRUE(download_item
->IsPaused());
897 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
898 DownloadItemIdAsArgList(download_item
)));
899 EXPECT_EQ(DownloadItem::CANCELLED
, download_item
->GetState());
901 // Cancel again. Shouldn't have any effect.
902 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
903 DownloadItemIdAsArgList(download_item
)));
904 EXPECT_EQ(DownloadItem::CANCELLED
, download_item
->GetState());
906 // Calling paused on a non-active download yields kNotInProgress.
907 error
= RunFunctionAndReturnError(
908 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item
));
909 EXPECT_STREQ(errors::kNotInProgress
, error
.c_str());
911 // Calling resume on a non-active download yields kNotResumable
912 error
= RunFunctionAndReturnError(
913 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item
));
914 EXPECT_STREQ(errors::kNotResumable
, error
.c_str());
916 // Calling pause on a non-existent download yields kInvalidId.
917 error
= RunFunctionAndReturnError(
918 new DownloadsPauseFunction(), "[-42]");
919 EXPECT_STREQ(errors::kInvalidId
, error
.c_str());
921 // Calling resume on a non-existent download yields kInvalidId
922 error
= RunFunctionAndReturnError(
923 new DownloadsResumeFunction(), "[-42]");
924 EXPECT_STREQ(errors::kInvalidId
, error
.c_str());
926 // Calling removeFile on a non-existent download yields kInvalidId.
927 error
= RunFunctionAndReturnError(
928 new DownloadsRemoveFileFunction(), "[-42]");
929 EXPECT_STREQ(errors::kInvalidId
, error
.c_str());
931 int id
= download_item
->GetId();
932 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
933 new DownloadsEraseFunction(),
934 base::StringPrintf("[{\"id\": %d}]", id
)));
935 DownloadManager::DownloadVector items
;
936 GetCurrentManager()->GetAllDownloads(&items
);
937 EXPECT_EQ(0UL, items
.size());
939 download_item
= NULL
;
940 base::ListValue
* result_list
= NULL
;
941 ASSERT_TRUE(result
->GetAsList(&result_list
));
942 ASSERT_EQ(1UL, result_list
->GetSize());
944 ASSERT_TRUE(result_list
->GetInteger(0, &element
));
945 EXPECT_EQ(id
, element
);
948 scoped_refptr
<UIThreadExtensionFunction
> MockedGetFileIconFunction(
949 const base::FilePath
& expected_path
,
950 IconLoader::IconSize icon_size
,
951 const std::string
& response
) {
952 scoped_refptr
<DownloadsGetFileIconFunction
> function(
953 new DownloadsGetFileIconFunction());
954 function
->SetIconExtractorForTesting(new MockIconExtractorImpl(
955 expected_path
, icon_size
, response
));
959 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted
961 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
962 DownloadExtensionTest_FileIcon_Active
) {
963 DownloadItem
* download_item
= CreateSlowTestDownload();
964 ASSERT_TRUE(download_item
);
965 ASSERT_FALSE(download_item
->GetTargetFilePath().empty());
966 std::string
args32(base::StringPrintf("[%d, {\"size\": 32}]",
967 download_item
->GetId()));
968 std::string result_string
;
970 // Get the icon for the in-progress download. This call should succeed even
971 // if the file type isn't registered.
972 // Test whether the correct path is being pased into the icon extractor.
973 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
974 download_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
975 base::StringPrintf("[%d, {}]", download_item
->GetId()), &result_string
));
977 // Now try a 16x16 icon.
978 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
979 download_item
->GetTargetFilePath(), IconLoader::SMALL
, "foo"),
980 base::StringPrintf("[%d, {\"size\": 16}]", download_item
->GetId()),
983 // Explicitly asking for 32x32 should give us a 32x32 icon.
984 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
985 download_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
986 args32
, &result_string
));
988 // Finish the download and try again.
989 FinishPendingSlowDownloads();
990 EXPECT_EQ(DownloadItem::COMPLETE
, download_item
->GetState());
991 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
992 download_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
993 args32
, &result_string
));
995 // Check the path passed to the icon extractor post-completion.
996 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
997 download_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
998 args32
, &result_string
));
1000 // Now create another download.
1001 download_item
= CreateSlowTestDownload();
1002 ASSERT_TRUE(download_item
);
1003 ASSERT_FALSE(download_item
->GetTargetFilePath().empty());
1004 args32
= base::StringPrintf("[%d, {\"size\": 32}]", download_item
->GetId());
1006 // Cancel the download. As long as the download has a target path, we should
1007 // be able to query the file icon.
1008 download_item
->Cancel(true);
1009 ASSERT_FALSE(download_item
->GetTargetFilePath().empty());
1010 // Let cleanup complete on the FILE thread.
1011 content::RunAllPendingInMessageLoop(BrowserThread::FILE);
1012 // Check the path passed to the icon extractor post-cancellation.
1013 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1014 download_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
1018 // Simulate an error during icon load by invoking the mock with an empty
1020 std::string error
= RunFunctionAndReturnError(
1021 MockedGetFileIconFunction(download_item
->GetTargetFilePath(),
1025 EXPECT_STREQ(errors::kIconNotFound
, error
.c_str());
1027 // Once the download item is deleted, we should return kInvalidId.
1028 int id
= download_item
->GetId();
1029 download_item
->Remove();
1030 download_item
= NULL
;
1031 EXPECT_EQ(static_cast<DownloadItem
*>(NULL
),
1032 GetCurrentManager()->GetDownload(id
));
1033 error
= RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args32
);
1034 EXPECT_STREQ(errors::kInvalidId
,
1038 // Test that we can acquire file icons for history downloads regardless of
1039 // whether they exist or not. If the file doesn't exist we should receive a
1040 // generic icon from the OS/toolkit that may or may not be specific to the file
1042 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1043 DownloadExtensionTest_FileIcon_History
) {
1044 const HistoryDownloadInfo kHistoryInfo
[] = {
1045 { FILE_PATH_LITERAL("real.txt"),
1046 DownloadItem::COMPLETE
,
1047 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
},
1048 { FILE_PATH_LITERAL("fake.txt"),
1049 DownloadItem::COMPLETE
,
1050 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
}
1052 DownloadManager::DownloadVector all_downloads
;
1053 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1056 base::FilePath real_path
= all_downloads
[0]->GetTargetFilePath();
1057 base::FilePath fake_path
= all_downloads
[1]->GetTargetFilePath();
1059 EXPECT_EQ(0, base::WriteFile(real_path
, "", 0));
1060 ASSERT_TRUE(base::PathExists(real_path
));
1061 ASSERT_FALSE(base::PathExists(fake_path
));
1063 for (DownloadManager::DownloadVector::iterator iter
= all_downloads
.begin();
1064 iter
!= all_downloads
.end();
1066 std::string result_string
;
1067 // Use a MockIconExtractorImpl to test if the correct path is being passed
1068 // into the DownloadFileIconExtractor.
1069 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1070 (*iter
)->GetTargetFilePath(), IconLoader::NORMAL
, "hello"),
1071 base::StringPrintf("[%d, {\"size\": 32}]", (*iter
)->GetId()),
1073 EXPECT_STREQ("hello", result_string
.c_str());
1077 // Test passing the empty query to search().
1078 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1079 DownloadExtensionTest_SearchEmptyQuery
) {
1080 ScopedCancellingItem
item(CreateSlowTestDownload());
1081 ASSERT_TRUE(item
.get());
1083 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1084 new DownloadsSearchFunction(), "[{}]"));
1085 ASSERT_TRUE(result
.get());
1086 base::ListValue
* result_list
= NULL
;
1087 ASSERT_TRUE(result
->GetAsList(&result_list
));
1088 ASSERT_EQ(1UL, result_list
->GetSize());
1091 // Test the |filenameRegex| parameter for search().
1092 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1093 DownloadExtensionTest_SearchFilenameRegex
) {
1094 const HistoryDownloadInfo kHistoryInfo
[] = {
1095 { FILE_PATH_LITERAL("foobar"),
1096 DownloadItem::COMPLETE
,
1097 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
},
1098 { FILE_PATH_LITERAL("baz"),
1099 DownloadItem::COMPLETE
,
1100 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
}
1102 DownloadManager::DownloadVector all_downloads
;
1103 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1106 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1107 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]"));
1108 ASSERT_TRUE(result
.get());
1109 base::ListValue
* result_list
= NULL
;
1110 ASSERT_TRUE(result
->GetAsList(&result_list
));
1111 ASSERT_EQ(1UL, result_list
->GetSize());
1112 base::DictionaryValue
* item_value
= NULL
;
1113 ASSERT_TRUE(result_list
->GetDictionary(0, &item_value
));
1115 ASSERT_TRUE(item_value
->GetInteger("id", &item_id
));
1116 ASSERT_EQ(all_downloads
[0]->GetId(), static_cast<uint32
>(item_id
));
1119 // Test the |id| parameter for search().
1120 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
, DownloadExtensionTest_SearchId
) {
1121 DownloadManager::DownloadVector items
;
1122 CreateSlowTestDownloads(2, &items
);
1123 ScopedItemVectorCanceller
delete_items(&items
);
1125 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1126 new DownloadsSearchFunction(), base::StringPrintf(
1127 "[{\"id\": %u}]", items
[0]->GetId())));
1128 ASSERT_TRUE(result
.get());
1129 base::ListValue
* result_list
= NULL
;
1130 ASSERT_TRUE(result
->GetAsList(&result_list
));
1131 ASSERT_EQ(1UL, result_list
->GetSize());
1132 base::DictionaryValue
* item_value
= NULL
;
1133 ASSERT_TRUE(result_list
->GetDictionary(0, &item_value
));
1135 ASSERT_TRUE(item_value
->GetInteger("id", &item_id
));
1136 ASSERT_EQ(items
[0]->GetId(), static_cast<uint32
>(item_id
));
1139 // Test specifying both the |id| and |filename| parameters for search().
1140 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1141 DownloadExtensionTest_SearchIdAndFilename
) {
1142 DownloadManager::DownloadVector items
;
1143 CreateSlowTestDownloads(2, &items
);
1144 ScopedItemVectorCanceller
delete_items(&items
);
1146 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1147 new DownloadsSearchFunction(),
1148 "[{\"id\": 0, \"filename\": \"foobar\"}]"));
1149 ASSERT_TRUE(result
.get());
1150 base::ListValue
* result_list
= NULL
;
1151 ASSERT_TRUE(result
->GetAsList(&result_list
));
1152 ASSERT_EQ(0UL, result_list
->GetSize());
1155 // Test a single |orderBy| parameter for search().
1156 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1157 DownloadExtensionTest_SearchOrderBy
) {
1158 const HistoryDownloadInfo kHistoryInfo
[] = {
1159 { FILE_PATH_LITERAL("zzz"),
1160 DownloadItem::COMPLETE
,
1161 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
},
1162 { FILE_PATH_LITERAL("baz"),
1163 DownloadItem::COMPLETE
,
1164 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
}
1166 DownloadManager::DownloadVector items
;
1167 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1170 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1171 new DownloadsSearchFunction(), "[{\"orderBy\": [\"filename\"]}]"));
1172 ASSERT_TRUE(result
.get());
1173 base::ListValue
* result_list
= NULL
;
1174 ASSERT_TRUE(result
->GetAsList(&result_list
));
1175 ASSERT_EQ(2UL, result_list
->GetSize());
1176 base::DictionaryValue
* item0_value
= NULL
;
1177 base::DictionaryValue
* item1_value
= NULL
;
1178 ASSERT_TRUE(result_list
->GetDictionary(0, &item0_value
));
1179 ASSERT_TRUE(result_list
->GetDictionary(1, &item1_value
));
1180 std::string item0_name
, item1_name
;
1181 ASSERT_TRUE(item0_value
->GetString("filename", &item0_name
));
1182 ASSERT_TRUE(item1_value
->GetString("filename", &item1_name
));
1183 ASSERT_GT(items
[0]->GetTargetFilePath().value(),
1184 items
[1]->GetTargetFilePath().value());
1185 ASSERT_LT(item0_name
, item1_name
);
1188 // Test specifying an empty |orderBy| parameter for search().
1189 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1190 DownloadExtensionTest_SearchOrderByEmpty
) {
1191 const HistoryDownloadInfo kHistoryInfo
[] = {
1192 { FILE_PATH_LITERAL("zzz"),
1193 DownloadItem::COMPLETE
,
1194 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
},
1195 { FILE_PATH_LITERAL("baz"),
1196 DownloadItem::COMPLETE
,
1197 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
}
1199 DownloadManager::DownloadVector items
;
1200 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1203 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1204 new DownloadsSearchFunction(), "[{\"orderBy\": []}]"));
1205 ASSERT_TRUE(result
.get());
1206 base::ListValue
* result_list
= NULL
;
1207 ASSERT_TRUE(result
->GetAsList(&result_list
));
1208 ASSERT_EQ(2UL, result_list
->GetSize());
1209 base::DictionaryValue
* item0_value
= NULL
;
1210 base::DictionaryValue
* item1_value
= NULL
;
1211 ASSERT_TRUE(result_list
->GetDictionary(0, &item0_value
));
1212 ASSERT_TRUE(result_list
->GetDictionary(1, &item1_value
));
1213 std::string item0_name
, item1_name
;
1214 ASSERT_TRUE(item0_value
->GetString("filename", &item0_name
));
1215 ASSERT_TRUE(item1_value
->GetString("filename", &item1_name
));
1216 ASSERT_GT(items
[0]->GetTargetFilePath().value(),
1217 items
[1]->GetTargetFilePath().value());
1218 // The order of results when orderBy is empty is unspecified. When there are
1219 // no sorters, DownloadQuery does not call sort(), so the order of the results
1220 // depends on the order of the items in base::hash_map<uint32,...>
1221 // DownloadManagerImpl::downloads_, which is unspecified and differs between
1222 // libc++ and libstdc++. http://crbug.com/365334
1225 // Test the |danger| option for search().
1226 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1227 DownloadExtensionTest_SearchDanger
) {
1228 const HistoryDownloadInfo kHistoryInfo
[] = {
1229 { FILE_PATH_LITERAL("zzz"),
1230 DownloadItem::COMPLETE
,
1231 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT
},
1232 { FILE_PATH_LITERAL("baz"),
1233 DownloadItem::COMPLETE
,
1234 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
}
1236 DownloadManager::DownloadVector items
;
1237 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1240 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1241 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]"));
1242 ASSERT_TRUE(result
.get());
1243 base::ListValue
* result_list
= NULL
;
1244 ASSERT_TRUE(result
->GetAsList(&result_list
));
1245 ASSERT_EQ(1UL, result_list
->GetSize());
1248 // Test the |state| option for search().
1249 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1250 DownloadExtensionTest_SearchState
) {
1251 DownloadManager::DownloadVector items
;
1252 CreateSlowTestDownloads(2, &items
);
1253 ScopedItemVectorCanceller
delete_items(&items
);
1255 items
[0]->Cancel(true);
1257 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1258 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]"));
1259 ASSERT_TRUE(result
.get());
1260 base::ListValue
* result_list
= NULL
;
1261 ASSERT_TRUE(result
->GetAsList(&result_list
));
1262 ASSERT_EQ(1UL, result_list
->GetSize());
1265 // Test the |limit| option for search().
1266 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1267 DownloadExtensionTest_SearchLimit
) {
1268 DownloadManager::DownloadVector items
;
1269 CreateSlowTestDownloads(2, &items
);
1270 ScopedItemVectorCanceller
delete_items(&items
);
1272 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1273 new DownloadsSearchFunction(), "[{\"limit\": 1}]"));
1274 ASSERT_TRUE(result
.get());
1275 base::ListValue
* result_list
= NULL
;
1276 ASSERT_TRUE(result
->GetAsList(&result_list
));
1277 ASSERT_EQ(1UL, result_list
->GetSize());
1280 // Test invalid search parameters.
1281 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1282 DownloadExtensionTest_SearchInvalid
) {
1283 std::string error
= RunFunctionAndReturnError(
1284 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]");
1285 EXPECT_STREQ(errors::kInvalidFilter
,
1287 error
= RunFunctionAndReturnError(
1288 new DownloadsSearchFunction(), "[{\"orderBy\": [\"goat\"]}]");
1289 EXPECT_STREQ(errors::kInvalidOrderBy
,
1291 error
= RunFunctionAndReturnError(
1292 new DownloadsSearchFunction(), "[{\"limit\": -1}]");
1293 EXPECT_STREQ(errors::kInvalidQueryLimit
,
1297 // Test searching using multiple conditions through multiple downloads.
1298 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1299 DownloadExtensionTest_SearchPlural
) {
1300 const HistoryDownloadInfo kHistoryInfo
[] = {
1301 { FILE_PATH_LITERAL("aaa"),
1302 DownloadItem::CANCELLED
,
1303 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
},
1304 { FILE_PATH_LITERAL("zzz"),
1305 DownloadItem::COMPLETE
,
1306 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT
},
1307 { FILE_PATH_LITERAL("baz"),
1308 DownloadItem::COMPLETE
,
1309 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT
},
1311 DownloadManager::DownloadVector items
;
1312 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1315 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1316 new DownloadsSearchFunction(), "[{"
1317 "\"state\": \"complete\", "
1318 "\"danger\": \"content\", "
1319 "\"orderBy\": [\"filename\"], "
1321 ASSERT_TRUE(result
.get());
1322 base::ListValue
* result_list
= NULL
;
1323 ASSERT_TRUE(result
->GetAsList(&result_list
));
1324 ASSERT_EQ(1UL, result_list
->GetSize());
1325 base::DictionaryValue
* item_value
= NULL
;
1326 ASSERT_TRUE(result_list
->GetDictionary(0, &item_value
));
1327 base::FilePath::StringType item_name
;
1328 ASSERT_TRUE(item_value
->GetString("filename", &item_name
));
1329 ASSERT_EQ(items
[2]->GetTargetFilePath().value(), item_name
);
1332 // Test that incognito downloads are only visible in incognito contexts, and
1333 // test that on-record downloads are visible in both incognito and on-record
1334 // contexts, for DownloadsSearchFunction, DownloadsPauseFunction,
1335 // DownloadsResumeFunction, and DownloadsCancelFunction.
1336 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1337 DownloadExtensionTest_SearchPauseResumeCancelGetFileIconIncognito
) {
1338 scoped_ptr
<base::Value
> result_value
;
1339 base::ListValue
* result_list
= NULL
;
1340 base::DictionaryValue
* result_dict
= NULL
;
1341 base::FilePath::StringType filename
;
1342 bool is_incognito
= false;
1344 std::string on_item_arg
;
1345 std::string off_item_arg
;
1346 std::string result_string
;
1348 // Set up one on-record item and one off-record item.
1349 // Set up the off-record item first because otherwise there are mysteriously 3
1350 // items total instead of 2.
1351 // TODO(benjhayden): Figure out where the third item comes from.
1353 DownloadItem
* off_item
= CreateSlowTestDownload();
1354 ASSERT_TRUE(off_item
);
1355 off_item_arg
= DownloadItemIdAsArgList(off_item
);
1358 DownloadItem
* on_item
= CreateSlowTestDownload();
1359 ASSERT_TRUE(on_item
);
1360 on_item_arg
= DownloadItemIdAsArgList(on_item
);
1361 ASSERT_TRUE(on_item
->GetTargetFilePath() != off_item
->GetTargetFilePath());
1363 // Extensions running in the incognito window should have access to both
1364 // items because the Test extension is in spanning mode.
1366 result_value
.reset(RunFunctionAndReturnResult(
1367 new DownloadsSearchFunction(), "[{}]"));
1368 ASSERT_TRUE(result_value
.get());
1369 ASSERT_TRUE(result_value
->GetAsList(&result_list
));
1370 ASSERT_EQ(2UL, result_list
->GetSize());
1371 ASSERT_TRUE(result_list
->GetDictionary(0, &result_dict
));
1372 ASSERT_TRUE(result_dict
->GetString("filename", &filename
));
1373 ASSERT_TRUE(result_dict
->GetBoolean("incognito", &is_incognito
));
1374 EXPECT_TRUE(on_item
->GetTargetFilePath() == base::FilePath(filename
));
1375 EXPECT_FALSE(is_incognito
);
1376 ASSERT_TRUE(result_list
->GetDictionary(1, &result_dict
));
1377 ASSERT_TRUE(result_dict
->GetString("filename", &filename
));
1378 ASSERT_TRUE(result_dict
->GetBoolean("incognito", &is_incognito
));
1379 EXPECT_TRUE(off_item
->GetTargetFilePath() == base::FilePath(filename
));
1380 EXPECT_TRUE(is_incognito
);
1382 // Extensions running in the on-record window should have access only to the
1385 result_value
.reset(RunFunctionAndReturnResult(
1386 new DownloadsSearchFunction(), "[{}]"));
1387 ASSERT_TRUE(result_value
.get());
1388 ASSERT_TRUE(result_value
->GetAsList(&result_list
));
1389 ASSERT_EQ(1UL, result_list
->GetSize());
1390 ASSERT_TRUE(result_list
->GetDictionary(0, &result_dict
));
1391 ASSERT_TRUE(result_dict
->GetString("filename", &filename
));
1392 EXPECT_TRUE(on_item
->GetTargetFilePath() == base::FilePath(filename
));
1393 ASSERT_TRUE(result_dict
->GetBoolean("incognito", &is_incognito
));
1394 EXPECT_FALSE(is_incognito
);
1396 // Pausing/Resuming the off-record item while on the record should return an
1397 // error. Cancelling "non-existent" downloads is not an error.
1398 error
= RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg
);
1399 EXPECT_STREQ(errors::kInvalidId
,
1401 error
= RunFunctionAndReturnError(new DownloadsResumeFunction(),
1403 EXPECT_STREQ(errors::kInvalidId
,
1405 error
= RunFunctionAndReturnError(
1406 new DownloadsGetFileIconFunction(),
1407 base::StringPrintf("[%d, {}]", off_item
->GetId()));
1408 EXPECT_STREQ(errors::kInvalidId
,
1413 // Do the FileIcon test for both the on- and off-items while off the record.
1414 // NOTE(benjhayden): This does not include the FileIcon test from history,
1415 // just active downloads. This shouldn't be a problem.
1416 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1417 on_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
1418 base::StringPrintf("[%d, {}]", on_item
->GetId()), &result_string
));
1419 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1420 off_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
1421 base::StringPrintf("[%d, {}]", off_item
->GetId()), &result_string
));
1423 // Do the pause/resume/cancel test for both the on- and off-items while off
1425 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg
));
1426 EXPECT_TRUE(on_item
->IsPaused());
1427 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg
));
1428 EXPECT_TRUE(on_item
->IsPaused());
1429 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg
));
1430 EXPECT_FALSE(on_item
->IsPaused());
1431 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg
));
1432 EXPECT_FALSE(on_item
->IsPaused());
1433 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg
));
1434 EXPECT_TRUE(on_item
->IsPaused());
1435 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg
));
1436 EXPECT_EQ(DownloadItem::CANCELLED
, on_item
->GetState());
1437 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg
));
1438 EXPECT_EQ(DownloadItem::CANCELLED
, on_item
->GetState());
1439 error
= RunFunctionAndReturnError(new DownloadsPauseFunction(), on_item_arg
);
1440 EXPECT_STREQ(errors::kNotInProgress
, error
.c_str());
1441 error
= RunFunctionAndReturnError(new DownloadsResumeFunction(), on_item_arg
);
1442 EXPECT_STREQ(errors::kNotResumable
, error
.c_str());
1443 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg
));
1444 EXPECT_TRUE(off_item
->IsPaused());
1445 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg
));
1446 EXPECT_TRUE(off_item
->IsPaused());
1447 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg
));
1448 EXPECT_FALSE(off_item
->IsPaused());
1449 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg
));
1450 EXPECT_FALSE(off_item
->IsPaused());
1451 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg
));
1452 EXPECT_TRUE(off_item
->IsPaused());
1453 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg
));
1454 EXPECT_EQ(DownloadItem::CANCELLED
, off_item
->GetState());
1455 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg
));
1456 EXPECT_EQ(DownloadItem::CANCELLED
, off_item
->GetState());
1457 error
= RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg
);
1458 EXPECT_STREQ(errors::kNotInProgress
, error
.c_str());
1459 error
= RunFunctionAndReturnError(new DownloadsResumeFunction(),
1461 EXPECT_STREQ(errors::kNotResumable
, error
.c_str());
1464 // Test that we can start a download and that the correct sequence of events is
1466 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1467 DownloadExtensionTest_Download_Basic
) {
1468 LoadExtension("downloads_split");
1469 ASSERT_TRUE(StartEmbeddedTestServer());
1470 ASSERT_TRUE(test_server()->Start());
1471 std::string download_url
= test_server()->GetURL("slow?0").spec();
1474 // Start downloading a file.
1475 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1476 new DownloadsDownloadFunction(), base::StringPrintf(
1477 "[{\"url\": \"%s\"}]", download_url
.c_str())));
1478 ASSERT_TRUE(result
.get());
1480 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1481 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1483 ScopedCancellingItem
canceller(item
);
1484 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1486 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1488 "[{\"danger\": \"safe\","
1489 " \"incognito\": false,"
1490 " \"mime\": \"text/plain\","
1491 " \"paused\": false,"
1492 " \"url\": \"%s\"}]",
1493 download_url
.c_str())));
1494 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1498 " \"previous\": \"\","
1499 " \"current\": \"%s\"}}]",
1501 GetFilename("slow.txt").c_str())));
1502 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1506 " \"previous\": \"in_progress\","
1507 " \"current\": \"complete\"}}]",
1511 // Test that we can start a download from an incognito context, and that the
1512 // download knows that it's incognito.
1513 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1514 DownloadExtensionTest_Download_Incognito
) {
1515 LoadExtension("downloads_split");
1516 ASSERT_TRUE(StartEmbeddedTestServer());
1517 ASSERT_TRUE(test_server()->Start());
1519 std::string download_url
= test_server()->GetURL("slow?0").spec();
1521 // Start downloading a file.
1522 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1523 new DownloadsDownloadFunction(), base::StringPrintf(
1524 "[{\"url\": \"%s\"}]", download_url
.c_str())));
1525 ASSERT_TRUE(result
.get());
1527 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1528 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1530 ScopedCancellingItem
canceller(item
);
1531 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1533 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1535 "[{\"danger\": \"safe\","
1536 " \"incognito\": true,"
1537 " \"mime\": \"text/plain\","
1538 " \"paused\": false,"
1539 " \"url\": \"%s\"}]",
1540 download_url
.c_str())));
1541 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1545 " \"previous\": \"\","
1546 " \"current\": \"%s\"}}]",
1548 GetFilename("slow.txt").c_str())));
1549 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1553 " \"current\": \"complete\","
1554 " \"previous\": \"in_progress\"}}]",
1559 // This test is very flaky on Win. http://crbug.com/248438
1560 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1561 DISABLED_DownloadExtensionTest_Download_UnsafeHeaders
1563 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1564 DownloadExtensionTest_Download_UnsafeHeaders
1567 // Test that we disallow certain headers case-insensitively.
1568 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1569 MAYBE_DownloadExtensionTest_Download_UnsafeHeaders
) {
1570 LoadExtension("downloads_split");
1571 ASSERT_TRUE(StartEmbeddedTestServer());
1572 ASSERT_TRUE(test_server()->Start());
1575 static const char* kUnsafeHeaders
[] = {
1582 "coNteNt-traNsfer-eNcodiNg",
1590 "trANsfer-eNcodiNg",
1596 "pRoxY-probably-not-evil",
1597 "sEc-probably-not-evil",
1599 "Access-Control-Request-Headers",
1600 "Access-Control-Request-Method",
1603 for (size_t index
= 0; index
< arraysize(kUnsafeHeaders
); ++index
) {
1604 std::string download_url
= test_server()->GetURL("slow?0").spec();
1605 EXPECT_STREQ(errors::kInvalidHeader
,
1606 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1608 "[{\"url\": \"%s\","
1609 " \"filename\": \"unsafe-header-%d.txt\","
1611 " \"name\": \"%s\","
1612 " \"value\": \"unsafe\"}]}]",
1613 download_url
.c_str(),
1614 static_cast<int>(index
),
1615 kUnsafeHeaders
[index
])).c_str());
1620 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1621 DISABLED_DownloadExtensionTest_Download_Subdirectory
1623 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1624 DownloadExtensionTest_Download_Subdirectory
1626 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1627 MAYBE_DownloadExtensionTest_Download_Subdirectory
) {
1628 LoadExtension("downloads_split");
1629 ASSERT_TRUE(StartEmbeddedTestServer());
1630 ASSERT_TRUE(test_server()->Start());
1631 std::string download_url
= test_server()->GetURL("slow?0").spec();
1634 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1635 new DownloadsDownloadFunction(), base::StringPrintf(
1636 "[{\"url\": \"%s\","
1637 " \"filename\": \"sub/dir/ect/ory.txt\"}]",
1638 download_url
.c_str())));
1639 ASSERT_TRUE(result
.get());
1641 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1642 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1644 ScopedCancellingItem
canceller(item
);
1645 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1647 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1649 "[{\"danger\": \"safe\","
1650 " \"incognito\": false,"
1651 " \"mime\": \"text/plain\","
1652 " \"paused\": false,"
1653 " \"url\": \"%s\"}]",
1654 download_url
.c_str())));
1655 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1659 " \"previous\": \"\","
1660 " \"current\": \"%s\"}}]",
1662 GetFilename("sub/dir/ect/ory.txt").c_str())));
1663 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1667 " \"previous\": \"in_progress\","
1668 " \"current\": \"complete\"}}]",
1672 // Test that invalid filenames are disallowed.
1673 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1674 DownloadExtensionTest_Download_InvalidFilename
) {
1675 LoadExtension("downloads_split");
1676 ASSERT_TRUE(StartEmbeddedTestServer());
1677 ASSERT_TRUE(test_server()->Start());
1678 std::string download_url
= test_server()->GetURL("slow?0").spec();
1681 EXPECT_STREQ(errors::kInvalidFilename
,
1682 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1684 "[{\"url\": \"%s\","
1685 " \"filename\": \"../../../../../etc/passwd\"}]",
1686 download_url
.c_str())).c_str());
1689 // flaky on mac: crbug.com/392288
1690 #if defined(OS_MACOSX)
1691 #define MAYBE_DownloadExtensionTest_Download_InvalidURLs \
1692 DISABLED_DownloadExtensionTest_Download_InvalidURLs
1694 #define MAYBE_DownloadExtensionTest_Download_InvalidURLs \
1695 DownloadExtensionTest_Download_InvalidURLs
1698 // Test that downloading invalid URLs immediately returns kInvalidURLError.
1699 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1700 MAYBE_DownloadExtensionTest_Download_InvalidURLs
) {
1701 LoadExtension("downloads_split");
1704 static const char* kInvalidURLs
[] = {
1710 "foo/bar.html#frag",
1714 for (size_t index
= 0; index
< arraysize(kInvalidURLs
); ++index
) {
1715 EXPECT_STREQ(errors::kInvalidURL
,
1716 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1718 "[{\"url\": \"%s\"}]", kInvalidURLs
[index
])).c_str())
1719 << kInvalidURLs
[index
];
1722 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1723 new DownloadsDownloadFunction(),
1724 "[{\"url\": \"javascript:document.write(\\\"hello\\\");\"}]").c_str());
1725 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1726 new DownloadsDownloadFunction(),
1727 "[{\"url\": \"javascript:return false;\"}]").c_str());
1728 EXPECT_STREQ("NETWORK_FAILED", RunFunctionAndReturnError(
1729 new DownloadsDownloadFunction(),
1730 "[{\"url\": \"ftp://example.com/example.txt\"}]").c_str());
1733 // TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to
1734 // permissions, test downloading from ftp.
1736 // Valid URLs plus fragments are still valid URLs.
1737 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1738 DownloadExtensionTest_Download_URLFragment
) {
1739 LoadExtension("downloads_split");
1740 ASSERT_TRUE(StartEmbeddedTestServer());
1741 ASSERT_TRUE(test_server()->Start());
1742 std::string download_url
= test_server()->GetURL("slow?0#fragment").spec();
1745 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1746 new DownloadsDownloadFunction(), base::StringPrintf(
1747 "[{\"url\": \"%s\"}]", download_url
.c_str())));
1748 ASSERT_TRUE(result
.get());
1750 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1751 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1753 ScopedCancellingItem
canceller(item
);
1754 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1756 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1758 "[{\"danger\": \"safe\","
1759 " \"incognito\": false,"
1760 " \"mime\": \"text/plain\","
1761 " \"paused\": false,"
1762 " \"url\": \"%s\"}]",
1763 download_url
.c_str())));
1764 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1768 " \"previous\": \"\","
1769 " \"current\": \"%s\"}}]",
1771 GetFilename("slow.txt").c_str())));
1772 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1776 " \"previous\": \"in_progress\","
1777 " \"current\": \"complete\"}}]",
1781 // conflictAction may be specified without filename.
1782 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1783 DownloadExtensionTest_Download_ConflictAction
) {
1784 static char kFilename
[] = "download.txt";
1785 LoadExtension("downloads_split");
1786 std::string download_url
= "data:text/plain,hello";
1789 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1790 new DownloadsDownloadFunction(), base::StringPrintf(
1791 "[{\"url\": \"%s\"}]", download_url
.c_str())));
1792 ASSERT_TRUE(result
.get());
1794 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1795 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1797 ScopedCancellingItem
canceller(item
);
1798 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1800 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1802 "[{\"danger\": \"safe\","
1803 " \"incognito\": false,"
1804 " \"mime\": \"text/plain\","
1805 " \"paused\": false,"
1806 " \"url\": \"%s\"}]",
1807 download_url
.c_str())));
1808 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1812 " \"previous\": \"\","
1813 " \"current\": \"%s\"}}]",
1815 GetFilename(kFilename
).c_str())));
1816 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1820 " \"previous\": \"in_progress\","
1821 " \"current\": \"complete\"}}]",
1824 result
.reset(RunFunctionAndReturnResult(
1825 new DownloadsDownloadFunction(), base::StringPrintf(
1826 "[{\"url\": \"%s\", \"conflictAction\": \"overwrite\"}]",
1827 download_url
.c_str())));
1828 ASSERT_TRUE(result
.get());
1830 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1831 item
= GetCurrentManager()->GetDownload(result_id
);
1833 ScopedCancellingItem
canceller2(item
);
1834 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1836 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1838 "[{\"danger\": \"safe\","
1839 " \"incognito\": false,"
1840 " \"mime\": \"text/plain\","
1841 " \"paused\": false,"
1842 " \"url\": \"%s\"}]",
1843 download_url
.c_str())));
1844 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1848 " \"previous\": \"\","
1849 " \"current\": \"%s\"}}]",
1851 GetFilename(kFilename
).c_str())));
1852 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1856 " \"previous\": \"in_progress\","
1857 " \"current\": \"complete\"}}]",
1861 // Valid data URLs are valid URLs.
1862 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1863 DownloadExtensionTest_Download_DataURL
) {
1864 LoadExtension("downloads_split");
1865 std::string download_url
= "data:text/plain,hello";
1868 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1869 new DownloadsDownloadFunction(), base::StringPrintf(
1870 "[{\"url\": \"%s\","
1871 " \"filename\": \"data.txt\"}]", download_url
.c_str())));
1872 ASSERT_TRUE(result
.get());
1874 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1875 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1877 ScopedCancellingItem
canceller(item
);
1878 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1880 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1882 "[{\"danger\": \"safe\","
1883 " \"incognito\": false,"
1884 " \"mime\": \"text/plain\","
1885 " \"paused\": false,"
1886 " \"url\": \"%s\"}]",
1887 download_url
.c_str())));
1888 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1892 " \"previous\": \"\","
1893 " \"current\": \"%s\"}}]",
1895 GetFilename("data.txt").c_str())));
1896 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1900 " \"previous\": \"in_progress\","
1901 " \"current\": \"complete\"}}]",
1905 // Valid file URLs are valid URLs.
1907 // Disabled due to crbug.com/175711
1908 #define MAYBE_DownloadExtensionTest_Download_File \
1909 DISABLED_DownloadExtensionTest_Download_File
1911 #define MAYBE_DownloadExtensionTest_Download_File \
1912 DownloadExtensionTest_Download_File
1914 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1915 MAYBE_DownloadExtensionTest_Download_File
) {
1917 LoadExtension("downloads_split");
1918 std::string download_url
= "file:///";
1920 download_url
+= "C:/";
1923 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1924 new DownloadsDownloadFunction(), base::StringPrintf(
1925 "[{\"url\": \"%s\","
1926 " \"filename\": \"file.txt\"}]", download_url
.c_str())));
1927 ASSERT_TRUE(result
.get());
1929 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1930 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1932 ScopedCancellingItem
canceller(item
);
1933 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1935 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1937 "[{\"danger\": \"safe\","
1938 " \"incognito\": false,"
1939 " \"mime\": \"text/html\","
1940 " \"paused\": false,"
1941 " \"url\": \"%s\"}]",
1942 download_url
.c_str())));
1943 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1947 " \"previous\": \"\","
1948 " \"current\": \"%s\"}}]",
1950 GetFilename("file.txt").c_str())));
1951 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1955 " \"previous\": \"in_progress\","
1956 " \"current\": \"complete\"}}]",
1960 // Test that auth-basic-succeed would fail if the resource requires the
1961 // Authorization header and chrome fails to propagate it back to the server.
1962 // This tests both that testserver.py does not succeed when it should fail as
1963 // well as how the downloads extension API exposes the failure to extensions.
1964 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1965 DownloadExtensionTest_Download_AuthBasic_Fail
) {
1966 LoadExtension("downloads_split");
1967 ASSERT_TRUE(StartEmbeddedTestServer());
1968 ASSERT_TRUE(test_server()->Start());
1969 std::string download_url
= test_server()->GetURL("auth-basic").spec();
1972 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1973 new DownloadsDownloadFunction(), base::StringPrintf(
1974 "[{\"url\": \"%s\","
1975 " \"filename\": \"auth-basic-fail.txt\"}]",
1976 download_url
.c_str())));
1977 ASSERT_TRUE(result
.get());
1979 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1980 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1982 ScopedCancellingItem
canceller(item
);
1983 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1985 ASSERT_TRUE(WaitForInterruption(
1987 content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED
,
1988 base::StringPrintf("[{\"danger\": \"safe\","
1989 " \"incognito\": false,"
1990 " \"mime\": \"text/html\","
1991 " \"paused\": false,"
1992 " \"url\": \"%s\"}]",
1993 download_url
.c_str())));
1996 // Test that DownloadsDownloadFunction propagates |headers| to the URLRequest.
1997 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1998 DownloadExtensionTest_Download_Headers
) {
1999 LoadExtension("downloads_split");
2000 ASSERT_TRUE(StartEmbeddedTestServer());
2001 ASSERT_TRUE(test_server()->Start());
2002 std::string download_url
= test_server()->GetURL("files/downloads/"
2003 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
2006 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2007 new DownloadsDownloadFunction(), base::StringPrintf(
2008 "[{\"url\": \"%s\","
2009 " \"filename\": \"headers-succeed.txt\","
2011 " {\"name\": \"Foo\", \"value\": \"bar\"},"
2012 " {\"name\": \"Qx\", \"value\":\"yo\"}]}]",
2013 download_url
.c_str())));
2014 ASSERT_TRUE(result
.get());
2016 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2017 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2019 ScopedCancellingItem
canceller(item
);
2020 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2022 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2024 "[{\"danger\": \"safe\","
2025 " \"incognito\": false,"
2026 " \"mime\": \"application/octet-stream\","
2027 " \"paused\": false,"
2028 " \"url\": \"%s\"}]",
2029 download_url
.c_str())));
2030 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2034 " \"previous\": \"\","
2035 " \"current\": \"%s\"}}]",
2037 GetFilename("headers-succeed.txt").c_str())));
2038 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2042 " \"previous\": \"in_progress\","
2043 " \"current\": \"complete\"}}]",
2047 // Test that headers-succeed would fail if the resource requires the headers and
2048 // chrome fails to propagate them back to the server. This tests both that
2049 // testserver.py does not succeed when it should fail as well as how the
2050 // downloads extension api exposes the failure to extensions.
2051 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2052 DownloadExtensionTest_Download_Headers_Fail
) {
2053 LoadExtension("downloads_split");
2054 ASSERT_TRUE(StartEmbeddedTestServer());
2055 ASSERT_TRUE(test_server()->Start());
2056 std::string download_url
= test_server()->GetURL("files/downloads/"
2057 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
2060 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2061 new DownloadsDownloadFunction(), base::StringPrintf(
2062 "[{\"url\": \"%s\","
2063 " \"filename\": \"headers-fail.txt\"}]",
2064 download_url
.c_str())));
2065 ASSERT_TRUE(result
.get());
2067 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2068 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2070 ScopedCancellingItem
canceller(item
);
2071 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2073 ASSERT_TRUE(WaitForInterruption(
2075 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT
,
2076 base::StringPrintf("[{\"danger\": \"safe\","
2077 " \"incognito\": false,"
2078 " \"bytesReceived\": 0.0,"
2079 " \"fileSize\": 0.0,"
2081 " \"paused\": false,"
2082 " \"url\": \"%s\"}]",
2083 download_url
.c_str())));
2086 // Test that DownloadsDownloadFunction propagates the Authorization header
2088 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2089 DownloadExtensionTest_Download_AuthBasic
) {
2090 LoadExtension("downloads_split");
2091 ASSERT_TRUE(StartEmbeddedTestServer());
2092 ASSERT_TRUE(test_server()->Start());
2093 std::string download_url
= test_server()->GetURL("auth-basic").spec();
2094 // This is just base64 of 'username:secret'.
2095 static const char* kAuthorization
= "dXNlcm5hbWU6c2VjcmV0";
2098 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2099 new DownloadsDownloadFunction(), base::StringPrintf(
2100 "[{\"url\": \"%s\","
2101 " \"filename\": \"auth-basic-succeed.txt\","
2103 " \"name\": \"Authorization\","
2104 " \"value\": \"Basic %s\"}]}]",
2105 download_url
.c_str(), kAuthorization
)));
2106 ASSERT_TRUE(result
.get());
2108 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2109 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2111 ScopedCancellingItem
canceller(item
);
2112 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2114 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2116 "[{\"danger\": \"safe\","
2117 " \"incognito\": false,"
2118 " \"bytesReceived\": 0.0,"
2119 " \"fileSize\": 0.0,"
2120 " \"mime\": \"text/html\","
2121 " \"paused\": false,"
2122 " \"url\": \"%s\"}]",
2123 download_url
.c_str())));
2124 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2128 " \"previous\": \"in_progress\","
2129 " \"current\": \"complete\"}}]",
2133 // Test that DownloadsDownloadFunction propagates the |method| and |body|
2134 // parameters to the URLRequest.
2135 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2136 DownloadExtensionTest_Download_Post
) {
2137 LoadExtension("downloads_split");
2138 ASSERT_TRUE(StartEmbeddedTestServer());
2139 ASSERT_TRUE(test_server()->Start());
2140 std::string download_url
= test_server()->GetURL("files/post/downloads/"
2141 "a_zip_file.zip?expected_body=BODY").spec();
2144 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2145 new DownloadsDownloadFunction(), base::StringPrintf(
2146 "[{\"url\": \"%s\","
2147 " \"filename\": \"post-succeed.txt\","
2148 " \"method\": \"POST\","
2149 " \"body\": \"BODY\"}]",
2150 download_url
.c_str())));
2151 ASSERT_TRUE(result
.get());
2153 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2154 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2156 ScopedCancellingItem
canceller(item
);
2157 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2159 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2161 "[{\"danger\": \"safe\","
2162 " \"incognito\": false,"
2163 " \"mime\": \"application/octet-stream\","
2164 " \"paused\": false,"
2165 " \"url\": \"%s\"}]",
2166 download_url
.c_str())));
2167 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2171 " \"previous\": \"\","
2172 " \"current\": \"%s\"}}]",
2174 GetFilename("post-succeed.txt").c_str())));
2175 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2179 " \"previous\": \"in_progress\","
2180 " \"current\": \"complete\"}}]",
2184 // Test that downloadPostSuccess would fail if the resource requires the POST
2185 // method, and chrome fails to propagate the |method| parameter back to the
2186 // server. This tests both that testserver.py does not succeed when it should
2187 // fail, and this tests how the downloads extension api exposes the failure to
2189 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2190 DownloadExtensionTest_Download_Post_Get
) {
2191 LoadExtension("downloads_split");
2192 ASSERT_TRUE(StartEmbeddedTestServer());
2193 ASSERT_TRUE(test_server()->Start());
2194 std::string download_url
= test_server()->GetURL("files/post/downloads/"
2195 "a_zip_file.zip?expected_body=BODY").spec();
2198 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2199 new DownloadsDownloadFunction(), base::StringPrintf(
2200 "[{\"url\": \"%s\","
2201 " \"body\": \"BODY\","
2202 " \"filename\": \"post-get.txt\"}]",
2203 download_url
.c_str())));
2204 ASSERT_TRUE(result
.get());
2206 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2207 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2209 ScopedCancellingItem
canceller(item
);
2210 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2212 ASSERT_TRUE(WaitForInterruption(
2214 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT
,
2215 base::StringPrintf("[{\"danger\": \"safe\","
2216 " \"incognito\": false,"
2218 " \"paused\": false,"
2220 " \"url\": \"%s\"}]",
2222 download_url
.c_str())));
2225 // Test that downloadPostSuccess would fail if the resource requires the POST
2226 // method, and chrome fails to propagate the |body| parameter back to the
2227 // server. This tests both that testserver.py does not succeed when it should
2228 // fail, and this tests how the downloads extension api exposes the failure to
2230 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2231 DownloadExtensionTest_Download_Post_NoBody
) {
2232 LoadExtension("downloads_split");
2233 ASSERT_TRUE(StartEmbeddedTestServer());
2234 ASSERT_TRUE(test_server()->Start());
2235 std::string download_url
= test_server()->GetURL("files/post/downloads/"
2236 "a_zip_file.zip?expected_body=BODY").spec();
2239 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2240 new DownloadsDownloadFunction(), base::StringPrintf(
2241 "[{\"url\": \"%s\","
2242 " \"method\": \"POST\","
2243 " \"filename\": \"post-nobody.txt\"}]",
2244 download_url
.c_str())));
2245 ASSERT_TRUE(result
.get());
2247 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2248 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2250 ScopedCancellingItem
canceller(item
);
2251 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2253 ASSERT_TRUE(WaitForInterruption(
2255 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT
,
2256 base::StringPrintf("[{\"danger\": \"safe\","
2257 " \"incognito\": false,"
2259 " \"paused\": false,"
2261 " \"url\": \"%s\"}]",
2263 download_url
.c_str())));
2266 // Test that cancel()ing an in-progress download causes its state to transition
2267 // to interrupted, and test that that state transition is detectable by an
2268 // onChanged event listener. TODO(benjhayden): Test other sources of
2269 // interruptions such as server death.
2270 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2271 DownloadExtensionTest_Download_Cancel
) {
2272 LoadExtension("downloads_split");
2273 ASSERT_TRUE(StartEmbeddedTestServer());
2274 ASSERT_TRUE(test_server()->Start());
2275 std::string download_url
= test_server()->GetURL(
2276 "download-known-size").spec();
2279 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2280 new DownloadsDownloadFunction(), base::StringPrintf(
2281 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2282 ASSERT_TRUE(result
.get());
2284 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2285 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2287 ScopedCancellingItem
canceller(item
);
2288 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2290 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2292 "[{\"danger\": \"safe\","
2293 " \"incognito\": false,"
2294 " \"mime\": \"application/octet-stream\","
2295 " \"paused\": false,"
2297 " \"url\": \"%s\"}]",
2299 download_url
.c_str())));
2301 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2304 " \"error\": {\"current\":\"USER_CANCELED\"},"
2306 " \"previous\": \"in_progress\","
2307 " \"current\": \"interrupted\"}}]",
2311 // flaky on mac: crbug.com/392288
2312 #if defined(OS_MACOSX)
2313 #define MAYBE_DownloadExtensionTest_Download_FileSystemURL \
2314 DISABLED_DownloadExtensionTest_Download_FileSystemURL
2316 #define MAYBE_DownloadExtensionTest_Download_FileSystemURL \
2317 DownloadExtensionTest_Download_FileSystemURL
2320 // Test downloading filesystem: URLs.
2321 // NOTE: chrome disallows creating HTML5 FileSystem Files in incognito.
2322 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2323 MAYBE_DownloadExtensionTest_Download_FileSystemURL
) {
2324 static const char* kPayloadData
= "on the record\ndata";
2326 LoadExtension("downloads_split");
2328 const std::string download_url
= "filesystem:" + GetExtensionURL() +
2329 "temporary/on_record.txt";
2331 // Setup a file in the filesystem which we can download.
2332 ASSERT_TRUE(HTML5FileWriter::CreateFileForTesting(
2333 BrowserContext::GetDefaultStoragePartition(browser()->profile())->
2334 GetFileSystemContext(),
2335 fileapi::FileSystemURL::CreateForTest(GURL(download_url
)),
2336 kPayloadData
, strlen(kPayloadData
)));
2339 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2340 new DownloadsDownloadFunction(), base::StringPrintf(
2341 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2342 ASSERT_TRUE(result
.get());
2344 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2346 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2348 ScopedCancellingItem
canceller(item
);
2349 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2351 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2353 "[{\"danger\": \"safe\","
2354 " \"incognito\": false,"
2355 " \"mime\": \"text/plain\","
2356 " \"paused\": false,"
2357 " \"url\": \"%s\"}]",
2358 download_url
.c_str())));
2359 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2363 " \"previous\": \"\","
2364 " \"current\": \"%s\"}}]",
2366 GetFilename("on_record.txt").c_str())));
2367 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2371 " \"previous\": \"in_progress\","
2372 " \"current\": \"complete\"}}]",
2374 std::string disk_data
;
2375 EXPECT_TRUE(base::ReadFileToString(item
->GetTargetFilePath(), &disk_data
));
2376 EXPECT_STREQ(kPayloadData
, disk_data
.c_str());
2379 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2380 DownloadExtensionTest_OnDeterminingFilename_NoChange
) {
2382 LoadExtension("downloads_split");
2383 AddFilenameDeterminer();
2384 ASSERT_TRUE(StartEmbeddedTestServer());
2385 ASSERT_TRUE(test_server()->Start());
2386 std::string download_url
= test_server()->GetURL("slow?0").spec();
2388 // Start downloading a file.
2389 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2390 new DownloadsDownloadFunction(), base::StringPrintf(
2391 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2392 ASSERT_TRUE(result
.get());
2394 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2395 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2397 ScopedCancellingItem
canceller(item
);
2398 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2400 // Wait for the onCreated and onDeterminingFilename events.
2401 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2403 "[{\"danger\": \"safe\","
2404 " \"incognito\": false,"
2406 " \"mime\": \"text/plain\","
2407 " \"paused\": false,"
2408 " \"url\": \"%s\"}]",
2410 download_url
.c_str())));
2411 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2414 " \"filename\":\"slow.txt\"}]",
2416 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2417 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2419 // Respond to the onDeterminingFilename.
2421 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2422 browser()->profile(),
2427 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2429 EXPECT_EQ("", error
);
2431 // The download should complete successfully.
2432 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2436 " \"previous\": \"\","
2437 " \"current\": \"%s\"}}]",
2439 GetFilename("slow.txt").c_str())));
2440 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2444 " \"previous\": \"in_progress\","
2445 " \"current\": \"complete\"}}]",
2449 // Disabled due to cross-platform flakes; http://crbug.com/370531.
2450 IN_PROC_BROWSER_TEST_F(
2451 DownloadExtensionTest
,
2452 DISABLED_DownloadExtensionTest_OnDeterminingFilename_Timeout
) {
2454 LoadExtension("downloads_split");
2455 AddFilenameDeterminer();
2456 ASSERT_TRUE(StartEmbeddedTestServer());
2457 ASSERT_TRUE(test_server()->Start());
2458 std::string download_url
= test_server()->GetURL("slow?0").spec();
2460 ExtensionDownloadsEventRouter::SetDetermineFilenameTimeoutSecondsForTesting(
2463 // Start downloading a file.
2464 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2465 new DownloadsDownloadFunction(), base::StringPrintf(
2466 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2467 ASSERT_TRUE(result
.get());
2469 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2470 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2472 ScopedCancellingItem
canceller(item
);
2473 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2475 // Wait for the onCreated and onDeterminingFilename events.
2476 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2477 base::StringPrintf("[{\"danger\": \"safe\","
2478 " \"incognito\": false,"
2480 " \"mime\": \"text/plain\","
2481 " \"paused\": false,"
2482 " \"url\": \"%s\"}]",
2484 download_url
.c_str())));
2485 ASSERT_TRUE(WaitFor(
2486 downloads::OnDeterminingFilename::kEventName
,
2487 base::StringPrintf("[{\"id\": %d,"
2488 " \"filename\":\"slow.txt\"}]",
2490 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2491 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2493 // Do not respond to the onDeterminingFilename.
2495 // The download should complete successfully.
2496 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2497 base::StringPrintf("[{\"id\": %d,"
2499 " \"previous\": \"\","
2500 " \"current\": \"%s\"}}]",
2502 GetFilename("slow.txt").c_str())));
2503 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2504 base::StringPrintf("[{\"id\": %d,"
2506 " \"previous\": \"in_progress\","
2507 " \"current\": \"complete\"}}]",
2511 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2512 DownloadExtensionTest_OnDeterminingFilename_Twice
) {
2514 LoadExtension("downloads_split");
2515 AddFilenameDeterminer();
2516 ASSERT_TRUE(StartEmbeddedTestServer());
2517 ASSERT_TRUE(test_server()->Start());
2518 std::string download_url
= test_server()->GetURL("slow?0").spec();
2520 // Start downloading a file.
2521 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2522 new DownloadsDownloadFunction(), base::StringPrintf(
2523 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2524 ASSERT_TRUE(result
.get());
2526 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2527 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2529 ScopedCancellingItem
canceller(item
);
2530 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2532 // Wait for the onCreated and onDeterminingFilename events.
2533 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2534 base::StringPrintf("[{\"danger\": \"safe\","
2535 " \"incognito\": false,"
2537 " \"mime\": \"text/plain\","
2538 " \"paused\": false,"
2539 " \"url\": \"%s\"}]",
2541 download_url
.c_str())));
2542 ASSERT_TRUE(WaitFor(
2543 downloads::OnDeterminingFilename::kEventName
,
2544 base::StringPrintf("[{\"id\": %d,"
2545 " \"filename\":\"slow.txt\"}]",
2547 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2548 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2550 // Respond to the onDeterminingFilename.
2552 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2553 browser()->profile(),
2558 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2560 EXPECT_EQ("", error
);
2562 // Calling DetermineFilename again should return an error instead of calling
2563 // DownloadTargetDeterminer.
2564 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2565 browser()->profile(),
2569 base::FilePath(FILE_PATH_LITERAL("different")),
2570 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
,
2572 EXPECT_EQ(errors::kTooManyListeners
, error
);
2574 // The download should complete successfully.
2575 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2576 base::StringPrintf("[{\"id\": %d,"
2578 " \"previous\": \"\","
2579 " \"current\": \"%s\"}}]",
2581 GetFilename("slow.txt").c_str())));
2582 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2583 base::StringPrintf("[{\"id\": %d,"
2585 " \"previous\": \"in_progress\","
2586 " \"current\": \"complete\"}}]",
2590 IN_PROC_BROWSER_TEST_F(
2591 DownloadExtensionTest
,
2592 DownloadExtensionTest_OnDeterminingFilename_DangerousOverride
) {
2594 LoadExtension("downloads_split");
2595 AddFilenameDeterminer();
2596 ASSERT_TRUE(StartEmbeddedTestServer());
2597 ASSERT_TRUE(test_server()->Start());
2598 std::string download_url
= test_server()->GetURL("slow?0").spec();
2600 // Start downloading a file.
2601 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2602 new DownloadsDownloadFunction(), base::StringPrintf(
2603 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2604 ASSERT_TRUE(result
.get());
2606 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2607 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2609 ScopedCancellingItem
canceller(item
);
2610 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2612 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2614 "[{\"danger\": \"safe\","
2615 " \"incognito\": false,"
2617 " \"mime\": \"text/plain\","
2618 " \"paused\": false,"
2619 " \"url\": \"%s\"}]",
2621 download_url
.c_str())));
2622 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2625 " \"filename\":\"slow.txt\"}]",
2627 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2628 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2630 // Respond to the onDeterminingFilename.
2632 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2633 browser()->profile(),
2637 base::FilePath(FILE_PATH_LITERAL("overridden.swf")),
2638 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2640 EXPECT_EQ("", error
);
2642 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2646 " \"previous\":\"safe\","
2647 " \"current\":\"file\"}}]",
2650 item
->ValidateDangerousDownload();
2651 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2655 " \"previous\":\"file\","
2656 " \"current\":\"accepted\"}}]",
2658 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2662 " \"previous\": \"in_progress\","
2663 " \"current\": \"complete\"}}]",
2665 EXPECT_EQ(downloads_directory().AppendASCII("overridden.swf"),
2666 item
->GetTargetFilePath());
2669 IN_PROC_BROWSER_TEST_F(
2670 DownloadExtensionTest
,
2671 DownloadExtensionTest_OnDeterminingFilename_ReferencesParentInvalid
) {
2673 LoadExtension("downloads_split");
2674 AddFilenameDeterminer();
2675 ASSERT_TRUE(StartEmbeddedTestServer());
2676 ASSERT_TRUE(test_server()->Start());
2677 std::string download_url
= test_server()->GetURL("slow?0").spec();
2679 // Start downloading a file.
2680 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2681 new DownloadsDownloadFunction(), base::StringPrintf(
2682 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2683 ASSERT_TRUE(result
.get());
2685 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2686 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2688 ScopedCancellingItem
canceller(item
);
2689 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2691 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2693 "[{\"danger\": \"safe\","
2694 " \"incognito\": false,"
2696 " \"mime\": \"text/plain\","
2697 " \"paused\": false,"
2698 " \"url\": \"%s\"}]",
2700 download_url
.c_str())));
2701 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2704 " \"filename\":\"slow.txt\"}]",
2706 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2707 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2709 // Respond to the onDeterminingFilename.
2711 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2712 browser()->profile(),
2716 base::FilePath(FILE_PATH_LITERAL("sneaky/../../sneaky.txt")),
2717 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2719 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
2720 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2724 " \"previous\": \"\","
2725 " \"current\": \"%s\"}}]",
2727 GetFilename("slow.txt").c_str())));
2728 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2732 " \"previous\": \"in_progress\","
2733 " \"current\": \"complete\"}}]",
2737 IN_PROC_BROWSER_TEST_F(
2738 DownloadExtensionTest
,
2739 DownloadExtensionTest_OnDeterminingFilename_IllegalFilename
) {
2741 LoadExtension("downloads_split");
2742 AddFilenameDeterminer();
2743 ASSERT_TRUE(StartEmbeddedTestServer());
2744 ASSERT_TRUE(test_server()->Start());
2745 std::string download_url
= test_server()->GetURL("slow?0").spec();
2747 // Start downloading a file.
2748 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2749 new DownloadsDownloadFunction(), base::StringPrintf(
2750 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2751 ASSERT_TRUE(result
.get());
2753 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2754 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2756 ScopedCancellingItem
canceller(item
);
2757 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2759 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2761 "[{\"danger\": \"safe\","
2762 " \"incognito\": false,"
2764 " \"mime\": \"text/plain\","
2765 " \"paused\": false,"
2766 " \"url\": \"%s\"}]",
2768 download_url
.c_str())));
2769 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2772 " \"filename\":\"slow.txt\"}]",
2774 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2775 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2777 // Respond to the onDeterminingFilename.
2779 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2780 browser()->profile(),
2784 base::FilePath(FILE_PATH_LITERAL("<")),
2785 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2787 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
2788 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2792 " \"previous\": \"\","
2793 " \"current\": \"%s\"}}]",
2795 GetFilename("slow.txt").c_str())));
2796 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2800 " \"previous\": \"in_progress\","
2801 " \"current\": \"complete\"}}]",
2805 IN_PROC_BROWSER_TEST_F(
2806 DownloadExtensionTest
,
2807 DownloadExtensionTest_OnDeterminingFilename_IllegalFilenameExtension
) {
2809 LoadExtension("downloads_split");
2810 AddFilenameDeterminer();
2811 ASSERT_TRUE(StartEmbeddedTestServer());
2812 ASSERT_TRUE(test_server()->Start());
2813 std::string download_url
= test_server()->GetURL("slow?0").spec();
2815 // Start downloading a file.
2816 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2817 new DownloadsDownloadFunction(), base::StringPrintf(
2818 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2819 ASSERT_TRUE(result
.get());
2821 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2822 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2824 ScopedCancellingItem
canceller(item
);
2825 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2827 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2829 "[{\"danger\": \"safe\","
2830 " \"incognito\": false,"
2832 " \"mime\": \"text/plain\","
2833 " \"paused\": false,"
2834 " \"url\": \"%s\"}]",
2836 download_url
.c_str())));
2837 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2840 " \"filename\":\"slow.txt\"}]",
2842 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2843 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2845 // Respond to the onDeterminingFilename.
2847 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2848 browser()->profile(),
2852 base::FilePath(FILE_PATH_LITERAL(
2853 "My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}/foo")),
2854 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2856 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
2857 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2861 " \"previous\": \"\","
2862 " \"current\": \"%s\"}}]",
2864 GetFilename("slow.txt").c_str())));
2865 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2869 " \"previous\": \"in_progress\","
2870 " \"current\": \"complete\"}}]",
2874 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2875 DISABLED_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2877 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2878 DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2880 IN_PROC_BROWSER_TEST_F(
2881 DownloadExtensionTest
,
2882 MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
) {
2884 LoadExtension("downloads_split");
2885 AddFilenameDeterminer();
2886 ASSERT_TRUE(StartEmbeddedTestServer());
2887 ASSERT_TRUE(test_server()->Start());
2888 std::string download_url
= test_server()->GetURL("slow?0").spec();
2890 // Start downloading a file.
2891 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2892 new DownloadsDownloadFunction(), base::StringPrintf(
2893 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2894 ASSERT_TRUE(result
.get());
2896 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2897 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2899 ScopedCancellingItem
canceller(item
);
2900 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2902 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2904 "[{\"danger\": \"safe\","
2905 " \"incognito\": false,"
2907 " \"mime\": \"text/plain\","
2908 " \"paused\": false,"
2909 " \"url\": \"%s\"}]",
2911 download_url
.c_str())));
2912 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2915 " \"filename\":\"slow.txt\"}]",
2917 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2918 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2920 // Respond to the onDeterminingFilename.
2922 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2923 browser()->profile(),
2927 base::FilePath(FILE_PATH_LITERAL("con.foo")),
2928 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2930 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
2931 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2935 " \"previous\": \"\","
2936 " \"current\": \"%s\"}}]",
2938 GetFilename("slow.txt").c_str())));
2939 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2943 " \"previous\": \"in_progress\","
2944 " \"current\": \"complete\"}}]",
2948 IN_PROC_BROWSER_TEST_F(
2949 DownloadExtensionTest
,
2950 DownloadExtensionTest_OnDeterminingFilename_CurDirInvalid
) {
2952 LoadExtension("downloads_split");
2953 AddFilenameDeterminer();
2954 ASSERT_TRUE(StartEmbeddedTestServer());
2955 ASSERT_TRUE(test_server()->Start());
2956 std::string download_url
= test_server()->GetURL("slow?0").spec();
2958 // Start downloading a file.
2959 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2960 new DownloadsDownloadFunction(), base::StringPrintf(
2961 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2962 ASSERT_TRUE(result
.get());
2964 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2965 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2967 ScopedCancellingItem
canceller(item
);
2968 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2970 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2972 "[{\"danger\": \"safe\","
2973 " \"incognito\": false,"
2975 " \"mime\": \"text/plain\","
2976 " \"paused\": false,"
2977 " \"url\": \"%s\"}]",
2979 download_url
.c_str())));
2980 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2983 " \"filename\":\"slow.txt\"}]",
2985 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2986 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2988 // Respond to the onDeterminingFilename.
2990 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2991 browser()->profile(),
2995 base::FilePath(FILE_PATH_LITERAL(".")),
2996 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2998 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
2999 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3003 " \"previous\": \"\","
3004 " \"current\": \"%s\"}}]",
3006 GetFilename("slow.txt").c_str())));
3007 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3011 " \"previous\": \"in_progress\","
3012 " \"current\": \"complete\"}}]",
3016 IN_PROC_BROWSER_TEST_F(
3017 DownloadExtensionTest
,
3018 DownloadExtensionTest_OnDeterminingFilename_ParentDirInvalid
) {
3019 ASSERT_TRUE(StartEmbeddedTestServer());
3020 ASSERT_TRUE(test_server()->Start());
3022 LoadExtension("downloads_split");
3023 AddFilenameDeterminer();
3024 std::string download_url
= test_server()->GetURL("slow?0").spec();
3026 // Start downloading a file.
3027 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3028 new DownloadsDownloadFunction(), base::StringPrintf(
3029 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3030 ASSERT_TRUE(result
.get());
3032 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3033 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3035 ScopedCancellingItem
canceller(item
);
3036 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3038 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3040 "[{\"danger\": \"safe\","
3041 " \"incognito\": false,"
3043 " \"mime\": \"text/plain\","
3044 " \"paused\": false,"
3045 " \"url\": \"%s\"}]",
3047 download_url
.c_str())));
3048 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3051 " \"filename\":\"slow.txt\"}]",
3053 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3054 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3056 // Respond to the onDeterminingFilename.
3058 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3059 browser()->profile(),
3063 base::FilePath(FILE_PATH_LITERAL("..")),
3064 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3066 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
3067 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3071 " \"previous\": \"\","
3072 " \"current\": \"%s\"}}]",
3074 GetFilename("slow.txt").c_str())));
3075 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3079 " \"previous\": \"in_progress\","
3080 " \"current\": \"complete\"}}]",
3084 IN_PROC_BROWSER_TEST_F(
3085 DownloadExtensionTest
,
3086 DownloadExtensionTest_OnDeterminingFilename_AbsPathInvalid
) {
3088 LoadExtension("downloads_split");
3089 AddFilenameDeterminer();
3090 ASSERT_TRUE(StartEmbeddedTestServer());
3091 ASSERT_TRUE(test_server()->Start());
3092 std::string download_url
= test_server()->GetURL("slow?0").spec();
3094 // Start downloading a file.
3095 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3096 new DownloadsDownloadFunction(), base::StringPrintf(
3097 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3098 ASSERT_TRUE(result
.get());
3100 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3101 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3103 ScopedCancellingItem
canceller(item
);
3104 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3106 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3108 "[{\"danger\": \"safe\","
3109 " \"incognito\": false,"
3111 " \"mime\": \"text/plain\","
3112 " \"paused\": false,"
3113 " \"url\": \"%s\"}]",
3115 download_url
.c_str())));
3116 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3119 " \"filename\":\"slow.txt\"}]",
3121 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3122 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3124 // Respond to the onDeterminingFilename. Absolute paths should be rejected.
3126 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3127 browser()->profile(),
3131 downloads_directory().Append(FILE_PATH_LITERAL("sneaky.txt")),
3132 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3134 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
3136 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3140 " \"previous\": \"\","
3141 " \"current\": \"%s\"}}]",
3143 GetFilename("slow.txt").c_str())));
3144 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3148 " \"previous\": \"in_progress\","
3149 " \"current\": \"complete\"}}]",
3153 IN_PROC_BROWSER_TEST_F(
3154 DownloadExtensionTest
,
3155 DownloadExtensionTest_OnDeterminingFilename_EmptyBasenameInvalid
) {
3157 LoadExtension("downloads_split");
3158 AddFilenameDeterminer();
3159 ASSERT_TRUE(StartEmbeddedTestServer());
3160 ASSERT_TRUE(test_server()->Start());
3161 std::string download_url
= test_server()->GetURL("slow?0").spec();
3163 // Start downloading a file.
3164 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3165 new DownloadsDownloadFunction(), base::StringPrintf(
3166 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3167 ASSERT_TRUE(result
.get());
3169 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3170 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3172 ScopedCancellingItem
canceller(item
);
3173 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3175 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3177 "[{\"danger\": \"safe\","
3178 " \"incognito\": false,"
3180 " \"mime\": \"text/plain\","
3181 " \"paused\": false,"
3182 " \"url\": \"%s\"}]",
3184 download_url
.c_str())));
3185 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3188 " \"filename\":\"slow.txt\"}]",
3190 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3191 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3193 // Respond to the onDeterminingFilename. Empty basenames should be rejected.
3195 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3196 browser()->profile(),
3200 base::FilePath(FILE_PATH_LITERAL("foo/")),
3201 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3203 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
3205 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3209 " \"previous\": \"\","
3210 " \"current\": \"%s\"}}]",
3212 GetFilename("slow.txt").c_str())));
3213 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3217 " \"previous\": \"in_progress\","
3218 " \"current\": \"complete\"}}]",
3222 // conflictAction may be specified without filename.
3223 IN_PROC_BROWSER_TEST_F(
3224 DownloadExtensionTest
,
3225 DownloadExtensionTest_OnDeterminingFilename_Overwrite
) {
3227 LoadExtension("downloads_split");
3228 AddFilenameDeterminer();
3229 ASSERT_TRUE(StartEmbeddedTestServer());
3230 ASSERT_TRUE(test_server()->Start());
3231 std::string download_url
= test_server()->GetURL("slow?0").spec();
3233 // Start downloading a file.
3234 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3235 new DownloadsDownloadFunction(), base::StringPrintf(
3236 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3237 ASSERT_TRUE(result
.get());
3239 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3240 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3242 ScopedCancellingItem
canceller(item
);
3243 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3244 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3246 "[{\"danger\": \"safe\","
3247 " \"incognito\": false,"
3249 " \"mime\": \"text/plain\","
3250 " \"paused\": false,"
3251 " \"url\": \"%s\"}]",
3253 download_url
.c_str())));
3254 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3257 " \"filename\":\"slow.txt\"}]",
3259 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3260 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3262 // Respond to the onDeterminingFilename.
3264 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3265 browser()->profile(),
3270 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3272 EXPECT_EQ("", error
);
3274 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3278 " \"previous\": \"\","
3279 " \"current\": \"%s\"}}]",
3281 GetFilename("slow.txt").c_str())));
3282 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3286 " \"previous\": \"in_progress\","
3287 " \"current\": \"complete\"}}]",
3290 // Start downloading a file.
3291 result
.reset(RunFunctionAndReturnResult(
3292 new DownloadsDownloadFunction(), base::StringPrintf(
3293 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3294 ASSERT_TRUE(result
.get());
3296 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3297 item
= GetCurrentManager()->GetDownload(result_id
);
3299 ScopedCancellingItem
canceller2(item
);
3300 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3302 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3304 "[{\"danger\": \"safe\","
3305 " \"incognito\": false,"
3307 " \"mime\": \"text/plain\","
3308 " \"paused\": false,"
3309 " \"url\": \"%s\"}]",
3311 download_url
.c_str())));
3312 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3315 " \"filename\":\"slow.txt\"}]",
3317 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3318 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3320 // Respond to the onDeterminingFilename.
3321 // Also test that DetermineFilename allows (chrome) extensions to set
3322 // filenames without (filename) extensions. (Don't ask about v8 extensions or
3323 // python extensions or kernel extensions or firefox extensions...)
3325 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3326 browser()->profile(),
3331 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
,
3333 EXPECT_EQ("", error
);
3335 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3339 " \"previous\": \"\","
3340 " \"current\": \"%s\"}}]",
3342 GetFilename("slow.txt").c_str())));
3343 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3347 " \"previous\": \"in_progress\","
3348 " \"current\": \"complete\"}}]",
3352 IN_PROC_BROWSER_TEST_F(
3353 DownloadExtensionTest
,
3354 DownloadExtensionTest_OnDeterminingFilename_Override
) {
3356 LoadExtension("downloads_split");
3357 AddFilenameDeterminer();
3358 ASSERT_TRUE(StartEmbeddedTestServer());
3359 ASSERT_TRUE(test_server()->Start());
3360 std::string download_url
= test_server()->GetURL("slow?0").spec();
3362 // Start downloading a file.
3363 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3364 new DownloadsDownloadFunction(), base::StringPrintf(
3365 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3366 ASSERT_TRUE(result
.get());
3368 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3369 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3371 ScopedCancellingItem
canceller(item
);
3372 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3373 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3375 "[{\"danger\": \"safe\","
3376 " \"incognito\": false,"
3378 " \"mime\": \"text/plain\","
3379 " \"paused\": false,"
3380 " \"url\": \"%s\"}]",
3382 download_url
.c_str())));
3383 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3386 " \"filename\":\"slow.txt\"}]",
3388 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3389 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3391 // Respond to the onDeterminingFilename.
3393 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3394 browser()->profile(),
3399 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3401 EXPECT_EQ("", error
);
3403 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3407 " \"previous\": \"\","
3408 " \"current\": \"%s\"}}]",
3410 GetFilename("slow.txt").c_str())));
3411 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3415 " \"previous\": \"in_progress\","
3416 " \"current\": \"complete\"}}]",
3419 // Start downloading a file.
3420 result
.reset(RunFunctionAndReturnResult(
3421 new DownloadsDownloadFunction(), base::StringPrintf(
3422 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3423 ASSERT_TRUE(result
.get());
3425 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3426 item
= GetCurrentManager()->GetDownload(result_id
);
3428 ScopedCancellingItem
canceller2(item
);
3429 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3431 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3433 "[{\"danger\": \"safe\","
3434 " \"incognito\": false,"
3436 " \"mime\": \"text/plain\","
3437 " \"paused\": false,"
3438 " \"url\": \"%s\"}]",
3440 download_url
.c_str())));
3441 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3444 " \"filename\":\"slow.txt\"}]",
3446 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3447 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3449 // Respond to the onDeterminingFilename.
3450 // Also test that DetermineFilename allows (chrome) extensions to set
3451 // filenames without (filename) extensions. (Don't ask about v8 extensions or
3452 // python extensions or kernel extensions or firefox extensions...)
3454 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3455 browser()->profile(),
3459 base::FilePath(FILE_PATH_LITERAL("foo")),
3460 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
,
3462 EXPECT_EQ("", error
);
3464 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3468 " \"previous\": \"\","
3469 " \"current\": \"%s\"}}]",
3471 GetFilename("foo").c_str())));
3472 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3476 " \"previous\": \"in_progress\","
3477 " \"current\": \"complete\"}}]",
3481 // TODO test precedence rules: install_time
3483 #if defined(OS_MACOSX)
3484 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer \
3485 DISABLED_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer
3487 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer \
3488 DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer
3490 IN_PROC_BROWSER_TEST_F(
3491 DownloadExtensionTest
,
3492 MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer
) {
3493 ASSERT_TRUE(StartEmbeddedTestServer());
3494 ASSERT_TRUE(test_server()->Start());
3496 LoadExtension("downloads_split");
3497 content::RenderProcessHost
* host
= AddFilenameDeterminer();
3498 std::string download_url
= test_server()->GetURL("slow?0").spec();
3500 // Start downloading a file.
3501 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3502 new DownloadsDownloadFunction(), base::StringPrintf(
3503 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3504 ASSERT_TRUE(result
.get());
3506 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3507 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3509 ScopedCancellingItem
canceller(item
);
3510 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3512 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3514 "[{\"danger\": \"safe\","
3515 " \"incognito\": false,"
3517 " \"mime\": \"text/plain\","
3518 " \"paused\": false,"
3519 " \"url\": \"%s\"}]",
3521 download_url
.c_str())));
3522 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3525 " \"filename\":\"slow.txt\"}]",
3527 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3528 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3530 // Remove a determiner while waiting for it.
3531 RemoveFilenameDeterminer(host
);
3533 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3537 " \"previous\": \"in_progress\","
3538 " \"current\": \"complete\"}}]",
3542 IN_PROC_BROWSER_TEST_F(
3543 DownloadExtensionTest
,
3544 DownloadExtensionTest_OnDeterminingFilename_IncognitoSplit
) {
3545 LoadExtension("downloads_split");
3546 ASSERT_TRUE(StartEmbeddedTestServer());
3547 ASSERT_TRUE(test_server()->Start());
3548 std::string download_url
= test_server()->GetURL("slow?0").spec();
3551 AddFilenameDeterminer();
3554 AddFilenameDeterminer();
3556 // Start an on-record download.
3558 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3559 new DownloadsDownloadFunction(), base::StringPrintf(
3560 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3561 ASSERT_TRUE(result
.get());
3563 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3564 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3566 ScopedCancellingItem
canceller(item
);
3567 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3569 // Wait for the onCreated and onDeterminingFilename events.
3570 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3572 "[{\"danger\": \"safe\","
3573 " \"incognito\": false,"
3575 " \"mime\": \"text/plain\","
3576 " \"paused\": false,"
3577 " \"url\": \"%s\"}]",
3579 download_url
.c_str())));
3580 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3583 " \"incognito\": false,"
3584 " \"filename\":\"slow.txt\"}]",
3586 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3587 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3589 // Respond to the onDeterminingFilename events.
3591 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3592 current_browser()->profile(),
3596 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3597 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3599 EXPECT_EQ("", error
);
3601 // The download should complete successfully.
3602 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3606 " \"previous\": \"\","
3607 " \"current\": \"%s\"}}]",
3609 GetFilename("42.txt").c_str())));
3610 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3614 " \"previous\": \"in_progress\","
3615 " \"current\": \"complete\"}}]",
3618 // Start an incognito download for comparison.
3620 result
.reset(RunFunctionAndReturnResult(
3621 new DownloadsDownloadFunction(), base::StringPrintf(
3622 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3623 ASSERT_TRUE(result
.get());
3625 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3626 item
= GetCurrentManager()->GetDownload(result_id
);
3628 ScopedCancellingItem
canceller2(item
);
3629 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3631 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3633 "[{\"danger\": \"safe\","
3634 " \"incognito\": true,"
3636 " \"mime\": \"text/plain\","
3637 " \"paused\": false,"
3638 " \"url\": \"%s\"}]",
3640 download_url
.c_str())));
3641 // On-Record renderers should not see events for off-record items.
3642 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3645 " \"incognito\": true,"
3646 " \"filename\":\"slow.txt\"}]",
3648 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3649 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3651 // Respond to the onDeterminingFilename.
3653 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3654 current_browser()->profile(),
3658 base::FilePath(FILE_PATH_LITERAL("5.txt")),
3659 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3661 EXPECT_EQ("", error
);
3663 // The download should complete successfully.
3664 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3668 " \"previous\": \"\","
3669 " \"current\": \"%s\"}}]",
3671 GetFilename("5.txt").c_str())));
3672 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3676 " \"previous\": \"in_progress\","
3677 " \"current\": \"complete\"}}]",
3681 IN_PROC_BROWSER_TEST_F(
3682 DownloadExtensionTest
,
3683 DownloadExtensionTest_OnDeterminingFilename_IncognitoSpanning
) {
3684 LoadExtension("downloads_spanning");
3685 ASSERT_TRUE(StartEmbeddedTestServer());
3686 ASSERT_TRUE(test_server()->Start());
3687 std::string download_url
= test_server()->GetURL("slow?0").spec();
3690 AddFilenameDeterminer();
3692 // There is a single extension renderer that sees both on-record and
3693 // off-record events. The extension functions see the on-record profile with
3694 // include_incognito=true.
3696 // Start an on-record download.
3698 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3699 new DownloadsDownloadFunction(), base::StringPrintf(
3700 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3701 ASSERT_TRUE(result
.get());
3703 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3704 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3706 ScopedCancellingItem
canceller(item
);
3707 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3709 // Wait for the onCreated and onDeterminingFilename events.
3710 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3712 "[{\"danger\": \"safe\","
3713 " \"incognito\": false,"
3715 " \"mime\": \"text/plain\","
3716 " \"paused\": false,"
3717 " \"url\": \"%s\"}]",
3719 download_url
.c_str())));
3720 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3723 " \"incognito\": false,"
3724 " \"filename\":\"slow.txt\"}]",
3726 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3727 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3729 // Respond to the onDeterminingFilename events.
3731 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3732 current_browser()->profile(),
3736 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3737 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3739 EXPECT_EQ("", error
);
3741 // The download should complete successfully.
3742 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3746 " \"previous\": \"\","
3747 " \"current\": \"%s\"}}]",
3749 GetFilename("42.txt").c_str())));
3750 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3754 " \"previous\": \"in_progress\","
3755 " \"current\": \"complete\"}}]",
3758 // Start an incognito download for comparison.
3760 result
.reset(RunFunctionAndReturnResult(
3761 new DownloadsDownloadFunction(), base::StringPrintf(
3762 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3763 ASSERT_TRUE(result
.get());
3765 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3766 item
= GetCurrentManager()->GetDownload(result_id
);
3768 ScopedCancellingItem
canceller2(item
);
3769 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3771 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3773 "[{\"danger\": \"safe\","
3774 " \"incognito\": true,"
3776 " \"mime\": \"text/plain\","
3777 " \"paused\": false,"
3778 " \"url\": \"%s\"}]",
3780 download_url
.c_str())));
3781 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3784 " \"incognito\": true,"
3785 " \"filename\":\"slow.txt\"}]",
3787 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3788 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3790 // Respond to the onDeterminingFilename.
3792 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3793 current_browser()->profile(),
3797 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3798 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3800 EXPECT_EQ("", error
);
3802 // The download should complete successfully.
3803 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3807 " \"previous\": \"\","
3808 " \"current\": \"%s\"}}]",
3810 GetFilename("42 (1).txt").c_str())));
3811 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3815 " \"previous\": \"in_progress\","
3816 " \"current\": \"complete\"}}]",
3821 // This test is very flaky on Win XP and Aura. http://crbug.com/248438
3822 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3823 DISABLED_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3825 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3826 DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3829 // Test download interruption while extensions determining filename. Should not
3830 // re-dispatch onDeterminingFilename.
3831 IN_PROC_BROWSER_TEST_F(
3832 DownloadExtensionTest
,
3833 MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
) {
3834 CommandLine::ForCurrentProcess()->AppendSwitch(
3835 switches::kEnableDownloadResumption
);
3836 LoadExtension("downloads_split");
3837 ASSERT_TRUE(StartEmbeddedTestServer());
3838 ASSERT_TRUE(test_server()->Start());
3840 content::RenderProcessHost
* host
= AddFilenameDeterminer();
3842 // Start a download.
3843 DownloadItem
* item
= NULL
;
3845 DownloadManager
* manager
= GetCurrentManager();
3846 scoped_ptr
<content::DownloadTestObserver
> observer(
3847 new JustInProgressDownloadObserver(manager
, 1));
3848 ASSERT_EQ(0, manager
->InProgressCount());
3849 ASSERT_EQ(0, manager
->NonMaliciousInProgressCount());
3850 // Tabs created just for a download are automatically closed, invalidating
3851 // the download's WebContents. Downloads without WebContents cannot be
3852 // resumed. http://crbug.com/225901
3853 ui_test_utils::NavigateToURLWithDisposition(
3855 GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl
),
3857 ui_test_utils::BROWSER_TEST_NONE
);
3858 observer
->WaitForFinished();
3859 EXPECT_EQ(1u, observer
->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS
));
3860 DownloadManager::DownloadVector items
;
3861 manager
->GetAllDownloads(&items
);
3862 for (DownloadManager::DownloadVector::iterator iter
= items
.begin();
3863 iter
!= items
.end(); ++iter
) {
3864 if ((*iter
)->GetState() == DownloadItem::IN_PROGRESS
) {
3865 // There should be only one IN_PROGRESS item.
3866 EXPECT_EQ(NULL
, item
);
3872 ScopedCancellingItem
canceller(item
);
3874 // Wait for the onCreated and onDeterminingFilename event.
3875 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3877 "[{\"danger\": \"safe\","
3878 " \"incognito\": false,"
3880 " \"mime\": \"application/octet-stream\","
3881 " \"paused\": false}]",
3883 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3886 " \"incognito\": false,"
3887 " \"filename\":\"download-unknown-size\"}]",
3889 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3890 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3893 ui_test_utils::NavigateToURLWithDisposition(
3895 GURL(URLRequestSlowDownloadJob::kErrorDownloadUrl
),
3897 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
3899 // Errors caught before filename determination are delayed until after
3900 // filename determination.
3902 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3903 current_browser()->profile(),
3907 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3908 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3911 EXPECT_EQ("", error
);
3912 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3916 " \"previous\": \"\","
3917 " \"current\": \"%s\"}}]",
3919 GetFilename("42.txt").c_str())));
3921 content::DownloadUpdatedObserver
interrupted(item
, base::Bind(
3922 ItemIsInterrupted
));
3923 ASSERT_TRUE(interrupted
.WaitForEvent());
3924 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3927 " \"error\":{\"current\":\"NETWORK_FAILED\"},"
3929 " \"previous\":\"in_progress\","
3930 " \"current\":\"interrupted\"}}]",
3934 // Downloads that are restarted on resumption trigger another download target
3936 RemoveFilenameDeterminer(host
);
3939 // Errors caught before filename determination is complete are delayed until
3940 // after filename determination so that, on resumption, filename determination
3941 // does not need to be re-done. So, there will not be a second
3942 // onDeterminingFilename event.
3944 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3947 " \"error\":{\"previous\":\"NETWORK_FAILED\"},"
3949 " \"previous\":\"interrupted\","
3950 " \"current\":\"in_progress\"}}]",
3954 FinishPendingSlowDownloads();
3956 // The download should complete successfully.
3957 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3961 " \"previous\": \"in_progress\","
3962 " \"current\": \"complete\"}}]",
3966 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
3967 DownloadExtensionTest_SetShelfEnabled
) {
3968 LoadExtension("downloads_split");
3969 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[false]"));
3970 EXPECT_FALSE(DownloadServiceFactory::GetForBrowserContext(
3971 browser()->profile())->IsShelfEnabled());
3972 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[true]"));
3973 EXPECT_TRUE(DownloadServiceFactory::GetForBrowserContext(
3974 browser()->profile())->IsShelfEnabled());
3975 // TODO(benjhayden) Test that existing shelves are hidden.
3976 // TODO(benjhayden) Test multiple extensions.
3977 // TODO(benjhayden) Test disabling extensions.
3978 // TODO(benjhayden) Test that browsers associated with other profiles are not
3980 // TODO(benjhayden) Test incognito.
3983 // TODO(benjhayden) Figure out why DisableExtension() does not fire
3984 // OnListenerRemoved.
3986 // TODO(benjhayden) Test that the shelf is shown for download() both with and
3987 // without a WebContents.
3989 void OnDangerPromptCreated(DownloadDangerPrompt
* prompt
) {
3990 prompt
->InvokeActionForTesting(DownloadDangerPrompt::ACCEPT
);
3993 #if defined(OS_MACOSX)
3994 // Flakily triggers and assert on Mac.
3995 // http://crbug.com/180759
3996 #define MAYBE_DownloadExtensionTest_AcceptDanger DownloadExtensionTest_AcceptDanger
3998 #define MAYBE_DownloadExtensionTest_AcceptDanger DISABLED_DownloadExtensionTest_AcceptDanger
4000 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
4001 MAYBE_DownloadExtensionTest_AcceptDanger
) {
4002 // Download a file that will be marked dangerous; click the browser action
4003 // button; the browser action poup will call acceptDanger(); when the
4004 // DownloadDangerPrompt is created, pretend that the user clicks the Accept
4005 // button; wait until the download completes.
4006 LoadExtension("downloads_split");
4007 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
4008 new DownloadsDownloadFunction(),
4009 "[{\"url\": \"data:,\", \"filename\": \"dangerous.swf\"}]"));
4010 ASSERT_TRUE(result
.get());
4012 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
4013 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
4015 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
4019 " \"previous\": \"safe\","
4020 " \"current\": \"file\"}}]",
4022 ASSERT_TRUE(item
->IsDangerous());
4023 ScopedCancellingItem
canceller(item
);
4024 scoped_ptr
<content::DownloadTestObserver
> observer(
4025 new content::DownloadTestObserverTerminal(
4026 GetCurrentManager(), 1,
4027 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_IGNORE
));
4028 DownloadsAcceptDangerFunction::OnPromptCreatedCallback callback
=
4029 base::Bind(&OnDangerPromptCreated
);
4030 DownloadsAcceptDangerFunction::OnPromptCreatedForTesting(
4032 BrowserActionTestUtil(browser()).Press(0);
4033 observer
->WaitForFinished();
4036 class DownloadsApiTest
: public ExtensionApiTest
{
4038 DownloadsApiTest() {}
4039 virtual ~DownloadsApiTest() {}
4041 DISALLOW_COPY_AND_ASSIGN(DownloadsApiTest
);
4045 IN_PROC_BROWSER_TEST_F(DownloadsApiTest
, DownloadsApiTest
) {
4046 ASSERT_TRUE(RunExtensionTest("downloads")) << message_
;
4049 TEST(DownloadInterruptReasonEnumsSynced
,
4050 DownloadInterruptReasonEnumsSynced
) {
4051 #define INTERRUPT_REASON(name, value) \
4052 EXPECT_EQ(InterruptReasonContentToExtension( \
4053 content::DOWNLOAD_INTERRUPT_REASON_##name), \
4054 downloads::INTERRUPT_REASON_##name); \
4056 InterruptReasonExtensionToContent(downloads::INTERRUPT_REASON_##name), \
4057 content::DOWNLOAD_INTERRUPT_REASON_##name);
4058 #include "content/public/browser/download_interrupt_reason_values.h"
4059 #undef INTERRUPT_REASON
4062 TEST(ExtensionDetermineDownloadFilenameInternal
,
4063 ExtensionDetermineDownloadFilenameInternal
) {
4064 std::string winner_id
;
4065 base::FilePath filename
;
4066 downloads::FilenameConflictAction conflict_action
=
4067 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
;
4068 ExtensionWarningSet warnings
;
4070 // Empty incumbent determiner
4072 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4073 base::FilePath(FILE_PATH_LITERAL("a")),
4074 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
,
4083 EXPECT_EQ("suggester", winner_id
);
4084 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename
.value());
4085 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
, conflict_action
);
4086 EXPECT_TRUE(warnings
.empty());
4090 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4091 base::FilePath(FILE_PATH_LITERAL("b")),
4092 downloads::FILENAME_CONFLICT_ACTION_PROMPT
,
4094 base::Time::Now() - base::TimeDelta::FromDays(1),
4101 EXPECT_EQ("incumbent", winner_id
);
4102 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename
.value());
4103 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
, conflict_action
);
4104 EXPECT_FALSE(warnings
.empty());
4105 EXPECT_EQ(ExtensionWarning::kDownloadFilenameConflict
,
4106 warnings
.begin()->warning_type());
4107 EXPECT_EQ("suggester", warnings
.begin()->extension_id());
4111 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4112 base::FilePath(FILE_PATH_LITERAL("b")),
4113 downloads::FILENAME_CONFLICT_ACTION_PROMPT
,
4117 base::Time::Now() - base::TimeDelta::FromDays(1),
4122 EXPECT_EQ("suggester", winner_id
);
4123 EXPECT_EQ(FILE_PATH_LITERAL("b"), filename
.value());
4124 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_PROMPT
, conflict_action
);
4125 EXPECT_FALSE(warnings
.empty());
4126 EXPECT_EQ(ExtensionWarning::kDownloadFilenameConflict
,
4127 warnings
.begin()->warning_type());
4128 EXPECT_EQ("incumbent", warnings
.begin()->extension_id());
4131 } // namespace extensions
4133 #endif // http://crbug.com/3061144