15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/external_protocol/external_protocol_handler.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FakeExternalProtocolHandlerWorker
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public ShellIntegration::DefaultProtocolClientWorker {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeExternalProtocolHandlerWorker(
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShellIntegration::DefaultWebClientObserver* observer,
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& protocol,
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShellIntegration::DefaultWebClientState os_state)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : ShellIntegration::DefaultProtocolClientWorker(observer, protocol),
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        os_state_(os_state) {}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~FakeExternalProtocolHandlerWorker() {}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ShellIntegration::DefaultWebClientState CheckIsDefault() OVERRIDE {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return os_state_;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool SetAsDefault(bool interactive_permitted) OVERRIDE {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShellIntegration::DefaultWebClientState os_state_;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FakeExternalProtocolHandlerDelegate
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public ExternalProtocolHandler::Delegate {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeExternalProtocolHandlerDelegate()
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : block_state_(ExternalProtocolHandler::BLOCK),
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        os_state_(ShellIntegration::UNKNOWN_DEFAULT),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        has_launched_(false),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        has_prompted_(false),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        has_blocked_ (false) {}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker(
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ShellIntegration::DefaultWebClientObserver* observer,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& protocol) OVERRIDE {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new FakeExternalProtocolHandlerWorker(observer, protocol, os_state_);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ExternalProtocolHandler::BlockState GetBlockState(
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const std::string& scheme) OVERRIDE {
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return block_state_;
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void BlockRequest() OVERRIDE {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(block_state_ == ExternalProtocolHandler::BLOCK ||
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                os_state_ == ShellIntegration::IS_DEFAULT);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_blocked_ = true;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RunExternalProtocolDialog(const GURL& url,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         int render_process_host_id,
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         int routing_id) OVERRIDE {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(block_state_, ExternalProtocolHandler::UNKNOWN);
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_NE(os_state_, ShellIntegration::IS_DEFAULT);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_prompted_ = true;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void LaunchUrlWithoutSecurityCheck(const GURL& url) OVERRIDE {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(block_state_, ExternalProtocolHandler::DONT_BLOCK);
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_NE(os_state_, ShellIntegration::IS_DEFAULT);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    has_launched_ = true;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FinishedProcessingCheck() OVERRIDE {
7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_os_state(ShellIntegration::DefaultWebClientState value) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    os_state_ = value;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_block_state(ExternalProtocolHandler::BlockState value) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    block_state_ = value;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_launched() { return has_launched_; }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_prompted() { return has_prompted_; }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_blocked() { return has_blocked_; }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExternalProtocolHandler::BlockState block_state_;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShellIntegration::DefaultWebClientState os_state_;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_launched_;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_prompted_;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_blocked_;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExternalProtocolHandlerTest : public testing::Test {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExternalProtocolHandlerTest()
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      : ui_thread_(BrowserThread::UI, base::MessageLoop::current()),
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        file_thread_(BrowserThread::FILE) {}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    file_thread_.Start();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void TearDown() {
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Ensure that g_accept_requests gets set back to true after test execution.
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ExternalProtocolHandler::PermitLaunchUrl();
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoTest(ExternalProtocolHandler::BlockState block_state,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              ShellIntegration::DefaultWebClientState os_state,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              bool should_prompt, bool should_launch, bool should_block) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL url("mailto:test@test.com");
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(delegate_.has_prompted());
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(delegate_.has_launched());
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_FALSE(delegate_.has_blocked());
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_.set_block_state(block_state);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_.set_os_state(os_state);
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ExternalProtocolHandler::LaunchUrlWithDelegate(url, 0, 0, &delegate_);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (block_state != ExternalProtocolHandler::BLOCK)
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      base::MessageLoop::current()->Run();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(should_prompt, delegate_.has_prompted());
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(should_launch, delegate_.has_launched());
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(should_block, delegate_.has_blocked());
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoopForUI ui_message_loop_;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::TestBrowserThread ui_thread_;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::TestBrowserThread file_thread_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeExternalProtocolHandlerDelegate delegate_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeBlockedChromeDefault) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTest(ExternalProtocolHandler::BLOCK,
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ShellIntegration::IS_DEFAULT,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         false, false, true);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeBlockedChromeNotDefault) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTest(ExternalProtocolHandler::BLOCK,
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ShellIntegration::NOT_DEFAULT,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         false, false, true);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeBlockedChromeUnknown) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTest(ExternalProtocolHandler::BLOCK,
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ShellIntegration::UNKNOWN_DEFAULT,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         false, false, true);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnBlockedChromeDefault) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTest(ExternalProtocolHandler::DONT_BLOCK,
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ShellIntegration::IS_DEFAULT,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         false, false, true);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnBlockedChromeNotDefault) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTest(ExternalProtocolHandler::DONT_BLOCK,
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ShellIntegration::NOT_DEFAULT,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         false, true, false);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnBlockedChromeUnknown) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTest(ExternalProtocolHandler::DONT_BLOCK,
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ShellIntegration::UNKNOWN_DEFAULT,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         false, true, false);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnknownChromeDefault) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTest(ExternalProtocolHandler::UNKNOWN,
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ShellIntegration::IS_DEFAULT,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         false, false, true);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnknownChromeNotDefault) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTest(ExternalProtocolHandler::UNKNOWN,
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ShellIntegration::NOT_DEFAULT,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         true, false, false);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExternalProtocolHandlerTest, TestLaunchSchemeUnknownChromeUnknown) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DoTest(ExternalProtocolHandler::UNKNOWN,
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ShellIntegration::UNKNOWN_DEFAULT,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         true, false, false);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
196