1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/extensions/api/image_writer_private/error_messages.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/extensions/api/image_writer_private/test_utils.h" 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/extensions/api/image_writer_private/write_from_url_operation.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/test/base/testing_profile.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/browser_thread.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/url_request/test_url_request_interceptor.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/url_request/url_fetcher.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace extensions { 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace image_writer { 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing content::BrowserThread; 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using testing::_; 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using testing::AnyNumber; 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using testing::AtLeast; 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using testing::Gt; 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using testing::Lt; 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const char kTestImageUrl[] = "http://localhost/test/image.zip"; 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitypedef net::LocalHostTestURLRequestInterceptor GetInterceptor; 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// This class gives us a generic Operation with the ability to set or inspect 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// the current path to the image file. 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class OperationForTest : public WriteFromUrlOperation { 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OperationForTest(base::WeakPtr<OperationManager> manager_, 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ExtensionId& extension_id, 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequestContextGetter* request_context, 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL url, 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& hash, 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& storage_unit_id) 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : WriteFromUrlOperation(manager_, 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extension_id, 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) request_context, 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) url, 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hash, 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) storage_unit_id) {} 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void StartImpl() OVERRIDE {} 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Expose stages for testing. 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void GetDownloadTarget(const base::Closure& continuation) { 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WriteFromUrlOperation::GetDownloadTarget(continuation); 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void Download(const base::Closure& continuation) { 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WriteFromUrlOperation::Download(continuation); 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void VerifyDownload(const base::Closure& continuation) { 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WriteFromUrlOperation::VerifyDownload(continuation); 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Helpers to set-up state for intermediate stages. 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void SetImagePath(const base::FilePath image_path) { 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) image_path_ = image_path; 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::FilePath GetImagePath() { return image_path_; } 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private: 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual ~OperationForTest() {}; 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ImageWriterWriteFromUrlOperationTest : public ImageWriterUnitTestBase { 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) protected: 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ImageWriterWriteFromUrlOperationTest() : manager_(&test_profile_) {} 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void SetUp() OVERRIDE { 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ImageWriterUnitTestBase::SetUp(); 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Turn on interception and set up our dummy file. 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLFetcher::SetEnableInterceptionForTests(true); 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci get_interceptor_.reset(new GetInterceptor( 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::SequencedWorkerPool::SKIP_ON_SHUTDOWN))); 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch get_interceptor_->SetResponse(GURL(kTestImageUrl), 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch test_utils_.GetImagePath()); 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void TearDown() OVERRIDE { 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ImageWriterUnitTestBase::TearDown(); 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Remember to turn off global interception. 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLFetcher::SetEnableInterceptionForTests(false); 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<OperationForTest> CreateOperation(const GURL& url, 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& hash) { 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<OperationForTest> operation( 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new OperationForTest(manager_.AsWeakPtr(), 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kDummyExtensionId, 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) test_profile_.GetRequestContext(), 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) url, 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hash, 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch test_utils_.GetDevicePath().AsUTF8Unsafe())); 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) operation->Start(); 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return operation; 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) TestingProfile test_profile_; 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<GetInterceptor> get_interceptor_; 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MockOperationManager manager_; 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ImageWriterWriteFromUrlOperationTest, SelectTargetWithoutExtension) { 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<OperationForTest> operation = 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateOperation(GURL("http://localhost/foo/bar"), ""); 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) operation->GetDownloadTarget(base::Bind(&base::DoNothing)); 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(FILE_PATH_LITERAL("bar"), 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) operation->GetImagePath().BaseName().value()); 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) operation->Cancel(); 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ImageWriterWriteFromUrlOperationTest, SelectTargetWithExtension) { 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<OperationForTest> operation = 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateOperation(GURL("http://localhost/foo/bar.zip"), ""); 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) operation->GetDownloadTarget(base::Bind(&base::DoNothing)); 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(FILE_PATH_LITERAL("bar.zip"), 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) operation->GetImagePath().BaseName().value()); 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) operation->Cancel(); 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ImageWriterWriteFromUrlOperationTest, DownloadFile) { 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This test actually triggers the URL fetch code, which will drain the 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // message queues while waiting for IO, thus we have to run until the 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // operation completes. 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::RunLoop runloop; 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Closure quit_closure = runloop.QuitClosure(); 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::FilePath download_target_path; 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<OperationForTest> operation = 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateOperation(GURL(kTestImageUrl), ""); 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(base::CreateTemporaryFileInDir(test_utils_.GetTempDir(), 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &download_target_path)); 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) operation->SetImagePath(download_target_path); 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL( 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) manager_, 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnProgress(kDummyExtensionId, image_writer_api::STAGE_DOWNLOAD, _)) 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .Times(AtLeast(1)); 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL( 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) manager_, 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnProgress(kDummyExtensionId, image_writer_api::STAGE_DOWNLOAD, 0)) 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .Times(AnyNumber()); 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL( 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) manager_, 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnProgress(kDummyExtensionId, image_writer_api::STAGE_DOWNLOAD, 100)) 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .Times(AnyNumber()); 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::BrowserThread::PostTask( 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::BrowserThread::FILE, 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&OperationForTest::Download, operation, quit_closure)); 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) runloop.Run(); 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(base::ContentsEqual(test_utils_.GetImagePath(), 174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch operation->GetImagePath())); 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(1, get_interceptor_->GetHitCount()); 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) operation->Cancel(); 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(ImageWriterWriteFromUrlOperationTest, VerifyFile) { 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<char[]> data_buffer(new char[kTestFileSize]); 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::ReadFile(test_utils_.GetImagePath(), data_buffer.get(), kTestFileSize); 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::MD5Digest expected_digest; 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::MD5Sum(data_buffer.get(), kTestFileSize, &expected_digest); 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::string expected_hash = base::MD5DigestToBase16(expected_digest); 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<OperationForTest> operation = 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateOperation(GURL(""), expected_hash); 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL( 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) manager_, 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnProgress(kDummyExtensionId, image_writer_api::STAGE_VERIFYDOWNLOAD, _)) 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .Times(AtLeast(1)); 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL( 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) manager_, 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnProgress(kDummyExtensionId, image_writer_api::STAGE_VERIFYDOWNLOAD, 0)) 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) .Times(AtLeast(1)); 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_CALL(manager_, 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnProgress(kDummyExtensionId, 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) image_writer_api::STAGE_VERIFYDOWNLOAD, 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 100)).Times(AtLeast(1)); 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch operation->SetImagePath(test_utils_.GetImagePath()); 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::BrowserThread::PostTask(content::BrowserThread::FILE, 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&OperationForTest::VerifyDownload, 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) operation, 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&base::DoNothing))); 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) operation->Cancel(); 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace image_writer 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace extensions 220