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::Read(json_args
).release()),
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().
1113 // http://crbug.com/508949
1114 #if defined(MEMORY_SANITIZER)
1115 #define MAYBE_DownloadExtensionTest_SearchId DISABLED_DownloadExtensionTest_SearchId
1117 #define MAYBE_DownloadExtensionTest_SearchId DownloadExtensionTest_SearchId
1119 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1120 MAYBE_DownloadExtensionTest_SearchId
) {
1121 DownloadManager::DownloadVector items
;
1122 CreateSlowTestDownloads(2, &items
);
1123 ScopedItemVectorCanceller
delete_items(&items
);
1125 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1126 new DownloadsSearchFunction(), base::StringPrintf(
1127 "[{\"id\": %u}]", items
[0]->GetId())));
1128 ASSERT_TRUE(result
.get());
1129 base::ListValue
* result_list
= NULL
;
1130 ASSERT_TRUE(result
->GetAsList(&result_list
));
1131 ASSERT_EQ(1UL, result_list
->GetSize());
1132 base::DictionaryValue
* item_value
= NULL
;
1133 ASSERT_TRUE(result_list
->GetDictionary(0, &item_value
));
1135 ASSERT_TRUE(item_value
->GetInteger("id", &item_id
));
1136 ASSERT_EQ(items
[0]->GetId(), static_cast<uint32
>(item_id
));
1139 // Test specifying both the |id| and |filename| parameters for search().
1141 // http://crbug.com/508949
1142 #if defined(MEMORY_SANITIZER)
1143 #define MAYBE_DownloadExtensionTest_SearchIdAndFilename DISABLED_DownloadExtensionTest_SearchIdAndFilename
1145 #define MAYBE_DownloadExtensionTest_SearchIdAndFilename DownloadExtensionTest_SearchIdAndFilename
1147 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1148 MAYBE_DownloadExtensionTest_SearchIdAndFilename
) {
1149 DownloadManager::DownloadVector items
;
1150 CreateSlowTestDownloads(2, &items
);
1151 ScopedItemVectorCanceller
delete_items(&items
);
1153 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1154 new DownloadsSearchFunction(),
1155 "[{\"id\": 0, \"filename\": \"foobar\"}]"));
1156 ASSERT_TRUE(result
.get());
1157 base::ListValue
* result_list
= NULL
;
1158 ASSERT_TRUE(result
->GetAsList(&result_list
));
1159 ASSERT_EQ(0UL, result_list
->GetSize());
1162 // Test a single |orderBy| parameter for search().
1163 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1164 DownloadExtensionTest_SearchOrderBy
) {
1165 const HistoryDownloadInfo kHistoryInfo
[] = {
1166 { FILE_PATH_LITERAL("zzz"),
1167 DownloadItem::COMPLETE
,
1168 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
},
1169 { FILE_PATH_LITERAL("baz"),
1170 DownloadItem::COMPLETE
,
1171 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
}
1173 DownloadManager::DownloadVector items
;
1174 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1177 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1178 new DownloadsSearchFunction(), "[{\"orderBy\": [\"filename\"]}]"));
1179 ASSERT_TRUE(result
.get());
1180 base::ListValue
* result_list
= NULL
;
1181 ASSERT_TRUE(result
->GetAsList(&result_list
));
1182 ASSERT_EQ(2UL, result_list
->GetSize());
1183 base::DictionaryValue
* item0_value
= NULL
;
1184 base::DictionaryValue
* item1_value
= NULL
;
1185 ASSERT_TRUE(result_list
->GetDictionary(0, &item0_value
));
1186 ASSERT_TRUE(result_list
->GetDictionary(1, &item1_value
));
1187 std::string item0_name
, item1_name
;
1188 ASSERT_TRUE(item0_value
->GetString("filename", &item0_name
));
1189 ASSERT_TRUE(item1_value
->GetString("filename", &item1_name
));
1190 ASSERT_GT(items
[0]->GetTargetFilePath().value(),
1191 items
[1]->GetTargetFilePath().value());
1192 ASSERT_LT(item0_name
, item1_name
);
1195 // Test specifying an empty |orderBy| parameter for search().
1196 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1197 DownloadExtensionTest_SearchOrderByEmpty
) {
1198 const HistoryDownloadInfo kHistoryInfo
[] = {
1199 { FILE_PATH_LITERAL("zzz"),
1200 DownloadItem::COMPLETE
,
1201 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
},
1202 { FILE_PATH_LITERAL("baz"),
1203 DownloadItem::COMPLETE
,
1204 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
}
1206 DownloadManager::DownloadVector items
;
1207 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1210 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1211 new DownloadsSearchFunction(), "[{\"orderBy\": []}]"));
1212 ASSERT_TRUE(result
.get());
1213 base::ListValue
* result_list
= NULL
;
1214 ASSERT_TRUE(result
->GetAsList(&result_list
));
1215 ASSERT_EQ(2UL, result_list
->GetSize());
1216 base::DictionaryValue
* item0_value
= NULL
;
1217 base::DictionaryValue
* item1_value
= NULL
;
1218 ASSERT_TRUE(result_list
->GetDictionary(0, &item0_value
));
1219 ASSERT_TRUE(result_list
->GetDictionary(1, &item1_value
));
1220 std::string item0_name
, item1_name
;
1221 ASSERT_TRUE(item0_value
->GetString("filename", &item0_name
));
1222 ASSERT_TRUE(item1_value
->GetString("filename", &item1_name
));
1223 ASSERT_GT(items
[0]->GetTargetFilePath().value(),
1224 items
[1]->GetTargetFilePath().value());
1225 // The order of results when orderBy is empty is unspecified. When there are
1226 // no sorters, DownloadQuery does not call sort(), so the order of the results
1227 // depends on the order of the items in base::hash_map<uint32,...>
1228 // DownloadManagerImpl::downloads_, which is unspecified and differs between
1229 // libc++ and libstdc++. http://crbug.com/365334
1232 // Test the |danger| option for search().
1233 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1234 DownloadExtensionTest_SearchDanger
) {
1235 const HistoryDownloadInfo kHistoryInfo
[] = {
1236 { FILE_PATH_LITERAL("zzz"),
1237 DownloadItem::COMPLETE
,
1238 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT
},
1239 { FILE_PATH_LITERAL("baz"),
1240 DownloadItem::COMPLETE
,
1241 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
}
1243 DownloadManager::DownloadVector items
;
1244 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1247 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1248 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]"));
1249 ASSERT_TRUE(result
.get());
1250 base::ListValue
* result_list
= NULL
;
1251 ASSERT_TRUE(result
->GetAsList(&result_list
));
1252 ASSERT_EQ(1UL, result_list
->GetSize());
1255 // Test the |state| option for search().
1257 // http://crbug.com/508949
1258 #if defined(MEMORY_SANITIZER)
1259 #define MAYBE_DownloadExtensionTest_SearchState DISABLED_DownloadExtensionTest_SearchState
1261 #define MAYBE_DownloadExtensionTest_SearchState DownloadExtensionTest_SearchState
1263 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1264 MAYBE_DownloadExtensionTest_SearchState
) {
1265 DownloadManager::DownloadVector items
;
1266 CreateSlowTestDownloads(2, &items
);
1267 ScopedItemVectorCanceller
delete_items(&items
);
1269 items
[0]->Cancel(true);
1271 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1272 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]"));
1273 ASSERT_TRUE(result
.get());
1274 base::ListValue
* result_list
= NULL
;
1275 ASSERT_TRUE(result
->GetAsList(&result_list
));
1276 ASSERT_EQ(1UL, result_list
->GetSize());
1279 // Test the |limit| option for search().
1281 // http://crbug.com/508949
1282 #if defined(MEMORY_SANITIZER)
1283 #define MAYBE_DownloadExtensionTest_SearchLimit DISABLED_DownloadExtensionTest_SearchLimit
1285 #define MAYBE_DownloadExtensionTest_SearchLimit DownloadExtensionTest_SearchLimit
1287 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1288 MAYBE_DownloadExtensionTest_SearchLimit
) {
1289 DownloadManager::DownloadVector items
;
1290 CreateSlowTestDownloads(2, &items
);
1291 ScopedItemVectorCanceller
delete_items(&items
);
1293 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1294 new DownloadsSearchFunction(), "[{\"limit\": 1}]"));
1295 ASSERT_TRUE(result
.get());
1296 base::ListValue
* result_list
= NULL
;
1297 ASSERT_TRUE(result
->GetAsList(&result_list
));
1298 ASSERT_EQ(1UL, result_list
->GetSize());
1301 // Test invalid search parameters.
1302 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1303 DownloadExtensionTest_SearchInvalid
) {
1304 std::string error
= RunFunctionAndReturnError(
1305 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]");
1306 EXPECT_STREQ(errors::kInvalidFilter
,
1308 error
= RunFunctionAndReturnError(
1309 new DownloadsSearchFunction(), "[{\"orderBy\": [\"goat\"]}]");
1310 EXPECT_STREQ(errors::kInvalidOrderBy
,
1312 error
= RunFunctionAndReturnError(
1313 new DownloadsSearchFunction(), "[{\"limit\": -1}]");
1314 EXPECT_STREQ(errors::kInvalidQueryLimit
,
1318 // Test searching using multiple conditions through multiple downloads.
1319 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1320 DownloadExtensionTest_SearchPlural
) {
1321 const HistoryDownloadInfo kHistoryInfo
[] = {
1322 { FILE_PATH_LITERAL("aaa"),
1323 DownloadItem::CANCELLED
,
1324 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
},
1325 { FILE_PATH_LITERAL("zzz"),
1326 DownloadItem::COMPLETE
,
1327 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT
},
1328 { FILE_PATH_LITERAL("baz"),
1329 DownloadItem::COMPLETE
,
1330 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT
},
1332 DownloadManager::DownloadVector items
;
1333 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo
, arraysize(kHistoryInfo
),
1336 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1337 new DownloadsSearchFunction(), "[{"
1338 "\"state\": \"complete\", "
1339 "\"danger\": \"content\", "
1340 "\"orderBy\": [\"filename\"], "
1342 ASSERT_TRUE(result
.get());
1343 base::ListValue
* result_list
= NULL
;
1344 ASSERT_TRUE(result
->GetAsList(&result_list
));
1345 ASSERT_EQ(1UL, result_list
->GetSize());
1346 base::DictionaryValue
* item_value
= NULL
;
1347 ASSERT_TRUE(result_list
->GetDictionary(0, &item_value
));
1348 base::FilePath::StringType item_name
;
1349 ASSERT_TRUE(item_value
->GetString("filename", &item_name
));
1350 ASSERT_EQ(items
[2]->GetTargetFilePath().value(), item_name
);
1353 // Test that incognito downloads are only visible in incognito contexts, and
1354 // test that on-record downloads are visible in both incognito and on-record
1355 // contexts, for DownloadsSearchFunction, DownloadsPauseFunction,
1356 // DownloadsResumeFunction, and DownloadsCancelFunction.
1357 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1358 DownloadExtensionTest_SearchPauseResumeCancelGetFileIconIncognito
) {
1359 scoped_ptr
<base::Value
> result_value
;
1360 base::ListValue
* result_list
= NULL
;
1361 base::DictionaryValue
* result_dict
= NULL
;
1362 base::FilePath::StringType filename
;
1363 bool is_incognito
= false;
1365 std::string on_item_arg
;
1366 std::string off_item_arg
;
1367 std::string result_string
;
1369 // Set up one on-record item and one off-record item.
1370 // Set up the off-record item first because otherwise there are mysteriously 3
1371 // items total instead of 2.
1372 // TODO(benjhayden): Figure out where the third item comes from.
1374 DownloadItem
* off_item
= CreateSlowTestDownload();
1375 ASSERT_TRUE(off_item
);
1376 off_item_arg
= DownloadItemIdAsArgList(off_item
);
1379 DownloadItem
* on_item
= CreateSlowTestDownload();
1380 ASSERT_TRUE(on_item
);
1381 on_item_arg
= DownloadItemIdAsArgList(on_item
);
1382 ASSERT_TRUE(on_item
->GetTargetFilePath() != off_item
->GetTargetFilePath());
1384 // Extensions running in the incognito window should have access to both
1385 // items because the Test extension is in spanning mode.
1387 result_value
.reset(RunFunctionAndReturnResult(
1388 new DownloadsSearchFunction(), "[{}]"));
1389 ASSERT_TRUE(result_value
.get());
1390 ASSERT_TRUE(result_value
->GetAsList(&result_list
));
1391 ASSERT_EQ(2UL, result_list
->GetSize());
1392 ASSERT_TRUE(result_list
->GetDictionary(0, &result_dict
));
1393 ASSERT_TRUE(result_dict
->GetString("filename", &filename
));
1394 ASSERT_TRUE(result_dict
->GetBoolean("incognito", &is_incognito
));
1395 EXPECT_TRUE(on_item
->GetTargetFilePath() == base::FilePath(filename
));
1396 EXPECT_FALSE(is_incognito
);
1397 ASSERT_TRUE(result_list
->GetDictionary(1, &result_dict
));
1398 ASSERT_TRUE(result_dict
->GetString("filename", &filename
));
1399 ASSERT_TRUE(result_dict
->GetBoolean("incognito", &is_incognito
));
1400 EXPECT_TRUE(off_item
->GetTargetFilePath() == base::FilePath(filename
));
1401 EXPECT_TRUE(is_incognito
);
1403 // Extensions running in the on-record window should have access only to the
1406 result_value
.reset(RunFunctionAndReturnResult(
1407 new DownloadsSearchFunction(), "[{}]"));
1408 ASSERT_TRUE(result_value
.get());
1409 ASSERT_TRUE(result_value
->GetAsList(&result_list
));
1410 ASSERT_EQ(1UL, result_list
->GetSize());
1411 ASSERT_TRUE(result_list
->GetDictionary(0, &result_dict
));
1412 ASSERT_TRUE(result_dict
->GetString("filename", &filename
));
1413 EXPECT_TRUE(on_item
->GetTargetFilePath() == base::FilePath(filename
));
1414 ASSERT_TRUE(result_dict
->GetBoolean("incognito", &is_incognito
));
1415 EXPECT_FALSE(is_incognito
);
1417 // Pausing/Resuming the off-record item while on the record should return an
1418 // error. Cancelling "non-existent" downloads is not an error.
1419 error
= RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg
);
1420 EXPECT_STREQ(errors::kInvalidId
,
1422 error
= RunFunctionAndReturnError(new DownloadsResumeFunction(),
1424 EXPECT_STREQ(errors::kInvalidId
,
1426 error
= RunFunctionAndReturnError(
1427 new DownloadsGetFileIconFunction(),
1428 base::StringPrintf("[%d, {}]", off_item
->GetId()));
1429 EXPECT_STREQ(errors::kInvalidId
,
1434 // Do the FileIcon test for both the on- and off-items while off the record.
1435 // NOTE(benjhayden): This does not include the FileIcon test from history,
1436 // just active downloads. This shouldn't be a problem.
1437 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1438 on_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
1439 base::StringPrintf("[%d, {}]", on_item
->GetId()), &result_string
));
1440 EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
1441 off_item
->GetTargetFilePath(), IconLoader::NORMAL
, "foo"),
1442 base::StringPrintf("[%d, {}]", off_item
->GetId()), &result_string
));
1444 // Do the pause/resume/cancel test for both the on- and off-items while off
1446 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg
));
1447 EXPECT_TRUE(on_item
->IsPaused());
1448 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg
));
1449 EXPECT_TRUE(on_item
->IsPaused());
1450 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg
));
1451 EXPECT_FALSE(on_item
->IsPaused());
1452 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg
));
1453 EXPECT_FALSE(on_item
->IsPaused());
1454 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg
));
1455 EXPECT_TRUE(on_item
->IsPaused());
1456 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg
));
1457 EXPECT_EQ(DownloadItem::CANCELLED
, on_item
->GetState());
1458 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg
));
1459 EXPECT_EQ(DownloadItem::CANCELLED
, on_item
->GetState());
1460 error
= RunFunctionAndReturnError(new DownloadsPauseFunction(), on_item_arg
);
1461 EXPECT_STREQ(errors::kNotInProgress
, error
.c_str());
1462 error
= RunFunctionAndReturnError(new DownloadsResumeFunction(), on_item_arg
);
1463 EXPECT_STREQ(errors::kNotResumable
, error
.c_str());
1464 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg
));
1465 EXPECT_TRUE(off_item
->IsPaused());
1466 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg
));
1467 EXPECT_TRUE(off_item
->IsPaused());
1468 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg
));
1469 EXPECT_FALSE(off_item
->IsPaused());
1470 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg
));
1471 EXPECT_FALSE(off_item
->IsPaused());
1472 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg
));
1473 EXPECT_TRUE(off_item
->IsPaused());
1474 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg
));
1475 EXPECT_EQ(DownloadItem::CANCELLED
, off_item
->GetState());
1476 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg
));
1477 EXPECT_EQ(DownloadItem::CANCELLED
, off_item
->GetState());
1478 error
= RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg
);
1479 EXPECT_STREQ(errors::kNotInProgress
, error
.c_str());
1480 error
= RunFunctionAndReturnError(new DownloadsResumeFunction(),
1482 EXPECT_STREQ(errors::kNotResumable
, error
.c_str());
1485 // Test that we can start a download and that the correct sequence of events is
1487 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1488 DownloadExtensionTest_Download_Basic
) {
1489 LoadExtension("downloads_split");
1490 ASSERT_TRUE(StartEmbeddedTestServer());
1491 ASSERT_TRUE(test_server()->Start());
1492 std::string download_url
= test_server()->GetURL("slow?0").spec();
1495 // Start downloading a file.
1496 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1497 new DownloadsDownloadFunction(), base::StringPrintf(
1498 "[{\"url\": \"%s\"}]", download_url
.c_str())));
1499 ASSERT_TRUE(result
.get());
1501 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1502 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1504 ScopedCancellingItem
canceller(item
);
1505 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1507 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1509 "[{\"danger\": \"safe\","
1510 " \"incognito\": false,"
1511 " \"mime\": \"text/plain\","
1512 " \"paused\": false,"
1513 " \"url\": \"%s\"}]",
1514 download_url
.c_str())));
1515 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1519 " \"previous\": \"\","
1520 " \"current\": \"%s\"}}]",
1522 GetFilename("slow.txt").c_str())));
1523 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1527 " \"previous\": \"in_progress\","
1528 " \"current\": \"complete\"}}]",
1532 // Test that we can start a download from an incognito context, and that the
1533 // download knows that it's incognito.
1534 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1535 DownloadExtensionTest_Download_Incognito
) {
1536 LoadExtension("downloads_split");
1537 ASSERT_TRUE(StartEmbeddedTestServer());
1538 ASSERT_TRUE(test_server()->Start());
1540 std::string download_url
= test_server()->GetURL("slow?0").spec();
1542 // Start downloading a file.
1543 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1544 new DownloadsDownloadFunction(), base::StringPrintf(
1545 "[{\"url\": \"%s\"}]", download_url
.c_str())));
1546 ASSERT_TRUE(result
.get());
1548 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1549 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1551 ScopedCancellingItem
canceller(item
);
1552 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1554 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1556 "[{\"danger\": \"safe\","
1557 " \"incognito\": true,"
1558 " \"mime\": \"text/plain\","
1559 " \"paused\": false,"
1560 " \"url\": \"%s\"}]",
1561 download_url
.c_str())));
1562 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1566 " \"previous\": \"\","
1567 " \"current\": \"%s\"}}]",
1569 GetFilename("slow.txt").c_str())));
1570 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1574 " \"current\": \"complete\","
1575 " \"previous\": \"in_progress\"}}]",
1580 // This test is very flaky on Win. http://crbug.com/248438
1581 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1582 DISABLED_DownloadExtensionTest_Download_UnsafeHeaders
1584 #define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
1585 DownloadExtensionTest_Download_UnsafeHeaders
1588 // Test that we disallow certain headers case-insensitively.
1589 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1590 MAYBE_DownloadExtensionTest_Download_UnsafeHeaders
) {
1591 LoadExtension("downloads_split");
1592 ASSERT_TRUE(StartEmbeddedTestServer());
1593 ASSERT_TRUE(test_server()->Start());
1596 static const char* const kUnsafeHeaders
[] = {
1603 "coNteNt-traNsfer-eNcodiNg",
1611 "trANsfer-eNcodiNg",
1617 "pRoxY-probably-not-evil",
1618 "sEc-probably-not-evil",
1620 "Access-Control-Request-Headers",
1621 "Access-Control-Request-Method",
1624 for (size_t index
= 0; index
< arraysize(kUnsafeHeaders
); ++index
) {
1625 std::string download_url
= test_server()->GetURL("slow?0").spec();
1626 EXPECT_STREQ(errors::kInvalidHeaderUnsafe
,
1627 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1629 "[{\"url\": \"%s\","
1630 " \"filename\": \"unsafe-header-%d.txt\","
1632 " \"name\": \"%s\","
1633 " \"value\": \"unsafe\"}]}]",
1634 download_url
.c_str(),
1635 static_cast<int>(index
),
1636 kUnsafeHeaders
[index
])).c_str());
1640 // Tests that invalid header names and values are rejected.
1641 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1642 DownloadExtensionTest_Download_InvalidHeaders
) {
1643 LoadExtension("downloads_split");
1644 ASSERT_TRUE(StartEmbeddedTestServer());
1645 ASSERT_TRUE(test_server()->Start());
1647 std::string download_url
= test_server()->GetURL("slow?0").spec();
1648 EXPECT_STREQ(errors::kInvalidHeaderName
,
1649 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1651 "[{\"url\": \"%s\","
1652 " \"filename\": \"unsafe-header-crlf.txt\","
1654 " \"name\": \"Header\\r\\nSec-Spoof: Hey\\r\\nX-Split:X\","
1655 " \"value\": \"unsafe\"}]}]",
1656 download_url
.c_str())).c_str());
1658 EXPECT_STREQ(errors::kInvalidHeaderValue
,
1659 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1661 "[{\"url\": \"%s\","
1662 " \"filename\": \"unsafe-header-crlf.txt\","
1664 " \"name\": \"Invalid-value\","
1665 " \"value\": \"hey\\r\\nSec-Spoof: Hey\"}]}]",
1666 download_url
.c_str())).c_str());
1670 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1671 DISABLED_DownloadExtensionTest_Download_Subdirectory
1673 #define MAYBE_DownloadExtensionTest_Download_Subdirectory\
1674 DownloadExtensionTest_Download_Subdirectory
1676 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1677 MAYBE_DownloadExtensionTest_Download_Subdirectory
) {
1678 LoadExtension("downloads_split");
1679 ASSERT_TRUE(StartEmbeddedTestServer());
1680 ASSERT_TRUE(test_server()->Start());
1681 std::string download_url
= test_server()->GetURL("slow?0").spec();
1684 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1685 new DownloadsDownloadFunction(), base::StringPrintf(
1686 "[{\"url\": \"%s\","
1687 " \"filename\": \"sub/dir/ect/ory.txt\"}]",
1688 download_url
.c_str())));
1689 ASSERT_TRUE(result
.get());
1691 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1692 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1694 ScopedCancellingItem
canceller(item
);
1695 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1697 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1699 "[{\"danger\": \"safe\","
1700 " \"incognito\": false,"
1701 " \"mime\": \"text/plain\","
1702 " \"paused\": false,"
1703 " \"url\": \"%s\"}]",
1704 download_url
.c_str())));
1705 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1709 " \"previous\": \"\","
1710 " \"current\": \"%s\"}}]",
1712 GetFilename("sub/dir/ect/ory.txt").c_str())));
1713 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1717 " \"previous\": \"in_progress\","
1718 " \"current\": \"complete\"}}]",
1722 // Test that invalid filenames are disallowed.
1723 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1724 DownloadExtensionTest_Download_InvalidFilename
) {
1725 LoadExtension("downloads_split");
1726 ASSERT_TRUE(StartEmbeddedTestServer());
1727 ASSERT_TRUE(test_server()->Start());
1728 std::string download_url
= test_server()->GetURL("slow?0").spec();
1731 EXPECT_STREQ(errors::kInvalidFilename
,
1732 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1734 "[{\"url\": \"%s\","
1735 " \"filename\": \"../../../../../etc/passwd\"}]",
1736 download_url
.c_str())).c_str());
1739 // flaky on mac: crbug.com/392288
1740 #if defined(OS_MACOSX)
1741 #define MAYBE_DownloadExtensionTest_Download_InvalidURLs \
1742 DISABLED_DownloadExtensionTest_Download_InvalidURLs
1744 #define MAYBE_DownloadExtensionTest_Download_InvalidURLs \
1745 DownloadExtensionTest_Download_InvalidURLs
1748 // Test that downloading invalid URLs immediately returns kInvalidURLError.
1749 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1750 MAYBE_DownloadExtensionTest_Download_InvalidURLs
) {
1751 LoadExtension("downloads_split");
1754 static const char* const kInvalidURLs
[] = {
1760 "foo/bar.html#frag",
1764 for (size_t index
= 0; index
< arraysize(kInvalidURLs
); ++index
) {
1765 EXPECT_STREQ(errors::kInvalidURL
,
1766 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1768 "[{\"url\": \"%s\"}]", kInvalidURLs
[index
])).c_str())
1769 << kInvalidURLs
[index
];
1772 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1773 new DownloadsDownloadFunction(),
1774 "[{\"url\": \"javascript:document.write(\\\"hello\\\");\"}]").c_str());
1775 EXPECT_STREQ("NETWORK_INVALID_REQUEST", RunFunctionAndReturnError(
1776 new DownloadsDownloadFunction(),
1777 "[{\"url\": \"javascript:return false;\"}]").c_str());
1778 EXPECT_STREQ("NETWORK_FAILED", RunFunctionAndReturnError(
1779 new DownloadsDownloadFunction(),
1780 "[{\"url\": \"ftp://example.com/example.txt\"}]").c_str());
1783 // TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to
1784 // permissions, test downloading from ftp.
1786 // Valid URLs plus fragments are still valid URLs.
1787 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1788 DownloadExtensionTest_Download_URLFragment
) {
1789 LoadExtension("downloads_split");
1790 ASSERT_TRUE(StartEmbeddedTestServer());
1791 ASSERT_TRUE(test_server()->Start());
1792 std::string download_url
= test_server()->GetURL("slow?0#fragment").spec();
1795 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1796 new DownloadsDownloadFunction(), base::StringPrintf(
1797 "[{\"url\": \"%s\"}]", download_url
.c_str())));
1798 ASSERT_TRUE(result
.get());
1800 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1801 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1803 ScopedCancellingItem
canceller(item
);
1804 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1806 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1808 "[{\"danger\": \"safe\","
1809 " \"incognito\": false,"
1810 " \"mime\": \"text/plain\","
1811 " \"paused\": false,"
1812 " \"url\": \"%s\"}]",
1813 download_url
.c_str())));
1814 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1818 " \"previous\": \"\","
1819 " \"current\": \"%s\"}}]",
1821 GetFilename("slow.txt").c_str())));
1822 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1826 " \"previous\": \"in_progress\","
1827 " \"current\": \"complete\"}}]",
1831 // conflictAction may be specified without filename.
1832 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1833 DownloadExtensionTest_Download_ConflictAction
) {
1834 static char kFilename
[] = "download.txt";
1835 LoadExtension("downloads_split");
1836 std::string download_url
= "data:text/plain,hello";
1839 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1840 new DownloadsDownloadFunction(), base::StringPrintf(
1841 "[{\"url\": \"%s\"}]", download_url
.c_str())));
1842 ASSERT_TRUE(result
.get());
1844 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1845 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1847 ScopedCancellingItem
canceller(item
);
1848 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1850 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1852 "[{\"danger\": \"safe\","
1853 " \"incognito\": false,"
1854 " \"mime\": \"text/plain\","
1855 " \"paused\": false,"
1856 " \"url\": \"%s\"}]",
1857 download_url
.c_str())));
1858 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1862 " \"previous\": \"\","
1863 " \"current\": \"%s\"}}]",
1865 GetFilename(kFilename
).c_str())));
1866 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1870 " \"previous\": \"in_progress\","
1871 " \"current\": \"complete\"}}]",
1874 result
.reset(RunFunctionAndReturnResult(
1875 new DownloadsDownloadFunction(), base::StringPrintf(
1876 "[{\"url\": \"%s\", \"conflictAction\": \"overwrite\"}]",
1877 download_url
.c_str())));
1878 ASSERT_TRUE(result
.get());
1880 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1881 item
= GetCurrentManager()->GetDownload(result_id
);
1883 ScopedCancellingItem
canceller2(item
);
1884 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1886 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1888 "[{\"danger\": \"safe\","
1889 " \"incognito\": false,"
1890 " \"mime\": \"text/plain\","
1891 " \"paused\": false,"
1892 " \"url\": \"%s\"}]",
1893 download_url
.c_str())));
1894 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1898 " \"previous\": \"\","
1899 " \"current\": \"%s\"}}]",
1901 GetFilename(kFilename
).c_str())));
1902 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1906 " \"previous\": \"in_progress\","
1907 " \"current\": \"complete\"}}]",
1911 // Valid data URLs are valid URLs.
1912 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1913 DownloadExtensionTest_Download_DataURL
) {
1914 LoadExtension("downloads_split");
1915 std::string download_url
= "data:text/plain,hello";
1918 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1919 new DownloadsDownloadFunction(), base::StringPrintf(
1920 "[{\"url\": \"%s\","
1921 " \"filename\": \"data.txt\"}]", download_url
.c_str())));
1922 ASSERT_TRUE(result
.get());
1924 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1925 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1927 ScopedCancellingItem
canceller(item
);
1928 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1930 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1932 "[{\"danger\": \"safe\","
1933 " \"incognito\": false,"
1934 " \"mime\": \"text/plain\","
1935 " \"paused\": false,"
1936 " \"url\": \"%s\"}]",
1937 download_url
.c_str())));
1938 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1942 " \"previous\": \"\","
1943 " \"current\": \"%s\"}}]",
1945 GetFilename("data.txt").c_str())));
1946 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1950 " \"previous\": \"in_progress\","
1951 " \"current\": \"complete\"}}]",
1955 // Valid file URLs are valid URLs.
1957 // Disabled due to crbug.com/175711
1958 #define MAYBE_DownloadExtensionTest_Download_File \
1959 DISABLED_DownloadExtensionTest_Download_File
1961 #define MAYBE_DownloadExtensionTest_Download_File \
1962 DownloadExtensionTest_Download_File
1964 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
1965 MAYBE_DownloadExtensionTest_Download_File
) {
1967 LoadExtension("downloads_split");
1968 std::string download_url
= "file:///";
1970 download_url
+= "C:/";
1973 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
1974 new DownloadsDownloadFunction(), base::StringPrintf(
1975 "[{\"url\": \"%s\","
1976 " \"filename\": \"file.txt\"}]", download_url
.c_str())));
1977 ASSERT_TRUE(result
.get());
1979 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
1980 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
1982 ScopedCancellingItem
canceller(item
);
1983 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
1985 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
1987 "[{\"danger\": \"safe\","
1988 " \"incognito\": false,"
1989 " \"mime\": \"text/html\","
1990 " \"paused\": false,"
1991 " \"url\": \"%s\"}]",
1992 download_url
.c_str())));
1993 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
1997 " \"previous\": \"\","
1998 " \"current\": \"%s\"}}]",
2000 GetFilename("file.txt").c_str())));
2001 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2005 " \"previous\": \"in_progress\","
2006 " \"current\": \"complete\"}}]",
2010 // Test that auth-basic-succeed would fail if the resource requires the
2011 // Authorization header and chrome fails to propagate it back to the server.
2012 // This tests both that testserver.py does not succeed when it should fail as
2013 // well as how the downloads extension API exposes the failure to extensions.
2014 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2015 DownloadExtensionTest_Download_AuthBasic_Fail
) {
2016 LoadExtension("downloads_split");
2017 ASSERT_TRUE(StartEmbeddedTestServer());
2018 ASSERT_TRUE(test_server()->Start());
2019 std::string download_url
= test_server()->GetURL("auth-basic").spec();
2022 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2023 new DownloadsDownloadFunction(), base::StringPrintf(
2024 "[{\"url\": \"%s\","
2025 " \"filename\": \"auth-basic-fail.txt\"}]",
2026 download_url
.c_str())));
2027 ASSERT_TRUE(result
.get());
2029 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2030 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2032 ScopedCancellingItem
canceller(item
);
2033 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2035 ASSERT_TRUE(WaitForInterruption(
2037 content::DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED
,
2038 base::StringPrintf("[{\"danger\": \"safe\","
2039 " \"incognito\": false,"
2040 " \"mime\": \"text/html\","
2041 " \"paused\": false,"
2042 " \"url\": \"%s\"}]",
2043 download_url
.c_str())));
2046 // Test that DownloadsDownloadFunction propagates |headers| to the URLRequest.
2047 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2048 DownloadExtensionTest_Download_Headers
) {
2049 LoadExtension("downloads_split");
2050 ASSERT_TRUE(StartEmbeddedTestServer());
2051 ASSERT_TRUE(test_server()->Start());
2052 std::string download_url
= test_server()->GetURL("files/downloads/"
2053 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
2056 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2057 new DownloadsDownloadFunction(), base::StringPrintf(
2058 "[{\"url\": \"%s\","
2059 " \"filename\": \"headers-succeed.txt\","
2061 " {\"name\": \"Foo\", \"value\": \"bar\"},"
2062 " {\"name\": \"Qx\", \"value\":\"yo\"}]}]",
2063 download_url
.c_str())));
2064 ASSERT_TRUE(result
.get());
2066 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2067 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2069 ScopedCancellingItem
canceller(item
);
2070 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2072 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2074 "[{\"danger\": \"safe\","
2075 " \"incognito\": false,"
2076 " \"mime\": \"application/octet-stream\","
2077 " \"paused\": false,"
2078 " \"url\": \"%s\"}]",
2079 download_url
.c_str())));
2080 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2084 " \"previous\": \"\","
2085 " \"current\": \"%s\"}}]",
2087 GetFilename("headers-succeed.txt").c_str())));
2088 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2092 " \"previous\": \"in_progress\","
2093 " \"current\": \"complete\"}}]",
2097 // Test that headers-succeed would fail if the resource requires the headers and
2098 // chrome fails to propagate them back to the server. This tests both that
2099 // testserver.py does not succeed when it should fail as well as how the
2100 // downloads extension api exposes the failure to extensions.
2101 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2102 DownloadExtensionTest_Download_Headers_Fail
) {
2103 LoadExtension("downloads_split");
2104 ASSERT_TRUE(StartEmbeddedTestServer());
2105 ASSERT_TRUE(test_server()->Start());
2106 std::string download_url
= test_server()->GetURL("files/downloads/"
2107 "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
2110 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2111 new DownloadsDownloadFunction(), base::StringPrintf(
2112 "[{\"url\": \"%s\","
2113 " \"filename\": \"headers-fail.txt\"}]",
2114 download_url
.c_str())));
2115 ASSERT_TRUE(result
.get());
2117 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2118 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2120 ScopedCancellingItem
canceller(item
);
2121 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2123 ASSERT_TRUE(WaitForInterruption(
2125 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT
,
2126 base::StringPrintf("[{\"danger\": \"safe\","
2127 " \"incognito\": false,"
2128 " \"bytesReceived\": 0.0,"
2129 " \"fileSize\": 0.0,"
2131 " \"paused\": false,"
2132 " \"url\": \"%s\"}]",
2133 download_url
.c_str())));
2136 // Test that DownloadsDownloadFunction propagates the Authorization header
2138 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2139 DownloadExtensionTest_Download_AuthBasic
) {
2140 LoadExtension("downloads_split");
2141 ASSERT_TRUE(StartEmbeddedTestServer());
2142 ASSERT_TRUE(test_server()->Start());
2143 std::string download_url
= test_server()->GetURL("auth-basic").spec();
2144 // This is just base64 of 'username:secret'.
2145 static const char kAuthorization
[] = "dXNlcm5hbWU6c2VjcmV0";
2148 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2149 new DownloadsDownloadFunction(), base::StringPrintf(
2150 "[{\"url\": \"%s\","
2151 " \"filename\": \"auth-basic-succeed.txt\","
2153 " \"name\": \"Authorization\","
2154 " \"value\": \"Basic %s\"}]}]",
2155 download_url
.c_str(), kAuthorization
)));
2156 ASSERT_TRUE(result
.get());
2158 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2159 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2161 ScopedCancellingItem
canceller(item
);
2162 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2164 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2166 "[{\"danger\": \"safe\","
2167 " \"incognito\": false,"
2168 " \"bytesReceived\": 0.0,"
2169 " \"fileSize\": 0.0,"
2170 " \"mime\": \"text/html\","
2171 " \"paused\": false,"
2172 " \"url\": \"%s\"}]",
2173 download_url
.c_str())));
2174 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2178 " \"previous\": \"in_progress\","
2179 " \"current\": \"complete\"}}]",
2183 // Test that DownloadsDownloadFunction propagates the |method| and |body|
2184 // parameters to the URLRequest.
2185 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2186 DownloadExtensionTest_Download_Post
) {
2187 LoadExtension("downloads_split");
2188 ASSERT_TRUE(StartEmbeddedTestServer());
2189 ASSERT_TRUE(test_server()->Start());
2190 std::string download_url
= test_server()->GetURL("files/post/downloads/"
2191 "a_zip_file.zip?expected_body=BODY").spec();
2194 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2195 new DownloadsDownloadFunction(), base::StringPrintf(
2196 "[{\"url\": \"%s\","
2197 " \"filename\": \"post-succeed.txt\","
2198 " \"method\": \"POST\","
2199 " \"body\": \"BODY\"}]",
2200 download_url
.c_str())));
2201 ASSERT_TRUE(result
.get());
2203 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2204 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2206 ScopedCancellingItem
canceller(item
);
2207 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2209 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2211 "[{\"danger\": \"safe\","
2212 " \"incognito\": false,"
2213 " \"mime\": \"application/octet-stream\","
2214 " \"paused\": false,"
2215 " \"url\": \"%s\"}]",
2216 download_url
.c_str())));
2217 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2221 " \"previous\": \"\","
2222 " \"current\": \"%s\"}}]",
2224 GetFilename("post-succeed.txt").c_str())));
2225 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2229 " \"previous\": \"in_progress\","
2230 " \"current\": \"complete\"}}]",
2234 // Test that downloadPostSuccess would fail if the resource requires the POST
2235 // method, and chrome fails to propagate the |method| parameter back to the
2236 // server. This tests both that testserver.py does not succeed when it should
2237 // fail, and this tests how the downloads extension api exposes the failure to
2239 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2240 DownloadExtensionTest_Download_Post_Get
) {
2241 LoadExtension("downloads_split");
2242 ASSERT_TRUE(StartEmbeddedTestServer());
2243 ASSERT_TRUE(test_server()->Start());
2244 std::string download_url
= test_server()->GetURL("files/post/downloads/"
2245 "a_zip_file.zip?expected_body=BODY").spec();
2248 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2249 new DownloadsDownloadFunction(), base::StringPrintf(
2250 "[{\"url\": \"%s\","
2251 " \"body\": \"BODY\","
2252 " \"filename\": \"post-get.txt\"}]",
2253 download_url
.c_str())));
2254 ASSERT_TRUE(result
.get());
2256 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2257 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2259 ScopedCancellingItem
canceller(item
);
2260 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2262 ASSERT_TRUE(WaitForInterruption(
2264 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT
,
2265 base::StringPrintf("[{\"danger\": \"safe\","
2266 " \"incognito\": false,"
2268 " \"paused\": false,"
2270 " \"url\": \"%s\"}]",
2272 download_url
.c_str())));
2275 // Test that downloadPostSuccess would fail if the resource requires the POST
2276 // method, and chrome fails to propagate the |body| parameter back to the
2277 // server. This tests both that testserver.py does not succeed when it should
2278 // fail, and this tests how the downloads extension api exposes the failure to
2280 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2281 DownloadExtensionTest_Download_Post_NoBody
) {
2282 LoadExtension("downloads_split");
2283 ASSERT_TRUE(StartEmbeddedTestServer());
2284 ASSERT_TRUE(test_server()->Start());
2285 std::string download_url
= test_server()->GetURL("files/post/downloads/"
2286 "a_zip_file.zip?expected_body=BODY").spec();
2289 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2290 new DownloadsDownloadFunction(), base::StringPrintf(
2291 "[{\"url\": \"%s\","
2292 " \"method\": \"POST\","
2293 " \"filename\": \"post-nobody.txt\"}]",
2294 download_url
.c_str())));
2295 ASSERT_TRUE(result
.get());
2297 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2298 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2300 ScopedCancellingItem
canceller(item
);
2301 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2303 ASSERT_TRUE(WaitForInterruption(
2305 content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT
,
2306 base::StringPrintf("[{\"danger\": \"safe\","
2307 " \"incognito\": false,"
2309 " \"paused\": false,"
2311 " \"url\": \"%s\"}]",
2313 download_url
.c_str())));
2316 // Test that cancel()ing an in-progress download causes its state to transition
2317 // to interrupted, and test that that state transition is detectable by an
2318 // onChanged event listener. TODO(benjhayden): Test other sources of
2319 // interruptions such as server death.
2320 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2321 DownloadExtensionTest_Download_Cancel
) {
2322 LoadExtension("downloads_split");
2323 ASSERT_TRUE(StartEmbeddedTestServer());
2324 ASSERT_TRUE(test_server()->Start());
2325 std::string download_url
= test_server()->GetURL(
2326 "download-known-size").spec();
2329 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2330 new DownloadsDownloadFunction(), base::StringPrintf(
2331 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2332 ASSERT_TRUE(result
.get());
2334 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2335 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2337 ScopedCancellingItem
canceller(item
);
2338 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2340 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2342 "[{\"danger\": \"safe\","
2343 " \"incognito\": false,"
2344 " \"mime\": \"application/octet-stream\","
2345 " \"paused\": false,"
2347 " \"url\": \"%s\"}]",
2349 download_url
.c_str())));
2351 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2354 " \"error\": {\"current\":\"USER_CANCELED\"},"
2356 " \"previous\": \"in_progress\","
2357 " \"current\": \"interrupted\"}}]",
2361 // flaky on mac: crbug.com/392288
2362 #if defined(OS_MACOSX)
2363 #define MAYBE_DownloadExtensionTest_Download_FileSystemURL \
2364 DISABLED_DownloadExtensionTest_Download_FileSystemURL
2366 #define MAYBE_DownloadExtensionTest_Download_FileSystemURL \
2367 DownloadExtensionTest_Download_FileSystemURL
2370 // Test downloading filesystem: URLs.
2371 // NOTE: chrome disallows creating HTML5 FileSystem Files in incognito.
2372 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2373 MAYBE_DownloadExtensionTest_Download_FileSystemURL
) {
2374 static const char kPayloadData
[] = "on the record\ndata";
2376 LoadExtension("downloads_split");
2378 const std::string download_url
= "filesystem:" + GetExtensionURL() +
2379 "temporary/on_record.txt";
2381 // Setup a file in the filesystem which we can download.
2382 ASSERT_TRUE(HTML5FileWriter::CreateFileForTesting(
2383 BrowserContext::GetDefaultStoragePartition(browser()->profile())
2384 ->GetFileSystemContext(),
2385 storage::FileSystemURL::CreateForTest(GURL(download_url
)),
2387 strlen(kPayloadData
)));
2390 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2391 new DownloadsDownloadFunction(), base::StringPrintf(
2392 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2393 ASSERT_TRUE(result
.get());
2395 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2397 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2399 ScopedCancellingItem
canceller(item
);
2400 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2402 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2404 "[{\"danger\": \"safe\","
2405 " \"incognito\": false,"
2406 " \"mime\": \"text/plain\","
2407 " \"paused\": false,"
2408 " \"url\": \"%s\"}]",
2409 download_url
.c_str())));
2410 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2414 " \"previous\": \"\","
2415 " \"current\": \"%s\"}}]",
2417 GetFilename("on_record.txt").c_str())));
2418 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2422 " \"previous\": \"in_progress\","
2423 " \"current\": \"complete\"}}]",
2425 std::string disk_data
;
2426 EXPECT_TRUE(base::ReadFileToString(item
->GetTargetFilePath(), &disk_data
));
2427 EXPECT_STREQ(kPayloadData
, disk_data
.c_str());
2430 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2431 DownloadExtensionTest_OnDeterminingFilename_NoChange
) {
2433 LoadExtension("downloads_split");
2434 AddFilenameDeterminer();
2435 ASSERT_TRUE(StartEmbeddedTestServer());
2436 ASSERT_TRUE(test_server()->Start());
2437 std::string download_url
= test_server()->GetURL("slow?0").spec();
2439 // Start downloading a file.
2440 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2441 new DownloadsDownloadFunction(), base::StringPrintf(
2442 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2443 ASSERT_TRUE(result
.get());
2445 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2446 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2448 ScopedCancellingItem
canceller(item
);
2449 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2451 // Wait for the onCreated and onDeterminingFilename events.
2452 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2454 "[{\"danger\": \"safe\","
2455 " \"incognito\": false,"
2457 " \"mime\": \"text/plain\","
2458 " \"paused\": false,"
2459 " \"url\": \"%s\"}]",
2461 download_url
.c_str())));
2462 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2465 " \"filename\":\"slow.txt\"}]",
2467 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2468 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2470 // Respond to the onDeterminingFilename.
2472 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2473 browser()->profile(),
2478 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2480 EXPECT_EQ("", error
);
2482 // The download should complete successfully.
2483 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2487 " \"previous\": \"\","
2488 " \"current\": \"%s\"}}]",
2490 GetFilename("slow.txt").c_str())));
2491 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2495 " \"previous\": \"in_progress\","
2496 " \"current\": \"complete\"}}]",
2500 // Disabled due to cross-platform flakes; http://crbug.com/370531.
2501 IN_PROC_BROWSER_TEST_F(
2502 DownloadExtensionTest
,
2503 DISABLED_DownloadExtensionTest_OnDeterminingFilename_Timeout
) {
2505 LoadExtension("downloads_split");
2506 AddFilenameDeterminer();
2507 ASSERT_TRUE(StartEmbeddedTestServer());
2508 ASSERT_TRUE(test_server()->Start());
2509 std::string download_url
= test_server()->GetURL("slow?0").spec();
2511 ExtensionDownloadsEventRouter::SetDetermineFilenameTimeoutSecondsForTesting(
2514 // Start downloading a file.
2515 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2516 new DownloadsDownloadFunction(), base::StringPrintf(
2517 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2518 ASSERT_TRUE(result
.get());
2520 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2521 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2523 ScopedCancellingItem
canceller(item
);
2524 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2526 // Wait for the onCreated and onDeterminingFilename events.
2527 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2528 base::StringPrintf("[{\"danger\": \"safe\","
2529 " \"incognito\": false,"
2531 " \"mime\": \"text/plain\","
2532 " \"paused\": false,"
2533 " \"url\": \"%s\"}]",
2535 download_url
.c_str())));
2536 ASSERT_TRUE(WaitFor(
2537 downloads::OnDeterminingFilename::kEventName
,
2538 base::StringPrintf("[{\"id\": %d,"
2539 " \"filename\":\"slow.txt\"}]",
2541 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2542 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2544 // Do not respond to the onDeterminingFilename.
2546 // The download should complete successfully.
2547 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2548 base::StringPrintf("[{\"id\": %d,"
2550 " \"previous\": \"\","
2551 " \"current\": \"%s\"}}]",
2553 GetFilename("slow.txt").c_str())));
2554 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2555 base::StringPrintf("[{\"id\": %d,"
2557 " \"previous\": \"in_progress\","
2558 " \"current\": \"complete\"}}]",
2562 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
2563 DownloadExtensionTest_OnDeterminingFilename_Twice
) {
2565 LoadExtension("downloads_split");
2566 AddFilenameDeterminer();
2567 ASSERT_TRUE(StartEmbeddedTestServer());
2568 ASSERT_TRUE(test_server()->Start());
2569 std::string download_url
= test_server()->GetURL("slow?0").spec();
2571 // Start downloading a file.
2572 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2573 new DownloadsDownloadFunction(), base::StringPrintf(
2574 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2575 ASSERT_TRUE(result
.get());
2577 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2578 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2580 ScopedCancellingItem
canceller(item
);
2581 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2583 // Wait for the onCreated and onDeterminingFilename events.
2584 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2585 base::StringPrintf("[{\"danger\": \"safe\","
2586 " \"incognito\": false,"
2588 " \"mime\": \"text/plain\","
2589 " \"paused\": false,"
2590 " \"url\": \"%s\"}]",
2592 download_url
.c_str())));
2593 ASSERT_TRUE(WaitFor(
2594 downloads::OnDeterminingFilename::kEventName
,
2595 base::StringPrintf("[{\"id\": %d,"
2596 " \"filename\":\"slow.txt\"}]",
2598 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2599 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2601 // Respond to the onDeterminingFilename.
2603 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2604 browser()->profile(),
2609 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2611 EXPECT_EQ("", error
);
2613 // Calling DetermineFilename again should return an error instead of calling
2614 // DownloadTargetDeterminer.
2615 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2616 browser()->profile(),
2620 base::FilePath(FILE_PATH_LITERAL("different")),
2621 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
,
2623 EXPECT_EQ(errors::kTooManyListeners
, error
);
2625 // The download should complete successfully.
2626 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2627 base::StringPrintf("[{\"id\": %d,"
2629 " \"previous\": \"\","
2630 " \"current\": \"%s\"}}]",
2632 GetFilename("slow.txt").c_str())));
2633 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2634 base::StringPrintf("[{\"id\": %d,"
2636 " \"previous\": \"in_progress\","
2637 " \"current\": \"complete\"}}]",
2641 IN_PROC_BROWSER_TEST_F(
2642 DownloadExtensionTest
,
2643 DownloadExtensionTest_OnDeterminingFilename_DangerousOverride
) {
2645 LoadExtension("downloads_split");
2646 AddFilenameDeterminer();
2647 ASSERT_TRUE(StartEmbeddedTestServer());
2648 ASSERT_TRUE(test_server()->Start());
2649 std::string download_url
= test_server()->GetURL("slow?0").spec();
2651 // Start downloading a file.
2652 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2653 new DownloadsDownloadFunction(), base::StringPrintf(
2654 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2655 ASSERT_TRUE(result
.get());
2657 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2658 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2660 ScopedCancellingItem
canceller(item
);
2661 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2663 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2665 "[{\"danger\": \"safe\","
2666 " \"incognito\": false,"
2668 " \"mime\": \"text/plain\","
2669 " \"paused\": false,"
2670 " \"url\": \"%s\"}]",
2672 download_url
.c_str())));
2673 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2676 " \"filename\":\"slow.txt\"}]",
2678 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2679 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2681 // Respond to the onDeterminingFilename.
2683 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
2684 browser()->profile(),
2688 base::FilePath(FILE_PATH_LITERAL("overridden.swf")),
2689 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2691 EXPECT_EQ("", error
);
2693 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2697 " \"previous\":\"safe\","
2698 " \"current\":\"file\"}}]",
2701 item
->ValidateDangerousDownload();
2702 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2706 " \"previous\":\"file\","
2707 " \"current\":\"accepted\"}}]",
2709 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2713 " \"previous\": \"in_progress\","
2714 " \"current\": \"complete\"}}]",
2716 EXPECT_EQ(downloads_directory().AppendASCII("overridden.swf"),
2717 item
->GetTargetFilePath());
2720 IN_PROC_BROWSER_TEST_F(
2721 DownloadExtensionTest
,
2722 DownloadExtensionTest_OnDeterminingFilename_ReferencesParentInvalid
) {
2724 LoadExtension("downloads_split");
2725 AddFilenameDeterminer();
2726 ASSERT_TRUE(StartEmbeddedTestServer());
2727 ASSERT_TRUE(test_server()->Start());
2728 std::string download_url
= test_server()->GetURL("slow?0").spec();
2730 // Start downloading a file.
2731 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2732 new DownloadsDownloadFunction(), base::StringPrintf(
2733 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2734 ASSERT_TRUE(result
.get());
2736 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2737 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2739 ScopedCancellingItem
canceller(item
);
2740 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2742 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2744 "[{\"danger\": \"safe\","
2745 " \"incognito\": false,"
2747 " \"mime\": \"text/plain\","
2748 " \"paused\": false,"
2749 " \"url\": \"%s\"}]",
2751 download_url
.c_str())));
2752 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2755 " \"filename\":\"slow.txt\"}]",
2757 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2758 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2760 // Respond to the onDeterminingFilename.
2762 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2763 browser()->profile(),
2767 base::FilePath(FILE_PATH_LITERAL("sneaky/../../sneaky.txt")),
2768 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2770 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
2771 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2775 " \"previous\": \"\","
2776 " \"current\": \"%s\"}}]",
2778 GetFilename("slow.txt").c_str())));
2779 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2783 " \"previous\": \"in_progress\","
2784 " \"current\": \"complete\"}}]",
2788 IN_PROC_BROWSER_TEST_F(
2789 DownloadExtensionTest
,
2790 DownloadExtensionTest_OnDeterminingFilename_IllegalFilename
) {
2792 LoadExtension("downloads_split");
2793 AddFilenameDeterminer();
2794 ASSERT_TRUE(StartEmbeddedTestServer());
2795 ASSERT_TRUE(test_server()->Start());
2796 std::string download_url
= test_server()->GetURL("slow?0").spec();
2798 // Start downloading a file.
2799 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2800 new DownloadsDownloadFunction(), base::StringPrintf(
2801 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2802 ASSERT_TRUE(result
.get());
2804 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2805 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2807 ScopedCancellingItem
canceller(item
);
2808 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2810 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2812 "[{\"danger\": \"safe\","
2813 " \"incognito\": false,"
2815 " \"mime\": \"text/plain\","
2816 " \"paused\": false,"
2817 " \"url\": \"%s\"}]",
2819 download_url
.c_str())));
2820 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2823 " \"filename\":\"slow.txt\"}]",
2825 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2826 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2828 // Respond to the onDeterminingFilename.
2830 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2831 browser()->profile(),
2835 base::FilePath(FILE_PATH_LITERAL("<")),
2836 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2838 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
2839 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2843 " \"previous\": \"\","
2844 " \"current\": \"%s\"}}]",
2846 GetFilename("slow.txt").c_str())));
2847 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2851 " \"previous\": \"in_progress\","
2852 " \"current\": \"complete\"}}]",
2856 IN_PROC_BROWSER_TEST_F(
2857 DownloadExtensionTest
,
2858 DownloadExtensionTest_OnDeterminingFilename_IllegalFilenameExtension
) {
2860 LoadExtension("downloads_split");
2861 AddFilenameDeterminer();
2862 ASSERT_TRUE(StartEmbeddedTestServer());
2863 ASSERT_TRUE(test_server()->Start());
2864 std::string download_url
= test_server()->GetURL("slow?0").spec();
2866 // Start downloading a file.
2867 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2868 new DownloadsDownloadFunction(), base::StringPrintf(
2869 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2870 ASSERT_TRUE(result
.get());
2872 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2873 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2875 ScopedCancellingItem
canceller(item
);
2876 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2878 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2880 "[{\"danger\": \"safe\","
2881 " \"incognito\": false,"
2883 " \"mime\": \"text/plain\","
2884 " \"paused\": false,"
2885 " \"url\": \"%s\"}]",
2887 download_url
.c_str())));
2888 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2891 " \"filename\":\"slow.txt\"}]",
2893 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2894 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2896 // Respond to the onDeterminingFilename.
2898 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2899 browser()->profile(),
2903 base::FilePath(FILE_PATH_LITERAL(
2904 "My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}/foo")),
2905 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2907 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
2908 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2912 " \"previous\": \"\","
2913 " \"current\": \"%s\"}}]",
2915 GetFilename("slow.txt").c_str())));
2916 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2920 " \"previous\": \"in_progress\","
2921 " \"current\": \"complete\"}}]",
2925 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2926 DISABLED_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2928 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename\
2929 DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
2931 IN_PROC_BROWSER_TEST_F(
2932 DownloadExtensionTest
,
2933 MAYBE_DownloadExtensionTest_OnDeterminingFilename_ReservedFilename
) {
2935 LoadExtension("downloads_split");
2936 AddFilenameDeterminer();
2937 ASSERT_TRUE(StartEmbeddedTestServer());
2938 ASSERT_TRUE(test_server()->Start());
2939 std::string download_url
= test_server()->GetURL("slow?0").spec();
2941 // Start downloading a file.
2942 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
2943 new DownloadsDownloadFunction(), base::StringPrintf(
2944 "[{\"url\": \"%s\"}]", download_url
.c_str())));
2945 ASSERT_TRUE(result
.get());
2947 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
2948 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
2950 ScopedCancellingItem
canceller(item
);
2951 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
2953 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
2955 "[{\"danger\": \"safe\","
2956 " \"incognito\": false,"
2958 " \"mime\": \"text/plain\","
2959 " \"paused\": false,"
2960 " \"url\": \"%s\"}]",
2962 download_url
.c_str())));
2963 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
2966 " \"filename\":\"slow.txt\"}]",
2968 ASSERT_TRUE(item
->GetTargetFilePath().empty());
2969 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
2971 // Respond to the onDeterminingFilename.
2973 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
2974 browser()->profile(),
2978 base::FilePath(FILE_PATH_LITERAL("con.foo")),
2979 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
2981 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
2982 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2986 " \"previous\": \"\","
2987 " \"current\": \"%s\"}}]",
2989 GetFilename("slow.txt").c_str())));
2990 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
2994 " \"previous\": \"in_progress\","
2995 " \"current\": \"complete\"}}]",
2999 IN_PROC_BROWSER_TEST_F(
3000 DownloadExtensionTest
,
3001 DownloadExtensionTest_OnDeterminingFilename_CurDirInvalid
) {
3003 LoadExtension("downloads_split");
3004 AddFilenameDeterminer();
3005 ASSERT_TRUE(StartEmbeddedTestServer());
3006 ASSERT_TRUE(test_server()->Start());
3007 std::string download_url
= test_server()->GetURL("slow?0").spec();
3009 // Start downloading a file.
3010 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3011 new DownloadsDownloadFunction(), base::StringPrintf(
3012 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3013 ASSERT_TRUE(result
.get());
3015 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3016 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3018 ScopedCancellingItem
canceller(item
);
3019 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3021 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3023 "[{\"danger\": \"safe\","
3024 " \"incognito\": false,"
3026 " \"mime\": \"text/plain\","
3027 " \"paused\": false,"
3028 " \"url\": \"%s\"}]",
3030 download_url
.c_str())));
3031 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3034 " \"filename\":\"slow.txt\"}]",
3036 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3037 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3039 // Respond to the onDeterminingFilename.
3041 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3042 browser()->profile(),
3046 base::FilePath(FILE_PATH_LITERAL(".")),
3047 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3049 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
3050 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3054 " \"previous\": \"\","
3055 " \"current\": \"%s\"}}]",
3057 GetFilename("slow.txt").c_str())));
3058 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3062 " \"previous\": \"in_progress\","
3063 " \"current\": \"complete\"}}]",
3067 IN_PROC_BROWSER_TEST_F(
3068 DownloadExtensionTest
,
3069 DownloadExtensionTest_OnDeterminingFilename_ParentDirInvalid
) {
3070 ASSERT_TRUE(StartEmbeddedTestServer());
3071 ASSERT_TRUE(test_server()->Start());
3073 LoadExtension("downloads_split");
3074 AddFilenameDeterminer();
3075 std::string download_url
= test_server()->GetURL("slow?0").spec();
3077 // Start downloading a file.
3078 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3079 new DownloadsDownloadFunction(), base::StringPrintf(
3080 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3081 ASSERT_TRUE(result
.get());
3083 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3084 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3086 ScopedCancellingItem
canceller(item
);
3087 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3089 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3091 "[{\"danger\": \"safe\","
3092 " \"incognito\": false,"
3094 " \"mime\": \"text/plain\","
3095 " \"paused\": false,"
3096 " \"url\": \"%s\"}]",
3098 download_url
.c_str())));
3099 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3102 " \"filename\":\"slow.txt\"}]",
3104 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3105 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3107 // Respond to the onDeterminingFilename.
3109 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3110 browser()->profile(),
3114 base::FilePath(FILE_PATH_LITERAL("..")),
3115 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3117 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
3118 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3122 " \"previous\": \"\","
3123 " \"current\": \"%s\"}}]",
3125 GetFilename("slow.txt").c_str())));
3126 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3130 " \"previous\": \"in_progress\","
3131 " \"current\": \"complete\"}}]",
3135 IN_PROC_BROWSER_TEST_F(
3136 DownloadExtensionTest
,
3137 DownloadExtensionTest_OnDeterminingFilename_AbsPathInvalid
) {
3139 LoadExtension("downloads_split");
3140 AddFilenameDeterminer();
3141 ASSERT_TRUE(StartEmbeddedTestServer());
3142 ASSERT_TRUE(test_server()->Start());
3143 std::string download_url
= test_server()->GetURL("slow?0").spec();
3145 // Start downloading a file.
3146 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3147 new DownloadsDownloadFunction(), base::StringPrintf(
3148 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3149 ASSERT_TRUE(result
.get());
3151 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3152 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3154 ScopedCancellingItem
canceller(item
);
3155 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3157 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3159 "[{\"danger\": \"safe\","
3160 " \"incognito\": false,"
3162 " \"mime\": \"text/plain\","
3163 " \"paused\": false,"
3164 " \"url\": \"%s\"}]",
3166 download_url
.c_str())));
3167 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3170 " \"filename\":\"slow.txt\"}]",
3172 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3173 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3175 // Respond to the onDeterminingFilename. Absolute paths should be rejected.
3177 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3178 browser()->profile(),
3182 downloads_directory().Append(FILE_PATH_LITERAL("sneaky.txt")),
3183 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3185 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
3187 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3191 " \"previous\": \"\","
3192 " \"current\": \"%s\"}}]",
3194 GetFilename("slow.txt").c_str())));
3195 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3199 " \"previous\": \"in_progress\","
3200 " \"current\": \"complete\"}}]",
3204 IN_PROC_BROWSER_TEST_F(
3205 DownloadExtensionTest
,
3206 DownloadExtensionTest_OnDeterminingFilename_EmptyBasenameInvalid
) {
3208 LoadExtension("downloads_split");
3209 AddFilenameDeterminer();
3210 ASSERT_TRUE(StartEmbeddedTestServer());
3211 ASSERT_TRUE(test_server()->Start());
3212 std::string download_url
= test_server()->GetURL("slow?0").spec();
3214 // Start downloading a file.
3215 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3216 new DownloadsDownloadFunction(), base::StringPrintf(
3217 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3218 ASSERT_TRUE(result
.get());
3220 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3221 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3223 ScopedCancellingItem
canceller(item
);
3224 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3226 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3228 "[{\"danger\": \"safe\","
3229 " \"incognito\": false,"
3231 " \"mime\": \"text/plain\","
3232 " \"paused\": false,"
3233 " \"url\": \"%s\"}]",
3235 download_url
.c_str())));
3236 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3239 " \"filename\":\"slow.txt\"}]",
3241 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3242 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3244 // Respond to the onDeterminingFilename. Empty basenames should be rejected.
3246 ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
3247 browser()->profile(),
3251 base::FilePath(FILE_PATH_LITERAL("foo/")),
3252 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3254 EXPECT_STREQ(errors::kInvalidFilename
, error
.c_str());
3256 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3260 " \"previous\": \"\","
3261 " \"current\": \"%s\"}}]",
3263 GetFilename("slow.txt").c_str())));
3264 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3268 " \"previous\": \"in_progress\","
3269 " \"current\": \"complete\"}}]",
3273 // conflictAction may be specified without filename.
3274 IN_PROC_BROWSER_TEST_F(
3275 DownloadExtensionTest
,
3276 DownloadExtensionTest_OnDeterminingFilename_Overwrite
) {
3278 LoadExtension("downloads_split");
3279 AddFilenameDeterminer();
3280 ASSERT_TRUE(StartEmbeddedTestServer());
3281 ASSERT_TRUE(test_server()->Start());
3282 std::string download_url
= test_server()->GetURL("slow?0").spec();
3284 // Start downloading a file.
3285 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3286 new DownloadsDownloadFunction(), base::StringPrintf(
3287 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3288 ASSERT_TRUE(result
.get());
3290 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3291 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3293 ScopedCancellingItem
canceller(item
);
3294 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3295 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3297 "[{\"danger\": \"safe\","
3298 " \"incognito\": false,"
3300 " \"mime\": \"text/plain\","
3301 " \"paused\": false,"
3302 " \"url\": \"%s\"}]",
3304 download_url
.c_str())));
3305 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3308 " \"filename\":\"slow.txt\"}]",
3310 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3311 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3313 // Respond to the onDeterminingFilename.
3315 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3316 browser()->profile(),
3321 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3323 EXPECT_EQ("", error
);
3325 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3329 " \"previous\": \"\","
3330 " \"current\": \"%s\"}}]",
3332 GetFilename("slow.txt").c_str())));
3333 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3337 " \"previous\": \"in_progress\","
3338 " \"current\": \"complete\"}}]",
3341 // Start downloading a file.
3342 result
.reset(RunFunctionAndReturnResult(
3343 new DownloadsDownloadFunction(), base::StringPrintf(
3344 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3345 ASSERT_TRUE(result
.get());
3347 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3348 item
= GetCurrentManager()->GetDownload(result_id
);
3350 ScopedCancellingItem
canceller2(item
);
3351 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3353 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3355 "[{\"danger\": \"safe\","
3356 " \"incognito\": false,"
3358 " \"mime\": \"text/plain\","
3359 " \"paused\": false,"
3360 " \"url\": \"%s\"}]",
3362 download_url
.c_str())));
3363 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3366 " \"filename\":\"slow.txt\"}]",
3368 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3369 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3371 // Respond to the onDeterminingFilename.
3372 // Also test that DetermineFilename allows (chrome) extensions to set
3373 // filenames without (filename) extensions. (Don't ask about v8 extensions or
3374 // python extensions or kernel extensions or firefox extensions...)
3376 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3377 browser()->profile(),
3382 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
,
3384 EXPECT_EQ("", error
);
3386 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3390 " \"previous\": \"\","
3391 " \"current\": \"%s\"}}]",
3393 GetFilename("slow.txt").c_str())));
3394 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3398 " \"previous\": \"in_progress\","
3399 " \"current\": \"complete\"}}]",
3403 IN_PROC_BROWSER_TEST_F(
3404 DownloadExtensionTest
,
3405 DownloadExtensionTest_OnDeterminingFilename_Override
) {
3407 LoadExtension("downloads_split");
3408 AddFilenameDeterminer();
3409 ASSERT_TRUE(StartEmbeddedTestServer());
3410 ASSERT_TRUE(test_server()->Start());
3411 std::string download_url
= test_server()->GetURL("slow?0").spec();
3413 // Start downloading a file.
3414 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3415 new DownloadsDownloadFunction(), base::StringPrintf(
3416 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3417 ASSERT_TRUE(result
.get());
3419 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3420 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3422 ScopedCancellingItem
canceller(item
);
3423 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3424 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3426 "[{\"danger\": \"safe\","
3427 " \"incognito\": false,"
3429 " \"mime\": \"text/plain\","
3430 " \"paused\": false,"
3431 " \"url\": \"%s\"}]",
3433 download_url
.c_str())));
3434 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3437 " \"filename\":\"slow.txt\"}]",
3439 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3440 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3442 // Respond to the onDeterminingFilename.
3444 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3445 browser()->profile(),
3450 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3452 EXPECT_EQ("", error
);
3454 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3458 " \"previous\": \"\","
3459 " \"current\": \"%s\"}}]",
3461 GetFilename("slow.txt").c_str())));
3462 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3466 " \"previous\": \"in_progress\","
3467 " \"current\": \"complete\"}}]",
3470 // Start downloading a file.
3471 result
.reset(RunFunctionAndReturnResult(
3472 new DownloadsDownloadFunction(), base::StringPrintf(
3473 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3474 ASSERT_TRUE(result
.get());
3476 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3477 item
= GetCurrentManager()->GetDownload(result_id
);
3479 ScopedCancellingItem
canceller2(item
);
3480 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3482 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3484 "[{\"danger\": \"safe\","
3485 " \"incognito\": false,"
3487 " \"mime\": \"text/plain\","
3488 " \"paused\": false,"
3489 " \"url\": \"%s\"}]",
3491 download_url
.c_str())));
3492 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3495 " \"filename\":\"slow.txt\"}]",
3497 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3498 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3500 // Respond to the onDeterminingFilename.
3501 // Also test that DetermineFilename allows (chrome) extensions to set
3502 // filenames without (filename) extensions. (Don't ask about v8 extensions or
3503 // python extensions or kernel extensions or firefox extensions...)
3505 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3506 browser()->profile(),
3510 base::FilePath(FILE_PATH_LITERAL("foo")),
3511 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
,
3513 EXPECT_EQ("", error
);
3515 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3519 " \"previous\": \"\","
3520 " \"current\": \"%s\"}}]",
3522 GetFilename("foo").c_str())));
3523 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3527 " \"previous\": \"in_progress\","
3528 " \"current\": \"complete\"}}]",
3532 // TODO test precedence rules: install_time
3534 #if defined(OS_MACOSX)
3535 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer \
3536 DISABLED_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer
3538 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer \
3539 DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer
3541 IN_PROC_BROWSER_TEST_F(
3542 DownloadExtensionTest
,
3543 MAYBE_DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer
) {
3544 ASSERT_TRUE(StartEmbeddedTestServer());
3545 ASSERT_TRUE(test_server()->Start());
3547 LoadExtension("downloads_split");
3548 content::RenderProcessHost
* host
= AddFilenameDeterminer();
3549 std::string download_url
= test_server()->GetURL("slow?0").spec();
3551 // Start downloading a file.
3552 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3553 new DownloadsDownloadFunction(), base::StringPrintf(
3554 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3555 ASSERT_TRUE(result
.get());
3557 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3558 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3560 ScopedCancellingItem
canceller(item
);
3561 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3563 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3565 "[{\"danger\": \"safe\","
3566 " \"incognito\": false,"
3568 " \"mime\": \"text/plain\","
3569 " \"paused\": false,"
3570 " \"url\": \"%s\"}]",
3572 download_url
.c_str())));
3573 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3576 " \"filename\":\"slow.txt\"}]",
3578 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3579 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3581 // Remove a determiner while waiting for it.
3582 RemoveFilenameDeterminer(host
);
3584 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3588 " \"previous\": \"in_progress\","
3589 " \"current\": \"complete\"}}]",
3593 IN_PROC_BROWSER_TEST_F(
3594 DownloadExtensionTest
,
3595 DownloadExtensionTest_OnDeterminingFilename_IncognitoSplit
) {
3596 LoadExtension("downloads_split");
3597 ASSERT_TRUE(StartEmbeddedTestServer());
3598 ASSERT_TRUE(test_server()->Start());
3599 std::string download_url
= test_server()->GetURL("slow?0").spec();
3602 AddFilenameDeterminer();
3605 AddFilenameDeterminer();
3607 // Start an on-record download.
3609 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3610 new DownloadsDownloadFunction(), base::StringPrintf(
3611 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3612 ASSERT_TRUE(result
.get());
3614 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3615 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3617 ScopedCancellingItem
canceller(item
);
3618 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3620 // Wait for the onCreated and onDeterminingFilename events.
3621 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3623 "[{\"danger\": \"safe\","
3624 " \"incognito\": false,"
3626 " \"mime\": \"text/plain\","
3627 " \"paused\": false,"
3628 " \"url\": \"%s\"}]",
3630 download_url
.c_str())));
3631 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3634 " \"incognito\": false,"
3635 " \"filename\":\"slow.txt\"}]",
3637 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3638 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3640 // Respond to the onDeterminingFilename events.
3642 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3643 current_browser()->profile(),
3647 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3648 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3650 EXPECT_EQ("", error
);
3652 // The download should complete successfully.
3653 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3657 " \"previous\": \"\","
3658 " \"current\": \"%s\"}}]",
3660 GetFilename("42.txt").c_str())));
3661 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3665 " \"previous\": \"in_progress\","
3666 " \"current\": \"complete\"}}]",
3669 // Start an incognito download for comparison.
3671 result
.reset(RunFunctionAndReturnResult(
3672 new DownloadsDownloadFunction(), base::StringPrintf(
3673 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3674 ASSERT_TRUE(result
.get());
3676 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3677 item
= GetCurrentManager()->GetDownload(result_id
);
3679 ScopedCancellingItem
canceller2(item
);
3680 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3682 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3684 "[{\"danger\": \"safe\","
3685 " \"incognito\": true,"
3687 " \"mime\": \"text/plain\","
3688 " \"paused\": false,"
3689 " \"url\": \"%s\"}]",
3691 download_url
.c_str())));
3692 // On-Record renderers should not see events for off-record items.
3693 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3696 " \"incognito\": true,"
3697 " \"filename\":\"slow.txt\"}]",
3699 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3700 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3702 // Respond to the onDeterminingFilename.
3704 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3705 current_browser()->profile(),
3709 base::FilePath(FILE_PATH_LITERAL("5.txt")),
3710 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3712 EXPECT_EQ("", error
);
3714 // The download should complete successfully.
3715 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3719 " \"previous\": \"\","
3720 " \"current\": \"%s\"}}]",
3722 GetFilename("5.txt").c_str())));
3723 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3727 " \"previous\": \"in_progress\","
3728 " \"current\": \"complete\"}}]",
3732 IN_PROC_BROWSER_TEST_F(
3733 DownloadExtensionTest
,
3734 DownloadExtensionTest_OnDeterminingFilename_IncognitoSpanning
) {
3735 LoadExtension("downloads_spanning");
3736 ASSERT_TRUE(StartEmbeddedTestServer());
3737 ASSERT_TRUE(test_server()->Start());
3738 std::string download_url
= test_server()->GetURL("slow?0").spec();
3741 AddFilenameDeterminer();
3743 // There is a single extension renderer that sees both on-record and
3744 // off-record events. The extension functions see the on-record profile with
3745 // include_incognito=true.
3747 // Start an on-record download.
3749 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
3750 new DownloadsDownloadFunction(), base::StringPrintf(
3751 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3752 ASSERT_TRUE(result
.get());
3754 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3755 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
3757 ScopedCancellingItem
canceller(item
);
3758 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3760 // Wait for the onCreated and onDeterminingFilename events.
3761 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3763 "[{\"danger\": \"safe\","
3764 " \"incognito\": false,"
3766 " \"mime\": \"text/plain\","
3767 " \"paused\": false,"
3768 " \"url\": \"%s\"}]",
3770 download_url
.c_str())));
3771 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3774 " \"incognito\": false,"
3775 " \"filename\":\"slow.txt\"}]",
3777 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3778 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3780 // Respond to the onDeterminingFilename events.
3782 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3783 current_browser()->profile(),
3787 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3788 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3790 EXPECT_EQ("", error
);
3792 // The download should complete successfully.
3793 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3797 " \"previous\": \"\","
3798 " \"current\": \"%s\"}}]",
3800 GetFilename("42.txt").c_str())));
3801 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3805 " \"previous\": \"in_progress\","
3806 " \"current\": \"complete\"}}]",
3809 // Start an incognito download for comparison.
3811 result
.reset(RunFunctionAndReturnResult(
3812 new DownloadsDownloadFunction(), base::StringPrintf(
3813 "[{\"url\": \"%s\"}]", download_url
.c_str())));
3814 ASSERT_TRUE(result
.get());
3816 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
3817 item
= GetCurrentManager()->GetDownload(result_id
);
3819 ScopedCancellingItem
canceller2(item
);
3820 ASSERT_EQ(download_url
, item
->GetOriginalUrl().spec());
3822 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3824 "[{\"danger\": \"safe\","
3825 " \"incognito\": true,"
3827 " \"mime\": \"text/plain\","
3828 " \"paused\": false,"
3829 " \"url\": \"%s\"}]",
3831 download_url
.c_str())));
3832 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3835 " \"incognito\": true,"
3836 " \"filename\":\"slow.txt\"}]",
3838 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3839 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3841 // Respond to the onDeterminingFilename.
3843 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3844 current_browser()->profile(),
3848 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3849 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3851 EXPECT_EQ("", error
);
3853 // The download should complete successfully.
3854 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3858 " \"previous\": \"\","
3859 " \"current\": \"%s\"}}]",
3861 GetFilename("42 (1).txt").c_str())));
3862 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3866 " \"previous\": \"in_progress\","
3867 " \"current\": \"complete\"}}]",
3872 // This test is very flaky on Win XP and Aura. http://crbug.com/248438
3873 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3874 DISABLED_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3876 #define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
3877 DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
3880 // Test download interruption while extensions determining filename. Should not
3881 // re-dispatch onDeterminingFilename.
3882 IN_PROC_BROWSER_TEST_F(
3883 DownloadExtensionTest
,
3884 MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
) {
3885 base::CommandLine::ForCurrentProcess()->AppendSwitch(
3886 switches::kEnableDownloadResumption
);
3887 LoadExtension("downloads_split");
3888 ASSERT_TRUE(StartEmbeddedTestServer());
3889 ASSERT_TRUE(test_server()->Start());
3891 content::RenderProcessHost
* host
= AddFilenameDeterminer();
3893 // Start a download.
3894 DownloadItem
* item
= NULL
;
3896 DownloadManager
* manager
= GetCurrentManager();
3897 scoped_ptr
<content::DownloadTestObserver
> observer(
3898 new JustInProgressDownloadObserver(manager
, 1));
3899 ASSERT_EQ(0, manager
->InProgressCount());
3900 ASSERT_EQ(0, manager
->NonMaliciousInProgressCount());
3901 // Tabs created just for a download are automatically closed, invalidating
3902 // the download's WebContents. Downloads without WebContents cannot be
3903 // resumed. http://crbug.com/225901
3904 ui_test_utils::NavigateToURLWithDisposition(
3906 GURL(net::URLRequestSlowDownloadJob::kUnknownSizeUrl
),
3908 ui_test_utils::BROWSER_TEST_NONE
);
3909 observer
->WaitForFinished();
3910 EXPECT_EQ(1u, observer
->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS
));
3911 DownloadManager::DownloadVector items
;
3912 manager
->GetAllDownloads(&items
);
3913 for (DownloadManager::DownloadVector::iterator iter
= items
.begin();
3914 iter
!= items
.end(); ++iter
) {
3915 if ((*iter
)->GetState() == DownloadItem::IN_PROGRESS
) {
3916 // There should be only one IN_PROGRESS item.
3917 EXPECT_EQ(NULL
, item
);
3923 ScopedCancellingItem
canceller(item
);
3925 // Wait for the onCreated and onDeterminingFilename event.
3926 ASSERT_TRUE(WaitFor(downloads::OnCreated::kEventName
,
3928 "[{\"danger\": \"safe\","
3929 " \"incognito\": false,"
3931 " \"mime\": \"application/octet-stream\","
3932 " \"paused\": false}]",
3934 ASSERT_TRUE(WaitFor(downloads::OnDeterminingFilename::kEventName
,
3937 " \"incognito\": false,"
3938 " \"filename\":\"download-unknown-size\"}]",
3940 ASSERT_TRUE(item
->GetTargetFilePath().empty());
3941 ASSERT_EQ(DownloadItem::IN_PROGRESS
, item
->GetState());
3944 ui_test_utils::NavigateToURLWithDisposition(
3946 GURL(net::URLRequestSlowDownloadJob::kErrorDownloadUrl
),
3948 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
3950 // Errors caught before filename determination are delayed until after
3951 // filename determination.
3953 ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
3954 current_browser()->profile(),
3958 base::FilePath(FILE_PATH_LITERAL("42.txt")),
3959 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
,
3962 EXPECT_EQ("", error
);
3963 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3967 " \"previous\": \"\","
3968 " \"current\": \"%s\"}}]",
3970 GetFilename("42.txt").c_str())));
3972 content::DownloadUpdatedObserver
interrupted(item
, base::Bind(
3973 ItemIsInterrupted
));
3974 ASSERT_TRUE(interrupted
.WaitForEvent());
3975 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3978 " \"error\":{\"current\":\"NETWORK_FAILED\"},"
3980 " \"previous\":\"in_progress\","
3981 " \"current\":\"interrupted\"}}]",
3985 // Downloads that are restarted on resumption trigger another download target
3987 RemoveFilenameDeterminer(host
);
3990 // Errors caught before filename determination is complete are delayed until
3991 // after filename determination so that, on resumption, filename determination
3992 // does not need to be re-done. So, there will not be a second
3993 // onDeterminingFilename event.
3995 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
3998 " \"error\":{\"previous\":\"NETWORK_FAILED\"},"
4000 " \"previous\":\"interrupted\","
4001 " \"current\":\"in_progress\"}}]",
4005 FinishPendingSlowDownloads();
4007 // The download should complete successfully.
4008 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
4012 " \"previous\": \"in_progress\","
4013 " \"current\": \"complete\"}}]",
4017 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
4018 DownloadExtensionTest_SetShelfEnabled
) {
4019 LoadExtension("downloads_split");
4020 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[false]"));
4021 EXPECT_FALSE(DownloadServiceFactory::GetForBrowserContext(
4022 browser()->profile())->IsShelfEnabled());
4023 EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[true]"));
4024 EXPECT_TRUE(DownloadServiceFactory::GetForBrowserContext(
4025 browser()->profile())->IsShelfEnabled());
4026 // TODO(benjhayden) Test that existing shelves are hidden.
4027 // TODO(benjhayden) Test multiple extensions.
4028 // TODO(benjhayden) Test disabling extensions.
4029 // TODO(benjhayden) Test that browsers associated with other profiles are not
4031 // TODO(benjhayden) Test incognito.
4034 // TODO(benjhayden) Figure out why DisableExtension() does not fire
4035 // OnListenerRemoved.
4037 // TODO(benjhayden) Test that the shelf is shown for download() both with and
4038 // without a WebContents.
4040 void OnDangerPromptCreated(DownloadDangerPrompt
* prompt
) {
4041 prompt
->InvokeActionForTesting(DownloadDangerPrompt::ACCEPT
);
4044 #if defined(OS_MACOSX)
4045 // Flakily triggers and assert on Mac.
4046 // http://crbug.com/180759
4047 #define MAYBE_DownloadExtensionTest_AcceptDanger DISABLED_DownloadExtensionTest_AcceptDanger
4049 #define MAYBE_DownloadExtensionTest_AcceptDanger DownloadExtensionTest_AcceptDanger
4051 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest
,
4052 MAYBE_DownloadExtensionTest_AcceptDanger
) {
4053 // Download a file that will be marked dangerous; click the browser action
4054 // button; the browser action poup will call acceptDanger(); when the
4055 // DownloadDangerPrompt is created, pretend that the user clicks the Accept
4056 // button; wait until the download completes.
4057 LoadExtension("downloads_split");
4058 scoped_ptr
<base::Value
> result(RunFunctionAndReturnResult(
4059 new DownloadsDownloadFunction(),
4060 "[{\"url\": \"data:,\", \"filename\": \"dangerous.swf\"}]"));
4061 ASSERT_TRUE(result
.get());
4063 ASSERT_TRUE(result
->GetAsInteger(&result_id
));
4064 DownloadItem
* item
= GetCurrentManager()->GetDownload(result_id
);
4066 ASSERT_TRUE(WaitFor(downloads::OnChanged::kEventName
,
4070 " \"previous\": \"safe\","
4071 " \"current\": \"file\"}}]",
4073 ASSERT_TRUE(item
->IsDangerous());
4074 ScopedCancellingItem
canceller(item
);
4075 scoped_ptr
<content::DownloadTestObserver
> observer(
4076 new content::DownloadTestObserverTerminal(
4077 GetCurrentManager(), 1,
4078 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_IGNORE
));
4079 DownloadsAcceptDangerFunction::OnPromptCreatedCallback callback
=
4080 base::Bind(&OnDangerPromptCreated
);
4081 DownloadsAcceptDangerFunction::OnPromptCreatedForTesting(
4083 BrowserActionTestUtil(browser()).Press(0);
4084 observer
->WaitForFinished();
4087 class DownloadsApiTest
: public ExtensionApiTest
{
4089 DownloadsApiTest() {}
4090 ~DownloadsApiTest() override
{}
4093 DISALLOW_COPY_AND_ASSIGN(DownloadsApiTest
);
4097 IN_PROC_BROWSER_TEST_F(DownloadsApiTest
, DownloadsApiTest
) {
4098 ASSERT_TRUE(RunExtensionTest("downloads")) << message_
;
4101 TEST(DownloadInterruptReasonEnumsSynced
,
4102 DownloadInterruptReasonEnumsSynced
) {
4103 #define INTERRUPT_REASON(name, value) \
4104 EXPECT_EQ(InterruptReasonContentToExtension( \
4105 content::DOWNLOAD_INTERRUPT_REASON_##name), \
4106 downloads::INTERRUPT_REASON_##name); \
4108 InterruptReasonExtensionToContent(downloads::INTERRUPT_REASON_##name), \
4109 content::DOWNLOAD_INTERRUPT_REASON_##name);
4110 #include "content/public/browser/download_interrupt_reason_values.h" // NOLINT
4111 #undef INTERRUPT_REASON
4114 TEST(ExtensionDetermineDownloadFilenameInternal
,
4115 ExtensionDetermineDownloadFilenameInternal
) {
4116 std::string winner_id
;
4117 base::FilePath filename
;
4118 downloads::FilenameConflictAction conflict_action
=
4119 downloads::FILENAME_CONFLICT_ACTION_UNIQUIFY
;
4120 WarningSet warnings
;
4122 // Empty incumbent determiner
4124 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4125 base::FilePath(FILE_PATH_LITERAL("a")),
4126 downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
,
4135 EXPECT_EQ("suggester", winner_id
);
4136 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename
.value());
4137 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
, conflict_action
);
4138 EXPECT_TRUE(warnings
.empty());
4142 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4143 base::FilePath(FILE_PATH_LITERAL("b")),
4144 downloads::FILENAME_CONFLICT_ACTION_PROMPT
,
4146 base::Time::Now() - base::TimeDelta::FromDays(1),
4153 EXPECT_EQ("incumbent", winner_id
);
4154 EXPECT_EQ(FILE_PATH_LITERAL("a"), filename
.value());
4155 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_OVERWRITE
, conflict_action
);
4156 EXPECT_FALSE(warnings
.empty());
4157 EXPECT_EQ(Warning::kDownloadFilenameConflict
,
4158 warnings
.begin()->warning_type());
4159 EXPECT_EQ("suggester", warnings
.begin()->extension_id());
4163 ExtensionDownloadsEventRouter::DetermineFilenameInternal(
4164 base::FilePath(FILE_PATH_LITERAL("b")),
4165 downloads::FILENAME_CONFLICT_ACTION_PROMPT
,
4169 base::Time::Now() - base::TimeDelta::FromDays(1),
4174 EXPECT_EQ("suggester", winner_id
);
4175 EXPECT_EQ(FILE_PATH_LITERAL("b"), filename
.value());
4176 EXPECT_EQ(downloads::FILENAME_CONFLICT_ACTION_PROMPT
, conflict_action
);
4177 EXPECT_FALSE(warnings
.empty());
4178 EXPECT_EQ(Warning::kDownloadFilenameConflict
,
4179 warnings
.begin()->warning_type());
4180 EXPECT_EQ("incumbent", warnings
.begin()->extension_id());
4183 } // namespace extensions
4185 #endif // http://crbug.com/306144