// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/external_protocol/external_protocol_handler.h" #include "base/message_loop.h" #include "content/public/test/test_browser_thread.h" #include "testing/gtest/include/gtest/gtest.h" using content::BrowserThread; class FakeExternalProtocolHandlerWorker : public ShellIntegration::DefaultProtocolClientWorker { public: FakeExternalProtocolHandlerWorker( ShellIntegration::DefaultWebClientObserver* observer, const std::string& protocol, ShellIntegration::DefaultWebClientState os_state) : ShellIntegration::DefaultProtocolClientWorker(observer, protocol), os_state_(os_state) {} private: virtual ~FakeExternalProtocolHandlerWorker() {} virtual ShellIntegration::DefaultWebClientState CheckIsDefault() OVERRIDE { return os_state_; } virtual bool SetAsDefault(bool interactive_permitted) OVERRIDE { return true; } ShellIntegration::DefaultWebClientState os_state_; }; class FakeExternalProtocolHandlerDelegate : public ExternalProtocolHandler::Delegate { public: FakeExternalProtocolHandlerDelegate() : block_state_(ExternalProtocolHandler::BLOCK), os_state_(ShellIntegration::UNKNOWN_DEFAULT), has_launched_(false), has_prompted_(false), has_blocked_ (false) {} virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker( ShellIntegration::DefaultWebClientObserver* observer, const std::string& protocol) OVERRIDE { return new FakeExternalProtocolHandlerWorker(observer, protocol, os_state_); } virtual ExternalProtocolHandler::BlockState GetBlockState( const std::string& scheme) OVERRIDE { return block_state_; } virtual void BlockRequest() OVERRIDE { ASSERT_TRUE(block_state_ == ExternalProtocolHandler::BLOCK || os_state_ == ShellIntegration::IS_DEFAULT); has_blocked_ = true; } virtual void RunExternalProtocolDialog(const GURL& url, int render_process_host_id, int routing_id) OVERRIDE { ASSERT_EQ(block_state_, ExternalProtocolHandler::UNKNOWN); ASSERT_NE(os_state_, ShellIntegration::IS_DEFAULT); has_prompted_ = true; } virtual void LaunchUrlWithoutSecurityCheck(const GURL& url) OVERRIDE { ASSERT_EQ(block_state_, ExternalProtocolHandler::DONT_BLOCK); ASSERT_NE(os_state_, ShellIntegration::IS_DEFAULT); has_launched_ = true; } virtual void FinishedProcessingCheck() OVERRIDE { base::MessageLoop::current()->Quit(); } void set_os_state(ShellIntegration::DefaultWebClientState value) { os_state_ = value; } void set_block_state(ExternalProtocolHandler::BlockState value) { block_state_ = value; } bool has_launched() { return has_launched_; } bool has_prompted() { return has_prompted_; } bool has_blocked() { return has_blocked_; } private: ExternalProtocolHandler::BlockState block_state_; ShellIntegration::DefaultWebClientState os_state_; bool has_launched_; bool has_prompted_; bool has_blocked_; }; class ExternalProtocolHandlerTest : public testing::Test { protected: ExternalProtocolHandlerTest() : ui_thread_(BrowserThread::UI, base::MessageLoop::current()), file_thread_(BrowserThread::FILE) {} virtual void SetUp() { file_thread_.Start(); } virtual void TearDown() { // Ensure that g_accept_requests gets set back to true after test execution. ExternalProtocolHandler::PermitLaunchUrl(); } void DoTest(ExternalProtocolHandler::BlockState block_state, ShellIntegration::DefaultWebClientState os_state, bool should_prompt, bool should_launch, bool should_block) { GURL url("mailto:test@test.com"); ASSERT_FALSE(delegate_.has_prompted()); ASSERT_FALSE(delegate_.has_launched()); ASSERT_FALSE(delegate_.has_blocked()); delegate_.set_block_state(block_state); delegate_.set_os_state(os_state); ExternalProtocolHandler::LaunchUrlWithDelegate(url, 0, 0, &delegate_); if (block_state != ExternalProtocolHandler::BLOCK) base::MessageLoop::current()->Run(); ASSERT_EQ(should_prompt, delegate_.has_prompted()); ASSERT_EQ(should_launch, delegate_.has_launched()); ASSERT_EQ(should_block, delegate_.has_blocked()); } base::MessageLoopForUI ui_message_loop_; content::TestBrowserThread ui_thread_; content::TestBrowserThread file_thread_; FakeExternalProtocolHandlerDelegate delegate_; }; TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeBlockedChromeDefault) { DoTest(ExternalProtocolHandler::BLOCK, ShellIntegration::IS_DEFAULT, false, false, true); } TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeBlockedChromeNotDefault) { DoTest(ExternalProtocolHandler::BLOCK, ShellIntegration::NOT_DEFAULT, false, false, true); } TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeBlockedChromeUnknown) { DoTest(ExternalProtocolHandler::BLOCK, ShellIntegration::UNKNOWN_DEFAULT, false, false, true); } TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnBlockedChromeDefault) { DoTest(ExternalProtocolHandler::DONT_BLOCK, ShellIntegration::IS_DEFAULT, false, false, true); } TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnBlockedChromeNotDefault) { DoTest(ExternalProtocolHandler::DONT_BLOCK, ShellIntegration::NOT_DEFAULT, false, true, false); } TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnBlockedChromeUnknown) { DoTest(ExternalProtocolHandler::DONT_BLOCK, ShellIntegration::UNKNOWN_DEFAULT, false, true, false); } TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnknownChromeDefault) { DoTest(ExternalProtocolHandler::UNKNOWN, ShellIntegration::IS_DEFAULT, false, false, true); } TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnknownChromeNotDefault) { DoTest(ExternalProtocolHandler::UNKNOWN, ShellIntegration::NOT_DEFAULT, true, false, false); } TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnknownChromeUnknown) { DoTest(ExternalProtocolHandler::UNKNOWN, ShellIntegration::UNKNOWN_DEFAULT, true, false, false); }