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/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