1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/api/image_writer_private/error_messages.h"
6 #include "chrome/browser/extensions/api/image_writer_private/test_utils.h"
7 #include "chrome/browser/extensions/api/image_writer_private/write_from_url_operation.h"
8 #include "chrome/test/base/testing_profile.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "net/url_request/test_url_request_interceptor.h"
11 #include "net/url_request/url_fetcher.h"
13 namespace extensions {
14 namespace image_writer {
18 using content::BrowserThread;
20 using testing::AnyNumber;
21 using testing::AtLeast;
25 const char kTestImageUrl[] = "http://localhost/test/image.zip";
27 typedef net::LocalHostTestURLRequestInterceptor GetInterceptor;
29 // This class gives us a generic Operation with the ability to set or inspect
30 // the current path to the image file.
31 class OperationForTest : public WriteFromUrlOperation {
33 OperationForTest(base::WeakPtr<OperationManager> manager_,
34 const ExtensionId& extension_id,
35 net::URLRequestContextGetter* request_context,
37 const std::string& hash,
38 const std::string& storage_unit_id)
39 : WriteFromUrlOperation(manager_,
46 virtual void StartImpl() OVERRIDE {}
48 // Expose stages for testing.
49 void GetDownloadTarget(const base::Closure& continuation) {
50 WriteFromUrlOperation::GetDownloadTarget(continuation);
53 void Download(const base::Closure& continuation) {
54 WriteFromUrlOperation::Download(continuation);
57 void VerifyDownload(const base::Closure& continuation) {
58 WriteFromUrlOperation::VerifyDownload(continuation);
61 // Helpers to set-up state for intermediate stages.
62 void SetImagePath(const base::FilePath image_path) {
63 image_path_ = image_path;
66 base::FilePath GetImagePath() { return image_path_; }
69 virtual ~OperationForTest() {};
72 class ImageWriterWriteFromUrlOperationTest : public ImageWriterUnitTestBase {
74 ImageWriterWriteFromUrlOperationTest() : manager_(&test_profile_) {}
76 virtual void SetUp() OVERRIDE {
77 ImageWriterUnitTestBase::SetUp();
79 // Turn on interception and set up our dummy file.
80 net::URLFetcher::SetEnableInterceptionForTests(true);
81 get_interceptor_.reset(new GetInterceptor(
82 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
83 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
84 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)));
85 get_interceptor_->SetResponse(GURL(kTestImageUrl),
86 test_utils_.GetImagePath());
89 virtual void TearDown() OVERRIDE {
90 ImageWriterUnitTestBase::TearDown();
92 // Remember to turn off global interception.
93 net::URLFetcher::SetEnableInterceptionForTests(false);
96 scoped_refptr<OperationForTest> CreateOperation(const GURL& url,
97 const std::string& hash) {
98 scoped_refptr<OperationForTest> operation(
99 new OperationForTest(manager_.AsWeakPtr(),
101 test_profile_.GetRequestContext(),
104 test_utils_.GetDevicePath().AsUTF8Unsafe()));
109 TestingProfile test_profile_;
110 scoped_ptr<GetInterceptor> get_interceptor_;
112 MockOperationManager manager_;
115 TEST_F(ImageWriterWriteFromUrlOperationTest, SelectTargetWithoutExtension) {
116 scoped_refptr<OperationForTest> operation =
117 CreateOperation(GURL("http://localhost/foo/bar"), "");
119 operation->GetDownloadTarget(base::Bind(&base::DoNothing));
121 EXPECT_EQ(FILE_PATH_LITERAL("bar"),
122 operation->GetImagePath().BaseName().value());
127 TEST_F(ImageWriterWriteFromUrlOperationTest, SelectTargetWithExtension) {
128 scoped_refptr<OperationForTest> operation =
129 CreateOperation(GURL("http://localhost/foo/bar.zip"), "");
131 operation->GetDownloadTarget(base::Bind(&base::DoNothing));
133 EXPECT_EQ(FILE_PATH_LITERAL("bar.zip"),
134 operation->GetImagePath().BaseName().value());
139 TEST_F(ImageWriterWriteFromUrlOperationTest, DownloadFile) {
140 // This test actually triggers the URL fetch code, which will drain the
141 // message queues while waiting for IO, thus we have to run until the
142 // operation completes.
143 base::RunLoop runloop;
144 base::Closure quit_closure = runloop.QuitClosure();
145 base::FilePath download_target_path;
146 scoped_refptr<OperationForTest> operation =
147 CreateOperation(GURL(kTestImageUrl), "");
149 EXPECT_TRUE(base::CreateTemporaryFileInDir(test_utils_.GetTempDir(),
150 &download_target_path));
151 operation->SetImagePath(download_target_path);
155 OnProgress(kDummyExtensionId, image_writer_api::STAGE_DOWNLOAD, _))
159 OnProgress(kDummyExtensionId, image_writer_api::STAGE_DOWNLOAD, 0))
163 OnProgress(kDummyExtensionId, image_writer_api::STAGE_DOWNLOAD, 100))
166 content::BrowserThread::PostTask(
167 content::BrowserThread::FILE,
169 base::Bind(&OperationForTest::Download, operation, quit_closure));
173 EXPECT_TRUE(base::ContentsEqual(test_utils_.GetImagePath(),
174 operation->GetImagePath()));
176 EXPECT_EQ(1, get_interceptor_->GetHitCount());
181 TEST_F(ImageWriterWriteFromUrlOperationTest, VerifyFile) {
182 scoped_ptr<char[]> data_buffer(new char[kTestFileSize]);
183 base::ReadFile(test_utils_.GetImagePath(), data_buffer.get(), kTestFileSize);
184 base::MD5Digest expected_digest;
185 base::MD5Sum(data_buffer.get(), kTestFileSize, &expected_digest);
186 std::string expected_hash = base::MD5DigestToBase16(expected_digest);
188 scoped_refptr<OperationForTest> operation =
189 CreateOperation(GURL(""), expected_hash);
193 OnProgress(kDummyExtensionId, image_writer_api::STAGE_VERIFYDOWNLOAD, _))
197 OnProgress(kDummyExtensionId, image_writer_api::STAGE_VERIFYDOWNLOAD, 0))
199 EXPECT_CALL(manager_,
200 OnProgress(kDummyExtensionId,
201 image_writer_api::STAGE_VERIFYDOWNLOAD,
202 100)).Times(AtLeast(1));
204 operation->SetImagePath(test_utils_.GetImagePath());
205 content::BrowserThread::PostTask(content::BrowserThread::FILE,
207 base::Bind(&OperationForTest::VerifyDownload,
209 base::Bind(&base::DoNothing)));
211 base::RunLoop().RunUntilIdle();
218 } // namespace image_writer
219 } // namespace extensions