protocol_handler_registry_unittest.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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/custom_handlers/protocol_handler_registry.h" 6 7#include <set> 8 9#include "base/memory/scoped_ptr.h" 10#include "base/message_loop.h" 11#include "base/strings/utf_string_conversions.h" 12#include "base/synchronization/waitable_event.h" 13#include "chrome/browser/chrome_notification_types.h" 14#include "chrome/browser/prefs/pref_service_syncable.h" 15#include "chrome/common/custom_handlers/protocol_handler.h" 16#include "chrome/test/base/testing_browser_process.h" 17#include "chrome/test/base/testing_profile.h" 18#include "components/user_prefs/pref_registry_syncable.h" 19#include "content/public/browser/notification_observer.h" 20#include "content/public/browser/notification_registrar.h" 21#include "content/public/browser/notification_source.h" 22#include "content/public/test/test_browser_thread.h" 23#include "content/public/test/test_renderer_host.h" 24#include "net/url_request/url_request.h" 25#include "net/url_request/url_request_context.h" 26#include "testing/gtest/include/gtest/gtest.h" 27 28using content::BrowserThread; 29 30namespace { 31 32void AssertInterceptedIO( 33 const GURL& url, 34 net::URLRequestJobFactory* interceptor) { 35 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 36 net::URLRequestContext context; 37 net::NetworkDelegate *network_delegate = NULL; 38 net::URLRequest request(url, NULL, &context); 39 scoped_refptr<net::URLRequestJob> job = 40 interceptor->MaybeCreateJobWithProtocolHandler( 41 url.scheme(), &request, network_delegate); 42 ASSERT_TRUE(job.get() != NULL); 43} 44 45void AssertIntercepted( 46 const GURL& url, 47 net::URLRequestJobFactory* interceptor) { 48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 49 BrowserThread::PostTask(BrowserThread::IO, 50 FROM_HERE, 51 base::Bind(AssertInterceptedIO, 52 url, 53 base::Unretained(interceptor))); 54 base::MessageLoop::current()->RunUntilIdle(); 55} 56 57// FakeURLRequestJobFactory returns NULL for all job creation requests and false 58// for all IsHandled*() requests. FakeURLRequestJobFactory can be chained to 59// ProtocolHandlerRegistry::JobInterceptorFactory so the result of 60// MaybeCreateJobWithProtocolHandler() indicates whether the 61// ProtocolHandlerRegistry properly handled a job creation request. 62class FakeURLRequestJobFactory : public net::URLRequestJobFactory { 63 // net::URLRequestJobFactory implementation: 64 virtual net::URLRequestJob* MaybeCreateJobWithProtocolHandler( 65 const std::string& scheme, 66 net::URLRequest* request, 67 net::NetworkDelegate* network_delegate) const OVERRIDE { 68 return NULL; 69 } 70 virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE { 71 return false; 72 } 73 virtual bool IsHandledURL(const GURL& url) const OVERRIDE { 74 return false; 75 } 76 virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE { 77 return true; 78 } 79}; 80 81void AssertWillHandleIO( 82 const std::string& scheme, 83 bool expected, 84 ProtocolHandlerRegistry::JobInterceptorFactory* interceptor) { 85 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 86 interceptor->Chain(scoped_ptr<net::URLRequestJobFactory>( 87 new FakeURLRequestJobFactory())); 88 ASSERT_EQ(expected, interceptor->IsHandledProtocol(scheme)); 89 interceptor->Chain(scoped_ptr<net::URLRequestJobFactory>()); 90} 91 92void AssertWillHandle( 93 const std::string& scheme, 94 bool expected, 95 ProtocolHandlerRegistry::JobInterceptorFactory* interceptor) { 96 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 97 BrowserThread::PostTask(BrowserThread::IO, 98 FROM_HERE, 99 base::Bind(AssertWillHandleIO, 100 scheme, 101 expected, 102 base::Unretained(interceptor))); 103 base::MessageLoop::current()->RunUntilIdle(); 104} 105 106class FakeDelegate : public ProtocolHandlerRegistry::Delegate { 107 public: 108 FakeDelegate() : force_os_failure_(false) {} 109 virtual ~FakeDelegate() { } 110 virtual void RegisterExternalHandler(const std::string& protocol) OVERRIDE { 111 ASSERT_TRUE( 112 registered_protocols_.find(protocol) == registered_protocols_.end()); 113 registered_protocols_.insert(protocol); 114 } 115 116 virtual void DeregisterExternalHandler(const std::string& protocol) OVERRIDE { 117 registered_protocols_.erase(protocol); 118 } 119 120 virtual ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker( 121 ShellIntegration::DefaultWebClientObserver* observer, 122 const std::string& protocol) OVERRIDE; 123 124 virtual ProtocolHandlerRegistry::DefaultClientObserver* CreateShellObserver( 125 ProtocolHandlerRegistry* registry) OVERRIDE; 126 127 virtual void RegisterWithOSAsDefaultClient( 128 const std::string& protocol, 129 ProtocolHandlerRegistry* reg) OVERRIDE { 130 ProtocolHandlerRegistry::Delegate::RegisterWithOSAsDefaultClient(protocol, 131 reg); 132 ASSERT_FALSE(IsFakeRegisteredWithOS(protocol)); 133 } 134 135 virtual bool IsExternalHandlerRegistered( 136 const std::string& protocol) OVERRIDE { 137 return registered_protocols_.find(protocol) != registered_protocols_.end(); 138 } 139 140 bool IsFakeRegisteredWithOS(const std::string& protocol) { 141 return os_registered_protocols_.find(protocol) != 142 os_registered_protocols_.end(); 143 } 144 145 void FakeRegisterWithOS(const std::string& protocol) { 146 os_registered_protocols_.insert(protocol); 147 } 148 149 void Reset() { 150 registered_protocols_.clear(); 151 os_registered_protocols_.clear(); 152 force_os_failure_ = false; 153 } 154 155 void set_force_os_failure(bool force) { force_os_failure_ = force; } 156 157 bool force_os_failure() { return force_os_failure_; } 158 159 private: 160 std::set<std::string> registered_protocols_; 161 std::set<std::string> os_registered_protocols_; 162 bool force_os_failure_; 163}; 164 165class FakeClientObserver 166 : public ProtocolHandlerRegistry::DefaultClientObserver { 167 public: 168 FakeClientObserver(ProtocolHandlerRegistry* registry, 169 FakeDelegate* registry_delegate) 170 : ProtocolHandlerRegistry::DefaultClientObserver(registry), 171 delegate_(registry_delegate) {} 172 173 virtual void SetDefaultWebClientUIState( 174 ShellIntegration::DefaultWebClientUIState state) OVERRIDE { 175 ProtocolHandlerRegistry::DefaultClientObserver::SetDefaultWebClientUIState( 176 state); 177 if (state == ShellIntegration::STATE_IS_DEFAULT) { 178 delegate_->FakeRegisterWithOS(worker_->protocol()); 179 } 180 if (state != ShellIntegration::STATE_PROCESSING) { 181 base::MessageLoop::current()->Quit(); 182 } 183 } 184 185 private: 186 FakeDelegate* delegate_; 187}; 188 189class FakeProtocolClientWorker 190 : public ShellIntegration::DefaultProtocolClientWorker { 191 public: 192 FakeProtocolClientWorker(ShellIntegration::DefaultWebClientObserver* observer, 193 const std::string& protocol, 194 bool force_failure) 195 : ShellIntegration::DefaultProtocolClientWorker(observer, protocol), 196 force_failure_(force_failure) {} 197 198 private: 199 virtual ~FakeProtocolClientWorker() {} 200 201 virtual ShellIntegration::DefaultWebClientState CheckIsDefault() OVERRIDE { 202 if (force_failure_) { 203 return ShellIntegration::NOT_DEFAULT; 204 } else { 205 return ShellIntegration::IS_DEFAULT; 206 } 207 } 208 209 virtual bool SetAsDefault(bool interactive_permitted) OVERRIDE { 210 return true; 211 } 212 213 private: 214 bool force_failure_; 215}; 216 217ProtocolHandlerRegistry::DefaultClientObserver* 218 FakeDelegate::CreateShellObserver(ProtocolHandlerRegistry* registry) { 219 return new FakeClientObserver(registry, this); 220} 221 222ShellIntegration::DefaultProtocolClientWorker* FakeDelegate::CreateShellWorker( 223 ShellIntegration::DefaultWebClientObserver* observer, 224 const std::string& protocol) { 225 return new FakeProtocolClientWorker(observer, protocol, force_os_failure_); 226} 227 228class NotificationCounter : public content::NotificationObserver { 229 public: 230 explicit NotificationCounter(Profile* profile) 231 : events_(0), 232 notification_registrar_() { 233 notification_registrar_.Add(this, 234 chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED, 235 content::Source<Profile>(profile)); 236 } 237 238 int events() { return events_; } 239 bool notified() { return events_ > 0; } 240 void Clear() { events_ = 0; } 241 virtual void Observe(int type, 242 const content::NotificationSource& source, 243 const content::NotificationDetails& details) OVERRIDE { 244 ++events_; 245 } 246 247 int events_; 248 content::NotificationRegistrar notification_registrar_; 249}; 250 251class QueryProtocolHandlerOnChange 252 : public content::NotificationObserver { 253 public: 254 QueryProtocolHandlerOnChange(Profile* profile, 255 ProtocolHandlerRegistry* registry) 256 : local_registry_(registry), 257 called_(false), 258 notification_registrar_() { 259 notification_registrar_.Add(this, 260 chrome::NOTIFICATION_PROTOCOL_HANDLER_REGISTRY_CHANGED, 261 content::Source<Profile>(profile)); 262 } 263 264 virtual void Observe(int type, 265 const content::NotificationSource& source, 266 const content::NotificationDetails& details) OVERRIDE { 267 std::vector<std::string> output; 268 local_registry_->GetRegisteredProtocols(&output); 269 called_ = true; 270 } 271 272 ProtocolHandlerRegistry* local_registry_; 273 bool called_; 274 content::NotificationRegistrar notification_registrar_; 275}; 276 277// URLRequest DCHECKS that the current MessageLoop is IO. It does this because 278// it can't check the thread id (since net can't depend on content.) We want 279// to harness our tests so all threads use the same loop allowing us to 280// guarantee all messages are processed.) By overriding the IsType method 281// we basically ignore the supplied message loop type, and instead infer 282// our type based on the current thread. GO DEPENDENCY INJECTION! 283class TestMessageLoop : public base::MessageLoop { 284 public: 285 TestMessageLoop() : base::MessageLoop(base::MessageLoop::TYPE_DEFAULT) {} 286 virtual ~TestMessageLoop() {} 287 virtual bool IsType(base::MessageLoop::Type type) const OVERRIDE { 288 switch (type) { 289 case base::MessageLoop::TYPE_UI: 290 return BrowserThread::CurrentlyOn(BrowserThread::UI); 291 case base::MessageLoop::TYPE_IO: 292 return BrowserThread::CurrentlyOn(BrowserThread::IO); 293 case base::MessageLoop::TYPE_DEFAULT: 294 return !BrowserThread::CurrentlyOn(BrowserThread::UI) && 295 !BrowserThread::CurrentlyOn(BrowserThread::IO); 296 } 297 return false; 298 } 299}; 300 301} // namespace 302 303class ProtocolHandlerRegistryTest : public testing::Test { 304 protected: 305 ProtocolHandlerRegistryTest() 306 : ui_thread_(BrowserThread::UI, &loop_), 307 file_thread_(BrowserThread::FILE, &loop_), 308 io_thread_(BrowserThread::IO, &loop_), 309 test_protocol_handler_(CreateProtocolHandler("test", "test")) {} 310 311 FakeDelegate* delegate() const { return delegate_; } 312 ProtocolHandlerRegistry* registry() { return registry_.get(); } 313 TestingProfile* profile() const { return profile_.get(); } 314 const ProtocolHandler& test_protocol_handler() const { 315 return test_protocol_handler_; 316 } 317 318 ProtocolHandler CreateProtocolHandler(const std::string& protocol, 319 const GURL& url, 320 const std::string& title) { 321 return ProtocolHandler::CreateProtocolHandler(protocol, url, 322 UTF8ToUTF16(title)); 323 } 324 325 ProtocolHandler CreateProtocolHandler(const std::string& protocol, 326 const std::string& name) { 327 return CreateProtocolHandler(protocol, GURL("http://" + name + "/%s"), 328 name); 329 } 330 331 void RecreateRegistry(bool initialize) { 332 TeadDownRegistry(); 333 SetUpRegistry(initialize); 334 } 335 336 // Returns a new registry, initializing it if |initialize| is true. 337 // Caller assumes ownership for the object 338 void SetUpRegistry(bool initialize) { 339 delegate_ = new FakeDelegate(); 340 registry_.reset(new ProtocolHandlerRegistry(profile(), delegate())); 341 if (initialize) registry_->InitProtocolSettings(); 342 } 343 344 void TeadDownRegistry() { 345 registry_->Shutdown(); 346 registry_.reset(); 347 // Registry owns the delegate_ it handles deletion of that object. 348 } 349 350 virtual void SetUp() { 351 profile_.reset(new TestingProfile()); 352 CHECK(profile_->GetPrefs()); 353 SetUpRegistry(true); 354 test_protocol_handler_ = 355 CreateProtocolHandler("test", GURL("http://test.com/%s"), "Test"); 356 } 357 358 virtual void TearDown() { 359 TeadDownRegistry(); 360 } 361 362 TestMessageLoop loop_; 363 364 private: 365 content::TestBrowserThread ui_thread_; 366 content::TestBrowserThread file_thread_; 367 content::TestBrowserThread io_thread_; 368 369 scoped_ptr<TestingProfile> profile_; 370 FakeDelegate* delegate_; // Registry assumes ownership of delegate_. 371 scoped_ptr<ProtocolHandlerRegistry> registry_; 372 ProtocolHandler test_protocol_handler_; 373}; 374 375// ProtocolHandlerRegistryTest tests are flaky on Linux & ChromeOS. 376// http://crbug.com/133023 377#if defined(OS_LINUX) || defined(OS_CHROMEOS) 378#define MAYBE_AcceptProtocolHandlerHandlesProtocol \ 379 DISABLED_AcceptProtocolHandlerHandlesProtocol 380#define MAYBE_DeniedProtocolIsntHandledUntilAccepted \ 381 DISABLED_DeniedProtocolIsntHandledUntilAccepted 382#define MAYBE_TestStartsAsDefault DISABLED_TestStartsAsDefault 383#define MAYBE_TestRemoveHandlerRemovesDefault \ 384 DISABLED_TestRemoveHandlerRemovesDefault 385#define MAYBE_TestClearDefaultGetsPropagatedToIO \ 386 DISABLED_TestClearDefaultGetsPropagatedToIO 387#define MAYBE_TestIsHandledProtocolWorksOnIOThread \ 388 DISABLED_TestIsHandledProtocolWorksOnIOThread 389#define MAYBE_TestInstallDefaultHandler \ 390 DISABLED_TestInstallDefaultHandler 391#else 392#define MAYBE_AcceptProtocolHandlerHandlesProtocol \ 393 AcceptProtocolHandlerHandlesProtocol 394#define MAYBE_DeniedProtocolIsntHandledUntilAccepted \ 395 DeniedProtocolIsntHandledUntilAccepted 396#define MAYBE_TestStartsAsDefault TestStartsAsDefault 397#define MAYBE_TestRemoveHandlerRemovesDefault TestRemoveHandlerRemovesDefault 398#define MAYBE_TestClearDefaultGetsPropagatedToIO \ 399 TestClearDefaultGetsPropagatedToIO 400#define MAYBE_TestIsHandledProtocolWorksOnIOThread \ 401 TestIsHandledProtocolWorksOnIOThread 402#define MAYBE_TestInstallDefaultHandler TestInstallDefaultHandler 403#endif // defined(OS_CHROMEOS) 404 405TEST_F(ProtocolHandlerRegistryTest, 406 MAYBE_AcceptProtocolHandlerHandlesProtocol) { 407 ASSERT_FALSE(registry()->IsHandledProtocol("test")); 408 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 409 ASSERT_TRUE(registry()->IsHandledProtocol("test")); 410} 411 412TEST_F(ProtocolHandlerRegistryTest, 413 MAYBE_DeniedProtocolIsntHandledUntilAccepted) { 414 registry()->OnDenyRegisterProtocolHandler(test_protocol_handler()); 415 ASSERT_FALSE(registry()->IsHandledProtocol("test")); 416 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 417 ASSERT_TRUE(registry()->IsHandledProtocol("test")); 418} 419 420TEST_F(ProtocolHandlerRegistryTest, ClearDefaultMakesProtocolNotHandled) { 421 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 422 registry()->ClearDefault("test"); 423 ASSERT_FALSE(registry()->IsHandledProtocol("test")); 424 ASSERT_TRUE(registry()->GetHandlerFor("test").IsEmpty()); 425} 426 427TEST_F(ProtocolHandlerRegistryTest, DisableDeregistersProtocolHandlers) { 428 ASSERT_FALSE(delegate()->IsExternalHandlerRegistered("test")); 429 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 430 ASSERT_TRUE(delegate()->IsExternalHandlerRegistered("test")); 431 432 registry()->Disable(); 433 ASSERT_FALSE(delegate()->IsExternalHandlerRegistered("test")); 434 registry()->Enable(); 435 ASSERT_TRUE(delegate()->IsExternalHandlerRegistered("test")); 436} 437 438TEST_F(ProtocolHandlerRegistryTest, IgnoreProtocolHandler) { 439 registry()->OnIgnoreRegisterProtocolHandler(test_protocol_handler()); 440 ASSERT_TRUE(registry()->IsIgnored(test_protocol_handler())); 441 442 registry()->RemoveIgnoredHandler(test_protocol_handler()); 443 ASSERT_FALSE(registry()->IsIgnored(test_protocol_handler())); 444} 445 446TEST_F(ProtocolHandlerRegistryTest, IgnoreEquivalentProtocolHandler) { 447 ProtocolHandler ph1 = CreateProtocolHandler("test", GURL("http://test/%s"), 448 "test1"); 449 ProtocolHandler ph2 = CreateProtocolHandler("test", GURL("http://test/%s"), 450 "test2"); 451 452 registry()->OnIgnoreRegisterProtocolHandler(ph1); 453 ASSERT_TRUE(registry()->IsIgnored(ph1)); 454 ASSERT_TRUE(registry()->HasIgnoredEquivalent(ph2)); 455 456 registry()->RemoveIgnoredHandler(ph1); 457 ASSERT_FALSE(registry()->IsIgnored(ph1)); 458 ASSERT_FALSE(registry()->HasIgnoredEquivalent(ph2)); 459} 460 461TEST_F(ProtocolHandlerRegistryTest, SaveAndLoad) { 462 ProtocolHandler stuff_protocol_handler( 463 CreateProtocolHandler("stuff", "stuff")); 464 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 465 registry()->OnIgnoreRegisterProtocolHandler(stuff_protocol_handler); 466 467 ASSERT_TRUE(registry()->IsHandledProtocol("test")); 468 ASSERT_TRUE(registry()->IsIgnored(stuff_protocol_handler)); 469 delegate()->Reset(); 470 RecreateRegistry(true); 471 ASSERT_TRUE(registry()->IsHandledProtocol("test")); 472 ASSERT_TRUE(registry()->IsIgnored(stuff_protocol_handler)); 473} 474 475TEST_F(ProtocolHandlerRegistryTest, TestEnabledDisabled) { 476 registry()->Disable(); 477 ASSERT_FALSE(registry()->enabled()); 478 registry()->Enable(); 479 ASSERT_TRUE(registry()->enabled()); 480} 481 482TEST_F(ProtocolHandlerRegistryTest, 483 DisallowRegisteringExternallyHandledProtocols) { 484 delegate()->RegisterExternalHandler("test"); 485 ASSERT_FALSE(registry()->CanSchemeBeOverridden("test")); 486} 487 488TEST_F(ProtocolHandlerRegistryTest, RemovingHandlerMeansItCanBeAddedAgain) { 489 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 490 ASSERT_TRUE(registry()->CanSchemeBeOverridden("test")); 491 registry()->RemoveHandler(test_protocol_handler()); 492 ASSERT_TRUE(registry()->CanSchemeBeOverridden("test")); 493} 494 495TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestStartsAsDefault) { 496 registry()->OnAcceptRegisterProtocolHandler(test_protocol_handler()); 497 ASSERT_TRUE(registry()->IsDefault(test_protocol_handler())); 498} 499 500TEST_F(ProtocolHandlerRegistryTest, TestClearDefault) { 501 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 502 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 503 registry()->OnAcceptRegisterProtocolHandler(ph1); 504 registry()->OnAcceptRegisterProtocolHandler(ph2); 505 506 registry()->OnAcceptRegisterProtocolHandler(ph1); 507 registry()->ClearDefault("test"); 508 ASSERT_FALSE(registry()->IsDefault(ph1)); 509 ASSERT_FALSE(registry()->IsDefault(ph2)); 510} 511 512TEST_F(ProtocolHandlerRegistryTest, TestGetHandlerFor) { 513 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 514 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 515 registry()->OnAcceptRegisterProtocolHandler(ph1); 516 registry()->OnAcceptRegisterProtocolHandler(ph2); 517 518 registry()->OnAcceptRegisterProtocolHandler(ph2); 519 ASSERT_EQ(ph2, registry()->GetHandlerFor("test")); 520 ASSERT_TRUE(registry()->IsHandledProtocol("test")); 521} 522 523TEST_F(ProtocolHandlerRegistryTest, TestMostRecentHandlerIsDefault) { 524 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 525 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 526 registry()->OnAcceptRegisterProtocolHandler(ph1); 527 registry()->OnAcceptRegisterProtocolHandler(ph2); 528 ASSERT_FALSE(registry()->IsDefault(ph1)); 529 ASSERT_TRUE(registry()->IsDefault(ph2)); 530} 531 532TEST_F(ProtocolHandlerRegistryTest, TestOnAcceptRegisterProtocolHandler) { 533 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 534 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 535 registry()->OnAcceptRegisterProtocolHandler(ph1); 536 registry()->OnAcceptRegisterProtocolHandler(ph2); 537 538 registry()->OnAcceptRegisterProtocolHandler(ph1); 539 ASSERT_TRUE(registry()->IsDefault(ph1)); 540 ASSERT_FALSE(registry()->IsDefault(ph2)); 541 542 registry()->OnAcceptRegisterProtocolHandler(ph2); 543 ASSERT_FALSE(registry()->IsDefault(ph1)); 544 ASSERT_TRUE(registry()->IsDefault(ph2)); 545} 546 547TEST_F(ProtocolHandlerRegistryTest, TestDefaultSaveLoad) { 548 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 549 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 550 registry()->OnDenyRegisterProtocolHandler(ph1); 551 registry()->OnDenyRegisterProtocolHandler(ph2); 552 553 registry()->OnAcceptRegisterProtocolHandler(ph2); 554 registry()->Disable(); 555 556 RecreateRegistry(true); 557 558 ASSERT_FALSE(registry()->enabled()); 559 registry()->Enable(); 560 ASSERT_FALSE(registry()->IsDefault(ph1)); 561 ASSERT_TRUE(registry()->IsDefault(ph2)); 562 563 RecreateRegistry(true); 564 ASSERT_TRUE(registry()->enabled()); 565} 566 567TEST_F(ProtocolHandlerRegistryTest, TestRemoveHandler) { 568 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 569 registry()->OnAcceptRegisterProtocolHandler(ph1); 570 registry()->OnAcceptRegisterProtocolHandler(ph1); 571 572 registry()->RemoveHandler(ph1); 573 ASSERT_FALSE(registry()->IsRegistered(ph1)); 574 ASSERT_FALSE(registry()->IsHandledProtocol("test")); 575} 576 577TEST_F(ProtocolHandlerRegistryTest, TestIsRegistered) { 578 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 579 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 580 registry()->OnAcceptRegisterProtocolHandler(ph1); 581 registry()->OnAcceptRegisterProtocolHandler(ph2); 582 583 ASSERT_TRUE(registry()->IsRegistered(ph1)); 584} 585 586TEST_F(ProtocolHandlerRegistryTest, TestIsEquivalentRegistered) { 587 ProtocolHandler ph1 = CreateProtocolHandler("test", GURL("http://test/%s"), 588 "test1"); 589 ProtocolHandler ph2 = CreateProtocolHandler("test", GURL("http://test/%s"), 590 "test2"); 591 registry()->OnAcceptRegisterProtocolHandler(ph1); 592 593 ASSERT_TRUE(registry()->IsRegistered(ph1)); 594 ASSERT_TRUE(registry()->HasRegisteredEquivalent(ph2)); 595} 596 597TEST_F(ProtocolHandlerRegistryTest, TestSilentlyRegisterHandler) { 598 ProtocolHandler ph1 = CreateProtocolHandler("test", GURL("http://test/%s"), 599 "test1"); 600 ProtocolHandler ph2 = CreateProtocolHandler("test", GURL("http://test/%s"), 601 "test2"); 602 ProtocolHandler ph3 = CreateProtocolHandler("ignore", GURL("http://test/%s"), 603 "ignore1"); 604 ProtocolHandler ph4 = CreateProtocolHandler("ignore", GURL("http://test/%s"), 605 "ignore2"); 606 607 ASSERT_FALSE(registry()->SilentlyHandleRegisterHandlerRequest(ph1)); 608 ASSERT_FALSE(registry()->IsRegistered(ph1)); 609 610 registry()->OnAcceptRegisterProtocolHandler(ph1); 611 ASSERT_TRUE(registry()->IsRegistered(ph1)); 612 613 ASSERT_TRUE(registry()->SilentlyHandleRegisterHandlerRequest(ph2)); 614 ASSERT_FALSE(registry()->IsRegistered(ph1)); 615 ASSERT_TRUE(registry()->IsRegistered(ph2)); 616 617 ASSERT_FALSE(registry()->SilentlyHandleRegisterHandlerRequest(ph3)); 618 ASSERT_FALSE(registry()->IsRegistered(ph3)); 619 620 registry()->OnIgnoreRegisterProtocolHandler(ph3); 621 ASSERT_FALSE(registry()->IsRegistered(ph3)); 622 ASSERT_TRUE(registry()->IsIgnored(ph3)); 623 624 ASSERT_TRUE(registry()->SilentlyHandleRegisterHandlerRequest(ph4)); 625 ASSERT_FALSE(registry()->IsRegistered(ph4)); 626 ASSERT_TRUE(registry()->HasIgnoredEquivalent(ph4)); 627} 628 629TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestRemoveHandlerRemovesDefault) { 630 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 631 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 632 ProtocolHandler ph3 = CreateProtocolHandler("test", "test3"); 633 634 registry()->OnAcceptRegisterProtocolHandler(ph1); 635 registry()->OnAcceptRegisterProtocolHandler(ph2); 636 registry()->OnAcceptRegisterProtocolHandler(ph3); 637 638 registry()->OnAcceptRegisterProtocolHandler(ph1); 639 registry()->RemoveHandler(ph1); 640 ASSERT_FALSE(registry()->IsDefault(ph1)); 641} 642 643TEST_F(ProtocolHandlerRegistryTest, TestGetHandlersFor) { 644 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 645 ProtocolHandler ph2 = CreateProtocolHandler("test", "test2"); 646 ProtocolHandler ph3 = CreateProtocolHandler("test", "test3"); 647 registry()->OnAcceptRegisterProtocolHandler(ph1); 648 registry()->OnAcceptRegisterProtocolHandler(ph2); 649 registry()->OnAcceptRegisterProtocolHandler(ph3); 650 651 ProtocolHandlerRegistry::ProtocolHandlerList handlers = 652 registry()->GetHandlersFor("test"); 653 ASSERT_EQ(static_cast<size_t>(3), handlers.size()); 654 655 ASSERT_EQ(ph3, handlers[0]); 656 ASSERT_EQ(ph2, handlers[1]); 657 ASSERT_EQ(ph1, handlers[2]); 658} 659 660TEST_F(ProtocolHandlerRegistryTest, TestGetRegisteredProtocols) { 661 std::vector<std::string> protocols; 662 registry()->GetRegisteredProtocols(&protocols); 663 ASSERT_EQ(static_cast<size_t>(0), protocols.size()); 664 665 registry()->GetHandlersFor("test"); 666 667 protocols.clear(); 668 registry()->GetRegisteredProtocols(&protocols); 669 ASSERT_EQ(static_cast<size_t>(0), protocols.size()); 670} 671 672TEST_F(ProtocolHandlerRegistryTest, TestIsHandledProtocol) { 673 registry()->GetHandlersFor("test"); 674 ASSERT_FALSE(registry()->IsHandledProtocol("test")); 675} 676 677TEST_F(ProtocolHandlerRegistryTest, TestNotifications) { 678 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 679 NotificationCounter counter(profile()); 680 681 registry()->OnAcceptRegisterProtocolHandler(ph1); 682 ASSERT_TRUE(counter.notified()); 683 counter.Clear(); 684 685 registry()->Disable(); 686 ASSERT_TRUE(counter.notified()); 687 counter.Clear(); 688 689 registry()->Enable(); 690 ASSERT_TRUE(counter.notified()); 691 counter.Clear(); 692 693 registry()->RemoveHandler(ph1); 694 ASSERT_TRUE(counter.notified()); 695 counter.Clear(); 696} 697 698TEST_F(ProtocolHandlerRegistryTest, TestReentrantNotifications) { 699 QueryProtocolHandlerOnChange queryer(profile(), registry()); 700 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 701 registry()->OnAcceptRegisterProtocolHandler(ph1); 702 ASSERT_TRUE(queryer.called_); 703} 704 705TEST_F(ProtocolHandlerRegistryTest, TestProtocolsWithNoDefaultAreHandled) { 706 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 707 registry()->OnAcceptRegisterProtocolHandler(ph1); 708 registry()->ClearDefault("test"); 709 std::vector<std::string> handled_protocols; 710 registry()->GetRegisteredProtocols(&handled_protocols); 711 ASSERT_EQ(static_cast<size_t>(1), handled_protocols.size()); 712 ASSERT_EQ("test", handled_protocols[0]); 713} 714 715TEST_F(ProtocolHandlerRegistryTest, TestDisablePreventsHandling) { 716 ProtocolHandler ph1 = CreateProtocolHandler("test", "test1"); 717 registry()->OnAcceptRegisterProtocolHandler(ph1); 718 ASSERT_TRUE(registry()->IsHandledProtocol("test")); 719 registry()->Disable(); 720 ASSERT_FALSE(registry()->IsHandledProtocol("test")); 721} 722 723// TODO(smckay): This is much more appropriately an integration 724// test. Make that so, then update the 725// ShellIntegretion{Delegate,Observer,Worker} test classes we use to fully 726// isolate this test from the FILE thread. 727TEST_F(ProtocolHandlerRegistryTest, TestOSRegistration) { 728 ProtocolHandler ph_do1 = CreateProtocolHandler("do", "test1"); 729 ProtocolHandler ph_do2 = CreateProtocolHandler("do", "test2"); 730 ProtocolHandler ph_dont = CreateProtocolHandler("dont", "test"); 731 732 ASSERT_FALSE(delegate()->IsFakeRegisteredWithOS("do")); 733 ASSERT_FALSE(delegate()->IsFakeRegisteredWithOS("dont")); 734 735 registry()->OnAcceptRegisterProtocolHandler(ph_do1); 736 registry()->OnDenyRegisterProtocolHandler(ph_dont); 737 base::MessageLoop::current()->Run(); // FILE thread needs to run. 738 ASSERT_TRUE(delegate()->IsFakeRegisteredWithOS("do")); 739 ASSERT_FALSE(delegate()->IsFakeRegisteredWithOS("dont")); 740 741 // This should not register with the OS, if it does the delegate 742 // will assert for us. We don't need to wait for the message loop 743 // as it should not go through to the shell worker. 744 registry()->OnAcceptRegisterProtocolHandler(ph_do2); 745} 746 747#if defined(OS_LINUX) 748// TODO(benwells): When Linux support is more reliable and 749// http://crbut.com/88255 is fixed this test will pass. 750#define MAYBE_TestOSRegistrationFailure DISABLED_TestOSRegistrationFailure 751#else 752#define MAYBE_TestOSRegistrationFailure TestOSRegistrationFailure 753#endif 754 755// TODO(smckay): This is much more appropriately an integration 756// test. Make that so, then update the 757// ShellIntegretion{Delegate,Observer,Worker} test classes we use to fully 758// isolate this test from the FILE thread. 759TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestOSRegistrationFailure) { 760 ProtocolHandler ph_do = CreateProtocolHandler("do", "test1"); 761 ProtocolHandler ph_dont = CreateProtocolHandler("dont", "test"); 762 763 ASSERT_FALSE(registry()->IsHandledProtocol("do")); 764 ASSERT_FALSE(registry()->IsHandledProtocol("dont")); 765 766 registry()->OnAcceptRegisterProtocolHandler(ph_do); 767 base::MessageLoop::current()->Run(); // FILE thread needs to run. 768 delegate()->set_force_os_failure(true); 769 registry()->OnAcceptRegisterProtocolHandler(ph_dont); 770 base::MessageLoop::current()->Run(); // FILE thread needs to run. 771 ASSERT_TRUE(registry()->IsHandledProtocol("do")); 772 ASSERT_EQ(static_cast<size_t>(1), registry()->GetHandlersFor("do").size()); 773 ASSERT_FALSE(registry()->IsHandledProtocol("dont")); 774 ASSERT_EQ(static_cast<size_t>(1), registry()->GetHandlersFor("dont").size()); 775} 776 777TEST_F(ProtocolHandlerRegistryTest, TestMaybeCreateTaskWorksFromIOThread) { 778 ProtocolHandler ph1 = CreateProtocolHandler("mailto", "test1"); 779 registry()->OnAcceptRegisterProtocolHandler(ph1); 780 GURL url("mailto:someone@something.com"); 781 782 scoped_ptr<net::URLRequestJobFactory> interceptor( 783 registry()->CreateJobInterceptorFactory()); 784 AssertIntercepted(url, interceptor.get()); 785} 786 787TEST_F(ProtocolHandlerRegistryTest, 788 MAYBE_TestIsHandledProtocolWorksOnIOThread) { 789 std::string scheme("mailto"); 790 ProtocolHandler ph1 = CreateProtocolHandler(scheme, "test1"); 791 registry()->OnAcceptRegisterProtocolHandler(ph1); 792 793 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> interceptor( 794 registry()->CreateJobInterceptorFactory()); 795 AssertWillHandle(scheme, true, interceptor.get()); 796} 797 798TEST_F(ProtocolHandlerRegistryTest, TestRemovingDefaultFallsBackToOldDefault) { 799 ProtocolHandler ph1 = CreateProtocolHandler("mailto", "test1"); 800 ProtocolHandler ph2 = CreateProtocolHandler("mailto", "test2"); 801 ProtocolHandler ph3 = CreateProtocolHandler("mailto", "test3"); 802 registry()->OnAcceptRegisterProtocolHandler(ph1); 803 registry()->OnAcceptRegisterProtocolHandler(ph2); 804 registry()->OnAcceptRegisterProtocolHandler(ph3); 805 806 ASSERT_TRUE(registry()->IsDefault(ph3)); 807 registry()->RemoveHandler(ph3); 808 ASSERT_TRUE(registry()->IsDefault(ph2)); 809 registry()->OnAcceptRegisterProtocolHandler(ph3); 810 ASSERT_TRUE(registry()->IsDefault(ph3)); 811 registry()->RemoveHandler(ph2); 812 ASSERT_TRUE(registry()->IsDefault(ph3)); 813 registry()->RemoveHandler(ph3); 814 ASSERT_TRUE(registry()->IsDefault(ph1)); 815} 816 817TEST_F(ProtocolHandlerRegistryTest, TestRemovingDefaultDoesntChangeHandlers) { 818 ProtocolHandler ph1 = CreateProtocolHandler("mailto", "test1"); 819 ProtocolHandler ph2 = CreateProtocolHandler("mailto", "test2"); 820 ProtocolHandler ph3 = CreateProtocolHandler("mailto", "test3"); 821 registry()->OnAcceptRegisterProtocolHandler(ph1); 822 registry()->OnAcceptRegisterProtocolHandler(ph2); 823 registry()->OnAcceptRegisterProtocolHandler(ph3); 824 registry()->RemoveHandler(ph3); 825 826 ProtocolHandlerRegistry::ProtocolHandlerList handlers = 827 registry()->GetHandlersFor("mailto"); 828 ASSERT_EQ(static_cast<size_t>(2), handlers.size()); 829 830 ASSERT_EQ(ph2, handlers[0]); 831 ASSERT_EQ(ph1, handlers[1]); 832} 833 834TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestClearDefaultGetsPropagatedToIO) { 835 std::string scheme("mailto"); 836 ProtocolHandler ph1 = CreateProtocolHandler(scheme, "test1"); 837 registry()->OnAcceptRegisterProtocolHandler(ph1); 838 registry()->ClearDefault(scheme); 839 840 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> interceptor( 841 registry()->CreateJobInterceptorFactory()); 842 AssertWillHandle(scheme, false, interceptor.get()); 843} 844 845TEST_F(ProtocolHandlerRegistryTest, TestLoadEnabledGetsPropogatedToIO) { 846 std::string mailto("mailto"); 847 ProtocolHandler ph1 = CreateProtocolHandler(mailto, "MailtoHandler"); 848 registry()->OnAcceptRegisterProtocolHandler(ph1); 849 850 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> interceptor( 851 registry()->CreateJobInterceptorFactory()); 852 AssertWillHandle(mailto, true, interceptor.get()); 853 registry()->Disable(); 854 AssertWillHandle(mailto, false, interceptor.get()); 855} 856 857TEST_F(ProtocolHandlerRegistryTest, TestReplaceHandler) { 858 ProtocolHandler ph1 = CreateProtocolHandler("mailto", 859 GURL("http://test.com/%s"), "test1"); 860 ProtocolHandler ph2 = CreateProtocolHandler("mailto", 861 GURL("http://test.com/updated-url/%s"), "test2"); 862 registry()->OnAcceptRegisterProtocolHandler(ph1); 863 ASSERT_TRUE(registry()->AttemptReplace(ph2)); 864 const ProtocolHandler& handler(registry()->GetHandlerFor("mailto")); 865 ASSERT_EQ(handler.url(), ph2.url()); 866} 867 868TEST_F(ProtocolHandlerRegistryTest, TestReplaceNonDefaultHandler) { 869 ProtocolHandler ph1 = CreateProtocolHandler("mailto", 870 GURL("http://test.com/%s"), "test1"); 871 ProtocolHandler ph2 = CreateProtocolHandler("mailto", 872 GURL("http://test.com/updated-url/%s"), "test2"); 873 ProtocolHandler ph3 = CreateProtocolHandler("mailto", 874 GURL("http://else.com/%s"), "test3"); 875 registry()->OnAcceptRegisterProtocolHandler(ph1); 876 registry()->OnAcceptRegisterProtocolHandler(ph3); 877 ASSERT_TRUE(registry()->AttemptReplace(ph2)); 878 const ProtocolHandler& handler(registry()->GetHandlerFor("mailto")); 879 ASSERT_EQ(handler.url(), ph3.url()); 880} 881 882TEST_F(ProtocolHandlerRegistryTest, TestReplaceRemovesStaleHandlers) { 883 ProtocolHandler ph1 = CreateProtocolHandler("mailto", 884 GURL("http://test.com/%s"), "test1"); 885 ProtocolHandler ph2 = CreateProtocolHandler("mailto", 886 GURL("http://test.com/updated-url/%s"), "test2"); 887 ProtocolHandler ph3 = CreateProtocolHandler("mailto", 888 GURL("http://test.com/third/%s"), "test"); 889 registry()->OnAcceptRegisterProtocolHandler(ph1); 890 registry()->OnAcceptRegisterProtocolHandler(ph2); 891 892 // This should replace the previous two handlers. 893 ASSERT_TRUE(registry()->AttemptReplace(ph3)); 894 const ProtocolHandler& handler(registry()->GetHandlerFor("mailto")); 895 ASSERT_EQ(handler.url(), ph3.url()); 896 registry()->RemoveHandler(ph3); 897 ASSERT_TRUE(registry()->GetHandlerFor("mailto").IsEmpty()); 898} 899 900TEST_F(ProtocolHandlerRegistryTest, TestIsSameOrigin) { 901 ProtocolHandler ph1 = CreateProtocolHandler("mailto", 902 GURL("http://test.com/%s"), "test1"); 903 ProtocolHandler ph2 = CreateProtocolHandler("mailto", 904 GURL("http://test.com/updated-url/%s"), "test2"); 905 ProtocolHandler ph3 = CreateProtocolHandler("mailto", 906 GURL("http://other.com/%s"), "test"); 907 ASSERT_EQ(ph1.url().GetOrigin() == ph2.url().GetOrigin(), 908 ph1.IsSameOrigin(ph2)); 909 ASSERT_EQ(ph1.url().GetOrigin() == ph2.url().GetOrigin(), 910 ph2.IsSameOrigin(ph1)); 911 ASSERT_EQ(ph2.url().GetOrigin() == ph3.url().GetOrigin(), 912 ph2.IsSameOrigin(ph3)); 913 ASSERT_EQ(ph3.url().GetOrigin() == ph2.url().GetOrigin(), 914 ph3.IsSameOrigin(ph2)); 915} 916 917TEST_F(ProtocolHandlerRegistryTest, MAYBE_TestInstallDefaultHandler) { 918 RecreateRegistry(false); 919 registry()->AddPredefinedHandler(CreateProtocolHandler( 920 "test", GURL("http://test.com/%s"), "Test")); 921 registry()->InitProtocolSettings(); 922 std::vector<std::string> protocols; 923 registry()->GetRegisteredProtocols(&protocols); 924 ASSERT_EQ(static_cast<size_t>(1), protocols.size()); 925} 926