Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: chrome/browser/download/download_extension_test.cc

Issue 10542038: Rewrite DownloadsApiTest in C++. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <algorithm> 5 #include <algorithm>
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h"
10 #include "base/message_loop.h"
8 #include "base/scoped_temp_dir.h" 11 #include "base/scoped_temp_dir.h"
12 #include "base/stl_util.h"
9 #include "base/stringprintf.h" 13 #include "base/stringprintf.h"
10 #include "chrome/browser/download/download_extension_api.h" 14 #include "chrome/browser/download/download_extension_api.h"
11 #include "chrome/browser/download/download_file_icon_extractor.h" 15 #include "chrome/browser/download/download_file_icon_extractor.h"
12 #include "chrome/browser/download/download_service.h" 16 #include "chrome/browser/download/download_service.h"
13 #include "chrome/browser/download/download_service_factory.h" 17 #include "chrome/browser/download/download_service_factory.h"
14 #include "chrome/browser/download/download_test_observer.h" 18 #include "chrome/browser/download/download_test_observer.h"
19 #include "chrome/browser/extensions/extension_apitest.h"
20 #include "chrome/browser/extensions/extension_event_names.h"
15 #include "chrome/browser/extensions/extension_function_test_utils.h" 21 #include "chrome/browser/extensions/extension_function_test_utils.h"
16 #include "chrome/browser/net/url_request_mock_util.h" 22 #include "chrome/browser/net/url_request_mock_util.h"
17 #include "chrome/browser/prefs/pref_service.h" 23 #include "chrome/browser/prefs/pref_service.h"
18 #include "chrome/browser/profiles/profile.h" 24 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/browser.h" 25 #include "chrome/browser/ui/browser.h"
26 #include "chrome/browser/ui/tab_contents/tab_contents.h"
27 #include "chrome/common/chrome_notification_types.h"
20 #include "chrome/common/pref_names.h" 28 #include "chrome/common/pref_names.h"
21 #include "chrome/test/base/in_process_browser_test.h" 29 #include "chrome/test/base/in_process_browser_test.h"
22 #include "chrome/test/base/ui_test_utils.h" 30 #include "chrome/test/base/ui_test_utils.h"
31 #include "content/public/browser/browser_context.h"
23 #include "content/public/browser/browser_thread.h" 32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/download_item.h"
24 #include "content/public/browser/download_manager.h" 34 #include "content/public/browser/download_manager.h"
25 #include "content/public/browser/download_persistent_store_info.h" 35 #include "content/public/browser/download_persistent_store_info.h"
36 #include "content/public/browser/notification_service.h"
37 #include "content/public/browser/web_contents.h"
38 #include "content/public/common/page_transition_types.h"
26 #include "content/test/net/url_request_slow_download_job.h" 39 #include "content/test/net/url_request_slow_download_job.h"
27 #include "net/base/data_url.h" 40 #include "net/base/data_url.h"
28 #include "net/base/net_util.h" 41 #include "net/base/net_util.h"
29 #include "ui/gfx/codec/png_codec.h" 42 #include "ui/gfx/codec/png_codec.h"
43 #include "webkit/fileapi/file_system_context.h"
44 #include "webkit/fileapi/file_system_operation_interface.h"
30 45
31 using content::BrowserContext; 46 using content::BrowserContext;
32 using content::BrowserThread; 47 using content::BrowserThread;
33 using content::DownloadItem; 48 using content::DownloadItem;
34 using content::DownloadManager; 49 using content::DownloadManager;
35 using content::DownloadPersistentStoreInfo; 50 using content::DownloadPersistentStoreInfo;
36 51
37 namespace { 52 namespace {
38 53
39 // Comparator that orders download items by their ID. Can be used with 54 // Comparator that orders download items by their ID. Can be used with
40 // std::sort. 55 // std::sort.
41 struct DownloadIdComparator { 56 struct DownloadIdComparator {
42 bool operator() (DownloadItem* first, DownloadItem* second) { 57 bool operator() (DownloadItem* first, DownloadItem* second) {
43 return first->GetId() < second->GetId(); 58 return first->GetId() < second->GetId();
44 } 59 }
45 }; 60 };
46 61
47 class DownloadExtensionTest : public InProcessBrowserTest { 62 class DownloadsEventsListener : public content::NotificationObserver {
63 public:
64 // WaitFor() gives up after this many milliseconds, figuring that the event it
65 // wants will never happen so that a failing test doesn't take too long to
66 // fail. This may be too short on very busy machines, or too long on very fast
67 // ones.
68 static const int kTimeOutMs = -1;
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 The comment and the value (which I take to mean "i
benjhayden 2012/06/19 15:01:59 Done.
69
70 DownloadsEventsListener()
71 : waiting_(false) {
72 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
73 content::NotificationService::AllSources());
74 }
75 virtual ~DownloadsEventsListener() {
76 STLDeleteElements(&events_);
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 Shouldn't this have a registrar_.Remove()?
benjhayden 2012/06/19 15:01:59 Done.
77 }
78
79 class Event {
80 public:
81 Event(Profile* profile,
82 const std::string& event_name,
83 const std::string& json_args,
84 base::Time caught)
85 : profile_(profile),
86 event_name_(event_name),
87 json_args_(json_args),
88 args_(base::JSONReader::Read(json_args)),
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 Is there some location you can point to for the fo
benjhayden 2012/06/19 15:01:59 The structure of args_ depends on event_name. See
89 caught_(caught) {
90 }
91
92 const base::Time& caught() { return caught_; }
93
94 bool Equals(const Event& other) {
95 if ((profile_ != other.profile_) ||
96 (event_name_ != other.event_name_))
97 return false;
98 if ((event_name_ == extension_event_names::kOnDownloadCreated ||
99 event_name_ == extension_event_names::kOnDownloadChanged) &&
100 args_.get() &&
101 other.args_.get()) {
102 base::ListValue* left_list = NULL;
103 base::DictionaryValue* left_dict = NULL;
104 base::ListValue* right_list = NULL;
105 base::DictionaryValue* right_dict = NULL;
106 if (!args_->GetAsList(&left_list) ||
107 !other.args_->GetAsList(&right_list) ||
108 !left_list->GetDictionary(0, &left_dict) ||
109 !right_list->GetDictionary(0, &right_dict))
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 Does this mean the Equals function returns false i
benjhayden 2012/06/19 15:01:59 For onCreated and onChanged events, yes.
110 return false;
111 for (base::DictionaryValue::Iterator iter(*left_dict);
112 iter.HasNext(); iter.Advance()) {
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 nit: indent? (May be just formatting in Rietveld.
benjhayden 2012/06/19 15:01:59 Done.
113 base::Value* right_value = NULL;
114 if (right_dict->HasKey(iter.key()) &&
115 right_dict->Get(iter.key(), &right_value) &&
116 !iter.value().Equals(right_value)) {
117 return false;
118 }
119 }
120 return true;
121 } else if ((event_name_ == extension_event_names::kOnDownloadErased) &&
122 args_.get() &&
123 other.args_.get()) {
124 int my_id = -1, other_id = -1;
125 return (args_->GetAsInteger(&my_id) &&
126 other.args_->GetAsInteger(&other_id) &&
127 my_id == other_id);
128 }
129 return json_args_ == other.json_args_;
130 }
131
132 std::string Debug() {
133 return base::StringPrintf("Event(%p, %s, %s, %f)",
134 profile_,
135 event_name_.c_str(),
136 json_args_.c_str(),
137 caught_.ToJsTime());
138 }
139
140 private:
141 Profile* profile_;
142 std::string event_name_;
143 std::string json_args_;
144 scoped_ptr<base::Value> args_;
145 base::Time caught_;
146
147 DISALLOW_COPY_AND_ASSIGN(Event);
148 };
149
150 typedef ExtensionDownloadsEventRouter::DownloadsNotificationSource
151 DownloadsNotificationSource;
152
153 void Observe(int type, const content::NotificationSource& source,
154 const content::NotificationDetails& details) {
155 switch (type) {
156 case chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT:
157 {
158 DownloadsNotificationSource* dns =
159 content::Source<DownloadsNotificationSource>(source).ptr();
160 ObserveInternal(dns->profile, dns->event_name,
161 *content::Details<std::string>(details).ptr());
162 break;
163 }
164 default:
165 NOTREACHED();
166 }
167 }
168
169 // This is public to accommodate the HTML5 FileSystem Files event.
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 I found this comment confusing when I first read i
benjhayden 2012/06/19 15:01:59 Done.
170 void ObserveInternal(Profile* profile, const std::string& event_name,
171 const std::string& json_args) {
172 Event* new_event = new Event(
173 profile, event_name, json_args, base::Time::Now());
174 events_.push_back(new_event);
175 if (waiting_ &&
176 waiting_for_.get() &&
177 waiting_for_->Equals(*new_event)) {
178 waiting_ = false;
179 MessageLoopForUI::current()->Quit();
180 }
181 }
182
183 bool WaitFor(int timeout_ms,
184 Profile* profile,
185 const std::string& event_name,
186 const std::string& json_args) {
187 waiting_for_.reset(new Event(profile, event_name, json_args, base::Time()));
188 for (std::deque<Event*>::const_iterator iter = events_.begin();
189 iter != events_.end(); ++iter) {
190 if ((*iter)->Equals(*waiting_for_.get()))
191 return true;
192 }
193 waiting_ = true;
194 if (timeout_ms > 0) {
195 MessageLoop::current()->PostDelayedTask(
196 FROM_HERE, base::Bind(
197 &DownloadsEventsListener::TimedOut, base::Unretained(this)),
198 timeout_ms);
199 }
200 ui_test_utils::RunMessageLoop();
201 bool success = !waiting_;
202 if (waiting_) {
203 // Print the events that were caught since the last WaitFor() call to help
204 // find the erroneous event.
205 // TODO(benjhayden) Fuzzy-match and highlight the erroneous event.
206 for (std::deque<Event*>::const_iterator iter = events_.begin();
207 iter != events_.end(); ++iter) {
208 if ((*iter)->caught() > last_wait_) {
209 LOG(INFO) << "Caught " << (*iter)->Debug();
210 }
211 }
212 if (waiting_for_.get()) {
213 LOG(INFO) << "Timed out waiting for " << waiting_for_->Debug();
214 }
215 waiting_ = false;
216 }
217 waiting_for_.reset();
218 last_wait_ = base::Time::Now();
219 return success;
220 }
221
222 bool WaitFor(Profile* profile,
223 const std::string& event_name,
224 const std::string& json_args) {
225 return WaitFor(kTimeOutMs, profile, event_name, json_args);
226 }
227
228 private:
229 void TimedOut() {
230 if (!waiting_for_.get())
231 return;
232 MessageLoopForUI::current()->Quit();
233 }
234
235 bool waiting_;
236 base::Time last_wait_;
237 scoped_ptr<Event> waiting_for_;
238 content::NotificationRegistrar registrar_;
239 std::deque<Event*> events_;
240
241 DISALLOW_COPY_AND_ASSIGN(DownloadsEventsListener);
242 };
243
244 class DownloadExtensionTest : public ExtensionApiTest {
245 public:
246 DownloadExtensionTest()
247 : extension_(NULL),
248 incognito_browser_(NULL),
249 current_browser_(NULL) {
250 }
251
252 void ObserveEvent(Profile* profile, const std::string& event_name,
253 const std::string& json_args) {
254 events_listener_->ObserveInternal(profile, event_name, json_args);
255 }
256
48 protected: 257 protected:
49 // Used with CreateHistoryDownloads 258 // Used with CreateHistoryDownloads
50 struct HistoryDownloadInfo { 259 struct HistoryDownloadInfo {
51 // Filename to use. CreateHistoryDownloads will append this filename to the 260 // Filename to use. CreateHistoryDownloads will append this filename to the
52 // temporary downloads directory specified by downloads_directory(). 261 // temporary downloads directory specified by downloads_directory().
53 const FilePath::CharType* filename; 262 const FilePath::CharType* filename;
54 263
55 // State for the download. Note that IN_PROGRESS downloads will be created 264 // State for the download. Note that IN_PROGRESS downloads will be created
56 // as CANCELLED. 265 // as CANCELLED.
57 DownloadItem::DownloadState state; 266 DownloadItem::DownloadState state;
58 267
59 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS 268 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
60 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT. 269 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT.
61 content::DownloadDangerType danger_type; 270 content::DownloadDangerType danger_type;
62 }; 271 };
63 272
64 virtual Browser* current_browser() { return browser(); } 273 void LoadExtension(const char* name) {
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 I find this confusing; reasonable to put a comment
benjhayden 2012/06/19 15:01:59 Done.
274 extension_ = LoadExtensionIncognito(test_data_dir_.AppendASCII(name));
275 CHECK(extension_);
276 }
277
278 Browser* current_browser() { return current_browser_; }
65 279
66 // InProcessBrowserTest 280 // InProcessBrowserTest
67 virtual void SetUpOnMainThread() OVERRIDE { 281 virtual void SetUpOnMainThread() OVERRIDE {
68 BrowserThread::PostTask( 282 BrowserThread::PostTask(
69 BrowserThread::IO, FROM_HERE, 283 BrowserThread::IO, FROM_HERE,
70 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); 284 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
71 InProcessBrowserTest::SetUpOnMainThread(); 285 InProcessBrowserTest::SetUpOnMainThread();
286 GoOnTheRecord();
72 CreateAndSetDownloadsDirectory(); 287 CreateAndSetDownloadsDirectory();
73 current_browser()->profile()->GetPrefs()->SetBoolean( 288 current_browser()->profile()->GetPrefs()->SetBoolean(
74 prefs::kPromptForDownload, false); 289 prefs::kPromptForDownload, false);
75 GetDownloadManager()->RemoveAllDownloads(); 290 GetOnRecordManager()->RemoveAllDownloads();
291 events_listener_.reset(new DownloadsEventsListener());
76 } 292 }
77 293
78 virtual DownloadManager* GetDownloadManager() { 294 void GoOnTheRecord() { current_browser_ = browser(); }
79 return BrowserContext::GetDownloadManager(current_browser()->profile()); 295
296 void GoOffTheRecord() {
297 if (!incognito_browser_) {
298 incognito_browser_ = CreateIncognitoBrowser();
299 GetOffRecordManager()->RemoveAllDownloads();
300 }
301 current_browser_ = incognito_browser_;
302 }
303
304 bool WaitFor(int timeout_ms, const std::string& event_name,
305 const std::string& json_args) {
306 return events_listener_->WaitFor(
307 timeout_ms, current_browser()->profile(), event_name, json_args);
308 }
309
310 bool WaitFor(const std::string& event_name, const std::string& json_args) {
311 return events_listener_->WaitFor(
312 current_browser()->profile(), event_name, json_args);
313 }
314
315 std::string GetURL(const char* path) {
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 Why not test_server()->GetURL?
benjhayden 2012/06/19 15:01:59 Done.
316 return base::StringPrintf("http://localhost:%d/%s",
317 test_server()->host_port_pair().port(),
318 path);
319 }
320
321 std::string GetExtensionURL() {
322 return extension_->url().spec();
323 }
324
325 std::string GetFilename(const char* path) {
326 return downloads_directory_.path().AppendASCII(path).AsUTF8Unsafe();
327 }
328
329 DownloadManager* GetOnRecordManager() {
330 return BrowserContext::GetDownloadManager(browser()->profile());
331 }
332 DownloadManager* GetOffRecordManager() {
333 return BrowserContext::GetDownloadManager(
334 browser()->profile()->GetOffTheRecordProfile());
335 }
336 DownloadManager* GetCurrentManager() {
337 return (current_browser_ == incognito_browser_) ?
338 GetOffRecordManager() : GetOnRecordManager();
80 } 339 }
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 I have mixed feelings about On/Off record state be
benjhayden 2012/06/19 15:01:59 I originally started with passing flags everywhere
81 340
82 // Creates a set of history downloads based on the provided |history_info| 341 // Creates a set of history downloads based on the provided |history_info|
83 // array. |count| is the number of elements in |history_info|. On success, 342 // array. |count| is the number of elements in |history_info|. On success,
84 // |items| will contain |count| DownloadItems in the order that they were 343 // |items| will contain |count| DownloadItems in the order that they were
85 // specified in |history_info|. Returns true on success and false otherwise. 344 // specified in |history_info|. Returns true on success and false otherwise.
86 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info, 345 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info,
87 size_t count, 346 size_t count,
88 DownloadManager::DownloadVector* items) { 347 DownloadManager::DownloadVector* items) {
89 DownloadIdComparator download_id_comparator; 348 DownloadIdComparator download_id_comparator;
90 base::Time current = base::Time::Now(); 349 base::Time current = base::Time::Now();
91 std::vector<DownloadPersistentStoreInfo> entries; 350 std::vector<DownloadPersistentStoreInfo> entries;
92 entries.reserve(count); 351 entries.reserve(count);
93 for (size_t i = 0; i < count; ++i) { 352 for (size_t i = 0; i < count; ++i) {
94 DownloadPersistentStoreInfo entry( 353 DownloadPersistentStoreInfo entry(
95 downloads_directory().Append(history_info[i].filename), 354 downloads_directory().Append(history_info[i].filename),
96 GURL(), GURL(), // URL, referrer 355 GURL(), GURL(), // URL, referrer
97 current, current, // start_time, end_time 356 current, current, // start_time, end_time
98 1, 1, // received_bytes, total_bytes 357 1, 1, // received_bytes, total_bytes
99 history_info[i].state, // state 358 history_info[i].state, // state
100 i + 1, // db_handle 359 i + 1, // db_handle
101 false); // opened 360 false); // opened
102 entries.push_back(entry); 361 entries.push_back(entry);
103 } 362 }
104 GetDownloadManager()->OnPersistentStoreQueryComplete(&entries); 363 GetOnRecordManager()->OnPersistentStoreQueryComplete(&entries);
105 GetDownloadManager()->GetAllDownloads(FilePath(), items); 364 GetOnRecordManager()->GetAllDownloads(FilePath(), items);
106 EXPECT_EQ(count, items->size()); 365 EXPECT_EQ(count, items->size());
107 if (count != items->size()) 366 if (count != items->size())
108 return false; 367 return false;
109 368
110 // Order by ID so that they are in the order that we created them. 369 // Order by ID so that they are in the order that we created them.
111 std::sort(items->begin(), items->end(), download_id_comparator); 370 std::sort(items->begin(), items->end(), download_id_comparator);
112 // Set the danger type if necessary. 371 // Set the danger type if necessary.
113 for (size_t i = 0; i < count; ++i) { 372 for (size_t i = 0; i < count; ++i) {
114 if (history_info[i].danger_type != 373 if (history_info[i].danger_type !=
115 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) { 374 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
(...skipping 13 matching lines...) Expand all
129 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); 388 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
130 ui_test_utils::NavigateToURLWithDisposition( 389 ui_test_utils::NavigateToURLWithDisposition(
131 current_browser(), slow_download_url, CURRENT_TAB, 390 current_browser(), slow_download_url, CURRENT_TAB,
132 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 391 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
133 observer->WaitForFinished(); 392 observer->WaitForFinished();
134 EXPECT_EQ( 393 EXPECT_EQ(
135 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS)); 394 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
136 // We don't expect a select file dialog. 395 // We don't expect a select file dialog.
137 ASSERT_FALSE(observer->select_file_dialog_seen()); 396 ASSERT_FALSE(observer->select_file_dialog_seen());
138 } 397 }
139 GetDownloadManager()->GetAllDownloads(FilePath(), items); 398 GetCurrentManager()->GetAllDownloads(FilePath(), items);
140 ASSERT_EQ(count, items->size()); 399 ASSERT_EQ(count, items->size());
141 } 400 }
142 401
143 DownloadItem* CreateSlowTestDownload() { 402 DownloadItem* CreateSlowTestDownload() {
144 scoped_ptr<DownloadTestObserver> observer( 403 scoped_ptr<DownloadTestObserver> observer(
145 CreateInProgressDownloadObserver(1)); 404 CreateInProgressDownloadObserver(1));
146 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); 405 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
147 DownloadManager* manager = GetDownloadManager(); 406 DownloadManager* manager = GetCurrentManager();
148 407
149 EXPECT_EQ(0, manager->InProgressCount()); 408 EXPECT_EQ(0, manager->InProgressCount());
150 if (manager->InProgressCount() != 0) 409 if (manager->InProgressCount() != 0)
151 return NULL; 410 return NULL;
152 411
153 ui_test_utils::NavigateToURLWithDisposition( 412 ui_test_utils::NavigateToURLWithDisposition(
154 current_browser(), slow_download_url, CURRENT_TAB, 413 current_browser(), slow_download_url, CURRENT_TAB,
155 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 414 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
156 415
157 observer->WaitForFinished(); 416 observer->WaitForFinished();
(...skipping 23 matching lines...) Expand all
181 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl); 440 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl);
182 ui_test_utils::NavigateToURLWithDisposition( 441 ui_test_utils::NavigateToURLWithDisposition(
183 current_browser(), finish_url, NEW_FOREGROUND_TAB, 442 current_browser(), finish_url, NEW_FOREGROUND_TAB,
184 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 443 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
185 observer->WaitForFinished(); 444 observer->WaitForFinished();
186 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); 445 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
187 } 446 }
188 447
189 DownloadTestObserver* CreateDownloadObserver(size_t download_count) { 448 DownloadTestObserver* CreateDownloadObserver(size_t download_count) {
190 return new DownloadTestObserverTerminal( 449 return new DownloadTestObserverTerminal(
191 GetDownloadManager(), download_count, true, 450 GetCurrentManager(), download_count, true,
192 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); 451 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
193 } 452 }
194 453
195 DownloadTestObserver* CreateInProgressDownloadObserver( 454 DownloadTestObserver* CreateInProgressDownloadObserver(
196 size_t download_count) { 455 size_t download_count) {
197 return new DownloadTestObserverInProgress(GetDownloadManager(), 456 return new DownloadTestObserverInProgress(
198 download_count, 457 GetCurrentManager(), download_count, true);
199 true); 458 }
459
460 bool RunFunction(UIThreadExtensionFunction* function,
461 const std::string& args) {
462 scoped_refptr<UIThreadExtensionFunction> delete_function(function);
463 SetUpExtensionFunction(function);
464 return extension_function_test_utils::RunFunction(
465 function, args, browser(), GetFlags());
200 } 466 }
201 467
202 extension_function_test_utils::RunFunctionFlags GetFlags() { 468 extension_function_test_utils::RunFunctionFlags GetFlags() {
203 return current_browser()->profile()->IsOffTheRecord() ? 469 return current_browser()->profile()->IsOffTheRecord() ?
204 extension_function_test_utils::INCLUDE_INCOGNITO : 470 extension_function_test_utils::INCLUDE_INCOGNITO :
205 extension_function_test_utils::NONE; 471 extension_function_test_utils::NONE;
206 } 472 }
207 473
208 // extension_function_test_utils::RunFunction*() only uses browser for its 474 // extension_function_test_utils::RunFunction*() only uses browser for its
209 // profile(), so pass it the on-record browser so that it always uses the 475 // profile(), so pass it the on-record browser so that it always uses the
210 // on-record profile. 476 // on-record profile to match real-life behavior.
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 Why does it match real-life behavior? Does this s
benjhayden 2012/06/19 15:01:59 Yes, ExtensionFunctions get the on-record profile
211
212 bool RunFunction(UIThreadExtensionFunction* function,
213 const std::string& args) {
214 // extension_function_test_utils::RunFunction() does not take
215 // ownership of |function|.
216 scoped_refptr<ExtensionFunction> function_owner(function);
217 return extension_function_test_utils::RunFunction(
218 function, args, browser(), GetFlags());
219 }
220 477
221 base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function, 478 base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function,
222 const std::string& args) { 479 const std::string& args) {
480 SetUpExtensionFunction(function);
223 return extension_function_test_utils::RunFunctionAndReturnResult( 481 return extension_function_test_utils::RunFunctionAndReturnResult(
224 function, args, browser(), GetFlags()); 482 function, args, browser(), GetFlags());
225 } 483 }
226 484
227 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, 485 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function,
228 const std::string& args) { 486 const std::string& args) {
487 SetUpExtensionFunction(function);
229 return extension_function_test_utils::RunFunctionAndReturnError( 488 return extension_function_test_utils::RunFunctionAndReturnError(
230 function, args, browser(), GetFlags()); 489 function, args, browser(), GetFlags());
231 } 490 }
232 491
233 bool RunFunctionAndReturnString(UIThreadExtensionFunction* function, 492 bool RunFunctionAndReturnString(UIThreadExtensionFunction* function,
234 const std::string& args, 493 const std::string& args,
235 std::string* result_string) { 494 std::string* result_string) {
495 SetUpExtensionFunction(function);
236 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args)); 496 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args));
237 EXPECT_TRUE(result.get()); 497 EXPECT_TRUE(result.get());
238 return result.get() && result->GetAsString(result_string); 498 return result.get() && result->GetAsString(result_string);
239 } 499 }
240 500
241 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) { 501 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) {
242 return base::StringPrintf("[%d]", download_item->GetId()); 502 return base::StringPrintf("[%d]", download_item->GetId());
243 } 503 }
244 504
245 // Checks if a data URL encoded image is a PNG of a given size. 505 // Checks if a data URL encoded image is a PNG of a given size.
(...skipping 17 matching lines...) Expand all
263 &width, &height)); 523 &width, &height));
264 EXPECT_EQ(expected_size, width); 524 EXPECT_EQ(expected_size, width);
265 EXPECT_EQ(expected_size, height); 525 EXPECT_EQ(expected_size, height);
266 } 526 }
267 527
268 const FilePath& downloads_directory() { 528 const FilePath& downloads_directory() {
269 return downloads_directory_.path(); 529 return downloads_directory_.path();
270 } 530 }
271 531
272 private: 532 private:
533 void SetUpExtensionFunction(UIThreadExtensionFunction* function) {
534 if (extension_) {
535 // Recreate the tab each time for insulation.
536 TabContents* tab = current_browser()->AddSelectedTabWithURL(
537 extension_->GetResourceURL("empty.html"),
538 content::PAGE_TRANSITION_LINK);
539 function->set_extension(extension_);
540 function->SetRenderViewHost(tab->web_contents()->GetRenderViewHost());
541 }
542 }
543
273 void CreateAndSetDownloadsDirectory() { 544 void CreateAndSetDownloadsDirectory() {
274 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); 545 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
275 current_browser()->profile()->GetPrefs()->SetFilePath( 546 current_browser()->profile()->GetPrefs()->SetFilePath(
276 prefs::kDownloadDefaultDirectory, 547 prefs::kDownloadDefaultDirectory,
277 downloads_directory_.path()); 548 downloads_directory_.path());
278 } 549 }
279 550
280 ScopedTempDir downloads_directory_; 551 ScopedTempDir downloads_directory_;
281 }; 552 const extensions::Extension* extension_;
282
283 class DownloadExtensionTestIncognito : public DownloadExtensionTest {
284 public:
285 virtual Browser* current_browser() OVERRIDE { return current_browser_; }
286
287 virtual void SetUpOnMainThread() OVERRIDE {
288 GoOnTheRecord();
289 DownloadExtensionTest::SetUpOnMainThread();
290 incognito_browser_ = CreateIncognitoBrowser();
291 GoOffTheRecord();
292 GetDownloadManager()->RemoveAllDownloads();
293 }
294
295 void GoOnTheRecord() { current_browser_ = browser(); }
296 void GoOffTheRecord() { current_browser_ = incognito_browser_; }
297
298 private:
299 Browser* incognito_browser_; 553 Browser* incognito_browser_;
300 Browser* current_browser_; 554 Browser* current_browser_;
555 scoped_ptr<DownloadsEventsListener> events_listener_;
556
557 DISALLOW_COPY_AND_ASSIGN(DownloadExtensionTest);
301 }; 558 };
302 559
303 class MockIconExtractorImpl : public DownloadFileIconExtractor { 560 class MockIconExtractorImpl : public DownloadFileIconExtractor {
304 public: 561 public:
305 MockIconExtractorImpl(const FilePath& path, IconLoader::IconSize icon_size, 562 MockIconExtractorImpl(const FilePath& path, IconLoader::IconSize icon_size,
306 const std::string& response) 563 const std::string& response)
307 : expected_path_(path), 564 : expected_path_(path),
308 expected_icon_size_(icon_size), 565 expected_icon_size_(icon_size),
309 response_(response) { 566 response_(response) {
310 } 567 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 if ((*item)->IsInProgress()) 626 if ((*item)->IsInProgress())
370 (*item)->Cancel(true); 627 (*item)->Cancel(true);
371 } 628 }
372 } 629 }
373 630
374 private: 631 private:
375 DownloadManager::DownloadVector* items_; 632 DownloadManager::DownloadVector* items_;
376 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller); 633 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller);
377 }; 634 };
378 635
379 } // namespace 636 void FileCreated(const std::string& url, const base::Closure& done,
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 Could you put two comments here, one that these fu
benjhayden 2012/06/19 15:01:59 Done.
637 base::PlatformFileError result) {
638 CHECK(BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done));
639 }
640
641 void CreateFileOnIOThread(fileapi::FileSystemOperationInterface* operation,
642 const base::Closure& done,
643 const std::string& url) {
644 operation->CreateFile(GURL(url),
645 true/*exclusive*/,
646 base::Bind(&FileCreated, url, done));
647 }
648
649 void OpenFileSystemCallback(fileapi::FileSystemContext* fs,
650 const std::string& filename,
651 const base::Closure& done,
652 base::PlatformFileError result,
653 const std::string& fs_name,
654 const GURL& root) {
655 fileapi::FileSystemOperationInterface* operation =
656 fs->CreateFileSystemOperation(root);
657 CHECK(BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
658 &CreateFileOnIOThread, operation, done, root.spec() + filename)));
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 nit: indent? (Again not sure about Rietveld forma
benjhayden 2012/06/19 15:01:59 Looks right to me. The previous line ends with a p
Randy Smith (Not in Mondays) 2012/06/19 19:23:23 Right--did the alignment wrong in my head. Ooops.
659 }
660
661 } // namespace
380 662
381 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_PauseResumeCancel) { 663 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_PauseResumeCancel) {
382 DownloadItem* download_item = CreateSlowTestDownload(); 664 DownloadItem* download_item = CreateSlowTestDownload();
383 ASSERT_TRUE(download_item); 665 ASSERT_TRUE(download_item);
384 666
385 // Call pause(). It should succeed and the download should be paused on 667 // Call pause(). It should succeed and the download should be paused on
386 // return. 668 // return.
387 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), 669 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
388 DownloadItemIdAsArgList(download_item))); 670 DownloadItemIdAsArgList(download_item)));
389 EXPECT_TRUE(download_item->IsPaused()); 671 EXPECT_TRUE(download_item->IsPaused());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item)); 705 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item));
424 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 706 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
425 error.c_str()); 707 error.c_str());
426 708
427 // Calling resume on a non-active download yields kInvalidOperationError 709 // Calling resume on a non-active download yields kInvalidOperationError
428 error = RunFunctionAndReturnError( 710 error = RunFunctionAndReturnError(
429 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item)); 711 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item));
430 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 712 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
431 error.c_str()); 713 error.c_str());
432 714
433 // Calling pause()/resume()/cancel() with invalid download Ids is 715 // Calling paused on a non-existent download yields kInvalidOperationError.
434 // tested in the API test (DownloadsApiTest). 716 error = RunFunctionAndReturnError(
717 new DownloadsPauseFunction(), "[-42]");
718 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
719 error.c_str());
720
721 // Calling resume on a non-existent download yields kInvalidOperationError
722 error = RunFunctionAndReturnError(
723 new DownloadsResumeFunction(), "[-42]");
724 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
725 error.c_str());
435 } 726 }
436 727
437 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted 728 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted
438 // download items. 729 // download items.
439 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_Active) { 730 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_Active) {
440 DownloadItem* download_item = CreateSlowTestDownload(); 731 DownloadItem* download_item = CreateSlowTestDownload();
441 ASSERT_TRUE(download_item); 732 ASSERT_TRUE(download_item);
442 733
443 // Get the icon for the in-progress download. This call should succeed even 734 // Get the icon for the in-progress download. This call should succeed even
444 // if the file type isn't registered. 735 // if the file type isn't registered.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 expected_path, IconLoader::NORMAL, "")); 810 expected_path, IconLoader::NORMAL, ""));
520 std::string error = RunFunctionAndReturnError(function.release(), args); 811 std::string error = RunFunctionAndReturnError(function.release(), args);
521 EXPECT_STREQ(download_extension_errors::kIconNotFoundError, 812 EXPECT_STREQ(download_extension_errors::kIconNotFoundError,
522 error.c_str()); 813 error.c_str());
523 814
524 // Once the download item is deleted, we should return kInvalidOperationError. 815 // Once the download item is deleted, we should return kInvalidOperationError.
525 download_item->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); 816 download_item->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD);
526 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args); 817 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args);
527 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 818 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
528 error.c_str()); 819 error.c_str());
529
530 // Asking for icons of other (invalid) sizes is tested in the API test
531 // (DownloadsApiTest).
532 } 820 }
533 821
534 // Test that we can acquire file icons for history downloads regardless of 822 // Test that we can acquire file icons for history downloads regardless of
535 // whether they exist or not. If the file doesn't exist we should receive a 823 // whether they exist or not. If the file doesn't exist we should receive a
536 // generic icon from the OS/toolkit that may or may not be specific to the file 824 // generic icon from the OS/toolkit that may or may not be specific to the file
537 // type. 825 // type.
538 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_History) { 826 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_History) {
539 const HistoryDownloadInfo kHistoryInfo[] = { 827 const HistoryDownloadInfo kHistoryInfo[] = {
540 { FILE_PATH_LITERAL("real.txt"), 828 { FILE_PATH_LITERAL("real.txt"),
541 DownloadItem::COMPLETE, 829 DownloadItem::COMPLETE,
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 base::ListValue* result_list = NULL; 1100 base::ListValue* result_list = NULL;
813 ASSERT_TRUE(result->GetAsList(&result_list)); 1101 ASSERT_TRUE(result->GetAsList(&result_list));
814 ASSERT_EQ(1UL, result_list->GetSize()); 1102 ASSERT_EQ(1UL, result_list->GetSize());
815 base::DictionaryValue* item_value = NULL; 1103 base::DictionaryValue* item_value = NULL;
816 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); 1104 ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
817 FilePath::StringType item_name; 1105 FilePath::StringType item_name;
818 ASSERT_TRUE(item_value->GetString("filename", &item_name)); 1106 ASSERT_TRUE(item_value->GetString("filename", &item_name));
819 ASSERT_EQ(items[2]->GetFullPath().value(), item_name); 1107 ASSERT_EQ(items[2]->GetFullPath().value(), item_name);
820 } 1108 }
821 1109
822 IN_PROC_BROWSER_TEST_F(DownloadExtensionTestIncognito, 1110 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
823 DownloadsApi_SearchIncognito) { 1111 DownloadExtensionTest_SearchIncognito) {
824 scoped_ptr<base::Value> result_value; 1112 scoped_ptr<base::Value> result_value;
825 base::ListValue* result_list = NULL; 1113 base::ListValue* result_list = NULL;
826 base::DictionaryValue* result_dict = NULL; 1114 base::DictionaryValue* result_dict = NULL;
827 FilePath::StringType filename; 1115 FilePath::StringType filename;
828 bool is_incognito = false; 1116 bool is_incognito = false;
829 std::string error; 1117 std::string error;
830 std::string on_item_arg; 1118 std::string on_item_arg;
831 std::string off_item_arg; 1119 std::string off_item_arg;
832 std::string result_string; 1120 std::string result_string;
833 1121
834 // Set up one on-record item and one off-record item. 1122 // Set up one on-record item and one off-record item.
1123 GoOffTheRecord();
1124 DownloadItem* off_item = CreateSlowTestDownload();
1125 ASSERT_TRUE(off_item);
1126 ASSERT_TRUE(off_item->IsOtr());
1127 off_item_arg = DownloadItemIdAsArgList(off_item);
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 Why reverse the order? Any particular reason? If
benjhayden 2012/06/19 15:01:59 Done.
835 1128
836 GoOnTheRecord(); 1129 GoOnTheRecord();
837 DownloadItem* on_item = CreateSlowTestDownload(); 1130 DownloadItem* on_item = CreateSlowTestDownload();
838 ASSERT_TRUE(on_item); 1131 ASSERT_TRUE(on_item);
839 ASSERT_FALSE(on_item->IsOtr()); 1132 ASSERT_FALSE(on_item->IsOtr());
840 on_item_arg = DownloadItemIdAsArgList(on_item); 1133 on_item_arg = DownloadItemIdAsArgList(on_item);
841
842 GoOffTheRecord();
843 DownloadItem* off_item = CreateSlowTestDownload();
844 ASSERT_TRUE(off_item);
845 ASSERT_TRUE(off_item->IsOtr());
846 ASSERT_TRUE(on_item->GetFullPath() != off_item->GetFullPath()); 1134 ASSERT_TRUE(on_item->GetFullPath() != off_item->GetFullPath());
847 off_item_arg = DownloadItemIdAsArgList(off_item);
848 1135
849 // Extensions running in the incognito window should have access to both 1136 // Extensions running in the incognito window should have access to both
850 // items because the Test extension is in spanning mode. 1137 // items because the Test extension is in spanning mode.
1138 GoOffTheRecord();
851 result_value.reset(RunFunctionAndReturnResult( 1139 result_value.reset(RunFunctionAndReturnResult(
852 new DownloadsSearchFunction(), "[{}]")); 1140 new DownloadsSearchFunction(), "[{}]"));
853 ASSERT_TRUE(result_value.get()); 1141 ASSERT_TRUE(result_value.get());
854 ASSERT_TRUE(result_value->GetAsList(&result_list)); 1142 ASSERT_TRUE(result_value->GetAsList(&result_list));
855 ASSERT_EQ(2UL, result_list->GetSize()); 1143 ASSERT_EQ(2UL, result_list->GetSize());
856 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict)); 1144 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict));
857 ASSERT_TRUE(result_dict->GetString("filename", &filename)); 1145 ASSERT_TRUE(result_dict->GetString("filename", &filename));
858 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito)); 1146 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
859 EXPECT_TRUE(on_item->GetFullPath() == FilePath(filename)); 1147 EXPECT_TRUE(on_item->GetFullPath() == FilePath(filename));
860 EXPECT_FALSE(is_incognito); 1148 EXPECT_FALSE(is_incognito);
(...skipping 25 matching lines...) Expand all
886 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), 1174 error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
887 off_item_arg); 1175 off_item_arg);
888 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 1176 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
889 error.c_str()); 1177 error.c_str());
890 error = RunFunctionAndReturnError( 1178 error = RunFunctionAndReturnError(
891 new DownloadsGetFileIconFunction(), 1179 new DownloadsGetFileIconFunction(),
892 base::StringPrintf("[%d, {}]", off_item->GetId())); 1180 base::StringPrintf("[%d, {}]", off_item->GetId()));
893 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 1181 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
894 error.c_str()); 1182 error.c_str());
895 1183
896 // TODO(benjhayden): Test incognito_split_mode() extension.
897 // TODO(benjhayden): Test download(), onCreated, onChanged, onErased.
898
899 GoOffTheRecord(); 1184 GoOffTheRecord();
900 1185
901 // Do the FileIcon test for both the on- and off-items while off the record. 1186 // Do the FileIcon test for both the on- and off-items while off the record.
902 // NOTE(benjhayden): This does not include the FileIcon test from history, 1187 // NOTE(benjhayden): This does not include the FileIcon test from history,
903 // just active downloads. This shouldn't be a problem. 1188 // just active downloads. This shouldn't be a problem.
904 EXPECT_TRUE(RunFunctionAndReturnString( 1189 EXPECT_TRUE(RunFunctionAndReturnString(
905 new DownloadsGetFileIconFunction(), 1190 new DownloadsGetFileIconFunction(),
906 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string)); 1191 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string));
907 EXPECT_TRUE(RunFunctionAndReturnString( 1192 EXPECT_TRUE(RunFunctionAndReturnString(
908 new DownloadsGetFileIconFunction(), 1193 new DownloadsGetFileIconFunction(),
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 EXPECT_TRUE(off_item->IsCancelled()); 1231 EXPECT_TRUE(off_item->IsCancelled());
947 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), 1232 error = RunFunctionAndReturnError(new DownloadsPauseFunction(),
948 off_item_arg); 1233 off_item_arg);
949 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 1234 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
950 error.c_str()); 1235 error.c_str());
951 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), 1236 error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
952 off_item_arg); 1237 off_item_arg);
953 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, 1238 EXPECT_STREQ(download_extension_errors::kInvalidOperationError,
954 error.c_str()); 1239 error.c_str());
955 } 1240 }
1241
1242 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1243 DownloadExtensionTest_DownloadsEventsListener) {
1244 // Test that DownloadsEventsListener times out quickly enough for an event
1245 // that isn't going to happen.
1246 ASSERT_FALSE(WaitFor(100, extension_event_names::kOnDownloadErased, "-1"));
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 What is this actually testing? Just that 100 != i
benjhayden 2012/06/19 15:01:59 This is actually testing that DownloadsEventsListe
Randy Smith (Not in Mondays) 2012/06/19 19:23:23 What you look to be testing is that WaitFor(100, .
benjhayden 2012/06/21 17:50:48 The test doesn't use the timeout, and I can always
1247 }
1248
1249 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1250 DownloadExtensionTest_Download_Basic) {
1251 LoadExtension("downloads_split");
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 What does this do/what is it for? Some documentat
benjhayden 2012/06/19 15:01:59 Done.
Randy Smith (Not in Mondays) 2012/06/19 19:23:23 As discussed, maybe a comment in the downloads_spl
benjhayden 2012/06/21 17:50:48 Done.
1252 CHECK(StartTestServer());
1253 std::string download_url = GetURL("slow?0");
1254 GoOnTheRecord();
1255 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1256 new DownloadsDownloadFunction(), base::StringPrintf(
1257 "[{\"url\": \"%s\"}]", download_url.c_str())));
1258 ASSERT_TRUE(result.get());
1259 int result_id = -1;
1260 ASSERT_TRUE(result->GetAsInteger(&result_id));
1261 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1262 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1263 ASSERT_TRUE(item);
1264 ScopedCancellingItem canceller(item);
1265 ASSERT_EQ(download_url, item->GetURL().spec());
1266 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 Doesn't this result in a hung test if the event ne
benjhayden 2012/06/19 15:01:59 Yep. See my new comments on kTimeOutMs.
1267 base::StringPrintf("[{\"danger\": \"safe\","
1268 " \"filename\": \"%s\","
1269 " \"incognito\": false,"
1270 " \"mime\": \"text/plain\","
1271 " \"paused\": false,"
1272 " \"url\": \"%s\"}]",
1273 GetFilename("slow.txt.crdownload").c_str(),
1274 download_url.c_str())));
1275 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1276 base::StringPrintf("[{\"id\": %d,"
1277 " \"filename\": {"
1278 " \"old\": \"%s\","
1279 " \"new\": \"%s\"},"
1280 " \"state\": {"
1281 " \"old\": \"in_progress\","
1282 " \"new\": \"complete\"}}]",
1283 result_id,
1284 GetFilename("slow.txt.crdownload").c_str(),
1285 GetFilename("slow.txt").c_str())));
1286 }
1287
1288 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1289 DownloadExtensionTest_Download_Incognito) {
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 If you're testing incognito, shouldn't part of tha
benjhayden 2012/06/19 15:01:59 That's tested in SearchIncognito.
1290 LoadExtension("downloads_split");
1291 CHECK(StartTestServer());
1292 GoOffTheRecord();
1293 std::string download_url = GetURL("slow?0");
1294 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1295 new DownloadsDownloadFunction(), base::StringPrintf(
1296 "[{\"url\": \"%s\"}]", download_url.c_str())));
1297 ASSERT_TRUE(result.get());
1298 int result_id = -1;
1299 ASSERT_TRUE(result->GetAsInteger(&result_id));
1300 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1301 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1302 ASSERT_TRUE(item);
1303 ScopedCancellingItem canceller(item);
1304 ASSERT_EQ(download_url, item->GetURL().spec());
1305 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1306 base::StringPrintf("[{\"danger\": \"safe\","
1307 " \"filename\": \"%s\","
1308 " \"incognito\": true,"
1309 " \"mime\": \"text/plain\","
1310 " \"paused\": false,"
1311 " \"url\": \"%s\"}]",
1312 GetFilename("slow.txt.crdownload").c_str(),
1313 download_url.c_str())));
1314 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1315 base::StringPrintf("[{\"id\":%d,"
1316 " \"filename\": {"
1317 " \"old\": \"%s\","
1318 " \"new\": \"%s\"},"
1319 " \"state\": {"
1320 " \"new\": \"complete\","
1321 " \"old\": \"in_progress\"}}]",
1322 result_id,
1323 GetFilename("slow.txt.crdownload").c_str(),
1324 GetFilename("slow.txt").c_str())));
1325 }
1326
1327 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1328 DownloadExtensionTest_Download_UnsafeHeaders) {
1329 LoadExtension("downloads_split");
1330 CHECK(StartTestServer());
1331 GoOnTheRecord();
1332 // Test that we disallow certain headers case-insensitive.
1333 static const char* kUnsafeHeaders[] = {
1334 "Accept-chArsEt",
1335 "accept-eNcoding",
1336 "coNNection",
1337 "coNteNt-leNgth",
1338 "cooKIE",
1339 "cOOkie2",
1340 "coNteNt-traNsfer-eNcodiNg",
1341 "dAtE",
1342 "ExpEcT",
1343 "hOsT",
1344 "kEEp-aLivE",
1345 "rEfErEr",
1346 "tE",
1347 "trAilER",
1348 "trANsfer-eNcodiNg",
1349 "upGRAde",
1350 "usER-agENt",
1351 "viA",
1352 "pRoxY-",
1353 "sEc-",
1354 "pRoxY-probably-not-evil",
1355 "sEc-probably-not-evil",
1356 "oRiGiN",
1357 "Access-Control-Request-Headers",
1358 "Access-Control-Request-Method",
1359 };
1360 for (size_t index = 0; index < arraysize(kUnsafeHeaders); ++index) {
1361 std::string download_url = GetURL("slow?0");
1362 EXPECT_STREQ(download_extension_errors::kGenericError,
1363 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1364 base::StringPrintf(
1365 "[{\"url\": \"%s\","
1366 " \"filename\": \"unsafe-header-%lu.txt\","
1367 " \"headers\": [{"
1368 " \"name\": \"%s\","
1369 " \"value\": \"unsafe\"}]}]",
1370 download_url.c_str(), index, kUnsafeHeaders[index])).c_str());
1371 }
1372 }
1373
1374 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1375 DownloadExtensionTest_Download_Subdirectory) {
1376 LoadExtension("downloads_split");
1377 CHECK(StartTestServer());
1378 // Test that subdirectories (slashes) are disallowed in filenames.
1379 // TODO(benjhayden) Update this when subdirectories are supported.
1380 std::string download_url = GetURL("slow?0");
1381 GoOnTheRecord();
1382 EXPECT_STREQ(download_extension_errors::kGenericError,
1383 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1384 base::StringPrintf(
1385 "[{\"url\": \"%s\","
1386 " \"filename\": \"sub/dir/ect/ory.txt\"}]",
1387 download_url.c_str())).c_str());
1388 }
1389
1390 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1391 DownloadExtensionTest_Download_InvalidFilename) {
1392 LoadExtension("downloads_split");
1393 CHECK(StartTestServer());
1394 // Test that invalid filenames are disallowed.
1395 std::string download_url = GetURL("slow?0");
1396 GoOnTheRecord();
1397 EXPECT_STREQ(download_extension_errors::kGenericError,
1398 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1399 base::StringPrintf(
1400 "[{\"url\": \"%s\","
1401 " \"filename\": \"../../../../../etc/passwd\"}]",
1402 download_url.c_str())).c_str());
1403 }
1404
1405 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1406 DownloadExtensionTest_Download_InvalidURLs) {
1407 LoadExtension("downloads_split");
1408 GoOnTheRecord();
1409 static const char* kInvalidURLs[] = {
1410 "foo bar",
1411 "../hello",
1412 "/hello",
1413 "google.com/",
1414 "http://",
1415 "#frag",
1416 "foo/bar.html#frag",
1417 "javascript:document.write(\\\"hello\\\");",
1418 "javascript:return false;",
1419 "ftp://example.com/example.txt",
1420 };
1421 for (size_t index = 0; index < arraysize(kInvalidURLs); ++index) {
1422 EXPECT_STREQ(download_extension_errors::kInvalidURLError,
1423 RunFunctionAndReturnError(new DownloadsDownloadFunction(),
1424 base::StringPrintf(
1425 "[{\"url\": \"%s\"}]", kInvalidURLs[index])).c_str());
1426 }
1427 }
1428
1429 // TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to
1430 // permissions, test downloading from ftp.
1431
1432 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1433 DownloadExtensionTest_Download_URLFragment) {
1434 LoadExtension("downloads_split");
1435 CHECK(StartTestServer());
1436 // Valid URLs plus fragments are still valid URLs.
1437 std::string download_url = GetURL("slow?0#fragment");
1438 GoOnTheRecord();
1439 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1440 new DownloadsDownloadFunction(), base::StringPrintf(
1441 "[{\"url\": \"%s\"}]", download_url.c_str())));
1442 ASSERT_TRUE(result.get());
1443 int result_id = -1;
1444 ASSERT_TRUE(result->GetAsInteger(&result_id));
1445 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1446 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1447 ASSERT_TRUE(item);
1448 ScopedCancellingItem canceller(item);
1449 ASSERT_EQ(download_url, item->GetURL().spec());
1450 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1451 base::StringPrintf("[{\"danger\": \"safe\","
1452 " \"filename\": \"%s\","
1453 " \"incognito\": false,"
1454 " \"mime\": \"text/plain\","
1455 " \"paused\": false,"
1456 " \"url\": \"%s\"}]",
1457 GetFilename("slow.txt.crdownload").c_str(),
1458 download_url.c_str())));
1459 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1460 base::StringPrintf("[{\"id\": %d,"
1461 " \"filename\": {"
1462 " \"old\": \"%s\","
1463 " \"new\": \"%s\"},"
1464 " \"state\": {"
1465 " \"old\": \"in_progress\","
1466 " \"new\": \"complete\"}}]",
1467 result_id,
1468 GetFilename("slow.txt.crdownload").c_str(),
1469 GetFilename("slow.txt").c_str())));
1470 }
1471
1472 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1473 DownloadExtensionTest_Download_DataURL) {
1474 LoadExtension("downloads_split");
1475 CHECK(StartTestServer());
1476 std::string download_url = "data:text/plain,hello";
1477 GoOnTheRecord();
1478 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1479 new DownloadsDownloadFunction(), base::StringPrintf(
1480 "[{\"url\": \"%s\","
1481 " \"filename\": \"data.txt\"}]", download_url.c_str())));
1482 ASSERT_TRUE(result.get());
1483 int result_id = -1;
1484 ASSERT_TRUE(result->GetAsInteger(&result_id));
1485 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1486 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1487 ASSERT_TRUE(item);
1488 ScopedCancellingItem canceller(item);
1489 ASSERT_EQ(download_url, item->GetURL().spec());
1490 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1491 base::StringPrintf("[{\"danger\": \"safe\","
1492 " \"filename\": \"%s\","
1493 " \"incognito\": false,"
1494 " \"mime\": \"text/plain\","
1495 " \"paused\": false,"
1496 " \"url\": \"%s\"}]",
1497 GetFilename("data.txt.crdownload").c_str(),
1498 download_url.c_str())));
1499 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1500 base::StringPrintf("[{\"id\": %d,"
1501 " \"filename\": {"
1502 " \"old\": \"%s\","
1503 " \"new\": \"%s\"},"
1504 " \"state\": {"
1505 " \"old\": \"in_progress\","
1506 " \"new\": \"complete\"}}]",
1507 result_id,
1508 GetFilename("data.txt.crdownload").c_str(),
1509 GetFilename("data.txt").c_str())));
1510 }
1511
1512 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1513 DownloadExtensionTest_Download_File) {
1514 LoadExtension("downloads_split");
1515 CHECK(StartTestServer());
1516 // Valid file URLs are valid URLs.
1517 std::string download_url = "file:///";
1518 GoOnTheRecord();
1519 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1520 new DownloadsDownloadFunction(), base::StringPrintf(
1521 "[{\"url\": \"%s\","
1522 " \"filename\": \"file.txt\"}]", download_url.c_str())));
1523 ASSERT_TRUE(result.get());
1524 int result_id = -1;
1525 ASSERT_TRUE(result->GetAsInteger(&result_id));
1526 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1527 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1528 ASSERT_TRUE(item);
1529 ScopedCancellingItem canceller(item);
1530 #if defined(OS_WIN)
1531 download_url += "/";
1532 #endif
1533 ASSERT_EQ(download_url, item->GetURL().spec());
1534 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1535 base::StringPrintf("[{\"danger\": \"safe\","
1536 " \"filename\": \"%s\","
1537 " \"incognito\": false,"
1538 " \"mime\": \"text/html\","
1539 " \"paused\": false,"
1540 " \"url\": \"%s\"}]",
1541 GetFilename("file.txt.crdownload").c_str(),
1542 download_url.c_str())));
1543 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1544 base::StringPrintf("[{\"id\": %d,"
1545 " \"filename\": {"
1546 " \"old\": \"%s\","
1547 " \"new\": \"%s\"},"
1548 " \"state\": {"
1549 " \"old\": \"in_progress\","
1550 " \"new\": \"complete\"}}]",
1551 result_id,
1552 GetFilename("file.txt.crdownload").c_str(),
1553 GetFilename("file.txt").c_str())));
1554 }
1555
1556 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1557 DownloadExtensionTest_Download_AuthBasic_Fail) {
1558 LoadExtension("downloads_split");
1559 CHECK(StartTestServer());
1560 std::string download_url = GetURL("auth-basic");
1561 GoOnTheRecord();
1562 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1563 new DownloadsDownloadFunction(), base::StringPrintf(
1564 "[{\"url\": \"%s\","
1565 " \"filename\": \"auth-basic-fail.txt\"}]",
1566 download_url.c_str())));
1567 ASSERT_TRUE(result.get());
1568 int result_id = -1;
1569 ASSERT_TRUE(result->GetAsInteger(&result_id));
1570 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1571 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1572 ASSERT_TRUE(item);
1573 ScopedCancellingItem canceller(item);
1574 ASSERT_EQ(download_url, item->GetURL().spec());
1575 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1576 base::StringPrintf("[{\"danger\": \"safe\","
1577 " \"incognito\": false,"
1578 " \"mime\": \"text/html\","
1579 " \"paused\": false,"
1580 " \"url\": \"%s\"}]",
1581 download_url.c_str())));
1582 // The item may or may not be interrupted before the onCreated event fires.
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 I'd add an explanatory line here or below (that in
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 Also, this pattern seems to occur repeatedly in th
benjhayden 2012/06/19 15:01:59 Done.
benjhayden 2012/06/19 15:01:59 Done.
1583 static const int kExpectedError = 30;
1584 if (item->IsInterrupted()) {
1585 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1586 base::StringPrintf("[{\"danger\": \"safe\","
1587 " \"incognito\": false,"
1588 " \"mime\": \"text/html\","
1589 " \"paused\": false,"
1590 " \"state\": \"interrupted\","
1591 " \"error\": %d,"
1592 " \"url\": \"%s\"}]",
1593 kExpectedError,
1594 download_url.c_str())));
1595 } else {
1596 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1597 base::StringPrintf("[{\"id\": %d,"
1598 " \"error\": {\"new\": 30},"
1599 " \"state\":{"
1600 " \"old\": \"in_progress\","
1601 " \"new\":\"interrupted\"}}]",
1602 result_id)));
1603 }
1604 }
1605
1606 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1607 DownloadExtensionTest_Download_Headers) {
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 It looks like this test is only testing that the s
benjhayden 2012/06/19 15:01:59 The test server verifies the expected_headers, and
1608 LoadExtension("downloads_split");
1609 CHECK(StartTestServer());
1610 // Test the |header| download option.
1611 std::string download_url = GetURL("files/downloads/a_zip_file.zip?"
1612 "expected_headers=Foo:bar&expected_headers=Qx:yo");
1613 GoOnTheRecord();
1614 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1615 new DownloadsDownloadFunction(), base::StringPrintf(
1616 "[{\"url\": \"%s\","
1617 " \"filename\": \"headers-succeed.txt\","
1618 " \"headers\": ["
1619 " {\"name\": \"Foo\", \"value\": \"bar\"},"
1620 " {\"name\": \"Qx\", \"value\":\"yo\"}]}]",
1621 download_url.c_str())));
1622 ASSERT_TRUE(result.get());
1623 int result_id = -1;
1624 ASSERT_TRUE(result->GetAsInteger(&result_id));
1625 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1626 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1627 ASSERT_TRUE(item);
1628 ScopedCancellingItem canceller(item);
1629 ASSERT_EQ(download_url, item->GetURL().spec());
1630 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1631 base::StringPrintf("[{\"danger\": \"safe\","
1632 " \"incognito\": false,"
1633 " \"mime\": \"application/octet-stream\","
1634 " \"paused\": false,"
1635 " \"url\": \"%s\"}]",
1636 download_url.c_str())));
1637 std::string incomplete_filename = GetFilename(
1638 "headers-succeed.txt.crdownload");
1639 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1640 base::StringPrintf("[{\"id\": %d,"
1641 " \"filename\": {"
1642 " \"old\": \"%s\","
1643 " \"new\": \"%s\"},"
1644 " \"state\": {"
1645 " \"old\": \"in_progress\","
1646 " \"new\": \"complete\"}}]",
1647 result_id,
1648 incomplete_filename.c_str(),
1649 GetFilename("headers-succeed.txt").c_str())));
1650 }
1651
1652 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 I think it's generally a good idea to have a line
benjhayden 2012/06/19 15:01:59 Done.
1653 DownloadExtensionTest_Download_Headers_Fail) {
1654 LoadExtension("downloads_split");
1655 CHECK(StartTestServer());
1656 // Test that headers-succeed would fail if the resource requires the headers
1657 // and chrome fails to propagate them back to the server. This tests both
1658 // that testserver.py does not succeed when it should fail as well as how
1659 // the downloads extension api exposes the failure to extensions.
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 As well as that the api really does propagate the
benjhayden 2012/06/19 15:01:59 No, that's tested by DownloadExtensionTest_Downloa
1660 std::string download_url = GetURL("files/downloads/a_zip_file.zip?"
1661 "expected_headers=Foo:bar&expected_headers=Qx:yo");
1662 static const int kExpectedError = 33;
1663 GoOnTheRecord();
1664 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1665 new DownloadsDownloadFunction(), base::StringPrintf(
1666 "[{\"url\": \"%s\","
1667 " \"filename\": \"headers-fail.txt\"}]",
1668 download_url.c_str())));
1669 ASSERT_TRUE(result.get());
1670 int result_id = -1;
1671 ASSERT_TRUE(result->GetAsInteger(&result_id));
1672 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1673 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1674 ASSERT_TRUE(item);
1675 ScopedCancellingItem canceller(item);
1676 ASSERT_EQ(download_url, item->GetURL().spec());
1677 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1678 base::StringPrintf("[{\"danger\": \"safe\","
1679 " \"incognito\": false,"
1680 " \"bytesReceived\": 0,"
1681 " \"mime\": \"\","
1682 " \"paused\": false,"
1683 " \"url\": \"%s\"}]", download_url.c_str())));
1684 if (item->IsInterrupted()) {
1685 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1686 base::StringPrintf("[{\"danger\": \"safe\","
1687 " \"incognito\": false,"
1688 " \"bytesReceived\": 0,"
1689 " \"mime\": \"\","
1690 " \"paused\": false,"
1691 " \"id\": %d,"
1692 " \"state\": \"interrupted\","
1693 " \"error\": %d,"
1694 " \"url\": \"%s\"}]",
1695 result_id,
1696 kExpectedError,
1697 download_url.c_str())));
1698 } else {
1699 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1700 base::StringPrintf("[{\"id\": %d,"
1701 " \"error\": {\"new\": %d},"
1702 " \"state\": {"
1703 " \"old\": \"in_progress\","
1704 " \"new\": \"interrupted\"}}]",
1705 result_id,
1706 kExpectedError)));
1707 }
1708 }
1709
1710 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1711 DownloadExtensionTest_Download_AuthBasic) {
1712 LoadExtension("downloads_split");
1713 CHECK(StartTestServer());
1714 std::string download_url = GetURL("auth-basic");
1715 // This is just base64 of 'username:secret'.
1716 static const char* kAuthorization = "dXNlcm5hbWU6c2VjcmV0";
1717 GoOnTheRecord();
1718 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1719 new DownloadsDownloadFunction(), base::StringPrintf(
1720 "[{\"url\": \"%s\","
1721 " \"filename\": \"auth-basic-succeed.txt\","
1722 " \"headers\": [{"
1723 " \"name\": \"Authorization\","
1724 " \"value\": \"Basic %s\"}]}]",
1725 download_url.c_str(), kAuthorization)));
1726 ASSERT_TRUE(result.get());
1727 int result_id = -1;
1728 ASSERT_TRUE(result->GetAsInteger(&result_id));
1729 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1730 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1731 ASSERT_TRUE(item);
1732 ScopedCancellingItem canceller(item);
1733 ASSERT_EQ(download_url, item->GetURL().spec());
1734 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1735 base::StringPrintf("[{\"danger\": \"safe\","
1736 " \"incognito\": false,"
1737 " \"mime\": \"text/html\","
1738 " \"paused\": false,"
1739 " \"url\": \"%s\"}]", download_url.c_str())));
1740 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1741 base::StringPrintf("[{\"id\": %d,"
1742 " \"state\": {"
1743 " \"old\": \"in_progress\","
1744 " \"new\": \"complete\"}}]", result_id)));
1745 }
1746
1747 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1748 DownloadExtensionTest_Download_Post) {
1749 LoadExtension("downloads_split");
1750 CHECK(StartTestServer());
1751 std::string download_url = GetURL("files/post/downloads/a_zip_file.zip?"
1752 "expected_body=BODY");
1753 GoOnTheRecord();
1754 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1755 new DownloadsDownloadFunction(), base::StringPrintf(
1756 "[{\"url\": \"%s\","
1757 " \"filename\": \"post-succeed.txt\","
1758 " \"method\": \"POST\","
1759 " \"body\": \"BODY\"}]",
1760 download_url.c_str())));
1761 ASSERT_TRUE(result.get());
1762 int result_id = -1;
1763 ASSERT_TRUE(result->GetAsInteger(&result_id));
1764 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1765 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1766 ASSERT_TRUE(item);
1767 ScopedCancellingItem canceller(item);
1768 ASSERT_EQ(download_url, item->GetURL().spec());
1769 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1770 base::StringPrintf("[{\"danger\": \"safe\","
1771 " \"incognito\": false,"
1772 " \"mime\": \"application/octet-stream\","
1773 " \"paused\": false,"
1774 " \"bytesReceived\": 164,"
1775 " \"url\": \"%s\"}]", download_url.c_str())));
1776 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1777 base::StringPrintf("[{\"id\": %d,"
1778 " \"state\": {"
1779 " \"old\": \"in_progress\","
1780 " \"new\": \"complete\"}}]", result_id)));
1781 }
1782
1783 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1784 DownloadExtensionTest_Download_Post_Get) {
1785 LoadExtension("downloads_split");
1786 CHECK(StartTestServer());
1787 // Test that downloadPostSuccess would fail if the resource requires the
1788 // POST method, and chrome fails to propagate the |method| parameter back to
1789 // the server. This tests both that testserver.py does not succeed when it
1790 // should fail, and this tests how the downloads extension api exposes the
1791 // failure to extensions.
1792 std::string download_url = GetURL("files/post/downloads/a_zip_file.zip?"
1793 "expected_body=BODY");
1794 GoOnTheRecord();
1795 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1796 new DownloadsDownloadFunction(), base::StringPrintf(
1797 "[{\"url\": \"%s\","
1798 " \"body\": \"BODY\","
1799 " \"filename\": \"post-get.txt\"}]",
1800 download_url.c_str())));
1801 ASSERT_TRUE(result.get());
1802 int result_id = -1;
1803 ASSERT_TRUE(result->GetAsInteger(&result_id));
1804 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1805 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1806 ASSERT_TRUE(item);
1807 ScopedCancellingItem canceller(item);
1808 ASSERT_EQ(download_url, item->GetURL().spec());
1809 static const int kExpectedError = 33;
1810 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1811 base::StringPrintf("[{\"danger\": \"safe\","
1812 " \"incognito\": false,"
1813 " \"mime\": \"\","
1814 " \"paused\": false,"
1815 " \"id\": %d,"
1816 " \"url\": \"%s\"}]",
1817 result_id,
1818 download_url.c_str())));
1819 if (item->IsInterrupted()) {
1820 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1821 base::StringPrintf("[{\"danger\": \"safe\","
1822 " \"incognito\": false,"
1823 " \"mime\": \"\","
1824 " \"paused\": false,"
1825 " \"id\": %d,"
1826 " \"state\": \"interrupted\","
1827 " \"error\": %d,"
1828 " \"url\": \"%s\"}]",
1829 result_id,
1830 kExpectedError,
1831 download_url.c_str())));
1832 } else {
1833 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1834 base::StringPrintf("[{\"id\": %d,"
1835 " \"error\": {\"new\": %d},"
1836 " \"state\": {"
1837 " \"old\": \"in_progress\","
1838 " \"new\": \"interrupted\"}}]",
1839 result_id,
1840 kExpectedError)));
1841 }
1842 }
1843
1844 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1845 DownloadExtensionTest_Download_Post_NoBody) {
1846 LoadExtension("downloads_split");
1847 CHECK(StartTestServer());
1848 // Test that downloadPostSuccess would fail if the resource requires the
1849 // POST method, and chrome fails to propagate the |body| parameter back to
1850 // the server. This tests both that testserver.py does not succeed when it
1851 // should fail, and this tests how the downloads extension api exposes the
1852 // failure to extensions.
1853 std::string download_url = GetURL("files/post/downloads/a_zip_file.zip?"
1854 "expected_body=BODY");
1855 GoOnTheRecord();
1856 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1857 new DownloadsDownloadFunction(), base::StringPrintf(
1858 "[{\"url\": \"%s\","
1859 " \"method\": \"POST\","
1860 " \"filename\": \"post-nobody.txt\"}]",
1861 download_url.c_str())));
1862 ASSERT_TRUE(result.get());
1863 int result_id = -1;
1864 ASSERT_TRUE(result->GetAsInteger(&result_id));
1865 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1866 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1867 ASSERT_TRUE(item);
1868 ScopedCancellingItem canceller(item);
1869 ASSERT_EQ(download_url, item->GetURL().spec());
1870 static const int kExpectedError = 33;
1871 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1872 base::StringPrintf("[{\"danger\": \"safe\","
1873 " \"incognito\": false,"
1874 " \"mime\": \"\","
1875 " \"paused\": false,"
1876 " \"id\": %d,"
1877 " \"url\": \"%s\"}]",
1878 result_id,
1879 download_url.c_str())));
1880 if (item->IsInterrupted()) {
1881 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1882 base::StringPrintf("[{\"danger\": \"safe\","
1883 " \"incognito\": false,"
1884 " \"mime\": \"\","
1885 " \"paused\": false,"
1886 " \"id\": %d,"
1887 " \"state\": \"interrupted\","
1888 " \"error\": %d,"
1889 " \"url\": \"%s\"}]",
1890 result_id,
1891 kExpectedError,
1892 download_url.c_str())));
1893 } else {
1894 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1895 base::StringPrintf("[{\"id\": %d,"
1896 " \"error\": {\"new\": %d},"
1897 " \"state\": {"
1898 " \"old\": \"in_progress\","
1899 " \"new\": \"interrupted\"}}]",
1900 result_id,
1901 kExpectedError)));
1902 }
1903 }
1904
1905 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1906 DownloadExtensionTest_Download_Cancel) {
1907 LoadExtension("downloads_split");
1908 CHECK(StartTestServer());
1909 // Test that cancel()ing an in-progress download causes its state to
1910 // transition to interrupted, and test that that state transition is
1911 // detectable by an onChanged event listener. TODO(benjhayden): Test other
1912 // sources of interruptions such as server death.
1913 std::string download_url = GetURL("download-known-size");
1914 GoOnTheRecord();
1915 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1916 new DownloadsDownloadFunction(), base::StringPrintf(
1917 "[{\"url\": \"%s\"}]", download_url.c_str())));
1918 ASSERT_TRUE(result.get());
1919 int result_id = -1;
1920 ASSERT_TRUE(result->GetAsInteger(&result_id));
1921 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1922 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1923 ASSERT_TRUE(item);
1924 ScopedCancellingItem canceller(item);
1925 ASSERT_EQ(download_url, item->GetURL().spec());
1926 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1927 base::StringPrintf("[{\"danger\": \"safe\","
1928 " \"incognito\": false,"
1929 " \"mime\": \"application/octet-stream\","
1930 " \"paused\": false,"
1931 " \"id\": %d,"
1932 " \"url\": \"%s\"}]",
1933 result_id,
1934 download_url.c_str())));
1935 item->Cancel(true);
1936 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1937 base::StringPrintf("[{\"id\": %d,"
1938 " \"error\": {\"new\": 40},"
1939 " \"state\": {"
1940 " \"old\": \"in_progress\","
1941 " \"new\": \"interrupted\"}}]",
1942 result_id)));
1943 }
1944
1945 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
1946 DownloadExtensionTest_Download_FileSystemURL) {
1947 LoadExtension("downloads_split");
1948 CHECK(StartTestServer());
1949 // Test downloading filesystem: URLs.
1950 // NOTE: chrome disallows creating HTML5 FileSystem Files in incognito.
Randy Smith (Not in Mondays) 2012/06/18 18:42:58 Should we test that?
benjhayden 2012/06/19 15:01:59 What would it buy to test that HTML5 Files are dis
Randy Smith (Not in Mondays) 2012/06/19 19:23:23 In a sorta vague fuzzy background way, yeah. I do
1951 std::string download_url = "filesystem:" + GetExtensionURL() +
1952 "temporary/on_record.txt";
1953 static const char* kHTML5FileCreated = "html5_file_created";
1954 GoOnTheRecord();
1955 fileapi::FileSystemContext* fs = BrowserContext::GetFileSystemContext(
1956 browser()->profile());
1957 base::Closure file_created = base::Bind(
1958 &DownloadExtensionTest::ObserveEvent,
1959 base::Unretained(this),
1960 browser()->profile(),
1961 kHTML5FileCreated,
1962 "on_record");
1963 fileapi::FileSystemContext::OpenFileSystemCallback fs_opened = base::Bind(
1964 &OpenFileSystemCallback,
1965 base::Unretained(fs),
1966 "on_record.txt",
1967 file_created);
1968 fs->OpenFileSystem(GURL(GetExtensionURL()),
1969 fileapi::kFileSystemTypeTemporary,
1970 true/*create*/,
1971 fs_opened);
1972 ASSERT_TRUE(WaitFor(kHTML5FileCreated, "on_record"));
1973 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
1974 new DownloadsDownloadFunction(), base::StringPrintf(
1975 "[{\"url\": \"%s\"}]", download_url.c_str())));
1976 ASSERT_TRUE(result.get());
1977 int result_id = -1;
1978 ASSERT_TRUE(result->GetAsInteger(&result_id));
1979 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id);
1980 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id);
1981 ASSERT_TRUE(item);
1982 ScopedCancellingItem canceller(item);
1983 ASSERT_EQ(download_url, item->GetURL().spec());
1984 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated,
1985 base::StringPrintf("[{\"danger\": \"safe\","
1986 " \"filename\": \"%s\","
1987 " \"incognito\": false,"
1988 " \"mime\": \"text/plain\","
1989 " \"paused\": false,"
1990 " \"url\": \"%s\"}]",
1991 GetFilename("on_record.txt.crdownload").c_str(),
1992 download_url.c_str())));
1993 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged,
1994 base::StringPrintf("[{\"id\": %d,"
1995 " \"filename\": {"
1996 " \"old\": \"%s\","
1997 " \"new\": \"%s\"},"
1998 " \"state\": {"
1999 " \"old\": \"in_progress\","
2000 " \"new\": \"complete\"}}]",
2001 result_id,
2002 GetFilename("on_record.txt.crdownload").c_str(),
2003 GetFilename("on_record.txt").c_str())));
2004 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698