| Index: chrome/browser/extensions/api/image_writer_private/operation_unittest.cc | 
| diff --git a/chrome/browser/extensions/api/image_writer_private/operation_unittest.cc b/chrome/browser/extensions/api/image_writer_private/operation_unittest.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..0cdc76eec0dc8bd289b5cf35dd72181c531c563f | 
| --- /dev/null | 
| +++ b/chrome/browser/extensions/api/image_writer_private/operation_unittest.cc | 
| @@ -0,0 +1,152 @@ | 
| +// Copyright 2013 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "base/file_util.h" | 
| +#include "base/files/scoped_temp_dir.h" | 
| +#include "base/message_loop/message_loop.h" | 
| +#include "base/run_loop.h" | 
| +#include "chrome/browser/extensions/api/image_writer_private/operation.h" | 
| +#include "chrome/browser/extensions/api/image_writer_private/operation_manager.h" | 
| +#include "chrome/test/base/testing_profile.h" | 
| +#include "content/public/browser/browser_thread.h" | 
| +#include "content/public/test/test_browser_thread_bundle.h" | 
| +#include "testing/gmock/include/gmock/gmock.h" | 
| +#include "testing/gtest/include/gtest/gtest.h" | 
| +#include "third_party/zlib/google/zip.h" | 
| + | 
| +namespace extensions { | 
| +namespace image_writer { | 
| + | 
| +namespace { | 
| + | 
| +using testing::_; | 
| +using testing::AnyNumber; | 
| +using testing::AtLeast; | 
| +using testing::Gt; | 
| +using testing::Lt; | 
| + | 
| +static const char kDummyExtensionId[] = "Dummy Extension"; | 
| +static unsigned int kTestFileSize = 1024 * 1024; // 1 MB | 
| +static unsigned char kTestPattern = 0x55; // 1 MB | 
| + | 
| +// This class gives us access to the protected methods of Operation so that we | 
| +// can call them directly. | 
| +class OperationForTest : public Operation { | 
| + public: | 
| +  OperationForTest(base::WeakPtr<OperationManager> manager, | 
| +                   const ExtensionId& extension_id, | 
| +                   const std::string& storage_unit_id) | 
| +      : Operation(manager, extension_id, storage_unit_id) {} | 
| + | 
| +  void Start() OVERRIDE { | 
| +  } | 
| + | 
| +  void UnzipStart(scoped_ptr<base::FilePath> zip_file) { | 
| +    Operation::UnzipStart(zip_file.Pass()); | 
| +  } | 
| + | 
| +  void WriteStart() { | 
| +    Operation::WriteStart(); | 
| +  } | 
| + | 
| +  void VerifyWriteStart() { | 
| +    Operation::Start(); | 
| +  } | 
| + | 
| +  void Finish() { | 
| +    Operation::Finish(); | 
| +  } | 
| +}; | 
| + | 
| +// A mock for OperationManager | 
| +class MockManager : public OperationManager { | 
| + public: | 
| +  explicit MockManager(Profile* profile) : OperationManager(profile) {} | 
| + | 
| +  MOCK_METHOD3(OnProgress, void(const ExtensionId&, | 
| +                                image_writer_api::Stage, | 
| +                                int)); | 
| +  MOCK_METHOD1(OnComplete, void(const ExtensionId&)); | 
| +  MOCK_METHOD4(OnError, void(const ExtensionId&, | 
| +                             image_writer_api::Stage, | 
| +                             int, | 
| +                             const std::string&)); | 
| +}; | 
| + | 
| +class ImageWriterOperationTest : public testing::Test { | 
| + protected: | 
| +  void SetUp() OVERRIDE { | 
| +    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 
| +    ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(), | 
| +                                                    &image_file_)); | 
| +    ASSERT_TRUE(file_util::CreateTemporaryFile(&device_file_)); | 
| +    ASSERT_TRUE(file_util::CreateTemporaryFile(&zip_file_)); | 
| + | 
| +    char buffer[kTestFileSize]; | 
| +    memset(buffer, kTestPattern, kTestFileSize); | 
| +    file_util::WriteFile(image_file_, buffer, kTestFileSize); | 
| + | 
| +    zip::Zip(temp_dir_.path(), zip_file_, true); | 
| +  } | 
| + | 
| +  void TearDown() OVERRIDE { | 
| +  } | 
| + | 
| +  base::FilePath zip_file_; | 
| +  base::FilePath image_file_; | 
| +  base::FilePath device_file_; | 
| +  TestingProfile test_profile_; | 
| +  base::ScopedTempDir temp_dir_; | 
| + | 
| + private: | 
| +  content::TestBrowserThreadBundle thread_bundle_; | 
| +}; | 
| + | 
| +} // namespace | 
| + | 
| +// Tests a successful unzip. | 
| +TEST_F(ImageWriterOperationTest, TestUnzip) { | 
| +  MockManager manager(&test_profile_); | 
| + | 
| +  scoped_refptr<OperationForTest> operation( | 
| +      new OperationForTest(manager.AsWeakPtr(), | 
| +                           kDummyExtensionId, | 
| +                           device_file_.AsUTF8Unsafe())); | 
| + | 
| +  scoped_ptr<base::FilePath> zip_file(new base::FilePath(zip_file_)); | 
| + | 
| +  // At least one progress report > 0% and < 100%. | 
| +  EXPECT_CALL(manager, OnProgress(kDummyExtensionId, | 
| +                                  image_writer_api::STAGE_UNZIP, | 
| +                                  Lt(100))).Times(AtLeast(1)); | 
| +  // At least one progress report at 100%. | 
| +  EXPECT_CALL(manager, OnProgress(kDummyExtensionId, | 
| +                                  image_writer_api::STAGE_UNZIP, | 
| +                                  100)).Times(AtLeast(1)); | 
| +  // At least one progress report at 0%. | 
| +  EXPECT_CALL(manager, OnProgress(kDummyExtensionId, | 
| +                                  image_writer_api::STAGE_UNZIP, | 
| +                                  0)).Times(AtLeast(1)); | 
| +  // Any number of additional progress calls in later stages. | 
| +  EXPECT_CALL(manager, OnProgress(kDummyExtensionId, | 
| +                                  Gt(image_writer_api::STAGE_UNZIP), | 
| +                                  _)).Times(AnyNumber()); | 
| +  // One completion call. | 
| +  EXPECT_CALL(manager, OnComplete(kDummyExtensionId)).Times(1); | 
| +  // No errors | 
| +  EXPECT_CALL(manager, OnError(_, _, _, _)).Times(0); | 
| + | 
| +  content::BrowserThread::PostTask(content::BrowserThread::FILE, | 
| +                                   FROM_HERE, | 
| +                                   base::Bind(&OperationForTest::UnzipStart, | 
| +                                              operation, | 
| +                                              base::Passed(&zip_file))); | 
| + | 
| +  base::RunLoop().RunUntilIdle(); | 
| + | 
| +  EXPECT_TRUE(base::ContentsEqual(image_file_, device_file_)); | 
| +} | 
| + | 
| +}  // namespace image_writer | 
| +}  // namespace extensions | 
|  |