1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Disable everything on windows only. http://crbug.com/306144
10 #include "base/files/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/json/json_reader.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/stl_util.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/synchronization/waitable_event.h"
18 #include "chrome/browser/download/download_file_icon_extractor.h"
19 #include "chrome/browser/download/download_service.h"
20 #include "chrome/browser/download/download_service_factory.h"
21 #include "chrome/browser/download/download_test_file_activity_observer.h"
22 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
23 #include "chrome/browser/extensions/browser_action_test_util.h"
24 #include "chrome/browser/extensions/extension_apitest.h"
25 #include "chrome/browser/extensions/extension_function_test_utils.h"
26 #include "chrome/browser/net/url_request_mock_util.h"
27 #include "chrome/browser/profiles/profile.h"
28 #include "chrome/browser/ui/browser.h"
29 #include "chrome/browser/ui/browser_tabstrip.h"
30 #include "chrome/common/pref_names.h"
31 #include "chrome/test/base/in_process_browser_test.h"
32 #include "chrome/test/base/ui_test_utils.h"
33 #include "content/public/browser/browser_context.h"
34 #include "content/public/browser/browser_thread.h"
35 #include "content/public/browser/download_item.h"
36 #include "content/public/browser/download_manager.h"
37 #include "content/public/browser/notification_service.h"
38 #include "content/public/browser/storage_partition.h"
39 #include "content/public/browser/web_contents.h"
40 #include "content/public/common/content_switches.h"
41 #include "content/public/test/download_test_observer.h"
42 #include "extensions/browser/event_router.h"
43 #include "extensions/browser/notification_types.h"
44 #include "net/base/data_url.h"
45 #include "net/base/net_util.h"
46 #include "net/test/url_request/url_request_slow_download_job.h"
47 #include "net/url_request/url_request.h"
48 #include "net/url_request/url_request_context.h"
49 #include "net/url_request/url_request_job.h"
50 #include "net/url_request/url_request_job_factory.h"
51 #include "net/url_request/url_request_job_factory_impl.h"
52 #include "storage/browser/fileapi/file_system_context.h"
53 #include "storage/browser/fileapi/file_system_operation_runner.h"
54 #include "storage/browser/fileapi/file_system_url.h"
55 #include "ui/base/page_transition_types.h"
57 using content::BrowserContext
;
58 using content::BrowserThread
;
59 using content::DownloadItem
;
60 using content::DownloadManager
;
62 namespace errors
= download_extension_errors
;
64 namespace extensions
{
65 namespace downloads
= api::downloads
;
69 // Comparator that orders download items by their ID. Can be used with
71 struct DownloadIdComparator
{
72 bool operator() (DownloadItem
* first
, DownloadItem
* second
) {
73 return first
->GetId() < second
->GetId();
77 class DownloadsEventsListener
: public content::NotificationObserver
{
79 DownloadsEventsListener()
82 extensions::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT
,
83 content::NotificationService::AllSources());
86 ~DownloadsEventsListener() override
{
87 registrar_
.Remove(this,
88 extensions::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT
,
89 content::NotificationService::AllSources());
90 STLDeleteElements(&events_
);
94 STLDeleteElements(&events_
);
99 Event(Profile
* profile
,
100 const std::string
& event_name
,
101 const std::string
& json_args
,
104 event_name_(event_name
),
105 json_args_(json_args
),
106 args_(base::JSONReader::DeprecatedRead(json_args
)),
109 const base::Time
& caught() { return caught_
; }
111 bool Satisfies(const Event
& other
) const {
112 return other
.SatisfiedBy(*this);
115 bool SatisfiedBy(const Event
& other
) const {
116 if ((profile_
!= other
.profile_
) ||
117 (event_name_
!= other
.event_name_
))
119 if (((event_name_
== downloads::OnDeterminingFilename::kEventName
) ||
120 (event_name_
== downloads::OnCreated::kEventName
) ||
121 (event_name_
== downloads::OnChanged::kEventName
)) &&
122 args_
.get() && other
.args_
.get()) {
123 base::ListValue
* left_list
= NULL
;
124 base::DictionaryValue
* left_dict
= NULL
;
125 base::ListValue
* right_list
= NULL
;
126 base::DictionaryValue
* right_dict
= NULL
;
127 if (!args_
->GetAsList(&left_list
) ||
128 !other
.args_
->GetAsList(&right_list
) ||
129 !left_list
->GetDictionary(0, &left_dict
) ||
130 !right_list
->GetDictionary(0, &right_dict
))
132 for (base::DictionaryValue::Iterator
iter(*left_dict
);
133 !iter
.IsAtEnd(); iter
.Advance()) {
134 base::Value
* right_value
= NULL
;
135 if (!right_dict
->HasKey(iter
.key()) ||
136 (right_dict
->Get(iter
.key(), &right_value
) &&
137 !iter
.value().Equals(right_value
))) {
142 } else if ((event_name_
== downloads::OnErased::kEventName
) &&
143 args_
.get() && other
.args_
.get()) {
144 int my_id
= -1, other_id
= -1;
145 return (args_
->GetAsInteger(&my_id
) &&
146 other
.args_
->GetAsInteger(&other_id
) &&
149 return json_args_
== other
.json_args_
;
152 std::string
Debug() {
153 return base::StringPrintf("Event(%p, %s, %s, %f)",
162 std::string event_name_
;
163 std::string json_args_
;
164 scoped_ptr
<base::Value
> args_
;
167 DISALLOW_COPY_AND_ASSIGN(Event
);
170 typedef ExtensionDownloadsEventRouter::DownloadsNotificationSource
171 DownloadsNotificationSource
;
173 void Observe(int type
,
174 const content::NotificationSource
& source
,
175 const content::NotificationDetails
& details
) override
{
177 case extensions::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT
: {
178 DownloadsNotificationSource
* dns
=
179 content::Source
<DownloadsNotificationSource
>(source
).ptr();
180 Event
* new_event
= new Event(
181 dns
->profile
, dns
->event_name
,
182 *content::Details
<std::string
>(details
).ptr(), base::Time::Now());
183 events_
.push_back(new_event
);
185 waiting_for_
.get() &&
186 new_event
->Satisfies(*waiting_for_
)) {
188 base::MessageLoopForUI::current()->Quit();
197 bool WaitFor(Profile
* profile
,
198 const std::string
& event_name
,
199 const std::string
& json_args
) {
200 waiting_for_
.reset(new Event(profile
, event_name
, json_args
, base::Time()));
201 for (std::deque
<Event
*>::const_iterator iter
= events_
.begin();
202 iter
!= events_
.end(); ++iter
) {
203 if ((*iter
)->Satisfies(*waiting_for_
.get())) {
208 content::RunMessageLoop();
209 bool success
= !waiting_
;
211 // Print the events that were caught since the last WaitFor() call to help
212 // find the erroneous event.
213 // TODO(benjhayden) Fuzzy-match and highlight the erroneous event.
214 for (std::deque
<Event
*>::const_iterator iter
= events_
.begin();
215 iter
!= events_
.end(); ++iter
) {
216 if ((*iter
)->caught() > last_wait_
) {
217 LOG(INFO
) << "Caught " << (*iter
)->Debug();
220 if (waiting_for_
.get()) {
221 LOG(INFO
) << "Timed out waiting for " << waiting_for_
->Debug();
225 waiting_for_
.reset();
226 last_wait_
= base::Time::Now();
232 base::Time last_wait_
;
233 scoped_ptr
<Event
> waiting_for_
;
234 content::NotificationRegistrar registrar_
;
235 std::deque
<Event
*> events_
;
237 DISALLOW_COPY_AND_ASSIGN(DownloadsEventsListener
);
240 class DownloadExtensionTest
: public ExtensionApiTest
{
242 DownloadExtensionTest()
244 incognito_browser_(NULL
),
245 current_browser_(NULL
) {
249 // Used with CreateHistoryDownloads
250 struct HistoryDownloadInfo
{
251 // Filename to use. CreateHistoryDownloads will append this filename to the
252 // temporary downloads directory specified by downloads_directory().
253 const base::FilePath::CharType
* filename
;
255 // State for the download. Note that IN_PROGRESS downloads will be created
257 DownloadItem::DownloadState state
;
259 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
260 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT.
261 content::DownloadDangerType danger_type
;
264 void LoadExtension(const char* name
) {
265 // Store the created Extension object so that we can attach it to
266 // ExtensionFunctions. Also load the extension in incognito profiles for
267 // testing incognito.
268 extension_
= LoadExtensionIncognito(test_data_dir_
.AppendASCII(name
));
270 content::WebContents
* tab
= chrome::AddSelectedTabWithURL(
272 extension_
->GetResourceURL("empty.html"),
273 ui::PAGE_TRANSITION_LINK
);
274 EventRouter::Get(current_browser()->profile())
275 ->AddEventListener(downloads::OnCreated::kEventName
,
276 tab
->GetRenderProcessHost(),
278 EventRouter::Get(current_browser()->profile())
279 ->AddEventListener(downloads::OnChanged::kEventName
,
280 tab
->GetRenderProcessHost(),
282 EventRouter::Get(current_browser()->profile())
283 ->AddEventListener(downloads::OnErased::kEventName
,
284 tab
->GetRenderProcessHost(),
288 content::RenderProcessHost
* AddFilenameDeterminer() {
289 ExtensionDownloadsEventRouter::SetDetermineFilenameTimeoutSecondsForTesting(
291 content::WebContents
* tab
= chrome::AddSelectedTabWithURL(
293 extension_
->GetResourceURL("empty.html"),
294 ui::PAGE_TRANSITION_LINK
);
295 EventRouter::Get(current_browser()->profile())
296 ->AddEventListener(downloads::OnDeterminingFilename::kEventName
,
297 tab
->GetRenderProcessHost(),
299 return tab
->GetRenderProcessHost();
302 void RemoveFilenameDeterminer(content::RenderProcessHost
* host
) {
303 EventRouter::Get(current_browser()->profile())->RemoveEventListener(
304 downloads::OnDeterminingFilename::kEventName
, host
, GetExtensionId());
307 Browser
* current_browser() { return current_browser_
; }
309 // InProcessBrowserTest
310 void SetUpOnMainThread() override
{
311 ExtensionApiTest::SetUpOnMainThread();
312 BrowserThread::PostTask(
313 BrowserThread::IO
, FROM_HERE
,
314 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled
, true));
315 InProcessBrowserTest::SetUpOnMainThread();
317 CreateAndSetDownloadsDirectory();
318 current_browser()->profile()->GetPrefs()->SetBoolean(
319 prefs::kPromptForDownload
, false);
320 GetOnRecordManager()->RemoveAllDownloads();
321 events_listener_
.reset(new DownloadsEventsListener());
322 // Disable file chooser for current profile.
323 DownloadTestFileActivityObserver
observer(current_browser()->profile());
324 observer
.EnableFileChooser(false);
327 void GoOnTheRecord() { current_browser_
= browser(); }
329 void GoOffTheRecord() {
330 if (!incognito_browser_
) {
331 incognito_browser_
= CreateIncognitoBrowser();
332 GetOffRecordManager()->RemoveAllDownloads();
333 // Disable file chooser for incognito profile.
334 DownloadTestFileActivityObserver
observer(incognito_browser_
->profile());
335 observer
.EnableFileChooser(false);
337 current_browser_
= incognito_browser_
;
340 bool WaitFor(const std::string
& event_name
, const std::string
& json_args
) {
341 return events_listener_
->WaitFor(
342 current_browser()->profile(), event_name
, json_args
);
345 bool WaitForInterruption(
347 content::DownloadInterruptReason expected_error
,
348 const std::string
& on_created_event
) {
349 if (!WaitFor(downloads::OnCreated::kEventName
, on_created_event
))
351 // Now, onCreated is always fired before interruption.
353 downloads::OnChanged::kEventName
,
356 " \"error\": {\"current\": \"%s\"},"
358 " \"previous\": \"in_progress\","
359 " \"current\": \"interrupted\"}}]",
361 content::DownloadInterruptReasonToString(expected_error
).c_str()));
365 events_listener_
->ClearEvents();
368 std::string
GetExtensionURL() {
369 return extension_
->url().spec();
371 std::string
GetExtensionId() {
372 return extension_
->id();
375 std::string
GetFilename(const char* path
) {
377 downloads_directory_
.path().AppendASCII(path
).AsUTF8Unsafe();
379 for (std::string::size_type next
= result
.find("\\");
380 next
!= std::string::npos
;
381 next
= result
.find("\\", next
)) {
382 result
.replace(next
, 1, "\\\\");
389 DownloadManager
* GetOnRecordManager() {
390 return BrowserContext::GetDownloadManager(browser()->profile());
392 DownloadManager
* GetOffRecordManager() {
393 return BrowserContext::GetDownloadManager(
394 browser()->profile()->GetOffTheRecordProfile());
396 DownloadManager
* GetCurrentManager() {
397 return (current_browser_
== incognito_browser_
) ?
398 GetOffRecordManager() : GetOnRecordManager();
401 // Creates a set of history downloads based on the provided |history_info|
402 // array. |count| is the number of elements in |history_info|. On success,
403 // |items| will contain |count| DownloadItems in the order that they were
404 // specified in |history_info|. Returns true on success and false otherwise.
405 bool CreateHistoryDownloads(const HistoryDownloadInfo
* history_info
,
407 DownloadManager::DownloadVector
* items
) {
408 DownloadIdComparator download_id_comparator
;
409 base::Time current
= base::Time::Now();
411 GetOnRecordManager()->GetAllDownloads(items
);
412 CHECK_EQ(0, static_cast<int>(items
->size()));
413 std::vector
<GURL
> url_chain
;
414 url_chain
.push_back(GURL());
415 for (size_t i
= 0; i
< count
; ++i
) {
416 DownloadItem
* item
= GetOnRecordManager()->CreateDownloadItem(
417 content::DownloadItem::kInvalidId
+ 1 + i
,
418 downloads_directory().Append(history_info
[i
].filename
),
419 downloads_directory().Append(history_info
[i
].filename
),
420 url_chain
, GURL(), // URL Chain, referrer
421 std::string(), std::string(), // mime_type, original_mime_type
422 current
, current
, // start_time, end_time
423 std::string(), std::string(), // etag, last_modified
424 1, 1, // received_bytes, total_bytes
425 history_info
[i
].state
, // state
426 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
,
427 content::DOWNLOAD_INTERRUPT_REASON_NONE
,
429 items
->push_back(item
);
432 // Order by ID so that they are in the order that we created them.
433 std::sort(items
->begin(), items
->end(), download_id_comparator
);
434 // Set the danger type if necessary.
435 for (size_t i
= 0; i
< count
; ++i
) {
436 if (history_info
[i
].danger_type
!=
437 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
) {
438 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT
,
439 history_info
[i
].danger_type
);
440 items
->at(i
)->OnContentCheckCompleted(history_info
[i
].danger_type
);
446 void CreateSlowTestDownloads(
447 size_t count
, DownloadManager::DownloadVector
* items
) {
448 for (size_t i
= 0; i
< count
; ++i
) {
449 scoped_ptr
<content::DownloadTestObserver
> observer(
450 CreateInProgressDownloadObserver(1));
451 GURL
slow_download_url(net::URLRequestSlowDownloadJob::kUnknownSizeUrl
);
452 ui_test_utils::NavigateToURL(current_browser(), slow_download_url
);
453 observer
->WaitForFinished();
455 1u, observer
->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS
));
457 GetCurrentManager()->GetAllDownloads(items
);
458 ASSERT_EQ(count
, items
->size());
461 DownloadItem
* CreateSlowTestDownload() {
462 scoped_ptr
<content::DownloadTestObserver
> observer(
463 CreateInProgressDownloadObserver(1));
464 GURL
slow_download_url(net::URLRequestSlowDownloadJob::kUnknownSizeUrl
);
465 DownloadManager
* manager
= GetCurrentManager();
467 EXPECT_EQ(0, manager
->NonMaliciousInProgressCount());
468 EXPECT_EQ(0, manager
->InProgressCount());
469 if (manager
->InProgressCount() != 0)
472 ui_test_utils::NavigateToURL(current_browser(), slow_download_url
);
474 observer
->WaitForFinished();
475 EXPECT_EQ(1u, observer
->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS
));
477 DownloadManager::DownloadVector items
;
478 manager
->GetAllDownloads(&items
);
480 DownloadItem
* new_item
= NULL
;
481 for (DownloadManager::DownloadVector::iterator iter
= items
.begin();
482 iter
!= items
.end(); ++iter
) {
483 if ((*iter
)->GetState() == DownloadItem::IN_PROGRESS
) {
484 // There should be only one IN_PROGRESS item.
485 EXPECT_EQ(NULL
, new_item
);
492 void FinishPendingSlowDownloads() {
493 scoped_ptr
<content::DownloadTestObserver
> observer(
494 CreateDownloadObserver(1));
495 GURL
finish_url(net::URLRequestSlowDownloadJob::kFinishDownloadUrl
);
496 ui_test_utils::NavigateToURLWithDisposition(
497 current_browser(), finish_url
, NEW_FOREGROUND_TAB
,
498 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
499 observer
->WaitForFinished();
500 EXPECT_EQ(1u, observer
->NumDownloadsSeenInState(DownloadItem::COMPLETE
));
503 content::DownloadTestObserver
* CreateDownloadObserver(size_t download_count
) {
504 return new content::DownloadTestObserverTerminal(
505 GetCurrentManager(), download_count
,
506 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL
);
509 content::DownloadTestObserver
* CreateInProgressDownloadObserver(
510 size_t download_count
) {
511 return new content::DownloadTestObserverInProgress(
512 GetCurrentManager(), download_count
);
515 bool RunFunction(UIThreadExtensionFunction
* function
,
516 const std::string
& args
) {
517 scoped_refptr
<UIThreadExtensionFunction
> delete_function(function
);
518 SetUpExtensionFunction(function
);
519 bool result
= extension_function_test_utils::RunFunction(
520 function
, args
, browser(), GetFlags());
522 LOG(ERROR
) << function
->GetError();
527 extension_function_test_utils::RunFunctionFlags
GetFlags() {
528 return current_browser()->profile()->IsOffTheRecord() ?
529 extension_function_test_utils::INCLUDE_INCOGNITO
:
530 extension_function_test_utils::NONE
;
533 // extension_function_test_utils::RunFunction*() only uses browser for its
534 // profile(), so pass it the on-record browser so that it always uses the
535 // on-record profile to match real-life behavior.
537 base::Value
* RunFunctionAndReturnResult(
538 scoped_refptr
<UIThreadExtensionFunction
> function
,
539 const std::string
& args
) {
540 SetUpExtensionFunction(function
.get());
541 return extension_function_test_utils::RunFunctionAndReturnSingleResult(
542 function
.get(), args
, browser(), GetFlags());
545 std::string
RunFunctionAndReturnError(
546 scoped_refptr
<UIThreadExtensionFunction
> function
,
547 const std::string
& args
) {
548 SetUpExtensionFunction(function
.get());
549 return extension_function_test_utils::RunFunctionAndReturnError(
550 function
.get(), args
, browser(), GetFlags());
553 bool RunFunctionAndReturnString(
554 scoped_refptr
<UIThreadExtensionFunction
> function
,
555 const std::string
& args
,
556 std::string
* result_string
) {
557 SetUpExtensionFunction(function
.get());
558 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(function
, args
));
559 EXPECT_TRUE(result
.get());
560 return result
.get() && result
->GetAsString(result_string
);
563 std::string
DownloadItemIdAsArgList(const DownloadItem
* download_item
) {
564 return base::StringPrintf("[%d]", download_item
->GetId());
567 const base::FilePath
& downloads_directory() {
568 return downloads_directory_
.path();
571 DownloadsEventsListener
* events_listener() { return events_listener_
.get(); }
574 void SetUpExtensionFunction(UIThreadExtensionFunction
* function
) {
576 // Recreate the tab each time for insulation.
577 content::WebContents
* tab
= chrome::AddSelectedTabWithURL(
579 extension_
->GetResourceURL("empty.html"),
580 ui::PAGE_TRANSITION_LINK
);
581 function
->set_extension(extension_
);
582 function
->SetRenderFrameHost(tab
->GetMainFrame());
586 void CreateAndSetDownloadsDirectory() {
587 ASSERT_TRUE(downloads_directory_
.CreateUniqueTempDir());
588 current_browser()->profile()->GetPrefs()->SetFilePath(
589 prefs::kDownloadDefaultDirectory
,
590 downloads_directory_
.path());
593 base::ScopedTempDir downloads_directory_
;
594 const Extension
* extension_
;
595 Browser
* incognito_browser_
;
596 Browser
* current_browser_
;
597 scoped_ptr
<DownloadsEventsListener
> events_listener_
;
599 DISALLOW_COPY_AND_ASSIGN(DownloadExtensionTest
);
602 class MockIconExtractorImpl
: public DownloadFileIconExtractor
{
604 MockIconExtractorImpl(const base::FilePath
& path
,
605 IconLoader::IconSize icon_size
,
606 const std::string
& response
)
607 : expected_path_(path
),
608 expected_icon_size_(icon_size
),
609 response_(response
) {
611 ~MockIconExtractorImpl() override
{}
613 bool ExtractIconURLForPath(const base::FilePath
& path
,
615 IconLoader::IconSize icon_size
,
616 IconURLCallback callback
) override
{
617 EXPECT_STREQ(expected_path_
.value().c_str(), path
.value().c_str());
618 EXPECT_EQ(expected_icon_size_
, icon_size
);
619 if (expected_path_
== path
&&
620 expected_icon_size_
== icon_size
) {
621 callback_
= callback
;
622 BrowserThread::PostTask(
623 BrowserThread::UI
, FROM_HERE
,
624 base::Bind(&MockIconExtractorImpl::RunCallback
,
625 base::Unretained(this)));
634 callback_
.Run(response_
);
635 // Drop the reference on extension function to avoid memory leaks.
636 callback_
= IconURLCallback();
639 base::FilePath expected_path_
;
640 IconLoader::IconSize expected_icon_size_
;
641 std::string response_
;
642 IconURLCallback callback_
;
645 bool ItemNotInProgress(DownloadItem
* item
) {
646 return item
->GetState() != DownloadItem::IN_PROGRESS
;
649 // Cancels the underlying DownloadItem when the ScopedCancellingItem goes out of
650 // scope. Like a scoped_ptr, but for DownloadItems.
651 class ScopedCancellingItem
{
653 explicit ScopedCancellingItem(DownloadItem
* item
) : item_(item
) {}
654 ~ScopedCancellingItem() {
656 content::DownloadUpdatedObserver
observer(
657 item_
, base::Bind(&ItemNotInProgress
));
658 observer
.WaitForEvent();
660 DownloadItem
* get() { return item_
; }
663 DISALLOW_COPY_AND_ASSIGN(ScopedCancellingItem
);
666 // Cancels all the underlying DownloadItems when the ScopedItemVectorCanceller
667 // goes out of scope. Generalization of ScopedCancellingItem to many
669 class ScopedItemVectorCanceller
{
671 explicit ScopedItemVectorCanceller(DownloadManager::DownloadVector
* items
)
674 ~ScopedItemVectorCanceller() {
675 for (DownloadManager::DownloadVector::const_iterator item
= items_
->begin();
676 item
!= items_
->end(); ++item
) {
677 if ((*item
)->GetState() == DownloadItem::IN_PROGRESS
)
678 (*item
)->Cancel(true);
679 content::DownloadUpdatedObserver
observer(
680 (*item
), base::Bind(&ItemNotInProgress
));
681 observer
.WaitForEvent();
686 DownloadManager::DownloadVector
* items_
;
687 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller
);
690 // Writes an HTML5 file so that it can be downloaded.
691 class HTML5FileWriter
{
693 static bool CreateFileForTesting(storage::FileSystemContext
* context
,
694 const storage::FileSystemURL
& path
,
697 // Create a temp file.
698 base::FilePath temp_file
;
699 if (!base::CreateTemporaryFile(&temp_file
) ||
700 base::WriteFile(temp_file
, data
, length
) != length
) {
703 // Invoke the fileapi to copy it into the sandboxed filesystem.
705 base::WaitableEvent
done_event(true, false);
706 BrowserThread::PostTask(
707 BrowserThread::IO
, FROM_HERE
,
708 base::Bind(&CreateFileForTestingOnIOThread
,
709 base::Unretained(context
),
711 base::Unretained(&result
),
712 base::Unretained(&done_event
)));
713 // Wait for that to finish.
715 base::DeleteFile(temp_file
, false);
720 static void CopyInCompletion(bool* result
,
721 base::WaitableEvent
* done_event
,
722 base::File::Error error
) {
723 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
724 *result
= error
== base::File::FILE_OK
;
725 done_event
->Signal();
728 static void CreateFileForTestingOnIOThread(
729 storage::FileSystemContext
* context
,
730 const storage::FileSystemURL
& path
,
731 const base::FilePath
& temp_file
,
733 base::WaitableEvent
* done_event
) {
734 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
735 context
->operation_runner()->CopyInForeignFile(
737 base::Bind(&CopyInCompletion
,
738 base::Unretained(result
),
739 base::Unretained(done_event
)));
743 // TODO(benjhayden) Merge this with the other TestObservers.
744 class JustInProgressDownloadObserver
745 : public content::DownloadTestObserverInProgress
{
747 JustInProgressDownloadObserver(
748 DownloadManager
* download_manager
, size_t wait_count
)
749 : content::DownloadTestObserverInProgress(download_manager
, wait_count
) {
752 ~JustInProgressDownloadObserver() override
{}
755 bool IsDownloadInFinalState(DownloadItem
* item
) override
{
756 return item
->GetState() == DownloadItem::IN_PROGRESS
;
759 DISALLOW_COPY_AND_ASSIGN(JustInProgressDownloadObserver
);
762 bool ItemIsInterrupted(DownloadItem
* item
) {
763 return item
->GetState() == DownloadItem::INTERRUPTED
;
766 content::DownloadInterruptReason
InterruptReasonExtensionToContent(
767 downloads::InterruptReason error
) {
769 case downloads::INTERRUPT_REASON_NONE
:
770 return content::DOWNLOAD_INTERRUPT_REASON_NONE
;
771 #define INTERRUPT_REASON(name, value) \
772 case downloads::INTERRUPT_REASON_##name: \
773 return content::DOWNLOAD_INTERRUPT_REASON_##name;
774 #include "content/public/browser/download_interrupt_reason_values.h"
775 #undef INTERRUPT_REASON
778 return content::DOWNLOAD_INTERRUPT_REASON_NONE
;
781 downloads::InterruptReason
InterruptReasonContentToExtension(
782 content::DownloadInterruptReason error
) {
784 case content::DOWNLOAD_INTERRUPT_REASON_NONE
:
785 return downloads::INTERRUPT_REASON_NONE
;
786 #define INTERRUPT_REASON(name, value) \
787 case content::DOWNLOAD_INTERRUPT_REASON_##name: \
788 return downloads::INTERRUPT_REASON_##name;
789 #include "content/public/browser/download_interrupt_reason_values.h"
790 #undef INTERRUPT_REASON
793 return downloads::INTERRUPT_REASON_NONE
;
798 #if defined(OS_CHROMEOS)
799 // http://crbug.com/396510
800 #define MAYBE_DownloadExtensionTest_Open DISABLED_DownloadExtensionTest_Open
802 #define MAYBE_DownloadExtensionTest_Open DownloadExtensionTest_Open
804 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
805 MAYBE_DownloadExtensionTest_Open
) {
806 LoadExtension("downloads_split");
807 DownloadsOpenFunction
* open_function
= new DownloadsOpenFunction();
808 open_function
->set_user_gesture(true);
809 EXPECT_STREQ(errors::kInvalidId
,
810 RunFunctionAndReturnError(
814 DownloadItem
* download_item
= CreateSlowTestDownload();
815 ASSERT_TRUE(download_item
);
816 EXPECT_FALSE(download_item
->GetOpened());
817 EXPECT_FALSE(download_item
->GetOpenWhenComplete());
818 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
820 "[{\"danger\": \"safe\","
821 " \"incognito\": false,"
822 " \"mime\": \"application/octet-stream\","
823 " \"paused\": false,"
824 " \"url\": \"%s\"}]",
825 download_item
->GetURL().spec().c_str())));
826 open_function
= new DownloadsOpenFunction();
827 open_function
->set_user_gesture(true);
828 EXPECT_STREQ(errors::kNotComplete
,
829 RunFunctionAndReturnError(
831 DownloadItemIdAsArgList(download_item
)).c_str());
833 FinishPendingSlowDownloads();
834 EXPECT_FALSE(download_item
->GetOpened());
836 open_function
= new DownloadsOpenFunction();
837 EXPECT_STREQ(errors::kUserGesture
,
838 RunFunctionAndReturnError(
840 DownloadItemIdAsArgList(download_item
)).c_str());
841 EXPECT_FALSE(download_item
->GetOpened());
843 open_function
= new DownloadsOpenFunction();
844 open_function
->set_user_gesture(true);
845 EXPECT_TRUE(RunFunction(open_function
,
846 DownloadItemIdAsArgList(download_item
)));
847 EXPECT_TRUE(download_item
->GetOpened());
850 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
851 DownloadExtensionTest_PauseResumeCancelErase
) {
852 DownloadItem
* download_item
= CreateSlowTestDownload();
853 ASSERT_TRUE(download_item
);
856 // Call pause(). It should succeed and the download should be paused on
858 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
859 DownloadItemIdAsArgList(download_item
)));
860 EXPECT_TRUE(download_item
->IsPaused());
862 // Calling removeFile on a non-active download yields kNotComplete
863 // and should not crash. http://crbug.com/319984
864 error
= RunFunctionAndReturnError(new DownloadsRemoveFileFunction(),
865 DownloadItemIdAsArgList(download_item
));
866 EXPECT_STREQ(errors::kNotComplete
, error
.c_str());
868 // Calling pause() twice shouldn't be an error.
869 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
870 DownloadItemIdAsArgList(download_item
)));
871 EXPECT_TRUE(download_item
->IsPaused());
873 // Now try resuming this download. It should succeed.
874 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
875 DownloadItemIdAsArgList(download_item
)));
876 EXPECT_FALSE(download_item
->IsPaused());
878 // Resume again. Resuming a download that wasn't paused is not an error.
879 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
880 DownloadItemIdAsArgList(download_item
)));
881 EXPECT_FALSE(download_item
->IsPaused());
884 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
885 DownloadItemIdAsArgList(download_item
)));
886 EXPECT_TRUE(download_item
->IsPaused());
889 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
890 DownloadItemIdAsArgList(download_item
)));
891 EXPECT_EQ(DownloadItem::CANCELLED
, download_item
->GetState());
893 // Cancel again. Shouldn't have any effect.
894 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
895 DownloadItemIdAsArgList(download_item
)));
896 EXPECT_EQ(DownloadItem::CANCELLED
, download_item
->GetState());
898 // Calling paused on a non-active download yields kNotInProgress.
899 error
= RunFunctionAndReturnError(
900 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item
));
901 EXPECT_STREQ(errors::kNotInProgress
, error
.c_str());
903 // Calling resume on a non-active download yields kNotResumable
904 error
= RunFunctionAndReturnError(
905 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item
));
906 EXPECT_STREQ(errors::kNotResumable
, error
.c_str());
908 // Calling pause on a non-existent download yields kInvalidId.
909 error
= RunFunctionAndReturnError(
910 new DownloadsPauseFunction(), "[-42]");
911 EXPECT_STREQ(errors::kInvalidId
, error
.c_str());
913 // Calling resume on a non-existent download yields kInvalidId
914 error
= RunFunctionAndReturnError(
915 new DownloadsResumeFunction(), "[-42]");
916 EXPECT_STREQ(errors::kInvalidId
, error
.c_str());
918 // Calling removeFile on a non-existent download yields kInvalidId.
919 error
= RunFunctionAndReturnError(
920 new DownloadsRemoveFileFunction(), "[-42]");
921 EXPECT_STREQ(errors::kInvalidId
, error
.c_str());
923 int id
= download_item
->GetId();
924 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
925 new DownloadsEraseFunction(),
926 base::StringPrintf("[{\"id\": %d}]", id
)));
927 DownloadManager::DownloadVector items
;
928 GetCurrentManager()->GetAllDownloads(&items
);
929 EXPECT_EQ(0UL, items
.size());
931 download_item
= NULL
;
932 base::ListValue
* result_list
= NULL
;
933 ASSERT_TRUE(result
->GetAsList(&result_list
));
934 ASSERT_EQ(1UL, result_list
->GetSize());
936 ASSERT_TRUE(result_list
->GetInteger(0, &element
));
937 EXPECT_EQ(id
, element
);
940 scoped_refptr
<UIThreadExtensionFunction
> MockedGetFileIconFunction(
941 const base::FilePath
& expected_path
,
942 IconLoader::IconSize icon_size
,
943 const std::string
& response
) {
944 scoped_refptr
<DownloadsGetFileIconFunction
> function(
945 new DownloadsGetFileIconFunction());
946 function
->SetIconExtractorForTesting(new MockIconExtractorImpl(
947 expected_path
, icon_size
, response
));
951 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted
953 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
954 DownloadExtensionTest_FileIcon_Active
) {
955 DownloadItem
* download_item
= CreateSlowTestDownload();
956 ASSERT_TRUE(download_item
);
957 ASSERT_FALSE(download_item
->GetTargetFilePath().empty());
958 std::string
args32(base::StringPrintf("[%d, {\"size\": 32}]",
959 download_item
->GetId()));
960 std::string result_string
;
962 // Get the icon for the in-progress download. This call should succeed even
963 // if the file type isn't registered.
964 // Test whether the correct path is being pased into the icon extractor.
965 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
966 download_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
967 base::StringPrintf("[%d, {}]", download_item
->GetId()), &result_string
));
969 // Now try a 16x16 icon.
970 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
971 download_item
->GetTargetFilePath(), IconLoader::SMALL
, "foo"),
972 base::StringPrintf("[%d, {\"size\": 16}]", download_item
->GetId()),
975 // Explicitly asking for 32x32 should give us a 32x32 icon.
976 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
977 download_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
978 args32
, &result_string
));
980 // Finish the download and try again.
981 FinishPendingSlowDownloads();
982 EXPECT_EQ(DownloadItem::COMPLETE
, download_item
->GetState());
983 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
984 download_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
985 args32
, &result_string
));
987 // Check the path passed to the icon extractor post-completion.
988 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
989 download_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
990 args32
, &result_string
));
992 // Now create another download.
993 download_item
= CreateSlowTestDownload();
994 ASSERT_TRUE(download_item
);
995 ASSERT_FALSE(download_item
->GetTargetFilePath().empty());
996 args32
= base::StringPrintf("[%d, {\"size\": 32}]", download_item
->GetId());
998 // Cancel the download. As long as the download has a target path, we should
999 // be able to query the file icon.
1000 download_item
->Cancel(true);
1001 ASSERT_FALSE(download_item
->GetTargetFilePath().empty());
1002 // Let cleanup complete on the FILE thread.
1003 content::RunAllPendingInMessageLoop(BrowserThread::FILE);
1004 // Check the path passed to the icon extractor post-cancellation.
1005 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1006 download_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
1010 // Simulate an error during icon load by invoking the mock with an empty
1012 std::string error
= RunFunctionAndReturnError(
1013 MockedGetFileIconFunction(download_item
->GetTargetFilePath(),
1017 EXPECT_STREQ(errors::kIconNotFound
, error
.c_str());
1019 // Once the download item is deleted, we should return kInvalidId.
1020 int id
= download_item
->GetId();
1021 download_item
->Remove();
1022 download_item
= NULL
;
1023 EXPECT_EQ(static_cast<DownloadItem
*>(NULL
),
1024 GetCurrentManager()->GetDownload(id
));
1025 error
= RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args32
);
1026 EXPECT_STREQ(errors::kInvalidId
,
1030 // Test that we can acquire file icons for history downloads regardless of
1031 // whether they exist or not. If the file doesn't exist we should receive a
1032 // generic icon from the OS/toolkit that may or may not be specific to the file
1034 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1035 DownloadExtensionTest_FileIcon_History
) {
1036 const HistoryDownloadInfo kHistoryInfo
[] = {
1037 { FILE_PATH_LITERAL("real.txt"),
1038 DownloadItem::COMPLETE
,
1039 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
},
1040 { FILE_PATH_LITERAL("fake.txt"),
1041 DownloadItem::COMPLETE
,
1042 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
}
1044 DownloadManager::DownloadVector all_downloads
;
1045 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1048 base::FilePath real_path
= all_downloads
[0]->GetTargetFilePath();
1049 base::FilePath fake_path
= all_downloads
[1]->GetTargetFilePath();
1051 EXPECT_EQ(0, base::WriteFile(real_path
, "", 0));
1052 ASSERT_TRUE(base::PathExists(real_path
));
1053 ASSERT_FALSE(base::PathExists(fake_path
));
1055 for (DownloadManager::DownloadVector::iterator iter
= all_downloads
.begin();
1056 iter
!= all_downloads
.end();
1058 std::string result_string
;
1059 // Use a MockIconExtractorImpl to test if the correct path is being passed
1060 // into the DownloadFileIconExtractor.
1061 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1062 (*iter
)->GetTargetFilePath(), IconLoader::NORMAL
, "hello"),
1063 base::StringPrintf("[%d, {\"size\": 32}]", (*iter
)->GetId()),
1065 EXPECT_STREQ("hello", result_string
.c_str());
1069 // Test passing the empty query to search().
1070 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1071 DownloadExtensionTest_SearchEmptyQuery
) {
1072 ScopedCancellingItem
item(CreateSlowTestDownload());
1073 ASSERT_TRUE(item
.get());
1075 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1076 new DownloadsSearchFunction(), "[{}]"));
1077 ASSERT_TRUE(result
.get());
1078 base::ListValue
* result_list
= NULL
;
1079 ASSERT_TRUE(result
->GetAsList(&result_list
));
1080 ASSERT_EQ(1UL, result_list
->GetSize());
1083 // Test the |filenameRegex| parameter for search().
1084 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1085 DownloadExtensionTest_SearchFilenameRegex
) {
1086 const HistoryDownloadInfo kHistoryInfo
[] = {
1087 { FILE_PATH_LITERAL("foobar"),
1088 DownloadItem::COMPLETE
,
1089 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
},
1090 { FILE_PATH_LITERAL("baz"),
1091 DownloadItem::COMPLETE
,
1092 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
}
1094 DownloadManager::DownloadVector all_downloads
;
1095 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1098 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1099 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]"));
1100 ASSERT_TRUE(result
.get());
1101 base::ListValue
* result_list
= NULL
;
1102 ASSERT_TRUE(result
->GetAsList(&result_list
));
1103 ASSERT_EQ(1UL, result_list
->GetSize());
1104 base::DictionaryValue
* item_value
= NULL
;
1105 ASSERT_TRUE(result_list
->GetDictionary(0, &item_value
));
1107 ASSERT_TRUE(item_value
->GetInteger("id", &item_id
));
1108 ASSERT_EQ(all_downloads
[0]->GetId(), static_cast<uint32
>(item_id
));
1111 // Test the |id| parameter for search().
1112 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
, DownloadExtensionTest_SearchId
) {
1113 DownloadManager::DownloadVector items
;
1114 CreateSlowTestDownloads(2, &items
);
1115 ScopedItemVectorCanceller
delete_items(&items
);
1117 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1118 new DownloadsSearchFunction(), base::StringPrintf(
1119 "[{\"id\": %u}]", items
[0]->GetId())));
1120 ASSERT_TRUE(result
.get());
1121 base::ListValue
* result_list
= NULL
;
1122 ASSERT_TRUE(result
->GetAsList(&result_list
));
1123 ASSERT_EQ(1UL, result_list
->GetSize());
1124 base::DictionaryValue
* item_value
= NULL
;
1125 ASSERT_TRUE(result_list
->GetDictionary(0, &item_value
));
1127 ASSERT_TRUE(item_value
->GetInteger("id", &item_id
));
1128 ASSERT_EQ(items
[0]->GetId(), static_cast<uint32
>(item_id
));
1131 // Test specifying both the |id| and |filename| parameters for search().
1132 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1133 DownloadExtensionTest_SearchIdAndFilename
) {
1134 DownloadManager::DownloadVector items
;
1135 CreateSlowTestDownloads(2, &items
);
1136 ScopedItemVectorCanceller
delete_items(&items
);
1138 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1139 new DownloadsSearchFunction(),
1140 "[{\"id\": 0, \"filename\": \"foobar\"}]"));
1141 ASSERT_TRUE(result
.get());
1142 base::ListValue
* result_list
= NULL
;
1143 ASSERT_TRUE(result
->GetAsList(&result_list
));
1144 ASSERT_EQ(0UL, result_list
->GetSize());
1147 // Test a single |orderBy| parameter for search().
1148 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1149 DownloadExtensionTest_SearchOrderBy
) {
1150 const HistoryDownloadInfo kHistoryInfo
[] = {
1151 { FILE_PATH_LITERAL("zzz"),
1152 DownloadItem::COMPLETE
,
1153 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
},
1154 { FILE_PATH_LITERAL("baz"),
1155 DownloadItem::COMPLETE
,
1156 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
}
1158 DownloadManager::DownloadVector items
;
1159 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1162 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1163 new DownloadsSearchFunction(), "[{\"orderBy\": [\"filename\"]}]"));
1164 ASSERT_TRUE(result
.get());
1165 base::ListValue
* result_list
= NULL
;
1166 ASSERT_TRUE(result
->GetAsList(&result_list
));
1167 ASSERT_EQ(2UL, result_list
->GetSize());
1168 base::DictionaryValue
* item0_value
= NULL
;
1169 base::DictionaryValue
* item1_value
= NULL
;
1170 ASSERT_TRUE(result_list
->GetDictionary(0, &item0_value
));
1171 ASSERT_TRUE(result_list
->GetDictionary(1, &item1_value
));
1172 std::string item0_name
, item1_name
;
1173 ASSERT_TRUE(item0_value
->GetString("filename", &item0_name
));
1174 ASSERT_TRUE(item1_value
->GetString("filename", &item1_name
));
1175 ASSERT_GT(items
[0]->GetTargetFilePath().value(),
1176 items
[1]->GetTargetFilePath().value());
1177 ASSERT_LT(item0_name
, item1_name
);
1180 // Test specifying an empty |orderBy| parameter for search().
1181 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1182 DownloadExtensionTest_SearchOrderByEmpty
) {
1183 const HistoryDownloadInfo kHistoryInfo
[] = {
1184 { FILE_PATH_LITERAL("zzz"),
1185 DownloadItem::COMPLETE
,
1186 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
},
1187 { FILE_PATH_LITERAL("baz"),
1188 DownloadItem::COMPLETE
,
1189 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
}
1191 DownloadManager::DownloadVector items
;
1192 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1195 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1196 new DownloadsSearchFunction(), "[{\"orderBy\": []}]"));
1197 ASSERT_TRUE(result
.get());
1198 base::ListValue
* result_list
= NULL
;
1199 ASSERT_TRUE(result
->GetAsList(&result_list
));
1200 ASSERT_EQ(2UL, result_list
->GetSize());
1201 base::DictionaryValue
* item0_value
= NULL
;
1202 base::DictionaryValue
* item1_value
= NULL
;
1203 ASSERT_TRUE(result_list
->GetDictionary(0, &item0_value
));
1204 ASSERT_TRUE(result_list
->GetDictionary(1, &item1_value
));
1205 std::string item0_name
, item1_name
;
1206 ASSERT_TRUE(item0_value
->GetString("filename", &item0_name
));
1207 ASSERT_TRUE(item1_value
->GetString("filename", &item1_name
));
1208 ASSERT_GT(items
[0]->GetTargetFilePath().value(),
1209 items
[1]->GetTargetFilePath().value());
1210 // The order of results when orderBy is empty is unspecified. When there are
1211 // no sorters, DownloadQuery does not call sort(), so the order of the results
1212 // depends on the order of the items in base::hash_map<uint32,...>
1213 // DownloadManagerImpl::downloads_, which is unspecified and differs between
1214 // libc++ and libstdc++. http://crbug.com/365334
1217 // Test the |danger| option for search().
1218 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1219 DownloadExtensionTest_SearchDanger
) {
1220 const HistoryDownloadInfo kHistoryInfo
[] = {
1221 { FILE_PATH_LITERAL("zzz"),
1222 DownloadItem::COMPLETE
,
1223 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT
},
1224 { FILE_PATH_LITERAL("baz"),
1225 DownloadItem::COMPLETE
,
1226 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
}
1228 DownloadManager::DownloadVector items
;
1229 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1232 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1233 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]"));
1234 ASSERT_TRUE(result
.get());
1235 base::ListValue
* result_list
= NULL
;
1236 ASSERT_TRUE(result
->GetAsList(&result_list
));
1237 ASSERT_EQ(1UL, result_list
->GetSize());
1240 // Test the |state| option for search().
1241 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1242 DownloadExtensionTest_SearchState
) {
1243 DownloadManager::DownloadVector items
;
1244 CreateSlowTestDownloads(2, &items
);
1245 ScopedItemVectorCanceller
delete_items(&items
);
1247 items
[0]->Cancel(true);
1249 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1250 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]"));
1251 ASSERT_TRUE(result
.get());
1252 base::ListValue
* result_list
= NULL
;
1253 ASSERT_TRUE(result
->GetAsList(&result_list
));
1254 ASSERT_EQ(1UL, result_list
->GetSize());
1257 // Test the |limit| option for search().
1258 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1259 DownloadExtensionTest_SearchLimit
) {
1260 DownloadManager::DownloadVector items
;
1261 CreateSlowTestDownloads(2, &items
);
1262 ScopedItemVectorCanceller
delete_items(&items
);
1264 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1265 new DownloadsSearchFunction(), "[{\"limit\": 1}]"));
1266 ASSERT_TRUE(result
.get());
1267 base::ListValue
* result_list
= NULL
;
1268 ASSERT_TRUE(result
->GetAsList(&result_list
));
1269 ASSERT_EQ(1UL, result_list
->GetSize());
1272 // Test invalid search parameters.
1273 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1274 DownloadExtensionTest_SearchInvalid
) {
1275 std::string error
= RunFunctionAndReturnError(
1276 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]");
1277 EXPECT_STREQ(errors::kInvalidFilter
,
1279 error
= RunFunctionAndReturnError(
1280 new DownloadsSearchFunction(), "[{\"orderBy\": [\"goat\"]}]");
1281 EXPECT_STREQ(errors::kInvalidOrderBy
,
1283 error
= RunFunctionAndReturnError(
1284 new DownloadsSearchFunction(), "[{\"limit\": -1}]");
1285 EXPECT_STREQ(errors::kInvalidQueryLimit
,
1289 // Test searching using multiple conditions through multiple downloads.
1290 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1291 DownloadExtensionTest_SearchPlural
) {
1292 const HistoryDownloadInfo kHistoryInfo
[] = {
1293 { FILE_PATH_LITERAL("aaa"),
1294 DownloadItem::CANCELLED
,
1295 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
},
1296 { FILE_PATH_LITERAL("zzz"),
1297 DownloadItem::COMPLETE
,
1298 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT
},
1299 { FILE_PATH_LITERAL("baz"),
1300 DownloadItem::COMPLETE
,
1301 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT
},
1303 DownloadManager::DownloadVector items
;
1304 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1307 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1308 new DownloadsSearchFunction(), "[{"
1309 "\"state\": \"complete\", "
1310 "\"danger\": \"content\", "
1311 "\"orderBy\": [\"filename\"], "
1313 ASSERT_TRUE(result
.get());
1314 base::ListValue
* result_list
= NULL
;
1315 ASSERT_TRUE(result
->GetAsList(&result_list
));
1316 ASSERT_EQ(1UL, result_list
->GetSize());
1317 base::DictionaryValue
* item_value
= NULL
;
1318 ASSERT_TRUE(result_list
->GetDictionary(0, &item_value
));
1319 base::FilePath::StringType item_name
;
1320 ASSERT_TRUE(item_value
->GetString("filename", &item_name
));
1321 ASSERT_EQ(items
[2]->GetTargetFilePath().value(), item_name
);
1324 // Test that incognito downloads are only visible in incognito contexts, and
1325 // test that on-record downloads are visible in both incognito and on-record
1326 // contexts, for DownloadsSearchFunction, DownloadsPauseFunction,
1327 // DownloadsResumeFunction, and DownloadsCancelFunction.
1328 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1329 DownloadExtensionTest_SearchPauseResumeCancelGetFileIconIncognito
) {
1330 scoped_ptr
<base::Value
> result_value
;
1331 base::ListValue
* result_list
= NULL
;
1332 base::DictionaryValue
* result_dict
= NULL
;
1333 base::FilePath::StringType filename
;
1334 bool is_incognito
= false;
1336 std::string on_item_arg
;
1337 std::string off_item_arg
;
1338 std::string result_string
;
1340 // Set up one on-record item and one off-record item.
1341 // Set up the off-record item first because otherwise there are mysteriously 3
1342 // items total instead of 2.
1343 // TODO(benjhayden): Figure out where the third item comes from.
1345 DownloadItem
* off_item
= CreateSlowTestDownload();
1346 ASSERT_TRUE(off_item
);
1347 off_item_arg
= DownloadItemIdAsArgList(off_item
);
1350 DownloadItem
* on_item
= CreateSlowTestDownload();
1351 ASSERT_TRUE(on_item
);
1352 on_item_arg
= DownloadItemIdAsArgList(on_item
);
1353 ASSERT_TRUE(on_item
->GetTargetFilePath() != off_item
->GetTargetFilePath());
1355 // Extensions running in the incognito window should have access to both
1356 // items because the Test extension is in spanning mode.
1358 result_value
.reset(RunFunctionAndReturnResult(
1359 new DownloadsSearchFunction(), "[{}]"));
1360 ASSERT_TRUE(result_value
.get());
1361 ASSERT_TRUE(result_value
->GetAsList(&result_list
));
1362 ASSERT_EQ(2UL, result_list
->GetSize());
1363 ASSERT_TRUE(result_list
->GetDictionary(0, &result_dict
));
1364 ASSERT_TRUE(result_dict
->GetString("filename", &filename
));
1365 ASSERT_TRUE(result_dict
->GetBoolean("incognito", &is_incognito
));
1366 EXPECT_TRUE(on_item
->GetTargetFilePath() == base::FilePath(filename
));
1367 EXPECT_FALSE(is_incognito
);
1368 ASSERT_TRUE(result_list
->GetDictionary(1, &result_dict
));
1369 ASSERT_TRUE(result_dict
->GetString("filename", &filename
));
1370 ASSERT_TRUE(result_dict
->GetBoolean("incognito", &is_incognito
));
1371 EXPECT_TRUE(off_item
->GetTargetFilePath() == base::FilePath(filename
));
1372 EXPECT_TRUE(is_incognito
);
1374 // Extensions running in the on-record window should have access only to the
1377 result_value
.reset(RunFunctionAndReturnResult(
1378 new DownloadsSearchFunction(), "[{}]"));
1379 ASSERT_TRUE(result_value
.get());
1380 ASSERT_TRUE(result_value
->GetAsList(&result_list
));
1381 ASSERT_EQ(1UL, result_list
->GetSize());
1382 ASSERT_TRUE(result_list
->GetDictionary(0, &result_dict
));
1383 ASSERT_TRUE(result_dict
->GetString("filename", &filename
));
1384 EXPECT_TRUE(on_item
->GetTargetFilePath() == base::FilePath(filename
));
1385 ASSERT_TRUE(result_dict
->GetBoolean("incognito", &is_incognito
));
1386 EXPECT_FALSE(is_incognito
);
1388 // Pausing/Resuming the off-record item while on the record should return an
1389 // error. Cancelling "non-existent" downloads is not an error.
1390 error
= RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg
);
1391 EXPECT_STREQ(errors::kInvalidId
,
1393 error
= RunFunctionAndReturnError(new DownloadsResumeFunction(),
1395 EXPECT_STREQ(errors::kInvalidId
,
1397 error
= RunFunctionAndReturnError(
1398 new DownloadsGetFileIconFunction(),
1399 base::StringPrintf("[%d, {}]", off_item
->GetId()));
1400 EXPECT_STREQ(errors::kInvalidId
,
1405 // Do the FileIcon test for both the on- and off-items while off the record.
1406 // NOTE(benjhayden): This does not include the FileIcon test from history,
1407 // just active downloads. This shouldn't be a problem.
1408 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1409 on_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
1410 base::StringPrintf("[%d, {}]", on_item
->GetId()), &result_string
));
1411 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1412 off_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
1413 base::StringPrintf("[%d, {}]", off_item
->GetId()), &result_string
));
1415 // Do the pause/resume/cancel test for both the on- and off-items while off
1417 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg
));
1418 EXPECT_TRUE(on_item
->IsPaused());
1419 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg
));
1420 EXPECT_TRUE(on_item
->IsPaused());
1421 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg
));
1422 EXPECT_FALSE(on_item
->IsPaused());
1423 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg
));
1424 EXPECT_FALSE(on_item
->IsPaused());
1425 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg
));
1426 EXPECT_TRUE(on_item
->IsPaused());
1427 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg
));
1428 EXPECT_EQ(DownloadItem::CANCELLED
, on_item
->GetState());
1429 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg
));
1430 EXPECT_EQ(DownloadItem::CANCELLED
, on_item
->GetState());
1431 error
= RunFunctionAndReturnError(new DownloadsPauseFunction(), on_item_arg
);
1432 EXPECT_STREQ(errors::kNotInProgress
, error
.c_str());
1433 error
= RunFunctionAndReturnError(new DownloadsResumeFunction(), on_item_arg
);
1434 EXPECT_STREQ(errors::kNotResumable
, error
.c_str());
1435 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg
));
1436 EXPECT_TRUE(off_item
->IsPaused());
1437 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg
));
1438 EXPECT_TRUE(off_item
->IsPaused());
1439 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg
));
1440 EXPECT_FALSE(off_item
->IsPaused());
1441 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg
));
1442 EXPECT_FALSE(off_item
->IsPaused());
1443 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg
));
1444 EXPECT_TRUE(off_item
->IsPaused());
1445 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg
));
1446 EXPECT_EQ(DownloadItem::CANCELLED
, off_item
->GetState());
1447 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg
));
1448 EXPECT_EQ(DownloadItem::CANCELLED
, off_item
->GetState());
1449 error
= RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg
);
1450 EXPECT_STREQ(errors::kNotInProgress
, error
.c_str());
1451 error
= RunFunctionAndReturnError(new DownloadsResumeFunction(),
1453 EXPECT_STREQ(errors::kNotResumable
, error
.c_str());
1456 // Test that we can start a download and that the correct sequence of events is
1458 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1459 DownloadExtensionTest_Download_Basic
) {
1460 LoadExtension("downloads_split");
1461 ASSERT_TRUE(StartEmbeddedTestServer());
1462 ASSERT_TRUE(test_server()->Start());
1463 std::string download_url
= test_server()->GetURL("slow?0").spec();
1466 // Start downloading a file.
1467 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1468 new DownloadsDownloadFunction(), base::StringPrintf(
1469 "[{\"url\": \"%s\"}]", download_url
.c_str())));
1470 ASSERT_TRUE(result
.get());
1472 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1473 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1475 ScopedCancellingItem
canceller(item
);
1476 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1478 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1480 "[{\"danger\": \"safe\","
1481 " \"incognito\": false,"
1482 " \"mime\": \"text/plain\","
1483 " \"paused\": false,"
1484 " \"url\": \"%s\"}]",
1485 download_url
.c_str())));
1486 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1490 " \"previous\": \"\","
1491 " \"current\": \"%s\"}}]",
1493 GetFilename("slow.txt").c_str())));
1494 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1498 " \"previous\": \"in_progress\","
1499 " \"current\": \"complete\"}}]",
1503 // Test that we can start a download from an incognito context, and that the
1504 // download knows that it's incognito.
1505 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1506 DownloadExtensionTest_Download_Incognito
) {
1507 LoadExtension("downloads_split");
1508 ASSERT_TRUE(StartEmbeddedTestServer());
1509 ASSERT_TRUE(test_server()->Start());
1511 std::string download_url
= test_server()->GetURL("slow?0").spec();
1513 // Start downloading a file.
1514 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1515 new DownloadsDownloadFunction(), base::StringPrintf(
1516 "[{\"url\": \"%s\"}]", download_url
.c_str())));
1517 ASSERT_TRUE(result
.get());
1519 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1520 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1522 ScopedCancellingItem
canceller(item
);
1523 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1525 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1527 "[{\"danger\": \"safe\","
1528 " \"incognito\": true,"
1529 " \"mime\": \"text/plain\","
1530 " \"paused\": false,"
1531 " \"url\": \"%s\"}]",
1532 download_url
.c_str())));
1533 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1537 " \"previous\": \"\","
1538 " \"current\": \"%s\"}}]",
1540 GetFilename("slow.txt").c_str())));
1541 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1545 " \"current\": \"complete\","
1546 " \"previous\": \"in_progress\"}}]",
1551 // This test is very flaky on Win. http://crbug.com/248438
1552 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1553 DISABLED_DownloadExtensionTest_Download_UnsafeHeaders
1555 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1556 DownloadExtensionTest_Download_UnsafeHeaders
1559 // Test that we disallow certain headers case-insensitively.
1560 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1561 MAYBE_DownloadExtensionTest_Download_UnsafeHeaders
) {
1562 LoadExtension("downloads_split");
1563 ASSERT_TRUE(StartEmbeddedTestServer());
1564 ASSERT_TRUE(test_server()->Start());
1567 static const char* const kUnsafeHeaders
[] = {
1574 "coNteNt-traNsfer-eNcodiNg",
1582 "trANsfer-eNcodiNg",
1588 "pRoxY-probably-not-evil",
1589 "sEc-probably-not-evil",
1591 "Access-Control-Request-Headers",
1592 "Access-Control-Request-Method",
1595 for (size_t index
= 0; index
< arraysize(kUnsafeHeaders
); ++index
) {
1596 std::string download_url
= test_server()->GetURL("slow?0").spec();
1597 EXPECT_STREQ(errors::kInvalidHeaderUnsafe
,
1598 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1600 "[{\"url\": \"%s\","
1601 " \"filename\": \"unsafe-header-%d.txt\","
1603 " \"name\": \"%s\","
1604 " \"value\": \"unsafe\"}]}]",
1605 download_url
.c_str(),
1606 static_cast<int>(index
),
1607 kUnsafeHeaders
[index
])).c_str());
1611 // Tests that invalid header names and values are rejected.
1612 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1613 DownloadExtensionTest_Download_InvalidHeaders
) {
1614 LoadExtension("downloads_split");
1615 ASSERT_TRUE(StartEmbeddedTestServer());
1616 ASSERT_TRUE(test_server()->Start());
1618 std::string download_url
= test_server()->GetURL("slow?0").spec();
1619 EXPECT_STREQ(errors::kInvalidHeaderName
,
1620 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1622 "[{\"url\": \"%s\","
1623 " \"filename\": \"unsafe-header-crlf.txt\","
1625 " \"name\": \"Header\\r\\nSec-Spoof: Hey\\r\\nX-Split:X\","
1626 " \"value\": \"unsafe\"}]}]",
1627 download_url
.c_str())).c_str());
1629 EXPECT_STREQ(errors::kInvalidHeaderValue
,
1630 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1632 "[{\"url\": \"%s\","
1633 " \"filename\": \"unsafe-header-crlf.txt\","
1635 " \"name\": \"Invalid-value\","
1636 " \"value\": \"hey\\r\\nSec-Spoof: Hey\"}]}]",
1637 download_url
.c_str())).c_str());
1641 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1642 DISABLED_DownloadExtensionTest_Download_Subdirectory
1644 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1645 DownloadExtensionTest_Download_Subdirectory
1647 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1648 MAYBE_DownloadExtensionTest_Download_Subdirectory
) {
1649 LoadExtension("downloads_split");
1650 ASSERT_TRUE(StartEmbeddedTestServer());
1651 ASSERT_TRUE(test_server()->Start());
1652 std::string download_url
= test_server()->GetURL("slow?0").spec();
1655 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1656 new DownloadsDownloadFunction(), base::StringPrintf(
1657 "[{\"url\": \"%s\","
1658 " \"filename\": \"sub/dir/ect/ory.txt\"}]",
1659 download_url
.c_str())));
1660 ASSERT_TRUE(result
.get());
1662 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1663 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1665 ScopedCancellingItem
canceller(item
);
1666 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1668 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1670 "[{\"danger\": \"safe\","
1671 " \"incognito\": false,"
1672 " \"mime\": \"text/plain\","
1673 " \"paused\": false,"
1674 " \"url\": \"%s\"}]",
1675 download_url
.c_str())));
1676 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1680 " \"previous\": \"\","
1681 " \"current\": \"%s\"}}]",
1683 GetFilename("sub/dir/ect/ory.txt").c_str())));
1684 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1688 " \"previous\": \"in_progress\","
1689 " \"current\": \"complete\"}}]",
1693 // Test that invalid filenames are disallowed.
1694 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1695 DownloadExtensionTest_Download_InvalidFilename
) {
1696 LoadExtension("downloads_split");
1697 ASSERT_TRUE(StartEmbeddedTestServer());
1698 ASSERT_TRUE(test_server()->Start());
1699 std::string download_url
= test_server()->GetURL("slow?0").spec();
1702 EXPECT_STREQ(errors::kInvalidFilename
,
1703 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1705 "[{\"url\": \"%s\","
1706 " \"filename\": \"../../../../../etc/passwd\"}]",
1707 download_url
.c_str())).c_str());
1710 // flaky on mac: crbug.com/392288
1711 #if defined(OS_MACOSX)
1712 #define MAYBE_DownloadExtensionTest_Download_InvalidURLs \
1713 DISABLED_DownloadExtensionTest_Download_InvalidURLs
1715 #define MAYBE_DownloadExtensionTest_Download_InvalidURLs \
1716 DownloadExtensionTest_Download_InvalidURLs
1719 // Test that downloading invalid URLs immediately returns kInvalidURLError.
1720 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1721 MAYBE_DownloadExtensionTest_Download_InvalidURLs
) {
1722 LoadExtension("downloads_split");
1725 static const char* const kInvalidURLs
[] = {
1731 "foo/bar.html#frag",
1735 for (size_t index
= 0; index
< arraysize(kInvalidURLs
); ++index
) {
1736 EXPECT_STREQ(errors::kInvalidURL
,
1737 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1739 "[{\"url\": \"%s\"}]", kInvalidURLs
[index
])).c_str())
1740 << kInvalidURLs
[index
];
1743 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1744 new DownloadsDownloadFunction(),
1745 "[{\"url\": \"javascript:document.write(\\\"hello\\\");\"}]").c_str());
1746 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1747 new DownloadsDownloadFunction(),
1748 "[{\"url\": \"javascript:return false;\"}]").c_str());
1749 EXPECT_STREQ("NETWORK_FAILED", RunFunctionAndReturnError(
1750 new DownloadsDownloadFunction(),
1751 "[{\"url\": \"ftp://example.com/example.txt\"}]").c_str());
1754 // TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to
1755 // permissions, test downloading from ftp.
1757 // Valid URLs plus fragments are still valid URLs.
1758 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1759 DownloadExtensionTest_Download_URLFragment
) {
1760 LoadExtension("downloads_split");
1761 ASSERT_TRUE(StartEmbeddedTestServer());
1762 ASSERT_TRUE(test_server()->Start());
1763 std::string download_url
= test_server()->GetURL("slow?0#fragment").spec();
1766 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1767 new DownloadsDownloadFunction(), base::StringPrintf(
1768 "[{\"url\": \"%s\"}]", download_url
.c_str())));
1769 ASSERT_TRUE(result
.get());
1771 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1772 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1774 ScopedCancellingItem
canceller(item
);
1775 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1777 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1779 "[{\"danger\": \"safe\","
1780 " \"incognito\": false,"
1781 " \"mime\": \"text/plain\","
1782 " \"paused\": false,"
1783 " \"url\": \"%s\"}]",
1784 download_url
.c_str())));
1785 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1789 " \"previous\": \"\","
1790 " \"current\": \"%s\"}}]",
1792 GetFilename("slow.txt").c_str())));
1793 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1797 " \"previous\": \"in_progress\","
1798 " \"current\": \"complete\"}}]",
1802 // conflictAction may be specified without filename.
1803 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1804 DownloadExtensionTest_Download_ConflictAction
) {
1805 static char kFilename
[] = "download.txt";
1806 LoadExtension("downloads_split");
1807 std::string download_url
= "data:text/plain,hello";
1810 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1811 new DownloadsDownloadFunction(), base::StringPrintf(
1812 "[{\"url\": \"%s\"}]", download_url
.c_str())));
1813 ASSERT_TRUE(result
.get());
1815 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1816 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1818 ScopedCancellingItem
canceller(item
);
1819 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1821 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1823 "[{\"danger\": \"safe\","
1824 " \"incognito\": false,"
1825 " \"mime\": \"text/plain\","
1826 " \"paused\": false,"
1827 " \"url\": \"%s\"}]",
1828 download_url
.c_str())));
1829 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1833 " \"previous\": \"\","
1834 " \"current\": \"%s\"}}]",
1836 GetFilename(kFilename
).c_str())));
1837 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1841 " \"previous\": \"in_progress\","
1842 " \"current\": \"complete\"}}]",
1845 result
.reset(RunFunctionAndReturnResult(
1846 new DownloadsDownloadFunction(), base::StringPrintf(
1847 "[{\"url\": \"%s\", \"conflictAction\": \"overwrite\"}]",
1848 download_url
.c_str())));
1849 ASSERT_TRUE(result
.get());
1851 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1852 item
= GetCurrentManager()->GetDownload(result_id
);
1854 ScopedCancellingItem
canceller2(item
);
1855 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1857 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1859 "[{\"danger\": \"safe\","
1860 " \"incognito\": false,"
1861 " \"mime\": \"text/plain\","
1862 " \"paused\": false,"
1863 " \"url\": \"%s\"}]",
1864 download_url
.c_str())));
1865 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1869 " \"previous\": \"\","
1870 " \"current\": \"%s\"}}]",
1872 GetFilename(kFilename
).c_str())));
1873 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1877 " \"previous\": \"in_progress\","
1878 " \"current\": \"complete\"}}]",
1882 // Valid data URLs are valid URLs.
1883 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1884 DownloadExtensionTest_Download_DataURL
) {
1885 LoadExtension("downloads_split");
1886 std::string download_url
= "data:text/plain,hello";
1889 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1890 new DownloadsDownloadFunction(), base::StringPrintf(
1891 "[{\"url\": \"%s\","
1892 " \"filename\": \"data.txt\"}]", download_url
.c_str())));
1893 ASSERT_TRUE(result
.get());
1895 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1896 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1898 ScopedCancellingItem
canceller(item
);
1899 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1901 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1903 "[{\"danger\": \"safe\","
1904 " \"incognito\": false,"
1905 " \"mime\": \"text/plain\","
1906 " \"paused\": false,"
1907 " \"url\": \"%s\"}]",
1908 download_url
.c_str())));
1909 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1913 " \"previous\": \"\","
1914 " \"current\": \"%s\"}}]",
1916 GetFilename("data.txt").c_str())));
1917 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1921 " \"previous\": \"in_progress\","
1922 " \"current\": \"complete\"}}]",
1926 // Valid file URLs are valid URLs.
1928 // Disabled due to crbug.com/175711
1929 #define MAYBE_DownloadExtensionTest_Download_File \
1930 DISABLED_DownloadExtensionTest_Download_File
1932 #define MAYBE_DownloadExtensionTest_Download_File \
1933 DownloadExtensionTest_Download_File
1935 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1936 MAYBE_DownloadExtensionTest_Download_File
) {
1938 LoadExtension("downloads_split");
1939 std::string download_url
= "file:///";
1941 download_url
+= "C:/";
1944 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1945 new DownloadsDownloadFunction(), base::StringPrintf(
1946 "[{\"url\": \"%s\","
1947 " \"filename\": \"file.txt\"}]", download_url
.c_str())));
1948 ASSERT_TRUE(result
.get());
1950 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1951 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1953 ScopedCancellingItem
canceller(item
);
1954 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1956 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1958 "[{\"danger\": \"safe\","
1959 " \"incognito\": false,"
1960 " \"mime\": \"text/html\","
1961 " \"paused\": false,"
1962 " \"url\": \"%s\"}]",
1963 download_url
.c_str())));
1964 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1968 " \"previous\": \"\","
1969 " \"current\": \"%s\"}}]",
1971 GetFilename("file.txt").c_str())));
1972 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1976 " \"previous\": \"in_progress\","
1977 " \"current\": \"complete\"}}]",
1981 // Test that auth-basic-succeed would fail if the resource requires the
1982 // Authorization header and chrome fails to propagate it back to the server.
1983 // This tests both that testserver.py does not succeed when it should fail as
1984 // well as how the downloads extension API exposes the failure to extensions.
1985 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1986 DownloadExtensionTest_Download_AuthBasic_Fail
) {
1987 LoadExtension("downloads_split");
1988 ASSERT_TRUE(StartEmbeddedTestServer());
1989 ASSERT_TRUE(test_server()->Start());
1990 std::string download_url
= test_server()->GetURL("auth-basic").spec();
1993 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1994 new DownloadsDownloadFunction(), base::StringPrintf(
1995 "[{\"url\": \"%s\","
1996 " \"filename\": \"auth-basic-fail.txt\"}]",
1997 download_url
.c_str())));
1998 ASSERT_TRUE(result
.get());
2000 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2001 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2003 ScopedCancellingItem
canceller(item
);
2004 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2006 ASSERT_TRUE(WaitForInterruption(
2008 content::DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED
,
2009 base::StringPrintf("[{\"danger\": \"safe\","
2010 " \"incognito\": false,"
2011 " \"mime\": \"text/html\","
2012 " \"paused\": false,"
2013 " \"url\": \"%s\"}]",
2014 download_url
.c_str())));
2017 // Test that DownloadsDownloadFunction propagates |headers| to the URLRequest.
2018 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2019 DownloadExtensionTest_Download_Headers
) {
2020 LoadExtension("downloads_split");
2021 ASSERT_TRUE(StartEmbeddedTestServer());
2022 ASSERT_TRUE(test_server()->Start());
2023 std::string download_url
= test_server()->GetURL("files/downloads/"
2024 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
2027 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2028 new DownloadsDownloadFunction(), base::StringPrintf(
2029 "[{\"url\": \"%s\","
2030 " \"filename\": \"headers-succeed.txt\","
2032 " {\"name\": \"Foo\", \"value\": \"bar\"},"
2033 " {\"name\": \"Qx\", \"value\":\"yo\"}]}]",
2034 download_url
.c_str())));
2035 ASSERT_TRUE(result
.get());
2037 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2038 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2040 ScopedCancellingItem
canceller(item
);
2041 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2043 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2045 "[{\"danger\": \"safe\","
2046 " \"incognito\": false,"
2047 " \"mime\": \"application/octet-stream\","
2048 " \"paused\": false,"
2049 " \"url\": \"%s\"}]",
2050 download_url
.c_str())));
2051 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2055 " \"previous\": \"\","
2056 " \"current\": \"%s\"}}]",
2058 GetFilename("headers-succeed.txt").c_str())));
2059 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2063 " \"previous\": \"in_progress\","
2064 " \"current\": \"complete\"}}]",
2068 // Test that headers-succeed would fail if the resource requires the headers and
2069 // chrome fails to propagate them back to the server. This tests both that
2070 // testserver.py does not succeed when it should fail as well as how the
2071 // downloads extension api exposes the failure to extensions.
2072 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2073 DownloadExtensionTest_Download_Headers_Fail
) {
2074 LoadExtension("downloads_split");
2075 ASSERT_TRUE(StartEmbeddedTestServer());
2076 ASSERT_TRUE(test_server()->Start());
2077 std::string download_url
= test_server()->GetURL("files/downloads/"
2078 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
2081 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2082 new DownloadsDownloadFunction(), base::StringPrintf(
2083 "[{\"url\": \"%s\","
2084 " \"filename\": \"headers-fail.txt\"}]",
2085 download_url
.c_str())));
2086 ASSERT_TRUE(result
.get());
2088 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2089 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2091 ScopedCancellingItem
canceller(item
);
2092 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2094 ASSERT_TRUE(WaitForInterruption(
2096 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT
,
2097 base::StringPrintf("[{\"danger\": \"safe\","
2098 " \"incognito\": false,"
2099 " \"bytesReceived\": 0.0,"
2100 " \"fileSize\": 0.0,"
2102 " \"paused\": false,"
2103 " \"url\": \"%s\"}]",
2104 download_url
.c_str())));
2107 // Test that DownloadsDownloadFunction propagates the Authorization header
2109 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2110 DownloadExtensionTest_Download_AuthBasic
) {
2111 LoadExtension("downloads_split");
2112 ASSERT_TRUE(StartEmbeddedTestServer());
2113 ASSERT_TRUE(test_server()->Start());
2114 std::string download_url
= test_server()->GetURL("auth-basic").spec();
2115 // This is just base64 of 'username:secret'.
2116 static const char kAuthorization
[] = "dXNlcm5hbWU6c2VjcmV0";
2119 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2120 new DownloadsDownloadFunction(), base::StringPrintf(
2121 "[{\"url\": \"%s\","
2122 " \"filename\": \"auth-basic-succeed.txt\","
2124 " \"name\": \"Authorization\","
2125 " \"value\": \"Basic %s\"}]}]",
2126 download_url
.c_str(), kAuthorization
)));
2127 ASSERT_TRUE(result
.get());
2129 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2130 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2132 ScopedCancellingItem
canceller(item
);
2133 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2135 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2137 "[{\"danger\": \"safe\","
2138 " \"incognito\": false,"
2139 " \"bytesReceived\": 0.0,"
2140 " \"fileSize\": 0.0,"
2141 " \"mime\": \"text/html\","
2142 " \"paused\": false,"
2143 " \"url\": \"%s\"}]",
2144 download_url
.c_str())));
2145 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2149 " \"previous\": \"in_progress\","
2150 " \"current\": \"complete\"}}]",
2154 // Test that DownloadsDownloadFunction propagates the |method| and |body|
2155 // parameters to the URLRequest.
2156 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2157 DownloadExtensionTest_Download_Post
) {
2158 LoadExtension("downloads_split");
2159 ASSERT_TRUE(StartEmbeddedTestServer());
2160 ASSERT_TRUE(test_server()->Start());
2161 std::string download_url
= test_server()->GetURL("files/post/downloads/"
2162 "a_zip_file.zip?expected_body=BODY").spec();
2165 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2166 new DownloadsDownloadFunction(), base::StringPrintf(
2167 "[{\"url\": \"%s\","
2168 " \"filename\": \"post-succeed.txt\","
2169 " \"method\": \"POST\","
2170 " \"body\": \"BODY\"}]",
2171 download_url
.c_str())));
2172 ASSERT_TRUE(result
.get());
2174 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2175 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2177 ScopedCancellingItem
canceller(item
);
2178 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2180 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2182 "[{\"danger\": \"safe\","
2183 " \"incognito\": false,"
2184 " \"mime\": \"application/octet-stream\","
2185 " \"paused\": false,"
2186 " \"url\": \"%s\"}]",
2187 download_url
.c_str())));
2188 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2192 " \"previous\": \"\","
2193 " \"current\": \"%s\"}}]",
2195 GetFilename("post-succeed.txt").c_str())));
2196 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2200 " \"previous\": \"in_progress\","
2201 " \"current\": \"complete\"}}]",
2205 // Test that downloadPostSuccess would fail if the resource requires the POST
2206 // method, and chrome fails to propagate the |method| parameter back to the
2207 // server. This tests both that testserver.py does not succeed when it should
2208 // fail, and this tests how the downloads extension api exposes the failure to
2210 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2211 DownloadExtensionTest_Download_Post_Get
) {
2212 LoadExtension("downloads_split");
2213 ASSERT_TRUE(StartEmbeddedTestServer());
2214 ASSERT_TRUE(test_server()->Start());
2215 std::string download_url
= test_server()->GetURL("files/post/downloads/"
2216 "a_zip_file.zip?expected_body=BODY").spec();
2219 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2220 new DownloadsDownloadFunction(), base::StringPrintf(
2221 "[{\"url\": \"%s\","
2222 " \"body\": \"BODY\","
2223 " \"filename\": \"post-get.txt\"}]",
2224 download_url
.c_str())));
2225 ASSERT_TRUE(result
.get());
2227 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2228 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2230 ScopedCancellingItem
canceller(item
);
2231 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2233 ASSERT_TRUE(WaitForInterruption(
2235 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT
,
2236 base::StringPrintf("[{\"danger\": \"safe\","
2237 " \"incognito\": false,"
2239 " \"paused\": false,"
2241 " \"url\": \"%s\"}]",
2243 download_url
.c_str())));
2246 // Test that downloadPostSuccess would fail if the resource requires the POST
2247 // method, and chrome fails to propagate the |body| parameter back to the
2248 // server. This tests both that testserver.py does not succeed when it should
2249 // fail, and this tests how the downloads extension api exposes the failure to
2251 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2252 DownloadExtensionTest_Download_Post_NoBody
) {
2253 LoadExtension("downloads_split");
2254 ASSERT_TRUE(StartEmbeddedTestServer());
2255 ASSERT_TRUE(test_server()->Start());
2256 std::string download_url
= test_server()->GetURL("files/post/downloads/"
2257 "a_zip_file.zip?expected_body=BODY").spec();
2260 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2261 new DownloadsDownloadFunction(), base::StringPrintf(
2262 "[{\"url\": \"%s\","
2263 " \"method\": \"POST\","
2264 " \"filename\": \"post-nobody.txt\"}]",
2265 download_url
.c_str())));
2266 ASSERT_TRUE(result
.get());
2268 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2269 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2271 ScopedCancellingItem
canceller(item
);
2272 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2274 ASSERT_TRUE(WaitForInterruption(
2276 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT
,
2277 base::StringPrintf("[{\"danger\": \"safe\","
2278 " \"incognito\": false,"
2280 " \"paused\": false,"
2282 " \"url\": \"%s\"}]",
2284 download_url
.c_str())));
2287 // Test that cancel()ing an in-progress download causes its state to transition
2288 // to interrupted, and test that that state transition is detectable by an
2289 // onChanged event listener. TODO(benjhayden): Test other sources of
2290 // interruptions such as server death.
2291 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2292 DownloadExtensionTest_Download_Cancel
) {
2293 LoadExtension("downloads_split");
2294 ASSERT_TRUE(StartEmbeddedTestServer());
2295 ASSERT_TRUE(test_server()->Start());
2296 std::string download_url
= test_server()->GetURL(
2297 "download-known-size").spec();
2300 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2301 new DownloadsDownloadFunction(), base::StringPrintf(
2302 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2303 ASSERT_TRUE(result
.get());
2305 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2306 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2308 ScopedCancellingItem
canceller(item
);
2309 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2311 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2313 "[{\"danger\": \"safe\","
2314 " \"incognito\": false,"
2315 " \"mime\": \"application/octet-stream\","
2316 " \"paused\": false,"
2318 " \"url\": \"%s\"}]",
2320 download_url
.c_str())));
2322 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2325 " \"error\": {\"current\":\"USER_CANCELED\"},"
2327 " \"previous\": \"in_progress\","
2328 " \"current\": \"interrupted\"}}]",
2332 // flaky on mac: crbug.com/392288
2333 #if defined(OS_MACOSX)
2334 #define MAYBE_DownloadExtensionTest_Download_FileSystemURL \
2335 DISABLED_DownloadExtensionTest_Download_FileSystemURL
2337 #define MAYBE_DownloadExtensionTest_Download_FileSystemURL \
2338 DownloadExtensionTest_Download_FileSystemURL
2341 // Test downloading filesystem: URLs.
2342 // NOTE: chrome disallows creating HTML5 FileSystem Files in incognito.
2343 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2344 MAYBE_DownloadExtensionTest_Download_FileSystemURL
) {
2345 static const char kPayloadData
[] = "on the record\ndata";
2347 LoadExtension("downloads_split");
2349 const std::string download_url
= "filesystem:" + GetExtensionURL() +
2350 "temporary/on_record.txt";
2352 // Setup a file in the filesystem which we can download.
2353 ASSERT_TRUE(HTML5FileWriter::CreateFileForTesting(
2354 BrowserContext::GetDefaultStoragePartition(browser()->profile())
2355 ->GetFileSystemContext(),
2356 storage::FileSystemURL::CreateForTest(GURL(download_url
)),
2358 strlen(kPayloadData
)));
2361 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2362 new DownloadsDownloadFunction(), base::StringPrintf(
2363 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2364 ASSERT_TRUE(result
.get());
2366 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2368 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2370 ScopedCancellingItem
canceller(item
);
2371 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2373 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2375 "[{\"danger\": \"safe\","
2376 " \"incognito\": false,"
2377 " \"mime\": \"text/plain\","
2378 " \"paused\": false,"
2379 " \"url\": \"%s\"}]",
2380 download_url
.c_str())));
2381 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2385 " \"previous\": \"\","
2386 " \"current\": \"%s\"}}]",
2388 GetFilename("on_record.txt").c_str())));
2389 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2393 " \"previous\": \"in_progress\","
2394 " \"current\": \"complete\"}}]",
2396 std::string disk_data
;
2397 EXPECT_TRUE(base::ReadFileToString(item
->GetTargetFilePath(), &disk_data
));
2398 EXPECT_STREQ(kPayloadData
, disk_data
.c_str());
2401 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2402 DownloadExtensionTest_OnDeterminingFilename_NoChange
) {
2404 LoadExtension("downloads_split");
2405 AddFilenameDeterminer();
2406 ASSERT_TRUE(StartEmbeddedTestServer());
2407 ASSERT_TRUE(test_server()->Start());
2408 std::string download_url
= test_server()->GetURL("slow?0").spec();
2410 // Start downloading a file.
2411 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2412 new DownloadsDownloadFunction(), base::StringPrintf(
2413 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2414 ASSERT_TRUE(result
.get());
2416 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2417 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2419 ScopedCancellingItem
canceller(item
);
2420 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2422 // Wait for the onCreated and onDeterminingFilename events.
2423 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2425 "[{\"danger\": \"safe\","
2426 " \"incognito\": false,"
2428 " \"mime\": \"text/plain\","
2429 " \"paused\": false,"
2430 " \"url\": \"%s\"}]",
2432 download_url
.c_str())));
2433 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2436 " \"filename\":\"slow.txt\"}]",
2438 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2439 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2441 // Respond to the onDeterminingFilename.
2443 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2444 browser()->profile(),
2449 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2451 EXPECT_EQ("", error
);
2453 // The download should complete successfully.
2454 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2458 " \"previous\": \"\","
2459 " \"current\": \"%s\"}}]",
2461 GetFilename("slow.txt").c_str())));
2462 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2466 " \"previous\": \"in_progress\","
2467 " \"current\": \"complete\"}}]",
2471 // Disabled due to cross-platform flakes; http://crbug.com/370531.
2472 IN_PROC_BROWSER_TEST_F(
2473 DownloadExtensionTest
,
2474 DISABLED_DownloadExtensionTest_OnDeterminingFilename_Timeout
) {
2476 LoadExtension("downloads_split");
2477 AddFilenameDeterminer();
2478 ASSERT_TRUE(StartEmbeddedTestServer());
2479 ASSERT_TRUE(test_server()->Start());
2480 std::string download_url
= test_server()->GetURL("slow?0").spec();
2482 ExtensionDownloadsEventRouter::SetDetermineFilenameTimeoutSecondsForTesting(
2485 // Start downloading a file.
2486 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2487 new DownloadsDownloadFunction(), base::StringPrintf(
2488 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2489 ASSERT_TRUE(result
.get());
2491 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2492 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2494 ScopedCancellingItem
canceller(item
);
2495 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2497 // Wait for the onCreated and onDeterminingFilename events.
2498 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2499 base::StringPrintf("[{\"danger\": \"safe\","
2500 " \"incognito\": false,"
2502 " \"mime\": \"text/plain\","
2503 " \"paused\": false,"
2504 " \"url\": \"%s\"}]",
2506 download_url
.c_str())));
2507 ASSERT_TRUE(WaitFor(
2508 downloads::OnDeterminingFilename::kEventName
,
2509 base::StringPrintf("[{\"id\": %d,"
2510 " \"filename\":\"slow.txt\"}]",
2512 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2513 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2515 // Do not respond to the onDeterminingFilename.
2517 // The download should complete successfully.
2518 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2519 base::StringPrintf("[{\"id\": %d,"
2521 " \"previous\": \"\","
2522 " \"current\": \"%s\"}}]",
2524 GetFilename("slow.txt").c_str())));
2525 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2526 base::StringPrintf("[{\"id\": %d,"
2528 " \"previous\": \"in_progress\","
2529 " \"current\": \"complete\"}}]",
2533 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2534 DownloadExtensionTest_OnDeterminingFilename_Twice
) {
2536 LoadExtension("downloads_split");
2537 AddFilenameDeterminer();
2538 ASSERT_TRUE(StartEmbeddedTestServer());
2539 ASSERT_TRUE(test_server()->Start());
2540 std::string download_url
= test_server()->GetURL("slow?0").spec();
2542 // Start downloading a file.
2543 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2544 new DownloadsDownloadFunction(), base::StringPrintf(
2545 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2546 ASSERT_TRUE(result
.get());
2548 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2549 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2551 ScopedCancellingItem
canceller(item
);
2552 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2554 // Wait for the onCreated and onDeterminingFilename events.
2555 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2556 base::StringPrintf("[{\"danger\": \"safe\","
2557 " \"incognito\": false,"
2559 " \"mime\": \"text/plain\","
2560 " \"paused\": false,"
2561 " \"url\": \"%s\"}]",
2563 download_url
.c_str())));
2564 ASSERT_TRUE(WaitFor(
2565 downloads::OnDeterminingFilename::kEventName
,
2566 base::StringPrintf("[{\"id\": %d,"
2567 " \"filename\":\"slow.txt\"}]",
2569 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2570 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2572 // Respond to the onDeterminingFilename.
2574 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2575 browser()->profile(),
2580 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2582 EXPECT_EQ("", error
);
2584 // Calling DetermineFilename again should return an error instead of calling
2585 // DownloadTargetDeterminer.
2586 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2587 browser()->profile(),
2591 base::FilePath(FILE_PATH_LITERAL("different")),
2592 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
,
2594 EXPECT_EQ(errors::kTooManyListeners
, error
);
2596 // The download should complete successfully.
2597 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2598 base::StringPrintf("[{\"id\": %d,"
2600 " \"previous\": \"\","
2601 " \"current\": \"%s\"}}]",
2603 GetFilename("slow.txt").c_str())));
2604 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2605 base::StringPrintf("[{\"id\": %d,"
2607 " \"previous\": \"in_progress\","
2608 " \"current\": \"complete\"}}]",
2612 IN_PROC_BROWSER_TEST_F(
2613 DownloadExtensionTest
,
2614 DownloadExtensionTest_OnDeterminingFilename_DangerousOverride
) {
2616 LoadExtension("downloads_split");
2617 AddFilenameDeterminer();
2618 ASSERT_TRUE(StartEmbeddedTestServer());
2619 ASSERT_TRUE(test_server()->Start());
2620 std::string download_url
= test_server()->GetURL("slow?0").spec();
2622 // Start downloading a file.
2623 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2624 new DownloadsDownloadFunction(), base::StringPrintf(
2625 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2626 ASSERT_TRUE(result
.get());
2628 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2629 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2631 ScopedCancellingItem
canceller(item
);
2632 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2634 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2636 "[{\"danger\": \"safe\","
2637 " \"incognito\": false,"
2639 " \"mime\": \"text/plain\","
2640 " \"paused\": false,"
2641 " \"url\": \"%s\"}]",
2643 download_url
.c_str())));
2644 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2647 " \"filename\":\"slow.txt\"}]",
2649 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2650 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2652 // Respond to the onDeterminingFilename.
2654 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2655 browser()->profile(),
2659 base::FilePath(FILE_PATH_LITERAL("overridden.swf")),
2660 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2662 EXPECT_EQ("", error
);
2664 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2668 " \"previous\":\"safe\","
2669 " \"current\":\"file\"}}]",
2672 item
->ValidateDangerousDownload();
2673 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2677 " \"previous\":\"file\","
2678 " \"current\":\"accepted\"}}]",
2680 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2684 " \"previous\": \"in_progress\","
2685 " \"current\": \"complete\"}}]",
2687 EXPECT_EQ(downloads_directory().AppendASCII("overridden.swf"),
2688 item
->GetTargetFilePath());
2691 IN_PROC_BROWSER_TEST_F(
2692 DownloadExtensionTest
,
2693 DownloadExtensionTest_OnDeterminingFilename_ReferencesParentInvalid
) {
2695 LoadExtension("downloads_split");
2696 AddFilenameDeterminer();
2697 ASSERT_TRUE(StartEmbeddedTestServer());
2698 ASSERT_TRUE(test_server()->Start());
2699 std::string download_url
= test_server()->GetURL("slow?0").spec();
2701 // Start downloading a file.
2702 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2703 new DownloadsDownloadFunction(), base::StringPrintf(
2704 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2705 ASSERT_TRUE(result
.get());
2707 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2708 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2710 ScopedCancellingItem
canceller(item
);
2711 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2713 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2715 "[{\"danger\": \"safe\","
2716 " \"incognito\": false,"
2718 " \"mime\": \"text/plain\","
2719 " \"paused\": false,"
2720 " \"url\": \"%s\"}]",
2722 download_url
.c_str())));
2723 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2726 " \"filename\":\"slow.txt\"}]",
2728 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2729 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2731 // Respond to the onDeterminingFilename.
2733 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2734 browser()->profile(),
2738 base::FilePath(FILE_PATH_LITERAL("sneaky/../../sneaky.txt")),
2739 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2741 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
2742 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2746 " \"previous\": \"\","
2747 " \"current\": \"%s\"}}]",
2749 GetFilename("slow.txt").c_str())));
2750 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2754 " \"previous\": \"in_progress\","
2755 " \"current\": \"complete\"}}]",
2759 IN_PROC_BROWSER_TEST_F(
2760 DownloadExtensionTest
,
2761 DownloadExtensionTest_OnDeterminingFilename_IllegalFilename
) {
2763 LoadExtension("downloads_split");
2764 AddFilenameDeterminer();
2765 ASSERT_TRUE(StartEmbeddedTestServer());
2766 ASSERT_TRUE(test_server()->Start());
2767 std::string download_url
= test_server()->GetURL("slow?0").spec();
2769 // Start downloading a file.
2770 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2771 new DownloadsDownloadFunction(), base::StringPrintf(
2772 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2773 ASSERT_TRUE(result
.get());
2775 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2776 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2778 ScopedCancellingItem
canceller(item
);
2779 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2781 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2783 "[{\"danger\": \"safe\","
2784 " \"incognito\": false,"
2786 " \"mime\": \"text/plain\","
2787 " \"paused\": false,"
2788 " \"url\": \"%s\"}]",
2790 download_url
.c_str())));
2791 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2794 " \"filename\":\"slow.txt\"}]",
2796 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2797 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2799 // Respond to the onDeterminingFilename.
2801 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2802 browser()->profile(),
2806 base::FilePath(FILE_PATH_LITERAL("<")),
2807 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2809 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
2810 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2814 " \"previous\": \"\","
2815 " \"current\": \"%s\"}}]",
2817 GetFilename("slow.txt").c_str())));
2818 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2822 " \"previous\": \"in_progress\","
2823 " \"current\": \"complete\"}}]",
2827 IN_PROC_BROWSER_TEST_F(
2828 DownloadExtensionTest
,
2829 DownloadExtensionTest_OnDeterminingFilename_IllegalFilenameExtension
) {
2831 LoadExtension("downloads_split");
2832 AddFilenameDeterminer();
2833 ASSERT_TRUE(StartEmbeddedTestServer());
2834 ASSERT_TRUE(test_server()->Start());
2835 std::string download_url
= test_server()->GetURL("slow?0").spec();
2837 // Start downloading a file.
2838 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2839 new DownloadsDownloadFunction(), base::StringPrintf(
2840 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2841 ASSERT_TRUE(result
.get());
2843 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2844 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2846 ScopedCancellingItem
canceller(item
);
2847 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2849 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2851 "[{\"danger\": \"safe\","
2852 " \"incognito\": false,"
2854 " \"mime\": \"text/plain\","
2855 " \"paused\": false,"
2856 " \"url\": \"%s\"}]",
2858 download_url
.c_str())));
2859 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2862 " \"filename\":\"slow.txt\"}]",
2864 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2865 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2867 // Respond to the onDeterminingFilename.
2869 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2870 browser()->profile(),
2874 base::FilePath(FILE_PATH_LITERAL(
2875 "My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}/foo")),
2876 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2878 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
2879 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2883 " \"previous\": \"\","
2884 " \"current\": \"%s\"}}]",
2886 GetFilename("slow.txt").c_str())));
2887 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2891 " \"previous\": \"in_progress\","
2892 " \"current\": \"complete\"}}]",
2896 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2897 DISABLED_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2899 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2900 DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2902 IN_PROC_BROWSER_TEST_F(
2903 DownloadExtensionTest
,
2904 MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
) {
2906 LoadExtension("downloads_split");
2907 AddFilenameDeterminer();
2908 ASSERT_TRUE(StartEmbeddedTestServer());
2909 ASSERT_TRUE(test_server()->Start());
2910 std::string download_url
= test_server()->GetURL("slow?0").spec();
2912 // Start downloading a file.
2913 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2914 new DownloadsDownloadFunction(), base::StringPrintf(
2915 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2916 ASSERT_TRUE(result
.get());
2918 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2919 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2921 ScopedCancellingItem
canceller(item
);
2922 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2924 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2926 "[{\"danger\": \"safe\","
2927 " \"incognito\": false,"
2929 " \"mime\": \"text/plain\","
2930 " \"paused\": false,"
2931 " \"url\": \"%s\"}]",
2933 download_url
.c_str())));
2934 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2937 " \"filename\":\"slow.txt\"}]",
2939 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2940 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2942 // Respond to the onDeterminingFilename.
2944 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2945 browser()->profile(),
2949 base::FilePath(FILE_PATH_LITERAL("con.foo")),
2950 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2952 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
2953 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2957 " \"previous\": \"\","
2958 " \"current\": \"%s\"}}]",
2960 GetFilename("slow.txt").c_str())));
2961 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2965 " \"previous\": \"in_progress\","
2966 " \"current\": \"complete\"}}]",
2970 IN_PROC_BROWSER_TEST_F(
2971 DownloadExtensionTest
,
2972 DownloadExtensionTest_OnDeterminingFilename_CurDirInvalid
) {
2974 LoadExtension("downloads_split");
2975 AddFilenameDeterminer();
2976 ASSERT_TRUE(StartEmbeddedTestServer());
2977 ASSERT_TRUE(test_server()->Start());
2978 std::string download_url
= test_server()->GetURL("slow?0").spec();
2980 // Start downloading a file.
2981 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2982 new DownloadsDownloadFunction(), base::StringPrintf(
2983 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2984 ASSERT_TRUE(result
.get());
2986 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2987 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2989 ScopedCancellingItem
canceller(item
);
2990 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2992 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2994 "[{\"danger\": \"safe\","
2995 " \"incognito\": false,"
2997 " \"mime\": \"text/plain\","
2998 " \"paused\": false,"
2999 " \"url\": \"%s\"}]",
3001 download_url
.c_str())));
3002 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3005 " \"filename\":\"slow.txt\"}]",
3007 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3008 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3010 // Respond to the onDeterminingFilename.
3012 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3013 browser()->profile(),
3017 base::FilePath(FILE_PATH_LITERAL(".")),
3018 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3020 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
3021 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3025 " \"previous\": \"\","
3026 " \"current\": \"%s\"}}]",
3028 GetFilename("slow.txt").c_str())));
3029 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3033 " \"previous\": \"in_progress\","
3034 " \"current\": \"complete\"}}]",
3038 IN_PROC_BROWSER_TEST_F(
3039 DownloadExtensionTest
,
3040 DownloadExtensionTest_OnDeterminingFilename_ParentDirInvalid
) {
3041 ASSERT_TRUE(StartEmbeddedTestServer());
3042 ASSERT_TRUE(test_server()->Start());
3044 LoadExtension("downloads_split");
3045 AddFilenameDeterminer();
3046 std::string download_url
= test_server()->GetURL("slow?0").spec();
3048 // Start downloading a file.
3049 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3050 new DownloadsDownloadFunction(), base::StringPrintf(
3051 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3052 ASSERT_TRUE(result
.get());
3054 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3055 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3057 ScopedCancellingItem
canceller(item
);
3058 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3060 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3062 "[{\"danger\": \"safe\","
3063 " \"incognito\": false,"
3065 " \"mime\": \"text/plain\","
3066 " \"paused\": false,"
3067 " \"url\": \"%s\"}]",
3069 download_url
.c_str())));
3070 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3073 " \"filename\":\"slow.txt\"}]",
3075 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3076 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3078 // Respond to the onDeterminingFilename.
3080 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3081 browser()->profile(),
3085 base::FilePath(FILE_PATH_LITERAL("..")),
3086 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3088 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
3089 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3093 " \"previous\": \"\","
3094 " \"current\": \"%s\"}}]",
3096 GetFilename("slow.txt").c_str())));
3097 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3101 " \"previous\": \"in_progress\","
3102 " \"current\": \"complete\"}}]",
3106 IN_PROC_BROWSER_TEST_F(
3107 DownloadExtensionTest
,
3108 DownloadExtensionTest_OnDeterminingFilename_AbsPathInvalid
) {
3110 LoadExtension("downloads_split");
3111 AddFilenameDeterminer();
3112 ASSERT_TRUE(StartEmbeddedTestServer());
3113 ASSERT_TRUE(test_server()->Start());
3114 std::string download_url
= test_server()->GetURL("slow?0").spec();
3116 // Start downloading a file.
3117 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3118 new DownloadsDownloadFunction(), base::StringPrintf(
3119 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3120 ASSERT_TRUE(result
.get());
3122 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3123 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3125 ScopedCancellingItem
canceller(item
);
3126 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3128 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3130 "[{\"danger\": \"safe\","
3131 " \"incognito\": false,"
3133 " \"mime\": \"text/plain\","
3134 " \"paused\": false,"
3135 " \"url\": \"%s\"}]",
3137 download_url
.c_str())));
3138 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3141 " \"filename\":\"slow.txt\"}]",
3143 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3144 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3146 // Respond to the onDeterminingFilename. Absolute paths should be rejected.
3148 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3149 browser()->profile(),
3153 downloads_directory().Append(FILE_PATH_LITERAL("sneaky.txt")),
3154 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3156 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
3158 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3162 " \"previous\": \"\","
3163 " \"current\": \"%s\"}}]",
3165 GetFilename("slow.txt").c_str())));
3166 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3170 " \"previous\": \"in_progress\","
3171 " \"current\": \"complete\"}}]",
3175 IN_PROC_BROWSER_TEST_F(
3176 DownloadExtensionTest
,
3177 DownloadExtensionTest_OnDeterminingFilename_EmptyBasenameInvalid
) {
3179 LoadExtension("downloads_split");
3180 AddFilenameDeterminer();
3181 ASSERT_TRUE(StartEmbeddedTestServer());
3182 ASSERT_TRUE(test_server()->Start());
3183 std::string download_url
= test_server()->GetURL("slow?0").spec();
3185 // Start downloading a file.
3186 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3187 new DownloadsDownloadFunction(), base::StringPrintf(
3188 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3189 ASSERT_TRUE(result
.get());
3191 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3192 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3194 ScopedCancellingItem
canceller(item
);
3195 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3197 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3199 "[{\"danger\": \"safe\","
3200 " \"incognito\": false,"
3202 " \"mime\": \"text/plain\","
3203 " \"paused\": false,"
3204 " \"url\": \"%s\"}]",
3206 download_url
.c_str())));
3207 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3210 " \"filename\":\"slow.txt\"}]",
3212 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3213 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3215 // Respond to the onDeterminingFilename. Empty basenames should be rejected.
3217 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3218 browser()->profile(),
3222 base::FilePath(FILE_PATH_LITERAL("foo/")),
3223 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3225 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
3227 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3231 " \"previous\": \"\","
3232 " \"current\": \"%s\"}}]",
3234 GetFilename("slow.txt").c_str())));
3235 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3239 " \"previous\": \"in_progress\","
3240 " \"current\": \"complete\"}}]",
3244 // conflictAction may be specified without filename.
3245 IN_PROC_BROWSER_TEST_F(
3246 DownloadExtensionTest
,
3247 DownloadExtensionTest_OnDeterminingFilename_Overwrite
) {
3249 LoadExtension("downloads_split");
3250 AddFilenameDeterminer();
3251 ASSERT_TRUE(StartEmbeddedTestServer());
3252 ASSERT_TRUE(test_server()->Start());
3253 std::string download_url
= test_server()->GetURL("slow?0").spec();
3255 // Start downloading a file.
3256 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3257 new DownloadsDownloadFunction(), base::StringPrintf(
3258 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3259 ASSERT_TRUE(result
.get());
3261 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3262 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3264 ScopedCancellingItem
canceller(item
);
3265 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3266 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3268 "[{\"danger\": \"safe\","
3269 " \"incognito\": false,"
3271 " \"mime\": \"text/plain\","
3272 " \"paused\": false,"
3273 " \"url\": \"%s\"}]",
3275 download_url
.c_str())));
3276 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3279 " \"filename\":\"slow.txt\"}]",
3281 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3282 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3284 // Respond to the onDeterminingFilename.
3286 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3287 browser()->profile(),
3292 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3294 EXPECT_EQ("", error
);
3296 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3300 " \"previous\": \"\","
3301 " \"current\": \"%s\"}}]",
3303 GetFilename("slow.txt").c_str())));
3304 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3308 " \"previous\": \"in_progress\","
3309 " \"current\": \"complete\"}}]",
3312 // Start downloading a file.
3313 result
.reset(RunFunctionAndReturnResult(
3314 new DownloadsDownloadFunction(), base::StringPrintf(
3315 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3316 ASSERT_TRUE(result
.get());
3318 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3319 item
= GetCurrentManager()->GetDownload(result_id
);
3321 ScopedCancellingItem
canceller2(item
);
3322 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3324 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3326 "[{\"danger\": \"safe\","
3327 " \"incognito\": false,"
3329 " \"mime\": \"text/plain\","
3330 " \"paused\": false,"
3331 " \"url\": \"%s\"}]",
3333 download_url
.c_str())));
3334 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3337 " \"filename\":\"slow.txt\"}]",
3339 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3340 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3342 // Respond to the onDeterminingFilename.
3343 // Also test that DetermineFilename allows (chrome) extensions to set
3344 // filenames without (filename) extensions. (Don't ask about v8 extensions or
3345 // python extensions or kernel extensions or firefox extensions...)
3347 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3348 browser()->profile(),
3353 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
,
3355 EXPECT_EQ("", error
);
3357 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3361 " \"previous\": \"\","
3362 " \"current\": \"%s\"}}]",
3364 GetFilename("slow.txt").c_str())));
3365 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3369 " \"previous\": \"in_progress\","
3370 " \"current\": \"complete\"}}]",
3374 IN_PROC_BROWSER_TEST_F(
3375 DownloadExtensionTest
,
3376 DownloadExtensionTest_OnDeterminingFilename_Override
) {
3378 LoadExtension("downloads_split");
3379 AddFilenameDeterminer();
3380 ASSERT_TRUE(StartEmbeddedTestServer());
3381 ASSERT_TRUE(test_server()->Start());
3382 std::string download_url
= test_server()->GetURL("slow?0").spec();
3384 // Start downloading a file.
3385 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3386 new DownloadsDownloadFunction(), base::StringPrintf(
3387 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3388 ASSERT_TRUE(result
.get());
3390 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3391 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3393 ScopedCancellingItem
canceller(item
);
3394 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3395 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3397 "[{\"danger\": \"safe\","
3398 " \"incognito\": false,"
3400 " \"mime\": \"text/plain\","
3401 " \"paused\": false,"
3402 " \"url\": \"%s\"}]",
3404 download_url
.c_str())));
3405 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3408 " \"filename\":\"slow.txt\"}]",
3410 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3411 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3413 // Respond to the onDeterminingFilename.
3415 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3416 browser()->profile(),
3421 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3423 EXPECT_EQ("", error
);
3425 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3429 " \"previous\": \"\","
3430 " \"current\": \"%s\"}}]",
3432 GetFilename("slow.txt").c_str())));
3433 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3437 " \"previous\": \"in_progress\","
3438 " \"current\": \"complete\"}}]",
3441 // Start downloading a file.
3442 result
.reset(RunFunctionAndReturnResult(
3443 new DownloadsDownloadFunction(), base::StringPrintf(
3444 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3445 ASSERT_TRUE(result
.get());
3447 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3448 item
= GetCurrentManager()->GetDownload(result_id
);
3450 ScopedCancellingItem
canceller2(item
);
3451 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3453 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3455 "[{\"danger\": \"safe\","
3456 " \"incognito\": false,"
3458 " \"mime\": \"text/plain\","
3459 " \"paused\": false,"
3460 " \"url\": \"%s\"}]",
3462 download_url
.c_str())));
3463 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3466 " \"filename\":\"slow.txt\"}]",
3468 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3469 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3471 // Respond to the onDeterminingFilename.
3472 // Also test that DetermineFilename allows (chrome) extensions to set
3473 // filenames without (filename) extensions. (Don't ask about v8 extensions or
3474 // python extensions or kernel extensions or firefox extensions...)
3476 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3477 browser()->profile(),
3481 base::FilePath(FILE_PATH_LITERAL("foo")),
3482 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
,
3484 EXPECT_EQ("", error
);
3486 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3490 " \"previous\": \"\","
3491 " \"current\": \"%s\"}}]",
3493 GetFilename("foo").c_str())));
3494 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3498 " \"previous\": \"in_progress\","
3499 " \"current\": \"complete\"}}]",
3503 // TODO test precedence rules: install_time
3505 #if defined(OS_MACOSX)
3506 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer \
3507 DISABLED_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer
3509 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer \
3510 DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer
3512 IN_PROC_BROWSER_TEST_F(
3513 DownloadExtensionTest
,
3514 MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer
) {
3515 ASSERT_TRUE(StartEmbeddedTestServer());
3516 ASSERT_TRUE(test_server()->Start());
3518 LoadExtension("downloads_split");
3519 content::RenderProcessHost
* host
= AddFilenameDeterminer();
3520 std::string download_url
= test_server()->GetURL("slow?0").spec();
3522 // Start downloading a file.
3523 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3524 new DownloadsDownloadFunction(), base::StringPrintf(
3525 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3526 ASSERT_TRUE(result
.get());
3528 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3529 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3531 ScopedCancellingItem
canceller(item
);
3532 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3534 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3536 "[{\"danger\": \"safe\","
3537 " \"incognito\": false,"
3539 " \"mime\": \"text/plain\","
3540 " \"paused\": false,"
3541 " \"url\": \"%s\"}]",
3543 download_url
.c_str())));
3544 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3547 " \"filename\":\"slow.txt\"}]",
3549 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3550 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3552 // Remove a determiner while waiting for it.
3553 RemoveFilenameDeterminer(host
);
3555 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3559 " \"previous\": \"in_progress\","
3560 " \"current\": \"complete\"}}]",
3564 IN_PROC_BROWSER_TEST_F(
3565 DownloadExtensionTest
,
3566 DownloadExtensionTest_OnDeterminingFilename_IncognitoSplit
) {
3567 LoadExtension("downloads_split");
3568 ASSERT_TRUE(StartEmbeddedTestServer());
3569 ASSERT_TRUE(test_server()->Start());
3570 std::string download_url
= test_server()->GetURL("slow?0").spec();
3573 AddFilenameDeterminer();
3576 AddFilenameDeterminer();
3578 // Start an on-record download.
3580 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3581 new DownloadsDownloadFunction(), base::StringPrintf(
3582 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3583 ASSERT_TRUE(result
.get());
3585 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3586 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3588 ScopedCancellingItem
canceller(item
);
3589 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3591 // Wait for the onCreated and onDeterminingFilename events.
3592 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3594 "[{\"danger\": \"safe\","
3595 " \"incognito\": false,"
3597 " \"mime\": \"text/plain\","
3598 " \"paused\": false,"
3599 " \"url\": \"%s\"}]",
3601 download_url
.c_str())));
3602 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3605 " \"incognito\": false,"
3606 " \"filename\":\"slow.txt\"}]",
3608 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3609 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3611 // Respond to the onDeterminingFilename events.
3613 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3614 current_browser()->profile(),
3618 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3619 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3621 EXPECT_EQ("", error
);
3623 // The download should complete successfully.
3624 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3628 " \"previous\": \"\","
3629 " \"current\": \"%s\"}}]",
3631 GetFilename("42.txt").c_str())));
3632 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3636 " \"previous\": \"in_progress\","
3637 " \"current\": \"complete\"}}]",
3640 // Start an incognito download for comparison.
3642 result
.reset(RunFunctionAndReturnResult(
3643 new DownloadsDownloadFunction(), base::StringPrintf(
3644 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3645 ASSERT_TRUE(result
.get());
3647 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3648 item
= GetCurrentManager()->GetDownload(result_id
);
3650 ScopedCancellingItem
canceller2(item
);
3651 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3653 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3655 "[{\"danger\": \"safe\","
3656 " \"incognito\": true,"
3658 " \"mime\": \"text/plain\","
3659 " \"paused\": false,"
3660 " \"url\": \"%s\"}]",
3662 download_url
.c_str())));
3663 // On-Record renderers should not see events for off-record items.
3664 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3667 " \"incognito\": true,"
3668 " \"filename\":\"slow.txt\"}]",
3670 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3671 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3673 // Respond to the onDeterminingFilename.
3675 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3676 current_browser()->profile(),
3680 base::FilePath(FILE_PATH_LITERAL("5.txt")),
3681 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3683 EXPECT_EQ("", error
);
3685 // The download should complete successfully.
3686 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3690 " \"previous\": \"\","
3691 " \"current\": \"%s\"}}]",
3693 GetFilename("5.txt").c_str())));
3694 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3698 " \"previous\": \"in_progress\","
3699 " \"current\": \"complete\"}}]",
3703 IN_PROC_BROWSER_TEST_F(
3704 DownloadExtensionTest
,
3705 DownloadExtensionTest_OnDeterminingFilename_IncognitoSpanning
) {
3706 LoadExtension("downloads_spanning");
3707 ASSERT_TRUE(StartEmbeddedTestServer());
3708 ASSERT_TRUE(test_server()->Start());
3709 std::string download_url
= test_server()->GetURL("slow?0").spec();
3712 AddFilenameDeterminer();
3714 // There is a single extension renderer that sees both on-record and
3715 // off-record events. The extension functions see the on-record profile with
3716 // include_incognito=true.
3718 // Start an on-record download.
3720 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3721 new DownloadsDownloadFunction(), base::StringPrintf(
3722 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3723 ASSERT_TRUE(result
.get());
3725 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3726 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3728 ScopedCancellingItem
canceller(item
);
3729 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3731 // Wait for the onCreated and onDeterminingFilename events.
3732 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3734 "[{\"danger\": \"safe\","
3735 " \"incognito\": false,"
3737 " \"mime\": \"text/plain\","
3738 " \"paused\": false,"
3739 " \"url\": \"%s\"}]",
3741 download_url
.c_str())));
3742 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3745 " \"incognito\": false,"
3746 " \"filename\":\"slow.txt\"}]",
3748 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3749 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3751 // Respond to the onDeterminingFilename events.
3753 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3754 current_browser()->profile(),
3758 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3759 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3761 EXPECT_EQ("", error
);
3763 // The download should complete successfully.
3764 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3768 " \"previous\": \"\","
3769 " \"current\": \"%s\"}}]",
3771 GetFilename("42.txt").c_str())));
3772 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3776 " \"previous\": \"in_progress\","
3777 " \"current\": \"complete\"}}]",
3780 // Start an incognito download for comparison.
3782 result
.reset(RunFunctionAndReturnResult(
3783 new DownloadsDownloadFunction(), base::StringPrintf(
3784 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3785 ASSERT_TRUE(result
.get());
3787 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3788 item
= GetCurrentManager()->GetDownload(result_id
);
3790 ScopedCancellingItem
canceller2(item
);
3791 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3793 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3795 "[{\"danger\": \"safe\","
3796 " \"incognito\": true,"
3798 " \"mime\": \"text/plain\","
3799 " \"paused\": false,"
3800 " \"url\": \"%s\"}]",
3802 download_url
.c_str())));
3803 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3806 " \"incognito\": true,"
3807 " \"filename\":\"slow.txt\"}]",
3809 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3810 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3812 // Respond to the onDeterminingFilename.
3814 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3815 current_browser()->profile(),
3819 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3820 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3822 EXPECT_EQ("", error
);
3824 // The download should complete successfully.
3825 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3829 " \"previous\": \"\","
3830 " \"current\": \"%s\"}}]",
3832 GetFilename("42 (1).txt").c_str())));
3833 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3837 " \"previous\": \"in_progress\","
3838 " \"current\": \"complete\"}}]",
3843 // This test is very flaky on Win XP and Aura. http://crbug.com/248438
3844 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3845 DISABLED_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3847 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3848 DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3851 // Test download interruption while extensions determining filename. Should not
3852 // re-dispatch onDeterminingFilename.
3853 IN_PROC_BROWSER_TEST_F(
3854 DownloadExtensionTest
,
3855 MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
) {
3856 base::CommandLine::ForCurrentProcess()->AppendSwitch(
3857 switches::kEnableDownloadResumption
);
3858 LoadExtension("downloads_split");
3859 ASSERT_TRUE(StartEmbeddedTestServer());
3860 ASSERT_TRUE(test_server()->Start());
3862 content::RenderProcessHost
* host
= AddFilenameDeterminer();
3864 // Start a download.
3865 DownloadItem
* item
= NULL
;
3867 DownloadManager
* manager
= GetCurrentManager();
3868 scoped_ptr
<content::DownloadTestObserver
> observer(
3869 new JustInProgressDownloadObserver(manager
, 1));
3870 ASSERT_EQ(0, manager
->InProgressCount());
3871 ASSERT_EQ(0, manager
->NonMaliciousInProgressCount());
3872 // Tabs created just for a download are automatically closed, invalidating
3873 // the download's WebContents. Downloads without WebContents cannot be
3874 // resumed. http://crbug.com/225901
3875 ui_test_utils::NavigateToURLWithDisposition(
3877 GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl
),
3879 ui_test_utils::BROWSER_TEST_NONE
);
3880 observer
->WaitForFinished();
3881 EXPECT_EQ(1u, observer
->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS
));
3882 DownloadManager::DownloadVector items
;
3883 manager
->GetAllDownloads(&items
);
3884 for (DownloadManager::DownloadVector::iterator iter
= items
.begin();
3885 iter
!= items
.end(); ++iter
) {
3886 if ((*iter
)->GetState() == DownloadItem::IN_PROGRESS
) {
3887 // There should be only one IN_PROGRESS item.
3888 EXPECT_EQ(NULL
, item
);
3894 ScopedCancellingItem
canceller(item
);
3896 // Wait for the onCreated and onDeterminingFilename event.
3897 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3899 "[{\"danger\": \"safe\","
3900 " \"incognito\": false,"
3902 " \"mime\": \"application/octet-stream\","
3903 " \"paused\": false}]",
3905 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3908 " \"incognito\": false,"
3909 " \"filename\":\"download-unknown-size\"}]",
3911 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3912 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3915 ui_test_utils::NavigateToURLWithDisposition(
3917 GURL(net::URLRequestSlowDownloadJob::kErrorDownloadUrl
),
3919 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
3921 // Errors caught before filename determination are delayed until after
3922 // filename determination.
3924 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3925 current_browser()->profile(),
3929 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3930 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3933 EXPECT_EQ("", error
);
3934 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3938 " \"previous\": \"\","
3939 " \"current\": \"%s\"}}]",
3941 GetFilename("42.txt").c_str())));
3943 content::DownloadUpdatedObserver
interrupted(item
, base::Bind(
3944 ItemIsInterrupted
));
3945 ASSERT_TRUE(interrupted
.WaitForEvent());
3946 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3949 " \"error\":{\"current\":\"NETWORK_FAILED\"},"
3951 " \"previous\":\"in_progress\","
3952 " \"current\":\"interrupted\"}}]",
3956 // Downloads that are restarted on resumption trigger another download target
3958 RemoveFilenameDeterminer(host
);
3961 // Errors caught before filename determination is complete are delayed until
3962 // after filename determination so that, on resumption, filename determination
3963 // does not need to be re-done. So, there will not be a second
3964 // onDeterminingFilename event.
3966 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3969 " \"error\":{\"previous\":\"NETWORK_FAILED\"},"
3971 " \"previous\":\"interrupted\","
3972 " \"current\":\"in_progress\"}}]",
3976 FinishPendingSlowDownloads();
3978 // The download should complete successfully.
3979 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3983 " \"previous\": \"in_progress\","
3984 " \"current\": \"complete\"}}]",
3988 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
3989 DownloadExtensionTest_SetShelfEnabled
) {
3990 LoadExtension("downloads_split");
3991 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[false]"));
3992 EXPECT_FALSE(DownloadServiceFactory::GetForBrowserContext(
3993 browser()->profile())->IsShelfEnabled());
3994 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[true]"));
3995 EXPECT_TRUE(DownloadServiceFactory::GetForBrowserContext(
3996 browser()->profile())->IsShelfEnabled());
3997 // TODO(benjhayden) Test that existing shelves are hidden.
3998 // TODO(benjhayden) Test multiple extensions.
3999 // TODO(benjhayden) Test disabling extensions.
4000 // TODO(benjhayden) Test that browsers associated with other profiles are not
4002 // TODO(benjhayden) Test incognito.
4005 // TODO(benjhayden) Figure out why DisableExtension() does not fire
4006 // OnListenerRemoved.
4008 // TODO(benjhayden) Test that the shelf is shown for download() both with and
4009 // without a WebContents.
4011 void OnDangerPromptCreated(DownloadDangerPrompt
* prompt
) {
4012 prompt
->InvokeActionForTesting(DownloadDangerPrompt::ACCEPT
);
4015 #if defined(OS_MACOSX)
4016 // Flakily triggers and assert on Mac.
4017 // http://crbug.com/180759
4018 #define MAYBE_DownloadExtensionTest_AcceptDanger DISABLED_DownloadExtensionTest_AcceptDanger
4020 #define MAYBE_DownloadExtensionTest_AcceptDanger DownloadExtensionTest_AcceptDanger
4022 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
4023 MAYBE_DownloadExtensionTest_AcceptDanger
) {
4024 // Download a file that will be marked dangerous; click the browser action
4025 // button; the browser action poup will call acceptDanger(); when the
4026 // DownloadDangerPrompt is created, pretend that the user clicks the Accept
4027 // button; wait until the download completes.
4028 LoadExtension("downloads_split");
4029 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
4030 new DownloadsDownloadFunction(),
4031 "[{\"url\": \"data:,\", \"filename\": \"dangerous.swf\"}]"));
4032 ASSERT_TRUE(result
.get());
4034 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
4035 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
4037 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
4041 " \"previous\": \"safe\","
4042 " \"current\": \"file\"}}]",
4044 ASSERT_TRUE(item
->IsDangerous());
4045 ScopedCancellingItem
canceller(item
);
4046 scoped_ptr
<content::DownloadTestObserver
> observer(
4047 new content::DownloadTestObserverTerminal(
4048 GetCurrentManager(), 1,
4049 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_IGNORE
));
4050 DownloadsAcceptDangerFunction::OnPromptCreatedCallback callback
=
4051 base::Bind(&OnDangerPromptCreated
);
4052 DownloadsAcceptDangerFunction::OnPromptCreatedForTesting(
4054 BrowserActionTestUtil(browser()).Press(0);
4055 observer
->WaitForFinished();
4058 class DownloadsApiTest
: public ExtensionApiTest
{
4060 DownloadsApiTest() {}
4061 ~DownloadsApiTest() override
{}
4064 DISALLOW_COPY_AND_ASSIGN(DownloadsApiTest
);
4068 IN_PROC_BROWSER_TEST_F(DownloadsApiTest
, DownloadsApiTest
) {
4069 ASSERT_TRUE(RunExtensionTest("downloads")) << message_
;
4072 TEST(DownloadInterruptReasonEnumsSynced
,
4073 DownloadInterruptReasonEnumsSynced
) {
4074 #define INTERRUPT_REASON(name, value) \
4075 EXPECT_EQ(InterruptReasonContentToExtension( \
4076 content::DOWNLOAD_INTERRUPT_REASON_##name), \
4077 downloads::INTERRUPT_REASON_##name); \
4079 InterruptReasonExtensionToContent(downloads::INTERRUPT_REASON_##name), \
4080 content::DOWNLOAD_INTERRUPT_REASON_##name);
4081 #include "content/public/browser/download_interrupt_reason_values.h" // NOLINT
4082 #undef INTERRUPT_REASON
4085 TEST(ExtensionDetermineDownloadFilenameInternal
,
4086 ExtensionDetermineDownloadFilenameInternal
) {
4087 std::string winner_id
;
4088 base::FilePath filename
;
4089 downloads::FilenameConflictAction conflict_action
=
4090 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
;
4091 WarningSet warnings
;
4093 // Empty incumbent determiner
4095 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4096 base::FilePath(FILE_PATH_LITERAL("a")),
4097 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
,
4106 EXPECT_EQ("suggester", winner_id
);
4107 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename
.value());
4108 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
, conflict_action
);
4109 EXPECT_TRUE(warnings
.empty());
4113 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4114 base::FilePath(FILE_PATH_LITERAL("b")),
4115 downloads::FILENAME_CONFLICT_ACTION_PROMPT
,
4117 base::Time::Now() - base::TimeDelta::FromDays(1),
4124 EXPECT_EQ("incumbent", winner_id
);
4125 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename
.value());
4126 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
, conflict_action
);
4127 EXPECT_FALSE(warnings
.empty());
4128 EXPECT_EQ(Warning::kDownloadFilenameConflict
,
4129 warnings
.begin()->warning_type());
4130 EXPECT_EQ("suggester", warnings
.begin()->extension_id());
4134 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4135 base::FilePath(FILE_PATH_LITERAL("b")),
4136 downloads::FILENAME_CONFLICT_ACTION_PROMPT
,
4140 base::Time::Now() - base::TimeDelta::FromDays(1),
4145 EXPECT_EQ("suggester", winner_id
);
4146 EXPECT_EQ(FILE_PATH_LITERAL("b"), filename
.value());
4147 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_PROMPT
, conflict_action
);
4148 EXPECT_FALSE(warnings
.empty());
4149 EXPECT_EQ(Warning::kDownloadFilenameConflict
,
4150 warnings
.begin()->warning_type());
4151 EXPECT_EQ("incumbent", warnings
.begin()->extension_id());
4154 } // namespace extensions
4156 #endif // http://crbug.com/3061144