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 "base/bind.h" 6 #include "base/file_util.h" 7 #include "base/memory/ref_counted.h" 8 #include "base/message_loop/message_loop.h" 9 #include "base/path_service.h" 10 #include "base/run_loop.h" 11 #include "base/strings/string_util.h" 12 #include "base/values.h" 13 #include "chrome/browser/extensions/sandboxed_unpacker.h" 14 #include "chrome/common/chrome_paths.h" 15 #include "content/public/browser/render_process_host.h" 16 #include "content/public/test/test_browser_thread_bundle.h" 17 #include "content/public/test/test_utils.h" 18 #include "extensions/common/constants.h" 19 #include "extensions/common/extension.h" 20 #include "testing/gtest/include/gtest/gtest.h" 21 #include "third_party/skia/include/core/SkBitmap.h" 22 23 namespace extensions { 24 25 class MockSandboxedUnpackerClient : public SandboxedUnpackerClient { 26 public: 27 28 void WaitForUnpack() { 29 scoped_refptr<content::MessageLoopRunner> runner = 30 new content::MessageLoopRunner; 31 quit_closure_ = runner->QuitClosure(); 32 runner->Run(); 33 } 34 35 base::FilePath temp_dir() const { return temp_dir_; } 36 37 private: 38 virtual ~MockSandboxedUnpackerClient() {} 39 40 virtual void OnUnpackSuccess(const base::FilePath& temp_dir, 41 const base::FilePath& extension_root, 42 const base::DictionaryValue* original_manifest, 43 const Extension* extension, 44 const SkBitmap& install_icon) OVERRIDE { 45 temp_dir_ = temp_dir; 46 quit_closure_.Run(); 47 48 } 49 50 virtual void OnUnpackFailure(const base::string16& error) OVERRIDE { 51 ASSERT_TRUE(false); 52 } 53 54 base::Closure quit_closure_; 55 base::FilePath temp_dir_; 56 }; 57 58 class SandboxedUnpackerTest : public testing::Test { 59 public: 60 virtual void SetUp() { 61 ASSERT_TRUE(extensions_dir_.CreateUniqueTempDir()); 62 browser_threads_.reset(new content::TestBrowserThreadBundle( 63 content::TestBrowserThreadBundle::IO_MAINLOOP)); 64 // It will delete itself. 65 client_ = new MockSandboxedUnpackerClient; 66 content::RenderProcessHost::SetRunRendererInProcess(true); 67 } 68 69 virtual void TearDown() { 70 // Need to destruct SandboxedUnpacker before the message loop since 71 // it posts a task to it. 72 sandboxed_unpacker_ = NULL; 73 base::RunLoop().RunUntilIdle(); 74 content::RenderProcessHost::SetRunRendererInProcess(false); 75 } 76 77 void SetupUnpacker(const std::string& crx_name) { 78 base::FilePath original_path; 79 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &original_path)); 80 original_path = original_path.AppendASCII("extensions") 81 .AppendASCII("unpacker") 82 .AppendASCII(crx_name); 83 ASSERT_TRUE(base::PathExists(original_path)) << original_path.value(); 84 85 sandboxed_unpacker_ = new SandboxedUnpacker( 86 original_path, 87 Manifest::INTERNAL, 88 Extension::NO_FLAGS, 89 extensions_dir_.path(), 90 base::MessageLoopProxy::current(), 91 client_); 92 93 base::MessageLoopProxy::current()->PostTask( 94 FROM_HERE, 95 base::Bind(&SandboxedUnpacker::Start, sandboxed_unpacker_.get())); 96 client_->WaitForUnpack(); 97 } 98 99 base::FilePath GetInstallPath() { 100 return client_->temp_dir().AppendASCII(kTempExtensionName); 101 } 102 103 protected: 104 base::ScopedTempDir extensions_dir_; 105 MockSandboxedUnpackerClient* client_; 106 scoped_refptr<SandboxedUnpacker> sandboxed_unpacker_; 107 scoped_ptr<content::TestBrowserThreadBundle> browser_threads_; 108 }; 109 110 TEST_F(SandboxedUnpackerTest, NoCatalogsSuccess) { 111 SetupUnpacker("no_l10n.crx"); 112 // Check that there is no _locales folder. 113 base::FilePath install_path = 114 GetInstallPath().Append(kLocaleFolder); 115 EXPECT_FALSE(base::PathExists(install_path)); 116 } 117 118 TEST_F(SandboxedUnpackerTest, WithCatalogsSuccess) { 119 SetupUnpacker("good_l10n.crx"); 120 // Check that there is _locales folder. 121 base::FilePath install_path = 122 GetInstallPath().Append(kLocaleFolder); 123 EXPECT_TRUE(base::PathExists(install_path)); 124 } 125 126 } // namespace extensions 127