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