Home | History | Annotate | Download | only in external_protocol
      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 "chrome/browser/external_protocol/external_protocol_handler.h"
      6 
      7 #include "base/message_loop/message_loop.h"
      8 #include "content/public/test/test_browser_thread.h"
      9 #include "testing/gtest/include/gtest/gtest.h"
     10 
     11 using content::BrowserThread;
     12 
     13 class FakeExternalProtocolHandlerWorker
     14     : public ShellIntegration::DefaultProtocolClientWorker {
     15  public:
     16   FakeExternalProtocolHandlerWorker(
     17       ShellIntegration::DefaultWebClientObserver* observer,
     18       const std::string& protocol,
     19       ShellIntegration::DefaultWebClientState os_state)
     20       : ShellIntegration::DefaultProtocolClientWorker(observer, protocol),
     21         os_state_(os_state) {}
     22 
     23  private:
     24   virtual ~FakeExternalProtocolHandlerWorker() {}
     25 
     26   virtual ShellIntegration::DefaultWebClientState CheckIsDefault() OVERRIDE {
     27     return os_state_;
     28   }
     29 
     30   virtual bool SetAsDefault(bool interactive_permitted) OVERRIDE {
     31     return true;
     32   }
     33 
     34   ShellIntegration::DefaultWebClientState os_state_;
     35 };
     36 
     37 class FakeExternalProtocolHandlerDelegate
     38     : public ExternalProtocolHandler::Delegate {
     39  public:
     40   FakeExternalProtocolHandlerDelegate()
     41       : block_state_(ExternalProtocolHandler::BLOCK),
     42         os_state_(ShellIntegration::UNKNOWN_DEFAULT),
     43         has_launched_(false),
     44         has_prompted_(false),
     45         has_blocked_ (false) {}
     46 
     47   virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
     48       ShellIntegration::DefaultWebClientObserver* observer,
     49       const std::string& protocol) OVERRIDE {
     50     return new FakeExternalProtocolHandlerWorker(observer, protocol, os_state_);
     51   }
     52 
     53   virtual ExternalProtocolHandler::BlockState GetBlockState(
     54       const std::string& scheme) OVERRIDE {
     55     return block_state_;
     56   }
     57 
     58   virtual void BlockRequest() OVERRIDE {
     59     ASSERT_TRUE(block_state_ == ExternalProtocolHandler::BLOCK ||
     60                 os_state_ == ShellIntegration::IS_DEFAULT);
     61     has_blocked_ = true;
     62   }
     63 
     64   virtual void RunExternalProtocolDialog(const GURL& url,
     65                                          int render_process_host_id,
     66                                          int routing_id) OVERRIDE {
     67     ASSERT_EQ(block_state_, ExternalProtocolHandler::UNKNOWN);
     68     ASSERT_NE(os_state_, ShellIntegration::IS_DEFAULT);
     69     has_prompted_ = true;
     70   }
     71 
     72   virtual void LaunchUrlWithoutSecurityCheck(const GURL& url) OVERRIDE {
     73     ASSERT_EQ(block_state_, ExternalProtocolHandler::DONT_BLOCK);
     74     ASSERT_NE(os_state_, ShellIntegration::IS_DEFAULT);
     75     has_launched_ = true;
     76   }
     77 
     78   virtual void FinishedProcessingCheck() OVERRIDE {
     79     base::MessageLoop::current()->Quit();
     80   }
     81 
     82   void set_os_state(ShellIntegration::DefaultWebClientState value) {
     83     os_state_ = value;
     84   }
     85 
     86   void set_block_state(ExternalProtocolHandler::BlockState value) {
     87     block_state_ = value;
     88   }
     89 
     90   bool has_launched() { return has_launched_; }
     91   bool has_prompted() { return has_prompted_; }
     92   bool has_blocked() { return has_blocked_; }
     93 
     94  private:
     95   ExternalProtocolHandler::BlockState block_state_;
     96   ShellIntegration::DefaultWebClientState os_state_;
     97   bool has_launched_;
     98   bool has_prompted_;
     99   bool has_blocked_;
    100 };
    101 
    102 class ExternalProtocolHandlerTest : public testing::Test {
    103  protected:
    104   ExternalProtocolHandlerTest()
    105       : ui_thread_(BrowserThread::UI, base::MessageLoop::current()),
    106         file_thread_(BrowserThread::FILE) {}
    107 
    108   virtual void SetUp() {
    109     file_thread_.Start();
    110   }
    111 
    112   virtual void TearDown() {
    113     // Ensure that g_accept_requests gets set back to true after test execution.
    114     ExternalProtocolHandler::PermitLaunchUrl();
    115   }
    116 
    117   void DoTest(ExternalProtocolHandler::BlockState block_state,
    118               ShellIntegration::DefaultWebClientState os_state,
    119               bool should_prompt, bool should_launch, bool should_block) {
    120     GURL url("mailto:test (at) test.com");
    121     ASSERT_FALSE(delegate_.has_prompted());
    122     ASSERT_FALSE(delegate_.has_launched());
    123     ASSERT_FALSE(delegate_.has_blocked());
    124 
    125     delegate_.set_block_state(block_state);
    126     delegate_.set_os_state(os_state);
    127     ExternalProtocolHandler::LaunchUrlWithDelegate(url, 0, 0, &delegate_);
    128     if (block_state != ExternalProtocolHandler::BLOCK)
    129       base::MessageLoop::current()->Run();
    130 
    131     ASSERT_EQ(should_prompt, delegate_.has_prompted());
    132     ASSERT_EQ(should_launch, delegate_.has_launched());
    133     ASSERT_EQ(should_block, delegate_.has_blocked());
    134   }
    135 
    136   base::MessageLoopForUI ui_message_loop_;
    137   content::TestBrowserThread ui_thread_;
    138   content::TestBrowserThread file_thread_;
    139 
    140   FakeExternalProtocolHandlerDelegate delegate_;
    141 };
    142 
    143 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeBlockedChromeDefault) {
    144   DoTest(ExternalProtocolHandler::BLOCK,
    145          ShellIntegration::IS_DEFAULT,
    146          false, false, true);
    147 }
    148 
    149 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeBlockedChromeNotDefault) {
    150   DoTest(ExternalProtocolHandler::BLOCK,
    151          ShellIntegration::NOT_DEFAULT,
    152          false, false, true);
    153 }
    154 
    155 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeBlockedChromeUnknown) {
    156   DoTest(ExternalProtocolHandler::BLOCK,
    157          ShellIntegration::UNKNOWN_DEFAULT,
    158          false, false, true);
    159 }
    160 
    161 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnBlockedChromeDefault) {
    162   DoTest(ExternalProtocolHandler::DONT_BLOCK,
    163          ShellIntegration::IS_DEFAULT,
    164          false, false, true);
    165 }
    166 
    167 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnBlockedChromeNotDefault) {
    168   DoTest(ExternalProtocolHandler::DONT_BLOCK,
    169          ShellIntegration::NOT_DEFAULT,
    170          false, true, false);
    171 }
    172 
    173 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnBlockedChromeUnknown) {
    174   DoTest(ExternalProtocolHandler::DONT_BLOCK,
    175          ShellIntegration::UNKNOWN_DEFAULT,
    176          false, true, false);
    177 }
    178 
    179 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnknownChromeDefault) {
    180   DoTest(ExternalProtocolHandler::UNKNOWN,
    181          ShellIntegration::IS_DEFAULT,
    182          false, false, true);
    183 }
    184 
    185 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnknownChromeNotDefault) {
    186   DoTest(ExternalProtocolHandler::UNKNOWN,
    187          ShellIntegration::NOT_DEFAULT,
    188          true, false, false);
    189 }
    190 
    191 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnknownChromeUnknown) {
    192   DoTest(ExternalProtocolHandler::UNKNOWN,
    193          ShellIntegration::UNKNOWN_DEFAULT,
    194          true, false, false);
    195 }
    196