OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include <algorithm> | |
6 | |
7 #include "base/file_util.h" | |
8 #include "base/scoped_temp_dir.h" | |
9 #include "base/stringprintf.h" | |
10 #include "chrome/browser/download/download_extension_api.h" | |
11 #include "chrome/browser/download/download_file_icon_extractor.h" | |
12 #include "chrome/browser/download/download_service.h" | |
13 #include "chrome/browser/download/download_service_factory.h" | |
14 #include "chrome/browser/download/download_test_observer.h" | |
15 #include "chrome/browser/extensions/extension_function_test_utils.h" | |
16 #include "chrome/browser/net/url_request_mock_util.h" | |
17 #include "chrome/browser/prefs/pref_service.h" | |
18 #include "chrome/browser/profiles/profile.h" | |
19 #include "chrome/browser/ui/browser.h" | |
20 #include "chrome/common/pref_names.h" | |
21 #include "chrome/test/base/in_process_browser_test.h" | |
22 #include "chrome/test/base/ui_test_utils.h" | |
23 #include "content/public/browser/browser_thread.h" | |
24 #include "content/public/browser/download_manager.h" | |
25 #include "content/public/browser/download_persistent_store_info.h" | |
26 #include "content/test/net/url_request_slow_download_job.h" | |
27 #include "net/base/data_url.h" | |
28 #include "net/base/net_util.h" | |
29 #include "ui/gfx/codec/png_codec.h" | |
30 | |
31 using content::BrowserThread; | |
32 using content::DownloadItem; | |
33 using content::DownloadManager; | |
34 using content::DownloadPersistentStoreInfo; | |
35 | |
36 namespace { | |
37 | |
38 // Comparator that orders download items by their ID. Can be used with | |
39 // std::sort. | |
40 struct DownloadIdComparator { | |
41 bool operator() (DownloadItem* first, DownloadItem* second) { | |
42 return first->GetId() < second->GetId(); | |
43 } | |
44 }; | |
45 | |
46 class DownloadExtensionTest : public InProcessBrowserTest { | |
47 protected: | |
48 // Used with CreateHistoryDownloads | |
49 struct HistoryDownloadInfo { | |
50 // Filename to use. CreateHistoryDownloads will append this filename to the | |
51 // temporary downloads directory specified by downloads_directory(). | |
52 const FilePath::CharType* filename; | |
53 | |
54 // State for the download. Note that IN_PROGRESS downloads will be created | |
55 // as CANCELLED. | |
56 DownloadItem::DownloadState state; | |
57 | |
58 // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS | |
59 // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT. | |
60 content::DownloadDangerType danger_type; | |
61 }; | |
62 | |
63 virtual Browser* current_browser() { return browser(); } | |
64 | |
65 // InProcessBrowserTest | |
66 virtual void SetUpOnMainThread() OVERRIDE { | |
67 BrowserThread::PostTask( | |
68 BrowserThread::IO, FROM_HERE, | |
69 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); | |
70 InProcessBrowserTest::SetUpOnMainThread(); | |
71 CreateAndSetDownloadsDirectory(); | |
72 current_browser()->profile()->GetPrefs()->SetBoolean( | |
73 prefs::kPromptForDownload, false); | |
74 GetDownloadManager()->RemoveAllDownloads(); | |
75 } | |
76 | |
77 virtual DownloadManager* GetDownloadManager() { | |
78 DownloadService* download_service = | |
79 DownloadServiceFactory::GetForProfile(current_browser()->profile()); | |
80 return download_service->GetDownloadManager(); | |
81 } | |
82 | |
83 // Creates a set of history downloads based on the provided |history_info| | |
84 // array. |count| is the number of elements in |history_info|. On success, | |
85 // |items| will contain |count| DownloadItems in the order that they were | |
86 // specified in |history_info|. Returns true on success and false otherwise. | |
87 bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info, | |
88 size_t count, | |
89 DownloadManager::DownloadVector* items) { | |
90 DownloadIdComparator download_id_comparator; | |
91 base::Time current = base::Time::Now(); | |
92 std::vector<DownloadPersistentStoreInfo> entries; | |
93 entries.reserve(count); | |
94 for (size_t i = 0; i < count; ++i) { | |
95 DownloadPersistentStoreInfo entry( | |
96 downloads_directory().Append(history_info[i].filename), | |
97 GURL(), GURL(), // URL, referrer | |
98 current, current, // start_time, end_time | |
99 1, 1, // received_bytes, total_bytes | |
100 history_info[i].state, // state | |
101 i + 1, // db_handle | |
102 false); // opened | |
103 entries.push_back(entry); | |
104 } | |
105 GetDownloadManager()->OnPersistentStoreQueryComplete(&entries); | |
106 GetDownloadManager()->GetAllDownloads(FilePath(), items); | |
107 EXPECT_EQ(count, items->size()); | |
108 if (count != items->size()) | |
109 return false; | |
110 | |
111 // Order by ID so that they are in the order that we created them. | |
112 std::sort(items->begin(), items->end(), download_id_comparator); | |
113 // Set the danger type if necessary. | |
114 for (size_t i = 0; i < count; ++i) { | |
115 if (history_info[i].danger_type != | |
116 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) { | |
117 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT, | |
118 history_info[i].danger_type); | |
119 items->at(i)->OnContentCheckCompleted(history_info[i].danger_type); | |
120 } | |
121 } | |
122 return true; | |
123 } | |
124 | |
125 void CreateSlowTestDownloads( | |
126 size_t count, DownloadManager::DownloadVector* items) { | |
127 for (size_t i = 0; i < count; ++i) { | |
128 scoped_ptr<DownloadTestObserver> observer( | |
129 CreateInProgressDownloadObserver(1)); | |
130 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); | |
131 ui_test_utils::NavigateToURLWithDisposition( | |
132 current_browser(), slow_download_url, CURRENT_TAB, | |
133 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | |
134 observer->WaitForFinished(); | |
135 EXPECT_EQ( | |
136 1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS)); | |
137 // We don't expect a select file dialog. | |
138 ASSERT_FALSE(observer->select_file_dialog_seen()); | |
139 } | |
140 GetDownloadManager()->GetAllDownloads(FilePath(), items); | |
141 ASSERT_EQ(count, items->size()); | |
142 } | |
143 | |
144 DownloadItem* CreateSlowTestDownload() { | |
145 scoped_ptr<DownloadTestObserver> observer( | |
146 CreateInProgressDownloadObserver(1)); | |
147 GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl); | |
148 DownloadManager* manager = GetDownloadManager(); | |
149 | |
150 EXPECT_EQ(0, manager->InProgressCount()); | |
151 if (manager->InProgressCount() != 0) | |
152 return NULL; | |
153 | |
154 ui_test_utils::NavigateToURLWithDisposition( | |
155 current_browser(), slow_download_url, CURRENT_TAB, | |
156 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | |
157 | |
158 observer->WaitForFinished(); | |
159 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS)); | |
160 // We don't expect a select file dialog. | |
161 if (observer->select_file_dialog_seen()) | |
162 return NULL; | |
163 | |
164 DownloadManager::DownloadVector items; | |
165 manager->GetAllDownloads(FilePath(), &items); | |
166 | |
167 DownloadItem* new_item = NULL; | |
168 for (DownloadManager::DownloadVector::iterator iter = items.begin(); | |
169 iter != items.end(); ++iter) { | |
170 if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) { | |
171 // There should be only one IN_PROGRESS item. | |
172 EXPECT_EQ(NULL, new_item); | |
173 new_item = *iter; | |
174 } | |
175 } | |
176 return new_item; | |
177 } | |
178 | |
179 void FinishPendingSlowDownloads() { | |
180 scoped_ptr<DownloadTestObserver> observer( | |
181 CreateDownloadObserver(1)); | |
182 GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl); | |
183 ui_test_utils::NavigateToURLWithDisposition( | |
184 current_browser(), finish_url, NEW_FOREGROUND_TAB, | |
185 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | |
186 observer->WaitForFinished(); | |
187 EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE)); | |
188 } | |
189 | |
190 DownloadTestObserver* CreateDownloadObserver(size_t download_count) { | |
191 return new DownloadTestObserverTerminal( | |
192 GetDownloadManager(), download_count, true, | |
193 DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); | |
194 } | |
195 | |
196 DownloadTestObserver* CreateInProgressDownloadObserver( | |
197 size_t download_count) { | |
198 return new DownloadTestObserverInProgress(GetDownloadManager(), | |
199 download_count, | |
200 true); | |
201 } | |
202 | |
203 extension_function_test_utils::RunFunctionFlags GetFlags() { | |
204 return current_browser()->profile()->IsOffTheRecord() ? | |
205 extension_function_test_utils::INCLUDE_INCOGNITO : | |
206 extension_function_test_utils::NONE; | |
207 } | |
208 | |
209 // extension_function_test_utils::RunFunction*() only uses browser for its | |
210 // profile(), so pass it the on-record browser so that it always uses the | |
211 // on-record profile. | |
212 | |
213 bool RunFunction(UIThreadExtensionFunction* function, | |
214 const std::string& args) { | |
215 // extension_function_test_utils::RunFunction() does not take | |
216 // ownership of |function|. | |
217 scoped_refptr<ExtensionFunction> function_owner(function); | |
218 return extension_function_test_utils::RunFunction( | |
219 function, args, browser(), GetFlags()); | |
220 } | |
221 | |
222 base::Value* RunFunctionAndReturnResult(UIThreadExtensionFunction* function, | |
223 const std::string& args) { | |
224 return extension_function_test_utils::RunFunctionAndReturnResult( | |
225 function, args, browser(), GetFlags()); | |
226 } | |
227 | |
228 std::string RunFunctionAndReturnError(UIThreadExtensionFunction* function, | |
229 const std::string& args) { | |
230 return extension_function_test_utils::RunFunctionAndReturnError( | |
231 function, args, browser(), GetFlags()); | |
232 } | |
233 | |
234 bool RunFunctionAndReturnString(UIThreadExtensionFunction* function, | |
235 const std::string& args, | |
236 std::string* result_string) { | |
237 scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args)); | |
238 EXPECT_TRUE(result.get()); | |
239 return result.get() && result->GetAsString(result_string); | |
240 } | |
241 | |
242 std::string DownloadItemIdAsArgList(const DownloadItem* download_item) { | |
243 return base::StringPrintf("[%d]", download_item->GetId()); | |
244 } | |
245 | |
246 // Checks if a data URL encoded image is a PNG of a given size. | |
247 void ExpectDataURLIsPNGWithSize(const std::string& url, int expected_size) { | |
248 std::string mime_type; | |
249 std::string charset; | |
250 std::string data; | |
251 EXPECT_FALSE(url.empty()); | |
252 EXPECT_TRUE(net::DataURL::Parse(GURL(url), &mime_type, &charset, &data)); | |
253 EXPECT_STREQ("image/png", mime_type.c_str()); | |
254 EXPECT_FALSE(data.empty()); | |
255 | |
256 if (data.empty()) | |
257 return; | |
258 | |
259 int width = -1, height = -1; | |
260 std::vector<unsigned char> decoded_data; | |
261 EXPECT_TRUE(gfx::PNGCodec::Decode( | |
262 reinterpret_cast<const unsigned char*>(data.c_str()), data.length(), | |
263 gfx::PNGCodec::FORMAT_RGBA, &decoded_data, | |
264 &width, &height)); | |
265 EXPECT_EQ(expected_size, width); | |
266 EXPECT_EQ(expected_size, height); | |
267 } | |
268 | |
269 const FilePath& downloads_directory() { | |
270 return downloads_directory_.path(); | |
271 } | |
272 | |
273 private: | |
274 void CreateAndSetDownloadsDirectory() { | |
275 ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir()); | |
276 current_browser()->profile()->GetPrefs()->SetFilePath( | |
277 prefs::kDownloadDefaultDirectory, | |
278 downloads_directory_.path()); | |
279 } | |
280 | |
281 ScopedTempDir downloads_directory_; | |
282 }; | |
283 | |
284 class DownloadExtensionTestIncognito : public DownloadExtensionTest { | |
285 public: | |
286 virtual Browser* current_browser() OVERRIDE { return current_browser_; } | |
287 | |
288 virtual void SetUpOnMainThread() OVERRIDE { | |
289 GoOnTheRecord(); | |
290 DownloadExtensionTest::SetUpOnMainThread(); | |
291 incognito_browser_ = CreateIncognitoBrowser(); | |
292 GoOffTheRecord(); | |
293 GetDownloadManager()->RemoveAllDownloads(); | |
294 } | |
295 | |
296 void GoOnTheRecord() { current_browser_ = browser(); } | |
297 void GoOffTheRecord() { current_browser_ = incognito_browser_; } | |
298 | |
299 private: | |
300 Browser* incognito_browser_; | |
301 Browser* current_browser_; | |
302 }; | |
303 | |
304 class MockIconExtractorImpl : public DownloadFileIconExtractor { | |
305 public: | |
306 MockIconExtractorImpl(const FilePath& path, IconLoader::IconSize icon_size, | |
307 const std::string& response) | |
308 : expected_path_(path), | |
309 expected_icon_size_(icon_size), | |
310 response_(response) { | |
311 } | |
312 virtual ~MockIconExtractorImpl() {} | |
313 | |
314 virtual bool ExtractIconURLForPath(const FilePath& path, | |
315 IconLoader::IconSize icon_size, | |
316 IconURLCallback callback) OVERRIDE { | |
317 EXPECT_STREQ(expected_path_.value().c_str(), path.value().c_str()); | |
318 EXPECT_EQ(expected_icon_size_, icon_size); | |
319 if (expected_path_ == path && | |
320 expected_icon_size_ == icon_size) { | |
321 callback_ = callback; | |
322 BrowserThread::PostTask( | |
323 BrowserThread::UI, FROM_HERE, | |
324 base::Bind(&MockIconExtractorImpl::RunCallback, | |
325 base::Unretained(this))); | |
326 return true; | |
327 } else { | |
328 return false; | |
329 } | |
330 } | |
331 | |
332 private: | |
333 void RunCallback() { | |
334 callback_.Run(response_); | |
335 } | |
336 | |
337 FilePath expected_path_; | |
338 IconLoader::IconSize expected_icon_size_; | |
339 std::string response_; | |
340 IconURLCallback callback_; | |
341 }; | |
342 | |
343 // Cancels the underlying DownloadItem when the ScopedCancellingItem goes out of | |
344 // scope. Like a scoped_ptr, but for DownloadItems. | |
345 class ScopedCancellingItem { | |
346 public: | |
347 explicit ScopedCancellingItem(DownloadItem* item) : item_(item) {} | |
348 ~ScopedCancellingItem() { | |
349 item_->Cancel(true); | |
350 } | |
351 DownloadItem* operator*() { return item_; } | |
352 DownloadItem* operator->() { return item_; } | |
353 DownloadItem* get() { return item_; } | |
354 private: | |
355 DownloadItem* item_; | |
356 DISALLOW_COPY_AND_ASSIGN(ScopedCancellingItem); | |
357 }; | |
358 | |
359 // Cancels all the underlying DownloadItems when the ScopedItemVectorCanceller | |
360 // goes out of scope. Generalization of ScopedCancellingItem to many | |
361 // DownloadItems. | |
362 class ScopedItemVectorCanceller { | |
363 public: | |
364 explicit ScopedItemVectorCanceller(DownloadManager::DownloadVector* items) | |
365 : items_(items) { | |
366 } | |
367 ~ScopedItemVectorCanceller() { | |
368 for (DownloadManager::DownloadVector::const_iterator item = items_->begin(); | |
369 item != items_->end(); ++item) { | |
370 if ((*item)->IsInProgress()) | |
371 (*item)->Cancel(true); | |
372 } | |
373 } | |
374 | |
375 private: | |
376 DownloadManager::DownloadVector* items_; | |
377 DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller); | |
378 }; | |
379 | |
380 } // namespace | |
381 | |
382 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_PauseResumeCancel) { | |
383 DownloadItem* download_item = CreateSlowTestDownload(); | |
384 ASSERT_TRUE(download_item); | |
385 | |
386 // Call pause(). It should succeed and the download should be paused on | |
387 // return. | |
388 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), | |
389 DownloadItemIdAsArgList(download_item))); | |
390 EXPECT_TRUE(download_item->IsPaused()); | |
391 | |
392 // Calling pause() twice shouldn't be an error. | |
393 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), | |
394 DownloadItemIdAsArgList(download_item))); | |
395 EXPECT_TRUE(download_item->IsPaused()); | |
396 | |
397 // Now try resuming this download. It should succeed. | |
398 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), | |
399 DownloadItemIdAsArgList(download_item))); | |
400 EXPECT_FALSE(download_item->IsPaused()); | |
401 | |
402 // Resume again. Resuming a download that wasn't paused is not an error. | |
403 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), | |
404 DownloadItemIdAsArgList(download_item))); | |
405 EXPECT_FALSE(download_item->IsPaused()); | |
406 | |
407 // Pause again. | |
408 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), | |
409 DownloadItemIdAsArgList(download_item))); | |
410 EXPECT_TRUE(download_item->IsPaused()); | |
411 | |
412 // And now cancel. | |
413 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), | |
414 DownloadItemIdAsArgList(download_item))); | |
415 EXPECT_TRUE(download_item->IsCancelled()); | |
416 | |
417 // Cancel again. Shouldn't have any effect. | |
418 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), | |
419 DownloadItemIdAsArgList(download_item))); | |
420 EXPECT_TRUE(download_item->IsCancelled()); | |
421 | |
422 // Calling paused on a non-active download yields kInvalidOperationError. | |
423 std::string error = RunFunctionAndReturnError( | |
424 new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item)); | |
425 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
426 error.c_str()); | |
427 | |
428 // Calling resume on a non-active download yields kInvalidOperationError | |
429 error = RunFunctionAndReturnError( | |
430 new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item)); | |
431 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
432 error.c_str()); | |
433 | |
434 // Calling pause()/resume()/cancel() with invalid download Ids is | |
435 // tested in the API test (DownloadsApiTest). | |
436 } | |
437 | |
438 // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted | |
439 // download items. | |
440 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_Active) { | |
441 DownloadItem* download_item = CreateSlowTestDownload(); | |
442 ASSERT_TRUE(download_item); | |
443 | |
444 // Get the icon for the in-progress download. This call should succeed even | |
445 // if the file type isn't registered. | |
446 std::string args = base::StringPrintf("[%d, {}]", download_item->GetId()); | |
447 std::string result_string; | |
448 EXPECT_TRUE(RunFunctionAndReturnString(new DownloadsGetFileIconFunction(), | |
449 args, &result_string)); | |
450 | |
451 // Note: We are checking if the result is a Data URL that has encoded | |
452 // image/png data for an icon of a specific size. Of these, only the icon size | |
453 // is specified in the API contract. The image type (image/png) and URL type | |
454 // (Data) are implementation details. | |
455 | |
456 // The default size for icons returned by getFileIcon() is 32x32. | |
457 ExpectDataURLIsPNGWithSize(result_string, 32); | |
458 | |
459 // Test whether the correct path is being pased into the icon extractor. | |
460 FilePath expected_path(download_item->GetTargetFilePath()); | |
461 scoped_refptr<DownloadsGetFileIconFunction> function( | |
462 new DownloadsGetFileIconFunction()); | |
463 function->SetIconExtractorForTesting(new MockIconExtractorImpl( | |
464 expected_path, IconLoader::NORMAL, "foo")); | |
465 EXPECT_TRUE(RunFunctionAndReturnString(function.release(), args, | |
466 &result_string)); | |
467 | |
468 // Now try a 16x16 icon. | |
469 args = base::StringPrintf("[%d, {\"size\": 16}]", download_item->GetId()); | |
470 EXPECT_TRUE(RunFunctionAndReturnString(new DownloadsGetFileIconFunction(), | |
471 args, &result_string)); | |
472 ExpectDataURLIsPNGWithSize(result_string, 16); | |
473 | |
474 // Explicitly asking for 32x32 should give us a 32x32 icon. | |
475 args = base::StringPrintf("[%d, {\"size\": 32}]", download_item->GetId()); | |
476 EXPECT_TRUE(RunFunctionAndReturnString(new DownloadsGetFileIconFunction(), | |
477 args, &result_string)); | |
478 ExpectDataURLIsPNGWithSize(result_string, 32); | |
479 | |
480 // Finish the download and try again. | |
481 FinishPendingSlowDownloads(); | |
482 EXPECT_EQ(DownloadItem::COMPLETE, download_item->GetState()); | |
483 EXPECT_TRUE(RunFunctionAndReturnString(new DownloadsGetFileIconFunction(), | |
484 args, &result_string)); | |
485 ExpectDataURLIsPNGWithSize(result_string, 32); | |
486 | |
487 // Check the path passed to the icon extractor post-completion. | |
488 function = new DownloadsGetFileIconFunction(); | |
489 function->SetIconExtractorForTesting(new MockIconExtractorImpl( | |
490 expected_path, IconLoader::NORMAL, "foo")); | |
491 EXPECT_TRUE(RunFunctionAndReturnString(function.release(), args, | |
492 &result_string)); | |
493 | |
494 // Now create another download. | |
495 download_item = CreateSlowTestDownload(); | |
496 ASSERT_TRUE(download_item); | |
497 expected_path = download_item->GetTargetFilePath(); | |
498 | |
499 // Cancel the download. As long as the download has a target path, we should | |
500 // be able to query the file icon. | |
501 download_item->Cancel(true); | |
502 // Let cleanup complete on the FILE thread. | |
503 ui_test_utils::RunAllPendingInMessageLoop(BrowserThread::FILE); | |
504 args = base::StringPrintf("[%d, {\"size\": 32}]", download_item->GetId()); | |
505 EXPECT_TRUE(RunFunctionAndReturnString(new DownloadsGetFileIconFunction(), | |
506 args, &result_string)); | |
507 ExpectDataURLIsPNGWithSize(result_string, 32); | |
508 | |
509 // Check the path passed to the icon extractor post-cancellation. | |
510 function = new DownloadsGetFileIconFunction(); | |
511 function->SetIconExtractorForTesting(new MockIconExtractorImpl( | |
512 expected_path, IconLoader::NORMAL, "foo")); | |
513 EXPECT_TRUE(RunFunctionAndReturnString(function.release(), args, | |
514 &result_string)); | |
515 | |
516 // Simulate an error during icon load by invoking the mock with an empty | |
517 // result string. | |
518 function = new DownloadsGetFileIconFunction(); | |
519 function->SetIconExtractorForTesting(new MockIconExtractorImpl( | |
520 expected_path, IconLoader::NORMAL, "")); | |
521 std::string error = RunFunctionAndReturnError(function.release(), args); | |
522 EXPECT_STREQ(download_extension_errors::kIconNotFoundError, | |
523 error.c_str()); | |
524 | |
525 // Once the download item is deleted, we should return kInvalidOperationError. | |
526 download_item->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD); | |
527 error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args); | |
528 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
529 error.c_str()); | |
530 | |
531 // Asking for icons of other (invalid) sizes is tested in the API test | |
532 // (DownloadsApiTest). | |
533 } | |
534 | |
535 // Test that we can acquire file icons for history downloads regardless of | |
536 // whether they exist or not. If the file doesn't exist we should receive a | |
537 // generic icon from the OS/toolkit that may or may not be specific to the file | |
538 // type. | |
539 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_History) { | |
540 const HistoryDownloadInfo kHistoryInfo[] = { | |
541 { FILE_PATH_LITERAL("real.txt"), | |
542 DownloadItem::COMPLETE, | |
543 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | |
544 { FILE_PATH_LITERAL("fake.txt"), | |
545 DownloadItem::COMPLETE, | |
546 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | |
547 }; | |
548 DownloadManager::DownloadVector all_downloads; | |
549 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), | |
550 &all_downloads)); | |
551 | |
552 FilePath real_path = all_downloads[0]->GetFullPath(); | |
553 FilePath fake_path = all_downloads[1]->GetFullPath(); | |
554 | |
555 EXPECT_EQ(0, file_util::WriteFile(real_path, "", 0)); | |
556 ASSERT_TRUE(file_util::PathExists(real_path)); | |
557 ASSERT_FALSE(file_util::PathExists(fake_path)); | |
558 | |
559 for (DownloadManager::DownloadVector::iterator iter = all_downloads.begin(); | |
560 iter != all_downloads.end(); | |
561 ++iter) { | |
562 std::string args(base::StringPrintf("[%d, {\"size\": 32}]", | |
563 (*iter)->GetId())); | |
564 std::string result_string; | |
565 EXPECT_TRUE(RunFunctionAndReturnString( | |
566 new DownloadsGetFileIconFunction(), args, &result_string)); | |
567 // Note: We are checking if the result is a Data URL that has encoded | |
568 // image/png data for an icon of a specific size. Of these, only the icon | |
569 // size is specified in the API contract. The image type (image/png) and URL | |
570 // type (Data) are implementation details. | |
571 ExpectDataURLIsPNGWithSize(result_string, 32); | |
572 | |
573 // Use a MockIconExtractorImpl to test if the correct path is being passed | |
574 // into the DownloadFileIconExtractor. | |
575 scoped_refptr<DownloadsGetFileIconFunction> function( | |
576 new DownloadsGetFileIconFunction()); | |
577 function->SetIconExtractorForTesting(new MockIconExtractorImpl( | |
578 (*iter)->GetFullPath(), IconLoader::NORMAL, "hello")); | |
579 EXPECT_TRUE(RunFunctionAndReturnString(function.release(), args, | |
580 &result_string)); | |
581 EXPECT_STREQ("hello", result_string.c_str()); | |
582 } | |
583 | |
584 // The temporary files should be cleaned up when the ScopedTempDir is removed. | |
585 } | |
586 | |
587 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchEmptyQuery) { | |
588 ScopedCancellingItem item(CreateSlowTestDownload()); | |
589 ASSERT_TRUE(item.get()); | |
590 | |
591 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
592 new DownloadsSearchFunction(), "[{}]")); | |
593 ASSERT_TRUE(result.get()); | |
594 base::ListValue* result_list = NULL; | |
595 ASSERT_TRUE(result->GetAsList(&result_list)); | |
596 ASSERT_EQ(1UL, result_list->GetSize()); | |
597 } | |
598 | |
599 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
600 DownloadsApi_SearchFilenameRegex) { | |
601 const HistoryDownloadInfo kHistoryInfo[] = { | |
602 { FILE_PATH_LITERAL("foobar"), | |
603 DownloadItem::COMPLETE, | |
604 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | |
605 { FILE_PATH_LITERAL("baz"), | |
606 DownloadItem::COMPLETE, | |
607 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | |
608 }; | |
609 DownloadManager::DownloadVector all_downloads; | |
610 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), | |
611 &all_downloads)); | |
612 | |
613 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
614 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]")); | |
615 ASSERT_TRUE(result.get()); | |
616 base::ListValue* result_list = NULL; | |
617 ASSERT_TRUE(result->GetAsList(&result_list)); | |
618 ASSERT_EQ(1UL, result_list->GetSize()); | |
619 base::DictionaryValue* item_value = NULL; | |
620 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); | |
621 int item_id = -1; | |
622 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); | |
623 ASSERT_EQ(0, item_id); | |
624 } | |
625 | |
626 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchId) { | |
627 DownloadManager::DownloadVector items; | |
628 CreateSlowTestDownloads(2, &items); | |
629 ScopedItemVectorCanceller delete_items(&items); | |
630 | |
631 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
632 new DownloadsSearchFunction(), "[{\"id\": 0}]")); | |
633 ASSERT_TRUE(result.get()); | |
634 base::ListValue* result_list = NULL; | |
635 ASSERT_TRUE(result->GetAsList(&result_list)); | |
636 ASSERT_EQ(1UL, result_list->GetSize()); | |
637 base::DictionaryValue* item_value = NULL; | |
638 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); | |
639 int item_id = -1; | |
640 ASSERT_TRUE(item_value->GetInteger("id", &item_id)); | |
641 ASSERT_EQ(0, item_id); | |
642 } | |
643 | |
644 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, | |
645 DownloadsApi_SearchIdAndFilename) { | |
646 DownloadManager::DownloadVector items; | |
647 CreateSlowTestDownloads(2, &items); | |
648 ScopedItemVectorCanceller delete_items(&items); | |
649 | |
650 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
651 new DownloadsSearchFunction(), "[{\"id\": 0,\"filename\": \"foobar\"}]")); | |
652 ASSERT_TRUE(result.get()); | |
653 base::ListValue* result_list = NULL; | |
654 ASSERT_TRUE(result->GetAsList(&result_list)); | |
655 ASSERT_EQ(0UL, result_list->GetSize()); | |
656 } | |
657 | |
658 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchOrderBy) { | |
659 const HistoryDownloadInfo kHistoryInfo[] = { | |
660 { FILE_PATH_LITERAL("zzz"), | |
661 DownloadItem::COMPLETE, | |
662 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | |
663 { FILE_PATH_LITERAL("baz"), | |
664 DownloadItem::COMPLETE, | |
665 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | |
666 }; | |
667 DownloadManager::DownloadVector items; | |
668 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), | |
669 &items)); | |
670 | |
671 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
672 new DownloadsSearchFunction(), "[{\"orderBy\": \"filename\"}]")); | |
673 ASSERT_TRUE(result.get()); | |
674 base::ListValue* result_list = NULL; | |
675 ASSERT_TRUE(result->GetAsList(&result_list)); | |
676 ASSERT_EQ(2UL, result_list->GetSize()); | |
677 base::DictionaryValue* item0_value = NULL; | |
678 base::DictionaryValue* item1_value = NULL; | |
679 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); | |
680 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); | |
681 std::string item0_name, item1_name; | |
682 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); | |
683 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); | |
684 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); | |
685 ASSERT_LT(item0_name, item1_name); | |
686 } | |
687 | |
688 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchOrderByEmpty) { | |
689 const HistoryDownloadInfo kHistoryInfo[] = { | |
690 { FILE_PATH_LITERAL("zzz"), | |
691 DownloadItem::COMPLETE, | |
692 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | |
693 { FILE_PATH_LITERAL("baz"), | |
694 DownloadItem::COMPLETE, | |
695 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | |
696 }; | |
697 DownloadManager::DownloadVector items; | |
698 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), | |
699 &items)); | |
700 | |
701 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
702 new DownloadsSearchFunction(), "[{\"orderBy\": \"\"}]")); | |
703 ASSERT_TRUE(result.get()); | |
704 base::ListValue* result_list = NULL; | |
705 ASSERT_TRUE(result->GetAsList(&result_list)); | |
706 ASSERT_EQ(2UL, result_list->GetSize()); | |
707 base::DictionaryValue* item0_value = NULL; | |
708 base::DictionaryValue* item1_value = NULL; | |
709 ASSERT_TRUE(result_list->GetDictionary(0, &item0_value)); | |
710 ASSERT_TRUE(result_list->GetDictionary(1, &item1_value)); | |
711 std::string item0_name, item1_name; | |
712 ASSERT_TRUE(item0_value->GetString("filename", &item0_name)); | |
713 ASSERT_TRUE(item1_value->GetString("filename", &item1_name)); | |
714 ASSERT_GT(items[0]->GetFullPath().value(), items[1]->GetFullPath().value()); | |
715 ASSERT_GT(item0_name, item1_name); | |
716 } | |
717 | |
718 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchDanger) { | |
719 const HistoryDownloadInfo kHistoryInfo[] = { | |
720 { FILE_PATH_LITERAL("zzz"), | |
721 DownloadItem::COMPLETE, | |
722 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, | |
723 { FILE_PATH_LITERAL("baz"), | |
724 DownloadItem::COMPLETE, | |
725 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS } | |
726 }; | |
727 DownloadManager::DownloadVector items; | |
728 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), | |
729 &items)); | |
730 | |
731 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
732 new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]")); | |
733 ASSERT_TRUE(result.get()); | |
734 base::ListValue* result_list = NULL; | |
735 ASSERT_TRUE(result->GetAsList(&result_list)); | |
736 ASSERT_EQ(1UL, result_list->GetSize()); | |
737 } | |
738 | |
739 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchState) { | |
740 DownloadManager::DownloadVector items; | |
741 CreateSlowTestDownloads(2, &items); | |
742 ScopedItemVectorCanceller delete_items(&items); | |
743 | |
744 items[0]->Cancel(true); | |
745 | |
746 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
747 new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]")); | |
748 ASSERT_TRUE(result.get()); | |
749 base::ListValue* result_list = NULL; | |
750 ASSERT_TRUE(result->GetAsList(&result_list)); | |
751 ASSERT_EQ(1UL, result_list->GetSize()); | |
752 } | |
753 | |
754 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchLimit) { | |
755 DownloadManager::DownloadVector items; | |
756 CreateSlowTestDownloads(2, &items); | |
757 ScopedItemVectorCanceller delete_items(&items); | |
758 | |
759 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
760 new DownloadsSearchFunction(), "[{\"limit\": 1}]")); | |
761 ASSERT_TRUE(result.get()); | |
762 base::ListValue* result_list = NULL; | |
763 ASSERT_TRUE(result->GetAsList(&result_list)); | |
764 ASSERT_EQ(1UL, result_list->GetSize()); | |
765 } | |
766 | |
767 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchInvalid) { | |
768 std::string error = RunFunctionAndReturnError( | |
769 new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]"); | |
770 EXPECT_STREQ(download_extension_errors::kInvalidFilterError, | |
771 error.c_str()); | |
772 error = RunFunctionAndReturnError( | |
773 new DownloadsSearchFunction(), "[{\"danger\": \"goat\"}]"); | |
774 EXPECT_STREQ(download_extension_errors::kInvalidDangerTypeError, | |
775 error.c_str()); | |
776 error = RunFunctionAndReturnError( | |
777 new DownloadsSearchFunction(), "[{\"state\": \"goat\"}]"); | |
778 EXPECT_STREQ(download_extension_errors::kInvalidStateError, | |
779 error.c_str()); | |
780 error = RunFunctionAndReturnError( | |
781 new DownloadsSearchFunction(), "[{\"orderBy\": \"goat\"}]"); | |
782 EXPECT_STREQ(download_extension_errors::kInvalidOrderByError, | |
783 error.c_str()); | |
784 error = RunFunctionAndReturnError( | |
785 new DownloadsSearchFunction(), "[{\"limit\": -1}]"); | |
786 EXPECT_STREQ(download_extension_errors::kInvalidQueryLimit, | |
787 error.c_str()); | |
788 } | |
789 | |
790 IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_SearchPlural) { | |
791 const HistoryDownloadInfo kHistoryInfo[] = { | |
792 { FILE_PATH_LITERAL("aaa"), | |
793 DownloadItem::CANCELLED, | |
794 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }, | |
795 { FILE_PATH_LITERAL("zzz"), | |
796 DownloadItem::COMPLETE, | |
797 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, | |
798 { FILE_PATH_LITERAL("baz"), | |
799 DownloadItem::COMPLETE, | |
800 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT }, | |
801 }; | |
802 DownloadManager::DownloadVector items; | |
803 ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo), | |
804 &items)); | |
805 | |
806 scoped_ptr<base::Value> result(RunFunctionAndReturnResult( | |
807 new DownloadsSearchFunction(), "[{" | |
808 "\"state\": \"complete\", " | |
809 "\"danger\": \"content\", " | |
810 "\"orderBy\": \"filename\", " | |
811 "\"limit\": 1}]")); | |
812 ASSERT_TRUE(result.get()); | |
813 base::ListValue* result_list = NULL; | |
814 ASSERT_TRUE(result->GetAsList(&result_list)); | |
815 ASSERT_EQ(1UL, result_list->GetSize()); | |
816 base::DictionaryValue* item_value = NULL; | |
817 ASSERT_TRUE(result_list->GetDictionary(0, &item_value)); | |
818 FilePath::StringType item_name; | |
819 ASSERT_TRUE(item_value->GetString("filename", &item_name)); | |
820 ASSERT_EQ(items[2]->GetFullPath().value(), item_name); | |
821 } | |
822 | |
823 IN_PROC_BROWSER_TEST_F(DownloadExtensionTestIncognito, | |
824 DownloadsApi_SearchIncognito) { | |
825 scoped_ptr<base::Value> result_value; | |
826 base::ListValue* result_list = NULL; | |
827 base::DictionaryValue* result_dict = NULL; | |
828 FilePath::StringType filename; | |
829 bool is_incognito = false; | |
830 std::string error; | |
831 std::string on_item_arg; | |
832 std::string off_item_arg; | |
833 std::string result_string; | |
834 | |
835 // Set up one on-record item and one off-record item. | |
836 | |
837 GoOnTheRecord(); | |
838 DownloadItem* on_item = CreateSlowTestDownload(); | |
839 ASSERT_TRUE(on_item); | |
840 ASSERT_FALSE(on_item->IsOtr()); | |
841 on_item_arg = DownloadItemIdAsArgList(on_item); | |
842 | |
843 GoOffTheRecord(); | |
844 DownloadItem* off_item = CreateSlowTestDownload(); | |
845 ASSERT_TRUE(off_item); | |
846 ASSERT_TRUE(off_item->IsOtr()); | |
847 ASSERT_TRUE(on_item->GetFullPath() != off_item->GetFullPath()); | |
848 off_item_arg = DownloadItemIdAsArgList(off_item); | |
849 | |
850 // Extensions running in the incognito window should have access to both | |
851 // items because the Test extension is in spanning mode. | |
852 result_value.reset(RunFunctionAndReturnResult( | |
853 new DownloadsSearchFunction(), "[{}]")); | |
854 ASSERT_TRUE(result_value.get()); | |
855 ASSERT_TRUE(result_value->GetAsList(&result_list)); | |
856 ASSERT_EQ(2UL, result_list->GetSize()); | |
857 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict)); | |
858 ASSERT_TRUE(result_dict->GetString("filename", &filename)); | |
859 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito)); | |
860 EXPECT_TRUE(on_item->GetFullPath() == FilePath(filename)); | |
861 EXPECT_FALSE(is_incognito); | |
862 ASSERT_TRUE(result_list->GetDictionary(1, &result_dict)); | |
863 ASSERT_TRUE(result_dict->GetString("filename", &filename)); | |
864 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito)); | |
865 EXPECT_TRUE(off_item->GetFullPath() == FilePath(filename)); | |
866 EXPECT_TRUE(is_incognito); | |
867 | |
868 // Extensions running in the on-record window should have access only to the | |
869 // on-record item. | |
870 GoOnTheRecord(); | |
871 result_value.reset(RunFunctionAndReturnResult( | |
872 new DownloadsSearchFunction(), "[{}]")); | |
873 ASSERT_TRUE(result_value.get()); | |
874 ASSERT_TRUE(result_value->GetAsList(&result_list)); | |
875 ASSERT_EQ(1UL, result_list->GetSize()); | |
876 ASSERT_TRUE(result_list->GetDictionary(0, &result_dict)); | |
877 ASSERT_TRUE(result_dict->GetString("filename", &filename)); | |
878 EXPECT_TRUE(on_item->GetFullPath() == FilePath(filename)); | |
879 ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito)); | |
880 EXPECT_FALSE(is_incognito); | |
881 | |
882 // Pausing/Resuming the off-record item while on the record should return an | |
883 // error. Cancelling "non-existent" downloads is not an error. | |
884 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg); | |
885 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
886 error.c_str()); | |
887 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), | |
888 off_item_arg); | |
889 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
890 error.c_str()); | |
891 error = RunFunctionAndReturnError( | |
892 new DownloadsGetFileIconFunction(), | |
893 base::StringPrintf("[%d, {}]", off_item->GetId())); | |
894 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
895 error.c_str()); | |
896 | |
897 // TODO(benjhayden): Test incognito_split_mode() extension. | |
898 // TODO(benjhayden): Test download(), onCreated, onChanged, onErased. | |
899 | |
900 GoOffTheRecord(); | |
901 | |
902 // Do the FileIcon test for both the on- and off-items while off the record. | |
903 // NOTE(benjhayden): This does not include the FileIcon test from history, | |
904 // just active downloads. This shouldn't be a problem. | |
905 EXPECT_TRUE(RunFunctionAndReturnString( | |
906 new DownloadsGetFileIconFunction(), | |
907 base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string)); | |
908 EXPECT_TRUE(RunFunctionAndReturnString( | |
909 new DownloadsGetFileIconFunction(), | |
910 base::StringPrintf("[%d, {}]", off_item->GetId()), &result_string)); | |
911 | |
912 // Do the pause/resume/cancel test for both the on- and off-items while off | |
913 // the record. | |
914 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg)); | |
915 EXPECT_TRUE(on_item->IsPaused()); | |
916 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg)); | |
917 EXPECT_TRUE(on_item->IsPaused()); | |
918 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg)); | |
919 EXPECT_FALSE(on_item->IsPaused()); | |
920 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg)); | |
921 EXPECT_FALSE(on_item->IsPaused()); | |
922 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg)); | |
923 EXPECT_TRUE(on_item->IsPaused()); | |
924 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg)); | |
925 EXPECT_TRUE(on_item->IsCancelled()); | |
926 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg)); | |
927 EXPECT_TRUE(on_item->IsCancelled()); | |
928 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), on_item_arg); | |
929 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
930 error.c_str()); | |
931 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), on_item_arg); | |
932 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
933 error.c_str()); | |
934 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg)); | |
935 EXPECT_TRUE(off_item->IsPaused()); | |
936 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg)); | |
937 EXPECT_TRUE(off_item->IsPaused()); | |
938 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg)); | |
939 EXPECT_FALSE(off_item->IsPaused()); | |
940 EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg)); | |
941 EXPECT_FALSE(off_item->IsPaused()); | |
942 EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg)); | |
943 EXPECT_TRUE(off_item->IsPaused()); | |
944 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg)); | |
945 EXPECT_TRUE(off_item->IsCancelled()); | |
946 EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg)); | |
947 EXPECT_TRUE(off_item->IsCancelled()); | |
948 error = RunFunctionAndReturnError(new DownloadsPauseFunction(), | |
949 off_item_arg); | |
950 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
951 error.c_str()); | |
952 error = RunFunctionAndReturnError(new DownloadsResumeFunction(), | |
953 off_item_arg); | |
954 EXPECT_STREQ(download_extension_errors::kInvalidOperationError, | |
955 error.c_str()); | |
956 } | |
OLD | NEW |