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 { return block_state_; } 55 56 virtual void BlockRequest() OVERRIDE { 57 ASSERT_TRUE(block_state_ == ExternalProtocolHandler::BLOCK || 58 os_state_ == ShellIntegration::IS_DEFAULT); 59 has_blocked_ = true; 60 } 61 62 virtual void RunExternalProtocolDialog(const GURL& url, 63 int render_process_host_id, 64 int routing_id) OVERRIDE { 65 ASSERT_EQ(block_state_, ExternalProtocolHandler::UNKNOWN); 66 ASSERT_NE(os_state_, ShellIntegration::IS_DEFAULT); 67 has_prompted_ = true; 68 } 69 70 virtual void LaunchUrlWithoutSecurityCheck(const GURL& url) OVERRIDE { 71 ASSERT_EQ(block_state_, ExternalProtocolHandler::DONT_BLOCK); 72 ASSERT_NE(os_state_, ShellIntegration::IS_DEFAULT); 73 has_launched_ = true; 74 } 75 76 virtual void FinishedProcessingCheck() OVERRIDE { 77 base::MessageLoop::current()->Quit(); 78 } 79 80 void set_os_state(ShellIntegration::DefaultWebClientState value) { 81 os_state_ = value; 82 } 83 84 void set_block_state(ExternalProtocolHandler::BlockState value) { 85 block_state_ = value; 86 } 87 88 bool has_launched() { return has_launched_; } 89 bool has_prompted() { return has_prompted_; } 90 bool has_blocked() { return has_blocked_; } 91 92 private: 93 ExternalProtocolHandler::BlockState block_state_; 94 ShellIntegration::DefaultWebClientState os_state_; 95 bool has_launched_; 96 bool has_prompted_; 97 bool has_blocked_; 98 }; 99 100 class ExternalProtocolHandlerTest : public testing::Test { 101 protected: 102 ExternalProtocolHandlerTest() 103 : ui_thread_(BrowserThread::UI, base::MessageLoop::current()), 104 file_thread_(BrowserThread::FILE) {} 105 106 virtual void SetUp() { 107 file_thread_.Start(); 108 } 109 110 virtual void TearDown() { 111 // Ensure that g_accept_requests gets set back to true after test execution. 112 ExternalProtocolHandler::PermitLaunchUrl(); 113 } 114 115 void DoTest(ExternalProtocolHandler::BlockState block_state, 116 ShellIntegration::DefaultWebClientState os_state, 117 bool should_prompt, bool should_launch, bool should_block) { 118 GURL url("mailto:test (at) test.com"); 119 ASSERT_FALSE(delegate_.has_prompted()); 120 ASSERT_FALSE(delegate_.has_launched()); 121 ASSERT_FALSE(delegate_.has_blocked()); 122 123 delegate_.set_block_state(block_state); 124 delegate_.set_os_state(os_state); 125 ExternalProtocolHandler::LaunchUrlWithDelegate(url, 0, 0, &delegate_); 126 if (block_state != ExternalProtocolHandler::BLOCK) 127 base::MessageLoop::current()->Run(); 128 129 ASSERT_EQ(should_prompt, delegate_.has_prompted()); 130 ASSERT_EQ(should_launch, delegate_.has_launched()); 131 ASSERT_EQ(should_block, delegate_.has_blocked()); 132 } 133 134 base::MessageLoopForUI ui_message_loop_; 135 content::TestBrowserThread ui_thread_; 136 content::TestBrowserThread file_thread_; 137 138 FakeExternalProtocolHandlerDelegate delegate_; 139 }; 140 141 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeBlockedChromeDefault) { 142 DoTest(ExternalProtocolHandler::BLOCK, 143 ShellIntegration::IS_DEFAULT, 144 false, false, true); 145 } 146 147 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeBlockedChromeNotDefault) { 148 DoTest(ExternalProtocolHandler::BLOCK, 149 ShellIntegration::NOT_DEFAULT, 150 false, false, true); 151 } 152 153 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeBlockedChromeUnknown) { 154 DoTest(ExternalProtocolHandler::BLOCK, 155 ShellIntegration::UNKNOWN_DEFAULT, 156 false, false, true); 157 } 158 159 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnBlockedChromeDefault) { 160 DoTest(ExternalProtocolHandler::DONT_BLOCK, 161 ShellIntegration::IS_DEFAULT, 162 false, false, true); 163 } 164 165 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnBlockedChromeNotDefault) { 166 DoTest(ExternalProtocolHandler::DONT_BLOCK, 167 ShellIntegration::NOT_DEFAULT, 168 false, true, false); 169 } 170 171 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnBlockedChromeUnknown) { 172 DoTest(ExternalProtocolHandler::DONT_BLOCK, 173 ShellIntegration::UNKNOWN_DEFAULT, 174 false, true, false); 175 } 176 177 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnknownChromeDefault) { 178 DoTest(ExternalProtocolHandler::UNKNOWN, 179 ShellIntegration::IS_DEFAULT, 180 false, false, true); 181 } 182 183 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnknownChromeNotDefault) { 184 DoTest(ExternalProtocolHandler::UNKNOWN, 185 ShellIntegration::NOT_DEFAULT, 186 true, false, false); 187 } 188 189 TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnknownChromeUnknown) { 190 DoTest(ExternalProtocolHandler::UNKNOWN, 191 ShellIntegration::UNKNOWN_DEFAULT, 192 true, false, false); 193 } 194