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