Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 // If positive, WaitFor() gives up after this many milliseconds, figuring that | |
| 65 // the event it wants will never happen so that a failing test doesn't take | |
| 66 // too long to fail. If negative, WaitFor() never gives you up, never lets you | |
| 67 // down... The problem is that on very busy machines, the event can take more | |
| 68 // than a few seconds. On very very busy machines, it can take more than many | |
| 69 // seconds. I'd set it at 44 seconds, but there are multiple WaitFor()s per | |
| 70 // TEST_F. I could make it keep track of how long the current TEST_F has been | |
| 71 // running, but if a machine is so busy that a normally instantaneous event is | |
| 72 // taking half a minute, then this soft timeout mechanism probably won't work | |
| 73 // anyway. So this mechanism is really only good for debugging on otherwise | |
| 74 // unloaded machines. Maybe at some point I'll figure out a way to safely set | |
| 75 // this to a sensible number that it won't cause too many timeouts on the | |
| 76 // bots. | |
|
Randy Smith (Not in Mondays)
2012/06/19 19:23:23
This comment is targeted at the WaitFor() routine.
benjhayden
2012/06/21 17:50:48
Done.
| |
| 77 static const int kTimeOutMs = -1; | |
| 78 | |
| 79 DownloadsEventsListener() | |
| 80 : waiting_(false) { | |
| 81 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | |
| 82 content::NotificationService::AllSources()); | |
| 83 } | |
| 84 virtual ~DownloadsEventsListener() { | |
| 85 registrar_.Remove(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | |
| 86 content::NotificationService::AllSources()); | |
| 87 STLDeleteElements(&events_); | |
| 88 } | |
| 89 | |
| 90 class Event { | |
| 91 public: | |
| 92 Event(Profile* profile, | |
| 93 const std::string& event_name, | |
| 94 const std::string& json_args, | |
| 95 base::Time caught) | |
| 96 : profile_(profile), | |
| 97 event_name_(event_name), | |
| 98 json_args_(json_args), | |
| 99 args_(base::JSONReader::Read(json_args)), | |
| 100 caught_(caught) { | |
| 101 } | |
| 102 | |
| 103 const base::Time& caught() { return caught_; } | |
| 104 | |
| 105 bool Equals(const Event& other) { | |
| 106 if ((profile_ != other.profile_) || | |
| 107 (event_name_ != other.event_name_)) | |
| 108 return false; | |
| 109 if ((event_name_ == extension_event_names::kOnDownloadCreated || | |
| 110 event_name_ == extension_event_names::kOnDownloadChanged) && | |
| 111 args_.get() && | |
| 112 other.args_.get()) { | |
| 113 base::ListValue* left_list = NULL; | |
| 114 base::DictionaryValue* left_dict = NULL; | |
| 115 base::ListValue* right_list = NULL; | |
| 116 base::DictionaryValue* right_dict = NULL; | |
| 117 if (!args_->GetAsList(&left_list) || | |
| 118 !other.args_->GetAsList(&right_list) || | |
| 119 !left_list->GetDictionary(0, &left_dict) || | |
| 120 !right_list->GetDictionary(0, &right_dict)) | |
| 121 return false; | |
| 122 for (base::DictionaryValue::Iterator iter(*left_dict); | |
| 123 iter.HasNext(); iter.Advance()) { | |
| 124 base::Value* right_value = NULL; | |
| 125 if (right_dict->HasKey(iter.key()) && | |
| 126 right_dict->Get(iter.key(), &right_value) && | |
| 127 !iter.value().Equals(right_value)) { | |
| 128 return false; | |
| 129 } | |
| 130 } | |
| 131 return true; | |
| 132 } else if ((event_name_ == extension_event_names::kOnDownloadErased) && | |
| 133 args_.get() && | |
| 134 other.args_.get()) { | |
| 135 int my_id = -1, other_id = -1; | |
| 136 return (args_->GetAsInteger(&my_id) && | |
| 137 other.args_->GetAsInteger(&other_id) && | |
| 138 my_id == other_id); | |
| 139 } | |
| 140 return json_args_ == other.json_args_; | |
| 141 } | |
| 142 | |
| 143 std::string Debug() { | |
| 144 return base::StringPrintf("Event(%p, %s, %s, %f)", | |
| 145 profile_, | |
| 146 event_name_.c_str(), | |
| 147 json_args_.c_str(), | |
| 148 caught_.ToJsTime()); | |
| 149 } | |
| 150 | |
| 151 private: | |
| 152 Profile* profile_; | |
| 153 std::string event_name_; | |
| 154 std::string json_args_; | |
| 155 scoped_ptr<base::Value> args_; | |
| 156 base::Time caught_; | |
| 157 | |
| 158 DISALLOW_COPY_AND_ASSIGN(Event); | |
| 159 }; | |
| 160 | |
| 161 typedef ExtensionDownloadsEventRouter::DownloadsNotificationSource | |
| 162 DownloadsNotificationSource; | |
| 163 | |
| 164 void Observe(int type, const content::NotificationSource& source, | |
| 165 const content::NotificationDetails& details) { | |
| 166 switch (type) { | |
| 167 case chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT: | |
| 168 { | |
| 169 DownloadsNotificationSource* dns = | |
| 170 content::Source<DownloadsNotificationSource>(source).ptr(); | |
| 171 Event* new_event = new Event( | |
| 172 dns->profile, | |
| 173 dns->event_name, | |
| 174 *content::Details<std::string>(details).ptr(), base::Time::Now()); | |
| 175 events_.push_back(new_event); | |
| 176 if (waiting_ && | |
| 177 waiting_for_.get() && | |
| 178 waiting_for_->Equals(*new_event)) { | |
| 179 waiting_ = false; | |
| 180 MessageLoopForUI::current()->Quit(); | |
| 181 } | |
| 182 break; | |
| 183 } | |
| 184 default: | |
| 185 NOTREACHED(); | |
| 186 } | |
| 187 } | |
| 188 | |
| 189 bool WaitFor(int timeout_ms, | |
| 190 Profile* profile, | |
| 191 const std::string& event_name, | |
| 192 const std::string& json_args) { | |
| 193 waiting_for_.reset(new Event(profile, event_name, json_args, base::Time())); | |
| 194 for (std::deque<Event*>::const_iterator iter = events_.begin(); | |
| 195 iter != events_.end(); ++iter) { | |
| 196 if ((*iter)->Equals(*waiting_for_.get())) | |
| 197 return true; | |
| 198 } | |
| 199 waiting_ = true; | |
| 200 if (timeout_ms > 0) { | |
| 201 MessageLoop::current()->PostDelayedTask( | |
| 202 FROM_HERE, base::Bind( | |
| 203 &DownloadsEventsListener::TimedOut, base::Unretained(this)), | |
| 204 timeout_ms); | |
| 205 } | |
| 206 ui_test_utils::RunMessageLoop(); | |
| 207 bool success = !waiting_; | |
| 208 if (waiting_) { | |
| 209 // Print the events that were caught since the last WaitFor() call to help | |
| 210 // find the erroneous event. | |
| 211 // TODO(benjhayden) Fuzzy-match and highlight the erroneous event. | |
| 212 for (std::deque<Event*>::const_iterator iter = events_.begin(); | |
| 213 iter != events_.end(); ++iter) { | |
| 214 if ((*iter)->caught() > last_wait_) { | |
| 215 LOG(INFO) << "Caught " << (*iter)->Debug(); | |
| 216 } | |
| 217 } | |
| 218 if (waiting_for_.get()) { | |
| 219 LOG(INFO) << "Timed out waiting for " << waiting_for_->Debug(); | |
| 220 } | |
| 221 waiting_ = false; | |
| 222 } | |
| 223 waiting_for_.reset(); | |
| 224 last_wait_ = base::Time::Now(); | |
| 225 return success; | |
| 226 } | |
| 227 | |
| 228 bool WaitFor(Profile* profile, | |
| 229 const std::string& event_name, | |
| 230 const std::string& json_args) { | |
| 231 return WaitFor(kTimeOutMs, profile, event_name, json_args); | |
| 232 } | |
| 233 | |
| 234 private: | |
| 235 void TimedOut() { | |
| 236 if (!waiting_for_.get()) | |
| 237 return; | |
| 238 MessageLoopForUI::current()->Quit(); | |
| 239 } | |
| 240 | |
| 241 bool waiting_; | |
| 242 base::Time last_wait_; | |
| 243 scoped_ptr<Event> waiting_for_; | |
| 244 content::NotificationRegistrar registrar_; | |
| 245 std::deque<Event*> events_; | |
| 246 | |
| 247 DISALLOW_COPY_AND_ASSIGN(DownloadsEventsListener); | |
| 248 }; | |
| 249 | |
| 250 class DownloadExtensionTest : public ExtensionApiTest { | |
| 251 public: | |
| 252 DownloadExtensionTest() | |
| 253 : extension_(NULL), | |
| 254 incognito_browser_(NULL), | |
| 255 current_browser_(NULL) { | |
| 256 } | |
| 257 | |
| 48 protected: | 258 protected: |
| 49 // Used with CreateHistoryDownloads | 259 // Used with CreateHistoryDownloads |
| 50 struct HistoryDownloadInfo { | 260 struct HistoryDownloadInfo { |
| 51 // Filename to use. CreateHistoryDownloads will append this filename to the | 261 // Filename to use. CreateHistoryDownloads will append this filename to the |
| 52 // temporary downloads directory specified by downloads_directory(). | 262 // temporary downloads directory specified by downloads_directory(). |
| 53 const FilePath::CharType* filename; | 263 const FilePath::CharType* filename; |
| 54 | 264 |
| 55 // State for the download. Note that IN_PROGRESS downloads will be created | 265 // State for the download. Note that IN_PROGRESS downloads will be created |
| 56 // as CANCELLED. | 266 // as CANCELLED. |
| 57 DownloadItem::DownloadState state; | 267 DownloadItem::DownloadState state; |
| 58 | 268 |
| 59 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS | 269 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS |
| 60 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT. | 270 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT. |
| 61 content::DownloadDangerType danger_type; | 271 content::DownloadDangerType danger_type; |
| 62 }; | 272 }; |
| 63 | 273 |
| 64 virtual Browser* current_browser() { return browser(); } | 274 void LoadExtension(const char* name) { |
| 275 // Store the created Extension object so that we can attach it to | |
| 276 // ExtensionFunctions. Also load the extension in incognito profiles for | |
| 277 // testing incognito. | |
| 278 extension_ = LoadExtensionIncognito(test_data_dir_.AppendASCII(name)); | |
| 279 CHECK(extension_); | |
| 280 } | |
| 281 | |
| 282 Browser* current_browser() { return current_browser_; } | |
| 65 | 283 |
| 66 // InProcessBrowserTest | 284 // InProcessBrowserTest |
| 67 virtual void SetUpOnMainThread() OVERRIDE { | 285 virtual void SetUpOnMainThread() OVERRIDE { |
| 68 BrowserThread::PostTask( | 286 BrowserThread::PostTask( |
| 69 BrowserThread::IO, FROM_HERE, | 287 BrowserThread::IO, FROM_HERE, |
| 70 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); | 288 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); |
| 71 InProcessBrowserTest::SetUpOnMainThread(); | 289 InProcessBrowserTest::SetUpOnMainThread(); |
| 290 GoOnTheRecord(); | |
| 72 CreateAndSetDownloadsDirectory(); | 291 CreateAndSetDownloadsDirectory(); |
| 73 current_browser()->profile()->GetPrefs()->SetBoolean( | 292 current_browser()->profile()->GetPrefs()->SetBoolean( |
| 74 prefs::kPromptForDownload, false); | 293 prefs::kPromptForDownload, false); |
| 75 GetDownloadManager()->RemoveAllDownloads(); | 294 GetOnRecordManager()->RemoveAllDownloads(); |
| 295 events_listener_.reset(new DownloadsEventsListener()); | |
| 76 } | 296 } |
| 77 | 297 |
| 78 virtual DownloadManager* GetDownloadManager() { | 298 void GoOnTheRecord() { current_browser_ = browser(); } |
| 79 return BrowserContext::GetDownloadManager(current_browser()->profile()); | 299 |
| 300 void GoOffTheRecord() { | |
| 301 if (!incognito_browser_) { | |
| 302 incognito_browser_ = CreateIncognitoBrowser(); | |
| 303 GetOffRecordManager()->RemoveAllDownloads(); | |
| 304 } | |
| 305 current_browser_ = incognito_browser_; | |
| 306 } | |
| 307 | |
| 308 bool WaitFor(int timeout_ms, const std::string& event_name, | |
| 309 const std::string& json_args) { | |
| 310 return events_listener_->WaitFor( | |
| 311 timeout_ms, current_browser()->profile(), event_name, json_args); | |
| 312 } | |
| 313 | |
| 314 bool WaitFor(const std::string& event_name, const std::string& json_args) { | |
| 315 return events_listener_->WaitFor( | |
| 316 current_browser()->profile(), event_name, json_args); | |
| 317 } | |
| 318 | |
| 319 bool WaitForInterruption(DownloadItem* item, int expected_error, | |
| 320 const std::string& on_created_event) { | |
| 321 if (!WaitFor(extension_event_names::kOnDownloadCreated, on_created_event)) | |
| 322 return false; | |
| 323 // The item may or may not be interrupted before the onCreated event fires. | |
| 324 if (item->IsInterrupted()) { | |
| 325 scoped_ptr<base::Value> args(base::JSONReader::Read(on_created_event)); | |
| 326 base::ListValue* args_list = NULL; | |
| 327 base::DictionaryValue* args_dict = NULL; | |
| 328 if (!args->GetAsList(&args_list) || | |
| 329 !args_list->GetDictionary(0, &args_dict)) | |
| 330 return false; | |
| 331 args_dict->SetString("state", "interrupted"); | |
| 332 args_dict->SetInteger("error", expected_error); | |
| 333 std::string created_error; | |
| 334 base::JSONWriter::Write(args_list, &created_error); | |
| 335 // This is not waiting for a different event, it's refining the | |
| 336 // expectations on the onCreated event that was just caught. Specifically, | |
| 337 // if a DownloadItem is already interrupted by the time the onCreated | |
| 338 // event fires, then the onCreated event should already describe the | |
| 339 // error. | |
| 340 return WaitFor(extension_event_names::kOnDownloadCreated, created_error); | |
| 341 } else { | |
| 342 return WaitFor(extension_event_names::kOnDownloadChanged, | |
| 343 base::StringPrintf("[{\"id\": %d," | |
| 344 " \"error\": {\"new\": %d}," | |
| 345 " \"state\": {" | |
| 346 " \"old\": \"in_progress\"," | |
| 347 " \"new\": \"interrupted\"}}]", | |
| 348 item->GetId(), | |
| 349 expected_error)); | |
| 350 } | |
| 351 } | |
| 352 | |
| 353 std::string GetURL(const char* path) { | |
| 354 return test_server()->GetURL(path).spec(); | |
|
Randy Smith (Not in Mondays)
2012/06/19 19:23:23
Personal preference would be to expand this inline
benjhayden
2012/06/21 17:50:48
Done.
| |
| 355 } | |
| 356 | |
| 357 std::string GetExtensionURL() { | |
| 358 return extension_->url().spec(); | |
| 359 } | |
| 360 | |
| 361 std::string GetFilename(const char* path) { | |
| 362 return downloads_directory_.path().AppendASCII(path).AsUTF8Unsafe(); | |
| 363 } | |
| 364 | |
| 365 DownloadManager* GetOnRecordManager() { | |
| 366 return BrowserContext::GetDownloadManager(browser()->profile()); | |
| 367 } | |
| 368 DownloadManager* GetOffRecordManager() { | |
| 369 return BrowserContext::GetDownloadManager( | |
| 370 browser()->profile()->GetOffTheRecordProfile()); | |
| 371 } | |
| 372 DownloadManager* GetCurrentManager() { | |
| 373 return (current_browser_ == incognito_browser_) ? | |
| 374 GetOffRecordManager() : GetOnRecordManager(); | |
| 80 } | 375 } |
| 81 | 376 |
| 82 // Creates a set of history downloads based on the provided |history_info| | 377 // 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, | 378 // array. |count| is the number of elements in |history_info|. On success, |
| 84 // |items| will contain |count| DownloadItems in the order that they were | 379 // |items| will contain |count| DownloadItems in the order that they were |
| 85 // specified in |history_info|. Returns true on success and false otherwise. | 380 // specified in |history_info|. Returns true on success and false otherwise. |
| 86 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info, | 381 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info, |
| 87 size_t count, | 382 size_t count, |
| 88 DownloadManager::DownloadVector* items) { | 383 DownloadManager::DownloadVector* items) { |
| 89 DownloadIdComparator download_id_comparator; | 384 DownloadIdComparator download_id_comparator; |
| 90 base::Time current = base::Time::Now(); | 385 base::Time current = base::Time::Now(); |
| 91 std::vector<DownloadPersistentStoreInfo> entries; | 386 std::vector<DownloadPersistentStoreInfo> entries; |
| 92 entries.reserve(count); | 387 entries.reserve(count); |
| 93 for (size_t i = 0; i < count; ++i) { | 388 for (size_t i = 0; i < count; ++i) { |
| 94 DownloadPersistentStoreInfo entry( | 389 DownloadPersistentStoreInfo entry( |
| 95 downloads_directory().Append(history_info[i].filename), | 390 downloads_directory().Append(history_info[i].filename), |
| 96 GURL(), GURL(), // URL, referrer | 391 GURL(), GURL(), // URL, referrer |
| 97 current, current, // start_time, end_time | 392 current, current, // start_time, end_time |
| 98 1, 1, // received_bytes, total_bytes | 393 1, 1, // received_bytes, total_bytes |
| 99 history_info[i].state, // state | 394 history_info[i].state, // state |
| 100 i + 1, // db_handle | 395 i + 1, // db_handle |
| 101 false); // opened | 396 false); // opened |
| 102 entries.push_back(entry); | 397 entries.push_back(entry); |
| 103 } | 398 } |
| 104 GetDownloadManager()->OnPersistentStoreQueryComplete(&entries); | 399 GetOnRecordManager()->OnPersistentStoreQueryComplete(&entries); |
| 105 GetDownloadManager()->GetAllDownloads(FilePath(), items); | 400 GetOnRecordManager()->GetAllDownloads(FilePath(), items); |
| 106 EXPECT_EQ(count, items->size()); | 401 EXPECT_EQ(count, items->size()); |
| 107 if (count != items->size()) | 402 if (count != items->size()) |
| 108 return false; | 403 return false; |
| 109 | 404 |
| 110 // Order by ID so that they are in the order that we created them. | 405 // Order by ID so that they are in the order that we created them. |
| 111 std::sort(items->begin(), items->end(), download_id_comparator); | 406 std::sort(items->begin(), items->end(), download_id_comparator); |
| 112 // Set the danger type if necessary. | 407 // Set the danger type if necessary. |
| 113 for (size_t i = 0; i < count; ++i) { | 408 for (size_t i = 0; i < count; ++i) { |
| 114 if (history_info[i].danger_type != | 409 if (history_info[i].danger_type != |
| 115 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) { | 410 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 129 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); | 424 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); |
| 130 ui_test_utils::NavigateToURLWithDisposition( | 425 ui_test_utils::NavigateToURLWithDisposition( |
| 131 current_browser(), slow_download_url, CURRENT_TAB, | 426 current_browser(), slow_download_url, CURRENT_TAB, |
| 132 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 427 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
| 133 observer->WaitForFinished(); | 428 observer->WaitForFinished(); |
| 134 EXPECT_EQ( | 429 EXPECT_EQ( |
| 135 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS)); | 430 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS)); |
| 136 // We don't expect a select file dialog. | 431 // We don't expect a select file dialog. |
| 137 ASSERT_FALSE(observer->select_file_dialog_seen()); | 432 ASSERT_FALSE(observer->select_file_dialog_seen()); |
| 138 } | 433 } |
| 139 GetDownloadManager()->GetAllDownloads(FilePath(), items); | 434 GetCurrentManager()->GetAllDownloads(FilePath(), items); |
| 140 ASSERT_EQ(count, items->size()); | 435 ASSERT_EQ(count, items->size()); |
| 141 } | 436 } |
| 142 | 437 |
| 143 DownloadItem* CreateSlowTestDownload() { | 438 DownloadItem* CreateSlowTestDownload() { |
| 144 scoped_ptr<DownloadTestObserver> observer( | 439 scoped_ptr<DownloadTestObserver> observer( |
| 145 CreateInProgressDownloadObserver(1)); | 440 CreateInProgressDownloadObserver(1)); |
| 146 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); | 441 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); |
| 147 DownloadManager* manager = GetDownloadManager(); | 442 DownloadManager* manager = GetCurrentManager(); |
| 148 | 443 |
| 149 EXPECT_EQ(0, manager->InProgressCount()); | 444 EXPECT_EQ(0, manager->InProgressCount()); |
| 150 if (manager->InProgressCount() != 0) | 445 if (manager->InProgressCount() != 0) |
| 151 return NULL; | 446 return NULL; |
| 152 | 447 |
| 153 ui_test_utils::NavigateToURLWithDisposition( | 448 ui_test_utils::NavigateToURLWithDisposition( |
| 154 current_browser(), slow_download_url, CURRENT_TAB, | 449 current_browser(), slow_download_url, CURRENT_TAB, |
| 155 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 450 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
| 156 | 451 |
| 157 observer->WaitForFinished(); | 452 observer->WaitForFinished(); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 181 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl); | 476 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl); |
| 182 ui_test_utils::NavigateToURLWithDisposition( | 477 ui_test_utils::NavigateToURLWithDisposition( |
| 183 current_browser(), finish_url, NEW_FOREGROUND_TAB, | 478 current_browser(), finish_url, NEW_FOREGROUND_TAB, |
| 184 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 479 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
| 185 observer->WaitForFinished(); | 480 observer->WaitForFinished(); |
| 186 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); | 481 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); |
| 187 } | 482 } |
| 188 | 483 |
| 189 DownloadTestObserver* CreateDownloadObserver(size_t download_count) { | 484 DownloadTestObserver* CreateDownloadObserver(size_t download_count) { |
| 190 return new DownloadTestObserverTerminal( | 485 return new DownloadTestObserverTerminal( |
| 191 GetDownloadManager(), download_count, true, | 486 GetCurrentManager(), download_count, true, |
| 192 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); | 487 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); |
| 193 } | 488 } |
| 194 | 489 |
| 195 DownloadTestObserver* CreateInProgressDownloadObserver( | 490 DownloadTestObserver* CreateInProgressDownloadObserver( |
| 196 size_t download_count) { | 491 size_t download_count) { |
| 197 return new DownloadTestObserverInProgress(GetDownloadManager(), | 492 return new DownloadTestObserverInProgress( |
| 198 download_count, | 493 GetCurrentManager(), download_count, true); |
| 199 true); | 494 } |
| 495 | |
| 496 bool RunFunction(UIThreadExtensionFunction* function, | |
| 497 const std::string& args) { | |
| 498 scoped_refptr<UIThreadExtensionFunction> delete_function(function); | |
| 499 SetUpExtensionFunction(function); | |
| 500 return extension_function_test_utils::RunFunction( | |
| 501 function, args, browser(), GetFlags()); | |
| 200 } | 502 } |
| 201 | 503 |
| 202 extension_function_test_utils::RunFunctionFlags GetFlags() { | 504 extension_function_test_utils::RunFunctionFlags GetFlags() { |
| 203 return current_browser()->profile()->IsOffTheRecord() ? | 505 return current_browser()->profile()->IsOffTheRecord() ? |
| 204 extension_function_test_utils::INCLUDE_INCOGNITO : | 506 extension_function_test_utils::INCLUDE_INCOGNITO : |
| 205 extension_function_test_utils::NONE; | 507 extension_function_test_utils::NONE; |
| 206 } | 508 } |
| 207 | 509 |
| 208 // extension_function_test_utils::RunFunction*() only uses browser for its | 510 // 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 | 511 // profile(), so pass it the on-record browser so that it always uses the |
| 210 // on-record profile. | 512 // on-record profile to match real-life behavior. |
| 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 | 513 |
| 221 base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function, | 514 base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function, |
| 222 const std::string& args) { | 515 const std::string& args) { |
| 516 SetUpExtensionFunction(function); | |
| 223 return extension_function_test_utils::RunFunctionAndReturnResult( | 517 return extension_function_test_utils::RunFunctionAndReturnResult( |
| 224 function, args, browser(), GetFlags()); | 518 function, args, browser(), GetFlags()); |
| 225 } | 519 } |
| 226 | 520 |
| 227 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, | 521 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, |
| 228 const std::string& args) { | 522 const std::string& args) { |
| 523 SetUpExtensionFunction(function); | |
| 229 return extension_function_test_utils::RunFunctionAndReturnError( | 524 return extension_function_test_utils::RunFunctionAndReturnError( |
| 230 function, args, browser(), GetFlags()); | 525 function, args, browser(), GetFlags()); |
| 231 } | 526 } |
| 232 | 527 |
| 233 bool RunFunctionAndReturnString(UIThreadExtensionFunction* function, | 528 bool RunFunctionAndReturnString(UIThreadExtensionFunction* function, |
| 234 const std::string& args, | 529 const std::string& args, |
| 235 std::string* result_string) { | 530 std::string* result_string) { |
| 531 SetUpExtensionFunction(function); | |
| 236 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args)); | 532 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args)); |
| 237 EXPECT_TRUE(result.get()); | 533 EXPECT_TRUE(result.get()); |
| 238 return result.get() && result->GetAsString(result_string); | 534 return result.get() && result->GetAsString(result_string); |
| 239 } | 535 } |
| 240 | 536 |
| 241 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) { | 537 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) { |
| 242 return base::StringPrintf("[%d]", download_item->GetId()); | 538 return base::StringPrintf("[%d]", download_item->GetId()); |
| 243 } | 539 } |
| 244 | 540 |
| 245 // Checks if a data URL encoded image is a PNG of a given size. | 541 // Checks if a data URL encoded image is a PNG of a given size. |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 263 &width, &height)); | 559 &width, &height)); |
| 264 EXPECT_EQ(expected_size, width); | 560 EXPECT_EQ(expected_size, width); |
| 265 EXPECT_EQ(expected_size, height); | 561 EXPECT_EQ(expected_size, height); |
| 266 } | 562 } |
| 267 | 563 |
| 268 const FilePath& downloads_directory() { | 564 const FilePath& downloads_directory() { |
| 269 return downloads_directory_.path(); | 565 return downloads_directory_.path(); |
| 270 } | 566 } |
| 271 | 567 |
| 272 private: | 568 private: |
| 569 void SetUpExtensionFunction(UIThreadExtensionFunction* function) { | |
| 570 if (extension_) { | |
| 571 // Recreate the tab each time for insulation. | |
| 572 TabContents* tab = current_browser()->AddSelectedTabWithURL( | |
| 573 extension_->GetResourceURL("empty.html"), | |
| 574 content::PAGE_TRANSITION_LINK); | |
| 575 function->set_extension(extension_); | |
| 576 function->SetRenderViewHost(tab->web_contents()->GetRenderViewHost()); | |
| 577 } | |
| 578 } | |
| 579 | |
| 273 void CreateAndSetDownloadsDirectory() { | 580 void CreateAndSetDownloadsDirectory() { |
| 274 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); | 581 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); |
| 275 current_browser()->profile()->GetPrefs()->SetFilePath( | 582 current_browser()->profile()->GetPrefs()->SetFilePath( |
| 276 prefs::kDownloadDefaultDirectory, | 583 prefs::kDownloadDefaultDirectory, |
| 277 downloads_directory_.path()); | 584 downloads_directory_.path()); |
| 278 } | 585 } |
| 279 | 586 |
| 280 ScopedTempDir downloads_directory_; | 587 ScopedTempDir downloads_directory_; |
| 281 }; | 588 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_; | 589 Browser* incognito_browser_; |
| 300 Browser* current_browser_; | 590 Browser* current_browser_; |
| 591 scoped_ptr<DownloadsEventsListener> events_listener_; | |
| 592 | |
| 593 DISALLOW_COPY_AND_ASSIGN(DownloadExtensionTest); | |
| 301 }; | 594 }; |
| 302 | 595 |
| 303 class MockIconExtractorImpl : public DownloadFileIconExtractor { | 596 class MockIconExtractorImpl : public DownloadFileIconExtractor { |
| 304 public: | 597 public: |
| 305 MockIconExtractorImpl(const FilePath& path, IconLoader::IconSize icon_size, | 598 MockIconExtractorImpl(const FilePath& path, IconLoader::IconSize icon_size, |
| 306 const std::string& response) | 599 const std::string& response) |
| 307 : expected_path_(path), | 600 : expected_path_(path), |
| 308 expected_icon_size_(icon_size), | 601 expected_icon_size_(icon_size), |
| 309 response_(response) { | 602 response_(response) { |
| 310 } | 603 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 if ((*item)->IsInProgress()) | 662 if ((*item)->IsInProgress()) |
| 370 (*item)->Cancel(true); | 663 (*item)->Cancel(true); |
| 371 } | 664 } |
| 372 } | 665 } |
| 373 | 666 |
| 374 private: | 667 private: |
| 375 DownloadManager::DownloadVector* items_; | 668 DownloadManager::DownloadVector* items_; |
| 376 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller); | 669 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller); |
| 377 }; | 670 }; |
| 378 | 671 |
| 379 } // namespace | 672 |
| 673 // Tests may create HTML5 FileSystem Files for testing. | |
| 674 // fileapi::FileSystemContext::OpenFileSystem() calls OpenFileSystemCallback() | |
| 675 // below, which runs CreateFileOnIOThread, which calls | |
| 676 // fileapi::FileSystemOperationInterface::CreateFile(), which calls | |
| 677 // FileCreated() below, which runs FileCreatedOnUIThread. | |
| 678 | |
| 679 static const char* kHTML5FileCreated = "html5_file_created"; | |
| 680 | |
| 681 void FileCreatedOnUIThread(Profile* profile, std::string filename) { | |
| 682 DownloadsEventsListener::DownloadsNotificationSource notification_source; | |
| 683 notification_source.event_name = kHTML5FileCreated; | |
| 684 notification_source.profile = profile; | |
| 685 content::NotificationService::current()->Notify( | |
| 686 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | |
| 687 content::Source<DownloadsEventsListener::DownloadsNotificationSource>( | |
| 688 ¬ification_source), | |
| 689 content::Details<std::string>(&filename)); | |
| 690 } | |
| 691 | |
| 692 void FileCreated(Profile* profile, const std::string& filename, | |
| 693 base::PlatformFileError result) { | |
| 694 CHECK(BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( | |
| 695 &FileCreatedOnUIThread, profile, filename))); | |
| 696 } | |
| 697 | |
| 698 void CreateFileOnIOThread(fileapi::FileSystemOperationInterface* operation, | |
| 699 Profile* profile, | |
| 700 const std::string& filename, | |
| 701 const std::string& url) { | |
| 702 operation->CreateFile(GURL(url + filename), | |
| 703 true/*exclusive*/, | |
| 704 base::Bind(&FileCreated, profile, filename)); | |
| 705 } | |
| 706 | |
| 707 void OpenFileSystemCallback(fileapi::FileSystemContext* fs, | |
| 708 const std::string& filename, | |
| 709 Profile* profile, | |
| 710 base::PlatformFileError result, | |
| 711 const std::string& fs_name, | |
| 712 const GURL& root) { | |
| 713 fileapi::FileSystemOperationInterface* operation = | |
| 714 fs->CreateFileSystemOperation(root); | |
| 715 CHECK(BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( | |
| 716 &CreateFileOnIOThread, operation, profile, filename, root.spec()))); | |
| 717 } | |
| 718 | |
| 719 } // namespace | |
| 380 | 720 |
| 381 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_PauseResumeCancel) { | 721 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_PauseResumeCancel) { |
| 382 DownloadItem* download_item = CreateSlowTestDownload(); | 722 DownloadItem* download_item = CreateSlowTestDownload(); |
| 383 ASSERT_TRUE(download_item); | 723 ASSERT_TRUE(download_item); |
| 384 | 724 |
| 385 // Call pause(). It should succeed and the download should be paused on | 725 // Call pause(). It should succeed and the download should be paused on |
| 386 // return. | 726 // return. |
| 387 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), | 727 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), |
| 388 DownloadItemIdAsArgList(download_item))); | 728 DownloadItemIdAsArgList(download_item))); |
| 389 EXPECT_TRUE(download_item->IsPaused()); | 729 EXPECT_TRUE(download_item->IsPaused()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item)); | 763 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item)); |
| 424 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 764 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
| 425 error.c_str()); | 765 error.c_str()); |
| 426 | 766 |
| 427 // Calling resume on a non-active download yields kInvalidOperationError | 767 // Calling resume on a non-active download yields kInvalidOperationError |
| 428 error = RunFunctionAndReturnError( | 768 error = RunFunctionAndReturnError( |
| 429 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item)); | 769 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item)); |
| 430 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 770 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
| 431 error.c_str()); | 771 error.c_str()); |
| 432 | 772 |
| 433 // Calling pause()/resume()/cancel() with invalid download Ids is | 773 // Calling paused on a non-existent download yields kInvalidOperationError. |
| 434 // tested in the API test (DownloadsApiTest). | 774 error = RunFunctionAndReturnError( |
| 775 new DownloadsPauseFunction(), "[-42]"); | |
| 776 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
| 777 error.c_str()); | |
| 778 | |
| 779 // Calling resume on a non-existent download yields kInvalidOperationError | |
| 780 error = RunFunctionAndReturnError( | |
| 781 new DownloadsResumeFunction(), "[-42]"); | |
| 782 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
| 783 error.c_str()); | |
| 435 } | 784 } |
| 436 | 785 |
| 437 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted | 786 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted |
| 438 // download items. | 787 // download items. |
| 439 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_Active) { | 788 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_Active) { |
| 440 DownloadItem* download_item = CreateSlowTestDownload(); | 789 DownloadItem* download_item = CreateSlowTestDownload(); |
| 441 ASSERT_TRUE(download_item); | 790 ASSERT_TRUE(download_item); |
| 442 | 791 |
| 443 // Get the icon for the in-progress download. This call should succeed even | 792 // Get the icon for the in-progress download. This call should succeed even |
| 444 // if the file type isn't registered. | 793 // if the file type isn't registered. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 519 expected_path, IconLoader::NORMAL, "")); | 868 expected_path, IconLoader::NORMAL, "")); |
| 520 std::string error = RunFunctionAndReturnError(function.release(), args); | 869 std::string error = RunFunctionAndReturnError(function.release(), args); |
| 521 EXPECT_STREQ(download_extension_errors::kIconNotFoundError, | 870 EXPECT_STREQ(download_extension_errors::kIconNotFoundError, |
| 522 error.c_str()); | 871 error.c_str()); |
| 523 | 872 |
| 524 // Once the download item is deleted, we should return kInvalidOperationError. | 873 // Once the download item is deleted, we should return kInvalidOperationError. |
| 525 download_item->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); | 874 download_item->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); |
| 526 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args); | 875 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args); |
| 527 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 876 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
| 528 error.c_str()); | 877 error.c_str()); |
| 529 | |
| 530 // Asking for icons of other (invalid) sizes is tested in the API test | |
| 531 // (DownloadsApiTest). | |
| 532 } | 878 } |
| 533 | 879 |
| 534 // Test that we can acquire file icons for history downloads regardless of | 880 // 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 | 881 // 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 | 882 // generic icon from the OS/toolkit that may or may not be specific to the file |
| 537 // type. | 883 // type. |
| 538 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_History) { | 884 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_History) { |
| 539 const HistoryDownloadInfo kHistoryInfo[] = { | 885 const HistoryDownloadInfo kHistoryInfo[] = { |
| 540 { FILE_PATH_LITERAL("real.txt"), | 886 { FILE_PATH_LITERAL("real.txt"), |
| 541 DownloadItem::COMPLETE, | 887 DownloadItem::COMPLETE, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 576 function->SetIconExtractorForTesting(new MockIconExtractorImpl( | 922 function->SetIconExtractorForTesting(new MockIconExtractorImpl( |
| 577 (*iter)->GetFullPath(), IconLoader::NORMAL, "hello")); | 923 (*iter)->GetFullPath(), IconLoader::NORMAL, "hello")); |
| 578 EXPECT_TRUE(RunFunctionAndReturnString(function.release(), args, | 924 EXPECT_TRUE(RunFunctionAndReturnString(function.release(), args, |
| 579 &result_string)); | 925 &result_string)); |
| 580 EXPECT_STREQ("hello", result_string.c_str()); | 926 EXPECT_STREQ("hello", result_string.c_str()); |
| 581 } | 927 } |
| 582 | 928 |
| 583 // The temporary files should be cleaned up when the ScopedTempDir is removed. | 929 // The temporary files should be cleaned up when the ScopedTempDir is removed. |
| 584 } | 930 } |
| 585 | 931 |
| 932 // Test passing the empty query to search(). | |
| 586 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchEmptyQuery) { | 933 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchEmptyQuery) { |
| 587 ScopedCancellingItem item(CreateSlowTestDownload()); | 934 ScopedCancellingItem item(CreateSlowTestDownload()); |
| 588 ASSERT_TRUE(item.get()); | 935 ASSERT_TRUE(item.get()); |
| 589 | 936 |
| 590 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 937 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
| 591 new DownloadsSearchFunction(), "[{}]")); | 938 new DownloadsSearchFunction(), "[{}]")); |
| 592 ASSERT_TRUE(result.get()); | 939 ASSERT_TRUE(result.get()); |
| 593 base::ListValue* result_list = NULL; | 940 base::ListValue* result_list = NULL; |
| 594 ASSERT_TRUE(result->GetAsList(&result_list)); | 941 ASSERT_TRUE(result->GetAsList(&result_list)); |
| 595 ASSERT_EQ(1UL, result_list->GetSize()); | 942 ASSERT_EQ(1UL, result_list->GetSize()); |
| 596 } | 943 } |
| 597 | 944 |
| 945 // Test the |filenameRegex| parameter for search(). | |
| 598 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 946 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
| 599 DownloadsApi_SearchFilenameRegex) { | 947 DownloadsApi_SearchFilenameRegex) { |
| 600 const HistoryDownloadInfo kHistoryInfo[] = { | 948 const HistoryDownloadInfo kHistoryInfo[] = { |
| 601 { FILE_PATH_LITERAL("foobar"), | 949 { FILE_PATH_LITERAL("foobar"), |
| 602 DownloadItem::COMPLETE, | 950 DownloadItem::COMPLETE, |
| 603 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | 951 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, |
| 604 { FILE_PATH_LITERAL("baz"), | 952 { FILE_PATH_LITERAL("baz"), |
| 605 DownloadItem::COMPLETE, | 953 DownloadItem::COMPLETE, |
| 606 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | 954 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } |
| 607 }; | 955 }; |
| 608 DownloadManager::DownloadVector all_downloads; | 956 DownloadManager::DownloadVector all_downloads; |
| 609 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), | 957 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), |
| 610 &all_downloads)); | 958 &all_downloads)); |
| 611 | 959 |
| 612 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 960 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
| 613 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]")); | 961 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]")); |
| 614 ASSERT_TRUE(result.get()); | 962 ASSERT_TRUE(result.get()); |
| 615 base::ListValue* result_list = NULL; | 963 base::ListValue* result_list = NULL; |
| 616 ASSERT_TRUE(result->GetAsList(&result_list)); | 964 ASSERT_TRUE(result->GetAsList(&result_list)); |
| 617 ASSERT_EQ(1UL, result_list->GetSize()); | 965 ASSERT_EQ(1UL, result_list->GetSize()); |
| 618 base::DictionaryValue* item_value = NULL; | 966 base::DictionaryValue* item_value = NULL; |
| 619 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); | 967 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); |
| 620 int item_id = -1; | 968 int item_id = -1; |
| 621 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); | 969 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); |
| 622 ASSERT_EQ(0, item_id); | 970 ASSERT_EQ(0, item_id); |
| 623 } | 971 } |
| 624 | 972 |
| 973 // Test the |id| parameter for search(). | |
| 625 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchId) { | 974 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchId) { |
| 626 DownloadManager::DownloadVector items; | 975 DownloadManager::DownloadVector items; |
| 627 CreateSlowTestDownloads(2, &items); | 976 CreateSlowTestDownloads(2, &items); |
| 628 ScopedItemVectorCanceller delete_items(&items); | 977 ScopedItemVectorCanceller delete_items(&items); |
| 629 | 978 |
| 630 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 979 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
| 631 new DownloadsSearchFunction(), "[{\"id\": 0}]")); | 980 new DownloadsSearchFunction(), "[{\"id\": 0}]")); |
| 632 ASSERT_TRUE(result.get()); | 981 ASSERT_TRUE(result.get()); |
| 633 base::ListValue* result_list = NULL; | 982 base::ListValue* result_list = NULL; |
| 634 ASSERT_TRUE(result->GetAsList(&result_list)); | 983 ASSERT_TRUE(result->GetAsList(&result_list)); |
| 635 ASSERT_EQ(1UL, result_list->GetSize()); | 984 ASSERT_EQ(1UL, result_list->GetSize()); |
| 636 base::DictionaryValue* item_value = NULL; | 985 base::DictionaryValue* item_value = NULL; |
| 637 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); | 986 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); |
| 638 int item_id = -1; | 987 int item_id = -1; |
| 639 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); | 988 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); |
| 640 ASSERT_EQ(0, item_id); | 989 ASSERT_EQ(0, item_id); |
| 641 } | 990 } |
| 642 | 991 |
| 992 // Test specifying both the |id| and |filename| parameters for search(). | |
| 643 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | 993 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, |
| 644 DownloadsApi_SearchIdAndFilename) { | 994 DownloadsApi_SearchIdAndFilename) { |
| 645 DownloadManager::DownloadVector items; | 995 DownloadManager::DownloadVector items; |
| 646 CreateSlowTestDownloads(2, &items); | 996 CreateSlowTestDownloads(2, &items); |
| 647 ScopedItemVectorCanceller delete_items(&items); | 997 ScopedItemVectorCanceller delete_items(&items); |
| 648 | 998 |
| 649 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 999 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
| 650 new DownloadsSearchFunction(), "[{\"id\": 0,\"filename\": \"foobar\"}]")); | 1000 new DownloadsSearchFunction(), |
| 1001 "[{\"id\": 0, \"filename\": \"foobar\"}]")); | |
| 651 ASSERT_TRUE(result.get()); | 1002 ASSERT_TRUE(result.get()); |
| 652 base::ListValue* result_list = NULL; | 1003 base::ListValue* result_list = NULL; |
| 653 ASSERT_TRUE(result->GetAsList(&result_list)); | 1004 ASSERT_TRUE(result->GetAsList(&result_list)); |
| 654 ASSERT_EQ(0UL, result_list->GetSize()); | 1005 ASSERT_EQ(0UL, result_list->GetSize()); |
| 655 } | 1006 } |
| 656 | 1007 |
| 1008 // Test a single |orderBy| parameter for search(). | |
| 657 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchOrderBy) { | 1009 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchOrderBy) { |
| 658 const HistoryDownloadInfo kHistoryInfo[] = { | 1010 const HistoryDownloadInfo kHistoryInfo[] = { |
| 659 { FILE_PATH_LITERAL("zzz"), | 1011 { FILE_PATH_LITERAL("zzz"), |
| 660 DownloadItem::COMPLETE, | 1012 DownloadItem::COMPLETE, |
| 661 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | 1013 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, |
| 662 { FILE_PATH_LITERAL("baz"), | 1014 { FILE_PATH_LITERAL("baz"), |
| 663 DownloadItem::COMPLETE, | 1015 DownloadItem::COMPLETE, |
| 664 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | 1016 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } |
| 665 }; | 1017 }; |
| 666 DownloadManager::DownloadVector items; | 1018 DownloadManager::DownloadVector items; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 677 base::DictionaryValue* item1_value = NULL; | 1029 base::DictionaryValue* item1_value = NULL; |
| 678 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); | 1030 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); |
| 679 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); | 1031 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); |
| 680 std::string item0_name, item1_name; | 1032 std::string item0_name, item1_name; |
| 681 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); | 1033 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); |
| 682 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); | 1034 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); |
| 683 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); | 1035 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); |
| 684 ASSERT_LT(item0_name, item1_name); | 1036 ASSERT_LT(item0_name, item1_name); |
| 685 } | 1037 } |
| 686 | 1038 |
| 1039 // Test specifying an empty |orderBy| parameter for search(). | |
| 687 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchOrderByEmpty) { | 1040 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchOrderByEmpty) { |
| 688 const HistoryDownloadInfo kHistoryInfo[] = { | 1041 const HistoryDownloadInfo kHistoryInfo[] = { |
| 689 { FILE_PATH_LITERAL("zzz"), | 1042 { FILE_PATH_LITERAL("zzz"), |
| 690 DownloadItem::COMPLETE, | 1043 DownloadItem::COMPLETE, |
| 691 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | 1044 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, |
| 692 { FILE_PATH_LITERAL("baz"), | 1045 { FILE_PATH_LITERAL("baz"), |
| 693 DownloadItem::COMPLETE, | 1046 DownloadItem::COMPLETE, |
| 694 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | 1047 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } |
| 695 }; | 1048 }; |
| 696 DownloadManager::DownloadVector items; | 1049 DownloadManager::DownloadVector items; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 707 base::DictionaryValue* item1_value = NULL; | 1060 base::DictionaryValue* item1_value = NULL; |
| 708 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); | 1061 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); |
| 709 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); | 1062 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); |
| 710 std::string item0_name, item1_name; | 1063 std::string item0_name, item1_name; |
| 711 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); | 1064 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); |
| 712 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); | 1065 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); |
| 713 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); | 1066 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); |
| 714 ASSERT_GT(item0_name, item1_name); | 1067 ASSERT_GT(item0_name, item1_name); |
| 715 } | 1068 } |
| 716 | 1069 |
| 1070 // Test the |danger| option for search(). | |
| 717 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchDanger) { | 1071 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchDanger) { |
| 718 const HistoryDownloadInfo kHistoryInfo[] = { | 1072 const HistoryDownloadInfo kHistoryInfo[] = { |
| 719 { FILE_PATH_LITERAL("zzz"), | 1073 { FILE_PATH_LITERAL("zzz"), |
| 720 DownloadItem::COMPLETE, | 1074 DownloadItem::COMPLETE, |
| 721 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, | 1075 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, |
| 722 { FILE_PATH_LITERAL("baz"), | 1076 { FILE_PATH_LITERAL("baz"), |
| 723 DownloadItem::COMPLETE, | 1077 DownloadItem::COMPLETE, |
| 724 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | 1078 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } |
| 725 }; | 1079 }; |
| 726 DownloadManager::DownloadVector items; | 1080 DownloadManager::DownloadVector items; |
| 727 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), | 1081 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), |
| 728 &items)); | 1082 &items)); |
| 729 | 1083 |
| 730 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 1084 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
| 731 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]")); | 1085 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]")); |
| 732 ASSERT_TRUE(result.get()); | 1086 ASSERT_TRUE(result.get()); |
| 733 base::ListValue* result_list = NULL; | 1087 base::ListValue* result_list = NULL; |
| 734 ASSERT_TRUE(result->GetAsList(&result_list)); | 1088 ASSERT_TRUE(result->GetAsList(&result_list)); |
| 735 ASSERT_EQ(1UL, result_list->GetSize()); | 1089 ASSERT_EQ(1UL, result_list->GetSize()); |
| 736 } | 1090 } |
| 737 | 1091 |
| 1092 // Test the |state| option for search(). | |
| 738 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchState) { | 1093 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchState) { |
| 739 DownloadManager::DownloadVector items; | 1094 DownloadManager::DownloadVector items; |
| 740 CreateSlowTestDownloads(2, &items); | 1095 CreateSlowTestDownloads(2, &items); |
| 741 ScopedItemVectorCanceller delete_items(&items); | 1096 ScopedItemVectorCanceller delete_items(&items); |
| 742 | 1097 |
| 743 items[0]->Cancel(true); | 1098 items[0]->Cancel(true); |
| 744 | 1099 |
| 745 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 1100 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
| 746 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]")); | 1101 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]")); |
| 747 ASSERT_TRUE(result.get()); | 1102 ASSERT_TRUE(result.get()); |
| 748 base::ListValue* result_list = NULL; | 1103 base::ListValue* result_list = NULL; |
| 749 ASSERT_TRUE(result->GetAsList(&result_list)); | 1104 ASSERT_TRUE(result->GetAsList(&result_list)); |
| 750 ASSERT_EQ(1UL, result_list->GetSize()); | 1105 ASSERT_EQ(1UL, result_list->GetSize()); |
| 751 } | 1106 } |
| 752 | 1107 |
| 1108 // Test the |limit| option for search(). | |
| 753 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchLimit) { | 1109 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchLimit) { |
| 754 DownloadManager::DownloadVector items; | 1110 DownloadManager::DownloadVector items; |
| 755 CreateSlowTestDownloads(2, &items); | 1111 CreateSlowTestDownloads(2, &items); |
| 756 ScopedItemVectorCanceller delete_items(&items); | 1112 ScopedItemVectorCanceller delete_items(&items); |
| 757 | 1113 |
| 758 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | 1114 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( |
| 759 new DownloadsSearchFunction(), "[{\"limit\": 1}]")); | 1115 new DownloadsSearchFunction(), "[{\"limit\": 1}]")); |
| 760 ASSERT_TRUE(result.get()); | 1116 ASSERT_TRUE(result.get()); |
| 761 base::ListValue* result_list = NULL; | 1117 base::ListValue* result_list = NULL; |
| 762 ASSERT_TRUE(result->GetAsList(&result_list)); | 1118 ASSERT_TRUE(result->GetAsList(&result_list)); |
| 763 ASSERT_EQ(1UL, result_list->GetSize()); | 1119 ASSERT_EQ(1UL, result_list->GetSize()); |
| 764 } | 1120 } |
| 765 | 1121 |
| 1122 // Test invalid search parameters. | |
| 766 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchInvalid) { | 1123 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchInvalid) { |
| 767 std::string error = RunFunctionAndReturnError( | 1124 std::string error = RunFunctionAndReturnError( |
| 768 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]"); | 1125 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]"); |
| 769 EXPECT_STREQ(download_extension_errors::kInvalidFilterError, | 1126 EXPECT_STREQ(download_extension_errors::kInvalidFilterError, |
| 770 error.c_str()); | 1127 error.c_str()); |
| 771 error = RunFunctionAndReturnError( | 1128 error = RunFunctionAndReturnError( |
| 772 new DownloadsSearchFunction(), "[{\"danger\": \"goat\"}]"); | 1129 new DownloadsSearchFunction(), "[{\"danger\": \"goat\"}]"); |
| 773 EXPECT_STREQ(download_extension_errors::kInvalidDangerTypeError, | 1130 EXPECT_STREQ(download_extension_errors::kInvalidDangerTypeError, |
| 774 error.c_str()); | 1131 error.c_str()); |
| 775 error = RunFunctionAndReturnError( | 1132 error = RunFunctionAndReturnError( |
| 776 new DownloadsSearchFunction(), "[{\"state\": \"goat\"}]"); | 1133 new DownloadsSearchFunction(), "[{\"state\": \"goat\"}]"); |
| 777 EXPECT_STREQ(download_extension_errors::kInvalidStateError, | 1134 EXPECT_STREQ(download_extension_errors::kInvalidStateError, |
| 778 error.c_str()); | 1135 error.c_str()); |
| 779 error = RunFunctionAndReturnError( | 1136 error = RunFunctionAndReturnError( |
| 780 new DownloadsSearchFunction(), "[{\"orderBy\": \"goat\"}]"); | 1137 new DownloadsSearchFunction(), "[{\"orderBy\": \"goat\"}]"); |
| 781 EXPECT_STREQ(download_extension_errors::kInvalidOrderByError, | 1138 EXPECT_STREQ(download_extension_errors::kInvalidOrderByError, |
| 782 error.c_str()); | 1139 error.c_str()); |
| 783 error = RunFunctionAndReturnError( | 1140 error = RunFunctionAndReturnError( |
| 784 new DownloadsSearchFunction(), "[{\"limit\": -1}]"); | 1141 new DownloadsSearchFunction(), "[{\"limit\": -1}]"); |
| 785 EXPECT_STREQ(download_extension_errors::kInvalidQueryLimit, | 1142 EXPECT_STREQ(download_extension_errors::kInvalidQueryLimit, |
| 786 error.c_str()); | 1143 error.c_str()); |
| 787 } | 1144 } |
| 788 | 1145 |
| 1146 // Test searching using multiple conditions through multiple downloads. | |
| 789 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchPlural) { | 1147 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchPlural) { |
| 790 const HistoryDownloadInfo kHistoryInfo[] = { | 1148 const HistoryDownloadInfo kHistoryInfo[] = { |
| 791 { FILE_PATH_LITERAL("aaa"), | 1149 { FILE_PATH_LITERAL("aaa"), |
| 792 DownloadItem::CANCELLED, | 1150 DownloadItem::CANCELLED, |
| 793 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | 1151 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, |
| 794 { FILE_PATH_LITERAL("zzz"), | 1152 { FILE_PATH_LITERAL("zzz"), |
| 795 DownloadItem::COMPLETE, | 1153 DownloadItem::COMPLETE, |
| 796 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, | 1154 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, |
| 797 { FILE_PATH_LITERAL("baz"), | 1155 { FILE_PATH_LITERAL("baz"), |
| 798 DownloadItem::COMPLETE, | 1156 DownloadItem::COMPLETE, |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 812 base::ListValue* result_list = NULL; | 1170 base::ListValue* result_list = NULL; |
| 813 ASSERT_TRUE(result->GetAsList(&result_list)); | 1171 ASSERT_TRUE(result->GetAsList(&result_list)); |
| 814 ASSERT_EQ(1UL, result_list->GetSize()); | 1172 ASSERT_EQ(1UL, result_list->GetSize()); |
| 815 base::DictionaryValue* item_value = NULL; | 1173 base::DictionaryValue* item_value = NULL; |
| 816 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); | 1174 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); |
| 817 FilePath::StringType item_name; | 1175 FilePath::StringType item_name; |
| 818 ASSERT_TRUE(item_value->GetString("filename", &item_name)); | 1176 ASSERT_TRUE(item_value->GetString("filename", &item_name)); |
| 819 ASSERT_EQ(items[2]->GetFullPath().value(), item_name); | 1177 ASSERT_EQ(items[2]->GetFullPath().value(), item_name); |
| 820 } | 1178 } |
| 821 | 1179 |
| 822 IN_PROC_BROWSER_TEST_F(DownloadExtensionTestIncognito, | 1180 // Test that incognito downloads are only visible in incognito contexts, and |
| 823 DownloadsApi_SearchIncognito) { | 1181 // test that on-record downloads are visible in both incognito and on-record |
| 1182 // contexts, for DownloadsSearchFunction, DownloadsPauseFunction, | |
| 1183 // DownloadsResumeFunction, and DownloadsCancelFunction. | |
| 1184 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1185 DownloadExtensionTest_SearchIncognito) { | |
| 824 scoped_ptr<base::Value> result_value; | 1186 scoped_ptr<base::Value> result_value; |
| 825 base::ListValue* result_list = NULL; | 1187 base::ListValue* result_list = NULL; |
| 826 base::DictionaryValue* result_dict = NULL; | 1188 base::DictionaryValue* result_dict = NULL; |
| 827 FilePath::StringType filename; | 1189 FilePath::StringType filename; |
| 828 bool is_incognito = false; | 1190 bool is_incognito = false; |
| 829 std::string error; | 1191 std::string error; |
| 830 std::string on_item_arg; | 1192 std::string on_item_arg; |
| 831 std::string off_item_arg; | 1193 std::string off_item_arg; |
| 832 std::string result_string; | 1194 std::string result_string; |
| 833 | 1195 |
| 834 // Set up one on-record item and one off-record item. | 1196 // Set up one on-record item and one off-record item. |
| 1197 // Set up the off-record item first because otherwise there are mysteriously 3 | |
| 1198 // items total instead of 2. | |
| 1199 // TODO(benjhayden): Figure out where the third item comes from. | |
| 1200 GoOffTheRecord(); | |
| 1201 DownloadItem* off_item = CreateSlowTestDownload(); | |
| 1202 ASSERT_TRUE(off_item); | |
| 1203 ASSERT_TRUE(off_item->IsOtr()); | |
| 1204 off_item_arg = DownloadItemIdAsArgList(off_item); | |
| 835 | 1205 |
| 836 GoOnTheRecord(); | 1206 GoOnTheRecord(); |
| 837 DownloadItem* on_item = CreateSlowTestDownload(); | 1207 DownloadItem* on_item = CreateSlowTestDownload(); |
| 838 ASSERT_TRUE(on_item); | 1208 ASSERT_TRUE(on_item); |
| 839 ASSERT_FALSE(on_item->IsOtr()); | 1209 ASSERT_FALSE(on_item->IsOtr()); |
| 840 on_item_arg = DownloadItemIdAsArgList(on_item); | 1210 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()); | 1211 ASSERT_TRUE(on_item->GetFullPath() != off_item->GetFullPath()); |
| 847 off_item_arg = DownloadItemIdAsArgList(off_item); | |
| 848 | 1212 |
| 849 // Extensions running in the incognito window should have access to both | 1213 // Extensions running in the incognito window should have access to both |
| 850 // items because the Test extension is in spanning mode. | 1214 // items because the Test extension is in spanning mode. |
| 1215 GoOffTheRecord(); | |
| 851 result_value.reset(RunFunctionAndReturnResult( | 1216 result_value.reset(RunFunctionAndReturnResult( |
| 852 new DownloadsSearchFunction(), "[{}]")); | 1217 new DownloadsSearchFunction(), "[{}]")); |
| 853 ASSERT_TRUE(result_value.get()); | 1218 ASSERT_TRUE(result_value.get()); |
| 854 ASSERT_TRUE(result_value->GetAsList(&result_list)); | 1219 ASSERT_TRUE(result_value->GetAsList(&result_list)); |
| 855 ASSERT_EQ(2UL, result_list->GetSize()); | 1220 ASSERT_EQ(2UL, result_list->GetSize()); |
| 856 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict)); | 1221 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict)); |
| 857 ASSERT_TRUE(result_dict->GetString("filename", &filename)); | 1222 ASSERT_TRUE(result_dict->GetString("filename", &filename)); |
| 858 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito)); | 1223 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito)); |
| 859 EXPECT_TRUE(on_item->GetFullPath() == FilePath(filename)); | 1224 EXPECT_TRUE(on_item->GetFullPath() == FilePath(filename)); |
| 860 EXPECT_FALSE(is_incognito); | 1225 EXPECT_FALSE(is_incognito); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 886 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), | 1251 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), |
| 887 off_item_arg); | 1252 off_item_arg); |
| 888 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 1253 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
| 889 error.c_str()); | 1254 error.c_str()); |
| 890 error = RunFunctionAndReturnError( | 1255 error = RunFunctionAndReturnError( |
| 891 new DownloadsGetFileIconFunction(), | 1256 new DownloadsGetFileIconFunction(), |
| 892 base::StringPrintf("[%d, {}]", off_item->GetId())); | 1257 base::StringPrintf("[%d, {}]", off_item->GetId())); |
| 893 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 1258 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
| 894 error.c_str()); | 1259 error.c_str()); |
| 895 | 1260 |
| 896 // TODO(benjhayden): Test incognito_split_mode() extension. | |
| 897 // TODO(benjhayden): Test download(), onCreated, onChanged, onErased. | |
| 898 | |
| 899 GoOffTheRecord(); | 1261 GoOffTheRecord(); |
| 900 | 1262 |
| 901 // Do the FileIcon test for both the on- and off-items while off the record. | 1263 // 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, | 1264 // NOTE(benjhayden): This does not include the FileIcon test from history, |
| 903 // just active downloads. This shouldn't be a problem. | 1265 // just active downloads. This shouldn't be a problem. |
| 904 EXPECT_TRUE(RunFunctionAndReturnString( | 1266 EXPECT_TRUE(RunFunctionAndReturnString( |
| 905 new DownloadsGetFileIconFunction(), | 1267 new DownloadsGetFileIconFunction(), |
| 906 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string)); | 1268 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string)); |
| 907 EXPECT_TRUE(RunFunctionAndReturnString( | 1269 EXPECT_TRUE(RunFunctionAndReturnString( |
| 908 new DownloadsGetFileIconFunction(), | 1270 new DownloadsGetFileIconFunction(), |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 946 EXPECT_TRUE(off_item->IsCancelled()); | 1308 EXPECT_TRUE(off_item->IsCancelled()); |
| 947 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), | 1309 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), |
| 948 off_item_arg); | 1310 off_item_arg); |
| 949 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 1311 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
| 950 error.c_str()); | 1312 error.c_str()); |
| 951 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), | 1313 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), |
| 952 off_item_arg); | 1314 off_item_arg); |
| 953 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | 1315 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, |
| 954 error.c_str()); | 1316 error.c_str()); |
| 955 } | 1317 } |
| 1318 | |
| 1319 // Test that DownloadsEventsListener times out quickly enough for an event | |
| 1320 // that isn't going to happen. | |
| 1321 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1322 DownloadExtensionTest_DownloadsEventsListener) { | |
| 1323 ASSERT_FALSE(WaitFor(100, extension_event_names::kOnDownloadErased, "-1")); | |
| 1324 } | |
| 1325 | |
| 1326 // Test that we can start a download and that the correct sequence of events is | |
| 1327 // fired for it. | |
| 1328 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1329 DownloadExtensionTest_Download_Basic) { | |
| 1330 LoadExtension("downloads_split"); | |
| 1331 CHECK(StartTestServer()); | |
| 1332 std::string download_url = GetURL("slow?0"); | |
| 1333 GoOnTheRecord(); | |
| 1334 | |
| 1335 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1336 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1337 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
| 1338 ASSERT_TRUE(result.get()); | |
| 1339 int result_id = -1; | |
| 1340 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 1341 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 1342 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 1343 ASSERT_TRUE(item); | |
| 1344 ScopedCancellingItem canceller(item); | |
| 1345 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 1346 | |
| 1347 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
| 1348 base::StringPrintf("[{\"danger\": \"safe\"," | |
| 1349 " \"filename\": \"%s\"," | |
| 1350 " \"incognito\": false," | |
| 1351 " \"mime\": \"text/plain\"," | |
| 1352 " \"paused\": false," | |
| 1353 " \"url\": \"%s\"}]", | |
| 1354 GetFilename("slow.txt.crdownload").c_str(), | |
| 1355 download_url.c_str()))); | |
| 1356 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
| 1357 base::StringPrintf("[{\"id\": %d," | |
| 1358 " \"filename\": {" | |
| 1359 " \"old\": \"%s\"," | |
| 1360 " \"new\": \"%s\"}," | |
| 1361 " \"state\": {" | |
| 1362 " \"old\": \"in_progress\"," | |
| 1363 " \"new\": \"complete\"}}]", | |
| 1364 result_id, | |
| 1365 GetFilename("slow.txt.crdownload").c_str(), | |
| 1366 GetFilename("slow.txt").c_str()))); | |
| 1367 } | |
| 1368 | |
| 1369 // Test that we can start a download from an incognito context, and that the | |
| 1370 // download knows that it's incognito. | |
| 1371 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1372 DownloadExtensionTest_Download_Incognito) { | |
| 1373 LoadExtension("downloads_split"); | |
| 1374 CHECK(StartTestServer()); | |
| 1375 GoOffTheRecord(); | |
| 1376 std::string download_url = GetURL("slow?0"); | |
| 1377 | |
| 1378 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1379 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1380 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
| 1381 ASSERT_TRUE(result.get()); | |
| 1382 int result_id = -1; | |
| 1383 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 1384 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 1385 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 1386 ASSERT_TRUE(item); | |
| 1387 ScopedCancellingItem canceller(item); | |
| 1388 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 1389 | |
| 1390 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
| 1391 base::StringPrintf("[{\"danger\": \"safe\"," | |
| 1392 " \"filename\": \"%s\"," | |
| 1393 " \"incognito\": true," | |
| 1394 " \"mime\": \"text/plain\"," | |
| 1395 " \"paused\": false," | |
| 1396 " \"url\": \"%s\"}]", | |
| 1397 GetFilename("slow.txt.crdownload").c_str(), | |
| 1398 download_url.c_str()))); | |
| 1399 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
| 1400 base::StringPrintf("[{\"id\":%d," | |
| 1401 " \"filename\": {" | |
| 1402 " \"old\": \"%s\"," | |
| 1403 " \"new\": \"%s\"}," | |
| 1404 " \"state\": {" | |
| 1405 " \"new\": \"complete\"," | |
| 1406 " \"old\": \"in_progress\"}}]", | |
| 1407 result_id, | |
| 1408 GetFilename("slow.txt.crdownload").c_str(), | |
| 1409 GetFilename("slow.txt").c_str()))); | |
| 1410 } | |
| 1411 | |
| 1412 // Test that we disallow certain headers case-insensitively. | |
| 1413 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1414 DownloadExtensionTest_Download_UnsafeHeaders) { | |
| 1415 LoadExtension("downloads_split"); | |
| 1416 CHECK(StartTestServer()); | |
| 1417 GoOnTheRecord(); | |
| 1418 | |
| 1419 static const char* kUnsafeHeaders[] = { | |
| 1420 "Accept-chArsEt", | |
| 1421 "accept-eNcoding", | |
| 1422 "coNNection", | |
| 1423 "coNteNt-leNgth", | |
| 1424 "cooKIE", | |
| 1425 "cOOkie2", | |
| 1426 "coNteNt-traNsfer-eNcodiNg", | |
| 1427 "dAtE", | |
| 1428 "ExpEcT", | |
| 1429 "hOsT", | |
| 1430 "kEEp-aLivE", | |
| 1431 "rEfErEr", | |
| 1432 "tE", | |
| 1433 "trAilER", | |
| 1434 "trANsfer-eNcodiNg", | |
| 1435 "upGRAde", | |
| 1436 "usER-agENt", | |
| 1437 "viA", | |
| 1438 "pRoxY-", | |
| 1439 "sEc-", | |
| 1440 "pRoxY-probably-not-evil", | |
| 1441 "sEc-probably-not-evil", | |
| 1442 "oRiGiN", | |
| 1443 "Access-Control-Request-Headers", | |
| 1444 "Access-Control-Request-Method", | |
| 1445 }; | |
| 1446 | |
| 1447 for (size_t index = 0; index < arraysize(kUnsafeHeaders); ++index) { | |
| 1448 std::string download_url = GetURL("slow?0"); | |
| 1449 EXPECT_STREQ(download_extension_errors::kGenericError, | |
| 1450 RunFunctionAndReturnError(new DownloadsDownloadFunction(), | |
| 1451 base::StringPrintf( | |
| 1452 "[{\"url\": \"%s\"," | |
| 1453 " \"filename\": \"unsafe-header-%lu.txt\"," | |
| 1454 " \"headers\": [{" | |
| 1455 " \"name\": \"%s\"," | |
| 1456 " \"value\": \"unsafe\"}]}]", | |
| 1457 download_url.c_str(), index, kUnsafeHeaders[index])).c_str()); | |
| 1458 } | |
| 1459 } | |
| 1460 | |
| 1461 // Test that subdirectories (slashes) are disallowed in filenames. | |
| 1462 // TODO(benjhayden) Update this when subdirectories are supported. | |
| 1463 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1464 DownloadExtensionTest_Download_Subdirectory) { | |
| 1465 LoadExtension("downloads_split"); | |
| 1466 CHECK(StartTestServer()); | |
| 1467 std::string download_url = GetURL("slow?0"); | |
| 1468 GoOnTheRecord(); | |
| 1469 | |
| 1470 EXPECT_STREQ(download_extension_errors::kGenericError, | |
| 1471 RunFunctionAndReturnError(new DownloadsDownloadFunction(), | |
| 1472 base::StringPrintf( | |
| 1473 "[{\"url\": \"%s\"," | |
| 1474 " \"filename\": \"sub/dir/ect/ory.txt\"}]", | |
| 1475 download_url.c_str())).c_str()); | |
| 1476 } | |
| 1477 | |
| 1478 // Test that invalid filenames are disallowed. | |
| 1479 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1480 DownloadExtensionTest_Download_InvalidFilename) { | |
| 1481 LoadExtension("downloads_split"); | |
| 1482 CHECK(StartTestServer()); | |
| 1483 std::string download_url = GetURL("slow?0"); | |
| 1484 GoOnTheRecord(); | |
| 1485 | |
| 1486 EXPECT_STREQ(download_extension_errors::kGenericError, | |
| 1487 RunFunctionAndReturnError(new DownloadsDownloadFunction(), | |
| 1488 base::StringPrintf( | |
| 1489 "[{\"url\": \"%s\"," | |
| 1490 " \"filename\": \"../../../../../etc/passwd\"}]", | |
| 1491 download_url.c_str())).c_str()); | |
| 1492 } | |
| 1493 | |
| 1494 // Test that downloading invalid URLs immediately returns kInvalidURLError. | |
| 1495 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1496 DownloadExtensionTest_Download_InvalidURLs) { | |
| 1497 LoadExtension("downloads_split"); | |
| 1498 GoOnTheRecord(); | |
| 1499 | |
| 1500 static const char* kInvalidURLs[] = { | |
| 1501 "foo bar", | |
| 1502 "../hello", | |
| 1503 "/hello", | |
| 1504 "google.com/", | |
| 1505 "http://", | |
| 1506 "#frag", | |
| 1507 "foo/bar.html#frag", | |
| 1508 "javascript:document.write(\\\"hello\\\");", | |
| 1509 "javascript:return false;", | |
| 1510 "ftp://example.com/example.txt", | |
| 1511 }; | |
| 1512 | |
| 1513 for (size_t index = 0; index < arraysize(kInvalidURLs); ++index) { | |
| 1514 EXPECT_STREQ(download_extension_errors::kInvalidURLError, | |
| 1515 RunFunctionAndReturnError(new DownloadsDownloadFunction(), | |
| 1516 base::StringPrintf( | |
| 1517 "[{\"url\": \"%s\"}]", kInvalidURLs[index])).c_str()); | |
| 1518 } | |
| 1519 } | |
| 1520 | |
| 1521 // TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to | |
| 1522 // permissions, test downloading from ftp. | |
| 1523 | |
| 1524 // Valid URLs plus fragments are still valid URLs. | |
| 1525 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1526 DownloadExtensionTest_Download_URLFragment) { | |
| 1527 LoadExtension("downloads_split"); | |
| 1528 CHECK(StartTestServer()); | |
| 1529 std::string download_url = GetURL("slow?0#fragment"); | |
| 1530 GoOnTheRecord(); | |
| 1531 | |
| 1532 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1533 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1534 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
| 1535 ASSERT_TRUE(result.get()); | |
| 1536 int result_id = -1; | |
| 1537 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 1538 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 1539 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 1540 ASSERT_TRUE(item); | |
| 1541 ScopedCancellingItem canceller(item); | |
| 1542 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 1543 | |
| 1544 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
| 1545 base::StringPrintf("[{\"danger\": \"safe\"," | |
| 1546 " \"filename\": \"%s\"," | |
| 1547 " \"incognito\": false," | |
| 1548 " \"mime\": \"text/plain\"," | |
| 1549 " \"paused\": false," | |
| 1550 " \"url\": \"%s\"}]", | |
| 1551 GetFilename("slow.txt.crdownload").c_str(), | |
| 1552 download_url.c_str()))); | |
| 1553 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
| 1554 base::StringPrintf("[{\"id\": %d," | |
| 1555 " \"filename\": {" | |
| 1556 " \"old\": \"%s\"," | |
| 1557 " \"new\": \"%s\"}," | |
| 1558 " \"state\": {" | |
| 1559 " \"old\": \"in_progress\"," | |
| 1560 " \"new\": \"complete\"}}]", | |
| 1561 result_id, | |
| 1562 GetFilename("slow.txt.crdownload").c_str(), | |
| 1563 GetFilename("slow.txt").c_str()))); | |
| 1564 } | |
| 1565 | |
| 1566 // Valid data URLs are valid URLs. | |
| 1567 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1568 DownloadExtensionTest_Download_DataURL) { | |
| 1569 LoadExtension("downloads_split"); | |
| 1570 CHECK(StartTestServer()); | |
| 1571 std::string download_url = "data:text/plain,hello"; | |
| 1572 GoOnTheRecord(); | |
| 1573 | |
| 1574 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1575 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1576 "[{\"url\": \"%s\"," | |
| 1577 " \"filename\": \"data.txt\"}]", download_url.c_str()))); | |
| 1578 ASSERT_TRUE(result.get()); | |
| 1579 int result_id = -1; | |
| 1580 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 1581 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 1582 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 1583 ASSERT_TRUE(item); | |
| 1584 ScopedCancellingItem canceller(item); | |
| 1585 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 1586 | |
| 1587 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
| 1588 base::StringPrintf("[{\"danger\": \"safe\"," | |
| 1589 " \"filename\": \"%s\"," | |
| 1590 " \"incognito\": false," | |
| 1591 " \"mime\": \"text/plain\"," | |
| 1592 " \"paused\": false," | |
| 1593 " \"url\": \"%s\"}]", | |
| 1594 GetFilename("data.txt.crdownload").c_str(), | |
| 1595 download_url.c_str()))); | |
| 1596 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
| 1597 base::StringPrintf("[{\"id\": %d," | |
| 1598 " \"filename\": {" | |
| 1599 " \"old\": \"%s\"," | |
| 1600 " \"new\": \"%s\"}," | |
| 1601 " \"state\": {" | |
| 1602 " \"old\": \"in_progress\"," | |
| 1603 " \"new\": \"complete\"}}]", | |
| 1604 result_id, | |
| 1605 GetFilename("data.txt.crdownload").c_str(), | |
| 1606 GetFilename("data.txt").c_str()))); | |
| 1607 } | |
| 1608 | |
| 1609 // Valid file URLs are valid URLs. | |
| 1610 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1611 DownloadExtensionTest_Download_File) { | |
| 1612 LoadExtension("downloads_split"); | |
| 1613 CHECK(StartTestServer()); | |
| 1614 std::string download_url = "file:///"; | |
| 1615 GoOnTheRecord(); | |
| 1616 | |
| 1617 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1618 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1619 "[{\"url\": \"%s\"," | |
| 1620 " \"filename\": \"file.txt\"}]", download_url.c_str()))); | |
| 1621 ASSERT_TRUE(result.get()); | |
| 1622 int result_id = -1; | |
| 1623 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 1624 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 1625 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 1626 ASSERT_TRUE(item); | |
| 1627 ScopedCancellingItem canceller(item); | |
| 1628 #if defined(OS_WIN) | |
| 1629 download_url += "/"; | |
| 1630 #endif | |
| 1631 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 1632 | |
| 1633 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
| 1634 base::StringPrintf("[{\"danger\": \"safe\"," | |
| 1635 " \"filename\": \"%s\"," | |
| 1636 " \"incognito\": false," | |
| 1637 " \"mime\": \"text/html\"," | |
| 1638 " \"paused\": false," | |
| 1639 " \"url\": \"%s\"}]", | |
| 1640 GetFilename("file.txt.crdownload").c_str(), | |
| 1641 download_url.c_str()))); | |
| 1642 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
| 1643 base::StringPrintf("[{\"id\": %d," | |
| 1644 " \"filename\": {" | |
| 1645 " \"old\": \"%s\"," | |
| 1646 " \"new\": \"%s\"}," | |
| 1647 " \"state\": {" | |
| 1648 " \"old\": \"in_progress\"," | |
| 1649 " \"new\": \"complete\"}}]", | |
| 1650 result_id, | |
| 1651 GetFilename("file.txt.crdownload").c_str(), | |
| 1652 GetFilename("file.txt").c_str()))); | |
| 1653 } | |
| 1654 | |
| 1655 // Test that auth-basic-succeed would fail if the resource requires the | |
| 1656 // Authorization header and chrome fails to propagate it back to the server. | |
| 1657 // This tests both that testserver.py does not succeed when it should fail as | |
| 1658 // well as how the downloads extension API exposes the failure to extensions. | |
| 1659 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1660 DownloadExtensionTest_Download_AuthBasic_Fail) { | |
| 1661 LoadExtension("downloads_split"); | |
| 1662 CHECK(StartTestServer()); | |
| 1663 std::string download_url = GetURL("auth-basic"); | |
| 1664 GoOnTheRecord(); | |
| 1665 | |
| 1666 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1667 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1668 "[{\"url\": \"%s\"," | |
| 1669 " \"filename\": \"auth-basic-fail.txt\"}]", | |
| 1670 download_url.c_str()))); | |
| 1671 ASSERT_TRUE(result.get()); | |
| 1672 int result_id = -1; | |
| 1673 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 1674 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 1675 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 1676 ASSERT_TRUE(item); | |
| 1677 ScopedCancellingItem canceller(item); | |
| 1678 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 1679 | |
| 1680 ASSERT_TRUE(WaitForInterruption(item, 30, base::StringPrintf( | |
| 1681 "[{\"danger\": \"safe\"," | |
| 1682 " \"incognito\": false," | |
| 1683 " \"mime\": \"text/html\"," | |
| 1684 " \"paused\": false," | |
| 1685 " \"url\": \"%s\"}]", | |
| 1686 download_url.c_str()))); | |
| 1687 } | |
| 1688 | |
| 1689 // Test that DownloadsDownloadFunction propagates |headers| to the URLRequest. | |
| 1690 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1691 DownloadExtensionTest_Download_Headers) { | |
| 1692 LoadExtension("downloads_split"); | |
| 1693 CHECK(StartTestServer()); | |
| 1694 std::string download_url = GetURL("files/downloads/a_zip_file.zip?" | |
| 1695 "expected_headers=Foo:bar&expected_headers=Qx:yo"); | |
| 1696 GoOnTheRecord(); | |
| 1697 | |
| 1698 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1699 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1700 "[{\"url\": \"%s\"," | |
| 1701 " \"filename\": \"headers-succeed.txt\"," | |
| 1702 " \"headers\": [" | |
| 1703 " {\"name\": \"Foo\", \"value\": \"bar\"}," | |
| 1704 " {\"name\": \"Qx\", \"value\":\"yo\"}]}]", | |
| 1705 download_url.c_str()))); | |
| 1706 ASSERT_TRUE(result.get()); | |
| 1707 int result_id = -1; | |
| 1708 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 1709 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 1710 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 1711 ASSERT_TRUE(item); | |
| 1712 ScopedCancellingItem canceller(item); | |
| 1713 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 1714 | |
| 1715 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
| 1716 base::StringPrintf("[{\"danger\": \"safe\"," | |
| 1717 " \"incognito\": false," | |
| 1718 " \"mime\": \"application/octet-stream\"," | |
| 1719 " \"paused\": false," | |
| 1720 " \"url\": \"%s\"}]", | |
| 1721 download_url.c_str()))); | |
| 1722 std::string incomplete_filename = GetFilename( | |
| 1723 "headers-succeed.txt.crdownload"); | |
| 1724 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
| 1725 base::StringPrintf("[{\"id\": %d," | |
| 1726 " \"filename\": {" | |
| 1727 " \"old\": \"%s\"," | |
| 1728 " \"new\": \"%s\"}," | |
| 1729 " \"state\": {" | |
| 1730 " \"old\": \"in_progress\"," | |
| 1731 " \"new\": \"complete\"}}]", | |
| 1732 result_id, | |
| 1733 incomplete_filename.c_str(), | |
| 1734 GetFilename("headers-succeed.txt").c_str()))); | |
| 1735 } | |
| 1736 | |
| 1737 // Test that headers-succeed would fail if the resource requires the headers and | |
| 1738 // chrome fails to propagate them back to the server. This tests both that | |
| 1739 // testserver.py does not succeed when it should fail as well as how the | |
| 1740 // downloads extension api exposes the failure to extensions. | |
| 1741 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1742 DownloadExtensionTest_Download_Headers_Fail) { | |
| 1743 LoadExtension("downloads_split"); | |
| 1744 CHECK(StartTestServer()); | |
| 1745 std::string download_url = GetURL("files/downloads/a_zip_file.zip?" | |
| 1746 "expected_headers=Foo:bar&expected_headers=Qx:yo"); | |
| 1747 GoOnTheRecord(); | |
| 1748 | |
| 1749 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1750 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1751 "[{\"url\": \"%s\"," | |
| 1752 " \"filename\": \"headers-fail.txt\"}]", | |
| 1753 download_url.c_str()))); | |
| 1754 ASSERT_TRUE(result.get()); | |
| 1755 int result_id = -1; | |
| 1756 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 1757 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 1758 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 1759 ASSERT_TRUE(item); | |
| 1760 ScopedCancellingItem canceller(item); | |
| 1761 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 1762 | |
| 1763 ASSERT_TRUE(WaitForInterruption(item, 33, base::StringPrintf( | |
| 1764 "[{\"danger\": \"safe\"," | |
| 1765 " \"incognito\": false," | |
| 1766 " \"bytesReceived\": 0," | |
| 1767 " \"mime\": \"\"," | |
| 1768 " \"paused\": false," | |
| 1769 " \"url\": \"%s\"}]", | |
| 1770 download_url.c_str()))); | |
| 1771 } | |
| 1772 | |
| 1773 // Test that DownloadsDownloadFunction propagates the Authorization header | |
| 1774 // correctly. | |
| 1775 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1776 DownloadExtensionTest_Download_AuthBasic) { | |
| 1777 LoadExtension("downloads_split"); | |
| 1778 CHECK(StartTestServer()); | |
| 1779 std::string download_url = GetURL("auth-basic"); | |
| 1780 // This is just base64 of 'username:secret'. | |
| 1781 static const char* kAuthorization = "dXNlcm5hbWU6c2VjcmV0"; | |
| 1782 GoOnTheRecord(); | |
| 1783 | |
| 1784 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1785 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1786 "[{\"url\": \"%s\"," | |
| 1787 " \"filename\": \"auth-basic-succeed.txt\"," | |
| 1788 " \"headers\": [{" | |
| 1789 " \"name\": \"Authorization\"," | |
| 1790 " \"value\": \"Basic %s\"}]}]", | |
| 1791 download_url.c_str(), kAuthorization))); | |
| 1792 ASSERT_TRUE(result.get()); | |
| 1793 int result_id = -1; | |
| 1794 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 1795 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 1796 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 1797 ASSERT_TRUE(item); | |
| 1798 ScopedCancellingItem canceller(item); | |
| 1799 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 1800 | |
| 1801 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
| 1802 base::StringPrintf("[{\"danger\": \"safe\"," | |
| 1803 " \"incognito\": false," | |
| 1804 " \"mime\": \"text/html\"," | |
| 1805 " \"paused\": false," | |
| 1806 " \"url\": \"%s\"}]", download_url.c_str()))); | |
| 1807 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
| 1808 base::StringPrintf("[{\"id\": %d," | |
| 1809 " \"state\": {" | |
| 1810 " \"old\": \"in_progress\"," | |
| 1811 " \"new\": \"complete\"}}]", result_id))); | |
| 1812 } | |
| 1813 | |
| 1814 // Test that DownloadsDownloadFunction propagates the |method| and |body| | |
| 1815 // parameters to the URLRequest. | |
| 1816 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1817 DownloadExtensionTest_Download_Post) { | |
| 1818 LoadExtension("downloads_split"); | |
| 1819 CHECK(StartTestServer()); | |
| 1820 std::string download_url = GetURL("files/post/downloads/a_zip_file.zip?" | |
| 1821 "expected_body=BODY"); | |
| 1822 GoOnTheRecord(); | |
| 1823 | |
| 1824 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1825 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1826 "[{\"url\": \"%s\"," | |
| 1827 " \"filename\": \"post-succeed.txt\"," | |
| 1828 " \"method\": \"POST\"," | |
| 1829 " \"body\": \"BODY\"}]", | |
| 1830 download_url.c_str()))); | |
| 1831 ASSERT_TRUE(result.get()); | |
| 1832 int result_id = -1; | |
| 1833 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 1834 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 1835 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 1836 ASSERT_TRUE(item); | |
| 1837 ScopedCancellingItem canceller(item); | |
| 1838 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 1839 | |
| 1840 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
| 1841 base::StringPrintf("[{\"danger\": \"safe\"," | |
| 1842 " \"incognito\": false," | |
| 1843 " \"mime\": \"application/octet-stream\"," | |
| 1844 " \"paused\": false," | |
| 1845 " \"bytesReceived\": 164," | |
| 1846 " \"url\": \"%s\"}]", download_url.c_str()))); | |
| 1847 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
| 1848 base::StringPrintf("[{\"id\": %d," | |
| 1849 " \"state\": {" | |
| 1850 " \"old\": \"in_progress\"," | |
| 1851 " \"new\": \"complete\"}}]", result_id))); | |
| 1852 } | |
| 1853 | |
| 1854 // Test that downloadPostSuccess would fail if the resource requires the POST | |
| 1855 // method, and chrome fails to propagate the |method| parameter back to the | |
| 1856 // server. This tests both that testserver.py does not succeed when it should | |
| 1857 // fail, and this tests how the downloads extension api exposes the failure to | |
| 1858 // extensions. | |
| 1859 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1860 DownloadExtensionTest_Download_Post_Get) { | |
| 1861 LoadExtension("downloads_split"); | |
| 1862 CHECK(StartTestServer()); | |
| 1863 std::string download_url = GetURL("files/post/downloads/a_zip_file.zip?" | |
| 1864 "expected_body=BODY"); | |
| 1865 GoOnTheRecord(); | |
| 1866 | |
| 1867 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1868 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1869 "[{\"url\": \"%s\"," | |
| 1870 " \"body\": \"BODY\"," | |
| 1871 " \"filename\": \"post-get.txt\"}]", | |
| 1872 download_url.c_str()))); | |
| 1873 ASSERT_TRUE(result.get()); | |
| 1874 int result_id = -1; | |
| 1875 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 1876 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 1877 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 1878 ASSERT_TRUE(item); | |
| 1879 ScopedCancellingItem canceller(item); | |
| 1880 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 1881 | |
| 1882 ASSERT_TRUE(WaitForInterruption(item, 33, base::StringPrintf( | |
| 1883 "[{\"danger\": \"safe\"," | |
| 1884 " \"incognito\": false," | |
| 1885 " \"mime\": \"\"," | |
| 1886 " \"paused\": false," | |
| 1887 " \"id\": %d," | |
| 1888 " \"url\": \"%s\"}]", | |
| 1889 result_id, | |
| 1890 download_url.c_str()))); | |
| 1891 } | |
| 1892 | |
| 1893 // Test that downloadPostSuccess would fail if the resource requires the POST | |
| 1894 // method, and chrome fails to propagate the |body| parameter back to the | |
| 1895 // server. This tests both that testserver.py does not succeed when it should | |
| 1896 // fail, and this tests how the downloads extension api exposes the failure to | |
| 1897 // extensions. | |
| 1898 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1899 DownloadExtensionTest_Download_Post_NoBody) { | |
| 1900 LoadExtension("downloads_split"); | |
| 1901 CHECK(StartTestServer()); | |
| 1902 std::string download_url = GetURL("files/post/downloads/a_zip_file.zip?" | |
| 1903 "expected_body=BODY"); | |
| 1904 GoOnTheRecord(); | |
| 1905 | |
| 1906 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1907 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1908 "[{\"url\": \"%s\"," | |
| 1909 " \"method\": \"POST\"," | |
| 1910 " \"filename\": \"post-nobody.txt\"}]", | |
| 1911 download_url.c_str()))); | |
| 1912 ASSERT_TRUE(result.get()); | |
| 1913 int result_id = -1; | |
| 1914 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 1915 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 1916 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 1917 ASSERT_TRUE(item); | |
| 1918 ScopedCancellingItem canceller(item); | |
| 1919 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 1920 | |
| 1921 ASSERT_TRUE(WaitForInterruption(item, 33, base::StringPrintf( | |
| 1922 "[{\"danger\": \"safe\"," | |
| 1923 " \"incognito\": false," | |
| 1924 " \"mime\": \"\"," | |
| 1925 " \"paused\": false," | |
| 1926 " \"id\": %d," | |
| 1927 " \"url\": \"%s\"}]", | |
| 1928 result_id, | |
| 1929 download_url.c_str()))); | |
| 1930 } | |
| 1931 | |
| 1932 // Test that cancel()ing an in-progress download causes its state to transition | |
| 1933 // to interrupted, and test that that state transition is detectable by an | |
| 1934 // onChanged event listener. TODO(benjhayden): Test other sources of | |
| 1935 // interruptions such as server death. | |
| 1936 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1937 DownloadExtensionTest_Download_Cancel) { | |
| 1938 LoadExtension("downloads_split"); | |
| 1939 CHECK(StartTestServer()); | |
| 1940 std::string download_url = GetURL("download-known-size"); | |
| 1941 GoOnTheRecord(); | |
| 1942 | |
| 1943 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1944 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1945 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
| 1946 ASSERT_TRUE(result.get()); | |
| 1947 int result_id = -1; | |
| 1948 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 1949 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 1950 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 1951 ASSERT_TRUE(item); | |
| 1952 ScopedCancellingItem canceller(item); | |
| 1953 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 1954 | |
| 1955 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
| 1956 base::StringPrintf("[{\"danger\": \"safe\"," | |
| 1957 " \"incognito\": false," | |
| 1958 " \"mime\": \"application/octet-stream\"," | |
| 1959 " \"paused\": false," | |
| 1960 " \"id\": %d," | |
| 1961 " \"url\": \"%s\"}]", | |
| 1962 result_id, | |
| 1963 download_url.c_str()))); | |
| 1964 item->Cancel(true); | |
| 1965 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
| 1966 base::StringPrintf("[{\"id\": %d," | |
| 1967 " \"error\": {\"new\": 40}," | |
| 1968 " \"state\": {" | |
| 1969 " \"old\": \"in_progress\"," | |
| 1970 " \"new\": \"interrupted\"}}]", | |
| 1971 result_id))); | |
| 1972 } | |
| 1973 | |
| 1974 // Test downloading filesystem: URLs. | |
| 1975 // NOTE: chrome disallows creating HTML5 FileSystem Files in incognito. | |
| 1976 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
| 1977 DownloadExtensionTest_Download_FileSystemURL) { | |
| 1978 static const char* kHTML5FileCreated = "html5_file_created"; | |
| 1979 LoadExtension("downloads_split"); | |
| 1980 fileapi::FileSystemContext* fs = BrowserContext::GetFileSystemContext( | |
| 1981 browser()->profile()); | |
| 1982 fileapi::FileSystemContext::OpenFileSystemCallback fs_opened = base::Bind( | |
| 1983 &OpenFileSystemCallback, | |
| 1984 base::Unretained(fs), | |
| 1985 "on_record.txt", | |
| 1986 browser()->profile()); | |
| 1987 fs->OpenFileSystem(GURL(GetExtensionURL()), | |
| 1988 fileapi::kFileSystemTypeTemporary, | |
| 1989 true/*create*/, | |
| 1990 fs_opened); | |
| 1991 ASSERT_TRUE(WaitFor(kHTML5FileCreated, "on_record.txt")); | |
| 1992 | |
| 1993 std::string download_url = "filesystem:" + GetExtensionURL() + | |
| 1994 "temporary/on_record.txt"; | |
| 1995 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
| 1996 new DownloadsDownloadFunction(), base::StringPrintf( | |
| 1997 "[{\"url\": \"%s\"}]", download_url.c_str()))); | |
| 1998 ASSERT_TRUE(result.get()); | |
| 1999 int result_id = -1; | |
| 2000 ASSERT_TRUE(result->GetAsInteger(&result_id)); | |
| 2001 | |
| 2002 DownloadItem* item = GetCurrentManager()->GetActiveDownloadItem(result_id); | |
| 2003 if (!item) item = GetCurrentManager()->GetDownloadItem(result_id); | |
| 2004 ASSERT_TRUE(item); | |
| 2005 ScopedCancellingItem canceller(item); | |
| 2006 ASSERT_EQ(download_url, item->GetURL().spec()); | |
| 2007 | |
| 2008 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadCreated, | |
| 2009 base::StringPrintf("[{\"danger\": \"safe\"," | |
| 2010 " \"filename\": \"%s\"," | |
| 2011 " \"incognito\": false," | |
| 2012 " \"mime\": \"text/plain\"," | |
| 2013 " \"paused\": false," | |
| 2014 " \"url\": \"%s\"}]", | |
| 2015 GetFilename("on_record.txt.crdownload").c_str(), | |
| 2016 download_url.c_str()))); | |
| 2017 ASSERT_TRUE(WaitFor(extension_event_names::kOnDownloadChanged, | |
| 2018 base::StringPrintf("[{\"id\": %d," | |
| 2019 " \"filename\": {" | |
| 2020 " \"old\": \"%s\"," | |
| 2021 " \"new\": \"%s\"}," | |
| 2022 " \"state\": {" | |
| 2023 " \"old\": \"in_progress\"," | |
| 2024 " \"new\": \"complete\"}}]", | |
| 2025 result_id, | |
| 2026 GetFilename("on_record.txt.crdownload").c_str(), | |
| 2027 GetFilename("on_record.txt").c_str()))); | |
| 2028 } | |
| OLD | NEW |